Merge branch 'test' of https://git.will-way.cn/zgty/zt-qms into test

This commit is contained in:
2026-03-16 18:28:47 +08:00
15 changed files with 264 additions and 455 deletions

View File

@@ -15,23 +15,19 @@ import com.zt.plat.module.qms.resource.material.controller.vo.MaterialInventoryO
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialInventoryOutboundRespVO;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialInventoryOutboundSaveReqVO;
import com.zt.plat.module.qms.resource.material.controller.vo.export.MaterialConsumeStatisticsExportVO;
import com.zt.plat.module.qms.resource.material.controller.vo.export.MaterialHazardousLedgerExportVO;
import com.zt.plat.module.qms.resource.material.dal.dataobject.MaterialInventoryOutboundDO;
import com.zt.plat.module.qms.resource.material.service.MaterialInventoryOutboundService;
import com.zt.plat.module.qms.resource.material.utils.ComplexExcelUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.jspecify.annotations.NonNull;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static com.zt.plat.framework.apilog.core.enums.OperateTypeEnum.EXPORT;

View File

@@ -1,53 +0,0 @@
package com.zt.plat.module.qms.resource.material.controller.vo.export;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 物料危化品台账导出VO")
@Data
//@ExcelIgnoreUnannotated
public class MaterialHazardousLedgerExportVO {
// 基础信息
private Integer serialNo; // 序号
private String company; // 单位
private String name; // 名称
private String substance; // 物质 json
private String hazardFeature; // 危险特性 json
private String englishName; // 英文名 json
private String alias; // 别名 json
private String hazardCategory; // 危险类别 json
private String isToxic; // 是否剧毒 json
private String casNo; // CAS 号 json
private String unNo; // UN 号 json
private String hazardCode; // 危规号 json
// 储存情况 - 合计
private String totalQuantity; // 储存量合计 (瓶)
// 化学分析室
private String chemStoreLocation; // 存放地点
private String chemQuantity; // 储存量 (瓶)
private String chemSpec; // 规格
private String chemUseLocation; // 使用地点 json
private String chemUse; // 用途 json
// 综合分析室
private String compStoreLocation; // 存放地点
private String compQuantity; // 储存量 (瓶)
private String compSpec; // 规格
private String compUseLocation; // 使用地点
private String compUse; // 用途
// 试金分析室
private String trialStoreLocation; // 存放地点
private String trialQuantity; // 储存量 (瓶)
private String trialSpec; // 规格
private String trialUseLocation; // 使用地点
private String trialUse; // 用途
// 其他
private String isExplosive; // 易制爆
private String isPoisonous; // 易制毒
private String remark; // 备注
}

View File

@@ -0,0 +1,62 @@
package com.zt.plat.module.qms.resource.material.controller.vo.export;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 物料危化品台账导出VO")
@Data
@ExcelIgnoreUnannotated
public class MaterialLedgerExportVO {
// 基础信息
// @ExcelProperty(value = "序号", index = 0)
private Integer serialNo;
@ExcelProperty(value = "单位")
private String companyName;
@ExcelProperty(value = "名称")
private String productName;
@ExcelProperty(value = "物质")
private String substance;
@ExcelProperty(value = "危险特性")
private String hazardFeature;
@ExcelProperty(value = "英文名")
private String englishName;
@ExcelProperty(value = "别名")
private String alias;
@ExcelProperty(value = "危险类别")
private String hazardCategory;
@ExcelProperty(value = "是否剧毒")
private String isToxic;
@ExcelProperty(value = "CAS 号")
private String casNo;
@ExcelProperty(value = "UN 号")
private String unNo;
@ExcelProperty(value = "危规号")
private String hazardCode;
// 储存情况 - 合计
@ExcelProperty(value = "储存量合计")
private String inventoryQuantity;
@ExcelProperty("部门")
private String departmentName;
@ExcelProperty(value = "存放地点")
private String locationName;
@ExcelProperty(value = "储存量")
private String departmentInventoryQuantity;
@ExcelProperty(value = "规格")
private String specification;
@ExcelProperty(value = "使用地点")
private String useLocation;
@ExcelProperty(value = "用途")
private String use;
// 其他
@ExcelProperty(value = "易制爆")
private String isExplosive;
@ExcelProperty(value = "易制毒")
private String isPoisonous;
@ExcelProperty(value = "备注")
private String remark;
}

View File

@@ -1,13 +1,12 @@
package com.zt.plat.module.qms.resource.material.controller.vo.resp;
import cn.hutool.json.JSONObject;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.zt.plat.module.qms.core.aspect.annotation.Dict;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 物料台账 Response VO")
@@ -19,21 +18,21 @@ public class MaterialInfomationLedgerRespVO {
@ExcelProperty("物料大类id")
private Long productId;
@Schema(description = "物料大类")
@ExcelProperty("物料大类")
@Schema(description = "物料名称")
@ExcelProperty("物料名称")
private String productName;
@Schema(description = "物料大类编码")
@ExcelProperty("物料大类编码")
private String productCode;
@Schema(description = "工段上级部门id")
@ExcelProperty("工段上级部门id")
private Long superiorDepartmentId;
@Schema(description = "公司id")
@ExcelProperty("公司id")
private Long companyId;
@Schema(description = "工段上级部门")
@ExcelProperty("工段上级部门")
private String superiorDepartmentName;
@Schema(description = "公司 - 取上级部门")
@ExcelProperty("单位")
private String companyName;
@Schema(description = "库存数量")
@ExcelProperty("库存数量")
@@ -53,15 +52,15 @@ public class MaterialInfomationLedgerRespVO {
@Schema(description = "工段部门id")
@ExcelProperty("工段部门id")
private Long assignDepartmentId;
private Long departmentId;
@Schema(description = "工段分配部门名称")
@ExcelProperty("工段分配部门名称")
private String assignDepartmentName;
private String departmentName;
@Schema(description = "工段部门库存数量")
@ExcelProperty("工段部门库存数量")
private BigDecimal assignDepartmentInventoryQuantity;
private BigDecimal departmentInventoryQuantity;
@Schema(description = "存放位置", example = "13603")
@ExcelProperty("存放位置")
@@ -93,7 +92,7 @@ public class MaterialInfomationLedgerRespVO {
@Schema(description = "大类其他配置")
@ExcelProperty("大类其他配置")
private String productCustomConfig;
private JSONObject productCustomConfig;
@Schema(description = "备注")
@ExcelProperty("备注")

View File

@@ -230,16 +230,20 @@ public interface MaterialInfomationMapper extends BaseMapperX<MaterialInfomation
return selectJoinList(MaterialInfoWithBizConfigVO.class, wrapper);
}
default PageResult<MaterialInfomationLedgerRespVO> selectInventoryLedgerPage(MaterialInfomationPageReqVO pageReqVO) {
default PageResult<MaterialInfomationLedgerRespVO> selectInventoryLedgerPage(MaterialInfomationPageReqVO reqVO) {
MPJLambdaWrapper<MaterialInfomationDO> wrapper = new MPJLambdaWrapperX<MaterialInfomationDO>()
.select(MaterialInfomationDO::getProductId)
.selectAs(MaterialInfomationDO::getDeptId, MaterialInfomationLedgerRespVO::getAssignDepartmentId)
.selectAs(MaterialInfomationDO::getDeptId, MaterialInfomationLedgerRespVO::getDepartmentId)
.select(MaterialInfomationDO::getLocationId)
.selectCount(MaterialInfomationDO::getId, MaterialInfomationLedgerRespVO::getAssignDepartmentInventoryQuantity)
.selectCount(MaterialInfomationDO::getId, MaterialInfomationLedgerRespVO::getDepartmentInventoryQuantity)
.innerJoin(MaterialProductDO.class, MaterialProductDO::getId, MaterialInfomationDO::getProductId)
.eqIfExists(MaterialProductDO::getHazardous, reqVO.getHazardous())
.eq(MaterialInfomationDO::getUsageStatus, 0)
.likeIfExists(MaterialProductDO::getName, reqVO.getName())
.groupBy(MaterialInfomationDO::getProductId,
MaterialInfomationDO::getDeptId,
MaterialInfomationDO::getLocationId);
return selectJoinPage(pageReqVO, MaterialInfomationLedgerRespVO.class, wrapper);
return selectJoinPage(reqVO, MaterialInfomationLedgerRespVO.class, wrapper);
}
}

View File

@@ -1,6 +1,7 @@
package com.zt.plat.module.qms.resource.material.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -26,14 +27,12 @@ import com.zt.plat.module.system.api.dept.DeptApi;
import com.zt.plat.module.system.api.dept.dto.DeptRespDTO;
import groovy.util.logging.Slf4j;
import jakarta.annotation.Resource;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -376,19 +375,19 @@ public class MaterialInfomationServiceImpl implements MaterialInfomationService
private void calculateSuperiorDepartmentInventory(List<MaterialInfomationLedgerRespVO> list) {
// 按上级部门 ID 分组,统计每个上级部门的总库存
Map<Long, BigDecimal> superiorDeptInventoryMap = list.stream()
.filter(item -> item.getSuperiorDepartmentId() != null)
.filter(item -> item.getCompanyId() != null)
.collect(Collectors.groupingBy(
MaterialInfomationLedgerRespVO::getSuperiorDepartmentId,
MaterialInfomationLedgerRespVO::getCompanyId,
Collectors.reducing(
BigDecimal.ZERO,
MaterialInfomationLedgerRespVO::getAssignDepartmentInventoryQuantity,
MaterialInfomationLedgerRespVO::getDepartmentInventoryQuantity,
BigDecimal::add
)
));
// 将累加结果设置到每条记录中
list.forEach(item -> {
BigDecimal totalInventory = superiorDeptInventoryMap.get(item.getSuperiorDepartmentId());
BigDecimal totalInventory = superiorDeptInventoryMap.get(item.getCompanyId());
item.setInventoryQuantity(totalInventory != null ? totalInventory : BigDecimal.ZERO);
});
}
@@ -409,42 +408,37 @@ public class MaterialInfomationServiceImpl implements MaterialInfomationService
private void enrichDepartmentInfo(List<MaterialInfomationLedgerRespVO> list) {
// 部门信息
List<Long> deptIds = list.stream().map(MaterialInfomationLedgerRespVO::getAssignDepartmentId).toList();
List<Long> deptIds = list.stream().map(MaterialInfomationLedgerRespVO::getDepartmentId).toList();
CommonResult<List<DeptRespDTO>> deptListResult = deptApi.getDeptList(deptIds);
List<DeptRespDTO> deptList = deptListResult.getData();
if (CollUtil.isEmpty(deptList)) return;
Map<Long, DeptRespDTO> deptMap = deptList.stream().collect(Collectors.toMap(DeptRespDTO::getId, Function.identity()));
list.forEach(item -> {
DeptRespDTO dept = deptMap.get(item.getAssignDepartmentId());
item.setAssignDepartmentName(dept.getName());
DeptRespDTO dept = deptMap.get(item.getDepartmentId());
item.setDepartmentName(dept.getName());
});
log.info("[enrichDepartmentInfo] 部门信息:{}", deptList);
List<Long> deptPrnIds = deptList.stream().map(DeptRespDTO::getParentId).toList();
log.info("[enrichDepartmentInfo] 父级部门ID:{}", deptPrnIds);
CommonResult<DeptRespDTO> dept1 = deptApi.getDept(deptPrnIds.get(0));
log.info("[enrichDepartmentInfo] 父级部门:{}", dept1.getData());
CommonResult<List<DeptRespDTO>> deptPrnListResult = deptApi.getDeptList(deptPrnIds);
List<DeptRespDTO> deptPrnList = deptPrnListResult.getData();
log.info("[enrichDepartmentInfo] 父级部门信息:{}", deptPrnList);
if (CollUtil.isEmpty(deptPrnList)) return;
Map<Long, DeptRespDTO> deptPrnMap = deptPrnList.stream().collect(Collectors.toMap(DeptRespDTO::getId, Function.identity()));
list.forEach(item -> {
DeptRespDTO dept = deptMap.get(item.getAssignDepartmentId());
DeptRespDTO dept = deptMap.get(item.getDepartmentId());
DeptRespDTO deptPrn = deptPrnMap.get(dept.getParentId());
item.setSuperiorDepartmentId(deptPrn.getId()).setSuperiorDepartmentName(deptPrn.getName());
item.setCompanyId(deptPrn.getId()).setCompanyName(deptPrn.getName());
});
}
private void enrichProductInfo(List<MaterialInfomationLedgerRespVO> list) {
List<Long> productIds = list.stream().map(MaterialInfomationLedgerRespVO::getProductId).toList();
List<MaterialProductDO> productList = materialProductService.getMaterialProductListByPdtIds(productIds);
if (CollUtil.isEmpty(productList)) return ;
if (CollUtil.isEmpty(productList)) return;
Map<Long, MaterialProductDO> productMap = productList.stream().collect(Collectors.toMap(MaterialProductDO::getId, Function.identity()));
list.forEach(item -> {
MaterialProductDO productDO = productMap.get(item.getProductId());
item.setProductName(productDO.getName())
.setProductCode(productDO.getCode())
.setProductCustomConfig(productDO.getCustomConfig());
.setProductCustomConfig(JSONUtil.parseObj(productDO.getCustomConfig()));
});
}
}

View File

@@ -2,7 +2,7 @@ package com.zt.plat.module.qms.resource.material.utils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.zt.plat.module.qms.resource.material.controller.vo.export.MaterialHazardousLedgerExportVO;
import com.zt.plat.module.qms.resource.material.controller.vo.export.MaterialLedgerExportVO;
import com.zt.plat.module.qms.resource.material.handler.excel.MaterialHazardousLedgerHeadHandler;
import com.zt.plat.module.qms.resource.material.handler.excel.MaterialHazardousLedgerStyleHandler;
import jakarta.servlet.http.HttpServletResponse;
@@ -15,9 +15,9 @@ import java.util.List;
public class ComplexExcelUtils {
public static void writeHazardousLedger(HttpServletResponse response,
String filename, String sheetName,
List<MaterialHazardousLedgerExportVO> dataList) throws IOException {
List<MaterialLedgerExportVO> dataList) throws IOException {
// 创建 ExcelWriter
EasyExcel.write(response.getOutputStream(), MaterialHazardousLedgerExportVO.class)
EasyExcel.write(response.getOutputStream(), MaterialLedgerExportVO.class)
.autoCloseStream(false)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
// 注册自定义表头处理器

View File

@@ -1,6 +1,8 @@
package com.zt.plat.module.qms.resource.record.controller.admin.recordrecord;
import com.zt.plat.framework.datapermission.core.annotation.DeptDataPermissionIgnore;
import com.zt.plat.framework.security.core.LoginUser;
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
import com.zt.plat.module.qms.common.service.BusinessFileService;
import com.zt.plat.module.qms.resource.clientManage.controller.vo.VersionManagementRespVO;
import com.zt.plat.module.qms.resource.record.constant.RecordConstants;
@@ -14,6 +16,9 @@ import com.zt.plat.module.qms.resource.record.controller.admin.recordrecord.vo.R
import com.zt.plat.module.qms.resource.record.dal.dataobject.recordpermission.RecordPermissionDO;
import com.zt.plat.module.qms.resource.record.service.recordcategory.RecordCategoryService;
import com.zt.plat.module.qms.resource.record.service.recordpermission.RecordPermissionService;
import com.zt.plat.module.system.api.dept.DeptApi;
import com.zt.plat.module.system.api.dept.dto.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
@@ -42,10 +47,12 @@ import com.zt.plat.framework.excel.core.util.ExcelUtils;
import com.zt.plat.framework.apilog.core.annotation.ApiAccessLog;
import static com.zt.plat.framework.apilog.core.enums.OperateTypeEnum.*;
import static com.zt.plat.module.qms.enums.ErrorCodeConstants.RECORD_PERMISSION_NOT_ALLOW;
import com.zt.plat.module.qms.resource.record.dal.dataobject.recordrecord.RecordRecordDO;
import com.zt.plat.module.qms.resource.record.service.recordrecord.RecordRecordService;
@Slf4j
@Tag(name = "管理后台 - 文件、模板、记录")
@RestController
@RequestMapping("/qms/resource/record-record")
@@ -69,6 +76,43 @@ public class RecordRecordController extends AbstractFileUploadController impleme
@Resource
private BusinessFileService businessFileService;
// @Resource
// private DeptApi deptApi;
// @GetMapping("/deptList")
// @Operation(summary = "获得文件记录关系")
//@PreAuthorize("@ss.hasPermission('qms:record-relation:query')")
// public CommonResult<List<DeptRespDTO>> getRecordRelation() {
// // 获取当前部门的所有子部门
// LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
// Long visitCompanyId = loginUser.getVisitCompanyId();
// log.info("visitCompanyId:{}", visitCompanyId);
// Long deptId = loginUser.getVisitDeptId();
// DeptListReqDTO dto = new DeptListReqDTO();
// List<String> deptIds = new ArrayList<>();
// deptIds.add(deptId.toString());
// dto.setIds(deptIds);
// CommonResult<List<DeptDetailRespDTO>> deptList = deptApi.getDeptList(dto);
// log.info("deptList:{}", deptList);
// // 获取当前所属公司下面的所有的部门
// if (visitCompanyId != null) {
//// return deptApi.getChildDeptList(visitCompanyId);
// CommonResult<List<DeptSimpleRespDTO>> allCompanyList = deptApi.getAllCompanyList();
// log.info("allCompanyList:{}", allCompanyList);
// DeptSimpleRespDTO deptSimpleRespDTO = allCompanyList.getData().get(0);
// deptSimpleRespDTO.getIsCompany();
// log.info("deptSimpleRespDTO:{}", deptSimpleRespDTO);
// CommonResult<List<DeptRespDTO>> childDeptList = deptApi.getChildDeptList(deptId);
// log.info("childDeptList:{}", childDeptList);
// CommonResult<Set<CompanyDeptInfoRespDTO>> companyDeptInfoListByUserId = deptApi.getCompanyDeptInfoListByUserId(loginUser.getId());
// log.info("companyDeptInfoListByUserId:{}", companyDeptInfoListByUserId);
// return childDeptList;
// }
// Long visitDeptId = loginUser.getVisitDeptId();
// if (visitDeptId == null) return CommonResult.error(RECORD_PERMISSION_NOT_ALLOW.getCode(), "用户部门不存在");
// return deptApi.getChildDeptList(visitDeptId);
// }
@PostMapping("/create")
@Operation(summary = "创建文件、模板、记录->分类明细")
@@ -151,5 +195,25 @@ public class RecordRecordController extends AbstractFileUploadController impleme
return success(BeanUtils.toBean(result, RecordRecordRespVO.class));
}
// 已由 XXL-Job 定时任务updateRecordStatusJob驱动此接口保留用于手动触发/测试
@GetMapping("/timing-updateRecordStatus")
@Operation(summary = "定时更新文件、模板、记录状态")
//@PreAuthorize("@ss.hasPermission('qms:record-record:update')")
public CommonResult<Boolean> timingUpdateRecordStatus() {
recordRecordService.updateRecordStatus();
return success(true);
}
/**
* 通过定时任务,判断文件是否到期(到期自动作废)
* @return
*/
// 已由 XXL-Job 定时任务XXX驱动此接口保留用于手动触发/测试
// @GetMapping("/timing-updateRecordStatus")
// @Operation(summary = "定时更新文件、模板、记录状态")
// //@PreAuthorize("@ss.hasPermission('qms:record-record:update')")
// public CommonResult<Boolean> timingUpdateRecordStatus() {
// recordRecordService.updateRecordStatus();
// return success(true);
// }
}

View File

@@ -0,0 +1,40 @@
package com.zt.plat.module.qms.resource.record.job;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.zt.plat.module.qms.resource.record.service.recordrecord.RecordRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 文件记录相关定时任务
*/
@Component
@Slf4j
public class RecordRecordJob {
@Autowired
private RecordRecordService recordRecordService;
/**
* 定时更新文件记录生效状态
* 检测 effectiveDate <= 当前时间 且 recordStatus != 1 的记录将其更新为已生效recordStatus = 1
*
* JobHandler 名称: updateRecordStatusJob
* 推荐 Cron: 0 0 0 * * ?(每天零点执行)
*/
@XxlJob("updateRecordStatusJob")
public void updateRecordStatusJob() {
log.info("[updateRecordStatusJob] 开始执行文件记录生效状态更新任务");
try {
Integer updateCount = recordRecordService.updateRecordStatus();
log.info("[updateRecordStatusJob] 任务执行成功,共更新 {} 条记录", updateCount);
XxlJobHelper.handleSuccess(String.format("任务执行成功,共更新 %d 条记录", updateCount));
} catch (Exception e) {
log.error("[updateRecordStatusJob] 任务执行失败:{}", e.getMessage(), e);
throw e;
}
}
}

Some files were not shown because too many files have changed in this diff Show More