22 KiB
22 KiB
随工水印相机 2.0 需求文档
项目背景
当前系统存在以下问题:
- 服务器配置较低(2H4G 6M带宽),无法支撑大量图片上传和下载
- 图片存储在服务器本地,占用服务器磁盘和带宽资源
- Excel 导出功能在服务器端执行,大量图片嵌入时会占用大量内存和带宽
优化目标
- 将图片存储迁移到腾讯云 COS,释放服务器带宽和存储压力
- 开发 CS 客户端,将 Excel 导出功能移至客户端本地执行
- 保持现有的目录分类结构,方便用户直接在 COS 打包下载
模块一:图片上传改造
1.1 功能描述
将图片上传方式从"上传到服务器"改为"客户端直传腾讯云 COS"。
1.2 业务流程
┌─────────┐ 1.请求上传签名 ┌─────────┐
│ 前端 │ ──────────────────▶ │ 服务器 │
│ UniApp │ ◀────────────────── │ .NET │
└─────────┘ 2.返回预签名URL └─────────┘
│
│ 3.直接上传图片(PUT)
▼
┌─────────┐
│ 腾讯云 │
│ COS │
└─────────┘
│
│ 4.上传成功,前端回调服务器保存记录
▼
┌─────────┐
│ 服务器 │
└─────────┘
1.3 COS 目录结构
保持现有分类结构,便于用户直接打包下载:
/workfiles/{yyyyMM}/{yyyyMMdd}/
├── 当日照片/{图片文件名}.jpg
├── 参与人员/{人员姓名}/{图片文件名}.jpg
├── 工作内容/{工作内容}/{图片文件名}.jpg
└── 部门/{部门名称}/{图片文件名}.jpg
1.4 接口设计
1.4.1 获取上传预签名 URL
请求:
POST /api/cos/getUploadUrls
请求参数:
{
"recordTime": "2025-01-05 10:30:00",
"deptName": "工程部",
"content": "日常巡检",
"workers": ["张三", "李四"],
"fileExt": ".jpg",
"imageCount": 3
}
响应:
{
"code": 200,
"data": {
"images": [
{
"imageId": "uuid-1",
"fileName": "1736051400_1234.jpg",
"uploadUrls": {
"daily": "https://xxx.cos.ap-xxx.myqcloud.com/workfiles/202501/20250105/当日照片/1736051400_1234.jpg?sign=xxx",
"workers": {
"张三": "https://xxx.cos.ap-xxx.myqcloud.com/workfiles/202501/20250105/参与人员/张三/1736051400_1234.jpg?sign=xxx",
"李四": "https://xxx.cos.ap-xxx.myqcloud.com/workfiles/202501/20250105/参与人员/李四/1736051400_1234.jpg?sign=xxx"
},
"content": "https://xxx.cos.ap-xxx.myqcloud.com/workfiles/202501/20250105/工作内容/日常巡检/1736051400_1234.jpg?sign=xxx",
"dept": "https://xxx.cos.ap-xxx.myqcloud.com/workfiles/202501/20250105/部门/工程部/1736051400_1234.jpg?sign=xxx"
},
"accessUrl": "https://xxx.cos.ap-xxx.myqcloud.com/workfiles/202501/20250105/当日照片/1736051400_1234.jpg"
}
]
}
}
1.4.2 保存工作记录(v3 新接口)
⚠️ 重要说明:原有
/addworkrecord(v1) 和/addworkrecordv2(v2) 接口保持不变,不做任何修改。新增 v3 接口用于 COS 直传场景。
请求:
POST /addworkrecordv3
请求参数:
{
"deptName": "工程部",
"recordTime": "2025-01-05 10:30:00",
"longitude": "116.397470",
"latitude": "39.908823",
"address": "北京市东城区xxx",
"content": "日常巡检",
"statusName": "进行中",
"remarks": "",
"workers": ["张三", "李四"],
"imageUrls": [
"https://xxx.cos.ap-xxx.myqcloud.com/workfiles/202501/20250105/当日照片/1736051400_1234.jpg",
"https://xxx.cos.ap-xxx.myqcloud.com/workfiles/202501/20250105/当日照片/1736051400_5678.jpg"
]
}
与 v2 接口的区别:
| 字段 | v2 接口 | v3 接口 |
|---|---|---|
| Image | Base64 字符串 | 无 |
| Images | Base64 字符串数组 | 无 |
| imageUrls | 无 | COS URL 数组 |
响应:
{
"code": 200,
"data": {
"id": 123,
"imageCount": 2
}
}
1.5 前端改造要点
- 拍照加水印后,先调用接口获取预签名 URL
- 使用
uni.uploadFile或fetch PUT直接上传到 COS - 同一张图片需要上传到多个目录(当日照片、参与人员、工作内容、部门)
- 全部上传成功后,调用保存接口记录数据
1.6 后端改造要点
- 新增腾讯云 COS SDK 依赖
- 配置 COS 密钥(SecretId、SecretKey、Bucket、Region)
- 实现预签名 URL 生成逻辑
- 新增 v3 接口(
/addworkrecordv3),接收 COS URL 而非 Base64 - 保留 v1、v2 接口不变,确保已发布版本兼容性
- v3 接口复用现有的数据库存储逻辑,仅修改图片处理部分
模块二:数据导出 API
2.1 功能描述
提供分页查询接口,供 CS 客户端调用获取工作记录数据。
2.2 接口设计
2.2.1 分页查询工作记录
请求:
GET /api/workrecord/export/list
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| pageNum | int | 是 | 页码,从 1 开始 |
| pageSize | int | 是 | 每页条数,最大 50 |
| startDate | string | 否 | 开始日期 yyyy-MM-dd |
| endDate | string | 否 | 结束日期 yyyy-MM-dd |
| deptName | string | 否 | 部门名称 |
| workerName | string | 否 | 人员姓名 |
| content | string | 否 | 工作内容(模糊匹配) |
响应:
{
"code": 200,
"data": {
"total": 1000,
"pageNum": 1,
"pageSize": 50,
"pages": 20,
"list": [
{
"id": 1,
"deptName": "工程部",
"recordTime": "2025-01-05 10:30:00",
"longitude": "116.397470",
"latitude": "39.908823",
"address": "北京市东城区xxx",
"content": "日常巡检",
"statusName": "进行中",
"workers": ["张三", "李四"],
"images": [
"https://xxx.cos.ap-xxx.myqcloud.com/workfiles/202501/20250105/当日照片/1736051400_1234.jpg",
"https://xxx.cos.ap-xxx.myqcloud.com/workfiles/202501/20250105/当日照片/1736051400_5678.jpg"
],
"createTime": "2025-01-05 10:35:00",
"updateTime": "2025-01-05 10:35:00"
}
]
}
}
2.3 注意事项
- 单页最大 50 条,防止一次性拉取过多数据
- 接口需要登录认证
- 客户端每次请求间隔 100ms,避免频繁请求
模块三:CS 客户端(Excel 导出工具)
3.1 功能描述
开发一个 Windows 桌面客户端,用于导出带图片的 Excel 文件。
3.2 技术选型
- 框架:WinForms + .NET 8
- 发布方式:AOT 单文件发布,双击即可运行,无需安装
- Excel 库:MiniExcel 或 EPPlus
3.3 功能模块
3.3.1 登录模块
- 输入服务器地址、用户名、密码
- 登录成功后保存 token
- 支持记住登录状态
3.3.2 查询条件模块
- 日期范围选择(开始日期、结束日期)
- 部门筛选(下拉选择)
- 人员筛选(输入框)
- 工作内容筛选(输入框)
3.3.3 数据预览模块
- 显示符合条件的记录总数
- 列表预览前 N 条数据
- 显示预计导出图片数量
3.3.4 导出模块
- 选择保存路径
- 显示导出进度(已处理 X/Y 条,已下载 X/Y 张图片)
- 支持取消导出
- 导出完成后自动打开文件夹
3.4 导出流程
1. 用户设置查询条件,点击"开始导出"
2. 分页调用 API 获取数据(每页 50 条)
3. 解析每条记录的图片 URL
4. 并发下载图片到本地临时目录(控制并发数,如 5 个)
5. 全部数据获取完成后,生成 Excel 文件
6. 将图片嵌入 Excel 对应单元格
7. 保存 Excel 文件
8. 清理临时文件
9. 提示导出完成
3.5 Excel 格式
⚠️ 重要说明:导出的 Excel 格式必须与现有服务端导出保持一致。
Excel 列定义(与现有格式一致):
| 列号 | 列名 | 说明 |
|---|---|---|
| A | 序号 | 自增序号 |
| B | 部门名称 | |
| C | 拍照时间 | 格式:yyyy-MM-dd HH:mm:ss |
| D | 经度 | |
| E | 纬度 | |
| F | 位置 | 地址信息 |
| G | 工作内容 | |
| H | 施工人员 | 多人用逗号分隔 |
| I | 状态 | |
| J | 施工图片 | 嵌入图片,多图水平排列 |
| K | 创建时间 | 格式:yyyy-MM-dd HH:mm:ss |
| L | 更新时间 | 格式:yyyy-MM-dd HH:mm:ss |
图片处理规则:
- 图片嵌入到单元格内
- 多张图片水平排列,间距 5 像素
- 单张图片尺寸:宽 100 像素,高 60 像素
- 图片压缩质量:50%
- 行高:60 像素(与图片高度一致)
示例效果:
┌────┬────────┬─────────────────────┬───────────┬──────────┬────────────┬──────────┬──────────┬────────┬─────────────────────┬─────────────────────┬─────────────────────┐
│序号│部门名称│拍照时间 │经度 │纬度 │位置 │工作内容 │施工人员 │状态 │施工图片 │创建时间 │更新时间 │
├────┼────────┼─────────────────────┼───────────┼──────────┼────────────┼──────────┼──────────┼────────┼─────────────────────┼─────────────────────┼─────────────────────┤
│ 1 │工程部 │2025-01-05 10:30:00 │116.397470 │39.908823 │北京市xxx │日常巡检 │张三,李四 │进行中 │[图1][图2][图3] │2025-01-05 10:35:00 │2025-01-05 10:35:00 │
│ 2 │工程部 │2025-01-05 11:00:00 │116.397470 │39.908823 │北京市xxx │设备维护 │王五 │已完成 │[图1][图2] │2025-01-05 11:05:00 │2025-01-05 11:05:00 │
└────┴────────┴─────────────────────┴───────────┴──────────┴────────────┴──────────┴──────────┴────────┴─────────────────────┴─────────────────────┴─────────────────────┘
技术实现:
- 使用 EPPlus 库生成 Excel(与服务端一致)
- 使用 SixLabors.ImageSharp 处理图片压缩
3.6 界面草图
┌─────────────────────────────────────────────────────────┐
│ 随工水印相机 - Excel 导出工具 [—][□][×] │
├─────────────────────────────────────────────────────────┤
│ 服务器: [https://xxx.com ] 用户名: [admin] [登录] │
├─────────────────────────────────────────────────────────┤
│ ┌─ 查询条件 ─────────────────────────────────────────┐ │
│ │ 日期范围: [2025-01-01] 至 [2025-01-31] │ │
│ │ 部门: [全部 ▼] 人员: [ ] │ │
│ │ 工作内容: [ ] │ │
│ │ [查询预览] │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ 查询结果: 共 256 条记录,约 512 张图片 │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ 序号 │ 日期 │ 部门 │ 工作内容 │ 图片数 │ │ │
│ │ 1 │ 2025-01-05 │ 工程部 │ 日常巡检 │ 3 │ │ │
│ │ 2 │ 2025-01-05 │ 工程部 │ 设备维护 │ 2 │ │ │
│ │ ... │ │ │ │ │ │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ 保存路径: [C:\Users\xxx\Desktop\导出.xlsx] [浏览...] │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ ████████████████████░░░░░░░░░░░░░░░░░░░░ 45% │ │
│ │ 正在下载图片: 230/512 │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ [取消] [开始导出] │
└─────────────────────────────────────────────────────────┘
模块四:历史数据迁移
4.1 功能描述
在 CS 客户端中集成历史数据迁移功能,将服务器本地的图片迁移到腾讯云 COS。
4.2 迁移方案
在 CS 客户端中新增"历史数据迁移"功能模块,通过可视化界面操作迁移。
4.3 功能设计
4.3.1 入口
- 在客户端主界面增加"历史数据迁移"按钮
- 点击后弹出迁移窗口
4.3.2 迁移窗口功能
-
数据列表展示
- 调用 API 获取所有未迁移的记录(ImageUrl 包含旧域名的记录)
- 列表显示:序号、日期、部门、工作内容、图片数量、迁移状态
- 支持分页加载
-
筛选条件
- 日期范围
- 部门
- 迁移状态(未迁移/已迁移/迁移失败)
-
选择操作
- 全选/取消全选
- 单条勾选
- 按页全选
-
迁移操作
- 点击"开始迁移"按钮
- 显示迁移进度(已处理 X/Y 条,已上传 X/Y 张图片)
- 支持取消迁移
- 迁移完成后刷新列表状态
4.4 迁移流程
1. 客户端调用 API 获取待迁移记录列表
2. 用户选择要迁移的记录(或全选)
3. 点击"开始迁移"
4. 对于每条记录:
a. 下载原图片到本地临时目录
b. 上传图片到 COS(保持目录结构)
c. 调用 API 更新数据库中的 ImageUrl
d. 更新迁移状态
5. 迁移完成,显示结果统计
4.5 后端 API 支持
4.5.1 获取待迁移记录列表
请求:
GET /api/workrecord/migration/list
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| pageNum | int | 是 | 页码 |
| pageSize | int | 是 | 每页条数,最大 50 |
| startDate | string | 否 | 开始日期 |
| endDate | string | 否 | 结束日期 |
| status | int | 否 | 0-未迁移 1-已迁移 2-失败 |
响应:
{
"code": 200,
"data": {
"total": 500,
"list": [
{
"id": 1,
"recordTime": "2025-01-05 10:30:00",
"deptName": "工程部",
"content": "日常巡检",
"imageCount": 3,
"images": [
{
"id": 101,
"imageUrl": "https://camera.api.suigongxj.top/workfiles/202501/20250105/当日照片/xxx.jpg"
}
],
"migrationStatus": 0
}
]
}
}
4.5.2 更新迁移后的 URL
请求:
POST /api/workrecord/migration/update
请求参数:
{
"recordId": 1,
"imageUrls": [
{
"oldUrl": "https://camera.api.suigongxj.top/workfiles/xxx.jpg",
"newUrl": "https://xxx.cos.ap-xxx.myqcloud.com/workfiles/xxx.jpg"
}
]
}
4.6 界面草图
┌─────────────────────────────────────────────────────────────────────┐
│ 历史数据迁移 [×] │
├─────────────────────────────────────────────────────────────────────┤
│ ┌─ 筛选条件 ─────────────────────────────────────────────────────┐ │
│ │ 日期范围: [2024-01-01] 至 [2025-01-05] │ │
│ │ 部门: [全部 ▼] 状态: [未迁移 ▼] [查询] │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ 共 500 条待迁移记录,约 1200 张图片 │
│ │
│ [☑] 全选当页 │
│ ┌────┬────┬────────────┬────────┬──────────┬────────┬────────────┐ │
│ │ ☑ │序号│ 日期 │ 部门 │ 工作内容 │ 图片数 │ 状态 │ │
│ ├────┼────┼────────────┼────────┼──────────┼────────┼────────────┤ │
│ │ ☑ │ 1 │ 2025-01-05 │ 工程部 │ 日常巡检 │ 3 │ 未迁移 │ │
│ │ ☑ │ 2 │ 2025-01-05 │ 工程部 │ 设备维护 │ 2 │ 未迁移 │ │
│ │ ☐ │ 3 │ 2025-01-04 │ 技术部 │ 系统检查 │ 5 │ 已迁移 │ │
│ │ ☑ │ 4 │ 2025-01-04 │ 工程部 │ 管道维修 │ 4 │ 迁移失败 │ │
│ │ ...│ │ │ │ │ │ │ │
│ └────┴────┴────────────┴────────┴──────────┴────────┴────────────┘ │
│ [上一页] 1/10 [下一页] │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ ████████████████████░░░░░░░░░░░░░░░░░░░░ 45% │ │
│ │ 正在迁移: 225/500 条,已上传图片: 540/1200 张 │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ 已选择 450 条记录 [取消迁移] [开始迁移] │
└─────────────────────────────────────────────────────────────────────┘
4.7 注意事项
- 迁移过程中客户端需要有 COS 上传权限(通过 API 获取临时密钥)
- 支持断点续传,迁移失败的记录可以重新选择迁移
- 迁移完成后原图片仍保留在服务器,需要手动清理
- 建议在业务低峰期执行大批量迁移
- 客户端需要处理网络异常,支持重试机制
非功能需求
安全性
- COS 预签名 URL 有效期设置为 30 分钟
- 导出 API 需要登录认证
- COS Bucket 设置为私有读写
性能
- 前端上传支持并发(建议 3 个并发)
- 客户端下载图片支持并发(建议 5 个并发)
- API 分页查询单页最大 50 条
- 客户端请求间隔 100ms
兼容性
- CS 客户端支持 Windows 10/11
- 前端兼容现有 UniApp 多端(H5、App、小程序)
开发计划
| 阶段 | 内容 | 预计工时 |
|---|---|---|
| 第一阶段 | 后端 COS 集成 + 上传接口改造 | 2 天 |
| 第二阶段 | 前端上传逻辑改造 | 2 天 |
| 第三阶段 | 导出 API 开发 | 1 天 |
| 第四阶段 | CS 客户端开发 | 3 天 |
| 第五阶段 | 历史数据迁移 | 1 天 |
| 第六阶段 | 测试 + 上线 | 1 天 |
总计:约 10 个工作日