package cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode;
|
|
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.util.StrUtil;
|
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeBindReqVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeGenerateReqVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodePageReqVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeReplaceReqVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeReplaceRespVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeRespVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.pro.bagcode.vo.MesProBagCodeTraceRespVO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.bagcode.MesProBagCodeDO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.batch.MesProBatchDO;
|
import cn.iocoder.yudao.module.mes.framework.qrcode.MesProQrLabelBuilder;
|
import cn.iocoder.yudao.module.mes.framework.qrcode.QrCodeImageUtils;
|
import cn.iocoder.yudao.module.mes.framework.qrcode.QrLabelInfo;
|
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
|
import cn.iocoder.yudao.module.mes.service.pro.bagcode.MesProBagCodeService;
|
import cn.iocoder.yudao.module.mes.service.pro.batch.MesProBatchService;
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameters;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
import jakarta.annotation.Resource;
|
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.validation.Valid;
|
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.Collections;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Set;
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_BAG_CODE_NOT_EXISTS;
|
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_QR_EXPORT_PARAMS_INVALID;
|
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_QR_EXPORT_TOO_MANY;
|
|
@Tag(name = "管理后台 - MES 袋码赋码(一袋一码)")
|
@RestController
|
@RequestMapping("/mes/pro/bag-code")
|
@Validated
|
public class MesProBagCodeController {
|
|
@Resource
|
private MesProBagCodeService bagCodeService;
|
@Resource
|
private MesProBatchService batchService;
|
@Resource
|
private AdminUserApi adminUserApi;
|
@Resource
|
private MesMdmItemService mdmItemService;
|
|
@PostMapping("/generate")
|
@Operation(summary = "生成袋码数据包(一袋一码)")
|
@PreAuthorize("@ss.hasPermission('mes:pro-bag-code:create')")
|
public CommonResult<String> generateBagCodes(@Valid @RequestBody MesProBagCodeGenerateReqVO generateReqVO) {
|
return success(bagCodeService.generateBagCodes(generateReqVO));
|
}
|
|
@PostMapping("/replace")
|
@Operation(summary = "作废破损袋码并生成等量替换袋码")
|
@PreAuthorize("@ss.hasPermission('mes:pro-bag-code:replace')")
|
public CommonResult<MesProBagCodeReplaceRespVO> replaceBagCodes(
|
@Valid @RequestBody MesProBagCodeReplaceReqVO replaceReqVO) {
|
return success(bagCodeService.replaceBagCodes(replaceReqVO));
|
}
|
|
@DeleteMapping("/delete-by-uuid")
|
@Operation(summary = "删除袋码生成组(数据包)")
|
@Parameter(name = "uuid", description = "生成组 UUID", required = true)
|
@PreAuthorize("@ss.hasPermission('mes:pro-bag-code:delete')")
|
public CommonResult<Boolean> deleteBagCodesByUuid(@RequestParam("uuid") String uuid) {
|
bagCodeService.deleteBagCodesByUuid(uuid);
|
return success(true);
|
}
|
|
@PutMapping("/bind-pallet")
|
@Operation(summary = "袋码绑定托盘")
|
@PreAuthorize("@ss.hasPermission('mes:pro-bag-code:update')")
|
public CommonResult<Boolean> bindPallet(@Valid @RequestBody MesProBagCodeBindReqVO bindReqVO) {
|
bagCodeService.bindPallet(bindReqVO);
|
return success(true);
|
}
|
|
@PutMapping("/unbind-pallet")
|
@Operation(summary = "袋码解绑托盘")
|
@PreAuthorize("@ss.hasPermission('mes:pro-bag-code:update')")
|
public CommonResult<Boolean> unbindPallet(@Valid @RequestBody MesProBagCodeBindReqVO bindReqVO) {
|
bagCodeService.unbindPallet(bindReqVO);
|
return success(true);
|
}
|
|
@GetMapping("/get")
|
@Operation(summary = "获得袋码")
|
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
@PreAuthorize("@ss.hasPermission('mes:pro-bag-code:query')")
|
public CommonResult<MesProBagCodeRespVO> getBagCode(@RequestParam("id") Long id) {
|
MesProBagCodeDO bagCode = bagCodeService.getBagCode(id);
|
if (bagCode == null) {
|
return success(null);
|
}
|
return success(buildBagCodeRespVOList(Collections.singletonList(bagCode)).get(0));
|
}
|
|
@GetMapping("/get-by-code")
|
@Operation(summary = "扫码追溯:根据袋码(二维码内容)反查批次、产线、责任人等信息")
|
@Parameter(name = "code", description = "袋码(二维码内容)", required = true, example = "PC20260818L01001-0001")
|
@PreAuthorize("@ss.hasPermission('mes:pro-bag-code:query')")
|
public CommonResult<MesProBagCodeTraceRespVO> getBagCodeByCode(@RequestParam("code") String code) {
|
MesProBagCodeDO bagCode = bagCodeService.getBagCodeByCode(code);
|
if (bagCode == null) {
|
throw exception(PRO_BAG_CODE_NOT_EXISTS);
|
}
|
return success(buildBagCodeTraceRespVO(bagCode));
|
}
|
|
@GetMapping("/page")
|
@Operation(summary = "获得袋码分页")
|
@PreAuthorize("@ss.hasPermission('mes:pro-bag-code:query')")
|
public CommonResult<PageResult<MesProBagCodeRespVO>> getBagCodePage(@Valid MesProBagCodePageReqVO pageReqVO) {
|
PageResult<MesProBagCodeDO> pageResult = bagCodeService.getBagCodePage(pageReqVO);
|
return success(new PageResult<>(buildBagCodeRespVOList(pageResult.getList()), pageResult.getTotal()));
|
}
|
|
@GetMapping("/list-by-uuid")
|
@Operation(summary = "获得生成组的袋码列表")
|
@Parameter(name = "uuid", description = "生成组 UUID", required = true)
|
@PreAuthorize("@ss.hasPermission('mes:pro-bag-code:query')")
|
public CommonResult<List<MesProBagCodeRespVO>> getBagCodeListByUuid(@RequestParam("uuid") String uuid) {
|
List<MesProBagCodeDO> list = bagCodeService.getBagCodeListByUuid(uuid);
|
return success(buildBagCodeRespVOList(list));
|
}
|
|
@GetMapping("/export-excel")
|
@Operation(summary = "批量导出袋码 Excel(交付印刷),导出后袋码标记为已导出印刷")
|
@PreAuthorize("@ss.hasPermission('mes:pro-bag-code:export')")
|
@ApiAccessLog(operateType = EXPORT)
|
public void exportBagCodeExcel(@Valid MesProBagCodePageReqVO pageReqVO,
|
HttpServletResponse response) throws IOException {
|
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
List<MesProBagCodeDO> list = bagCodeService.getBagCodePage(pageReqVO).getList();
|
List<MesProBagCodeRespVO> voList = buildBagCodeRespVOList(list);
|
// 导出即交付印刷:标记为已导出印刷并记录时间(仅处理"已生成"状态的袋码)
|
bagCodeService.markBagCodesPrinted(convertList(list, MesProBagCodeDO::getId));
|
ExcelUtils.write(response, "袋码数据包.xls", "数据", MesProBagCodeRespVO.class, voList);
|
}
|
|
@GetMapping("/export-qr")
|
@Operation(summary = "批量导出袋码二维码图片 ZIP(图片叠加关键信息文字),供印刷使用")
|
@Parameters({
|
@Parameter(name = "uuid", description = "生成组 UUID(优先),为空则按 batchId 导出"),
|
@Parameter(name = "batchId", description = "生产批次编号")
|
})
|
@PreAuthorize("@ss.hasPermission('mes:pro-bag-code:export')")
|
@ApiAccessLog(operateType = EXPORT)
|
public void exportBagCodeQr(@RequestParam(value = "uuid", required = false) String uuid,
|
@RequestParam(value = "batchId", required = false) Long batchId,
|
HttpServletResponse response) throws IOException {
|
List<MesProBagCodeDO> list;
|
String zipName;
|
if (StrUtil.isNotEmpty(uuid)) {
|
list = bagCodeService.getBagCodeListByUuid(uuid);
|
zipName = "袋码二维码-" + uuid;
|
} else if (batchId != null) {
|
list = bagCodeService.getBagCodeListByBatchId(batchId);
|
zipName = "袋码二维码-" + batchId;
|
} else {
|
throw exception(PRO_QR_EXPORT_PARAMS_INVALID);
|
}
|
if (CollUtil.isEmpty(list)) {
|
throw exception(PRO_BAG_CODE_NOT_EXISTS);
|
}
|
if (list.size() > QrCodeImageUtils.MAX_QR_EXPORT) {
|
throw exception(PRO_QR_EXPORT_TOO_MANY);
|
}
|
QrCodeImageUtils.writeZip(response, zipName, buildBagCodeQrLabels(list));
|
}
|
|
// ==================== 拼接 VO ====================
|
|
private List<MesProBagCodeRespVO> buildBagCodeRespVOList(List<MesProBagCodeDO> list) {
|
if (CollUtil.isEmpty(list)) {
|
return Collections.emptyList();
|
}
|
// 1. 获得关联数据(仅批次的产线信息)
|
Map<Long, MesProBatchDO> batchMap = convertMap(
|
batchService.getBatchList(convertSet(list, MesProBagCodeDO::getBatchId)), MesProBatchDO::getId);
|
// 2. 构建结果
|
return BeanUtils.toBean(list, MesProBagCodeRespVO.class, vo ->
|
MapUtils.findAndThen(batchMap, vo.getBatchId(), batch ->
|
vo.setLineCode(batch.getLineCode()).setLineName(batch.getLineName())));
|
}
|
|
private MesProBagCodeTraceRespVO buildBagCodeTraceRespVO(MesProBagCodeDO bagCode) {
|
MesProBagCodeTraceRespVO respVO = BeanUtils.toBean(bagCode, MesProBagCodeTraceRespVO.class);
|
var replacement = bagCode.getStatus() != null
|
&& bagCode.getStatus().equals(cn.iocoder.yudao.module.mes.enums.pro.MesProBagCodeStatusEnum.CANCELED.getStatus())
|
? bagCodeService.getReplacementByOldBagCodeId(bagCode.getId())
|
: bagCodeService.getReplacementByNewBagCodeId(bagCode.getId());
|
if (replacement != null) {
|
respVO.setReplacementUuid(replacement.getReplaceUuid());
|
if (bagCode.getId().equals(replacement.getOldBagCodeId())) {
|
respVO.setReplacedByCode(replacement.getNewCode());
|
} else {
|
respVO.setReplacementOfCode(replacement.getOldCode());
|
}
|
}
|
// 批次信息
|
MesProBatchDO batch = batchService.getBatch(bagCode.getBatchId());
|
if (batch != null) {
|
respVO.setBatchStatus(batch.getStatus())
|
.setProduceDate(batch.getProduceDate())
|
.setLineCode(batch.getLineCode())
|
.setLineName(batch.getLineName())
|
.setOwnerUserId(batch.getOwnerUserId())
|
.setItemId(batch.getItemId());
|
// 责任人
|
if (batch.getOwnerUserId() != null) {
|
AdminUserRespDTO user = adminUserApi.getUser(batch.getOwnerUserId());
|
if (user != null) {
|
respVO.setOwnerUserName(user.getNickname());
|
}
|
}
|
// 品种信息
|
if (batch.getItemId() != null) {
|
MesMdmItemDO item = mdmItemService.getItem(batch.getItemId());
|
if (item != null) {
|
respVO.setItemCode(item.getCode())
|
.setItemName(item.getName())
|
.setItemSpecification(item.getSpecification());
|
}
|
}
|
}
|
return respVO;
|
}
|
|
/**
|
* 构建袋码二维码标签列表(二维码编码纯码值,图片叠加关键信息文字)
|
*/
|
private List<QrLabelInfo> buildBagCodeQrLabels(List<MesProBagCodeDO> list) {
|
// 1. 获得关联数据(批次、品种、责任人)
|
Map<Long, MesProBatchDO> batchMap = convertMap(
|
batchService.getBatchList(convertSet(list, MesProBagCodeDO::getBatchId)), MesProBatchDO::getId);
|
Map<Long, MesMdmItemDO> itemMap = mdmItemService.getItemMap(
|
convertSet(batchMap.values(), MesProBatchDO::getItemId));
|
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
|
convertSet(batchMap.values(), MesProBatchDO::getOwnerUserId));
|
// 2. 构建标签
|
List<QrLabelInfo> labels = new ArrayList<>(list.size());
|
for (MesProBagCodeDO bagCode : list) {
|
labels.add(MesProQrLabelBuilder.buildBagCodeLabel(
|
bagCode, batchMap.get(bagCode.getBatchId()), itemMap, userMap));
|
}
|
return labels;
|
}
|
|
}
|