Commit 6a6f391d6f70d99354a374d2a42ee3711e451ad0

Authored by 王富生
2 parents a6132677 f2fb187d

Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
#	urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/road/RoadStreetController.java
Showing 50 changed files with 1292 additions and 179 deletions
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/api/material/MaterialApi.java 0 → 100644
  1 +package com.zteits.urbanops.module.garden.api.material;
  2 +
  3 +import com.zteits.urbanops.module.garden.api.material.dto.MaterialInventoryOutDto;
  4 +
  5 +/**
  6 + * @Classname MaterialApi
  7 + * @Description 物料出库
  8 + * @Date 2025/12/16 16:19
  9 + * @Created by wangqian
  10 + */
  11 +public interface MaterialApi {
  12 +
  13 + /**
  14 + * 创建物料出库
  15 + *
  16 + * @param outDto 创建信息
  17 + * @return 编号
  18 + */
  19 + Long createMaterialInventoryOut(MaterialInventoryOutDto outDto);
  20 +}
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/api/material/MaterialApiImpl.java 0 → 100644
  1 +package com.zteits.urbanops.module.garden.api.material;
  2 +
  3 +import cn.hutool.core.bean.BeanUtil;
  4 +import com.zteits.urbanops.module.garden.api.material.dto.MaterialInventoryOutDto;
  5 +import com.zteits.urbanops.module.garden.controller.admin.materialinventoryout.vo.MaterialInventoryOutSaveReqVO;
  6 +import com.zteits.urbanops.module.garden.service.materialinventoryout.MaterialInventoryOutService;
  7 +import jakarta.annotation.Resource;
  8 +import org.springframework.stereotype.Service;
  9 +import org.springframework.validation.annotation.Validated;
  10 +
  11 +/**
  12 + * @Classname MaterialApiImpl
  13 + * @Description 物料接口
  14 + * @Date 2025/12/16 16:21
  15 + * @Created by wangqian
  16 + */
  17 +@Service
  18 +@Validated
  19 +public class MaterialApiImpl implements MaterialApi{
  20 +
  21 + @Resource
  22 + private MaterialInventoryOutService materialInventoryOutService;
  23 + @Override
  24 + public Long createMaterialInventoryOut(MaterialInventoryOutDto outDto) {
  25 + MaterialInventoryOutSaveReqVO createReqVO = BeanUtil.toBean(outDto, MaterialInventoryOutSaveReqVO.class);
  26 + return materialInventoryOutService.createMaterialInventoryOut(createReqVO);
  27 + }
  28 +}
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/api/material/dto/MaterialInventoryOutDto.java 0 → 100644
  1 +package com.zteits.urbanops.module.garden.api.material.dto;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotNull;
  5 +import lombok.Data;
  6 +
  7 +import java.time.LocalDateTime;
  8 +
  9 +/**
  10 + * @Classname MaterialInventoryOutDto
  11 + * @Description 物料出库
  12 + * @Date 2025/12/16 16:22
  13 + * @Created by wangqian
  14 + */
  15 +@Data
  16 +public class MaterialInventoryOutDto {
  17 + @Schema(description = "入库ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "18713")
  18 + private Long id;
  19 +
  20 + @Schema(description = "物料ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "14541")
  21 + @NotNull(message = "物料ID不能为空")
  22 + private Long materialId;
  23 +
  24 + @Schema(description = "物料名称", example = "芋艿")
  25 + private String materialName;
  26 +
  27 + @Schema(description = "出库数量", requiredMode = Schema.RequiredMode.REQUIRED)
  28 + @NotNull(message = "出库数量不能为空")
  29 + private Long outInventoryNum;
  30 +
  31 + @Schema(description = "出库日期", requiredMode = Schema.RequiredMode.REQUIRED)
  32 + @NotNull(message = "出库日期不能为空")
  33 + private LocalDateTime outDate;
  34 +
  35 +}
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/assigntasks/AssignTasksController.java
@@ -92,12 +92,10 @@ public class AssignTasksController { @@ -92,12 +92,10 @@ public class AssignTasksController {
92 List<AssignTasksInfoDO> assignTaskInfoList = asignTasksInfoService.getAssignTasksInfos(assignTasks.getId()); 92 List<AssignTasksInfoDO> assignTaskInfoList = asignTasksInfoService.getAssignTasksInfos(assignTasks.getId());
93 assignTasksRespVO.setAssignTaskInfoList(assignTaskInfoList); 93 assignTasksRespVO.setAssignTaskInfoList(assignTaskInfoList);
94 //获取单位集合 94 //获取单位集合
95 - List<String> companyIds = CollectionUtil.isEmpty(assignTaskInfoList) 95 + List<Long> companyIds = CollectionUtil.isEmpty(assignTaskInfoList)
96 ? Collections.emptyList() 96 ? Collections.emptyList()
97 : assignTaskInfoList.stream() 97 : assignTaskInfoList.stream()
98 .map(AssignTasksInfoDO::getCompanyId) 98 .map(AssignTasksInfoDO::getCompanyId)
99 - .map(StrUtil::toString) // Hutool 工具类:自动处理 null(转为 null 字符串,需配合过滤)  
100 - .filter(StrUtil::isNotEmpty) // 过滤 null/空字符串  
101 .distinct() 99 .distinct()
102 .collect(Collectors.toList()); 100 .collect(Collectors.toList());
103 assignTasksRespVO.setCompanyIds(companyIds); 101 assignTasksRespVO.setCompanyIds(companyIds);
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/assigntasks/vo/AssignTasksRespVO.java
@@ -63,7 +63,7 @@ public class AssignTasksRespVO { @@ -63,7 +63,7 @@ public class AssignTasksRespVO {
63 @Schema(description = "修改人(关联用户ID,最后修改人)") 63 @Schema(description = "修改人(关联用户ID,最后修改人)")
64 private String updater; 64 private String updater;
65 65
66 - private List<String> companyIds; 66 + private List<Long> companyIds;
67 private List<AssignTasksInfoDO> assignTaskInfoList; 67 private List<AssignTasksInfoDO> assignTaskInfoList;
68 68
69 public void setParentFinish(Integer parentFinish) { 69 public void setParentFinish(Integer parentFinish) {
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/assigntasks/vo/AssignTasksSaveReqVO.java
@@ -58,6 +58,6 @@ public class AssignTasksSaveReqVO { @@ -58,6 +58,6 @@ public class AssignTasksSaveReqVO {
58 58
59 /*单位集合*/ 59 /*单位集合*/
60 @NotEmpty(message = "派发单位不能为空") 60 @NotEmpty(message = "派发单位不能为空")
61 - private List<String> companyIds; 61 + private List<Long> companyIds;
62 62
63 } 63 }
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/inspectionplan/InspectionPlanController.java
@@ -47,7 +47,7 @@ public class InspectionPlanController { @@ -47,7 +47,7 @@ public class InspectionPlanController {
47 @PreAuthorize("@ss.hasPermission('garden:inspection-plan:create')") 47 @PreAuthorize("@ss.hasPermission('garden:inspection-plan:create')")
48 public CommonResult<Integer> createInspectionPlan(@Valid @RequestBody InspectionPlanSaveReqVO createReqVO) { 48 public CommonResult<Integer> createInspectionPlan(@Valid @RequestBody InspectionPlanSaveReqVO createReqVO) {
49 if(!createReqVO.verify()){ 49 if(!createReqVO.verify()){
50 - log.warn("次数值范围:1-10或者分数格式:1/3, rateValue={}", createReqVO.getRateValue()); 50 + log.warn("次数值范围:1-1000或者分数格式:1/3, rateValue={}", createReqVO.getRateValue());
51 return error(PLAN_RATE_VALUE_ERROR); 51 return error(PLAN_RATE_VALUE_ERROR);
52 } 52 }
53 // //临时计划 53 // //临时计划
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/inspectionplan/vo/InspectionPlanCommitPageReqVO.java
@@ -63,4 +63,12 @@ public class InspectionPlanCommitPageReqVO extends PageParam { @@ -63,4 +63,12 @@ public class InspectionPlanCommitPageReqVO extends PageParam {
63 private String remark; 63 private String remark;
64 64
65 private List<String> busiLineList; 65 private List<String> busiLineList;
  66 +
  67 + @Schema(description = "创建开始时间")
  68 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
  69 + private LocalDate createTimeStart;
  70 +
  71 + @Schema(description = "创建结束时间")
  72 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
  73 + private LocalDate createTimeEnd;
66 } 74 }
67 \ No newline at end of file 75 \ No newline at end of file
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/inspectionplan/vo/InspectionPlanSaveReqVO.java
@@ -46,6 +46,7 @@ public class InspectionPlanSaveReqVO { @@ -46,6 +46,7 @@ public class InspectionPlanSaveReqVO {
46 46
47 @Schema(description = "频次值", requiredMode = Schema.RequiredMode.REQUIRED) 47 @Schema(description = "频次值", requiredMode = Schema.RequiredMode.REQUIRED)
48 @NotEmpty(message = "频次值不能为空") 48 @NotEmpty(message = "频次值不能为空")
  49 + @Size(max = 6 , message = "频次值长度不能大于6")
49 private String rateValue; 50 private String rateValue;
50 51
51 @Schema(description = "周期ID: 0:次;1:日/次;2:周/次;3:月/次;4:季/次;5:半年/次;6:年/次", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 52 @Schema(description = "周期ID: 0:次;1:日/次;2:周/次;3:月/次;4:季/次;5:半年/次;6:年/次", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/maintainplan/vo/MaintainPlanCommitPageReqVO.java
@@ -60,4 +60,12 @@ public class MaintainPlanCommitPageReqVO extends PageParam { @@ -60,4 +60,12 @@ public class MaintainPlanCommitPageReqVO extends PageParam {
60 @Schema(description = "提交人用户ID", example = "王五") 60 @Schema(description = "提交人用户ID", example = "王五")
61 private String userName; 61 private String userName;
62 62
63 -}  
64 \ No newline at end of file 63 \ No newline at end of file
  64 + @Schema(description = "创建开始时间")
  65 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
  66 + private LocalDate createTimeStart;
  67 +
  68 + @Schema(description = "创建结束时间")
  69 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
  70 + private LocalDate createTimeEnd;
  71 +
  72 +}
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/maintainplan/vo/MaintainPlanDetailRespVO.java
@@ -74,4 +74,4 @@ public class MaintainPlanDetailRespVO { @@ -74,4 +74,4 @@ public class MaintainPlanDetailRespVO {
74 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 74 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
75 @ExcelProperty("创建时间") 75 @ExcelProperty("创建时间")
76 private LocalDateTime createTime; 76 private LocalDateTime createTime;
77 -}  
78 \ No newline at end of file 77 \ No newline at end of file
  78 +}
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/maintainplan/vo/MaintainPlanSaveReqVO.java
@@ -46,6 +46,7 @@ public class MaintainPlanSaveReqVO { @@ -46,6 +46,7 @@ public class MaintainPlanSaveReqVO {
46 46
47 @Schema(description = "频次值", requiredMode = Schema.RequiredMode.REQUIRED) 47 @Schema(description = "频次值", requiredMode = Schema.RequiredMode.REQUIRED)
48 @NotEmpty(message = "频次值不能为空") 48 @NotEmpty(message = "频次值不能为空")
  49 + @Size(max = 6 , message = "频次值长度不能大于6")
49 private String rateValue; 50 private String rateValue;
50 51
51 @Schema(description = "周期ID: 1:日/次;2:周/次;3:月/次;4:年/次;5:按次;6:季度;7:半年", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 52 @Schema(description = "周期ID: 1:日/次;2:周/次;3:月/次;4:年/次;5:按次;6:季度;7:半年", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/road/RoadStreetController.java
@@ -40,14 +40,14 @@ public class RoadStreetController { @@ -40,14 +40,14 @@ public class RoadStreetController {
40 40
41 @PostMapping("/create") 41 @PostMapping("/create")
42 @Operation(summary = "创建街道") 42 @Operation(summary = "创建街道")
43 - @PreAuthorize("@ss.hasPermission('garden:road-street:create')") 43 +// @PreAuthorize("@ss.hasPermission('garden:road-street:create')")
44 public CommonResult<Long> createRoadStreet(@Valid @RequestBody RoadStreetSaveReqVO createReqVO) { 44 public CommonResult<Long> createRoadStreet(@Valid @RequestBody RoadStreetSaveReqVO createReqVO) {
45 return success(roadStreetService.createRoadStreet(createReqVO)); 45 return success(roadStreetService.createRoadStreet(createReqVO));
46 } 46 }
47 47
48 @PutMapping("/update") 48 @PutMapping("/update")
49 @Operation(summary = "更新街道") 49 @Operation(summary = "更新街道")
50 - @PreAuthorize("@ss.hasPermission('garden:road-street:update')") 50 +// @PreAuthorize("@ss.hasPermission('garden:road-street:update')")
51 public CommonResult<Boolean> updateRoadStreet(@Valid @RequestBody RoadStreetSaveReqVO updateReqVO) { 51 public CommonResult<Boolean> updateRoadStreet(@Valid @RequestBody RoadStreetSaveReqVO updateReqVO) {
52 roadStreetService.updateRoadStreet(updateReqVO); 52 roadStreetService.updateRoadStreet(updateReqVO);
53 return success(true); 53 return success(true);
@@ -56,7 +56,7 @@ public class RoadStreetController { @@ -56,7 +56,7 @@ public class RoadStreetController {
56 @DeleteMapping("/delete") 56 @DeleteMapping("/delete")
57 @Operation(summary = "删除街道") 57 @Operation(summary = "删除街道")
58 @Parameter(name = "id", description = "编号", required = true) 58 @Parameter(name = "id", description = "编号", required = true)
59 - @PreAuthorize("@ss.hasPermission('garden:road-street:delete')") 59 +// @PreAuthorize("@ss.hasPermission('garden:road-street:delete')")
60 public CommonResult<Boolean> deleteRoadStreet(@RequestParam("id") Long id) { 60 public CommonResult<Boolean> deleteRoadStreet(@RequestParam("id") Long id) {
61 roadStreetService.deleteRoadStreet(id); 61 roadStreetService.deleteRoadStreet(id);
62 return success(true); 62 return success(true);
@@ -65,7 +65,7 @@ public class RoadStreetController { @@ -65,7 +65,7 @@ public class RoadStreetController {
65 @DeleteMapping("/delete-list") 65 @DeleteMapping("/delete-list")
66 @Parameter(name = "ids", description = "编号", required = true) 66 @Parameter(name = "ids", description = "编号", required = true)
67 @Operation(summary = "批量删除街道") 67 @Operation(summary = "批量删除街道")
68 - @PreAuthorize("@ss.hasPermission('garden:road-street:delete')") 68 +// @PreAuthorize("@ss.hasPermission('garden:road-street:delete')")
69 public CommonResult<Boolean> deleteRoadStreetList(@RequestParam("ids") List<Long> ids) { 69 public CommonResult<Boolean> deleteRoadStreetList(@RequestParam("ids") List<Long> ids) {
70 roadStreetService.deleteRoadStreetListByIds(ids); 70 roadStreetService.deleteRoadStreetListByIds(ids);
71 return success(true); 71 return success(true);
@@ -74,7 +74,7 @@ public class RoadStreetController { @@ -74,7 +74,7 @@ public class RoadStreetController {
74 @GetMapping("/get") 74 @GetMapping("/get")
75 @Operation(summary = "获得街道") 75 @Operation(summary = "获得街道")
76 @Parameter(name = "id", description = "编号", required = true, example = "1024") 76 @Parameter(name = "id", description = "编号", required = true, example = "1024")
77 - @PreAuthorize("@ss.hasPermission('garden:road-street:query')") 77 +// @PreAuthorize("@ss.hasPermission('garden:road-street:query')")
78 public CommonResult<RoadStreetRespVO> getRoadStreet(@RequestParam("id") Long id) { 78 public CommonResult<RoadStreetRespVO> getRoadStreet(@RequestParam("id") Long id) {
79 RoadStreetDO roadStreet = roadStreetService.getRoadStreet(id); 79 RoadStreetDO roadStreet = roadStreetService.getRoadStreet(id);
80 return success(BeanUtils.toBean(roadStreet, RoadStreetRespVO.class)); 80 return success(BeanUtils.toBean(roadStreet, RoadStreetRespVO.class));
@@ -90,7 +90,7 @@ public class RoadStreetController { @@ -90,7 +90,7 @@ public class RoadStreetController {
90 90
91 @GetMapping("/page") 91 @GetMapping("/page")
92 @Operation(summary = "获得街道分页") 92 @Operation(summary = "获得街道分页")
93 - @PreAuthorize("@ss.hasPermission('garden:road-street:query')") 93 +// @PreAuthorize("@ss.hasPermission('garden:road-street:query')")
94 public CommonResult<PageResult<RoadStreetRespVO>> getRoadStreetPage(@Valid RoadStreetPageReqVO pageReqVO) { 94 public CommonResult<PageResult<RoadStreetRespVO>> getRoadStreetPage(@Valid RoadStreetPageReqVO pageReqVO) {
95 PageResult<RoadStreetDO> pageResult = roadStreetService.getRoadStreetPage(pageReqVO); 95 PageResult<RoadStreetDO> pageResult = roadStreetService.getRoadStreetPage(pageReqVO);
96 return success(BeanUtils.toBean(pageResult, RoadStreetRespVO.class)); 96 return success(BeanUtils.toBean(pageResult, RoadStreetRespVO.class));
@@ -98,7 +98,7 @@ public class RoadStreetController { @@ -98,7 +98,7 @@ public class RoadStreetController {
98 98
99 @GetMapping("/export-excel") 99 @GetMapping("/export-excel")
100 @Operation(summary = "导出街道 Excel") 100 @Operation(summary = "导出街道 Excel")
101 - @PreAuthorize("@ss.hasPermission('garden:road-street:export')") 101 +// @PreAuthorize("@ss.hasPermission('garden:road-street:export')")
102 @ApiAccessLog(operateType = EXPORT) 102 @ApiAccessLog(operateType = EXPORT)
103 public void exportRoadStreetExcel(@Valid RoadStreetPageReqVO pageReqVO, 103 public void exportRoadStreetExcel(@Valid RoadStreetPageReqVO pageReqVO,
104 HttpServletResponse response) throws IOException { 104 HttpServletResponse response) throws IOException {
@@ -109,4 +109,4 @@ public class RoadStreetController { @@ -109,4 +109,4 @@ public class RoadStreetController {
109 BeanUtils.toBean(list, RoadStreetRespVO.class)); 109 BeanUtils.toBean(list, RoadStreetRespVO.class));
110 } 110 }
111 111
112 -}  
113 \ No newline at end of file 112 \ No newline at end of file
  113 +}
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/dal/dataobject/assigntasksinfo/AssignTasksInfoDO.java
@@ -38,7 +38,7 @@ public class AssignTasksInfoDO extends BaseDO { @@ -38,7 +38,7 @@ public class AssignTasksInfoDO extends BaseDO {
38 /** 38 /**
39 * 单位ID(关联单位表主键) 39 * 单位ID(关联单位表主键)
40 */ 40 */
41 - private String companyId; 41 + private Long companyId;
42 /** 42 /**
43 * 单位ID(关联单位表主键) 43 * 单位ID(关联单位表主键)
44 */ 44 */
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/enums/ErrorCodeConstants.java
@@ -98,7 +98,7 @@ public interface ErrorCodeConstants { @@ -98,7 +98,7 @@ public interface ErrorCodeConstants {
98 ErrorCode PLAN_RATE_DETAIL_EXISTS = new ErrorCode(1-100-007-003, "计划频次已存在"); 98 ErrorCode PLAN_RATE_DETAIL_EXISTS = new ErrorCode(1-100-007-003, "计划频次已存在");
99 ErrorCode PLAN_RATE_VALUE_ERROR = new ErrorCode(1-100-007-004, "次数值范围:1-10或者分数格式:1/3"); 99 ErrorCode PLAN_RATE_VALUE_ERROR = new ErrorCode(1-100-007-004, "次数值范围:1-10或者分数格式:1/3");
100 ErrorCode PLAN_RATE_VALUE_INTEGER_ERROR = new ErrorCode(1-100-007-005, "临时计划-次数值范围:1-10的整数"); 100 ErrorCode PLAN_RATE_VALUE_INTEGER_ERROR = new ErrorCode(1-100-007-005, "临时计划-次数值范围:1-10的整数");
101 - 101 + ErrorCode PLAN_NAME_EXISTED = new ErrorCode(1-100-007-006, "计划名称已存在");
102 ErrorCode MATERIAL_TYPE_NOT_EXISTS = new ErrorCode(1-100-004-001, "物料类型不存在"); 102 ErrorCode MATERIAL_TYPE_NOT_EXISTS = new ErrorCode(1-100-004-001, "物料类型不存在");
103 ErrorCode MATERIAL_TYPE_MANAGER_NOT_EXISTS = new ErrorCode(1-100-004-002, "耗材类别管理不存在"); 103 ErrorCode MATERIAL_TYPE_MANAGER_NOT_EXISTS = new ErrorCode(1-100-004-002, "耗材类别管理不存在");
104 104
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/assigntasks/AssignTasksServiceImpl.java
@@ -92,7 +92,7 @@ public class AssignTasksServiceImpl implements AssignTasksService { @@ -92,7 +92,7 @@ public class AssignTasksServiceImpl implements AssignTasksService {
92 assignTasksMapper.updateById(updateObj); 92 assignTasksMapper.updateById(updateObj);
93 93
94 // 1. 处理关联的单位任务信息(仅当存在单位ID列表时) 94 // 1. 处理关联的单位任务信息(仅当存在单位ID列表时)
95 - List<String> companyIds = updateReqVO.getCompanyIds(); 95 + List<Long> companyIds = updateReqVO.getCompanyIds();
96 // add by wq 20251116 96 // add by wq 20251116
97 List<AssignTasksInfoDO> assignTaskInfoList = assignTasksInfoMapper.selectList(AssignTasksInfoDO::getTaskId, updateObj.getId()); 97 List<AssignTasksInfoDO> assignTaskInfoList = assignTasksInfoMapper.selectList(AssignTasksInfoDO::getTaskId, updateObj.getId());
98 if (CollectionUtils.isEmpty(assignTaskInfoList)) { 98 if (CollectionUtils.isEmpty(assignTaskInfoList)) {
@@ -113,11 +113,11 @@ public class AssignTasksServiceImpl implements AssignTasksService { @@ -113,11 +113,11 @@ public class AssignTasksServiceImpl implements AssignTasksService {
113 113
114 114
115 //获取已添加单位集合 115 //获取已添加单位集合
116 - List<String> existingCompanyIds = assignTaskInfoList.stream()  
117 - .map(info -> String.valueOf(info.getCompanyId())) 116 + List<Long> existingCompanyIds = assignTaskInfoList.stream()
  117 + .map(info -> info.getCompanyId())
118 .collect(Collectors.toList()); 118 .collect(Collectors.toList());
119 //排除 existingCompanyIds 中的元素 作为新增的单位 119 //排除 existingCompanyIds 中的元素 作为新增的单位
120 - List<String> filteredCompanyIds = companyIds.stream() 120 + List<Long> filteredCompanyIds = companyIds.stream()
121 .filter(Objects::nonNull) 121 .filter(Objects::nonNull)
122 .filter(id -> !existingCompanyIds.contains(id)) // 直接用列表 contains() 122 .filter(id -> !existingCompanyIds.contains(id)) // 直接用列表 contains()
123 .collect(Collectors.toList()); 123 .collect(Collectors.toList());
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/assigntasksinfo/AssignTasksInfoService.java
@@ -70,7 +70,7 @@ public interface AssignTasksInfoService { @@ -70,7 +70,7 @@ public interface AssignTasksInfoService {
70 * @param assignTasks 70 * @param assignTasks
71 * @Return java.lang.Long 71 * @Return java.lang.Long
72 */ 72 */
73 - public void saveAssignTasksInfos(List<String> companyIds, AssignTasksDO assignTasks); 73 + public void saveAssignTasksInfos(List<Long> companyIds, AssignTasksDO assignTasks);
74 74
75 /** 75 /**
76 * @Author wangqian 76 * @Author wangqian
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/assigntasksinfo/AssignTasksInfoServiceImpl.java
@@ -126,7 +126,7 @@ public class AssignTasksInfoServiceImpl implements AssignTasksInfoService { @@ -126,7 +126,7 @@ public class AssignTasksInfoServiceImpl implements AssignTasksInfoService {
126 } 126 }
127 127
128 @Override 128 @Override
129 - public void saveAssignTasksInfos(List<String> companyIds, AssignTasksDO assignTasks) { 129 + public void saveAssignTasksInfos(List<Long> companyIds, AssignTasksDO assignTasks) {
130 // 获得用户基本信息 130 // 获得用户基本信息
131 if (companyIds != null && companyIds.size() > 0) { 131 if (companyIds != null && companyIds.size() > 0) {
132 //1、获取单位集合 132 //1、获取单位集合
@@ -140,7 +140,7 @@ public class AssignTasksInfoServiceImpl implements AssignTasksInfoService { @@ -140,7 +140,7 @@ public class AssignTasksInfoServiceImpl implements AssignTasksInfoService {
140 dept -> dept.getName().trim(), // value 映射:取 companyName(去空格) 140 dept -> dept.getName().trim(), // value 映射:取 companyName(去空格)
141 (oldValue, newValue) -> newValue 141 (oldValue, newValue) -> newValue
142 )); 142 ));
143 - for (String companyId : companyIds) { 143 + for (Long companyId : companyIds) {
144 AssignTasksInfoDO assignTaskInfo = new AssignTasksInfoDO(); 144 AssignTasksInfoDO assignTaskInfo = new AssignTasksInfoDO();
145 assignTaskInfo.setCompanyId(companyId); 145 assignTaskInfo.setCompanyId(companyId);
146 assignTaskInfo.setCompanyName(companyIdToNameMap.get(Long.valueOf(companyId))); 146 assignTaskInfo.setCompanyName(companyIdToNameMap.get(Long.valueOf(companyId)));
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/inspectionplan/InspectionPlanServiceImpl.java
@@ -148,7 +148,12 @@ public class InspectionPlanServiceImpl implements InspectionPlanService { @@ -148,7 +148,12 @@ public class InspectionPlanServiceImpl implements InspectionPlanService {
148 String planAttrLabel = DictFrameworkUtils.parseDictDataLabel(PlanConstants.GARDEN_PLAN_ATTR_REDIS_KEY, createReqVO.getPlanAttr()); 148 String planAttrLabel = DictFrameworkUtils.parseDictDataLabel(PlanConstants.GARDEN_PLAN_ATTR_REDIS_KEY, createReqVO.getPlanAttr());
149 String planTypeIdLabel = DictFrameworkUtils.parseDictDataLabel(PlanConstants.INSPECTION_MAINTAIN_TYPE, createReqVO.getPlanTypeId()); 149 String planTypeIdLabel = DictFrameworkUtils.parseDictDataLabel(PlanConstants.INSPECTION_MAINTAIN_TYPE, createReqVO.getPlanTypeId());
150 String planNameSuffix = StringUtil.isNotEmpty(createReqVO.getPlanNameSuffix()) ? createReqVO.getPlanNameSuffix() : ""; 150 String planNameSuffix = StringUtil.isNotEmpty(createReqVO.getPlanNameSuffix()) ? createReqVO.getPlanNameSuffix() : "";
151 - inspectionPlan.setPlanName(roadReqVO.getRoadName() + planAttrLabel + planTypeIdLabel + planNameSuffix); 151 + String planName = roadReqVO.getRoadName() + planAttrLabel + planTypeIdLabel + planNameSuffix;
  152 + InspectionPlanDO existInspectionPlan = inspectionPlanMapper.selectOne(new QueryWrapper<InspectionPlanDO>().lambda().eq(InspectionPlanDO::getPlanName, planName));
  153 + if (existInspectionPlan != null) {
  154 + throw exception(PLAN_NAME_EXISTED, planName);
  155 + }
  156 + inspectionPlan.setPlanName(planName);
152 inspectionPlanList.add(inspectionPlan); 157 inspectionPlanList.add(inspectionPlan);
153 /*2.插入角色*/ 158 /*2.插入角色*/
154 createReqVO.getRoleIds().forEach(roleId -> { 159 createReqVO.getRoleIds().forEach(roleId -> {
@@ -244,17 +249,18 @@ public class InspectionPlanServiceImpl implements InspectionPlanService { @@ -244,17 +249,18 @@ public class InspectionPlanServiceImpl implements InspectionPlanService {
244 .ge(InspectionPlanDO::getEndTime, req.getBeginTime()); // end_time >= startTime 249 .ge(InspectionPlanDO::getEndTime, req.getBeginTime()); // end_time >= startTime
245 250
246 count = inspectionPlanMapper.selectCount(sql); 251 count = inspectionPlanMapper.selectCount(sql);
247 - } else {  
248 - QueryWrapper<InspectionPlanDO> sql = new QueryWrapper<>();  
249 - sql.lambda().eq(InspectionPlanDO::getPlanTypeId, req.getPlanTypeId())  
250 - .in(InspectionPlanDO::getRoadId, roadIds)  
251 - .eq(InspectionPlanDO::getDeleted, 0)  
252 - .eq(InspectionPlanDO::getPlanAttr, 2) //临时计划  
253 - .le(InspectionPlanDO::getBeginTime, req.getEndTime()) // start_time <= endTime  
254 - .ge(InspectionPlanDO::getEndTime, req.getBeginTime()); // end_time >= startTime  
255 -  
256 - count = inspectionPlanMapper.selectCount(sql);  
257 } 252 }
  253 +// else {
  254 +// QueryWrapper<InspectionPlanDO> sql = new QueryWrapper<>();
  255 +// sql.lambda().eq(InspectionPlanDO::getPlanTypeId, req.getPlanTypeId())
  256 +// .in(InspectionPlanDO::getRoadId, roadIds)
  257 +// .eq(InspectionPlanDO::getDeleted, 0)
  258 +// .eq(InspectionPlanDO::getPlanAttr, 2) //临时计划
  259 +// .le(InspectionPlanDO::getBeginTime, req.getEndTime()) // start_time <= endTime
  260 +// .ge(InspectionPlanDO::getEndTime, req.getBeginTime()); // end_time >= startTime
  261 +//
  262 +// count = inspectionPlanMapper.selectCount(sql);
  263 +// }
258 264
259 if (count > 0) { 265 if (count > 0) {
260 throw exception(INSPECTION_PLAN_EXISTS); 266 throw exception(INSPECTION_PLAN_EXISTS);
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/maintainplan/MaintainPlanServiceImpl.java
@@ -124,7 +124,7 @@ public class MaintainPlanServiceImpl implements MaintainPlanService { @@ -124,7 +124,7 @@ public class MaintainPlanServiceImpl implements MaintainPlanService {
124 calculate.add(periodResult); 124 calculate.add(periodResult);
125 planNum = Integer.parseInt(createReqVO.getRateValue()); 125 planNum = Integer.parseInt(createReqVO.getRateValue());
126 }else{ 126 }else{
127 - calculate= TimeIntervalFrequencyUtil.calculate(createReqVO.getBeginTime().toString(), createReqVO.getEndTime().toString(), rateValue, createReqVO.getCycleId()); 127 + calculate= TimeIntervalFrequencyUtil.calculateNew(createReqVO.getBeginTime().toString(), createReqVO.getEndTime().toString(), rateValue, createReqVO.getCycleId());
128 if (CollectionUtils.isEmpty(calculate)) { 128 if (CollectionUtils.isEmpty(calculate)) {
129 log.warn("获取两个时间之间间隔天数错误"); 129 log.warn("获取两个时间之间间隔天数错误");
130 return CommonResult.error(INSPECTION_CYCLE_ERROR); 130 return CommonResult.error(INSPECTION_CYCLE_ERROR);
@@ -158,9 +158,15 @@ public class MaintainPlanServiceImpl implements MaintainPlanService { @@ -158,9 +158,15 @@ public class MaintainPlanServiceImpl implements MaintainPlanService {
158 maintainPlan.setRoadName(roadReqVO.getRoadName()); 158 maintainPlan.setRoadName(roadReqVO.getRoadName());
159 //计划属性label 159 //计划属性label
160 String planAttrLabel = DictFrameworkUtils.parseDictDataLabel(PlanConstants.GARDEN_PLAN_ATTR_REDIS_KEY, createReqVO.getPlanAttr()); 160 String planAttrLabel = DictFrameworkUtils.parseDictDataLabel(PlanConstants.GARDEN_PLAN_ATTR_REDIS_KEY, createReqVO.getPlanAttr());
161 - String planTypeIdLabel = DictFrameworkUtils.parseDictDataLabel(PlanConstants.INSPECTION_MAINTAIN_TYPE, createReqVO.getPlanTypeId()); 161 + String planTypeIdLabel = DictFrameworkUtils.parseDictDataLabel(PlanConstants.MAINTAIN_TYPE, createReqVO.getPlanTypeId());
162 String planNameSuffix = StringUtil.isNotEmpty(createReqVO.getPlanNameSuffix()) ? createReqVO.getPlanNameSuffix() : ""; 162 String planNameSuffix = StringUtil.isNotEmpty(createReqVO.getPlanNameSuffix()) ? createReqVO.getPlanNameSuffix() : "";
163 - maintainPlan.setPlanName(roadReqVO.getRoadName() + planAttrLabel + planTypeIdLabel + planNameSuffix); 163 + String planName = roadReqVO.getRoadName() + planAttrLabel + planTypeIdLabel + planNameSuffix;
  164 + MaintainPlanDO existMaintainPlan = maintainPlanMapper.selectOne(new QueryWrapper<MaintainPlanDO>().lambda().eq(MaintainPlanDO::getPlanName, planName));
  165 + if (existMaintainPlan != null) {
  166 + throw exception(PLAN_NAME_EXISTED, planName);
  167 + }
  168 +
  169 + maintainPlan.setPlanName(planName);
164 maintainPlanList.add(maintainPlan); 170 maintainPlanList.add(maintainPlan);
165 /*2.插入角色*/ 171 /*2.插入角色*/
166 createReqVO.getRoleIds().forEach(roleId -> { 172 createReqVO.getRoleIds().forEach(roleId -> {
@@ -262,17 +268,18 @@ public class MaintainPlanServiceImpl implements MaintainPlanService { @@ -262,17 +268,18 @@ public class MaintainPlanServiceImpl implements MaintainPlanService {
262 .ge(MaintainPlanDO::getEndTime, req.getBeginTime()); // end_time >= startTime 268 .ge(MaintainPlanDO::getEndTime, req.getBeginTime()); // end_time >= startTime
263 269
264 count = maintainPlanMapper.selectCount(sql); 270 count = maintainPlanMapper.selectCount(sql);
265 - } else {  
266 - QueryWrapper<MaintainPlanDO> sql = new QueryWrapper<>();  
267 - sql.lambda().eq(MaintainPlanDO::getPlanTypeId, req.getPlanTypeId())  
268 - .in(MaintainPlanDO::getRoadId, roadIds)  
269 - .eq(MaintainPlanDO::getDeleted, 0)  
270 - .eq(MaintainPlanDO::getPlanAttr, 2) //临时计划  
271 - .le(MaintainPlanDO::getBeginTime, req.getEndTime()) // start_time <= endTime  
272 - .ge(MaintainPlanDO::getEndTime, req.getBeginTime()); // end_time >= startTime  
273 -  
274 - count = maintainPlanMapper.selectCount(sql);  
275 } 271 }
  272 +// else {
  273 +// QueryWrapper<MaintainPlanDO> sql = new QueryWrapper<>();
  274 +// sql.lambda().eq(MaintainPlanDO::getPlanTypeId, req.getPlanTypeId())
  275 +// .in(MaintainPlanDO::getRoadId, roadIds)
  276 +// .eq(MaintainPlanDO::getDeleted, 0)
  277 +// .eq(MaintainPlanDO::getPlanAttr, 2) //临时计划
  278 +// .le(MaintainPlanDO::getBeginTime, req.getEndTime()) // start_time <= endTime
  279 +// .ge(MaintainPlanDO::getEndTime, req.getBeginTime()); // end_time >= startTime
  280 +//
  281 +// count = maintainPlanMapper.selectCount(sql);
  282 +// }
276 283
277 if (count > 0) { 284 if (count > 0) {
278 throw exception(INSPECTION_PLAN_EXISTS); 285 throw exception(INSPECTION_PLAN_EXISTS);
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/util/StringValidateUtil.java
@@ -3,13 +3,13 @@ package com.zteits.urbanops.module.garden.util; @@ -3,13 +3,13 @@ package com.zteits.urbanops.module.garden.util;
3 import java.util.regex.Pattern; 3 import java.util.regex.Pattern;
4 4
5 /** 5 /**
6 - * 字符串校验工具:校验是否为1-20的整数或合法分数(如1/3) 6 + * 字符串校验工具:校验是否为1-1000的整数或合法分数(如1/3)
7 */ 7 */
8 public class StringValidateUtil { 8 public class StringValidateUtil {
9 9
10 - // 正则表达式:匹配1-10的数字 或 分子/分母(分子、分母均为1-10的数字) 10 + // 正则表达式:匹配1-1000的数字 或 分子/分母(分子、分母均为1-100的数字)
11 private static final Pattern PATTERN = Pattern.compile( 11 private static final Pattern PATTERN = Pattern.compile(
12 - "^(?:[1-9]|10)$|^(?:[1-9]|10)/(?:[1-9]|10)$" 12 + "^(?:[1-9]|[1-9]\\d|1\\d{2}|1000)$|^(?:[1-9]|[1-9]\\d|100)/(?:[1-9]|[1-9]\\d|100)$"
13 ); 13 );
14 14
15 /** 15 /**
@@ -38,7 +38,7 @@ public class StringValidateUtil { @@ -38,7 +38,7 @@ public class StringValidateUtil {
38 // 检查是否为纯数字 38 // 检查是否为纯数字
39 if (isNumber(input)) { 39 if (isNumber(input)) {
40 int num = Integer.parseInt(input); 40 int num = Integer.parseInt(input);
41 - return num >= 1 && num <= 10; 41 + return num >= 1 && num <= 1000;
42 } 42 }
43 43
44 // 检查是否为分数格式 44 // 检查是否为分数格式
@@ -52,7 +52,7 @@ public class StringValidateUtil { @@ -52,7 +52,7 @@ public class StringValidateUtil {
52 return false; 52 return false;
53 } 53 }
54 int numerator = Integer.parseInt(parts[0]); 54 int numerator = Integer.parseInt(parts[0]);
55 - if (numerator < 1 || numerator > 10) { 55 + if (numerator < 1 || numerator > 100) {
56 return false; 56 return false;
57 } 57 }
58 // 校验分母 58 // 校验分母
@@ -60,7 +60,7 @@ public class StringValidateUtil { @@ -60,7 +60,7 @@ public class StringValidateUtil {
60 return false; 60 return false;
61 } 61 }
62 int denominator = Integer.parseInt(parts[1]); 62 int denominator = Integer.parseInt(parts[1]);
63 - return denominator >= 1 && denominator <= 10; 63 + return denominator >= 1 && denominator <= 100;
64 } 64 }
65 65
66 // 既不是数字也不是分数 66 // 既不是数字也不是分数
@@ -107,7 +107,7 @@ public class StringValidateUtil { @@ -107,7 +107,7 @@ public class StringValidateUtil {
107 // 3. 转换为数字并校验范围 107 // 3. 转换为数字并校验范围
108 try { 108 try {
109 int number = Integer.parseInt(str); 109 int number = Integer.parseInt(str);
110 - return number >= 1 && number <= 10; 110 + return number >= 1 && number <= 100;
111 } catch (NumberFormatException e) { 111 } catch (NumberFormatException e) {
112 // 理论上不会走到这里(已通过正则校验),兜底处理 112 // 理论上不会走到这里(已通过正则校验),兜底处理
113 return false; 113 return false;
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/util/timeinterval/TimeIntervalFrequencyUtil.java
@@ -2,6 +2,7 @@ package com.zteits.urbanops.module.garden.util.timeinterval; @@ -2,6 +2,7 @@ package com.zteits.urbanops.module.garden.util.timeinterval;
2 2
3 import java.time.LocalDate; 3 import java.time.LocalDate;
4 import java.time.format.DateTimeFormatter; 4 import java.time.format.DateTimeFormatter;
  5 +import java.time.temporal.ChronoUnit;
5 import java.util.ArrayList; 6 import java.util.ArrayList;
6 import java.util.Collections; 7 import java.util.Collections;
7 import java.util.List; 8 import java.util.List;
@@ -38,6 +39,82 @@ public class TimeIntervalFrequencyUtil { @@ -38,6 +39,82 @@ public class TimeIntervalFrequencyUtil {
38 * @param cycleId 1:日/次;2:周/次;3:月/次;4:年/次;5:按次;6:季度;7:半年 39 * @param cycleId 1:日/次;2:周/次;3:月/次;4:年/次;5:按次;6:季度;7:半年
39 * @return 划分结果列表 40 * @return 划分结果列表
40 */ 41 */
  42 + /**
  43 + * 计算时间段划分结果(基于固定天数换算)
  44 + *
  45 + * @param startStr 开始日期 (yyyy-MM-dd)
  46 + * @param endStr 结束日期 (yyyy-MM-dd)
  47 + * @param freq 频次值,格式 "x/y",其中 x 为每周期次数,y 为周期数量
  48 + * @param cycleId 周期类型:1:日/次;2:周/次;3:月/次;4:年/次;5:按次;6:季度;7:半年
  49 + * @return 时间段划分结果列表,包含每个时间段的开始日期、结束日期和执行次数
  50 + */
  51 + public static List<PeriodResult> calculateNew(String startStr, String endStr, String freq, Integer cycleId) {
  52 + // 解析日期参数
  53 + LocalDate startDate = LocalDate.parse(startStr, FORMATTER);
  54 + LocalDate endDate = LocalDate.parse(endStr, FORMATTER);
  55 +
  56 + // 边界条件:开始日期晚于结束日期时返回空列表
  57 + if (startDate.isAfter(endDate)) {
  58 + return Collections.emptyList();
  59 + }
  60 +
  61 + // 解析频次参数 (格式: "x/y")
  62 + String[] freqParts = freq.split("/", 2);
  63 + if (freqParts.length != 2) {
  64 + throw new IllegalArgumentException(String.format("频次值格式错误,应为 'x/y': %s", freq));
  65 + }
  66 + int timesPerPeriod = Integer.parseInt(freqParts[0]); // 每周期执行次数
  67 + int periodCount = Integer.parseInt(freqParts[1]); // 周期数量
  68 +
  69 + // 计算周期相关天数
  70 + long daysPerPeriod = convertToDaysNew(periodCount, cycleId); // 单个周期的天数
  71 + long totalPeriodDays = daysPerPeriod * periodCount; // 总周期天数
  72 +
  73 + List<PeriodResult> resultList = new ArrayList<>();
  74 + LocalDate segmentStart = startDate;
  75 +
  76 + // 循环划分时间段
  77 + while (!segmentStart.isAfter(endDate)) {
  78 + // 计算当前时间段的理论结束日期(segmentStart + totalPeriodDays - 1)
  79 + LocalDate segmentEnd = safePlusDays(segmentStart, totalPeriodDays - 1);
  80 +
  81 + // 如果理论结束日期超过总结束日期,则截断
  82 + if (segmentEnd.isAfter(endDate)) {
  83 + segmentEnd = endDate;
  84 + }
  85 +
  86 + // 计算当前时间段的实际天数(包含开始和结束日期)
  87 + long daysInSegment = ChronoUnit.DAYS.between(segmentStart, segmentEnd) + 1;
  88 +
  89 + // 计算当前时间段的执行次数:(实际天数/周期天数) * 每周期次数,向上取整
  90 + double proportion = (double) daysInSegment / daysPerPeriod;
  91 + int executionCount = (int) Math.ceil(proportion * timesPerPeriod);
  92 +
  93 + // 添加当前时间段结果
  94 + resultList.add(new PeriodResult(segmentStart, segmentEnd, executionCount));
  95 +
  96 + // 计算下一个时间段的开始日期(当前结束日期的次日)
  97 + LocalDate nextSegmentStart = segmentEnd.plusDays(1);
  98 +
  99 + // 如果下一个开始日期超过总结束日期,则退出循环
  100 + if (nextSegmentStart.isAfter(endDate)) {
  101 + break;
  102 + }
  103 +
  104 + segmentStart = nextSegmentStart;
  105 + }
  106 +
  107 + return resultList;
  108 + }
  109 + /**
  110 + * 计算时间段划分结果(基于固定天数换算)
  111 + *
  112 + * @param startStr 开始日期 (yyyy-MM-dd)
  113 + * @param endStr 结束日期 (yyyy-MM-dd)
  114 + * @param freq 频次值,格式 "x/y"
  115 + * @param cycleId 1:日/次;2:周/次;3:月/次;4:年/次;5:按次;6:季度;7:半年
  116 + * @return 划分结果列表
  117 + */
41 public static List<PeriodResult> calculate(String startStr, String endStr, String freq, Integer cycleId) { 118 public static List<PeriodResult> calculate(String startStr, String endStr, String freq, Integer cycleId) {
42 LocalDate start = LocalDate.parse(startStr, FORMATTER); 119 LocalDate start = LocalDate.parse(startStr, FORMATTER);
43 LocalDate end = LocalDate.parse(endStr, FORMATTER); 120 LocalDate end = LocalDate.parse(endStr, FORMATTER);
@@ -77,10 +154,45 @@ public class TimeIntervalFrequencyUtil { @@ -77,10 +154,45 @@ public class TimeIntervalFrequencyUtil {
77 154
78 return results; 155 return results;
79 } 156 }
80 -  
81 /** 157 /**
82 * 将 y 个单位转换为固定天数 158 * 将 y 个单位转换为固定天数
83 - * 1:日/次;2:周/次;3:月/次;4:年/次;5:按次;6:季度;7:半年 159 + * TIME(0, "次"),
  160 + * DAY(1, "次/日"),
  161 + * WEEK(2, "次/周"),
  162 + * MONTH(3, "次/月"),
  163 + * QUARTER(4, "次/季"),
  164 + * SEMIANNUAL(5, "次/半年"),
  165 + * YEAR(6, "次/年");
  166 + */
  167 + private static long convertToDaysNew(int y, Integer cycleId) {
  168 + switch (cycleId) {
  169 + case 1: // DAY
  170 + return 1;
  171 + case 2: // WEEK
  172 + return (long) 7;
  173 + case 3: // MONTH
  174 + return (long) 30;
  175 + case 6: // YEAR
  176 + return (long) 365;
  177 + case 0: // TIME
  178 + return 9999; // 按次:将整个时间段视为1个周期
  179 + case 4: // QUARTER
  180 + return (long) 90; // 1季度=3个月=90天
  181 + case 5: // SEMIANNUAL
  182 + return (long) 180; // 半年=6个月=180天
  183 + default:
  184 + throw new IllegalArgumentException("无效的周期ID: " + cycleId);
  185 + }
  186 + }
  187 + /**
  188 + * 将 y 个单位转换为固定天数
  189 + * TIME(0, "次"),
  190 + * DAY(1, "次/日"),
  191 + * WEEK(2, "次/周"),
  192 + * MONTH(3, "次/月"),
  193 + * QUARTER(4, "次/季"),
  194 + * SEMIANNUAL(5, "次/半年"),
  195 + * YEAR(6, "次/年");
84 */ 196 */
85 private static long convertToDays(int y, Integer cycleId) { 197 private static long convertToDays(int y, Integer cycleId) {
86 switch (cycleId) { 198 switch (cycleId) {
@@ -90,13 +202,13 @@ public class TimeIntervalFrequencyUtil { @@ -90,13 +202,13 @@ public class TimeIntervalFrequencyUtil {
90 return (long) y * 7; 202 return (long) y * 7;
91 case 3: // MONTH 203 case 3: // MONTH
92 return (long) y * 30; 204 return (long) y * 30;
93 - case 4: // YEAR 205 + case 6: // YEAR
94 return (long) y * 365; 206 return (long) y * 365;
95 - case 5: // TIME 207 + case 0: // TIME
96 return 1; // 按次:将整个时间段视为1个周期 208 return 1; // 按次:将整个时间段视为1个周期
97 - case 6: // QUARTER 209 + case 4: // QUARTER
98 return (long) y * 90; // 1季度=3个月=90天 210 return (long) y * 90; // 1季度=3个月=90天
99 - case 7: // SEMIANNUAL 211 + case 5: // SEMIANNUAL
100 return (long) y * 180; // 半年=6个月=180天 212 return (long) y * 180; // 半年=6个月=180天
101 default: 213 default:
102 throw new IllegalArgumentException("无效的周期ID: " + cycleId); 214 throw new IllegalArgumentException("无效的周期ID: " + cycleId);
@@ -117,52 +229,56 @@ public class TimeIntervalFrequencyUtil { @@ -117,52 +229,56 @@ public class TimeIntervalFrequencyUtil {
117 229
118 // ====================== 测试用例 ====================== 230 // ====================== 测试用例 ======================
119 public static void main(String[] args) { 231 public static void main(String[] args) {
120 - //1:日/次;2:周/次;3:月/次;4:年/次  
121 - System.out.println("=== 示例1:每2天3次(即:3/2),按日 ===2025-12-01 2025-12-31");  
122 - List<PeriodResult> r1 = calculate("2025-12-01", "2025-12-31", "3/2", 1);  
123 - r1.forEach(System.out::println);  
124 - // 输出:  
125 - // 2025-01-01 2025-01-03 1次  
126 - // 2025-01-04 2025-01-06 1次  
127 - // 2025-01-07 2025-01-07 1次  
128 - System.out.println("\n=== 示例2:每2周3次(即:3/2)(14天),按周 ===2025-12-01 2025-12-10");  
129 - List<PeriodResult> r2 = calculate("2025-12-01", "2025-12-10", "3/2", 2); 232 +
  233 + List<PeriodResult> r2 = calculateNew("2026-01-01", "2026-02-15", "7/1", 2);
130 r2.forEach(System.out::println); 234 r2.forEach(System.out::println);
131 - // 每2周 = 14天  
132 - // 2025-01-01 ~ 2025-01-14  
133 - // 2025-01-15 ~ 2025-01-28  
134 - // 2025-01-29 ~ 2025-02-08(剩余11天)  
135 - System.out.println("\n=== 示例3:每2个月4次(即:4/2)(30天),按月 === 2025-09-15 2025-12-31");  
136 - List<PeriodResult> r3 = calculate("2025-09-15", "2025-12-31", "4/2", 3);  
137 - r3.forEach(System.out::println);  
138 - // 每1月 = 30天  
139 - // 2025-01-01 ~ 2025-01-30  
140 - // 2025-01-31 ~ 2025-02-28(30天?→ 实际是29天,但按30天算)  
141 - // 2025-03-01 ~ 2025-03-15(不足)  
142 -  
143 - System.out.println("\n=== 示例4:每2年1次(即:1/2)(730天),按年 ===2025-01-01 2030-01-01");  
144 - List<PeriodResult> r4 = calculate("2025-01-01", "2030-01-01", "1/2", 4);  
145 - r4.forEach(System.out::println);  
146 - // 每2年 = 730天  
147 - // 2025-01-01 ~ 2025-12-26(+729d)  
148 - // 2025-12-27 ~ 2027-12-21  
149 - // 2027-12-22 ~ 2029-12-16  
150 - // 2029-12-17 ~ 2030-01-01(最后一段)  
151 - System.out.println("\n=== 示例5:每1年4次(即:4/1),按年(测试)=== 2023-09-15 2025-01-31");  
152 - List<PeriodResult> r5 = calculate("2023-09-15", "2025-01-31", "4/1", 4);  
153 - r5.forEach(System.out::println);  
154 -  
155 - // 新增示例:按次、季度、半年  
156 - System.out.println("\n=== 示例6:按次单位,整个时间段算1个周期 === 2025-01-01 2025-12-31");  
157 - List<PeriodResult> r6 = calculate("2025-01-01", "2025-12-31", "2/1", 5);  
158 - r6.forEach(System.out::println);  
159 -  
160 - System.out.println("\n=== 示例7:每1季度2次(即:2/1),按季度(90天)=== 2025-01-01 2025-12-31");  
161 - List<PeriodResult> r7 = calculate("2025-01-01", "2025-12-31", "2/1", 6);  
162 - r7.forEach(System.out::println);  
163 -  
164 - System.out.println("\n=== 示例8:每1半年3次(即:3/1),按半年(180天)=== 2025-01-01 2025-12-31");  
165 - List<PeriodResult> r8 = calculate("2025-01-01", "2025-12-31", "3/1", 7);  
166 - r8.forEach(System.out::println); 235 +
  236 +// //1:日/次;2:周/次;3:月/次;4:年/次
  237 +// System.out.println("=== 示例1:每2天3次(即:3/2),按日 ===2025-12-01 2025-12-31");
  238 +// List<PeriodResult> r1 = calculate("2025-12-01", "2025-12-31", "3/2", 1);
  239 +// r1.forEach(System.out::println);
  240 +// // 输出:
  241 +// // 2025-01-01 2025-01-03 1次
  242 +// // 2025-01-04 2025-01-06 1次
  243 +// // 2025-01-07 2025-01-07 1次
  244 +// System.out.println("\n=== 示例2:每2周3次(即:3/2)(14天),按周 ===2025-12-01 2025-12-10");
  245 +// List<PeriodResult> r2 = calculate("2025-12-01", "2025-12-10", "3/2", 2);
  246 +// r2.forEach(System.out::println);
  247 +// // 每2周 = 14天
  248 +// // 2025-01-01 ~ 2025-01-14
  249 +// // 2025-01-15 ~ 2025-01-28
  250 +// // 2025-01-29 ~ 2025-02-08(剩余11天)
  251 +// System.out.println("\n=== 示例3:每2个月4次(即:4/2)(30天),按月 === 2025-09-15 2025-12-31");
  252 +// List<PeriodResult> r3 = calculate("2025-09-15", "2025-12-31", "4/2", 3);
  253 +// r3.forEach(System.out::println);
  254 +// // 每1月 = 30天
  255 +// // 2025-01-01 ~ 2025-01-30
  256 +// // 2025-01-31 ~ 2025-02-28(30天?→ 实际是29天,但按30天算)
  257 +// // 2025-03-01 ~ 2025-03-15(不足)
  258 +//
  259 +// System.out.println("\n=== 示例4:每2年1次(即:1/2)(730天),按年 ===2025-01-01 2030-01-01");
  260 +// List<PeriodResult> r4 = calculate("2025-01-01", "2030-01-01", "1/2", 4);
  261 +// r4.forEach(System.out::println);
  262 +// // 每2年 = 730天
  263 +// // 2025-01-01 ~ 2025-12-26(+729d)
  264 +// // 2025-12-27 ~ 2027-12-21
  265 +// // 2027-12-22 ~ 2029-12-16
  266 +// // 2029-12-17 ~ 2030-01-01(最后一段)
  267 +// System.out.println("\n=== 示例5:每1年4次(即:4/1),按年(测试)=== 2023-09-15 2025-01-31");
  268 +// List<PeriodResult> r5 = calculate("2023-09-15", "2025-01-31", "4/1", 4);
  269 +// r5.forEach(System.out::println);
  270 +//
  271 +// // 新增示例:按次、季度、半年
  272 +// System.out.println("\n=== 示例6:按次单位,整个时间段算1个周期 === 2025-01-01 2025-12-31");
  273 +// List<PeriodResult> r6 = calculate("2025-01-01", "2025-12-31", "2/1", 5);
  274 +// r6.forEach(System.out::println);
  275 +//
  276 +// System.out.println("\n=== 示例7:每1季度2次(即:2/1),按季度(90天)=== 2025-01-01 2025-12-31");
  277 +// List<PeriodResult> r7 = calculate("2025-01-01", "2025-12-31", "2/1", 6);
  278 +// r7.forEach(System.out::println);
  279 +//
  280 +// System.out.println("\n=== 示例8:每1半年3次(即:3/1),按半年(180天)=== 2025-01-01 2025-12-31");
  281 +// List<PeriodResult> r8 = calculate("2025-01-01", "2025-12-31", "3/1", 7);
  282 +// r8.forEach(System.out::println);
167 } 283 }
168 } 284 }
urbanops-module-garden/src/main/resources/mapper/inspectionplan/InspectionPlanCommitMapper.xml
@@ -85,7 +85,12 @@ @@ -85,7 +85,12 @@
85 <if test="req.remark != null and req.remark !=''"> 85 <if test="req.remark != null and req.remark !=''">
86 AND a.remark LIKE CONCAT('%', #{req.remark} ,'%') 86 AND a.remark LIKE CONCAT('%', #{req.remark} ,'%')
87 </if> 87 </if>
88 - 88 + <if test="req.createTimeStart != null">
  89 + <![CDATA[AND DATE_FORMAT(a.create_time, '%Y-%m-%d') >= #{req.createTimeStart}]]>
  90 + </if>
  91 + <if test="req.createTimeEnd != null">
  92 + <![CDATA[AND DATE_FORMAT(a.create_time, '%Y-%m-%d') <= #{req.createTimeEnd}]]>
  93 + </if>
89 order by a.id desc 94 order by a.id desc
90 </select> 95 </select>
91 96
@@ -133,4 +138,4 @@ @@ -133,4 +138,4 @@
133 </foreach> 138 </foreach>
134 </if> 139 </if>
135 </select> 140 </select>
136 -</mapper>  
137 \ No newline at end of file 141 \ No newline at end of file
  142 +</mapper>
urbanops-module-garden/src/main/resources/mapper/inspectionplan/InspectionPlanMapper.xml
@@ -24,8 +24,10 @@ @@ -24,8 +24,10 @@
24 a.finish_state, 24 a.finish_state,
25 a.begin_time, 25 a.begin_time,
26 a.end_time 26 a.end_time
27 - FROM  
28 - garden_inspection_plan a 27 + FROM garden_inspection_plan a JOIN -- 建议用显式JOIN代替隐式连接,可读性更高
  28 + garden_inspection_plan_detail b ON
  29 + a.batch_no = b.batch_no
  30 + AND a.deleted = b.deleted
29 WHERE a.deleted = 0 31 WHERE a.deleted = 0
30 <if test="req.roadName != null and req.roadName !=''"> 32 <if test="req.roadName != null and req.roadName !=''">
31 AND a.road_name LIKE CONCAT('%',#{req.roadName},'%') 33 AND a.road_name LIKE CONCAT('%',#{req.roadName},'%')
@@ -44,14 +46,17 @@ @@ -44,14 +46,17 @@
44 </if> 46 </if>
45 <!--状态 1:未完成;2:已完成;3:已失效--> 47 <!--状态 1:未完成;2:已完成;3:已失效-->
46 <if test="req.finishState == 3"> 48 <if test="req.finishState == 3">
  49 + and b.finish_state = #{req.finishState}
47 <![CDATA[and a.end_time < #{req.localDate}]]> 50 <![CDATA[and a.end_time < #{req.localDate}]]>
48 </if> 51 </if>
49 <if test="req.finishState == 2"> 52 <if test="req.finishState == 2">
50 - and a.finish_state = #{req.finishState} 53 + and b.finish_state = #{req.finishState}
51 </if> 54 </if>
52 <if test="req.finishState == 1"> 55 <if test="req.finishState == 1">
53 - and a.finish_state = #{req.finishState} 56 + and b.finish_state = #{req.finishState}
54 <![CDATA[and a.end_time >= #{req.localDate}]]> 57 <![CDATA[and a.end_time >= #{req.localDate}]]>
  58 + <![CDATA[and b.end_time >= #{req.localDate}]]>
  59 + <![CDATA[and b.begin_time <= #{req.localDate}]]>
55 </if> 60 </if>
56 </select> 61 </select>
57 -</mapper>  
58 \ No newline at end of file 62 \ No newline at end of file
  63 +</mapper>
urbanops-module-garden/src/main/resources/mapper/maintainplan/MaintainPlanCommitMapper.xml
@@ -76,6 +76,12 @@ @@ -76,6 +76,12 @@
76 <if test="req.finishTime != null"> 76 <if test="req.finishTime != null">
77 AND DATE_FORMAT(c.finish_time, '%Y-%m-%d') = #{req.finishTime} 77 AND DATE_FORMAT(c.finish_time, '%Y-%m-%d') = #{req.finishTime}
78 </if> 78 </if>
  79 + <if test="req.createTimeStart != null">
  80 + <![CDATA[AND DATE_FORMAT(a.create_time, '%Y-%m-%d') >= #{req.createTimeStart}]]>
  81 + </if>
  82 + <if test="req.createTimeEnd != null">
  83 + <![CDATA[AND DATE_FORMAT(a.create_time, '%Y-%m-%d') <= #{req.createTimeEnd}]]>
  84 + </if>
79 </select> 85 </select>
80 86
81 <select id="appMaintainPlanCommitDetailPage" resultType="com.zteits.urbanops.module.garden.controller.app.maintainplan.vo.AppMaintainPlanCommitDetailPageRespVO"> 87 <select id="appMaintainPlanCommitDetailPage" resultType="com.zteits.urbanops.module.garden.controller.app.maintainplan.vo.AppMaintainPlanCommitDetailPageRespVO">
urbanops-module-garden/src/main/resources/mapper/maintainplan/MaintainPlanDetailMapper.xml
@@ -59,6 +59,8 @@ @@ -59,6 +59,8 @@
59 <if test="req.finishState == 1"> 59 <if test="req.finishState == 1">
60 and c.finish_state = #{req.finishState} 60 and c.finish_state = #{req.finishState}
61 <![CDATA[and c.end_time >= #{req.localDateTime}]]> 61 <![CDATA[and c.end_time >= #{req.localDateTime}]]>
  62 + <![CDATA[and c.begin_time <= #{req.localDateTime}]]>
  63 +
62 </if> 64 </if>
63 </select> 65 </select>
64 66
urbanops-module-garden/src/main/resources/mapper/maintainplan/MaintainPlanMapper.xml
@@ -26,8 +26,12 @@ @@ -26,8 +26,12 @@
26 a.end_time 26 a.end_time
27 FROM 27 FROM
28 garden_maintain_plan a 28 garden_maintain_plan a
29 - WHERE a.deleted=0  
30 - <if test="req.roadName != null and req.roadName !=''"> 29 + JOIN -- 建议用显式JOIN代替隐式连接,可读性更高
  30 + garden_maintain_plan_detail b ON
  31 + a.batch_no = b.batch_no
  32 + AND a.deleted = b.deleted
  33 + WHERE a.deleted = 0
  34 + <if test="req.roadName != null and req.roadName !=''">
31 AND a.road_name LIKE CONCAT('%',#{req.roadName},'%') 35 AND a.road_name LIKE CONCAT('%',#{req.roadName},'%')
32 </if> 36 </if>
33 <if test="req.batchNos != null and req.batchNos.size() > 0"> 37 <if test="req.batchNos != null and req.batchNos.size() > 0">
@@ -44,15 +48,17 @@ @@ -44,15 +48,17 @@
44 </if> 48 </if>
45 <!--状态 1:未完成;2:已完成;3:已失效--> 49 <!--状态 1:未完成;2:已完成;3:已失效-->
46 <if test="req.finishState == 3"> 50 <if test="req.finishState == 3">
47 - and a.finish_state = #{req.finishState} 51 + and b.finish_state = #{req.finishState}
48 <![CDATA[and a.end_time < #{req.localDate}]]> 52 <![CDATA[and a.end_time < #{req.localDate}]]>
49 </if> 53 </if>
50 <if test="req.finishState == 2"> 54 <if test="req.finishState == 2">
51 - and a.finish_state = #{req.finishState} 55 + and b.finish_state = #{req.finishState}
52 </if> 56 </if>
53 <if test="req.finishState == 1"> 57 <if test="req.finishState == 1">
54 - and a.finish_state = #{req.finishState} 58 + and b.finish_state = #{req.finishState}
55 <![CDATA[and a.end_time >= #{req.localDate}]]> 59 <![CDATA[and a.end_time >= #{req.localDate}]]>
  60 + <![CDATA[and b.end_time >= #{req.localDate}]]>
  61 + <![CDATA[and b.begin_time <= #{req.localDate}]]>
56 </if> 62 </if>
57 </select> 63 </select>
58 64
@@ -103,6 +109,8 @@ @@ -103,6 +109,8 @@
103 <if test="req.finishState == 1"> 109 <if test="req.finishState == 1">
104 and c.finish_state = #{req.finishState} 110 and c.finish_state = #{req.finishState}
105 <![CDATA[and c.end_time >= #{req.localDateTime}]]> 111 <![CDATA[and c.end_time >= #{req.localDateTime}]]>
  112 + <![CDATA[and c.begin_time <= #{req.localDateTime}]]>
  113 +
106 </if> 114 </if>
107 </select> 115 </select>
108 116
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/admin/attachment/AttachmentController.java
@@ -101,4 +101,11 @@ public class AttachmentController { @@ -101,4 +101,11 @@ public class AttachmentController {
101 BeanUtils.toBean(list, AttachmentRespVO.class)); 101 BeanUtils.toBean(list, AttachmentRespVO.class));
102 } 102 }
103 103
104 -}  
105 \ No newline at end of file 104 \ No newline at end of file
  105 + @PostMapping("/getByCondition")
  106 + @Operation(summary = "获得工单附件信息")
  107 + @PreAuthorize("@ss.hasPermission('workorder:attachment:query')")
  108 + public CommonResult<List<AttachmentRespVO>> getAttachmentByCondition(@Valid @RequestBody AttachmentReqVO reqVO) {
  109 + List<AttachmentDO> attachment = attachmentService.getAttachmentByCondition(reqVO);
  110 + return success(BeanUtils.toBean(attachment, AttachmentRespVO.class));
  111 + }
  112 +}
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/admin/attachment/vo/AttachmentPageReqVO.java
@@ -19,7 +19,7 @@ public class AttachmentPageReqVO extends PageParam { @@ -19,7 +19,7 @@ public class AttachmentPageReqVO extends PageParam {
19 @Schema(description = "业务线:yl 园林,wy 物业,sz 市政 ") 19 @Schema(description = "业务线:yl 园林,wy 物业,sz 市政 ")
20 private String busiLine; 20 private String busiLine;
21 21
22 - @Schema(description = "业务类型:01 问题图片,02 街道图片,03 选景图片", example = "1") 22 + @Schema(description = "业务类型:01 问题图片,02 进行中图片,03 已完成图片", example = "01")
23 private String busiType; 23 private String busiType;
24 24
25 @Schema(description = "文件名称") 25 @Schema(description = "文件名称")
@@ -41,4 +41,4 @@ public class AttachmentPageReqVO extends PageParam { @@ -41,4 +41,4 @@ public class AttachmentPageReqVO extends PageParam {
41 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 41 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
42 private LocalDateTime[] createTime; 42 private LocalDateTime[] createTime;
43 43
44 -}  
45 \ No newline at end of file 44 \ No newline at end of file
  45 +}
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/admin/attachment/vo/AttachmentReqVO.java 0 → 100644
  1 +package com.zteits.urbanops.module.workorder.controller.admin.attachment.vo;
  2 +
  3 +import com.zteits.urbanops.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import org.springframework.format.annotation.DateTimeFormat;
  7 +
  8 +import java.time.LocalDateTime;
  9 +
  10 +import static com.zteits.urbanops.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +
  12 +@Schema(description = "管理后台 - 工单附件信息分页 Request VO")
  13 +@Data
  14 +public class AttachmentReqVO extends PageParam {
  15 +
  16 + @Schema(description = "工单号")
  17 + private String orderNo;
  18 +
  19 + @Schema(description = "业务线:yl 园林,wy 物业,sz 市政 ")
  20 + private String busiLine;
  21 +
  22 + @Schema(description = "业务类型:01 问题图片,02 进行中图片,03 已完成图片", example = "01")
  23 + private String busiType;
  24 +
  25 +}
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/admin/maininfo/vo/MainInfoHasTaskPageReqVO.java 0 → 100644
  1 +package com.zteits.urbanops.module.workorder.controller.admin.maininfo.vo;
  2 +
  3 +import com.zteits.urbanops.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import jakarta.validation.constraints.NotNull;
  6 +import lombok.Data;
  7 +import org.springframework.format.annotation.DateTimeFormat;
  8 +
  9 +import java.time.LocalDateTime;
  10 +
  11 +import static com.zteits.urbanops.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  12 +
  13 +/**
  14 + * 类描述:工单工作流分页请求 reqVO
  15 + * 创建人:yanhuiqing
  16 + * 创建时间:2025/12/15 21:41
  17 + * 修改人:yanhuiqing
  18 + * 修改时间:2025/12/15 21:41
  19 + * 修改备注:
  20 + *
  21 + * @author yanhuiqing
  22 + * @version 1.0
  23 + */
  24 +@Schema(description = "管理后台 - 工单工作流信息分页 Request VO")
  25 +@Data
  26 +public class MainInfoHasTaskPageReqVO extends PageParam {
  27 + @NotNull
  28 + @Schema(description = "任务指派人", example = "admin")
  29 + private Long userId;
  30 + @Schema(description = "流程定义key", example = "quik_local_test")
  31 + private String key;
  32 + @Schema(description = "开始时间")
  33 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  34 + private LocalDateTime[] startTime;
  35 + @Schema(description = "结束时间")
  36 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  37 + private LocalDateTime[] endTime;
  38 + @Schema(description = "业务线:yl 园林,wy 物业,sz 市政 ")
  39 + private String busiLine;
  40 + @Schema(description = "工单号")
  41 + private String orderNo;
  42 + @Schema(description = "工单名称", example = "张三")
  43 + private String orderName;
  44 + @Schema(description = "工单描述", example = "你说的对")
  45 + private String remark;
  46 + @Schema(description = "道路名称", example = "王五")
  47 + private String roadName;
  48 + @Schema(description = "街道名称", example = "芋艿")
  49 + private String streetName;
  50 + @Schema(description = "养护级别ID", example = "1")
  51 + private Integer curingLevelId;
  52 +}
0 \ No newline at end of file 53 \ No newline at end of file
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/admin/materialdetail/MaterialDetailController.java
@@ -101,4 +101,17 @@ public class MaterialDetailController { @@ -101,4 +101,17 @@ public class MaterialDetailController {
101 BeanUtils.toBean(list, MaterialDetailRespVO.class)); 101 BeanUtils.toBean(list, MaterialDetailRespVO.class));
102 } 102 }
103 103
104 -}  
105 \ No newline at end of file 104 \ No newline at end of file
  105 + /**
  106 + * 批量创建物料明细
  107 + * @param materialDetailSaveReqVOs 物料明细保存请求列表
  108 + * @return 统一响应结果
  109 + */
  110 + @PostMapping("/batch-create")
  111 + @Operation(summary = "批量创建工单耗材明细")
  112 + @PreAuthorize("@ss.hasPermission('workorder:material-detail:create')")
  113 + public CommonResult<Boolean> batchCreateMaterialDetail(
  114 + @RequestBody @Valid List<MaterialDetailSaveReqVO> materialDetailSaveReqVOs) {
  115 + return success(materialDetailService.batchCreateMaterialDetail(materialDetailSaveReqVOs));
  116 + }
  117 +
  118 +}
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/admin/materialdetail/vo/MaterialDetailSaveReqVO.java
@@ -16,14 +16,6 @@ public class MaterialDetailSaveReqVO { @@ -16,14 +16,6 @@ public class MaterialDetailSaveReqVO {
16 @NotEmpty(message = "工单号不能为空") 16 @NotEmpty(message = "工单号不能为空")
17 private String orderNo; 17 private String orderNo;
18 18
19 - @Schema(description = "提交用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "10300")  
20 - @NotNull(message = "提交用户ID不能为空")  
21 - private Long userId;  
22 -  
23 - @Schema(description = "提交用户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")  
24 - @NotEmpty(message = "提交用户名称不能为空")  
25 - private String userName;  
26 -  
27 @Schema(description = "种类ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "27821") 19 @Schema(description = "种类ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "27821")
28 @NotNull(message = "种类ID不能为空") 20 @NotNull(message = "种类ID不能为空")
29 private Long classifyId; 21 private Long classifyId;
@@ -60,7 +52,17 @@ public class MaterialDetailSaveReqVO { @@ -60,7 +52,17 @@ public class MaterialDetailSaveReqVO {
60 private String status; 52 private String status;
61 53
62 @Schema(description = "描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "你说的对") 54 @Schema(description = "描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "你说的对")
63 - @NotEmpty(message = "描述不能为空")  
64 private String remark; 55 private String remark;
65 56
66 -}  
67 \ No newline at end of file 57 \ No newline at end of file
  58 + /*耗材ID*/
  59 + @Schema(description = "耗材ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "111")
  60 + @NotNull(message = "物料ID不能为空")
  61 + private Long materialId;
  62 +
  63 + /**
  64 + * 耗材名称
  65 + */
  66 + @Schema(description = "耗材名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "耗材名称")
  67 + @NotEmpty(message = "耗材名称不能为空")
  68 + private String materialName;
  69 +}
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/AppGardenWorkOrderController.java
@@ -104,7 +104,7 @@ public class AppGardenWorkOrderController { @@ -104,7 +104,7 @@ public class AppGardenWorkOrderController {
104 } 104 }
105 105
106 @PutMapping("/return") 106 @PutMapping("/return")
107 - @Operation(summary = "退回任务", description = "用于【流程详情】的【退回】按钮") 107 + @Operation(summary = " app - 退回任务", description = "用于【流程详情】的【退回】按钮")
108 //@PreAuthorize("@ss.hasPermission('bpm:garden-workorder:update')") 108 //@PreAuthorize("@ss.hasPermission('bpm:garden-workorder:update')")
109 public CommonResult<Boolean> returnTask(@Valid @RequestBody AppGardenTaskReturnReqVO reqVO) { 109 public CommonResult<Boolean> returnTask(@Valid @RequestBody AppGardenTaskReturnReqVO reqVO) {
110 gardenService.returnTask(reqVO); 110 gardenService.returnTask(reqVO);
@@ -112,7 +112,7 @@ public class AppGardenWorkOrderController { @@ -112,7 +112,7 @@ public class AppGardenWorkOrderController {
112 } 112 }
113 113
114 @PutMapping("/withdraw") 114 @PutMapping("/withdraw")
115 - @Operation(summary = "撤回任务") 115 + @Operation(summary = "app - 撤回任务")
116 //@PreAuthorize("@ss.hasPermission('bpm:garden-workorder:update')") 116 //@PreAuthorize("@ss.hasPermission('bpm:garden-workorder:update')")
117 public CommonResult<Boolean> withdrawTask(@RequestParam("taskId") String taskId) { 117 public CommonResult<Boolean> withdrawTask(@RequestParam("taskId") String taskId) {
118 gardenService.withdrawTask(taskId); 118 gardenService.withdrawTask(taskId);
@@ -120,7 +120,7 @@ public class AppGardenWorkOrderController { @@ -120,7 +120,7 @@ public class AppGardenWorkOrderController {
120 } 120 }
121 121
122 @PutMapping("/delegate") 122 @PutMapping("/delegate")
123 - @Operation(summary = "委派任务", description = "用于【流程详情】的【委派】按钮") 123 + @Operation(summary = "app - 委派任务", description = "用于【流程详情】的【委派】按钮")
124 //@PreAuthorize("@ss.hasPermission('bpm:garden-workorder:update')") 124 //@PreAuthorize("@ss.hasPermission('bpm:garden-workorder:update')")
125 public CommonResult<Boolean> delegateTask(@Valid @RequestBody AppGardenTaskDelegateReqVO reqVO) { 125 public CommonResult<Boolean> delegateTask(@Valid @RequestBody AppGardenTaskDelegateReqVO reqVO) {
126 gardenService.delegateTask(reqVO); 126 gardenService.delegateTask(reqVO);
@@ -128,7 +128,7 @@ public class AppGardenWorkOrderController { @@ -128,7 +128,7 @@ public class AppGardenWorkOrderController {
128 } 128 }
129 129
130 @PutMapping("/transfer") 130 @PutMapping("/transfer")
131 - @Operation(summary = "转派任务", description = "用于【流程详情】的【转派】按钮") 131 + @Operation(summary = "app - 转派任务", description = "用于【流程详情】的【转派】按钮")
132 //@PreAuthorize("@ss.hasPermission('bpm:garden-workorder:update')") 132 //@PreAuthorize("@ss.hasPermission('bpm:garden-workorder:update')")
133 public CommonResult<Boolean> transferTask(@Valid @RequestBody AppGardenTaskTransferReqVO reqVO) { 133 public CommonResult<Boolean> transferTask(@Valid @RequestBody AppGardenTaskTransferReqVO reqVO) {
134 gardenService.transferTask(reqVO); 134 gardenService.transferTask(reqVO);
@@ -149,4 +149,19 @@ public class AppGardenWorkOrderController { @@ -149,4 +149,19 @@ public class AppGardenWorkOrderController {
149 PageResult<AppGardenTaskRespVO> pageResult = gardenService.getTaskTodoPage(pageVO); 149 PageResult<AppGardenTaskRespVO> pageResult = gardenService.getTaskTodoPage(pageVO);
150 return success(pageResult); 150 return success(pageResult);
151 } 151 }
  152 +
  153 + @GetMapping("doneBuzSimplePage")
  154 + @Operation(summary = "app - 获取工单业务已办任务分页")
  155 + //@PreAuthorize("@ss.hasPermission('bpm:garden-workorder:query')")
  156 + public CommonResult<PageResult<AppGardenWorkOrderRespVO>> getTaskDoneBuzSimplePage(@Valid AppGardenWorkOrderPageReqVO pageVO) {
  157 + PageResult<AppGardenWorkOrderRespVO> pageResult = gardenService.getTaskDoneBuzSimplePage(pageVO);
  158 + return success(pageResult);
  159 + }
  160 + @GetMapping("todoBuzSimplePage")
  161 + @Operation(summary = "app - 获取工单业务待办任务分页")
  162 + //@PreAuthorize("@ss.hasPermission('bpm:garden-workorder:query')")
  163 + public CommonResult<PageResult<AppGardenWorkOrderRespVO>> getTaskTodoBuzSimplePage(@Valid AppGardenWorkOrderPageReqVO pageVO) {
  164 + PageResult<AppGardenWorkOrderRespVO> pageResult = gardenService.getTaskTodoBuzSimplePage(pageVO);
  165 + return success(pageResult);
  166 + }
152 } 167 }
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/app/garden/vo/AppGardenWorkOrderRespVO.java
@@ -4,6 +4,7 @@ import com.zteits.urbanops.module.workorder.controller.admin.maininfo.vo.MainInf @@ -4,6 +4,7 @@ import com.zteits.urbanops.module.workorder.controller.admin.maininfo.vo.MainInf
4 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 5 import lombok.Data;
6 6
  7 +import java.time.LocalDateTime;
7 import java.util.List; 8 import java.util.List;
8 9
9 /** 10 /**
@@ -21,4 +22,22 @@ public class AppGardenWorkOrderRespVO extends MainInfoRespVO { @@ -21,4 +22,22 @@ public class AppGardenWorkOrderRespVO extends MainInfoRespVO {
21 22
22 @Schema(description = "处理完成照片", example = "9184") 23 @Schema(description = "处理完成照片", example = "9184")
23 private List<String> completeImgsList; 24 private List<String> completeImgsList;
  25 +
  26 + @Schema(description = "任务id")
  27 + private String taskId;
  28 +
  29 + @Schema(description = "任务名称")
  30 + private String taskName;
  31 +
  32 + @Schema(description = "流程定义名称")
  33 + private String processDefinitionName;
  34 +
  35 + @Schema(description = "任务开始时间")
  36 + private LocalDateTime startTime;
  37 +
  38 + @Schema(description = "任务结束时间")
  39 + private LocalDateTime endTime;
  40 +
  41 + @Schema(description = "流程定义key")
  42 + private String key_;
24 } 43 }
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/convert/garden/AppGardenTaskConvert.java
1 package com.zteits.urbanops.module.workorder.convert.garden; 1 package com.zteits.urbanops.module.workorder.convert.garden;
2 2
  3 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
3 import com.zteits.urbanops.framework.common.pojo.PageResult; 4 import com.zteits.urbanops.framework.common.pojo.PageResult;
4 import com.zteits.urbanops.framework.common.util.collection.CollectionUtils; 5 import com.zteits.urbanops.framework.common.util.collection.CollectionUtils;
5 import com.zteits.urbanops.framework.common.util.date.DateUtils; 6 import com.zteits.urbanops.framework.common.util.date.DateUtils;
@@ -11,7 +12,12 @@ import com.zteits.urbanops.module.bpm.dal.dataobject.definition.BpmProcessDefini @@ -11,7 +12,12 @@ import com.zteits.urbanops.module.bpm.dal.dataobject.definition.BpmProcessDefini
11 import com.zteits.urbanops.module.bpm.framework.flowable.core.util.FlowableUtils; 12 import com.zteits.urbanops.module.bpm.framework.flowable.core.util.FlowableUtils;
12 import com.zteits.urbanops.module.system.api.dept.dto.DeptRespDTO; 13 import com.zteits.urbanops.module.system.api.dept.dto.DeptRespDTO;
13 import com.zteits.urbanops.module.system.api.user.dto.AdminUserRespDTO; 14 import com.zteits.urbanops.module.system.api.user.dto.AdminUserRespDTO;
  15 +import com.zteits.urbanops.module.workorder.api.constant.BpmCommonConstant;
  16 +import com.zteits.urbanops.module.workorder.controller.app.garden.vo.AppGardenWorkOrderRespVO;
14 import com.zteits.urbanops.module.workorder.controller.app.garden.vo.task.AppGardenTaskRespVO; 17 import com.zteits.urbanops.module.workorder.controller.app.garden.vo.task.AppGardenTaskRespVO;
  18 +import com.zteits.urbanops.module.workorder.dal.dataobject.attachment.AttachmentDO;
  19 +import com.zteits.urbanops.module.workorder.dal.dataobject.maininfo.MainInfoExtDO;
  20 +import com.zteits.urbanops.module.workorder.dal.mysql.attachment.AttachmentMapper;
15 import org.flowable.engine.history.HistoricProcessInstance; 21 import org.flowable.engine.history.HistoricProcessInstance;
16 import org.flowable.engine.runtime.ProcessInstance; 22 import org.flowable.engine.runtime.ProcessInstance;
17 import org.flowable.task.api.Task; 23 import org.flowable.task.api.Task;
@@ -19,8 +25,11 @@ import org.flowable.task.api.history.HistoricTaskInstance; @@ -19,8 +25,11 @@ import org.flowable.task.api.history.HistoricTaskInstance;
19 import org.mapstruct.Mapper; 25 import org.mapstruct.Mapper;
20 import org.mapstruct.factory.Mappers; 26 import org.mapstruct.factory.Mappers;
21 27
  28 +import java.util.Arrays;
  29 +import java.util.Collections;
22 import java.util.List; 30 import java.util.List;
23 import java.util.Map; 31 import java.util.Map;
  32 +import java.util.stream.Collectors;
24 33
25 import static com.zteits.urbanops.framework.common.util.collection.MapUtils.findAndThen; 34 import static com.zteits.urbanops.framework.common.util.collection.MapUtils.findAndThen;
26 35
@@ -88,4 +97,80 @@ public interface AppGardenTaskConvert { @@ -88,4 +97,80 @@ public interface AppGardenTaskConvert {
88 return new PageResult<>(taskVOList, pageResult.getTotal()); 97 return new PageResult<>(taskVOList, pageResult.getTotal());
89 } 98 }
90 99
  100 + default PageResult<AppGardenWorkOrderRespVO> buildBuziTaskPage(PageResult<MainInfoExtDO> pageResult, AttachmentMapper attachmentMapper){
  101 + // 1. 源分页对象为空,返回空分页
  102 + if (pageResult == null) {
  103 + return PageResult.empty();
  104 + }
  105 +
  106 + // 2. 转换列表数据,保留分页参数(总数、页码、页大小等)
  107 + List<AppGardenWorkOrderRespVO> targetList = convertList(pageResult.getList(), attachmentMapper);
  108 + return new PageResult<>(targetList, pageResult.getTotal());
  109 + }
  110 +
  111 + default List<AppGardenWorkOrderRespVO> convertList(List<MainInfoExtDO> sourceList, AttachmentMapper attachmentMapper) {
  112 + // 1. 源列表为空,返回空列表(避免NPE)
  113 + if (sourceList == null || sourceList.isEmpty()) {
  114 + return Collections.emptyList();
  115 + }
  116 +
  117 + // 2. 遍历源列表,调用单对象转换方法
  118 + return sourceList.stream()
  119 + .map(source -> convert(source, attachmentMapper))
  120 + .collect(Collectors.toList());
  121 + }
  122 +
  123 + /**
  124 + * MainInfoExtDO → AppGardenWorkOrderRespVO
  125 + * @param source 源对象
  126 + * @param attachmentMapper 附件Mapper,用于查询图片列表
  127 + * @return 目标对象
  128 + */
  129 + default AppGardenWorkOrderRespVO convert(MainInfoExtDO source, AttachmentMapper attachmentMapper) {
  130 + // 1. 源对象为空,直接返回null
  131 + if (source == null) {
  132 + return null;
  133 + }
  134 +
  135 + AppGardenWorkOrderRespVO target = new AppGardenWorkOrderRespVO();
  136 + org.springframework.beans.BeanUtils.copyProperties(source, target);
  137 +
  138 + // 3. 手动赋值扩展字段:查询问题图片列表和完成图片列表
  139 + List<String> problemImgsList = queryAttachment(
  140 + source.getBusiLine(),
  141 + BpmCommonConstant.PROBLEM_IMG_GROUP,
  142 + source.getOrderNo(),
  143 + attachmentMapper
  144 + );
  145 + List<String> completeImgsList = queryAttachment(
  146 + source.getBusiLine(),
  147 + BpmCommonConstant.RESULT_IMG_GROUP,
  148 + source.getOrderNo(),
  149 + attachmentMapper
  150 + );
  151 + target.setProblemImgsList(problemImgsList);
  152 + target.setCompleteImgsList(completeImgsList);
  153 +
  154 + return target;
  155 + }
  156 +
  157 + default List<String> queryAttachment(String busiLine, String busiType, String orderNo, AttachmentMapper attachmentMapper) {
  158 +
  159 + LambdaQueryWrapper<AttachmentDO> queryWrapper = new LambdaQueryWrapper<AttachmentDO>()
  160 + .eq(AttachmentDO::getBusiLine, busiLine)
  161 + .eq(AttachmentDO::getBusiType, busiType)
  162 + .eq(AttachmentDO::getOrderNo, orderNo);
  163 + List<AttachmentDO> attachments = attachmentMapper.selectList(queryWrapper);
  164 + if (attachments == null || attachments.isEmpty()) {
  165 + return List.of();
  166 + }
  167 + return attachments.stream()
  168 + .map(AttachmentDO::getFileNames)
  169 + .filter(s -> s != null && !s.isEmpty())
  170 + .flatMap(s -> Arrays.stream(s.split(",")).map(String::trim))
  171 + .filter(s -> !s.isEmpty())
  172 + .distinct()
  173 + .collect(Collectors.toList());
  174 + }
  175 +
91 } 176 }
92 \ No newline at end of file 177 \ No newline at end of file
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/dal/dataobject/attachment/AttachmentDO.java
@@ -32,11 +32,11 @@ public class AttachmentDO extends BaseDO { @@ -32,11 +32,11 @@ public class AttachmentDO extends BaseDO {
32 */ 32 */
33 private String orderNo; 33 private String orderNo;
34 /** 34 /**
35 - * 业务线:yl 园林,wy 物业,sz 市政 35 + * 业务线:yl 园林,wy 物业,sz 市政
36 */ 36 */
37 private String busiLine; 37 private String busiLine;
38 /** 38 /**
39 - * 业务类型:01 问题图片,02 街道图片,03 选景图片 39 + * 业务类型:01 问题图片,02 进行中图片,03 已完成图片
40 */ 40 */
41 private String busiType; 41 private String busiType;
42 /** 42 /**
@@ -61,4 +61,4 @@ public class AttachmentDO extends BaseDO { @@ -61,4 +61,4 @@ public class AttachmentDO extends BaseDO {
61 private String remark; 61 private String remark;
62 62
63 63
64 -}  
65 \ No newline at end of file 64 \ No newline at end of file
  65 +}
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/dal/dataobject/maininfo/MainInfoExtDO.java 0 → 100644
  1 +package com.zteits.urbanops.module.workorder.dal.dataobject.maininfo;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.KeySequence;
  4 +import com.baomidou.mybatisplus.annotation.TableName;
  5 +import com.zteits.urbanops.framework.mybatis.core.dataobject.BaseDO;
  6 +import lombok.*;
  7 +
  8 +import java.math.BigDecimal;
  9 +import java.time.LocalDateTime;
  10 +
  11 +/**
  12 + * 类描述:工单扩展信息,支持工作流任务信息 DO
  13 + * 创建人:yanhuiqing
  14 + * 创建时间:2025/12/15 17:37
  15 + * 修改人:yanhuiqing
  16 + * 修改时间:2025/12/15 17:37
  17 + * 修改备注:
  18 + *
  19 + * @author yanhuiqing
  20 + * @version 1.0
  21 + */
  22 +
  23 +@Data
  24 +@EqualsAndHashCode(callSuper = true)
  25 +@ToString(callSuper = true)
  26 +@Builder
  27 +@NoArgsConstructor
  28 +@AllArgsConstructor
  29 +public class MainInfoExtDO extends BaseDO {
  30 +
  31 + /**
  32 + * ID
  33 + */
  34 + private Long id;
  35 + /**
  36 + * 业务线:yl 园林,wy 物业,sz 市政
  37 + */
  38 + private String busiLine;
  39 + /**
  40 + * 工单号
  41 + */
  42 + private String orderNo;
  43 + /**
  44 + * 工单名称
  45 + */
  46 + private String orderName;
  47 + /**
  48 + * 来源ID
  49 + */
  50 + private Integer sourceId;
  51 + /**
  52 + * 来源名称
  53 + */
  54 + private String sourceName;
  55 + /**
  56 + * 道路ID
  57 + */
  58 + private Long roadId;
  59 + /**
  60 + * 道路名称
  61 + */
  62 + private String roadName;
  63 + /**
  64 + * 街道ID
  65 + */
  66 + private String streetId;
  67 + /**
  68 + * 街道名称
  69 + */
  70 + private String streetName;
  71 + /**
  72 + * 养护级别ID
  73 + */
  74 + private Integer curingLevelId;
  75 + /**
  76 + * 养护级别
  77 + */
  78 + private String curingLevelName;
  79 + /**
  80 + * 提交日期
  81 + */
  82 + private LocalDateTime commitDate;
  83 +
  84 + /**
  85 + * 完成时间
  86 + */
  87 + private LocalDateTime finishDate;
  88 + /**
  89 + * 紧急程度:1:特急;2:紧急;3:一般
  90 + */
  91 + private Integer pressingType;
  92 + /**
  93 + * 提交用户ID
  94 + */
  95 + private Long userId;
  96 + /**
  97 + * 提交用户名称
  98 + */
  99 + private String userName;
  100 + /**
  101 + * 部门id
  102 + */
  103 + private Long companyId;
  104 + /**
  105 + * 经纬度类型: 1:国标; 2:百度;3:高德;4:腾讯
  106 + */
  107 + private Integer latLonType;
  108 + /**
  109 + * 经度
  110 + */
  111 + private BigDecimal lat;
  112 + /**
  113 + * 维度
  114 + */
  115 + private BigDecimal lon;
  116 + /**
  117 + * 经纬度地址
  118 + */
  119 + private String lonLatAddress;
  120 + /**
  121 + * 三方工单ID
  122 + */
  123 + private String thirdWorkNo;
  124 + /**
  125 + * 三方工单结果上报状态:1:待推送;2:推送成功;3:推送失败
  126 + */
  127 + private Integer thirdPushState;
  128 + /**
  129 + * 业务状态
  130 + */
  131 + private String buzStatus;
  132 + /**
  133 + * 审批状态
  134 + */
  135 + private Integer status;
  136 + /**
  137 + * 流程实例的编号
  138 + */
  139 + private String processInstanceId;
  140 + /**
  141 + * 工单描述
  142 + */
  143 + private String remark;
  144 + /**
  145 + * 工单完成结果描述
  146 + */
  147 + private String handleResult;
  148 + /**
  149 + * 任务id
  150 + */
  151 + private String taskId;
  152 + /**
  153 + * 任务名称
  154 + */
  155 + private String taskName;
  156 + /**
  157 + * 流程定义名称
  158 + */
  159 + private String processDefinitionName;
  160 + /**
  161 + * 任务开始时间
  162 + */
  163 + private LocalDateTime startTime;
  164 + /**
  165 + * 任务结束时间
  166 + */
  167 + private LocalDateTime endTime;
  168 + /**
  169 + * 流程定义key
  170 + */
  171 + private String key_;
  172 +
  173 +
  174 +}
0 \ No newline at end of file 175 \ No newline at end of file
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/dal/dataobject/materialdetail/MaterialDetailDO.java
@@ -66,7 +66,7 @@ public class MaterialDetailDO extends BaseDO { @@ -66,7 +66,7 @@ public class MaterialDetailDO extends BaseDO {
66 /** 66 /**
67 * 使用数量 67 * 使用数量
68 */ 68 */
69 - private Double userCount; 69 + private Long userCount;
70 /** 70 /**
71 * 单位 71 * 单位
72 */ 72 */
@@ -80,5 +80,11 @@ public class MaterialDetailDO extends BaseDO { @@ -80,5 +80,11 @@ public class MaterialDetailDO extends BaseDO {
80 */ 80 */
81 private String remark; 81 private String remark;
82 82
  83 + /*耗材ID*/
  84 + private Long materialId;
83 85
84 -}  
85 \ No newline at end of file 86 \ No newline at end of file
  87 + /**
  88 + * 耗材名称
  89 + */
  90 + private String materialName;
  91 +}
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/dal/mysql/maininfo/MainInfoExtMapper.java 0 → 100644
  1 +package com.zteits.urbanops.module.workorder.dal.mysql.maininfo;
  2 +
  3 +import com.baomidou.mybatisplus.core.conditions.Wrapper;
  4 +import com.baomidou.mybatisplus.core.metadata.IPage;
  5 +import com.zteits.urbanops.framework.common.pojo.PageParam;
  6 +import com.zteits.urbanops.framework.common.pojo.PageResult;
  7 +import com.zteits.urbanops.framework.mybatis.core.mapper.BaseMapperX;
  8 +import com.zteits.urbanops.framework.mybatis.core.util.MyBatisUtils;
  9 +import com.zteits.urbanops.module.workorder.controller.admin.maininfo.vo.MainInfoHasTaskPageReqVO;
  10 +import com.zteits.urbanops.module.workorder.controller.admin.maininfo.vo.MainInfoPageReqVO;
  11 +import com.zteits.urbanops.module.workorder.dal.dataobject.maininfo.MainInfoDO;
  12 +import com.zteits.urbanops.module.workorder.dal.dataobject.maininfo.MainInfoExtDO;
  13 +import org.apache.ibatis.annotations.*;
  14 +
  15 +/**
  16 + * 类描述:工单工作流扩展Mapper
  17 + * 创建人:yanhuiqing
  18 + * 创建时间:2025/12/15 17:27
  19 + * 修改人:yanhuiqing
  20 + * 修改时间:2025/12/15 17:27
  21 + * 修改备注:
  22 + *
  23 + * @author yanhuiqing
  24 + * @version 1.0
  25 + */
  26 +@Mapper
  27 +public interface MainInfoExtMapper extends BaseMapperX<MainInfoDO> {
  28 + @Select({
  29 + "<script>",
  30 + "SELECT",
  31 + " m.*,",
  32 + " t.ID_ AS task_id,",
  33 + " t.NAME_ AS task_name,",
  34 + " pd.NAME_ AS process_definition_name,",
  35 + " t.START_TIME_,",
  36 + " t.END_TIME_,",
  37 + " pd.KEY_",
  38 + "FROM act_hi_taskinst t",
  39 + "LEFT JOIN act_re_procdef pd ON t.PROC_DEF_ID_ = pd.ID_",
  40 + "LEFT JOIN workorder_main_info m ON t.PROC_INST_ID_ = m.process_instance_id AND m.deleted = 0",
  41 + "WHERE 1=1",
  42 + " AND t.END_TIME_ IS NOT NULL",
  43 + " <if test='query.userId != null'>",
  44 + " AND t.ASSIGNEE_ = #{query.userId}",
  45 + " </if>",
  46 + " <if test='query.key != null'>",
  47 + " AND pd.KEY_ = #{query.key}",
  48 + " </if>",
  49 + " <if test='query.startTime != null'>",
  50 + " <![CDATA[ AND t.START_TIME_ >= #{query.startTime} ]]>",
  51 + " </if>",
  52 + " <if test='query.endTime != null'>",
  53 + " <![CDATA[ AND t.END_TIME_ <= #{query.endTime} ]]>",
  54 + " </if>",
  55 + " <if test='query.busiLine != null'>",
  56 + " AND m.busi_line = #{query.busiLine}",
  57 + " </if>",
  58 + " <if test=\"query.orderNo != null and query.orderNo != ''\">",
  59 + " AND m.order_no LIKE CONCAT('%', #{query.orderNo}, '%')",
  60 + " </if>",
  61 + " <if test=\"query.orderName != null and query.orderName != ''\">",
  62 + " AND m.order_name LIKE CONCAT('%', #{query.orderName}, '%')",
  63 + " </if>",
  64 + " <if test=\"query.remark != null and query.remark != ''\">",
  65 + " AND m.remark LIKE CONCAT('%', #{query.remark}, '%')",
  66 + " </if>",
  67 + " <if test=\"query.roadName != null and query.roadName != ''\">",
  68 + " AND m.road_name LIKE CONCAT('%', #{query.roadName}, '%')",
  69 + " </if>",
  70 + " <if test=\"query.streetName != null and query.streetName != ''\">",
  71 + " AND m.street_name = #{query.streetName}",
  72 + " <!-- 若需模糊匹配,改为:AND m.street_name LIKE CONCAT('%', #{query.streetName}, '%') -->",
  73 + " </if>",
  74 + " <if test='query.curingLevelId != null'>",
  75 + " AND m.curing_level_id = #{query.curingLevelId}",
  76 + " </if>",
  77 + "ORDER BY t.END_TIME_ DESC",
  78 + "</script>"
  79 + })
  80 + @Results({
  81 + @Result(column = "id", property = "id"),
  82 + @Result(column = "busi_line", property = "busiLine"),
  83 + @Result(column = "order_no", property = "orderNo"),
  84 + @Result(column = "order_name", property = "orderName"),
  85 + @Result(column = "source_id", property = "sourceId"),
  86 + @Result(column = "source_name", property = "sourceName"),
  87 + @Result(column = "road_id", property = "roadId"),
  88 + @Result(column = "road_name", property = "roadName"),
  89 + @Result(column = "street_id", property = "streetId"),
  90 + @Result(column = "street_name", property = "streetName"),
  91 + @Result(column = "curing_level_id", property = "curingLevelId"),
  92 + @Result(column = "curing_level_name", property = "curingLevelName"),
  93 + @Result(column = "commit_date", property = "commitDate"),
  94 + @Result(column = "finish_date", property = "finishDate"),
  95 + @Result(column = "pressing_type", property = "pressingType"),
  96 + @Result(column = "user_id", property = "userId"),
  97 + @Result(column = "user_name", property = "userName"),
  98 + @Result(column = "company_id", property = "companyId"),
  99 + @Result(column = "lat_lon_type", property = "latLonType"),
  100 + @Result(column = "lat", property = "lat"),
  101 + @Result(column = "lon", property = "lon"),
  102 + @Result(column = "lon_lat_address", property = "lonLatAddress"),
  103 + @Result(column = "third_work_no", property = "thirdWorkNo"),
  104 + @Result(column = "third_push_state", property = "thirdPushState"),
  105 + @Result(column = "buz_status", property = "buzStatus"),
  106 + @Result(column = "status", property = "status"),
  107 + @Result(column = "process_instance_id", property = "processInstanceId"),
  108 + @Result(column = "remark", property = "remark"),
  109 + @Result(column = "handle_result", property = "handleResult"),
  110 + @Result(column = "creator", property = "creator"),
  111 + @Result(column = "create_time", property = "createTime"),
  112 + @Result(column = "updater", property = "updater"),
  113 + @Result(column = "update_time", property = "updateTime"),
  114 + @Result(column = "deleted", property = "deleted"),
  115 +
  116 + @Result(column = "task_id", property = "taskId"),
  117 + @Result(column = "task_name", property = "taskName"),
  118 + @Result(column = "process_definition_name", property = "processDefinitionName"),
  119 + @Result(column = "START_TIME_", property = "startTime"),
  120 + @Result(column = "END_TIME_", property = "endTime"),
  121 + @Result(column = "KEY_", property = "key_")
  122 + })
  123 + IPage<MainInfoExtDO> selectDoneExtPage(IPage<MainInfoExtDO> page, @Param("query") MainInfoHasTaskPageReqVO reqVO);
  124 +
  125 + default PageResult<MainInfoExtDO> selectWorkOrderDonePage(PageParam pageParam, @Param("query") MainInfoHasTaskPageReqVO reqVO) {
  126 + IPage<MainInfoExtDO> mpPage = MyBatisUtils.buildPage(pageParam);
  127 + mpPage = selectDoneExtPage(mpPage, reqVO);
  128 + return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
  129 + }
  130 +
  131 + @Select({
  132 + "<script>",
  133 + "SELECT",
  134 + " m.*,",
  135 + " t.ID_ AS task_id,",
  136 + " t.NAME_ AS task_name,",
  137 + " pd.NAME_ AS process_definition_name,",
  138 + " t.CREATE_TIME_ AS START_TIME_,",
  139 + " t.DUE_DATE_ AS END_TIME_,",
  140 + " pd.KEY_",
  141 + "FROM act_ru_task t",
  142 + "LEFT JOIN act_re_procdef pd ON t.PROC_DEF_ID_ = pd.ID_",
  143 + "LEFT JOIN workorder_main_info m ON t.PROC_INST_ID_ = m.process_instance_id AND m.deleted = 0",
  144 + "WHERE 1=1",
  145 + " AND t.SUSPENSION_STATE_ = 1",
  146 + " <if test='query.userId != null'>",
  147 + " AND t.ASSIGNEE_ = #{query.userId}",
  148 + " </if>",
  149 + " <if test='query.key != null'>",
  150 + " AND pd.KEY_ = #{query.key}",
  151 + " </if>",
  152 + " <if test='query.startTime != null'>",
  153 + " <![CDATA[ AND t.CREATE_TIME_ >= #{query.startTime} ]]>",
  154 + " </if>",
  155 + " <if test='query.busiLine != null'>",
  156 + " AND m.busi_line = #{query.busiLine}",
  157 + " </if>",
  158 + " <if test=\"query.orderNo != null and query.orderNo != ''\">",
  159 + " AND m.order_no LIKE CONCAT('%', #{query.orderNo}, '%')",
  160 + " </if>",
  161 + " <if test=\"query.orderName != null and query.orderName != ''\">",
  162 + " AND m.order_name LIKE CONCAT('%', #{query.orderName}, '%')",
  163 + " </if>",
  164 + " <if test=\"query.remark != null and query.remark != ''\">",
  165 + " AND m.remark LIKE CONCAT('%', #{query.remark}, '%')",
  166 + " </if>",
  167 + " <if test=\"query.roadName != null and query.roadName != ''\">",
  168 + " AND m.road_name LIKE CONCAT('%', #{query.roadName}, '%')",
  169 + " </if>",
  170 + " <if test=\"query.streetName != null and query.streetName != ''\">",
  171 + " AND m.street_name = #{query.streetName}",
  172 + " <!-- 若需模糊匹配,改为:AND m.street_name LIKE CONCAT('%', #{query.streetName}, '%') -->",
  173 + " </if>",
  174 + " <if test='query.curingLevelId != null'>",
  175 + " AND m.curing_level_id = #{query.curingLevelId}",
  176 + " </if>",
  177 + "ORDER BY t.CREATE_TIME_ DESC",
  178 + "</script>"
  179 + })
  180 + @Results({
  181 + @Result(column = "id", property = "id"),
  182 + @Result(column = "busi_line", property = "busiLine"),
  183 + @Result(column = "order_no", property = "orderNo"),
  184 + @Result(column = "order_name", property = "orderName"),
  185 + @Result(column = "source_id", property = "sourceId"),
  186 + @Result(column = "source_name", property = "sourceName"),
  187 + @Result(column = "road_id", property = "roadId"),
  188 + @Result(column = "road_name", property = "roadName"),
  189 + @Result(column = "street_id", property = "streetId"),
  190 + @Result(column = "street_name", property = "streetName"),
  191 + @Result(column = "curing_level_id", property = "curingLevelId"),
  192 + @Result(column = "curing_level_name", property = "curingLevelName"),
  193 + @Result(column = "commit_date", property = "commitDate"),
  194 + @Result(column = "finish_date", property = "finishDate"),
  195 + @Result(column = "pressing_type", property = "pressingType"),
  196 + @Result(column = "user_id", property = "userId"),
  197 + @Result(column = "user_name", property = "userName"),
  198 + @Result(column = "company_id", property = "companyId"),
  199 + @Result(column = "lat_lon_type", property = "latLonType"),
  200 + @Result(column = "lat", property = "lat"),
  201 + @Result(column = "lon", property = "lon"),
  202 + @Result(column = "lon_lat_address", property = "lonLatAddress"),
  203 + @Result(column = "third_work_no", property = "thirdWorkNo"),
  204 + @Result(column = "third_push_state", property = "thirdPushState"),
  205 + @Result(column = "buz_status", property = "buzStatus"),
  206 + @Result(column = "status", property = "status"),
  207 + @Result(column = "process_instance_id", property = "processInstanceId"),
  208 + @Result(column = "remark", property = "remark"),
  209 + @Result(column = "handle_result", property = "handleResult"),
  210 + @Result(column = "creator", property = "creator"),
  211 + @Result(column = "create_time", property = "createTime"),
  212 + @Result(column = "updater", property = "updater"),
  213 + @Result(column = "update_time", property = "updateTime"),
  214 + @Result(column = "deleted", property = "deleted"),
  215 +
  216 + @Result(column = "task_id", property = "taskId"),
  217 + @Result(column = "task_name", property = "taskName"),
  218 + @Result(column = "process_definition_name", property = "processDefinitionName"),
  219 + @Result(column = "START_TIME_", property = "startTime"),
  220 + @Result(column = "END_TIME_", property = "endTime"),
  221 + @Result(column = "KEY_", property = "key_")
  222 + })
  223 + IPage<MainInfoExtDO> selectTodoExtPage(IPage<MainInfoExtDO> page, @Param("query") MainInfoHasTaskPageReqVO reqVO);
  224 +
  225 + default PageResult<MainInfoExtDO> selectWorkOrderTodoPage(PageParam pageParam, @Param("query") MainInfoHasTaskPageReqVO reqVO) {
  226 + IPage<MainInfoExtDO> mpPage = MyBatisUtils.buildPage(pageParam);
  227 + mpPage = selectTodoExtPage(mpPage, reqVO);
  228 + return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
  229 + }
  230 +}
0 \ No newline at end of file 231 \ No newline at end of file
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/dal/mysql/maininfo/MainInfoMapper.java
@@ -2,12 +2,14 @@ package com.zteits.urbanops.module.workorder.dal.mysql.maininfo; @@ -2,12 +2,14 @@ package com.zteits.urbanops.module.workorder.dal.mysql.maininfo;
2 2
3 import java.util.*; 3 import java.util.*;
4 4
  5 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
5 import com.zteits.urbanops.framework.common.pojo.PageResult; 6 import com.zteits.urbanops.framework.common.pojo.PageResult;
6 import com.zteits.urbanops.framework.mybatis.core.query.LambdaQueryWrapperX; 7 import com.zteits.urbanops.framework.mybatis.core.query.LambdaQueryWrapperX;
7 import com.zteits.urbanops.framework.mybatis.core.mapper.BaseMapperX; 8 import com.zteits.urbanops.framework.mybatis.core.mapper.BaseMapperX;
8 import com.zteits.urbanops.module.workorder.dal.dataobject.maininfo.MainInfoDO; 9 import com.zteits.urbanops.module.workorder.dal.dataobject.maininfo.MainInfoDO;
9 import org.apache.ibatis.annotations.Mapper; 10 import org.apache.ibatis.annotations.Mapper;
10 import com.zteits.urbanops.module.workorder.controller.admin.maininfo.vo.*; 11 import com.zteits.urbanops.module.workorder.controller.admin.maininfo.vo.*;
  12 +import org.apache.poi.ss.formula.functions.T;
11 13
12 /** 14 /**
13 * 工单信息 Mapper 15 * 工单信息 Mapper
@@ -85,4 +87,12 @@ public interface MainInfoMapper extends BaseMapperX&lt;MainInfoDO&gt; { @@ -85,4 +87,12 @@ public interface MainInfoMapper extends BaseMapperX&lt;MainInfoDO&gt; {
85 .orderByDesc(MainInfoDO::getId)); 87 .orderByDesc(MainInfoDO::getId));
86 } 88 }
87 89
  90 + default List<MainInfoDO> selectListIn(String field, Collection<?> values) {
  91 + // 空集合判断:避免 SQL 中出现 IN () 语法错误
  92 + if (values == null || values.isEmpty()) {
  93 + return List.of(); // 返回空列表(JDK9+),也可以用 new ArrayList<>()
  94 + }
  95 + return selectList(new QueryWrapper<MainInfoDO>().in(field, values));
  96 + }
  97 +
88 } 98 }
89 \ No newline at end of file 99 \ No newline at end of file
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/attachment/AttachmentService.java
@@ -59,4 +59,12 @@ public interface AttachmentService { @@ -59,4 +59,12 @@ public interface AttachmentService {
59 */ 59 */
60 PageResult<AttachmentDO> getAttachmentPage(AttachmentPageReqVO pageReqVO); 60 PageResult<AttachmentDO> getAttachmentPage(AttachmentPageReqVO pageReqVO);
61 61
62 -}  
63 \ No newline at end of file 62 \ No newline at end of file
  63 + /**
  64 + * 获得工单附件信息
  65 + *
  66 + * @param reqVO 编号
  67 + * @return 工单附件信息
  68 + */
  69 + List<AttachmentDO> getAttachmentByCondition(AttachmentReqVO reqVO);
  70 +
  71 +}
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/attachment/AttachmentServiceImpl.java
1 package com.zteits.urbanops.module.workorder.service.attachment; 1 package com.zteits.urbanops.module.workorder.service.attachment;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
  4 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  5 +import com.baomidou.mybatisplus.core.toolkit.StringUtils;
4 import org.springframework.stereotype.Service; 6 import org.springframework.stereotype.Service;
5 import jakarta.annotation.Resource; 7 import jakarta.annotation.Resource;
6 import org.springframework.validation.annotation.Validated; 8 import org.springframework.validation.annotation.Validated;
@@ -15,7 +17,9 @@ import com.zteits.urbanops.framework.common.util.object.BeanUtils; @@ -15,7 +17,9 @@ import com.zteits.urbanops.framework.common.util.object.BeanUtils;
15 17
16 import com.zteits.urbanops.module.workorder.dal.mysql.attachment.AttachmentMapper; 18 import com.zteits.urbanops.module.workorder.dal.mysql.attachment.AttachmentMapper;
17 19
  20 +import static com.zteits.urbanops.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
18 import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception; 21 import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception;
  22 +import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception0;
19 import static com.zteits.urbanops.framework.common.util.collection.CollectionUtils.convertList; 23 import static com.zteits.urbanops.framework.common.util.collection.CollectionUtils.convertList;
20 import static com.zteits.urbanops.framework.common.util.collection.CollectionUtils.diffList; 24 import static com.zteits.urbanops.framework.common.util.collection.CollectionUtils.diffList;
21 import static com.zteits.urbanops.module.workorder.enums.ErrorCodeConstants.*; 25 import static com.zteits.urbanops.module.workorder.enums.ErrorCodeConstants.*;
@@ -60,10 +64,10 @@ public class AttachmentServiceImpl implements AttachmentService { @@ -60,10 +64,10 @@ public class AttachmentServiceImpl implements AttachmentService {
60 } 64 }
61 65
62 @Override 66 @Override
63 - public void deleteAttachmentListByIds(List<Long> ids) { 67 + public void deleteAttachmentListByIds(List<Long> ids) {
64 // 删除 68 // 删除
65 attachmentMapper.deleteByIds(ids); 69 attachmentMapper.deleteByIds(ids);
66 - } 70 + }
67 71
68 72
69 private void validateAttachmentExists(Long id) { 73 private void validateAttachmentExists(Long id) {
@@ -82,4 +86,16 @@ public class AttachmentServiceImpl implements AttachmentService { @@ -82,4 +86,16 @@ public class AttachmentServiceImpl implements AttachmentService {
82 return attachmentMapper.selectPage(pageReqVO); 86 return attachmentMapper.selectPage(pageReqVO);
83 } 87 }
84 88
85 -}  
86 \ No newline at end of file 89 \ No newline at end of file
  90 + @Override
  91 + public List<AttachmentDO> getAttachmentByCondition(AttachmentReqVO reqVO) {
  92 + if (StringUtils.isEmpty(reqVO.getOrderNo())) {
  93 + throw exception0(BAD_REQUEST.getCode(),"工单号不能为空");
  94 + }
  95 + LambdaQueryWrapper<AttachmentDO> queryWrapper = new LambdaQueryWrapper<>();
  96 + queryWrapper.eq(AttachmentDO::getOrderNo, reqVO.getOrderNo());
  97 + if (StringUtils.isNotEmpty(reqVO.getBusiType())) {
  98 + queryWrapper.eq(AttachmentDO::getBusiType, reqVO.getBusiType());
  99 + }
  100 + return attachmentMapper.selectList(queryWrapper);
  101 + }
  102 +}
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/BpmGardenService.java
@@ -119,4 +119,18 @@ public interface BpmGardenService { @@ -119,4 +119,18 @@ public interface BpmGardenService {
119 * @return 119 * @return
120 */ 120 */
121 AppGardenApprovalDetailRespVO getApprovalDetail(AppGardenApprovalDetailReqVO reqVO); 121 AppGardenApprovalDetailRespVO getApprovalDetail(AppGardenApprovalDetailReqVO reqVO);
  122 +
  123 + /**
  124 + * 工单业务已完结 列表 -app 端
  125 + * @param pageVO
  126 + * @return
  127 + */
  128 + PageResult<AppGardenWorkOrderRespVO> getTaskDoneBuzSimplePage(AppGardenWorkOrderPageReqVO pageVO);
  129 +
  130 + /**
  131 + * 工单业务待办 列表 -app端
  132 + * @param pageVO
  133 + * @return
  134 + */
  135 + PageResult<AppGardenWorkOrderRespVO> getTaskTodoBuzSimplePage(AppGardenWorkOrderPageReqVO pageVO);
122 } 136 }
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/BpmGardenServiceImpl.java
@@ -25,6 +25,7 @@ import com.zteits.urbanops.module.workorder.api.constant.BpmCommonConstant; @@ -25,6 +25,7 @@ import com.zteits.urbanops.module.workorder.api.constant.BpmCommonConstant;
25 import com.zteits.urbanops.module.workorder.api.workorder.WorkOrderApi; 25 import com.zteits.urbanops.module.workorder.api.workorder.WorkOrderApi;
26 import com.zteits.urbanops.module.workorder.controller.admin.garden.vo.BpmGardenWorkOrderCreateReqVO; 26 import com.zteits.urbanops.module.workorder.controller.admin.garden.vo.BpmGardenWorkOrderCreateReqVO;
27 import com.zteits.urbanops.module.workorder.controller.admin.garden.vo.BpmGardenWorkOrderPageReqVO; 27 import com.zteits.urbanops.module.workorder.controller.admin.garden.vo.BpmGardenWorkOrderPageReqVO;
  28 +import com.zteits.urbanops.module.workorder.controller.admin.maininfo.vo.MainInfoHasTaskPageReqVO;
28 import com.zteits.urbanops.module.workorder.controller.admin.maininfo.vo.MainInfoPageReqVO; 29 import com.zteits.urbanops.module.workorder.controller.admin.maininfo.vo.MainInfoPageReqVO;
29 import com.zteits.urbanops.module.workorder.controller.app.garden.vo.*; 30 import com.zteits.urbanops.module.workorder.controller.app.garden.vo.*;
30 import com.zteits.urbanops.module.workorder.controller.app.garden.vo.process.AppGardenApprovalDetailReqVO; 31 import com.zteits.urbanops.module.workorder.controller.app.garden.vo.process.AppGardenApprovalDetailReqVO;
@@ -35,7 +36,9 @@ import com.zteits.urbanops.module.workorder.convert.garden.BpmGardenWorkOrderCon @@ -35,7 +36,9 @@ import com.zteits.urbanops.module.workorder.convert.garden.BpmGardenWorkOrderCon
35 import com.zteits.urbanops.module.workorder.dal.dataobject.attachment.AttachmentDO; 36 import com.zteits.urbanops.module.workorder.dal.dataobject.attachment.AttachmentDO;
36 import com.zteits.urbanops.module.workorder.dal.dataobject.garden.BpmGardenWorkOrderDO; 37 import com.zteits.urbanops.module.workorder.dal.dataobject.garden.BpmGardenWorkOrderDO;
37 import com.zteits.urbanops.module.workorder.dal.dataobject.maininfo.MainInfoDO; 38 import com.zteits.urbanops.module.workorder.dal.dataobject.maininfo.MainInfoDO;
  39 +import com.zteits.urbanops.module.workorder.dal.dataobject.maininfo.MainInfoExtDO;
38 import com.zteits.urbanops.module.workorder.dal.mysql.attachment.AttachmentMapper; 40 import com.zteits.urbanops.module.workorder.dal.mysql.attachment.AttachmentMapper;
  41 +import com.zteits.urbanops.module.workorder.dal.mysql.maininfo.MainInfoExtMapper;
39 import com.zteits.urbanops.module.workorder.dal.mysql.maininfo.MainInfoMapper; 42 import com.zteits.urbanops.module.workorder.dal.mysql.maininfo.MainInfoMapper;
40 import jakarta.annotation.Resource; 43 import jakarta.annotation.Resource;
41 import org.flowable.engine.RuntimeService; 44 import org.flowable.engine.RuntimeService;
@@ -51,6 +54,8 @@ import java.time.LocalDateTime; @@ -51,6 +54,8 @@ import java.time.LocalDateTime;
51 import java.util.HashMap; 54 import java.util.HashMap;
52 import java.util.List; 55 import java.util.List;
53 import java.util.Map; 56 import java.util.Map;
  57 +import java.util.Set;
  58 +import java.util.stream.Collectors;
54 59
55 import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception; 60 import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception;
56 import static com.zteits.urbanops.framework.common.util.collection.CollectionUtils.convertSet; 61 import static com.zteits.urbanops.framework.common.util.collection.CollectionUtils.convertSet;
@@ -70,6 +75,9 @@ public class BpmGardenServiceImpl implements BpmGardenService{ @@ -70,6 +75,9 @@ public class BpmGardenServiceImpl implements BpmGardenService{
70 private AttachmentMapper attachmentMapper; 75 private AttachmentMapper attachmentMapper;
71 @Resource 76 @Resource
72 private MainInfoMapper workOrderMapper; 77 private MainInfoMapper workOrderMapper;
  78 +
  79 + @Resource
  80 + private MainInfoExtMapper workOrderExtMapper;
73 @Resource 81 @Resource
74 private BpmProcessInstanceApi processInstanceApi; 82 private BpmProcessInstanceApi processInstanceApi;
75 @Resource 83 @Resource
@@ -201,6 +209,71 @@ public class BpmGardenServiceImpl implements BpmGardenService{ @@ -201,6 +209,71 @@ public class BpmGardenServiceImpl implements BpmGardenService{
201 } 209 }
202 210
203 @Override 211 @Override
  212 + public PageResult<AppGardenWorkOrderRespVO> getTaskDoneBuzSimplePage(AppGardenWorkOrderPageReqVO pageVO) {
  213 + MainInfoHasTaskPageReqVO taskBuzReqVO = new MainInfoHasTaskPageReqVO();
  214 + String type = pageVO.getType();
  215 + String content = pageVO.getSearchContent();
  216 + if(ObjectUtils.isNotAllEmpty(type)){
  217 + if("1".equals(type)){
  218 + if(ObjectUtils.isNotAllEmpty(content)){taskBuzReqVO.setRoadName(content);}
  219 + } else
  220 + if("2".equals(type)){
  221 + if(ObjectUtils.isNotAllEmpty(content)){taskBuzReqVO.setOrderName(content);}
  222 + }else
  223 + if("3".equals(type)){
  224 + if(ObjectUtils.isNotAllEmpty(content)){taskBuzReqVO.setRemark(content);}
  225 + } else
  226 + if("4".equals(type)){
  227 + if(ObjectUtils.isNotAllEmpty(content)){taskBuzReqVO.setOrderNo(content);}
  228 + }else {
  229 + if (ObjectUtils.isNotAllEmpty(content)) {
  230 + taskBuzReqVO.setOrderName(content);
  231 + }
  232 + }
  233 + }else {//默认是工单名称
  234 + if (ObjectUtils.isNotAllEmpty(content)) {
  235 + taskBuzReqVO.setOrderName(content);
  236 + }
  237 + }
  238 + taskBuzReqVO.setUserId(SecurityFrameworkUtils.getLoginUserId());
  239 + PageResult<MainInfoExtDO> pageResult = workOrderExtMapper.selectWorkOrderDonePage(pageVO,taskBuzReqVO);
  240 + return AppGardenTaskConvert.INSTANCE.buildBuziTaskPage(pageResult,attachmentMapper);
  241 + }
  242 +
  243 + @Override
  244 + public PageResult<AppGardenWorkOrderRespVO> getTaskTodoBuzSimplePage(AppGardenWorkOrderPageReqVO pageVO) {
  245 + MainInfoHasTaskPageReqVO taskBuzReqVO = new MainInfoHasTaskPageReqVO();
  246 + String type = pageVO.getType();
  247 + String content = pageVO.getSearchContent();
  248 + if(ObjectUtils.isNotAllEmpty(type)){
  249 + if("1".equals(type)){
  250 + if(ObjectUtils.isNotAllEmpty(content)){taskBuzReqVO.setRoadName(content);}
  251 + } else
  252 + if("2".equals(type)){
  253 + if(ObjectUtils.isNotAllEmpty(content)){taskBuzReqVO.setOrderName(content);}
  254 + }else
  255 + if("3".equals(type)){
  256 + if(ObjectUtils.isNotAllEmpty(content)){taskBuzReqVO.setRemark(content);}
  257 + } else
  258 + if("4".equals(type)){
  259 + if(ObjectUtils.isNotAllEmpty(content)){taskBuzReqVO.setOrderNo(content);}
  260 + }else {
  261 + if (ObjectUtils.isNotAllEmpty(content)) {
  262 + taskBuzReqVO.setOrderName(content);
  263 + }
  264 + }
  265 + }else {//默认是工单名称
  266 + if (ObjectUtils.isNotAllEmpty(content)) {
  267 + taskBuzReqVO.setOrderName(content);
  268 + }
  269 + }
  270 + taskBuzReqVO.setUserId(SecurityFrameworkUtils.getLoginUserId());
  271 + PageResult<MainInfoExtDO> pageResult = workOrderExtMapper.selectWorkOrderTodoPage(pageVO,taskBuzReqVO);
  272 +
  273 + return AppGardenTaskConvert.INSTANCE.buildBuziTaskPage(pageResult,attachmentMapper);
  274 + }
  275 +
  276 + @Override
204 public PageResult<AppGardenTaskRespVO> getTaskDonePage(AppGardenTaskPageReqVO pageVO) { 277 public PageResult<AppGardenTaskRespVO> getTaskDonePage(AppGardenTaskPageReqVO pageVO) {
205 BpmTaskPageReqVO targetVO = BeanUtils.toBean(pageVO,BpmTaskPageReqVO.class); 278 BpmTaskPageReqVO targetVO = BeanUtils.toBean(pageVO,BpmTaskPageReqVO.class);
206 PageResult<HistoricTaskInstance> pageResult = taskService.getTaskDonePage(SecurityFrameworkUtils.getLoginUserId(), targetVO); 279 PageResult<HistoricTaskInstance> pageResult = taskService.getTaskDonePage(SecurityFrameworkUtils.getLoginUserId(), targetVO);
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/garden/listener/AutoCompleteExecutionListener.java 0 → 100644
  1 +package com.zteits.urbanops.module.workorder.service.garden.listener;
  2 +
  3 +import org.flowable.common.engine.api.FlowableException;
  4 +import org.flowable.engine.delegate.DelegateExecution;
  5 +import org.flowable.engine.delegate.ExecutionListener;
  6 +import org.flowable.common.engine.impl.identity.Authentication; // 关键导入
  7 +import org.springframework.stereotype.Component;
  8 +
  9 +/**
  10 + * 流程启动时的执行监听器:设置自动完成变量
  11 + */
  12 +@Component("autoCompleteExecutionListener")
  13 +public class AutoCompleteExecutionListener implements ExecutionListener {
  14 +
  15 + @Override
  16 + public void notify(DelegateExecution execution) {
  17 + try {
  18 + // 1. 获取发起人ID:使用Authentication工具类(适配新版本)
  19 + String initiator = null;
  20 + // 获取当前认证的用户ID(静态方法)
  21 + if (Authentication.getAuthenticatedUserId() != null) {
  22 + initiator = Authentication.getAuthenticatedUserId();
  23 + } else {
  24 + // 备选:从流程变量中获取
  25 + initiator = (String) execution.getVariable("initiator");
  26 + }
  27 +
  28 + // 容错:默认用户
  29 + if (initiator == null || initiator.isEmpty()) {
  30 + initiator = "system_admin";
  31 + }
  32 +
  33 + // 2. 设置skipExpression需要的变量:autoComplete=true(表示跳过用户任务)
  34 + execution.setVariable("autoComplete", true);
  35 + // 3. 存储发起人ID和备注变量(用于追溯)
  36 + execution.setVariable("initiator", initiator);
  37 + execution.setVariable("completeRemark", "系统自动完成,办理人:" + initiator);
  38 +
  39 + } catch (Exception e) {
  40 + throw new FlowableException("设置自动完成变量失败:" + e.getMessage(), e);
  41 + }
  42 + }
  43 +}
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/maininfo/MainInfoService.java
@@ -59,4 +59,12 @@ public interface MainInfoService { @@ -59,4 +59,12 @@ public interface MainInfoService {
59 */ 59 */
60 PageResult<MainInfoDO> getMainInfoPage(MainInfoPageReqVO pageReqVO); 60 PageResult<MainInfoDO> getMainInfoPage(MainInfoPageReqVO pageReqVO);
61 61
62 -}  
63 \ No newline at end of file 62 \ No newline at end of file
  63 + /**
  64 + * 获得工单信息
  65 + *
  66 + * @param orderNo 编号
  67 + * @return 工单信息
  68 + */
  69 + MainInfoDO getMainInfoByOrderNo(String orderNo);
  70 +
  71 +}
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/maininfo/MainInfoServiceImpl.java
1 package com.zteits.urbanops.module.workorder.service.maininfo; 1 package com.zteits.urbanops.module.workorder.service.maininfo;
2 2
3 -import cn.hutool.core.collection.CollUtil;  
4 -import org.springframework.stereotype.Service;  
5 -import jakarta.annotation.Resource;  
6 -import org.springframework.validation.annotation.Validated;  
7 -import org.springframework.transaction.annotation.Transactional;  
8 -  
9 -import java.util.*;  
10 -import com.zteits.urbanops.module.workorder.controller.admin.maininfo.vo.*;  
11 -import com.zteits.urbanops.module.workorder.dal.dataobject.maininfo.MainInfoDO;  
12 import com.zteits.urbanops.framework.common.pojo.PageResult; 3 import com.zteits.urbanops.framework.common.pojo.PageResult;
13 -import com.zteits.urbanops.framework.common.pojo.PageParam;  
14 import com.zteits.urbanops.framework.common.util.object.BeanUtils; 4 import com.zteits.urbanops.framework.common.util.object.BeanUtils;
15 - 5 +import com.zteits.urbanops.module.workorder.controller.admin.maininfo.vo.MainInfoPageReqVO;
  6 +import com.zteits.urbanops.module.workorder.controller.admin.maininfo.vo.MainInfoSaveReqVO;
  7 +import com.zteits.urbanops.module.workorder.dal.dataobject.maininfo.MainInfoDO;
16 import com.zteits.urbanops.module.workorder.dal.mysql.maininfo.MainInfoMapper; 8 import com.zteits.urbanops.module.workorder.dal.mysql.maininfo.MainInfoMapper;
  9 +import jakarta.annotation.Resource;
  10 +import org.springframework.stereotype.Service;
  11 +import org.springframework.validation.annotation.Validated;
  12 +
  13 +import java.util.List;
17 14
18 import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception; 15 import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception;
19 -import static com.zteits.urbanops.framework.common.util.collection.CollectionUtils.convertList;  
20 -import static com.zteits.urbanops.framework.common.util.collection.CollectionUtils.diffList;  
21 -import static com.zteits.urbanops.module.workorder.enums.ErrorCodeConstants.*; 16 +import static com.zteits.urbanops.module.workorder.enums.ErrorCodeConstants.MAIN_INFO_NOT_EXISTS;
22 17
23 /** 18 /**
24 * 工单信息 Service 实现类 19 * 工单信息 Service 实现类
@@ -82,4 +77,9 @@ public class MainInfoServiceImpl implements MainInfoService { @@ -82,4 +77,9 @@ public class MainInfoServiceImpl implements MainInfoService {
82 return mainInfoMapper.selectPage(pageReqVO); 77 return mainInfoMapper.selectPage(pageReqVO);
83 } 78 }
84 79
85 -}  
86 \ No newline at end of file 80 \ No newline at end of file
  81 + @Override
  82 + public MainInfoDO getMainInfoByOrderNo(String orderNo) {
  83 + return mainInfoMapper.selectOne(MainInfoDO::getOrderNo, orderNo);
  84 + }
  85 +
  86 +}
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/materialdetail/MaterialDetailService.java
@@ -59,4 +59,12 @@ public interface MaterialDetailService { @@ -59,4 +59,12 @@ public interface MaterialDetailService {
59 */ 59 */
60 PageResult<MaterialDetailDO> getMaterialDetailPage(MaterialDetailPageReqVO pageReqVO); 60 PageResult<MaterialDetailDO> getMaterialDetailPage(MaterialDetailPageReqVO pageReqVO);
61 61
62 -}  
63 \ No newline at end of file 62 \ No newline at end of file
  63 + /**
  64 + * 创建工单耗材明细
  65 + *
  66 + * @param createReqVO 创建信息
  67 + * @return 编号
  68 + */
  69 + Boolean batchCreateMaterialDetail(@Valid List<MaterialDetailSaveReqVO> createReqVO);
  70 +
  71 +}
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/service/materialdetail/MaterialDetailServiceImpl.java
1 package com.zteits.urbanops.module.workorder.service.materialdetail; 1 package com.zteits.urbanops.module.workorder.service.materialdetail;
2 2
3 -import cn.hutool.core.collection.CollUtil;  
4 -import org.springframework.stereotype.Service;  
5 -import jakarta.annotation.Resource;  
6 -import org.springframework.validation.annotation.Validated;  
7 -import org.springframework.transaction.annotation.Transactional;  
8 -  
9 -import java.util.*;  
10 -import com.zteits.urbanops.module.workorder.controller.admin.materialdetail.vo.*;  
11 -import com.zteits.urbanops.module.workorder.dal.dataobject.materialdetail.MaterialDetailDO;  
12 import com.zteits.urbanops.framework.common.pojo.PageResult; 3 import com.zteits.urbanops.framework.common.pojo.PageResult;
13 -import com.zteits.urbanops.framework.common.pojo.PageParam;  
14 import com.zteits.urbanops.framework.common.util.object.BeanUtils; 4 import com.zteits.urbanops.framework.common.util.object.BeanUtils;
15 - 5 +import com.zteits.urbanops.module.garden.api.material.MaterialApi;
  6 +import com.zteits.urbanops.module.garden.api.material.dto.MaterialInventoryOutDto;
  7 +import com.zteits.urbanops.module.garden.controller.admin.materialinventoryout.vo.MaterialInventoryOutSaveReqVO;
  8 +import com.zteits.urbanops.module.garden.service.materialinventoryout.MaterialInventoryOutService;
  9 +import com.zteits.urbanops.module.workorder.controller.admin.materialdetail.vo.MaterialDetailPageReqVO;
  10 +import com.zteits.urbanops.module.workorder.controller.admin.materialdetail.vo.MaterialDetailSaveReqVO;
  11 +import com.zteits.urbanops.module.workorder.dal.dataobject.maininfo.MainInfoDO;
  12 +import com.zteits.urbanops.module.workorder.dal.dataobject.materialdetail.MaterialDetailDO;
16 import com.zteits.urbanops.module.workorder.dal.mysql.materialdetail.MaterialDetailMapper; 13 import com.zteits.urbanops.module.workorder.dal.mysql.materialdetail.MaterialDetailMapper;
  14 +import com.zteits.urbanops.module.workorder.service.maininfo.MainInfoService;
  15 +import jakarta.annotation.Resource;
  16 +import org.springframework.stereotype.Service;
  17 +import org.springframework.transaction.annotation.Transactional;
  18 +import org.springframework.validation.annotation.Validated;
  19 +
  20 +import java.time.LocalDateTime;
  21 +import java.util.List;
  22 +import java.util.stream.Collectors;
17 23
  24 +import static com.zteits.urbanops.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
18 import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception; 25 import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception;
19 -import static com.zteits.urbanops.framework.common.util.collection.CollectionUtils.convertList;  
20 -import static com.zteits.urbanops.framework.common.util.collection.CollectionUtils.diffList;  
21 -import static com.zteits.urbanops.module.workorder.enums.ErrorCodeConstants.*; 26 +import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception0;
  27 +import static com.zteits.urbanops.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  28 +import static com.zteits.urbanops.framework.security.core.util.SecurityFrameworkUtils.getLoginUserNickname;
  29 +import static com.zteits.urbanops.module.workorder.enums.ErrorCodeConstants.MATERIAL_DETAIL_NOT_EXISTS;
22 30
23 /** 31 /**
24 * 工单耗材明细 Service 实现类 32 * 工单耗材明细 Service 实现类
@@ -32,10 +40,18 @@ public class MaterialDetailServiceImpl implements MaterialDetailService { @@ -32,10 +40,18 @@ public class MaterialDetailServiceImpl implements MaterialDetailService {
32 @Resource 40 @Resource
33 private MaterialDetailMapper materialDetailMapper; 41 private MaterialDetailMapper materialDetailMapper;
34 42
  43 + @Resource
  44 + private MaterialApi materialApi;
  45 +
  46 + @Resource
  47 + private MainInfoService mainInfoService;
  48 +
35 @Override 49 @Override
36 public Long createMaterialDetail(MaterialDetailSaveReqVO createReqVO) { 50 public Long createMaterialDetail(MaterialDetailSaveReqVO createReqVO) {
37 // 插入 51 // 插入
38 MaterialDetailDO materialDetail = BeanUtils.toBean(createReqVO, MaterialDetailDO.class); 52 MaterialDetailDO materialDetail = BeanUtils.toBean(createReqVO, MaterialDetailDO.class);
  53 + materialDetail.setUserId(getLoginUserId());
  54 + materialDetail.setUserName(getLoginUserNickname());
39 materialDetailMapper.insert(materialDetail); 55 materialDetailMapper.insert(materialDetail);
40 56
41 // 返回 57 // 返回
@@ -82,4 +98,39 @@ public class MaterialDetailServiceImpl implements MaterialDetailService { @@ -82,4 +98,39 @@ public class MaterialDetailServiceImpl implements MaterialDetailService {
82 return materialDetailMapper.selectPage(pageReqVO); 98 return materialDetailMapper.selectPage(pageReqVO);
83 } 99 }
84 100
85 -}  
86 \ No newline at end of file 101 \ No newline at end of file
  102 + @Override
  103 + @Transactional
  104 + public Boolean batchCreateMaterialDetail(List<MaterialDetailSaveReqVO> createReqVO) {
  105 +
  106 + List<MaterialDetailDO> materialDetailList = createReqVO.stream()
  107 + .map(vo -> {
  108 + MaterialDetailDO detailDO = new MaterialDetailDO();
  109 + BeanUtils.copyProperties(vo, detailDO); // 单个对象属性拷贝
  110 + detailDO.setUserId(getLoginUserId());
  111 + detailDO.setUserName(getLoginUserNickname());
  112 + return detailDO;
  113 + })
  114 + .collect(Collectors.toList());
  115 +
  116 + //订单号校验
  117 + for (MaterialDetailDO materialDetailDO : materialDetailList) {
  118 + MainInfoDO mainInfoDO = mainInfoService.getMainInfoByOrderNo(materialDetailDO.getOrderNo());
  119 + if (mainInfoDO == null) {
  120 + throw exception0(BAD_REQUEST.getCode(),"订单号"+materialDetailDO.getOrderNo()+"不存在");
  121 + }
  122 + }
  123 + //耗材出库
  124 + for (MaterialDetailDO materialDetailDO : materialDetailList) {
  125 + MaterialInventoryOutDto outDto = new MaterialInventoryOutDto();
  126 + outDto.setMaterialId(materialDetailDO.getMaterialId());
  127 + outDto.setMaterialName(materialDetailDO.getMaterialName());
  128 + outDto.setOutInventoryNum(materialDetailDO.getUserCount());
  129 + outDto.setOutDate(LocalDateTime.now());
  130 + materialApi.createMaterialInventoryOut(outDto);
  131 + }
  132 + //保存耗材
  133 + materialDetailMapper.insertBatch(materialDetailList);
  134 + return Boolean.TRUE;
  135 + }
  136 +
  137 +}