# 阶段一架构设计 — 基础设施与用户体系 > 基于 Team A 需求规格(spec.md) > 嵌入 Team A 关键信息 --- ## 一、系统架构 ### 1.1 整体架构 ``` ┌─────────────────────────────────────────────────────────────┐ │ 客户端层 │ ├─────────────────────────┬───────────────────────────────────┤ │ 微信小程序 (wxapp) │ 后台管理系统 (wxbackstage) │ │ - 原生微信开发 │ - Vue 2 + Element UI │ │ - 面向四类用户 │ - 面向政府管理部门 │ └───────────┬─────────────┴───────────────┬───────────────────┘ │ │ ▼ ▼ ┌─────────────────────────────────────────────────────────────┐ │ API 网关层 │ │ - JWT Token 认证 │ │ - 权限拦截器(RBAC) │ │ - 接口路径:/api/wx/* (小程序) /api/admin/* (后台) │ └───────────────────────────┬─────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ 业务逻辑层 │ ├──────────┬──────────┬──────────┬──────────┬────────────────┤ │ 用户模块 │ 系统模块 │ 审核模块 │ 首页模块 │ 通用模块 │ │ AuthService│ SysService│ AuditService│ HomeService│ CommonService│ └──────┬───┴──────┬───┴──────┬───┴──────┬───┴────────┬───────┘ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ ┌─────────────────────────────────────────────────────────────┐ │ 数据访问层 │ │ - MyBatis XML 映射 │ │ - Mapper 接口 │ └───────────────────────────┬─────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ 数据存储层 │ ├─────────────────────────┬───────────────────────────────────┤ │ MySQL (crrc 库) │ Redis (缓存) │ │ - 15 张业务表 │ - Token 黑名单 │ │ - AES 加密字段 │ - 验证码缓存 │ │ - SHA256 哈希索引 │ - 数据大屏统计 │ └─────────────────────────┴───────────────────────────────────┘ ``` ### 1.2 模块划分 | 模块 | 包名 | 职责 | |------|------|------| | 用户模块 | com.sayu.service | 用户认证、身份管理、权限控制 | | 系统模块 | com.sayu.service | 角色管理、账号管理、字典管理、操作日志 | | 审核模块 | com.sayu.service | 审核流程、审核列表、审核日志 | | 首页模块 | com.sayu.service | 首页数据、行情展示 | | 通用模块 | com.sayu.util | 工具类、常量、异常处理 | ### 1.3 分层架构 ``` Controller 层(API 入口) ↓ Service 层(业务逻辑) ↓ Mapper 层(数据访问) ↓ Entity/DTO/VO 层(数据模型) ``` **职责划分**: - **Controller**: 接收请求、参数校验、调用 Service、返回响应 - **Service**: 业务逻辑、事务管理、异常处理 - **Mapper**: 数据库操作、MyBatis XML 映射 - **Entity**: 数据库实体,与表结构对应 - **DTO**: 数据传输对象,Service 层间传递 - **VO**: 视图对象,Controller 返回给前端 --- ## 二、数据库设计 ### 2.1 ER 图 ``` sys_user (用户基础表) │ ├── 1:N ──→ user_identity (身份关联表) │ │ │ ├── 1:1 ──→ grower_profile (果农档案) │ ├── 1:1 ──→ worker_profile (工人档案) │ ├── 1:1 ──→ buyer_profile (客商档案) │ └── 1:1 ──→ supplier_shop (农资店铺) │ └── 1:N ──→ operation_log (操作日志) audit_log (审核日志) │ └── 关联 → user_identity sys_role (角色表) │ └── N:M ──→ sys_permission (权限表) ``` ### 2.2 核心表设计 #### sys_user(用户基础表) | 字段 | 类型 | 约束 | 说明 | |------|------|------|------| | id | BIGINT | PK, AUTO_INCREMENT | 用户ID | | openid | VARCHAR(64) | UNIQUE, INDEX | 微信 openid | | username | VARCHAR(50) | UNIQUE | 后台登录用户名 | | password | VARCHAR(100) | | BCrypt 加密密码 | | phone | VARCHAR(100) | | AES 加密手机号 | | phone_hash | VARCHAR(64) | UNIQUE, INDEX | SHA256 手机号哈希 | | real_name | VARCHAR(50) | | 真实姓名 | | status | TINYINT | INDEX | 状态:0正常 1禁用 2锁定 | | lock_reason | VARCHAR(200) | | 锁定原因 | | login_fail_count | INT | | 连续登录失败次数 | | lock_time | DATETIME | | 锁定时间 | | created_at | DATETIME | | 创建时间 | | updated_at | DATETIME | | 更新时间 | #### user_identity(身份关联表) | 字段 | 类型 | 约束 | 说明 | |------|------|------|------| | id | BIGINT | PK, AUTO_INCREMENT | 身份ID | | user_id | BIGINT | INDEX | 关联用户ID | | identity_type | VARCHAR(20) | INDEX | 身份类型:GROWER/WORKER/BUYER/SUPPLIER | | status | TINYINT | | 状态:0正常 1禁用 | | created_at | DATETIME | | 创建时间 | #### sys_role(角色表) | 字段 | 类型 | 约束 | 说明 | |------|------|------|------| | id | BIGINT | PK, AUTO_INCREMENT | 角色ID | | role_name | VARCHAR(50) | UNIQUE | 角色名称 | | role_code | VARCHAR(50) | UNIQUE | 角色编码 | | description | VARCHAR(200) | | 角色描述 | | status | TINYINT | | 状态:0正常 1禁用 | | is_system | TINYINT | | 是否系统预置:0否 1是 | | created_at | DATETIME | | 创建时间 | #### sys_permission(权限表) | 字段 | 类型 | 约束 | 说明 | |------|------|------|------| | id | BIGINT | PK, AUTO_INCREMENT | 权限ID | | parent_id | BIGINT | | 父权限ID | | perm_name | VARCHAR(50) | | 权限名称 | | perm_code | VARCHAR(100) | UNIQUE | 权限编码 | | perm_type | VARCHAR(20) | | 类型:MENU/BUTTON | | path | VARCHAR(200) | | 菜单路径 | | icon | VARCHAR(100) | | 菜单图标 | | sort_order | INT | | 排序号 | | status | TINYINT | | 状态:0正常 1禁用 | #### sys_role_permission(角色权限关联表) | 字段 | 类型 | 约束 | 说明 | |------|------|------|------| | id | BIGINT | PK, AUTO_INCREMENT | 主键 | | role_id | BIGINT | INDEX | 角色ID | | permission_id | BIGINT | INDEX | 权限ID | #### sys_dict(字典表) | 字段 | 类型 | 约束 | 说明 | |------|------|------|------| | id | BIGINT | PK, AUTO_INCREMENT | 字典ID | | dict_type | VARCHAR(50) | INDEX | 字典类型 | | dict_code | VARCHAR(50) | UNIQUE | 字典编码 | | dict_name | VARCHAR(100) | | 字典名称 | | sort_order | INT | | 排序号 | | is_system | TINYINT | | 是否系统内置:0否 1是 | | status | TINYINT | | 状态:0正常 1禁用 | #### audit_log(审核日志表) | 字段 | 类型 | 约束 | 说明 | |------|------|------|------| | id | BIGINT | PK, AUTO_INCREMENT | 日志ID | | target_type | VARCHAR(50) | | 审核对象类型 | | target_id | BIGINT | | 审核对象ID | | operator_id | BIGINT | INDEX | 审核人ID | | action | VARCHAR(20) | | 审核动作:APPROVE/REJECT | | reason | VARCHAR(500) | | 审核原因 | | created_at | DATETIME | | 审核时间 | #### operation_log(操作日志表) | 字段 | 类型 | 约束 | 说明 | |------|------|------|------| | id | BIGINT | PK, AUTO_INCREMENT | 日志ID | | operator_id | BIGINT | INDEX | 操作人ID | | operator_name | VARCHAR(50) | | 操作人姓名 | | operation_type | VARCHAR(50) | | 操作类型 | | operation_module | VARCHAR(50) | | 操作模块 | | operation_content | VARCHAR(500) | | 操作内容 | | ip_address | VARCHAR(50) | | IP地址 | | result | TINYINT | | 操作结果:0失败 1成功 | | created_at | DATETIME | | 操作时间 | ### 2.3 索引设计 ```sql -- sys_user 表索引 CREATE UNIQUE INDEX idx_phone_hash ON sys_user(phone_hash); CREATE UNIQUE INDEX idx_openid ON sys_user(openid); CREATE INDEX idx_status ON sys_user(status); -- user_identity 表索引 CREATE INDEX idx_user_id ON user_identity(user_id); CREATE INDEX idx_identity_type ON user_identity(identity_type); -- audit_log 表索引 CREATE INDEX idx_operator_id ON audit_log(operator_id); -- operation_log 表索引 CREATE INDEX idx_operator_id ON operation_log(operator_id); ``` --- ## 三、接口设计 ### 3.1 认证接口 #### POST /api/wx/auth/login — 微信登录 **请求参数**: ```json { "code": "wx_login_code" } ``` **响应参数**: ```json { "code": 200, "message": "success", "data": { "token": "jwt_token", "userId": 1, "identities": [ { "identityId": 1, "identityType": "GROWER", "identityName": "果农" } ] } } ``` **业务逻辑**: 1. 用 code 调用微信接口换取 openid 2. 查询 openid 是否已绑定用户 3. 已绑定 → 签发 JWT token 4. 未绑定 → 返回错误码 1001(提示联系村委会) #### POST /api/admin/auth/login — 后台登录 **请求参数**: ```json { "username": "admin", "password": "admin123" } ``` **响应参数**: ```json { "code": 200, "message": "success", "data": { "token": "jwt_token", "userId": 1, "username": "admin", "realName": "管理员", "roleId": 1, "roleName": "超级管理员" } } ``` **业务逻辑**: 1. 验证用户名存在 2. 验证密码正确(BCrypt) 3. 验证账号状态 4. 签发 JWT token 5. 记录登录日志 #### POST /api/wx/auth/select-identity — 选择身份 **请求参数**: ```json { "identityId": 1 } ``` **响应参数**: ```json { "code": 200, "message": "success", "data": { "token": "new_jwt_token_with_identity" } } ``` ### 3.2 用户接口 #### GET /api/wx/user/info — 获取用户信息 **响应参数**: ```json { "code": 200, "message": "success", "data": { "userId": 1, "realName": "张三", "phone": "138****8888", "identities": [...], "currentIdentity": { "identityId": 1, "identityType": "GROWER" } } } ``` #### PUT /api/admin/user/status — 修改用户状态 **请求参数**: ```json { "userId": 1, "status": 0, "lockReason": "违规操作" } ``` ### 3.3 系统管理接口 #### GET /api/admin/role/list — 角色列表 **响应参数**: ```json { "code": 200, "message": "success", "data": { "total": 8, "list": [ { "id": 1, "roleName": "超级管理员", "roleCode": "ADMIN", "status": 0, "isSystem": 1 } ] } } ``` #### POST /api/admin/account — 创建账号 **请求参数**: ```json { "username": "newadmin", "password": "Admin123", "realName": "新管理员", "phone": "13800138000", "roleId": 2 } ``` #### GET /api/admin/dict/list — 字典列表 **请求参数**: ``` ?dictType=apple_variety ``` **响应参数**: ```json { "code": 200, "message": "success", "data": [ { "id": 1, "dictType": "apple_variety", "dictCode": "red_fuji", "dictName": "红富士", "sortOrder": 1 } ] } ``` #### GET /api/admin/operation-log/list — 操作日志列表 **请求参数**: ``` ?page=1&pageSize=10&operatorId=1&startTime=2026-05-01&endTime=2026-05-30 ``` ### 3.4 审核接口 #### GET /api/admin/audit/list — 审核列表 **请求参数**: ``` ?page=1&pageSize=10&targetType=GROWER_PROFILE&status=PENDING ``` #### PUT /api/admin/audit/{id} — 审核操作 **请求参数**: ```json { "action": "APPROVE", "reason": "" } ``` ### 3.5 首页接口 #### GET /api/wx/home/grower — 果农首页 **响应参数**: ```json { "code": 200, "message": "success", "data": { "greeting": "早安,张三!", "marketPrices": [ { "variety": "红富士", "priceMin": 3.5, "priceMax": 4.2, "trend": "up", "updateTime": "2026-05-30 08:00" } ], "quickEntries": [ {"name": "找工人", "icon": "worker", "path": "/pages/worker/list"}, {"name": "找客商", "icon": "buyer", "path": "/pages/buyer/list"}, {"name": "买农资", "icon": "supplier", "path": "/pages/supplier/list"}, {"name": "发布需求", "icon": "publish", "path": "/pages/recruit/publish"} ] } } ``` #### GET /api/wx/home/worker — 工人首页 **响应参数**: ```json { "code": 200, "message": "success", "data": { "recommendedRecruits": [ { "id": 1, "workType": "采摘", "price": 150, "priceUnit": "元/天", "days": 5, "peopleCount": 3, "growerName": "李四", "distance": 2.5 } ] } } ``` --- ## 四、安全设计 ### 4.1 认证流程 ``` 客户端请求 │ ▼ 拦截器检查 Token │ ├── 无 Token → 401 未认证 │ ├── Token 无效 → 401 未认证 │ ├── Token 过期 → 401 未认证 │ └── Token 有效 → 解析用户信息 │ ▼ 检查权限(RBAC) │ ├── 无权限 → 403 禁止访问 │ └── 有权限 → 执行业务逻辑 ``` ### 4.2 权限模型 ``` 用户 (sys_user) │ └── N:M ──→ 角色 (sys_role) │ └── N:M ──→ 权限 (sys_permission) ``` **权限检查流程**: 1. 从 Token 解析 userId 和 roleId 2. 查询角色关联的权限列表 3. 检查当前接口是否在权限列表中 4. 无权限返回 403 ### 4.3 数据安全 - **手机号**: AES 加密存储,SHA256 哈希索引 - **密码**: BCrypt 加密 - **Token**: JWT 签名,有效期控制 - **接口**: 参数校验,SQL 注入防护 - **日志**: 敏感操作记录 --- ## 五、技术选型 ### 5.1 后端技术栈 | 技术 | 版本 | 用途 | |------|------|------| | Java | 1.8 | 开发语言 | | Spring Boot | 1.5.9 | 应用框架 | | MyBatis | 1.3.2 | ORM 框架 | | MySQL | 5.7+ | 数据库 | | Redis | 3.0+ | 缓存 | | JWT (jjwt) | 0.9.1 | Token 认证 | |阿里云 OSS | 3.15.1 | 文件存储 | | 阿里云短信 | 2.1.0 | 短信服务 | | Apache POI | 3.17 | Excel 处理 | ### 5.2 前端技术栈 | 技术 | 版本 | 用途 | |------|------|------| | 微信小程序 | 基础库 ≥2.0 | 移动端 | | Vue | 2.6.14 | 后台前端框架 | | Element UI | 2.15.9 | UI 组件库 | | ECharts | 5.4.3 | 数据可视化 | | Axios | 0.27.2 | HTTP 客户端 | ### 5.3 开发工具 | 工具 | 用途 | |------|------| | Maven | 构建工具 | | Git | 版本控制 | | Gogs | 代码仓库 | | Navicat/DBeaver | 数据库客户端 | | 微信开发者工具 | 小程序开发 | --- ## 六、部署架构 ### 6.1 开发环境 ``` 本地开发机 ├── JDK 1.8 ├── Maven 3.6.3 ├── MySQL 5.7 ├── Redis 3.0 └── 微信开发者工具 ``` ### 6.2 生产环境(规划) ``` 云服务器 ├── Nginx(反向代理) ├── Spring Boot 应用(8080 端口) ├── MySQL 数据库 ├── Redis 缓存 └── 阿里云 OSS(文件存储) ``` --- ## 七、关键决策记录 ### 7.1 认证方案选择 **决策**: 采用 JWT Token 认证 **原因**: 1. 无状态,适合分布式部署 2. 小程序和后台可共用认证机制 3. 支持自定义 payload(userId, identityId, identityType) **权衡**: - Token 无法主动失效 → 采用 Redis 黑名单机制 - Token 有效期管理 → 小程序24h,后台8h ### 7.2 权限模型选择 **决策**: 采用 RBAC(Role-Based Access Control) **原因**: 1. 角色数量有限(8种),管理简单 2. 权限变更通过角色控制,影响范围可控 3. 支持细粒度权限(菜单+按钮) **权衡**: - 不支持数据级权限 → 后续可扩展 - 权限变更需重新登录 → 可优化为实时生效 ### 7.3 手机号存储方案 **决策**: AES 加密存储 + SHA256 哈希索引 **原因**: 1. 满足隐私保护要求 2. SHA256 哈希支持精确查询 3. AES 加密支持解密显示(管理后台) **权衡**: - 无法支持模糊查询 → 业务上不需要 - 哈希碰撞风险 → SHA256 碰撞概率极低