1. 项目概述
市容监察管理系统是一个基于.NET框架和微信小程序的综合解决方案,旨在为城市管理部门提供高效、便捷的市容环境监管工具。作为一名从事软件开发十余年的工程师,我深知这类系统在实际应用中的痛点——传统纸质记录方式效率低下、信息传递滞后、问题处理周期长。这套系统正是为了解决这些问题而设计开发的。
系统采用前后端分离架构,后端基于.NET Core构建,提供稳定的API服务;前端则依托微信小程序生态,让巡查人员可以随时随地进行问题上报和处理。这种组合既保证了系统的性能和安全,又充分利用了微信平台的用户基础和便捷性。
2. 系统架构设计
2.1 技术选型解析
在技术选型上,我们经过多方考量最终确定了以下技术栈:
后端技术栈:
- .NET Core 3.1:微软推出的跨平台开发框架,性能优异且生态完善
- Entity Framework Core:ORM框架,简化数据库操作
- JWT认证:保障接口安全
- Redis:缓存热点数据,提升系统响应速度
前端技术栈:
- 微信小程序原生开发:无需安装,即用即走
- Vant Weapp组件库:提供丰富的UI组件
- ECharts for Weixin:数据可视化展示
数据库:
- SQL Server 2019:关系型数据库,适合结构化数据存储
- 配合使用Dapper提升复杂查询性能
这个技术组合的亮点在于:
- .NET Core的高性能能够支撑大量并发请求
- 微信小程序的低使用门槛让一线工作人员快速上手
- SQL Server+Redis的组合既保证了数据安全又提升了访问速度
2.2 系统架构图
整个系统采用分层架构设计,从上到下分为:
表现层(微信小程序) → API网关层 → 应用服务层 → 领域层 → 基础设施层每层职责明确,通过接口进行通信,这样的设计使得系统各模块耦合度低,便于后期维护和扩展。
实际开发中发现,清晰的接口定义能减少30%以上的联调时间。建议在项目初期就制定详细的接口文档规范。
3. 核心功能模块实现
3.1 问题上报模块
这是系统的核心功能之一,实现了市容问题的快速采集和定位。关键技术点包括:
- 多媒体上传:
- 采用微信小程序chooseImage接口选择图片
- 使用uploadFile接口上传到服务器
- 服务器端使用七牛云SDK转存到对象存储
- 返回可访问的URL存入数据库
- 地理位置获取:
wx.getLocation({ type: 'gcj02', success: (res) => { this.setData({ latitude: res.latitude, longitude: res.longitude }) } })这里需要注意:
- 小程序需要配置地理位置权限
- 建议使用GCJ-02坐标系(火星坐标系)
- 高精度定位会消耗更多电量,需合理设置参数
- 表单验证:
public class ReportDto { [Required(ErrorMessage = "问题类型不能为空")] public int ProblemType { get; set; } [StringLength(500, ErrorMessage = "描述不能超过500字")] public string Description { get; set; } [Required(ErrorMessage = "至少上传一张图片")] public List<string> ImageUrls { get; set; } }3.2 任务分派模块
管理员收到问题上报后,需要将任务分派给具体责任人。我们实现了智能分派算法:
- 基于GIS的空间分析,自动推荐距离最近的处理人员
- 考虑人员当前任务量,避免分配不均
- 支持手动调整和优先级设置
核心代码片段:
public async Task<ActionResult> AssignTask(AssignTaskDto dto) { // 验证输入 var validator = new AssignTaskValidator(); var result = validator.Validate(dto); if (!result.IsValid) { return BadRequest(result.Errors); } // 创建任务实体 var task = new InspectionTask { ProblemId = dto.ProblemId, AssigneeId = dto.AssigneeId, Deadline = DateTime.Now.AddHours(dto.ExpectedHours), Status = TaskStatus.Assigned }; // 保存到数据库 await _taskRepository.AddAsync(task); await _unitOfWork.SaveChangesAsync(); // 发送微信模板消息通知 await _notificationService.SendTaskAssignedNotification(task.Id); return Ok(); }3.3 处理反馈模块
处理人员完成任务后,需要通过小程序提交处理结果。这个模块的关键在于:
- 支持多张处理前后对比图片上传
- 结构化的问题解决描述
- 自动计算响应时效
- 满意度评价收集
数据库设计要点:
CREATE TABLE ProblemFeedback ( Id INT PRIMARY KEY IDENTITY, TaskId INT NOT NULL, HandlerId INT NOT NULL, ProcessDescription NVARCHAR(1000), BeforeImageUrls NVARCHAR(MAX), AfterImageUrls NVARCHAR(MAX), ProcessTime DATETIME2, Cost DECIMAL(10,2), IsSolved BIT, Satisfaction INT, FOREIGN KEY (TaskId) REFERENCES InspectionTask(Id), FOREIGN KEY (HandlerId) REFERENCES SystemUser(Id) );4. 数据库设计与优化
4.1 主要数据表结构
系统共设计20余张数据表,核心表包括:
- 用户表:
CREATE TABLE SystemUser ( Id INT PRIMARY KEY IDENTITY, Username NVARCHAR(50) NOT NULL UNIQUE, PasswordHash NVARCHAR(200) NOT NULL, RealName NVARCHAR(50), Phone NVARCHAR(20), DepartmentId INT, RoleType INT NOT NULL, IsActive BIT DEFAULT 1, CreatedTime DATETIME2 DEFAULT GETDATE(), FOREIGN KEY (DepartmentId) REFERENCES Department(Id) );- 问题记录表:
CREATE TABLE ProblemReport ( Id INT PRIMARY KEY IDENTITY, ReporterId INT NOT NULL, ProblemTypeId INT NOT NULL, Description NVARCHAR(500), Location GEOGRAPHY, Address NVARCHAR(200), ImageUrls NVARCHAR(MAX), Status INT DEFAULT 0, ReportTime DATETIME2 DEFAULT GETDATE(), FOREIGN KEY (ReporterId) REFERENCES SystemUser(Id), FOREIGN KEY (ProblemTypeId) REFERENCES ProblemType(Id) );- 任务表:
CREATE TABLE InspectionTask ( Id INT PRIMARY KEY IDENTITY, ProblemId INT NOT NULL, AssignerId INT NOT NULL, AssigneeId INT NOT NULL, AssignTime DATETIME2 DEFAULT GETDATE(), Deadline DATETIME2, Status INT DEFAULT 0, Priority INT DEFAULT 0, FOREIGN KEY (ProblemId) REFERENCES ProblemReport(Id), FOREIGN KEY (AssignerId) REFERENCES SystemUser(Id), FOREIGN KEY (AssigneeId) REFERENCES SystemUser(Id) );4.2 性能优化实践
在实际运行中,我们针对以下场景做了优化:
- 空间索引优化:
CREATE SPATIAL INDEX IX_ProblemReport_Location ON ProblemReport(Location) USING GEOGRAPHY_GRID WITH ( GRIDS = (LEVEL_1 = MEDIUM, LEVEL_2 = MEDIUM, LEVEL_3 = MEDIUM, LEVEL_4 = MEDIUM), CELLS_PER_OBJECT = 16 );- 查询优化:
- 对常用查询字段建立适当索引
- 使用Include索引减少Key Lookup
- 复杂报表查询使用预计算表
- 缓存策略:
- 使用Redis缓存热点数据
- 实现二级缓存(内存+Redis)
- 缓存失效策略:滑动过期+绝对过期组合
在用户量达到500+时,我们发现空间查询性能下降明显。通过添加空间索引和优化查询语句,响应时间从原来的2s+降低到200ms左右。
5. 微信小程序实现细节
5.1 小程序端架构
小程序采用模块化开发,主要目录结构:
├── components # 公共组件 │ ├── image-uploader │ ├── location-picker │ └── tab-bar ├── pages # 页面目录 │ ├── report # 问题上报 │ ├── task # 任务管理 │ └── me # 个人中心 ├── services # 服务层 │ ├── api.js # 接口封装 │ └── auth.js # 认证服务 └── utils # 工具类 ├── request.js # 请求封装 └── validator.js # 验证工具5.2 关键实现技术
- 地图集成:
// 页面配置 Page({ data: { markers: [{ id: 0, latitude: 23.099994, longitude: 113.324520, iconPath: '/images/location.png', width: 30, height: 30 }] }, onLoad() { this.getLocation(); }, getLocation() { wx.getLocation({ type: 'gcj02', success: (res) => { this.setData({ latitude: res.latitude, longitude: res.longitude, markers: [{ ...this.data.markers[0], latitude: res.latitude, longitude: res.longitude }] }) } }) } })- 图片上传优化:
- 使用wx.compressImage压缩图片
- 分片上传大文件
- 显示上传进度
- 失败自动重试机制
- 数据缓存策略:
- 使用wx.setStorageSync缓存静态数据
- 设置合理的缓存过期时间
- 监听网络状态变化调整缓存策略
6. 系统安全设计
6.1 认证与授权
- JWT认证流程:
- 用户登录获取token
- 每次请求携带token
- 服务端验证token有效性
- 解析token获取用户信息
- 权限控制:
[Authorize(Roles = "Inspector,Admin")] [HttpPost("assign-task")] public async Task<IActionResult> AssignTask([FromBody] AssignTaskDto dto) { // 业务逻辑 }- 敏感数据保护:
- 密码使用PBKDF2算法加盐哈希
- 敏感信息加密存储
- 日志脱敏处理
6.2 接口安全
- 防SQL注入:
- 使用参数化查询
- 限制数据库账号权限
- 定期扫描SQL注入漏洞
- 防XSS攻击:
- 输入输出编码
- 使用Content Security Policy
- 设置HttpOnly的Cookie
- 速率限制:
services.AddRateLimiter(options => { options.GlobalLimiter = PartitionedRateLimiter.Create<HttpContext, string>(context => RateLimitPartition.GetFixedWindowLimiter( partitionKey: context.User.Identity?.Name ?? context.Request.Headers.Host.ToString(), factory: partition => new FixedWindowRateLimiterOptions { AutoReplenishment = true, PermitLimit = 100, QueueLimit = 0, Window = TimeSpan.FromMinutes(1) })); });7. 部署与运维
7.1 部署架构
我们采用Docker容器化部署方案:
前端层:Nginx (负载均衡) → 微信小程序 后端层:Nginx → API服务集群 (.NET Core) 数据层:SQL Server Always On集群 + Redis哨兵模式 监控层:Prometheus + Grafana7.2 CI/CD流程
- 代码提交:触发GitHub Actions
- 自动化测试:
- 单元测试
- 集成测试
- E2E测试
- 构建镜像:
- 构建Docker镜像
- 扫描安全漏洞
- 部署:
- 滚动更新到测试环境
- 人工确认后发布生产
7.3 监控告警
- 指标监控:
- 接口响应时间
- 错误率
- 系统资源使用率
- 数据库性能指标
- 日志收集:
- 使用ELK栈收集分析日志
- 关键业务操作审计日志
- 异常日志自动告警
- 健康检查:
app.MapHealthChecks("/health", new HealthCheckOptions { Predicate = _ => true, ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse });8. 项目总结与反思
这个项目从立项到上线历时6个月,期间遇到了不少挑战也积累了很多经验:
- 技术收获:
- 深入掌握了.NET Core的性能优化技巧
- 积累了微信小程序与后端API的交互经验
- 实践了微服务架构下的分布式事务解决方案
- 项目管理经验:
- 使用Azure DevOps进行敏捷开发
- 代码评审和结对编程显著提高了代码质量
- 自动化测试覆盖率达到了80%+
- 性能数据:
- 单API实例可支撑1000+ TPS
- 平均响应时间<200ms
- 支持500+并发用户
- 待改进点:
- 初期低估了GIS功能的复杂度
- 小程序兼容性问题较多
- 压力测试开始得较晚
这个项目让我深刻体会到,一个好的系统不仅要有完善的功能,更需要考虑实际使用场景。比如我们最初设计的图片上传功能在4G网络环境下表现不佳,后来通过优化压缩算法和增加断点续传才解决了问题。这也提醒我,在系统设计阶段就要充分考虑各种使用环境。