9 changed files with 1072 additions and 0 deletions
-
112src/main/java/com/gaotao/modules/shopOrder/controller/WorkOrderAllocController.java
-
81src/main/java/com/gaotao/modules/shopOrder/dao/WorkOrderAllocMapper.java
-
129src/main/java/com/gaotao/modules/shopOrder/entity/UspWorkOrderAllocData.java
-
105src/main/java/com/gaotao/modules/shopOrder/entity/dto/U8WorkHourRequestDto.java
-
32src/main/java/com/gaotao/modules/shopOrder/entity/dto/U8WorkHourResponseDto.java
-
294src/main/java/com/gaotao/modules/shopOrder/service/Impl/WorkOrderAllocServiceImpl.java
-
47src/main/java/com/gaotao/modules/shopOrder/service/WorkOrderAllocService.java
-
5src/main/resources/application-dev.yml
-
267src/main/resources/mapper/shopOrder/WorkOrderAllocMapper.xml
@ -0,0 +1,112 @@ |
|||
package com.gaotao.modules.shopOrder.controller; |
|||
|
|||
import com.gaotao.common.utils.PageUtils; |
|||
import com.gaotao.common.utils.R; |
|||
import com.gaotao.modules.pda.utils.ResponseData; |
|||
import com.gaotao.modules.shopOrder.entity.SearchShopOrder; |
|||
import com.gaotao.modules.shopOrder.entity.UspWorkOrderAllocData; |
|||
import com.gaotao.modules.shopOrder.service.WorkOrderAllocService; |
|||
import com.gaotao.modules.sys.controller.AbstractController; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
import java.util.ArrayList; |
|||
|
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 工单数据汇总控制器 |
|||
* @author system |
|||
* @date 2026/01/05 |
|||
*/ |
|||
@RestController |
|||
@RequestMapping("/shopOrder/workOrderAlloc") |
|||
public class WorkOrderAllocController extends AbstractController { |
|||
|
|||
@Autowired |
|||
private WorkOrderAllocService workOrderAllocService; |
|||
|
|||
/** |
|||
* 分页查询生产订单(工单数据汇总专用) |
|||
*/ |
|||
@PostMapping("/searchShopOrder") |
|||
public R searchShopOrder(@RequestBody SearchShopOrder query) { |
|||
// 设置当前用户 |
|||
if (query.getUser() == null || query.getUser().isEmpty()) { |
|||
query.setUser(getUser().getUsername()); |
|||
} |
|||
PageUtils page = workOrderAllocService.searchShopOrderForAlloc(query); |
|||
return R.ok().put("page", page); |
|||
} |
|||
|
|||
/** |
|||
* 查询工单汇总数据(根据allocType) |
|||
*/ |
|||
@PostMapping("/list") |
|||
public R list(@RequestBody UspWorkOrderAllocData params) { |
|||
List<UspWorkOrderAllocData> list = workOrderAllocService.selectByAllocType(params); |
|||
|
|||
// 手动分页处理 |
|||
int totalCount = list.size(); |
|||
int pageSize = params.getLimit() > 0 ? params.getLimit() : 20; |
|||
int offset = params.getPage(); |
|||
int currPage = offset / pageSize + 1; |
|||
|
|||
int fromIndex = offset; |
|||
int toIndex = Math.min(fromIndex + pageSize, totalCount); |
|||
|
|||
List<UspWorkOrderAllocData> pageList; |
|||
if (fromIndex < totalCount) { |
|||
pageList = list.subList(fromIndex, toIndex); |
|||
} else { |
|||
pageList = new ArrayList<>(); |
|||
} |
|||
|
|||
PageUtils page = new PageUtils(pageList, totalCount, pageSize, currPage); |
|||
return R.ok().put("page", page); |
|||
} |
|||
|
|||
/** |
|||
* 执行工单数据汇总(调用存储过程) |
|||
*/ |
|||
@PostMapping("/executeAlloc") |
|||
public R executeAlloc(@RequestBody WorkOrderAllocRequest request) { |
|||
String currentUser = getUser().getUsername(); |
|||
|
|||
ResponseData response = workOrderAllocService.executeWorkOrderAlloc( |
|||
request.getQuery(), |
|||
request.getOrderNoList(), |
|||
currentUser, |
|||
request.isAllocAll() |
|||
); |
|||
|
|||
if (response.isSuccess()) { |
|||
return R.ok(response.getMsg()); |
|||
} else { |
|||
return R.error(response.getMsg()); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 执行工单数据回传(调用U8接口) |
|||
*/ |
|||
@PostMapping("/executeSync") |
|||
public R executeSync(@RequestBody UspWorkOrderAllocData params) { |
|||
ResponseData response = workOrderAllocService.executeWorkOrderSync(params); |
|||
if (response.isSuccess()) { |
|||
return R.ok(response.getMsg()); |
|||
} else { |
|||
return R.error(response.getMsg()); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 工单数据汇总请求DTO |
|||
*/ |
|||
@lombok.Data |
|||
public static class WorkOrderAllocRequest { |
|||
private SearchShopOrder query; |
|||
private List<String> orderNoList; |
|||
private boolean allocAll; |
|||
} |
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
package com.gaotao.modules.shopOrder.dao; |
|||
|
|||
import com.gaotao.modules.shopOrder.entity.SearchShopOrder; |
|||
import com.gaotao.modules.shopOrder.entity.UspWorkOrderAllocData; |
|||
import org.apache.ibatis.annotations.Mapper; |
|||
import org.apache.ibatis.annotations.Param; |
|||
import org.springframework.stereotype.Repository; |
|||
|
|||
import java.util.Date; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 工单数据汇总Mapper |
|||
* @author system |
|||
* @date 2026/01/05 |
|||
*/ |
|||
@Mapper |
|||
@Repository |
|||
public interface WorkOrderAllocMapper { |
|||
|
|||
/** |
|||
* 分页查询生产订单(工单数据汇总专用) |
|||
* @param query 查询条件 |
|||
* @return 生产订单列表 |
|||
*/ |
|||
List<SearchShopOrder> searchShopOrderForAlloc(@Param("query") SearchShopOrder query); |
|||
|
|||
/** |
|||
* 根据allocType查询工单汇总数据 |
|||
* @param data 查询条件 |
|||
* @return 汇总数据列表 |
|||
*/ |
|||
List<UspWorkOrderAllocData> selectByAllocType(UspWorkOrderAllocData data); |
|||
|
|||
/** |
|||
* 查询未传输的数据(产量未传输或工时未传输) |
|||
* @param data 查询条件 |
|||
* @return 未传输数据列表 |
|||
*/ |
|||
List<UspWorkOrderAllocData> selectUnSyncedData(UspWorkOrderAllocData data); |
|||
|
|||
/** |
|||
* 更新SFDC表的synced_code和synced_flag |
|||
* @param site 工厂编码 |
|||
* @param orderNo 订单号 |
|||
* @param batchNo 批次号 |
|||
* @param syncedCode 同步单号 |
|||
*/ |
|||
void updateSfdcSyncedCode(@Param("site") String site, |
|||
@Param("orderNo") String orderNo, |
|||
@Param("batchNo") String batchNo, |
|||
@Param("syncedCode") String syncedCode); |
|||
|
|||
/** |
|||
* 更新UspWorkOrderAlloc的同步异常信息 |
|||
* @param site 工厂编码 |
|||
* @param orderNo 订单号 |
|||
* @param rowNo 行号 |
|||
* @param syncedDate 同步时间 |
|||
* @param syncedMes 异常信息 |
|||
*/ |
|||
void updateAllocSyncedError(@Param("site") String site, |
|||
@Param("orderNo") String orderNo, |
|||
@Param("rowNo") String rowNo, |
|||
@Param("syncedDate") Date syncedDate, |
|||
@Param("syncedMes") String syncedMes); |
|||
|
|||
/** |
|||
* 插入临时表(单条) |
|||
* @param site 工厂编码 |
|||
* @param orderNo 订单号 |
|||
*/ |
|||
void insertAllocTemp(@Param("site") String site, |
|||
@Param("orderNo") String orderNo); |
|||
|
|||
/** |
|||
* 批量插入临时表(根据查询条件) |
|||
* @param query 查询条件 |
|||
*/ |
|||
void insertAllocTempByQuery(@Param("query") SearchShopOrder query); |
|||
} |
|||
@ -0,0 +1,129 @@ |
|||
package com.gaotao.modules.shopOrder.entity; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonFormat; |
|||
import com.gaotao.common.utils.QueryPage; |
|||
import lombok.Data; |
|||
import org.springframework.format.annotation.DateTimeFormat; |
|||
|
|||
import java.math.BigDecimal; |
|||
import java.util.Date; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 工单数据汇总实体类 |
|||
* @author system |
|||
* @date 2026/01/05 |
|||
*/ |
|||
@Data |
|||
public class UspWorkOrderAllocData extends QueryPage { |
|||
|
|||
/** |
|||
* 工厂编码 |
|||
*/ |
|||
private String site; |
|||
|
|||
/** |
|||
* 生产订单号 |
|||
*/ |
|||
private String orderNo; |
|||
|
|||
/** |
|||
* ERP订单号 |
|||
*/ |
|||
private String erpOrderNo; |
|||
|
|||
/** |
|||
* ERP订单行号 |
|||
*/ |
|||
private String erpOrderLineNo; |
|||
|
|||
/** |
|||
* 行号 |
|||
*/ |
|||
private String rowNo; |
|||
|
|||
/** |
|||
* 工序号 |
|||
*/ |
|||
private String itemNo; |
|||
|
|||
/** |
|||
* 操作员 |
|||
*/ |
|||
private String operator; |
|||
|
|||
/** |
|||
* 报告数量 |
|||
*/ |
|||
private Double allocReportQty; |
|||
|
|||
/** |
|||
* 合格数量 |
|||
*/ |
|||
private Double allocApproveQty; |
|||
|
|||
/** |
|||
* 不良数量 |
|||
*/ |
|||
private Double allocScrapQty; |
|||
|
|||
/** |
|||
* 数据类型(产量未传输、产量已传输、工时未传输、工时已传输) |
|||
*/ |
|||
private String allocType; |
|||
|
|||
/** |
|||
* 汇总操作人 |
|||
*/ |
|||
private String allocBy; |
|||
|
|||
/** |
|||
* 汇总时间 |
|||
*/ |
|||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
|||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
|||
private Date allocDate; |
|||
|
|||
/** |
|||
* 调机时长 |
|||
*/ |
|||
private BigDecimal allocSetupTime; |
|||
|
|||
/** |
|||
* 制造时长 |
|||
*/ |
|||
private BigDecimal allocManfTime; |
|||
|
|||
/** |
|||
* 回传时间 |
|||
*/ |
|||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
|||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
|||
private Date syncedDate; |
|||
|
|||
/** |
|||
* 异常原因 |
|||
*/ |
|||
private String syncedMes; |
|||
|
|||
/** |
|||
* 批次号 |
|||
*/ |
|||
private String batchNo; |
|||
|
|||
/** |
|||
* 当前登录人 |
|||
*/ |
|||
private String currentUser; |
|||
|
|||
/** |
|||
* 查询的allocType列表(用于批量查询) |
|||
*/ |
|||
private List<String> allocTypeList; |
|||
|
|||
/** |
|||
* 批量勾选的工单号列表 |
|||
*/ |
|||
private List<String> orderNoList; |
|||
} |
|||
|
|||
@ -0,0 +1,105 @@ |
|||
package com.gaotao.modules.shopOrder.entity.dto; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonFormat; |
|||
import com.fasterxml.jackson.annotation.JsonProperty; |
|||
import lombok.Data; |
|||
|
|||
import java.math.BigDecimal; |
|||
import java.util.Date; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* U8生产报工档案接口请求DTO |
|||
* @author system |
|||
* @date 2026/01/05 |
|||
*/ |
|||
@Data |
|||
public class U8WorkHourRequestDto { |
|||
|
|||
/** |
|||
* 生产订单号 |
|||
*/ |
|||
@JsonProperty("Mocode") |
|||
private String mocode; |
|||
|
|||
/** |
|||
* 订单行号 |
|||
*/ |
|||
@JsonProperty("IrowNo") |
|||
private String irowNo; |
|||
|
|||
/** |
|||
* 汇总日期 |
|||
*/ |
|||
@JsonProperty("DDate") |
|||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") |
|||
private Date dDate; |
|||
|
|||
/** |
|||
* 明细列表 |
|||
*/ |
|||
@JsonProperty("DetailList") |
|||
private List<DetailItem> detailList; |
|||
|
|||
/** |
|||
* 明细项 |
|||
*/ |
|||
@Data |
|||
public static class DetailItem { |
|||
|
|||
/** |
|||
* MES行号 |
|||
*/ |
|||
@JsonProperty("MESIrowNo") |
|||
private String mesIrowNo; |
|||
|
|||
/** |
|||
* 工序号 |
|||
*/ |
|||
@JsonProperty("SortSeq") |
|||
private String sortSeq; |
|||
|
|||
/** |
|||
* 设备编码 |
|||
*/ |
|||
@JsonProperty("EQId") |
|||
private String eqId; |
|||
|
|||
/** |
|||
* 班次编码 |
|||
*/ |
|||
@JsonProperty("DutyClassCode") |
|||
private String dutyClassCode; |
|||
|
|||
/** |
|||
* 员工编码 |
|||
*/ |
|||
@JsonProperty("EmployCode") |
|||
private String employCode; |
|||
|
|||
/** |
|||
* 合格数量 |
|||
*/ |
|||
@JsonProperty("QualifiedQty") |
|||
private Double qualifiedQty; |
|||
|
|||
/** |
|||
* 不合格数量 |
|||
*/ |
|||
@JsonProperty("RefusedQty") |
|||
private String refusedQty; |
|||
|
|||
/** |
|||
* 报废数量 |
|||
*/ |
|||
@JsonProperty("ScrapQty") |
|||
private Double scrapQty; |
|||
|
|||
/** |
|||
* 工时(调机时长+制造时长) |
|||
*/ |
|||
@JsonProperty("WorkHr") |
|||
private BigDecimal workHr; |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,32 @@ |
|||
package com.gaotao.modules.shopOrder.entity.dto; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonProperty; |
|||
import lombok.Data; |
|||
|
|||
/** |
|||
* U8生产报工档案接口响应DTO |
|||
* @author system |
|||
* @date 2026/01/05 |
|||
*/ |
|||
@Data |
|||
public class U8WorkHourResponseDto { |
|||
|
|||
/** |
|||
* 标记:failure:错误,success 成功 |
|||
*/ |
|||
@JsonProperty("Flag") |
|||
private String flag; |
|||
|
|||
/** |
|||
* success 时返回U8单号 |
|||
*/ |
|||
@JsonProperty("U8CCode") |
|||
private String u8CCode; |
|||
|
|||
/** |
|||
* 错误消息,成功则不返回 |
|||
*/ |
|||
@JsonProperty("ErrMsg") |
|||
private String errMsg; |
|||
} |
|||
|
|||
@ -0,0 +1,294 @@ |
|||
package com.gaotao.modules.shopOrder.service.Impl; |
|||
|
|||
import com.alibaba.fastjson.JSON; |
|||
import com.gaotao.common.utils.PageUtils; |
|||
import com.gaotao.modules.pda.utils.ResponseData; |
|||
import com.gaotao.modules.pms.util.HttpClientUtil; |
|||
import com.gaotao.modules.report.dao.ProcedureDao; |
|||
import com.gaotao.modules.shopOrder.dao.WorkOrderAllocMapper; |
|||
import com.gaotao.modules.shopOrder.entity.SearchShopOrder; |
|||
import com.gaotao.modules.shopOrder.entity.UspWorkOrderAllocData; |
|||
import com.gaotao.modules.shopOrder.entity.dto.U8WorkHourRequestDto; |
|||
import com.gaotao.modules.shopOrder.entity.dto.U8WorkHourResponseDto; |
|||
import com.gaotao.modules.shopOrder.service.WorkOrderAllocService; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
|
|||
import java.math.BigDecimal; |
|||
import java.util.*; |
|||
import java.util.stream.Collectors; |
|||
|
|||
/** |
|||
* 工单数据汇总服务实现类 |
|||
* @author system |
|||
* @date 2026/01/05 |
|||
*/ |
|||
@Slf4j |
|||
@Service |
|||
public class WorkOrderAllocServiceImpl implements WorkOrderAllocService { |
|||
|
|||
@Autowired |
|||
private WorkOrderAllocMapper workOrderAllocMapper; |
|||
|
|||
@Autowired |
|||
private ProcedureDao procedureDao; |
|||
|
|||
/** |
|||
* U8接口地址,从配置文件读取 |
|||
*/ |
|||
@Value("${u8.workhour.add.url:}") |
|||
private String u8WorkHourAddUrl; |
|||
|
|||
@Override |
|||
public PageUtils searchShopOrderForAlloc(SearchShopOrder query) { |
|||
// 查询数据 |
|||
List<SearchShopOrder> list = workOrderAllocMapper.searchShopOrderForAlloc(query); |
|||
|
|||
// 构建分页结果 |
|||
int total = list.size(); |
|||
int pageSize = query.getLimit() > 0 ? query.getLimit() : 20; |
|||
int offset = query.getPage(); |
|||
int currPage = offset / pageSize + 1; |
|||
|
|||
// 手动分页处理 |
|||
int fromIndex = offset; |
|||
int toIndex = Math.min(fromIndex + pageSize, total); |
|||
|
|||
List<SearchShopOrder> pageList; |
|||
if (fromIndex < total) { |
|||
pageList = list.subList(fromIndex, toIndex); |
|||
} else { |
|||
pageList = new ArrayList<>(); |
|||
} |
|||
|
|||
return new PageUtils(pageList, total, pageSize, currPage); |
|||
} |
|||
|
|||
@Override |
|||
public List<UspWorkOrderAllocData> selectByAllocType(UspWorkOrderAllocData data) { |
|||
return workOrderAllocMapper.selectByAllocType(data); |
|||
} |
|||
|
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public ResponseData executeWorkOrderAlloc(SearchShopOrder query, List<String> orderNoList, String currentUser, boolean allocAll) { |
|||
ResponseData responseData = new ResponseData(); |
|||
try { |
|||
log.info("开始执行工单数据汇总,操作人:{},汇总所有:{}", currentUser, allocAll); |
|||
|
|||
// 1. 插入临时表(存储过程会先清空临时表) |
|||
if (allocAll) { |
|||
// 汇总所有:根据查询条件插入临时表 |
|||
workOrderAllocMapper.insertAllocTempByQuery(query); |
|||
log.info("已根据查询条件插入临时表"); |
|||
} else { |
|||
// 汇总选中的:逐条插入临时表 |
|||
String site = query.getSite() != null ? query.getSite() : ""; |
|||
for (String orderNo : orderNoList) { |
|||
workOrderAllocMapper.insertAllocTemp(site, orderNo); |
|||
} |
|||
log.info("已插入{}条选中的工单到临时表", orderNoList.size()); |
|||
} |
|||
|
|||
// 2. 调用存储过程,orderNo传空字符串 |
|||
List<Object> params = new ArrayList<>(); |
|||
params.add(query.getSite() != null ? query.getSite() : ""); |
|||
params.add(""); // orderNo传空字符串 |
|||
params.add(currentUser); |
|||
|
|||
List<Map<String, Object>> resultList = procedureDao.getProcedureData("UspInsertWorkOrderAlloc", params); |
|||
|
|||
// 3. 判断执行结果 |
|||
String resultMsg = "工单数据汇总完成"; |
|||
if (resultList != null && !resultList.isEmpty()) { |
|||
String code = String.valueOf(resultList.get(0).get("resultCode")); |
|||
if ("400".equalsIgnoreCase(code)) { |
|||
String msg = String.valueOf(resultList.get(0).get("resultMsg")); |
|||
responseData.setCode("500"); |
|||
responseData.setSuccess(false); |
|||
responseData.setMsg("工单数据汇总失败: " + msg); |
|||
return responseData; |
|||
} |
|||
// 获取返回消息 |
|||
if (resultList.get(0).get("resultMsg") != null) { |
|||
resultMsg = String.valueOf(resultList.get(0).get("resultMsg")); |
|||
} |
|||
} |
|||
|
|||
responseData.setCode("200"); |
|||
responseData.setSuccess(true); |
|||
responseData.setMsg(resultMsg); |
|||
log.info("工单数据汇总成功:{}", resultMsg); |
|||
|
|||
} catch (Exception e) { |
|||
log.error("执行工单数据汇总时发生异常", e); |
|||
responseData.setCode("500"); |
|||
responseData.setSuccess(false); |
|||
responseData.setMsg("执行工单数据汇总时发生异常: " + e.getMessage()); |
|||
} |
|||
return responseData; |
|||
} |
|||
|
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public ResponseData executeWorkOrderSync(UspWorkOrderAllocData data) { |
|||
ResponseData responseData = new ResponseData(); |
|||
try { |
|||
log.info("开始执行工单数据回传"); |
|||
|
|||
// 1. 查询未传输的数据 |
|||
List<UspWorkOrderAllocData> unSyncedList = workOrderAllocMapper.selectUnSyncedData(data); |
|||
|
|||
if (unSyncedList == null || unSyncedList.isEmpty()) { |
|||
responseData.setCode("200"); |
|||
responseData.setSuccess(true); |
|||
responseData.setMsg("没有需要回传的数据"); |
|||
return responseData; |
|||
} |
|||
|
|||
log.info("查询到{}条待回传数据", unSyncedList.size()); |
|||
|
|||
int successCount = 0; |
|||
int failCount = 0; |
|||
StringBuilder errorMessages = new StringBuilder(); |
|||
|
|||
// 2. 按照erp_orderNo和erp_orderLineNo分组 |
|||
Map<String, List<UspWorkOrderAllocData>> groupedData = unSyncedList.stream() |
|||
.collect(Collectors.groupingBy(item -> |
|||
item.getErpOrderNo() + "_" + item.getErpOrderLineNo() + "_" + |
|||
(item.getAllocDate() != null ? item.getAllocDate().getTime() : ""))); |
|||
|
|||
// 3. 逐组调用U8接口 |
|||
for (Map.Entry<String, List<UspWorkOrderAllocData>> entry : groupedData.entrySet()) { |
|||
List<UspWorkOrderAllocData> groupItems = entry.getValue(); |
|||
if (groupItems.isEmpty()) continue; |
|||
|
|||
UspWorkOrderAllocData firstItem = groupItems.get(0); |
|||
|
|||
try { |
|||
// 构建U8请求参数 |
|||
U8WorkHourRequestDto requestDto = new U8WorkHourRequestDto(); |
|||
requestDto.setMocode(firstItem.getErpOrderNo()); |
|||
requestDto.setIrowNo(firstItem.getErpOrderLineNo()); |
|||
requestDto.setDDate(firstItem.getAllocDate()); |
|||
|
|||
List<U8WorkHourRequestDto.DetailItem> detailList = new ArrayList<>(); |
|||
for (UspWorkOrderAllocData item : groupItems) { |
|||
U8WorkHourRequestDto.DetailItem detailItem = new U8WorkHourRequestDto.DetailItem(); |
|||
detailItem.setMesIrowNo(item.getRowNo()); |
|||
detailItem.setSortSeq(item.getItemNo()); |
|||
detailItem.setEqId(""); |
|||
detailItem.setDutyClassCode(""); |
|||
detailItem.setEmployCode(item.getOperator()); |
|||
detailItem.setQualifiedQty(item.getAllocApproveQty()); |
|||
detailItem.setRefusedQty(""); |
|||
detailItem.setScrapQty(item.getAllocScrapQty()); |
|||
|
|||
// 计算工时:调机时长 + 制造时长 |
|||
BigDecimal workHr = BigDecimal.ZERO; |
|||
if (item.getAllocSetupTime() != null) { |
|||
workHr = workHr.add(item.getAllocSetupTime()); |
|||
} |
|||
if (item.getAllocManfTime() != null) { |
|||
workHr = workHr.add(item.getAllocManfTime()); |
|||
} |
|||
detailItem.setWorkHr(workHr); |
|||
|
|||
detailList.add(detailItem); |
|||
} |
|||
requestDto.setDetailList(detailList); |
|||
|
|||
// 调用U8接口 |
|||
log.info("调用U8接口,请求参数: {}", JSON.toJSONString(requestDto)); |
|||
com.gaotao.modules.pms.util.ResponseData httpResponse = |
|||
HttpClientUtil.doPostByRaw(u8WorkHourAddUrl, requestDto); |
|||
|
|||
if (httpResponse.isSuccess()) { |
|||
// 解析响应 |
|||
U8WorkHourResponseDto u8Response = JSON.parseObject(httpResponse.getMsg(), U8WorkHourResponseDto.class); |
|||
|
|||
if ("success".equalsIgnoreCase(u8Response.getFlag())) { |
|||
// 接口调用成功,更新SFDC表 |
|||
String u8CCode = u8Response.getU8CCode(); |
|||
for (UspWorkOrderAllocData item : groupItems) { |
|||
workOrderAllocMapper.updateSfdcSyncedCode( |
|||
item.getSite(), |
|||
item.getOrderNo(), |
|||
item.getBatchNo(), |
|||
u8CCode); |
|||
} |
|||
successCount += groupItems.size(); |
|||
log.info("U8接口调用成功,返回单号: {}", u8CCode); |
|||
} else { |
|||
// 接口返回错误 |
|||
String errMsg = u8Response.getErrMsg(); |
|||
for (UspWorkOrderAllocData item : groupItems) { |
|||
workOrderAllocMapper.updateAllocSyncedError( |
|||
item.getSite(), |
|||
item.getOrderNo(), |
|||
item.getRowNo(), |
|||
new Date(), |
|||
errMsg); |
|||
} |
|||
failCount += groupItems.size(); |
|||
errorMessages.append("订单").append(firstItem.getErpOrderNo()) |
|||
.append("回传失败: ").append(errMsg).append("; "); |
|||
log.error("U8接口返回错误: {}", errMsg); |
|||
} |
|||
} else { |
|||
// HTTP请求失败 |
|||
String errMsg = "HTTP请求失败: " + httpResponse.getMsg(); |
|||
for (UspWorkOrderAllocData item : groupItems) { |
|||
workOrderAllocMapper.updateAllocSyncedError( |
|||
item.getSite(), |
|||
item.getOrderNo(), |
|||
item.getRowNo(), |
|||
new Date(), |
|||
errMsg); |
|||
} |
|||
failCount += groupItems.size(); |
|||
errorMessages.append("订单").append(firstItem.getErpOrderNo()) |
|||
.append("回传失败: ").append(errMsg).append("; "); |
|||
log.error("调用U8接口HTTP请求失败: {}", httpResponse.getMsg()); |
|||
} |
|||
|
|||
} catch (Exception e) { |
|||
// 异常处理 |
|||
String errMsg = "处理异常: " + e.getMessage(); |
|||
for (UspWorkOrderAllocData item : groupItems) { |
|||
workOrderAllocMapper.updateAllocSyncedError( |
|||
item.getSite(), |
|||
item.getOrderNo(), |
|||
item.getRowNo(), |
|||
new Date(), |
|||
errMsg); |
|||
} |
|||
failCount += groupItems.size(); |
|||
errorMessages.append("订单").append(firstItem.getErpOrderNo()) |
|||
.append("回传异常: ").append(e.getMessage()).append("; "); |
|||
log.error("工单数据回传处理异常,订单号: {}", firstItem.getErpOrderNo(), e); |
|||
} |
|||
} |
|||
|
|||
// 返回结果 |
|||
String resultMsg = String.format("工单数据回传完成,成功%d条,失败%d条", successCount, failCount); |
|||
if (failCount > 0) { |
|||
resultMsg += "。失败详情: " + errorMessages.toString(); |
|||
} |
|||
|
|||
responseData.setCode(failCount > 0 ? "500" : "200"); |
|||
responseData.setSuccess(failCount == 0); |
|||
responseData.setMsg(resultMsg); |
|||
|
|||
} catch (Exception e) { |
|||
log.error("执行工单数据回传时发生异常", e); |
|||
responseData.setCode("500"); |
|||
responseData.setSuccess(false); |
|||
responseData.setMsg("执行工单数据回传时发生异常: " + e.getMessage()); |
|||
} |
|||
return responseData; |
|||
} |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
package com.gaotao.modules.shopOrder.service; |
|||
|
|||
import com.gaotao.common.utils.PageUtils; |
|||
import com.gaotao.modules.pda.utils.ResponseData; |
|||
import com.gaotao.modules.shopOrder.entity.SearchShopOrder; |
|||
import com.gaotao.modules.shopOrder.entity.UspWorkOrderAllocData; |
|||
|
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 工单数据汇总服务接口 |
|||
* @author system |
|||
* @date 2026/01/05 |
|||
*/ |
|||
public interface WorkOrderAllocService { |
|||
|
|||
/** |
|||
* 分页查询生产订单(工单数据汇总专用) |
|||
* @param query 查询条件 |
|||
* @return 分页结果 |
|||
*/ |
|||
PageUtils searchShopOrderForAlloc(SearchShopOrder query); |
|||
|
|||
/** |
|||
* 根据allocType查询工单汇总数据 |
|||
* @param data 查询条件 |
|||
* @return 汇总数据列表 |
|||
*/ |
|||
List<UspWorkOrderAllocData> selectByAllocType(UspWorkOrderAllocData data); |
|||
|
|||
/** |
|||
* 执行工单数据汇总(调用存储过程) |
|||
* @param query 查询条件(用于汇总所有时) |
|||
* @param orderNoList 工单号列表(选择的工单) |
|||
* @param currentUser 当前登录人 |
|||
* @param allocAll 是否汇总所有(true:汇总查询条件下所有工单,false:只汇总选中的) |
|||
* @return 执行结果 |
|||
*/ |
|||
ResponseData executeWorkOrderAlloc(SearchShopOrder query, List<String> orderNoList, String currentUser, boolean allocAll); |
|||
|
|||
/** |
|||
* 执行工单数据回传(调用U8接口) |
|||
* @param data 查询条件(包含工单筛选条件) |
|||
* @return 执行结果 |
|||
*/ |
|||
ResponseData executeWorkOrderSync(UspWorkOrderAllocData data); |
|||
} |
|||
@ -0,0 +1,267 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
|||
<mapper namespace="com.gaotao.modules.shopOrder.dao.WorkOrderAllocMapper"> |
|||
|
|||
<!-- 分页查询生产订单(工单数据汇总专用) --> |
|||
<select id="searchShopOrderForAlloc" parameterType="com.gaotao.modules.shopOrder.entity.SearchShopOrder" resultType="com.gaotao.modules.shopOrder.entity.SearchShopOrder"> |
|||
Select |
|||
T.OrderNo, |
|||
T.NeedDate, |
|||
T.OrderType, |
|||
T.PartNo, |
|||
p.PartDescription + ' / ' + isnull(p.Spec, '') AS PartDescription, |
|||
T.LotSize, |
|||
T.Planner, |
|||
T.Status, |
|||
T.CustomerID, |
|||
P.ConfigurationTemplateID AS CustomerName, |
|||
T.PlanStartDate, |
|||
T.Leadtime, |
|||
T.EnterDate, |
|||
T.Username, |
|||
T.FinishedQty, |
|||
T.ReleaseDate, |
|||
T.ReleaseGuys, |
|||
T.ScheduleDate, |
|||
T.Scheduler, |
|||
T.IssueDate, |
|||
T.ReportDate, |
|||
T.ReceiveDate, |
|||
T.Printed, |
|||
T.ProjectID, |
|||
pr.ProjectName, |
|||
T.BOMRevNo, |
|||
T.RoutingRevNo, |
|||
T.OriginalNeedDate, |
|||
T.OrderRef1, |
|||
T.OrderRef2, |
|||
T.Site, |
|||
T.Remark, |
|||
CostRollUpFlag, |
|||
T.ManualFlag, |
|||
T.OriSOOrderNo, |
|||
P.FamilyID, |
|||
dbo.Get_PartFamilyDesc (P.Site, P.FamilyID) AS FamilyName, |
|||
P.GroupID, |
|||
dbo.Get_PartGroupDesc (P.Site, P.GroupID) AS GroupName, |
|||
T.ReceiveStatus, |
|||
T.RepairSOFlag, |
|||
T.E_OriginalOrderType, |
|||
T.E_OriginalOrderNo, |
|||
T.E_Levels, |
|||
P.PartType, |
|||
P.Remark AS CustPartNo, |
|||
T.NeedDate AS COPlanShipDate, |
|||
T.batch_no batchNo, |
|||
(SELECT COUNT(1) FROM SOScheduledRouting where Site = T.site and OrderNo = T.OrderNo) AS apsResourceTotal, |
|||
(SELECT COUNT(1) FROM SOScheduledRouting where Site = T.site and OrderNo = T.OrderNo AND QtyReported <![CDATA[<=]]> 0 AND TimeReported <![CDATA[<=]]> 0) AS notYetStartedResourceTotal, |
|||
0 alreadyApplyTotal |
|||
from Part as p,ShopOrder as T |
|||
left join Project as pr on pr.Site=T.Site and pr.Projectid=T.ProjectID |
|||
<where> |
|||
AND T.Site = p.Site and T.PartNo = p.PartNo |
|||
and T.site in (Select Site from AccessSite where upper(UserID)=#{query.user}) |
|||
<if test="query.orderType != null and query.orderType != ''"> |
|||
AND T.OrderType like '%' + #{query.orderType} + '%' |
|||
</if> |
|||
<if test="query.planner != null and query.planner != ''"> |
|||
AND T.Planner like '%' + #{query.planner} + '%' |
|||
</if> |
|||
<if test="query.site != null and query.site != ''"> |
|||
AND T.Site like '%' + #{query.site} + '%' |
|||
</if> |
|||
<if test="query.buNo != null and query.buNo != ''"> |
|||
AND T.bu_no like '%' + #{query.buNo} + '%' |
|||
</if> |
|||
<if test="query.partType != null and query.partType != ''"> |
|||
AND P.PartType like '%' + #{query.partType} + '%' |
|||
</if> |
|||
<if test="query.partNo != null and query.partNo != ''"> |
|||
AND T.PartNo like '%' + #{query.partNo} + '%' |
|||
</if> |
|||
<if test="query.status != null and query.status != ''"> |
|||
AND T.Status = #{query.status} |
|||
</if> |
|||
<if test="query.statusList != null and query.statusList.size > 0"> |
|||
AND T.Status in |
|||
<foreach item="item" collection="query.statusList" open="(" separator="," close=")"> |
|||
#{item} |
|||
</foreach> |
|||
</if> |
|||
<if test="query.partDescription != null and query.partDescription != ''"> |
|||
AND p.PartDescription like '%' + #{query.partDescription} + '%' |
|||
</if> |
|||
<if test="query.projectID != null and query.projectID != ''"> |
|||
AND T.ProjectID like '%' + #{query.projectID} + '%' |
|||
</if> |
|||
<if test="query.remark != null and query.remark != ''"> |
|||
AND T.Remark like '%' + #{query.remark} + '%' |
|||
</if> |
|||
<if test="query.orderNo != null and query.orderNo != ''"> |
|||
AND T.OrderNo like '%' + #{query.orderNo} + '%' |
|||
</if> |
|||
<if test="query.orderRef1 != null and query.orderRef1 != ''"> |
|||
AND T.OrderRef1 like '%' + #{query.orderRef1} + '%' |
|||
</if> |
|||
<if test="query.costRollUpFlag != null and query.costRollUpFlag != ''"> |
|||
AND CostRollUpFlag like '%' + #{query.costRollUpFlag} + '%' |
|||
</if> |
|||
<if test="query.date1 != null"> |
|||
AND T.EnterDate >= #{query.date1} |
|||
</if> |
|||
<if test="query.date2 != null"> |
|||
AND dateadd(DAY, 1, #{query.date2}) > T.EnterDate |
|||
</if> |
|||
<if test="query.date3 != null"> |
|||
AND T.NeedDate >= #{query.date3} |
|||
</if> |
|||
<if test="query.date4 != null"> |
|||
AND dateadd(DAY, 1, #{query.date4}) > T.NeedDate |
|||
</if> |
|||
</where> |
|||
ORDER BY T.EnterDate DESC |
|||
</select> |
|||
|
|||
<!-- 根据allocType查询工单汇总数据 --> |
|||
<select id="selectByAllocType" parameterType="com.gaotao.modules.shopOrder.entity.UspWorkOrderAllocData" |
|||
resultType="com.gaotao.modules.shopOrder.entity.UspWorkOrderAllocData"> |
|||
SELECT |
|||
site, |
|||
orderNo, |
|||
batchNo, |
|||
erp_orderNo as erpOrderNo, |
|||
erp_orderLineNo as erpOrderLineNo, |
|||
rowNo, |
|||
itemNo, |
|||
operator, |
|||
allocReportQty, |
|||
allocApproveQty, |
|||
allocScrapQty, |
|||
allocSetupTime, |
|||
allocManfTime, |
|||
allocBy, |
|||
allocDate, |
|||
synced_date as syncedDate, |
|||
synced_mes as syncedMes, |
|||
allocType |
|||
FROM UspWorkOrderAlloc |
|||
<where> |
|||
<if test="site != null and site != ''"> |
|||
AND site = #{site} |
|||
</if> |
|||
<if test="orderNo != null and orderNo != ''"> |
|||
AND orderNo = #{orderNo} |
|||
</if> |
|||
<if test="allocType != null and allocType != ''"> |
|||
AND allocType = #{allocType} |
|||
</if> |
|||
</where> |
|||
ORDER BY allocDate DESC |
|||
</select> |
|||
|
|||
<!-- 查询未传输的数据 --> |
|||
<select id="selectUnSyncedData" parameterType="com.gaotao.modules.shopOrder.entity.UspWorkOrderAllocData" |
|||
resultType="com.gaotao.modules.shopOrder.entity.UspWorkOrderAllocData"> |
|||
SELECT |
|||
site, |
|||
orderNo, |
|||
batchNo, |
|||
erp_orderNo as erpOrderNo, |
|||
erp_orderLineNo as erpOrderLineNo, |
|||
rowNo, |
|||
itemNo, |
|||
operator, |
|||
allocReportQty, |
|||
allocApproveQty, |
|||
allocScrapQty, |
|||
allocSetupTime, |
|||
allocManfTime, |
|||
allocBy, |
|||
allocDate, |
|||
synced_date as syncedDate, |
|||
synced_mes as syncedMes, |
|||
allocType |
|||
FROM UspWorkOrderAlloc |
|||
<where> |
|||
AND (allocType = '产量未传输' OR allocType = '工时未传输') |
|||
<if test="site != null and site != ''"> |
|||
AND site = #{site} |
|||
</if> |
|||
<if test="orderNoList != null and orderNoList.size() > 0"> |
|||
AND orderNo IN |
|||
<foreach collection="orderNoList" item="item" open="(" separator="," close=")"> |
|||
#{item} |
|||
</foreach> |
|||
</if> |
|||
</where> |
|||
ORDER BY allocDate ASC |
|||
</select> |
|||
|
|||
<!-- 更新SFDC表的同步信息 --> |
|||
<update id="updateSfdcSyncedCode"> |
|||
UPDATE SFDC |
|||
SET synced_code = #{syncedCode}, |
|||
synced_flag = 'Y' |
|||
WHERE Site = #{site} |
|||
AND OrderNo = #{orderNo} |
|||
AND ItemNo = #{batchNo} |
|||
</update> |
|||
|
|||
<!-- 更新UspWorkOrderAlloc的同步异常信息 --> |
|||
<update id="updateAllocSyncedError"> |
|||
UPDATE UspWorkOrderAlloc |
|||
SET synced_date = #{syncedDate}, |
|||
synced_mes = #{syncedMes} |
|||
WHERE site = #{site} |
|||
AND orderNo = #{orderNo} |
|||
AND rowNo = #{rowNo} |
|||
</update> |
|||
|
|||
<!-- 插入临时表(单条) --> |
|||
<insert id="insertAllocTemp"> |
|||
INSERT INTO UspWorkOrderAllocTemp (site, orderNo) |
|||
VALUES (#{site}, #{orderNo}) |
|||
</insert> |
|||
|
|||
<!-- 根据查询条件批量插入临时表 --> |
|||
<insert id="insertAllocTempByQuery"> |
|||
INSERT INTO UspWorkOrderAllocTemp (site, orderNo) |
|||
SELECT T.Site, T.OrderNo |
|||
FROM ShopOrder T |
|||
LEFT JOIN Part P ON T.Site = P.Site AND T.PartNo = P.PartNo |
|||
<where> |
|||
AND T.site in (Select Site from AccessSite where upper(UserID)=#{query.user}) |
|||
<if test="query.orderType != null and query.orderType != ''"> |
|||
AND T.OrderType like '%' + #{query.orderType} + '%' |
|||
</if> |
|||
<if test="query.site != null and query.site != ''"> |
|||
AND T.Site like '%' + #{query.site} + '%' |
|||
</if> |
|||
<if test="query.partNo != null and query.partNo != ''"> |
|||
AND T.PartNo like '%' + #{query.partNo} + '%' |
|||
</if> |
|||
<if test="query.status != null and query.status != ''"> |
|||
AND T.Status = #{query.status} |
|||
</if> |
|||
<if test="query.partDescription != null and query.partDescription != ''"> |
|||
AND P.PartDescription like '%' + #{query.partDescription} + '%' |
|||
</if> |
|||
<if test="query.orderNo != null and query.orderNo != ''"> |
|||
AND T.OrderNo like '%' + #{query.orderNo} + '%' |
|||
</if> |
|||
<if test="query.date1 != null"> |
|||
AND T.EnterDate >= #{query.date1} |
|||
</if> |
|||
<if test="query.date2 != null"> |
|||
AND dateadd(DAY, 1, #{query.date2}) > T.EnterDate |
|||
</if> |
|||
<if test="query.date3 != null"> |
|||
AND T.NeedDate >= #{query.date3} |
|||
</if> |
|||
<if test="query.date4 != null"> |
|||
AND dateadd(DAY, 1, #{query.date4}) > T.NeedDate |
|||
</if> |
|||
</where> |
|||
</insert> |
|||
|
|||
</mapper> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue