You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

288 lines
12 KiB

1 year ago
​
11 months ago
1 year ago
​
​
11 months ago
​
2 months ago
1 year ago
​
11 months ago
1 year ago
11 months ago
1 year ago
​
11 months ago
​
​
1 year ago
​
​
​
11 months ago
1 year ago
​
​
​
​
11 months ago
1 year ago
​
​
​
​
​
​
11 months ago
1 year ago
​
11 months ago
​
11 months ago
​
​
​
​
​
​
2 months ago
​
11 months ago
1 year ago
​
​
​
​
​
​
​
​
​
​
11 months ago
1 year ago
11 months ago
3 weeks ago
1 year ago
3 weeks ago
1 year ago
​
​
11 months ago
​
1 year ago
1 year ago
​
3 weeks ago
11 months ago
​
1 year ago
​
​
​
​
​
11 months ago
1 year ago
11 months ago
1 year ago
11 months ago
1 year ago
​
​
​
​
11 months ago
​
2 months ago
​
​
​
​
​
​
​
11 months ago
2 months ago
11 months ago
​
​
​
11 months ago
​
​
11 months ago
​
​
​
​
11 months ago
​
​
​
11 months ago
2 months ago
2 months ago
​
11 months ago
2 months ago
11 months ago
2 months ago
​
​
11 months ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
11 months ago
11 months ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
11 months ago
11 months ago
​
11 months ago
11 months ago
11 months ago
11 months ago
​
​
​
​
2 months ago
2 months ago
​
​
​
11 months ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
2 months ago
​
​
​
11 months ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
1 year ago
​
  1. package com.gaotao.modules.handlingunit.controller;
  2. import com.gaotao.common.exception.XJException;
  3. import com.gaotao.common.utils.R;
  4. import com.gaotao.modules.handlingunit.entity.HandlingUnit;
  5. import com.gaotao.modules.handlingunit.service.HandlingUnitService;
  6. import com.gaotao.modules.handlingunit.service.HandlingUnitIdGeneratorService;
  7. import com.gaotao.modules.handlingunit.service.HandlingUnitIdLogService;
  8. import com.gaotao.modules.autoWareHourceHaian.service.HaiAnPdaLabelSplitService;
  9. import com.gaotao.modules.handlingunit.dao.HandlingUnitMapper;
  10. import com.gaotao.modules.sys.controller.AbstractController;
  11. import lombok.extern.slf4j.Slf4j;
  12. import org.springframework.beans.BeanUtils;
  13. import org.springframework.beans.factory.annotation.Autowired;
  14. import org.springframework.transaction.annotation.Transactional;
  15. import org.springframework.web.bind.annotation.*;
  16. import java.math.BigDecimal;
  17. import java.util.Date;
  18. import java.util.HashMap;
  19. import java.util.Map;
  20. /**
  21. * PDA标签查询控制器
  22. *
  23. * <p><b>主要功能:</b></p>
  24. * <ul>
  25. * <li>扫描标签查询HandlingUnit信息</li>
  26. * <li>显示物料编码、库位、仓库、批次号、wdr等信息</li>
  27. * </ul>
  28. *
  29. * @author System
  30. * @since 2025-01-23
  31. */
  32. @Slf4j
  33. @RestController
  34. @RequestMapping("/pda/label")
  35. public class PdaLabelController extends AbstractController {
  36. @Autowired
  37. private HandlingUnitService handlingUnitService;
  38. @Autowired
  39. private HandlingUnitMapper handlingUnitMapper;
  40. @Autowired
  41. private HandlingUnitIdGeneratorService handlingUnitIdGeneratorService;
  42. @Autowired
  43. private HandlingUnitIdLogService handlingUnitIdLogService;
  44. @Autowired
  45. private HaiAnPdaLabelSplitService haiAnPdaLabelSplitService;
  46. /**
  47. * @Author System
  48. * @Description 查询标签信息
  49. * @Date 2025/01/23
  50. * @Param [Map<String, Object>]
  51. * @return com.gaotao.common.utils.R
  52. **/
  53. @PostMapping("query")
  54. public R queryLabelInfo(@RequestBody Map<String, Object> params) {
  55. try {
  56. String site = params == null ? null : (String) params.get("site");
  57. String labelCode = params == null ? null : (String) params.get("labelCode");
  58. log.info("=== 开始查询标签信息 ===");
  59. if (site == null || site.trim().isEmpty()) {
  60. return R.error("工厂编码不能为空");
  61. }
  62. if (labelCode == null || labelCode.trim().isEmpty()) {
  63. return R.error("标签编码不能为空");
  64. }
  65. // 按登录大工厂展开小工厂后查标签。查无返回 null;多小工厂重复时由服务抛出明确异常。- rqrq
  66. HandlingUnit handlingUnit = handlingUnitService.queryPdaLabelByBigSite(site, labelCode);
  67. if (handlingUnit == null) {
  68. log.warn("标签不存在: site={}, labelCode={}", site, labelCode);
  69. return R.error("标签不存在");
  70. }
  71. // 查询只回显真实X/N/Y/Q状态;拆分、发料等写操作各自执行状态准入,Q不会因查询被使用。- rqrq
  72. log.info("查询到标签信息: unitId={}, partNo={}, locationId={}, warehouseId={}, batchNo={}, wdr={}",
  73. handlingUnit.getUnitId(),
  74. handlingUnit.getPartNo(),
  75. handlingUnit.getLocationId(),
  76. handlingUnit.getWarehouseId(),
  77. handlingUnit.getBatchNo(),
  78. handlingUnit.getWdr());
  79. log.info("=== 标签信息查询完成 ===");
  80. return R.ok().put("data", handlingUnit);
  81. } catch (Exception e) {
  82. log.error("=== 查询标签信息失败 === 错误信息: {}", e.getMessage(), e);
  83. return R.error("查询失败: " + e.getMessage());
  84. }
  85. }
  86. /**
  87. * @Author rqrq
  88. * @Description 取消WMS预定 - rqrq
  89. * @Date 2025/11/01
  90. * @Param [Map<String, Object>]
  91. * @return com.gaotao.common.utils.R
  92. **/
  93. @PostMapping("cancelReserve")
  94. public R cancelReserve(@RequestBody Map<String, Object> params) throws Exception {
  95. String site = (String) params.get("site");
  96. String unitId = (String) params.get("unitId");
  97. log.info("=== 开始取消WMS预定 - rqrq ===");
  98. log.info("工厂: {}, 标签编码: {}", site, unitId);
  99. // 参数验证 - rqrq
  100. if (site == null || site.trim().isEmpty()) {
  101. throw new RuntimeException("工厂编码不能为空");
  102. }
  103. if (unitId == null || unitId.trim().isEmpty()) {
  104. throw new RuntimeException("标签编码不能为空");
  105. }
  106. // 查询HandlingUnit是否存在 - rqrq
  107. HandlingUnit handlingUnit = handlingUnitService.lambdaQuery()
  108. .eq(HandlingUnit::getSite, site)
  109. .eq(HandlingUnit::getUnitId, unitId.trim())
  110. .one();
  111. if (handlingUnit == null) {
  112. log.warn("标签不存在 - rqrq: site={}, unitId={}", site, unitId);
  113. throw new RuntimeException("标签不存在");
  114. }
  115. // 检查是否被预定 - rqrq
  116. if (!"Y".equals(handlingUnit.getReserveFlag())) {
  117. log.warn("标签未被预定 - rqrq: site={}, unitId={}", site, unitId);
  118. throw new RuntimeException("该标签未被WMS预定");
  119. }
  120. // 调用Mapper方法取消预定 - rqrq
  121. handlingUnitMapper.cancelReserve(site, unitId);
  122. log.info("取消WMS预定成功 - rqrq: unitId={}", unitId);
  123. log.info("=== 取消WMS预定完成 - rqrq ===");
  124. return R.ok();
  125. }
  126. /**
  127. * @Author System
  128. * @Description 标签拆分 - 将原标签拆分出指定数量到新标签
  129. * @Date 2025/01/18
  130. * @Param [Map<String, Object>]
  131. * @return com.gaotao.common.utils.R
  132. **/
  133. @PostMapping("split")
  134. @Transactional
  135. public R splitLabel(@RequestBody Map<String, Object> params) {
  136. try {
  137. String site = (String) params.get("site");
  138. String unitId = (String) params.get("unitId");
  139. String operatorName = (String) params.get("operatorName");
  140. BigDecimal splitQty = new BigDecimal(params.get("splitQty").toString());
  141. log.info("=== 开始标签拆分 ===");
  142. log.info("工厂: {}, 原标签: {}, 拆分数量: {}, 操作人: {}", site, unitId, splitQty, operatorName);
  143. // 1. 参数验证
  144. if (site == null || site.trim().isEmpty()) {
  145. throw new XJException("工厂编码不能为空");
  146. }
  147. if (unitId == null || unitId.trim().isEmpty()) {
  148. throw new XJException("标签编码不能为空");
  149. }
  150. if (splitQty.compareTo(BigDecimal.ZERO) <= 0) {
  151. throw new XJException("拆分数量必须大于0");
  152. }
  153. // 2. 查询原标签
  154. HandlingUnit originalUnit = handlingUnitService.lambdaQuery()
  155. .eq(HandlingUnit::getSite, site)
  156. .eq(HandlingUnit::getUnitId, unitId)
  157. .one();
  158. if (originalUnit == null) {
  159. throw new XJException("原标签不存在");
  160. }
  161. // 3. 验证库存状态
  162. if (!"Y".equals(originalUnit.getInStockFlag()) && !"X".equals(originalUnit.getInStockFlag())) {
  163. throw new XJException("该标签库存已被消耗,不能拆分");
  164. }
  165. // 4. 验证拆分数量
  166. BigDecimal originalQty = originalUnit.getQty();
  167. if (splitQty.compareTo(originalQty) >= 0) {
  168. throw new XJException("拆分数量必须小于原标签数量(" + originalQty + ")");
  169. }
  170. // 5. 生成新标签编码
  171. String newUnitId = handlingUnitIdGeneratorService.generateUnitId(site);
  172. log.info("生成新标签编码: {}", newUnitId);
  173. // 6. 创建新标签(复制原标签所有信息,只修改数量)
  174. HandlingUnit newUnit = new HandlingUnit();
  175. BeanUtils.copyProperties(originalUnit, newUnit);
  176. newUnit.setUnitId(newUnitId);
  177. newUnit.setQty(splitQty); // 新标签数量
  178. newUnit.setOriginalQty(splitQty); // 新标签原始数量
  179. newUnit.setSourceType("SPLIT"); // 来源类型:拆分
  180. newUnit.setParentUnitId(unitId); // 原标签编码
  181. newUnit.setCreatedDate(new Date());
  182. newUnit.setCreatedBy(operatorName);
  183. newUnit.setModifiedDate(new Date());
  184. newUnit.setModifiedBy(operatorName);
  185. newUnit.setRemark("从标签 " + unitId + " 拆分");
  186. // 新标签不得继承原标签预定:预定仍留在原标签剩余量上,避免同一预定单据挂两张标签。海安手工分拣拆分也依赖此口径 - rqrq
  187. newUnit.setReserveFlag("N");
  188. newUnit.setReserveOrderRef1(null);
  189. newUnit.setReserveOrderRef2(null);
  190. newUnit.setReserveOrderRef3(null);
  191. // 7. 保存新标签
  192. boolean saveResult = handlingUnitService.save(newUnit);
  193. if (!saveResult) {
  194. log.error("严重错误:新标签保存返回失败!unitId={}", newUnitId);
  195. handlingUnitIdLogService.logUnitIdGeneration(
  196. newUnitId, site, "LABEL_SPLIT", unitId,
  197. "", originalUnit.getPartNo(), originalUnit.getBatchNo(),
  198. splitQty.doubleValue(), operatorName,
  199. "N", "保存失败-save返回false"
  200. );
  201. throw new XJException("新标签保存失败(save返回false): " + newUnitId);
  202. }
  203. // 8. 记录新标签生成日志
  204. handlingUnitIdLogService.logUnitIdGeneration(
  205. newUnitId, site, "LABEL_SPLIT", unitId,
  206. "", originalUnit.getPartNo(), originalUnit.getBatchNo(),
  207. splitQty.doubleValue(), operatorName,
  208. "Y", "标签拆分成功"
  209. );
  210. // 9. 更新原标签数量
  211. BigDecimal remainQty = originalQty.subtract(splitQty);
  212. originalUnit.setQty(remainQty);
  213. originalUnit.setModifiedDate(new Date());
  214. originalUnit.setModifiedBy(operatorName);
  215. boolean updateResult = handlingUnitService.updateById(originalUnit);
  216. if (!updateResult) {
  217. log.error("严重错误:原标签更新失败!unitId={}", unitId);
  218. throw new XJException("原标签更新失败");
  219. }
  220. // 海安账套(site以54开头):若原标签已在haian_pallet_detail,同步回写剩余qty;未入盘则跳过 - rqrq
  221. haiAnPdaLabelSplitService.syncPalletDetailQtyAfterSplit(
  222. originalUnit.getSite(), unitId, remainQty);
  223. log.info("=== 标签拆分成功 ===");
  224. log.info("原标签: {} 剩余数量: {}", unitId, remainQty);
  225. log.info("新标签: {} 数量: {}", newUnitId, splitQty);
  226. // 10. 返回结果(包含原标签和新标签ID,用于打印)
  227. Map<String, Object> result = new HashMap<>();
  228. result.put("originalUnitId", unitId);
  229. result.put("newUnitId", newUnitId);
  230. result.put("originalQty", originalQty);
  231. result.put("remainQty", remainQty);
  232. result.put("splitQty", splitQty);
  233. return R.ok().put("data", result);
  234. } catch (XJException e) {
  235. log.error("=== 标签拆分失败 === 错误信息: {}", e.getMessage());
  236. return R.error(e.getMessage());
  237. } catch (Exception e) {
  238. log.error("=== 标签拆分失败 === 错误信息: {}", e.getMessage(), e);
  239. return R.error("拆分失败: " + e.getMessage());
  240. }
  241. }
  242. }