WorkCamera/docs/1.0.5/开发改动文档.md
2025-12-27 13:41:33 +08:00

19 KiB
Raw Blame History

v1.0.5 开发改动文档 - 支持连拍功能

一、需求概述

本次版本主要新增连拍功能,允许用户在一条工作记录中拍摄多张照片,所有照片共享相同的表单信息(位置、部门、工作内容等)。

需求要点

  1. 页面顶部增加"图片列表"区域,显示所有已拍摄图片缩略图
  2. 点击缩略图可切换预览
  3. 底部增加【继续拍照】【删除图片】按钮
  4. 所有图片统一使用第一张图片的水印信息
  5. 删除图片需二次确认
  6. 一条工作记录对应多张图片(不是多条记录)
  7. 兼容老数据(单图记录)

二、数据库改动(核心)

2.1 当前表结构

cam_workrecord工作记录表

字段名 类型 说明
Id int (PK, 自增) 主键
RecordTime datetime 拍照时间
Address nvarchar(max) 地址
Longitude nvarchar(100) 经度
Latitude nvarchar(100) 纬度
Content nvarchar(max) 工作内容
Remarks nvarchar(max) 备注
DeptName nvarchar(100) 部门名称
StatusName nvarchar(100) 状态
ImageUrl nvarchar(300) 图片路径(单张,将废弃)
CreateTime datetime 创建时间
UpdateTime datetime 更新时间

cam_worker施工人员表

字段名 类型 说明
Id bigint (PK, 自增) 主键
WorkrecordId int (FK) 关联工作记录ID
WorkerName nvarchar(100) 人员姓名
CreateTime datetime 创建时间
UpdateTime datetime 更新时间

2.2 新增表结构

cam_workrecord_image新增工作记录图片表

字段名 类型 说明
Id bigint (PK, 自增) 主键
WorkrecordId int (FK) 关联工作记录ID
ImageUrl nvarchar(500) 图片路径
SortOrder int 排序1=第一张,作为封面)
CreateTime datetime 创建时间
UpdateTime datetime 更新时间

2.3 建表SQL脚本

USE [WatermarkCamera]
GO

-- 创建工作记录图片表
CREATE TABLE [dbo].[cam_workrecord_image](
    [Id] [bigint] IDENTITY(1,1) NOT NULL,
    [WorkrecordId] [int] NOT NULL,
    [ImageUrl] [nvarchar](500) NOT NULL,
    [SortOrder] [int] NOT NULL DEFAULT 1,
    [CreateTime] [datetime] NOT NULL DEFAULT (getdate()),
    [UpdateTime] [datetime] NOT NULL DEFAULT (getdate()),
    CONSTRAINT [PK_cam_workrecord_image] PRIMARY KEY CLUSTERED ([Id] ASC)
) ON [PRIMARY]
GO

-- 添加外键约束
ALTER TABLE [dbo].[cam_workrecord_image]
ADD CONSTRAINT [FK_cam_workrecord_image_workrecord]
FOREIGN KEY ([WorkrecordId]) REFERENCES [dbo].[cam_workrecord]([Id])
ON DELETE CASCADE
GO

-- 添加索引
CREATE NONCLUSTERED INDEX [IX_cam_workrecord_image_WorkrecordId]
ON [dbo].[cam_workrecord_image] ([WorkrecordId] ASC)
GO

-- 添加字段说明
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'主键', @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cam_workrecord_image', @level2type=N'COLUMN',@level2name=N'Id'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'工作记录ID', @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cam_workrecord_image', @level2type=N'COLUMN',@level2name=N'WorkrecordId'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'图片路径', @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cam_workrecord_image', @level2type=N'COLUMN',@level2name=N'ImageUrl'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'排序1=第一张封面图)', @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cam_workrecord_image', @level2type=N'COLUMN',@level2name=N'SortOrder'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'创建时间', @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cam_workrecord_image', @level2type=N'COLUMN',@level2name=N'CreateTime'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'更新时间', @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'cam_workrecord_image', @level2type=N'COLUMN',@level2name=N'UpdateTime'
GO

2.4 老数据迁移脚本

重要:先执行建表脚本,再执行迁移脚本

USE [WatermarkCamera]
GO

-- 迁移老数据:将 cam_workrecord.ImageUrl 迁移到 cam_workrecord_image 表
INSERT INTO [dbo].[cam_workrecord_image]
    ([WorkrecordId], [ImageUrl], [SortOrder], [CreateTime], [UpdateTime])
SELECT
    [Id] AS WorkrecordId,
    [ImageUrl],
    1 AS SortOrder,  -- 老数据都是第一张(封面图)
    ISNULL([CreateTime], GETDATE()),
    ISNULL([UpdateTime], GETDATE())
FROM [dbo].[cam_workrecord]
WHERE [ImageUrl] IS NOT NULL AND [ImageUrl] <> ''
GO

-- 验证迁移结果
SELECT
    '迁移前 cam_workrecord 有图片记录数' AS [说明],
    COUNT(*) AS [数量]
FROM [dbo].[cam_workrecord]
WHERE [ImageUrl] IS NOT NULL AND [ImageUrl] <> ''

UNION ALL

SELECT
    '迁移后 cam_workrecord_image 记录数' AS [说明],
    COUNT(*) AS [数量]
FROM [dbo].[cam_workrecord_image]
GO

-- 注意:暂不删除 cam_workrecord.ImageUrl 字段,保持兼容性
-- 后续版本可考虑废弃该字段

2.5 数据结构示意

迁移后数据示例:

cam_workrecord:

Id Content DeptName ImageUrl保留兼容
101 混凝土浇筑 建筑部 /workfiles/.../img1.jpg

cam_workrecord_image:

Id WorkrecordId ImageUrl SortOrder
1 101 /workfiles/.../img1.jpg 1

新增连拍数据示例:

cam_workrecord:

Id Content DeptName ImageUrl封面图
102 模板搭建 建筑部 /workfiles/.../img2.jpg

cam_workrecord_image:

Id WorkrecordId ImageUrl SortOrder
2 102 /workfiles/.../img2.jpg 1
3 102 /workfiles/.../img3.jpg 2
4 102 /workfiles/.../img4.jpg 3

三、后端改动

3.1 改动文件清单

文件路径 改动说明
ZR.Model/Business/CamWorkrecordImage.cs 新增:图片实体类
ZR.Model/Business/Dto/CamWorkrecordDto.cs 修改DTO新增图片列表字段
ZR.Service/Business/CamWorkrecordImageService.cs 新增:图片服务类
ZR.Admin.WebApi/Controllers/CommonController.cs 修改:接口支持多图
ZR.Admin.WebApi/Controllers/Business/CamWorkrecordController.cs 修改后台接口支持多图、导出Excel

3.2 接口策略

重要说明:原有接口需要改动,但要保持入参兼容

原因老版本APP传单张图片新版本APP传多张图片接口需要同时支持。

接口 用途 改动
/addworkrecord 单图/多图提交 改动:支持多图,同时兼容单图
/addworkrecords 多图批量提交(可选) 新增(可选)

3.3 实体类改动

新增 CamWorkrecordImage.cs

namespace ZR.Model.Business
{
    /// <summary>
    /// 工作记录图片
    /// </summary>
    [SugarTable("cam_workrecord_image")]
    public class CamWorkrecordImage
    {
        /// <summary>
        /// 主键
        /// </summary>
        [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
        public long Id { get; set; }

        /// <summary>
        /// 工作记录ID
        /// </summary>
        public int WorkrecordId { get; set; }

        /// <summary>
        /// 图片路径
        /// </summary>
        public string ImageUrl { get; set; }

        /// <summary>
        /// 排序1=第一张封面图)
        /// </summary>
        public int SortOrder { get; set; }

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreateTime { get; set; }

        /// <summary>
        /// 更新时间
        /// </summary>
        public DateTime UpdateTime { get; set; }
    }
}

3.4 DTO改动

CamWorkrecordDto.cs 修改:

public class CamRecordWorkDto
{
    public int? Id { get; set; }
    public string DeptName { get; set; }

    /// <summary>
    /// 单张图片Base64兼容老版本APP
    /// </summary>
    public string Image { get; set; }

    /// <summary>
    /// 多张图片Base64数组新版本APP使用
    /// </summary>
    public List<string> Images { get; set; }

    public string ImageUrl { get; set; }
    public DateTime? RecordTime { get; set; }
    public string Longitude { get; set; }
    public string Latitude { get; set; }
    public string Address { get; set; }
    public string Content { get; set; }
    public string StatusName { get; set; }
    public string Remarks { get; set; }
    public List<string> Workers { get; set; }
}

/// <summary>
/// 工作记录图片DTO
/// </summary>
public class CamWorkrecordImageDto
{
    public long Id { get; set; }
    public int WorkrecordId { get; set; }
    public string ImageUrl { get; set; }
    public int SortOrder { get; set; }
}

3.5 接口改动逻辑

CommonController.cs - AddCamWorkRecord 改动:

[HttpPost]
[Route("/addworkrecord")]
[AllowAnonymous]
public async Task<IActionResult> AddCamWorkRecord([FromBody] CamRecordWorkDto parm)
{
    // 1. 参数校验
    if (parm.Workers == null || parm.Workers.Count == 0)
        return ToResponse(ResultCode.PARAM_ERROR, "请选择工作人员");

    // 2. 获取图片列表(兼容新旧版本)
    var imageList = new List<string>();
    if (parm.Images != null && parm.Images.Count > 0)
    {
        // 新版本APP多张图片
        imageList = parm.Images;
    }
    else if (!string.IsNullOrEmpty(parm.Image))
    {
        // 老版本APP单张图片
        imageList.Add(parm.Image);
    }
    else if (string.IsNullOrEmpty(parm.ImageUrl))
    {
        return ToResponse(ResultCode.PARAM_ERROR, "请上传图片");
    }

    // 3. 保存工作记录(只保存一条)
    var modal = parm.Adapt<CamWorkrecord>().ToCreate(HttpContext);
    modal.CreateTime = DateTime.Now;
    modal.UpdateTime = DateTime.Now;

    // 4. 处理图片并保存到 cam_workrecord_image 表
    var savedImageUrls = new List<string>();
    int sortOrder = 1;
    foreach (var imageBase64 in imageList)
    {
        var imageUrl = await SaveImageFile(imageBase64, parm);
        savedImageUrls.Add(imageUrl);

        // 保存图片记录
        var imageRecord = new CamWorkrecordImage
        {
            WorkrecordId = modal.Id,
            ImageUrl = imageUrl,
            SortOrder = sortOrder++,
            CreateTime = DateTime.Now,
            UpdateTime = DateTime.Now
        };
        await _CamWorkrecordImageService.InsertAsync(imageRecord);
    }

    // 5. 更新主表的 ImageUrl封面图兼容老逻辑
    if (savedImageUrls.Count > 0)
    {
        modal.ImageUrl = savedImageUrls[0];
        await _CamWorkrecordService.UpdateAsync(modal);
    }

    // 6. 保存施工人员
    // ... 原有逻辑

    return SUCCESS(new { id = modal.Id, imageCount = savedImageUrls.Count });
}

3.6 后台接口改动

CamWorkrecordController.cs 需要改动:

  1. 查询详情:返回图片列表
[HttpGet("{Id}")]
public IActionResult GetCamWorkrecord(int Id)
{
    var response = _CamWorkrecordService.GetInfo(Id);
    var info = response.Adapt<CamWorkrecordDto>();

    // 获取图片列表
    var images = _CamWorkrecordImageService.GetList(Id);
    info.Images = images.Select(x => x.ImageUrl).ToList();

    // ... 其他逻辑
    return SUCCESS(info);
}
  1. 导出Excel:支持多图(显示第一张或全部)
// 导出时获取每条记录的所有图片
// 可选方案:只显示第一张,或合并显示所有图片路径
  1. 删除记录:级联删除图片
// 删除工作记录时cam_workrecord_image 会自动级联删除(外键约束)

3.7 兼容性说明

场景 处理方式
老版本APP传 Image 字段 兼容,转为单元素数组处理
新版本APP传 Images 数组 正常处理多图
老数据查询 cam_workrecord_image 表读取(已迁移)
新数据查询 cam_workrecord_image 表读取
ImageUrl 字段 保留作为封面图,兼容老代码

四、后台管理改动

4.1 改动文件

文件路径 改动说明
ZR.Vue/src/views/business/CamWorkrecord.vue 列表/详情显示多图
ZR.Vue/src/api/business/camworkrecord.js API调整可选

4.2 列表页改动

显示图片数量或缩略图列表:

<el-table-column prop="imageUrl" label="图片" width="160">
  <template #default="scope">
    <div class="image-list">
      <!-- 显示第一张作为封面 -->
      <ImagePreview :src="scope.row.imageUrl" />
      <!-- 显示图片数量 -->
      <span v-if="scope.row.imageCount > 1" class="image-count">
        +{{ scope.row.imageCount - 1 }}
      </span>
    </div>
  </template>
</el-table-column>

4.3 详情页改动

显示所有图片:

<el-form-item label="施工图片">
  <div class="image-gallery">
    <div v-for="(img, index) in form.images" :key="index" class="image-item">
      <ImagePreview :src="img" />
      <span class="image-index">{{ index + 1 }}</span>
    </div>
  </div>
</el-form-item>

4.4 编辑页改动

确认需求:允许增删图片

支持多图上传/管理:

  • 显示现有图片列表(带排序序号)
  • 支持添加新图片限制最多15张
  • 支持删除图片至少保留1张
  • 支持拖拽排序(可选)

UI示例

<el-form-item label="施工图片">
  <div class="image-manager">
    <!-- 图片列表 -->
    <div v-for="(img, index) in form.images" :key="index" class="image-item">
      <ImagePreview :src="img.imageUrl" />
      <span class="image-index">{{ index + 1 }}</span>
      <el-button
        type="danger"
        size="small"
        icon="delete"
        :disabled="form.images.length <= 1"
        @click="removeImage(index)">
      </el-button>
    </div>

    <!-- 添加图片按钮 -->
    <el-upload
      v-if="form.images.length < 15"
      :auto-upload="false"
      :show-file-list="false"
      @change="handleAddImage">
      <el-button icon="plus">添加图片</el-button>
    </el-upload>

    <div class="image-tip">
      已上传 {{ form.images.length }}/15 张图片
    </div>
  </div>
</el-form-item>

后端接口改动:

  • 编辑时需要支持:新增图片、删除图片、更新排序
  • 可采用"先删后增"策略:删除原有图片记录,重新插入新的图片列表

4.5 导出Excel改动

确认需求:导出本记录的所有图片

实现方案:

  • 每条记录可能有多张图片需要调整Excel布局
  • 方案1多张图片横向排列在同一单元格推荐
  • 方案2多张图片纵向排列合并其他列单元格

代码改动思路:

// 导出时获取每条记录的所有图片
var images = _CamWorkrecordImageService.GetListByWorkrecordId(item.Id);

// 计算需要的列宽或行高
int imageCount = images.Count;
int imageWidth = 100;  // 单张图片宽度
int totalWidth = imageWidth * Math.Min(imageCount, 5); // 最多显示5张超出换行

// 将多张图片绘制到Excel单元格中
foreach (var img in images)
{
    // 绘制图片...
}

注意事项:

  • 图片过多时Excel文件会很大建议压缩图片质量
  • 考虑增加"图片数量"列,方便查看

五、前端APP改动

5.1 改动文件

文件路径 改动说明
uniapp/WorkCameraf/pages/index/index.vue 主要改动UI和逻辑
uniapp/WorkCameraf/common/utils.js 水印处理调整
uniapp/WorkCameraf/common/server.js 接口调用参数调整

5.2 数据结构改动

data() {
  return {
    imageList: [],       // 图片列表 [{original: '', watermark: '', id: ''}]
    currentIndex: 0,     // 当前选中图片索引
    maxImageCount: 15,   // 最大图片数量限制
    // ...其他字段保持不变
  }
}

5.3 继续拍照限制

async continueCapture() {
  // 检查是否达到最大数量
  if (this.imageList.length >= this.maxImageCount) {
    uni.showToast({
      title: '最多只能拍摄15张图片',
      icon: 'none'
    })
    return
  }
  // ... 继续拍照逻辑
}

5.4 提交数据改动

async submitData() {
  const images = this.imageList.map(item => item.watermark)

  const params = {
    // ... 其他字段
    Images: images,  // 新增:多张图片数组
    // Image: xxx,   // 不再使用单张字段
  }

  await addWatermarkRecord(params)
}

六、开发任务清单

6.1 数据库任务

  • 1. 执行建表脚本cam_workrecord_image
  • 2. 执行老数据迁移脚本
  • 3. 验证迁移结果

6.2 后端任务

  • 1. 新增 CamWorkrecordImage 实体类
  • 2. 新增 ICamWorkrecordImageService 服务接口和实现
  • 3. 修改 CamRecordWorkDto,新增 Images 字段
  • 4. 修改 /addworkrecord 接口,支持多图(兼容单图)
  • 5. 修改查询接口,返回图片列表
  • 6. 修改删除接口,确保级联删除图片
  • 7. 修改导出Excel处理多图场景
  • 8. 接口测试

6.3 后台前端任务

  • 1. 列表页:显示图片数量或缩略图
  • 2. 详情页:显示所有图片
  • 3. 编辑页:支持多图管理
  • 4. 测试验证

6.4 APP前端任务

  • 1. 修改数据结构,支持图片列表
  • 2. 添加图片列表UI组件
  • 3. 实现图片切换功能
  • 4. 实现继续拍照功能
  • 5. 实现删除图片功能(含二次确认)
  • 6. 修改提交逻辑,传 Images 数组
  • 7. 样式调整和优化
  • 8. H5端测试
  • 9. APP端测试

七、需求确认事项

序号 问题 确认结果 状态
1 连拍最多支持几张图片? 最多15张 已确认
2 后台导出Excel是否需要导出所有图片 导出本记录的所有图片 已确认
3 后台编辑时是否允许增删图片? 允许增删图片 已确认
4 是否需要删除 cam_workrecord.ImageUrl 字段? 保留兼容,需写迁移脚本 已确认
5 图片文件存储路径是否需要调整? 保持现有结构 已确认

八、风险评估

风险项 风险等级 应对措施
老数据迁移失败 迁移前备份数据库,验证迁移结果
老版本APP不兼容 接口保持入参兼容,支持单图和多图
多图上传超时 前端压缩,限制图片数量和大小
后台显示异常 兼容处理无图片或单图场景

九、版本计划

  • 数据库迁移:上线前执行
  • 开发周期:待定
  • 测试周期:待定
  • 上线时间:待定

文档版本v2.0 编写日期2025-12-27 编写人Claude AI Assistant