|
@@ -1,11 +1,11 @@
|
|
|
-# 阶段一架构设计 — 基础设施与用户体系
|
|
|
|
|
|
|
+# 阶段2a架构设计 — 果农核心功能
|
|
|
|
|
|
|
|
-> 基于 Team A 需求规格(spec.md)
|
|
|
|
|
-> 嵌入 Team A 关键信息
|
|
|
|
|
|
|
+> 基于 Team A 需求规格(阶段2a spec.md)
|
|
|
|
|
+> 新增模块:果农名片、招工发布、找工人、找客商、后台审核
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
-## 一、系统架构
|
|
|
|
|
|
|
+## 一、系统架构(继承阶段一 + 扩展)
|
|
|
|
|
|
|
|
### 1.1 整体架构
|
|
### 1.1 整体架构
|
|
|
|
|
|
|
@@ -31,7 +31,11 @@
|
|
|
│ 业务逻辑层 │
|
|
│ 业务逻辑层 │
|
|
|
├──────────┬──────────┬──────────┬──────────┬────────────────┤
|
|
├──────────┬──────────┬──────────┬──────────┬────────────────┤
|
|
|
│ 用户模块 │ 系统模块 │ 审核模块 │ 首页模块 │ 通用模块 │
|
|
│ 用户模块 │ 系统模块 │ 审核模块 │ 首页模块 │ 通用模块 │
|
|
|
-│ AuthService│ SysService│ AuditService│ HomeService│ CommonService│
|
|
|
|
|
|
|
+│AuthService│SysService│AuditService│HomeService│CommonService│
|
|
|
|
|
+├──────────┼──────────┼──────────┼──────────┼────────────────┤
|
|
|
|
|
+│ 果农模块 │ 招工模块 │ 搜索模块 │ 文件模块 │ 工具模块 │
|
|
|
|
|
+│GrowerSvc │RecruitSvc│SearchSvc │FileService│ DistanceUtil │
|
|
|
|
|
+│GrowerAudit│RecruitRev│CallLogSvc│ │ KeywordCheck │
|
|
|
└──────┬───┴──────┬───┴──────┬───┴──────┬───┴────────┬───────┘
|
|
└──────┬───┴──────┬───┴──────┬───┴──────┬───┴────────┬───────┘
|
|
|
│ │ │ │ │
|
|
│ │ │ │ │
|
|
|
▼ ▼ ▼ ▼ ▼
|
|
▼ ▼ ▼ ▼ ▼
|
|
@@ -45,24 +49,24 @@
|
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
|
│ 数据存储层 │
|
|
│ 数据存储层 │
|
|
|
├─────────────────────────┬───────────────────────────────────┤
|
|
├─────────────────────────┬───────────────────────────────────┤
|
|
|
-│ MySQL (crrc 库) │ Redis (缓存) │
|
|
|
|
|
-│ - 15 张业务表 │ - Token 黑名单 │
|
|
|
|
|
-│ - AES 加密字段 │ - 验证码缓存 │
|
|
|
|
|
-│ - SHA256 哈希索引 │ - 数据大屏统计 │
|
|
|
|
|
|
|
+│ MySQL (sayu 库) │ 本地文件存储 │
|
|
|
|
|
+│ - 20 张业务表 │ - ./uploads/image/ │
|
|
|
|
|
+│ - AES 加密字段 │ - ./uploads/video/ │
|
|
|
|
|
+│ - SHA256 哈希索引 │ │
|
|
|
└─────────────────────────┴───────────────────────────────────┘
|
|
└─────────────────────────┴───────────────────────────────────┘
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-### 1.2 模块划分
|
|
|
|
|
|
|
+### 1.2 阶段2a新增模块
|
|
|
|
|
|
|
|
| 模块 | 包名 | 职责 |
|
|
| 模块 | 包名 | 职责 |
|
|
|
|------|------|------|
|
|
|------|------|------|
|
|
|
-| 用户模块 | com.sayu.service | 用户认证、身份管理、权限控制 |
|
|
|
|
|
-| 系统模块 | com.sayu.service | 角色管理、账号管理、字典管理、操作日志 |
|
|
|
|
|
-| 审核模块 | com.sayu.service | 审核流程、审核列表、审核日志 |
|
|
|
|
|
-| 首页模块 | com.sayu.service | 首页数据、行情展示 |
|
|
|
|
|
-| 通用模块 | com.sayu.util | 工具类、常量、异常处理 |
|
|
|
|
|
|
|
+| 果农模块 | com.sayu.service | 果农档案CRUD、审核状态管理 |
|
|
|
|
|
+| 招工模块 | com.sayu.service | 招工发布、编辑、下架、敏感词检测 |
|
|
|
|
|
+| 搜索模块 | com.sayu.service | 工人列表、客商列表、距离计算 |
|
|
|
|
|
+| 文件模块 | com.sayu.service | 文件上传、存储、访问、删除 |
|
|
|
|
|
+| 审核模块(扩展) | com.sayu.service | 名片审核、待复核列表、SLA提醒 |
|
|
|
|
|
|
|
|
-### 1.3 分层架构
|
|
|
|
|
|
|
+### 1.3 分层架构(继承阶段一)
|
|
|
|
|
|
|
|
```
|
|
```
|
|
|
Controller 层(API 入口)
|
|
Controller 层(API 入口)
|
|
@@ -74,243 +78,285 @@ Mapper 层(数据访问)
|
|
|
Entity/DTO/VO 层(数据模型)
|
|
Entity/DTO/VO 层(数据模型)
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-**职责划分**:
|
|
|
|
|
-- **Controller**: 接收请求、参数校验、调用 Service、返回响应
|
|
|
|
|
-- **Service**: 业务逻辑、事务管理、异常处理
|
|
|
|
|
-- **Mapper**: 数据库操作、MyBatis XML 映射
|
|
|
|
|
-- **Entity**: 数据库实体,与表结构对应
|
|
|
|
|
-- **DTO**: 数据传输对象,Service 层间传递
|
|
|
|
|
-- **VO**: 视图对象,Controller 返回给前端
|
|
|
|
|
-
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
-## 二、数据库设计
|
|
|
|
|
|
|
+## 二、数据库设计(继承阶段一 + 扩展)
|
|
|
|
|
|
|
|
-### 2.1 ER 图
|
|
|
|
|
|
|
+### 2.1 ER 图(阶段2a涉及)
|
|
|
|
|
|
|
|
```
|
|
```
|
|
|
sys_user (用户基础表)
|
|
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 (操作日志)
|
|
|
|
|
|
|
+ └── 1:N ──→ user_identity (身份关联表)
|
|
|
|
|
+ │
|
|
|
|
|
+ ├── 1:1 ──→ grower_profile (果农档案) ←── 阶段2a核心
|
|
|
|
|
+ │ │
|
|
|
|
|
+ │ └── 1:N ──→ recruit_info (招工信息) ←── 阶段2a核心
|
|
|
|
|
+ │
|
|
|
|
|
+ ├── 1:1 ──→ worker_profile (工人档案)
|
|
|
|
|
+ │ │
|
|
|
|
|
+ │ └── 1:N ──→ worker_apply (工人报名)
|
|
|
|
|
+ │
|
|
|
|
|
+ └── 1:1 ──→ buyer_profile (客商档案)
|
|
|
|
|
|
|
|
-audit_log (审核日志)
|
|
|
|
|
|
|
+call_log (拨号日志) ←── 阶段2a新增使用
|
|
|
│
|
|
│
|
|
|
- └── 关联 → user_identity
|
|
|
|
|
|
|
+ ├── caller_identity_id → user_identity
|
|
|
|
|
+ └── callee_identity_id → user_identity
|
|
|
|
|
|
|
|
-sys_role (角色表)
|
|
|
|
|
|
|
+audit_log (审核日志) ←── 阶段2a扩展使用
|
|
|
│
|
|
│
|
|
|
- └── N:M ──→ sys_permission (权限表)
|
|
|
|
|
|
|
+ └── target_type = 'GROWER_PROFILE' / 'RECRUIT_REVIEW'
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-### 2.2 核心表设计
|
|
|
|
|
|
|
+### 2.2 阶段2a涉及的核心表
|
|
|
|
|
|
|
|
-#### sys_user(用户基础表)
|
|
|
|
|
|
|
+#### grower_profile(果农档案表)— 阶段2a核心
|
|
|
|
|
|
|
|
| 字段 | 类型 | 约束 | 说明 |
|
|
| 字段 | 类型 | 约束 | 说明 |
|
|
|
|------|------|------|------|
|
|
|------|------|------|------|
|
|
|
-| 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 | 主键 |
|
|
|
|
|
+| user_identity_id | BIGINT | INDEX | 关联user_identity.id |
|
|
|
|
|
+| name | VARCHAR(50) | | 姓名 |
|
|
|
|
|
+| varieties | VARCHAR(200) | | 苹果品种(JSON数组) |
|
|
|
|
|
+| yield_amount | DECIMAL(10,2) | | 产量(斤) |
|
|
|
|
|
+| expected_price | DECIMAL(8,2) | | 预期价格(元/斤) |
|
|
|
|
|
+| address | VARCHAR(200) | | 果园地址 |
|
|
|
|
|
+| latitude | DECIMAL(10,7) | INDEX | 纬度 |
|
|
|
|
|
+| longitude | DECIMAL(10,7) | INDEX | 经度 |
|
|
|
|
|
+| video_url | VARCHAR(255) | | 果园视频URL(本地存储) |
|
|
|
|
|
+| photos | TEXT | | 照片URL(JSON数组) |
|
|
|
|
|
+| audit_status | TINYINT | INDEX | 0待审 1通过 2驳回 |
|
|
|
|
|
+| audit_remark | VARCHAR(200) | | 驳回原因 |
|
|
|
|
|
+
|
|
|
|
|
+#### recruit_info(招工信息表)— 阶段2a核心
|
|
|
|
|
|
|
|
| 字段 | 类型 | 约束 | 说明 |
|
|
| 字段 | 类型 | 约束 | 说明 |
|
|
|
|------|------|------|------|
|
|
|------|------|------|------|
|
|
|
-| 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 | 主键 |
|
|
|
|
|
+| user_identity_id | BIGINT | INDEX | 发布者身份ID |
|
|
|
|
|
+| work_types | VARCHAR(100) | | 工种(JSON数组) |
|
|
|
|
|
+| price | DECIMAL(8,2) | | 价格 |
|
|
|
|
|
+| price_unit | VARCHAR(10) | | DAY/PIECE |
|
|
|
|
|
+| worker_count | INT | | 需要人数 |
|
|
|
|
|
+| days | INT | | 天数 |
|
|
|
|
|
+| location | VARCHAR(200) | | 工作地点 |
|
|
|
|
|
+| latitude | DECIMAL(10,7) | INDEX | 纬度 |
|
|
|
|
|
+| longitude | DECIMAL(10,7) | INDEX | 经度 |
|
|
|
|
|
+| remark | VARCHAR(500) | | 备注 |
|
|
|
|
|
+| status | TINYINT | INDEX | 0下架 1发布中 |
|
|
|
|
|
+| keyword_flag | TINYINT | INDEX | 0正常 1待复核 |
|
|
|
|
|
+| created_at | DATETIME | | 发布时间 |
|
|
|
|
|
+
|
|
|
|
|
+#### call_log(拨号日志表)— 阶段2a新增使用
|
|
|
|
|
|
|
|
| 字段 | 类型 | 约束 | 说明 |
|
|
| 字段 | 类型 | 约束 | 说明 |
|
|
|
|------|------|------|------|
|
|
|------|------|------|------|
|
|
|
-| 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 | | 创建时间 |
|
|
|
|
|
|
|
+| id | BIGINT | PK, AUTO_INCREMENT | 主键 |
|
|
|
|
|
+| caller_identity_id | BIGINT | INDEX | 拨号方身份ID |
|
|
|
|
|
+| callee_identity_id | BIGINT | INDEX | 被拨方身份ID |
|
|
|
|
|
+| call_time | DATETIME | | 拨号时间 |
|
|
|
|
|
|
|
|
-#### sys_permission(权限表)
|
|
|
|
|
|
|
+### 2.3 索引设计(阶段2a新增)
|
|
|
|
|
|
|
|
-| 字段 | 类型 | 约束 | 说明 |
|
|
|
|
|
-|------|------|------|------|
|
|
|
|
|
-| 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(角色权限关联表)
|
|
|
|
|
|
|
+```sql
|
|
|
|
|
+-- grower_profile 表索引
|
|
|
|
|
+CREATE INDEX idx_user_identity_id ON grower_profile(user_identity_id);
|
|
|
|
|
+CREATE INDEX idx_audit_status ON grower_profile(audit_status);
|
|
|
|
|
+CREATE INDEX idx_lat_lng ON grower_profile(latitude, longitude);
|
|
|
|
|
|
|
|
-| 字段 | 类型 | 约束 | 说明 |
|
|
|
|
|
-|------|------|------|------|
|
|
|
|
|
-| id | BIGINT | PK, AUTO_INCREMENT | 主键 |
|
|
|
|
|
-| role_id | BIGINT | INDEX | 角色ID |
|
|
|
|
|
-| permission_id | BIGINT | INDEX | 权限ID |
|
|
|
|
|
|
|
+-- recruit_info 表索引
|
|
|
|
|
+CREATE INDEX idx_user_identity_id ON recruit_info(user_identity_id);
|
|
|
|
|
+CREATE INDEX idx_status ON recruit_info(status);
|
|
|
|
|
+CREATE INDEX idx_keyword_flag ON recruit_info(keyword_flag);
|
|
|
|
|
+CREATE INDEX idx_lat_lng ON recruit_info(latitude, longitude);
|
|
|
|
|
|
|
|
-#### sys_dict(字典表)
|
|
|
|
|
|
|
+-- call_log 表索引
|
|
|
|
|
+CREATE INDEX idx_caller ON call_log(caller_identity_id);
|
|
|
|
|
+CREATE INDEX idx_callee ON call_log(callee_identity_id);
|
|
|
|
|
+```
|
|
|
|
|
|
|
|
-| 字段 | 类型 | 约束 | 说明 |
|
|
|
|
|
-|------|------|------|------|
|
|
|
|
|
-| 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(审核日志表)
|
|
|
|
|
|
|
+## 三、接口设计(阶段2a新增)
|
|
|
|
|
|
|
|
-| 字段 | 类型 | 约束 | 说明 |
|
|
|
|
|
-|------|------|------|------|
|
|
|
|
|
-| 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 | | 审核时间 |
|
|
|
|
|
|
|
+### 3.1 果农名片接口
|
|
|
|
|
|
|
|
-#### operation_log(操作日志表)
|
|
|
|
|
|
|
+#### GET /api/wx/grower/profile — 获取果农档案
|
|
|
|
|
|
|
|
-| 字段 | 类型 | 约束 | 说明 |
|
|
|
|
|
-|------|------|------|------|
|
|
|
|
|
-| 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);
|
|
|
|
|
|
|
+**请求头**: `Authorization: Bearer {token}`
|
|
|
|
|
|
|
|
--- user_identity 表索引
|
|
|
|
|
-CREATE INDEX idx_user_id ON user_identity(user_id);
|
|
|
|
|
-CREATE INDEX idx_identity_type ON user_identity(identity_type);
|
|
|
|
|
|
|
+**响应参数**:
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "code": 200,
|
|
|
|
|
+ "message": "success",
|
|
|
|
|
+ "data": {
|
|
|
|
|
+ "id": 1,
|
|
|
|
|
+ "name": "张三",
|
|
|
|
|
+ "varieties": ["红富士", "嘎啦"],
|
|
|
|
|
+ "yieldAmount": 50000,
|
|
|
|
|
+ "expectedPrice": 4.0,
|
|
|
|
|
+ "address": "洒渔镇黄兴村",
|
|
|
|
|
+ "latitude": 27.3331,
|
|
|
|
|
+ "longitude": 103.7168,
|
|
|
|
|
+ "videoUrl": "http://localhost:8080/files/video/abc.mp4",
|
|
|
|
|
+ "photos": ["http://localhost:8080/files/image/1.jpg"],
|
|
|
|
|
+ "auditStatus": 0,
|
|
|
|
|
+ "auditRemark": null
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
|
|
|
--- audit_log 表索引
|
|
|
|
|
-CREATE INDEX idx_operator_id ON audit_log(operator_id);
|
|
|
|
|
|
|
+#### PUT /api/wx/grower/profile — 更新果农档案
|
|
|
|
|
|
|
|
--- operation_log 表索引
|
|
|
|
|
-CREATE INDEX idx_operator_id ON operation_log(operator_id);
|
|
|
|
|
|
|
+**描述**: 更新果农名片信息,审核状态重置为待审
|
|
|
|
|
+
|
|
|
|
|
+**请求参数**:
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "name": "张三",
|
|
|
|
|
+ "varieties": ["红富士", "嘎啦"],
|
|
|
|
|
+ "yieldAmount": 50000,
|
|
|
|
|
+ "expectedPrice": 4.0,
|
|
|
|
|
+ "address": "洒渔镇黄兴村",
|
|
|
|
|
+ "latitude": 27.3331,
|
|
|
|
|
+ "longitude": 103.7168,
|
|
|
|
|
+ "videoUrl": "http://localhost:8080/files/video/abc.mp4",
|
|
|
|
|
+ "photos": ["http://localhost:8080/files/image/1.jpg"]
|
|
|
|
|
+}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
+**业务逻辑**:
|
|
|
|
|
+1. 验证必填字段
|
|
|
|
|
+2. 更新 grower_profile
|
|
|
|
|
+3. 重置 audit_status=0,清空 audit_remark
|
|
|
|
|
+
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
-## 三、接口设计
|
|
|
|
|
|
|
+### 3.2 招工接口
|
|
|
|
|
|
|
|
-### 3.1 认证接口
|
|
|
|
|
|
|
+#### POST /api/wx/grower/recruit — 发布招工
|
|
|
|
|
|
|
|
-#### POST /api/wx/auth/login — 微信登录
|
|
|
|
|
|
|
+**描述**: 发布招工信息,免审核直接发布
|
|
|
|
|
|
|
|
**请求参数**:
|
|
**请求参数**:
|
|
|
```json
|
|
```json
|
|
|
{
|
|
{
|
|
|
- "code": "wx_login_code"
|
|
|
|
|
|
|
+ "workTypes": ["采摘工", "分拣工"],
|
|
|
|
|
+ "price": 150,
|
|
|
|
|
+ "priceUnit": "DAY",
|
|
|
|
|
+ "workerCount": 3,
|
|
|
|
|
+ "days": 5,
|
|
|
|
|
+ "location": "洒渔镇黄兴村",
|
|
|
|
|
+ "latitude": 27.3331,
|
|
|
|
|
+ "longitude": 103.7168,
|
|
|
|
|
+ "remark": "需要有经验的采摘工"
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
+**业务逻辑**:
|
|
|
|
|
+1. 验证必填字段(workTypes、price、priceUnit、workerCount、location)
|
|
|
|
|
+2. 敏感词检测(keyword_flag)
|
|
|
|
|
+3. 创建 recruit_info(status=1,免审核)
|
|
|
|
|
+
|
|
|
|
|
+#### GET /api/wx/grower/recruit — 我的招工列表
|
|
|
|
|
+
|
|
|
|
|
+**请求参数**: `?page=1&pageSize=20`
|
|
|
|
|
+
|
|
|
**响应参数**:
|
|
**响应参数**:
|
|
|
```json
|
|
```json
|
|
|
{
|
|
{
|
|
|
"code": 200,
|
|
"code": 200,
|
|
|
"message": "success",
|
|
"message": "success",
|
|
|
"data": {
|
|
"data": {
|
|
|
- "token": "jwt_token",
|
|
|
|
|
- "userId": 1,
|
|
|
|
|
- "identities": [
|
|
|
|
|
|
|
+ "total": 5,
|
|
|
|
|
+ "page": 1,
|
|
|
|
|
+ "pageSize": 20,
|
|
|
|
|
+ "list": [
|
|
|
{
|
|
{
|
|
|
- "identityId": 1,
|
|
|
|
|
- "identityType": "GROWER",
|
|
|
|
|
- "identityName": "果农"
|
|
|
|
|
|
|
+ "id": 1,
|
|
|
|
|
+ "workTypes": ["采摘工"],
|
|
|
|
|
+ "price": 150,
|
|
|
|
|
+ "priceUnit": "DAY",
|
|
|
|
|
+ "workerCount": 3,
|
|
|
|
|
+ "days": 5,
|
|
|
|
|
+ "location": "洒渔镇黄兴村",
|
|
|
|
|
+ "status": 1,
|
|
|
|
|
+ "keywordFlag": 0,
|
|
|
|
|
+ "applyCount": 2,
|
|
|
|
|
+ "createdAt": "2026-05-30 10:00"
|
|
|
}
|
|
}
|
|
|
]
|
|
]
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-**业务逻辑**:
|
|
|
|
|
-1. 用 code 调用微信接口换取 openid
|
|
|
|
|
-2. 查询 openid 是否已绑定用户
|
|
|
|
|
-3. 已绑定 → 签发 JWT token
|
|
|
|
|
-4. 未绑定 → 返回错误码 1001(提示联系村委会)
|
|
|
|
|
-
|
|
|
|
|
-#### POST /api/admin/auth/login — 后台登录
|
|
|
|
|
|
|
+#### PUT /api/wx/grower/recruit/{id} — 编辑招工
|
|
|
|
|
|
|
|
**请求参数**:
|
|
**请求参数**:
|
|
|
```json
|
|
```json
|
|
|
{
|
|
{
|
|
|
- "username": "admin",
|
|
|
|
|
- "password": "admin123"
|
|
|
|
|
|
|
+ "price": 180,
|
|
|
|
|
+ "workerCount": 5,
|
|
|
|
|
+ "remark": "价格上调,急招"
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
+**业务逻辑**:
|
|
|
|
|
+1. 验证招工存在且属于当前用户
|
|
|
|
|
+2. 更新可编辑字段
|
|
|
|
|
+3. 重新触发敏感词检测
|
|
|
|
|
+
|
|
|
|
|
+#### DELETE /api/wx/grower/recruit/{id} — 下架招工
|
|
|
|
|
+
|
|
|
|
|
+**业务逻辑**:
|
|
|
|
|
+1. 验证招工存在且属于当前用户
|
|
|
|
|
+2. 更新 status=0(逻辑删除)
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### 3.3 找工人/客商接口
|
|
|
|
|
+
|
|
|
|
|
+#### GET /api/wx/grower/workers — 工人列表
|
|
|
|
|
+
|
|
|
|
|
+**请求参数**: `?workType=采摘工&page=1&pageSize=20`
|
|
|
|
|
+
|
|
|
**响应参数**:
|
|
**响应参数**:
|
|
|
```json
|
|
```json
|
|
|
{
|
|
{
|
|
|
"code": 200,
|
|
"code": 200,
|
|
|
"message": "success",
|
|
"message": "success",
|
|
|
"data": {
|
|
"data": {
|
|
|
- "token": "jwt_token",
|
|
|
|
|
- "userId": 1,
|
|
|
|
|
- "username": "admin",
|
|
|
|
|
- "realName": "管理员",
|
|
|
|
|
- "roleId": 1,
|
|
|
|
|
- "roleName": "超级管理员"
|
|
|
|
|
|
|
+ "total": 10,
|
|
|
|
|
+ "page": 1,
|
|
|
|
|
+ "pageSize": 20,
|
|
|
|
|
+ "list": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "identityId": 5,
|
|
|
|
|
+ "name": "李四",
|
|
|
|
|
+ "skills": ["采摘工", "分拣工"],
|
|
|
|
|
+ "price": 150,
|
|
|
|
|
+ "priceUnit": "DAY",
|
|
|
|
|
+ "status": 1,
|
|
|
|
|
+ "distance": 2.5
|
|
|
|
|
+ }
|
|
|
|
|
+ ]
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
**业务逻辑**:
|
|
**业务逻辑**:
|
|
|
-1. 验证用户名存在
|
|
|
|
|
-2. 验证密码正确(BCrypt)
|
|
|
|
|
-3. 验证账号状态
|
|
|
|
|
-4. 签发 JWT token
|
|
|
|
|
-5. 记录登录日志
|
|
|
|
|
|
|
+1. 查询 status=1(空闲)的工人
|
|
|
|
|
+2. 可选按工种筛选(skills JSON字段 LIKE 查询)
|
|
|
|
|
+3. 计算距离(Haversine公式)
|
|
|
|
|
+4. 按距离升序排序
|
|
|
|
|
|
|
|
-#### POST /api/wx/auth/select-identity — 选择身份
|
|
|
|
|
|
|
+#### GET /api/wx/grower/buyers — 客商列表
|
|
|
|
|
|
|
|
-**请求参数**:
|
|
|
|
|
-```json
|
|
|
|
|
-{
|
|
|
|
|
- "identityId": 1
|
|
|
|
|
-}
|
|
|
|
|
-```
|
|
|
|
|
|
|
+**请求参数**: `?page=1&pageSize=20`
|
|
|
|
|
|
|
|
**响应参数**:
|
|
**响应参数**:
|
|
|
```json
|
|
```json
|
|
@@ -318,14 +364,38 @@ CREATE INDEX idx_operator_id ON operation_log(operator_id);
|
|
|
"code": 200,
|
|
"code": 200,
|
|
|
"message": "success",
|
|
"message": "success",
|
|
|
"data": {
|
|
"data": {
|
|
|
- "token": "new_jwt_token_with_identity"
|
|
|
|
|
|
|
+ "total": 5,
|
|
|
|
|
+ "page": 1,
|
|
|
|
|
+ "pageSize": 20,
|
|
|
|
|
+ "list": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "identityId": 10,
|
|
|
|
|
+ "name": "王五果业",
|
|
|
|
|
+ "varieties": ["红富士", "嘎啦"],
|
|
|
|
|
+ "priceRange": "3.5-4.5",
|
|
|
|
|
+ "totalAmount": 100000,
|
|
|
|
|
+ "standards": "果径≥80mm",
|
|
|
|
|
+ "address": "昭通市水果批发市场"
|
|
|
|
|
+ }
|
|
|
|
|
+ ]
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-### 3.2 用户接口
|
|
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### 3.4 拨号接口
|
|
|
|
|
+
|
|
|
|
|
+#### POST /api/wx/call/phone — 拨号接口
|
|
|
|
|
|
|
|
-#### GET /api/wx/user/info — 获取用户信息
|
|
|
|
|
|
|
+**描述**: 获取对方手机号并记录拨号日志
|
|
|
|
|
+
|
|
|
|
|
+**请求参数**:
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "calleeIdentityId": 5
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
|
|
|
**响应参数**:
|
|
**响应参数**:
|
|
|
```json
|
|
```json
|
|
@@ -333,32 +403,24 @@ CREATE INDEX idx_operator_id ON operation_log(operator_id);
|
|
|
"code": 200,
|
|
"code": 200,
|
|
|
"message": "success",
|
|
"message": "success",
|
|
|
"data": {
|
|
"data": {
|
|
|
- "userId": 1,
|
|
|
|
|
- "realName": "张三",
|
|
|
|
|
"phone": "138****8888",
|
|
"phone": "138****8888",
|
|
|
- "identities": [...],
|
|
|
|
|
- "currentIdentity": {
|
|
|
|
|
- "identityId": 1,
|
|
|
|
|
- "identityType": "GROWER"
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ "realPhone": "13800138000"
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-#### PUT /api/admin/user/status — 修改用户状态
|
|
|
|
|
|
|
+**业务逻辑**:
|
|
|
|
|
+1. 验证被拨方存在
|
|
|
|
|
+2. 记录拨号日志(call_log)
|
|
|
|
|
+3. 返回脱敏手机号给前端显示,真实手机号用于拨号
|
|
|
|
|
|
|
|
-**请求参数**:
|
|
|
|
|
-```json
|
|
|
|
|
-{
|
|
|
|
|
- "userId": 1,
|
|
|
|
|
- "status": 0,
|
|
|
|
|
- "lockReason": "违规操作"
|
|
|
|
|
-}
|
|
|
|
|
-```
|
|
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+### 3.5 后台审核接口
|
|
|
|
|
|
|
|
-### 3.3 系统管理接口
|
|
|
|
|
|
|
+#### GET /api/admin/audit/grower-profile — 名片审核列表
|
|
|
|
|
|
|
|
-#### GET /api/admin/role/list — 角色列表
|
|
|
|
|
|
|
+**请求参数**: `?page=1&pageSize=10&status=0`
|
|
|
|
|
|
|
|
**响应参数**:
|
|
**响应参数**:
|
|
|
```json
|
|
```json
|
|
@@ -366,86 +428,52 @@ CREATE INDEX idx_operator_id ON operation_log(operator_id);
|
|
|
"code": 200,
|
|
"code": 200,
|
|
|
"message": "success",
|
|
"message": "success",
|
|
|
"data": {
|
|
"data": {
|
|
|
- "total": 8,
|
|
|
|
|
|
|
+ "total": 3,
|
|
|
|
|
+ "page": 1,
|
|
|
|
|
+ "pageSize": 10,
|
|
|
"list": [
|
|
"list": [
|
|
|
{
|
|
{
|
|
|
"id": 1,
|
|
"id": 1,
|
|
|
- "roleName": "超级管理员",
|
|
|
|
|
- "roleCode": "ADMIN",
|
|
|
|
|
- "status": 0,
|
|
|
|
|
- "isSystem": 1
|
|
|
|
|
|
|
+ "growerName": "张三",
|
|
|
|
|
+ "varieties": ["红富士"],
|
|
|
|
|
+ "yieldAmount": 50000,
|
|
|
|
|
+ "videoUrl": "...",
|
|
|
|
|
+ "photos": ["..."],
|
|
|
|
|
+ "auditStatus": 0,
|
|
|
|
|
+ "createdAt": "2026-05-30 10:00"
|
|
|
}
|
|
}
|
|
|
]
|
|
]
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-#### POST /api/admin/account — 创建账号
|
|
|
|
|
|
|
+#### PUT /api/admin/audit/grower-profile/{id} — 名片审核操作
|
|
|
|
|
|
|
|
**请求参数**:
|
|
**请求参数**:
|
|
|
```json
|
|
```json
|
|
|
{
|
|
{
|
|
|
- "username": "newadmin",
|
|
|
|
|
- "password": "Admin123",
|
|
|
|
|
- "realName": "新管理员",
|
|
|
|
|
- "phone": "13800138000",
|
|
|
|
|
- "roleId": 2
|
|
|
|
|
|
|
+ "action": "APPROVE",
|
|
|
|
|
+ "reason": ""
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-#### GET /api/admin/dict/list — 字典列表
|
|
|
|
|
-
|
|
|
|
|
-**请求参数**:
|
|
|
|
|
-```
|
|
|
|
|
-?dictType=apple_variety
|
|
|
|
|
-```
|
|
|
|
|
-
|
|
|
|
|
-**响应参数**:
|
|
|
|
|
|
|
+或驳回:
|
|
|
```json
|
|
```json
|
|
|
{
|
|
{
|
|
|
- "code": 200,
|
|
|
|
|
- "message": "success",
|
|
|
|
|
- "data": [
|
|
|
|
|
- {
|
|
|
|
|
- "id": 1,
|
|
|
|
|
- "dictType": "apple_variety",
|
|
|
|
|
- "dictCode": "red_fuji",
|
|
|
|
|
- "dictName": "红富士",
|
|
|
|
|
- "sortOrder": 1
|
|
|
|
|
- }
|
|
|
|
|
- ]
|
|
|
|
|
|
|
+ "action": "REJECT",
|
|
|
|
|
+ "reason": "视频内容不清晰,请重新上传"
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-#### 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": ""
|
|
|
|
|
-}
|
|
|
|
|
-```
|
|
|
|
|
|
|
+**业务逻辑**:
|
|
|
|
|
+1. 验证审核记录存在
|
|
|
|
|
+2. 驳回时 reason 不能为空
|
|
|
|
|
+3. 更新 grower_profile.audit_status
|
|
|
|
|
+4. 记录审核日志(audit_log)
|
|
|
|
|
|
|
|
-### 3.5 首页接口
|
|
|
|
|
|
|
+#### GET /api/admin/audit/recruit-review — 待复核招工列表
|
|
|
|
|
|
|
|
-#### GET /api/wx/home/grower — 果农首页
|
|
|
|
|
|
|
+**请求参数**: `?page=1&pageSize=10`
|
|
|
|
|
|
|
|
**响应参数**:
|
|
**响应参数**:
|
|
|
```json
|
|
```json
|
|
@@ -453,205 +481,171 @@ CREATE INDEX idx_operator_id ON operation_log(operator_id);
|
|
|
"code": 200,
|
|
"code": 200,
|
|
|
"message": "success",
|
|
"message": "success",
|
|
|
"data": {
|
|
"data": {
|
|
|
- "greeting": "早安,张三!",
|
|
|
|
|
- "marketPrices": [
|
|
|
|
|
|
|
+ "total": 2,
|
|
|
|
|
+ "list": [
|
|
|
{
|
|
{
|
|
|
- "variety": "红富士",
|
|
|
|
|
- "priceMin": 3.5,
|
|
|
|
|
- "priceMax": 4.2,
|
|
|
|
|
- "trend": "up",
|
|
|
|
|
- "updateTime": "2026-05-30 08:00"
|
|
|
|
|
|
|
+ "id": 1,
|
|
|
|
|
+ "workTypes": ["采摘工"],
|
|
|
|
|
+ "remark": "日薪300元,...",
|
|
|
|
|
+ "keywordFlag": 1,
|
|
|
|
|
+ "publisherName": "张三",
|
|
|
|
|
+ "createdAt": "2026-05-30 10: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 — 工人首页
|
|
|
|
|
|
|
+#### PUT /api/admin/audit/recruit-review/{id} — 待复核操作
|
|
|
|
|
|
|
|
-**响应参数**:
|
|
|
|
|
|
|
+**请求参数**:
|
|
|
```json
|
|
```json
|
|
|
{
|
|
{
|
|
|
- "code": 200,
|
|
|
|
|
- "message": "success",
|
|
|
|
|
- "data": {
|
|
|
|
|
- "recommendedRecruits": [
|
|
|
|
|
- {
|
|
|
|
|
- "id": 1,
|
|
|
|
|
- "workType": "采摘",
|
|
|
|
|
- "price": 150,
|
|
|
|
|
- "priceUnit": "元/天",
|
|
|
|
|
- "days": 5,
|
|
|
|
|
- "peopleCount": 3,
|
|
|
|
|
- "growerName": "李四",
|
|
|
|
|
- "distance": 2.5
|
|
|
|
|
- }
|
|
|
|
|
- ]
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ "action": "NORMAL",
|
|
|
|
|
+ "reason": ""
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
----
|
|
|
|
|
-
|
|
|
|
|
-## 四、安全设计
|
|
|
|
|
-
|
|
|
|
|
-### 4.1 认证流程
|
|
|
|
|
-
|
|
|
|
|
-```
|
|
|
|
|
-客户端请求
|
|
|
|
|
- │
|
|
|
|
|
- ▼
|
|
|
|
|
-拦截器检查 Token
|
|
|
|
|
- │
|
|
|
|
|
- ├── 无 Token → 401 未认证
|
|
|
|
|
- │
|
|
|
|
|
- ├── Token 无效 → 401 未认证
|
|
|
|
|
- │
|
|
|
|
|
- ├── Token 过期 → 401 未认证
|
|
|
|
|
- │
|
|
|
|
|
- └── Token 有效 → 解析用户信息
|
|
|
|
|
- │
|
|
|
|
|
- ▼
|
|
|
|
|
- 检查权限(RBAC)
|
|
|
|
|
- │
|
|
|
|
|
- ├── 无权限 → 403 禁止访问
|
|
|
|
|
- │
|
|
|
|
|
- └── 有权限 → 执行业务逻辑
|
|
|
|
|
-```
|
|
|
|
|
-
|
|
|
|
|
-### 4.2 权限模型
|
|
|
|
|
-
|
|
|
|
|
-```
|
|
|
|
|
-用户 (sys_user)
|
|
|
|
|
- │
|
|
|
|
|
- └── N:M ──→ 角色 (sys_role)
|
|
|
|
|
- │
|
|
|
|
|
- └── N:M ──→ 权限 (sys_permission)
|
|
|
|
|
|
|
+或强制下架:
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "action": "FORCE_OFFLINE",
|
|
|
|
|
+ "reason": "内容违规"
|
|
|
|
|
+}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-**权限检查流程**:
|
|
|
|
|
-1. 从 Token 解析 userId 和 roleId
|
|
|
|
|
-2. 查询角色关联的权限列表
|
|
|
|
|
-3. 检查当前接口是否在权限列表中
|
|
|
|
|
-4. 无权限返回 403
|
|
|
|
|
-
|
|
|
|
|
-### 4.3 数据安全
|
|
|
|
|
-
|
|
|
|
|
-- **手机号**: AES 加密存储,SHA256 哈希索引
|
|
|
|
|
-- **密码**: BCrypt 加密
|
|
|
|
|
-- **Token**: JWT 签名,有效期控制
|
|
|
|
|
-- **接口**: 参数校验,SQL 注入防护
|
|
|
|
|
-- **日志**: 敏感操作记录
|
|
|
|
|
|
|
+**业务逻辑**:
|
|
|
|
|
+1. 验证招工存在
|
|
|
|
|
+2. NORMAL → keyword_flag=0
|
|
|
|
|
+3. FORCE_OFFLINE → status=0,记录原因
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
-## 五、技术选型
|
|
|
|
|
|
|
+## 四、安全设计(继承阶段一 + 扩展)
|
|
|
|
|
|
|
|
-### 5.1 后端技术栈
|
|
|
|
|
|
|
+### 4.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 | 数据库客户端 |
|
|
|
|
|
-| 微信开发者工具 | 小程序开发 |
|
|
|
|
|
-
|
|
|
|
|
----
|
|
|
|
|
|
|
+```
|
|
|
|
|
+前端上传 → 格式白名单校验 → 大小限制 → 存储到本地目录
|
|
|
|
|
+ │
|
|
|
|
|
+ ▼
|
|
|
|
|
+ 返回文件URL
|
|
|
|
|
+```
|
|
|
|
|
|
|
|
-## 六、部署架构
|
|
|
|
|
|
|
+- **格式白名单**: 图片(jpg,jpeg,png,gif)、视频(mp4,mov,avi)
|
|
|
|
|
+- **大小限制**: 图片≤5MB,视频≤50MB
|
|
|
|
|
+- **EXIF清除**: 前端责任,后端不二次处理(性能考虑)
|
|
|
|
|
+- **路径安全**: 文件名使用UUID,防止路径穿越
|
|
|
|
|
|
|
|
-### 6.1 开发环境
|
|
|
|
|
|
|
+### 4.2 内容安全
|
|
|
|
|
|
|
|
```
|
|
```
|
|
|
-本地开发机
|
|
|
|
|
-├── JDK 1.8
|
|
|
|
|
-├── Maven 3.6.3
|
|
|
|
|
-├── MySQL 5.7
|
|
|
|
|
-├── Redis 3.0
|
|
|
|
|
-└── 微信开发者工具
|
|
|
|
|
|
|
+招工发布 → 敏感词检测 → keyword_flag 标记 → 不阻塞发布
|
|
|
|
|
+ │
|
|
|
|
|
+ ▼
|
|
|
|
|
+ 待复核列表
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-### 6.2 生产环境(规划)
|
|
|
|
|
|
|
+- **敏感词库**: 初始硬编码,仅含明确违规词
|
|
|
|
|
+- **检测方式**: 正则匹配
|
|
|
|
|
+- **处理方式**: keyword_flag=1 进入待复核,不阻塞发布
|
|
|
|
|
+
|
|
|
|
|
+### 4.3 拨号安全
|
|
|
|
|
|
|
|
```
|
|
```
|
|
|
-云服务器
|
|
|
|
|
-├── Nginx(反向代理)
|
|
|
|
|
-├── Spring Boot 应用(8080 端口)
|
|
|
|
|
-├── MySQL 数据库
|
|
|
|
|
-├── Redis 缓存
|
|
|
|
|
-└── 阿里云 OSS(文件存储)
|
|
|
|
|
|
|
+拨号请求 → 记录拨号日志 → 返回脱敏手机号 → 前端拨号
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
+- **日志记录**: 拨号方ID、被拨方ID、时间
|
|
|
|
|
+- **数据脱敏**: 列表不返回手机号,拨号接口单独获取
|
|
|
|
|
+
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
-## 七、关键决策记录
|
|
|
|
|
|
|
+## 五、关键技术方案
|
|
|
|
|
|
|
|
-### 7.1 认证方案选择
|
|
|
|
|
|
|
+### 5.1 距离计算(Haversine公式)
|
|
|
|
|
|
|
|
-**决策**: 采用 JWT Token 认证
|
|
|
|
|
|
|
+```java
|
|
|
|
|
+public class DistanceUtil {
|
|
|
|
|
+ private static final double EARTH_RADIUS = 6371; // 地球半径(km)
|
|
|
|
|
|
|
|
-**原因**:
|
|
|
|
|
-1. 无状态,适合分布式部署
|
|
|
|
|
-2. 小程序和后台可共用认证机制
|
|
|
|
|
-3. 支持自定义 payload(userId, identityId, identityType)
|
|
|
|
|
|
|
+ public static double calculate(double lat1, double lng1, double lat2, double lng2) {
|
|
|
|
|
+ double dLat = Math.toRadians(lat2 - lat1);
|
|
|
|
|
+ double dLng = Math.toRadians(lng2 - lng1);
|
|
|
|
|
+ double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
|
|
|
|
|
+ Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
|
|
|
|
|
+ Math.sin(dLng / 2) * Math.sin(dLng / 2);
|
|
|
|
|
+ double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|
|
|
|
+ return EARTH_RADIUS * c;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
|
|
|
-**权衡**:
|
|
|
|
|
-- Token 无法主动失效 → 采用 Redis 黑名单机制
|
|
|
|
|
-- Token 有效期管理 → 小程序24h,后台8h
|
|
|
|
|
|
|
+**说明**:
|
|
|
|
|
+- 输入:两个经纬度点(DECIMAL(10,7))
|
|
|
|
|
+- 输出:距离(km,保留1位小数)
|
|
|
|
|
+- 精度:小数点后7位,误差≤1米
|
|
|
|
|
|
|
|
-### 7.2 权限模型选择
|
|
|
|
|
|
|
+### 5.2 敏感词检测
|
|
|
|
|
|
|
|
-**决策**: 采用 RBAC(Role-Based Access Control)
|
|
|
|
|
|
|
+```java
|
|
|
|
|
+public class KeywordCheckService {
|
|
|
|
|
+ // 初始敏感词库(硬编码)
|
|
|
|
|
+ private static final List<String> KEYWORDS = Arrays.asList(
|
|
|
|
|
+ // 仅含明确违规词,不含正常业务词汇
|
|
|
|
|
+ );
|
|
|
|
|
|
|
|
-**原因**:
|
|
|
|
|
-1. 角色数量有限(8种),管理简单
|
|
|
|
|
-2. 权限变更通过角色控制,影响范围可控
|
|
|
|
|
-3. 支持细粒度权限(菜单+按钮)
|
|
|
|
|
|
|
+ public boolean containsSensitiveWord(String text) {
|
|
|
|
|
+ if (text == null) return false;
|
|
|
|
|
+ for (String keyword : KEYWORDS) {
|
|
|
|
|
+ if (text.contains(keyword)) return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
|
|
|
-**权衡**:
|
|
|
|
|
-- 不支持数据级权限 → 后续可扩展
|
|
|
|
|
-- 权限变更需重新登录 → 可优化为实时生效
|
|
|
|
|
|
|
+### 5.3 视频压缩(异步)
|
|
|
|
|
|
|
|
-### 7.3 手机号存储方案
|
|
|
|
|
|
|
+```java
|
|
|
|
|
+@Service
|
|
|
|
|
+public class VideoCompressService {
|
|
|
|
|
+ @Async
|
|
|
|
|
+ public void compressVideo(String inputPath, String outputPath) {
|
|
|
|
|
+ // FFmpeg 命令:720p,码率2Mbps
|
|
|
|
|
+ // ffmpeg -i input.mp4 -vf scale=-1:720 -b:v 2M output.mp4
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
|
|
|
-**决策**: AES 加密存储 + SHA256 哈希索引
|
|
|
|
|
|
|
+**约束**:
|
|
|
|
|
+- 异步执行,不影响用户操作
|
|
|
|
|
+- 失败自动重试3次
|
|
|
|
|
+- 压缩后替换原文件
|
|
|
|
|
|
|
|
-**原因**:
|
|
|
|
|
-1. 满足隐私保护要求
|
|
|
|
|
-2. SHA256 哈希支持精确查询
|
|
|
|
|
-3. AES 加密支持解密显示(管理后台)
|
|
|
|
|
|
|
+---
|
|
|
|
|
|
|
|
-**权衡**:
|
|
|
|
|
-- 无法支持模糊查询 → 业务上不需要
|
|
|
|
|
-- 哈希碰撞风险 → SHA256 碰撞概率极低
|
|
|
|
|
|
|
+## 六、阶段2a新增文件清单
|
|
|
|
|
+
|
|
|
|
|
+| 文件 | 说明 |
|
|
|
|
|
+|------|------|
|
|
|
|
|
+| GrowerProfileController.java | 果农档案API |
|
|
|
|
|
+| GrowerProfileService.java | 果农档案业务逻辑 |
|
|
|
|
|
+| GrowerProfileMapper.xml | 果农档案MyBatis映射 |
|
|
|
|
|
+| RecruitController.java | 招工CRUD API |
|
|
|
|
|
+| RecruitService.java | 招工业务逻辑 |
|
|
|
|
|
+| RecruitMapper.xml | 招工MyBatis映射 |
|
|
|
|
|
+| WorkerSearchController.java | 工人列表API |
|
|
|
|
|
+| WorkerSearchService.java | 工人搜索业务逻辑 |
|
|
|
|
|
+| BuyerSearchController.java | 客商列表API |
|
|
|
|
|
+| BuyerSearchService.java | 客商搜索业务逻辑 |
|
|
|
|
|
+| CallPhoneController.java | 拨号API |
|
|
|
|
|
+| CallLogService.java | 拨号日志业务逻辑 |
|
|
|
|
|
+| CallLogMapper.xml | 拨号日志MyBatis映射 |
|
|
|
|
|
+| GrowerAuditController.java | 名片审核API |
|
|
|
|
|
+| GrowerAuditService.java | 名片审核业务逻辑 |
|
|
|
|
|
+| RecruitReviewController.java | 待复核API |
|
|
|
|
|
+| RecruitReviewService.java | 待复核业务逻辑 |
|
|
|
|
|
+| KeywordCheckService.java | 敏感词检测服务 |
|
|
|
|
|
+| DistanceUtil.java | 距离计算工具类 |
|
|
|
|
|
+| VideoCompressService.java | 视频压缩服务 |
|