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.

424 lines
15 KiB

2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
  1. package com.ccl.tt.service.impl;
  2. import java.io.BufferedOutputStream;
  3. import java.io.File;
  4. import java.io.FileOutputStream;
  5. import java.sql.Timestamp;
  6. import java.util.ArrayList;
  7. import java.util.Calendar;
  8. import java.util.Date;
  9. import java.util.List;
  10. import java.util.Map;
  11. import java.util.zip.ZipEntry;
  12. import java.util.zip.ZipOutputStream;
  13. import org.slf4j.Logger;
  14. import org.slf4j.LoggerFactory;
  15. import org.springframework.beans.factory.annotation.Autowired;
  16. import org.springframework.beans.factory.annotation.Value;
  17. import org.springframework.security.core.Authentication;
  18. import org.springframework.security.core.context.SecurityContextHolder;
  19. import org.springframework.stereotype.Service;
  20. import org.springframework.transaction.annotation.Transactional;
  21. import com.ccl.tt.dao.BasicDao;
  22. import com.ccl.tt.dao.FinalRollDao;
  23. import com.ccl.tt.dao.PrepressDao;
  24. import com.ccl.tt.data.PartData;
  25. import com.ccl.tt.entity.Sequence;
  26. import com.ccl.tt.entity.SoInfo;
  27. import com.ccl.tt.model.SoOrderFileHist;
  28. import com.ccl.tt.repository.SequenceRepository;
  29. import com.ccl.tt.repository.SoInfoRepository;
  30. import com.ccl.tt.service.PrepressService;
  31. import com.ccl.tt.utils.DateUtils;
  32. import com.ccl.tt.utils.SerialUtil;
  33. /**
  34. *
  35. * @ClassName: PrepressServiceImpl
  36. * @Description: 印前的方法实现
  37. * @author: LR
  38. * @date: 2024年6月18日 下午5:59:42
  39. * @Copyright:
  40. */
  41. @Service
  42. public class PrepressServiceImpl implements PrepressService {
  43. private static final Logger logger = LoggerFactory.getLogger(PrepressServiceImpl.class);
  44. @Value("${ifs.datasource.sql.order}")
  45. String ifsOrderSql;
  46. @Value("${item.filePath}")
  47. private String filePath;
  48. @Autowired
  49. private PrepressDao prepressDao;
  50. @Autowired
  51. private BasicDao basicDao;
  52. @Autowired
  53. private SoInfoRepository soInfoRepo;
  54. @Autowired
  55. private SequenceRepository seqRepo;
  56. @Autowired
  57. private FinalRollDao finalRollDao;
  58. @Override
  59. public Map<String, Object> getIfsOrder(String orderNo) {
  60. Map<String, Object> resultMap = prepressDao.getResultMapBySql(ifsOrderSql, orderNo);
  61. //判断是否非空
  62. if (resultMap == null || resultMap.isEmpty()) {
  63. throw new RuntimeException("Order information not found for " + orderNo + ":");
  64. }
  65. //校验工单是否存在当前的物料编码
  66. String partNo = String.valueOf(resultMap.get("part_no"));
  67. //判断物料是否存在
  68. if(partNo == null || "".equals(partNo)) {
  69. throw new RuntimeException("Material information not found for " + orderNo + "!");
  70. }
  71. //查询物料信息
  72. PartData part = basicDao.getPartDataByPartNo(partNo);
  73. //判断是否存在
  74. if(null == part) {
  75. throw new RuntimeException("Please maintain material code first:"+partNo+"!");
  76. }
  77. //填充物料信息
  78. resultMap.put("revNo", part.getRevNo());
  79. resultMap.put("partNo", part.getPartNo());
  80. resultMap.put("partDesc", part.getPartDesc());
  81. resultMap.put("apn", part.getSerialApn());
  82. resultMap.put("customerPartNo", part.getCustomerPartNo());
  83. resultMap.put("standardRollQty", part.getPackageQty());
  84. resultMap.put("noOfCross", part.getCross());
  85. resultMap.put("projectCode", part.getProjectCode());
  86. return resultMap;
  87. }
  88. @Override
  89. @Transactional
  90. public void addSoInfo(SoInfo soInfo) throws Exception {
  91. String orderNo = soInfo.getOrderNo();
  92. soInfo.setCreatedDate(new Timestamp(System.currentTimeMillis()));
  93. soInfo.setStatus(SoInfo.CREATED);
  94. soInfo.setIsrework("N");
  95. String needDateStr = soInfo.getNeedDate();
  96. Date needDate = DateUtils.getDateByParten(needDateStr, "yyyy-MM-dd");
  97. String currentDateStr = DateUtils.getStringDate(new Date(), "yyyy-MM-dd");
  98. Date currentDate = DateUtils.getAddNumsDateByType(DateUtils.getDateByParten(currentDateStr, "yyyy-MM-dd"), 3, "DAY");
  99. //判断是否需要
  100. if(needDate.getTime() > currentDate.getTime()) {
  101. throw new RuntimeException("Order planned start date is too late, please contact planning to modify!");
  102. }
  103. //判断是否存在
  104. SoInfo tempData = soInfoRepo.findByOrderNo(orderNo);
  105. if(tempData != null) {
  106. throw new RuntimeException("Current order already exists!");
  107. }
  108. soInfo.setFirstRollTime(needDate);
  109. //需要判断当前的数量是否能够整排
  110. int inputLotSize = soInfo.getInputLotSize();
  111. int cross = soInfo.getNoOfCross();
  112. if(inputLotSize % cross > 0) {
  113. inputLotSize = ((inputLotSize / cross) + 1) * cross;
  114. //重置工单得生产数量
  115. soInfo.setInputLotSize(inputLotSize);
  116. }
  117. soInfo.validate();
  118. //查询是否物料编码是否存在
  119. String partNo = soInfo.getPartNo();
  120. //判断物料是否存在
  121. if(partNo == null || "".equals(partNo)) {
  122. throw new RuntimeException("Material code cannot be empty!");
  123. }
  124. //查询物料信息
  125. PartData part = basicDao.getPartDataByPartNo(partNo);
  126. //判断是否存在
  127. if(null == part) {
  128. throw new RuntimeException("Please maintain material code first:"+partNo+"!");
  129. }
  130. //设置参数
  131. soInfo.setLaminationFlag("Y");
  132. //查询长度是否符合要求
  133. String apn = soInfo.getApn();
  134. if(apn.length() != 11) {
  135. throw new RuntimeException("Length of apn does not comply with the rules!");
  136. }
  137. String revNo = soInfo.getRevNo();
  138. if(revNo.length() != 1) {
  139. throw new RuntimeException("revNo length does not comply with the rules!");
  140. }
  141. //设置参数
  142. soInfo.setCustomerPartNoAll(part.getCustomerPartNo());
  143. soInfoRepo.save(soInfo);
  144. }
  145. @Override
  146. @Transactional
  147. public void genSerials(Integer id) {
  148. //查询工单得信息
  149. SoInfo soInfo = soInfoRepo.findOne(id);
  150. //校验工单得信息
  151. if (soInfo == null){
  152. throw new RuntimeException("Order not found!");
  153. }
  154. if (soInfo.getSerialsGenDate() != null){
  155. throw new RuntimeException("Already generated!");
  156. }
  157. //产生码包的模板
  158. String snTemplate = genSerialTemplate(soInfo);
  159. if(snTemplate == null || "".equals(snTemplate)){
  160. throw new RuntimeException("eeeecode not found!");
  161. }
  162. soInfo.setSerialsTemplate(snTemplate);
  163. //find existing
  164. Sequence seq = seqRepo.findByTag(snTemplate);
  165. if (seq == null){
  166. seq = new Sequence();
  167. seq.setTag(snTemplate);
  168. seq.setSeq(0);
  169. }
  170. soInfo.setSerialStart(seq.getSeq() + 1);
  171. soInfo.setSerialEnd(soInfo.getSerialStart() + soInfo.getInputLotSize() - 1);
  172. //调用方法产生当前码包文件
  173. List<String> serialList = this.genSoOrderSerialList(soInfo);
  174. //公共参数
  175. String orderNo = soInfo.getOrderNo();
  176. String partNo = soInfo.getPartNo();
  177. //生成单排的文件
  178. this.genSingleRowZipSerialFile(orderNo, partNo, serialList);
  179. //生成多排的文件
  180. this.genMultiRowZipSerialFile(orderNo, partNo, serialList);
  181. //保存工单得信息
  182. Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
  183. soInfo.setRolls(0);
  184. soInfo.setStatus(SoInfo.GENERATED);
  185. soInfo.setSerialsGenBy(authentication.getName());
  186. soInfo.setSerialsGenDate(new Timestamp(System.currentTimeMillis()));
  187. //保存sn的记录数据 以前2023RQ添加的
  188. finalRollDao.deleteSNTemplateCopy(soInfo);
  189. finalRollDao.saveSNTemplateCopy(soInfo);
  190. //保存工单得信息
  191. soInfoRepo.save(soInfo);
  192. //保存序列号的信息
  193. seq.setSeq(soInfo.getSerialEnd());
  194. seqRepo.save(seq);
  195. }
  196. /**
  197. *
  198. * @Title: genMultiRowZipSerialFile
  199. * @Description: 创建多排的文件
  200. * @author: LR
  201. * @date 2024年5月22日 下午2:48:25
  202. * @return: void
  203. * @throws
  204. */
  205. public void genMultiRowZipSerialFile(String orderNo, String partNo, List<String> serialList) {
  206. //查询物料的信息
  207. PartData part = basicDao.getPartDataByPartNo(partNo);
  208. int crossNumber = part.getCross();
  209. String apn = part.getApn();
  210. String revNo = part.getRevNo();
  211. int serialSize = serialList.size();
  212. int rows = serialSize / crossNumber;
  213. String baseDatePath = DateUtils.getStringDate(new Date(), "yyyy-MM-dd");
  214. String sourceFilePath = filePath + "\\" +baseDatePath;
  215. File sourceFile = new File(sourceFilePath);
  216. //判断是否存在不存在创建目录
  217. if(!sourceFile.exists()) {
  218. sourceFile.mkdirs();
  219. }
  220. //创建文件
  221. long start = System.currentTimeMillis();
  222. String zipFileName = orderNo+"-"+partNo+".zip";
  223. File zipFile = new File(sourceFile, zipFileName);
  224. try (FileOutputStream fos = new FileOutputStream(zipFile);
  225. BufferedOutputStream bos = new BufferedOutputStream(fos);
  226. ZipOutputStream zos = new ZipOutputStream(bos);)
  227. {
  228. String fileName = orderNo+"-"+partNo+".csv";
  229. ZipEntry entry = new ZipEntry(fileName);
  230. zos.putNextEntry(entry);
  231. //写入ID
  232. zos.write(( "ID-1").getBytes("UTF-8"));
  233. zos.write((",").getBytes("UTF-8"));
  234. //创建表头
  235. for(int i = 1; i <= crossNumber; i++) {
  236. //首先循环生成表头的文件
  237. zos.write(("SN"+i).getBytes("UTF-8"));
  238. zos.write((",").getBytes("UTF-8"));
  239. }
  240. //换行写数据
  241. zos.write(("\r\n").getBytes("UTF-8"));
  242. //双重for循环开始写入数据
  243. //外层for循环写行
  244. for(int i = 0; i < rows; i++) {
  245. //写入行数
  246. zos.write((i + 1+"").getBytes("UTF-8"));
  247. zos.write((",").getBytes("UTF-8"));
  248. //内层循环循环列
  249. for(int j = 0; j < crossNumber; j++) {
  250. int serialIndex = (j * rows) + i;
  251. //写数据
  252. zos.write((serialList.get(serialIndex)).getBytes("UTF-8"));
  253. zos.write((",").getBytes("UTF-8"));
  254. }
  255. //换行写数据
  256. zos.write(("\r\n").getBytes("UTF-8"));
  257. }
  258. //把数据刷入缓存中
  259. zos.flush();
  260. bos.flush();
  261. fos.flush();
  262. } catch (Exception e) {
  263. e.printStackTrace();
  264. }
  265. //记录时间
  266. long duration = System.currentTimeMillis() - start;
  267. logger.info("Generated SN for order [{}], size={}, duration={}.",
  268. orderNo, serialList.size(), duration);
  269. //创建文件记录
  270. //创建文件记录
  271. SoOrderFileHist fileHist = new SoOrderFileHist();
  272. fileHist.setSite("41");
  273. fileHist.setOrderNo(orderNo);
  274. fileHist.setFileName(zipFileName);
  275. fileHist.setFilePath(zipFile.getAbsolutePath());
  276. fileHist.setIsMulti("Y");
  277. //保存当前的文件记录
  278. prepressDao.insertSoOrderFileHist(fileHist);
  279. }
  280. /**
  281. *
  282. * @Title: genSingleRowZipSerialFile
  283. * @Description:
  284. * @author: LR
  285. * @date 2024年5月22日 下午2:00:30
  286. * @return: void
  287. * @throws
  288. */
  289. public void genSingleRowZipSerialFile(String orderNo, String partNo, List<String> serialList) {
  290. //公共参数
  291. String baseDatePath = DateUtils.getStringDate(new Date(), "yyyy-MM-dd");
  292. String sourceFilePath = filePath + "\\" +baseDatePath;
  293. File sourceFile = new File(sourceFilePath);
  294. //判断是否存在不存在创建目录
  295. if(!sourceFile.exists()) {
  296. sourceFile.mkdirs();
  297. }
  298. //创建文件
  299. long start = System.currentTimeMillis();
  300. String zipFileName = orderNo+"single.zip";
  301. File zipFile = new File(sourceFile, zipFileName);
  302. try (FileOutputStream fos = new FileOutputStream(zipFile);
  303. BufferedOutputStream bos = new BufferedOutputStream(fos);
  304. ZipOutputStream zos = new ZipOutputStream(bos);)
  305. {
  306. String fileName = orderNo+"single.csv";
  307. ZipEntry entry = new ZipEntry(fileName);
  308. zos.putNextEntry(entry);
  309. //创建表头
  310. zos.write(("SN").getBytes("UTF-8"));
  311. zos.write((",").getBytes("UTF-8"));
  312. zos.write(( "ID" + "\r\n").getBytes("UTF-8"));
  313. //循环开始写入数据
  314. for(int i = 0; i < serialList.size(); i++) {
  315. //写数据
  316. zos.write((serialList.get(i)).getBytes("UTF-8"));
  317. zos.write((",").getBytes("UTF-8"));
  318. zos.write(((i + 1) + "\r\n").getBytes("UTF-8"));
  319. }
  320. //把数据刷入缓存中
  321. zos.flush();
  322. bos.flush();
  323. fos.flush();
  324. } catch (Exception e) {
  325. e.printStackTrace();
  326. }
  327. long duration = System.currentTimeMillis() - start;
  328. logger.info("Generated SN for order [{}], size={}, duration={}.",
  329. orderNo, serialList.size(), duration);
  330. //创建文件记录
  331. SoOrderFileHist fileHist = new SoOrderFileHist();
  332. fileHist.setSite("41");
  333. fileHist.setOrderNo(orderNo);
  334. fileHist.setFileName(zipFileName);
  335. fileHist.setFilePath(zipFile.getAbsolutePath());
  336. fileHist.setIsMulti("N");
  337. //保存当前的文件记录
  338. prepressDao.insertSoOrderFileHist(fileHist);
  339. }
  340. /**
  341. *
  342. * @Title: genSoOrderSerialList
  343. * @Description: 产生按照要求符合条件的码包数据
  344. * @author: LR
  345. * @date 2024年6月19日 下午3:01:40
  346. * @return: List<String>
  347. * @throws
  348. */
  349. public List<String> genSoOrderSerialList(SoInfo soInfo) {
  350. List<String> snList = new ArrayList<>();
  351. String partNo = soInfo.getPartNo();
  352. //查询当前物料的数据
  353. PartData part = basicDao.getPartDataByPartNo(partNo);
  354. String codeType = part.getCodeType();
  355. for (int snIndex = soInfo.getSerialStart(); snIndex <= soInfo.getSerialEnd(); snIndex++) {
  356. String currentSn = SerialUtil.getSerialNo(soInfo.getSerialsTemplate(), snIndex, codeType);
  357. snList.add(currentSn);
  358. }
  359. return snList;
  360. }
  361. /**
  362. *
  363. * @Title: genSerialTemplate
  364. * @Description: 产生码包的模板的方法
  365. * @author: LR
  366. * @date 2024年6月19日 下午2:50:09
  367. * @return: String
  368. * @throws
  369. */
  370. public String genSerialTemplate(SoInfo soInfo) {
  371. //公共参数
  372. String partNo = soInfo.getPartNo();
  373. //查询物料的属性
  374. PartData part = basicDao.getPartDataByPartNo(partNo);
  375. //查询相关的参数
  376. String codeType = part.getCodeType();
  377. Calendar cal = Calendar.getInstance();
  378. cal.setTime(soInfo.getSerialsDate());
  379. String platCode3 = "J4K";
  380. String year1 = String.valueOf(cal.get(Calendar.YEAR) % 10);
  381. String week2 = org.apache.commons.lang3.StringUtils.leftPad(String.valueOf(cal.get(Calendar.WEEK_OF_YEAR)), 2, '0');
  382. String day1 = String.valueOf(cal.get(Calendar.DAY_OF_WEEK));
  383. String code4 = "____";
  384. String appleEEEE4 = part.getEeeeCode();
  385. String rev1 = part.getRevNo();
  386. String delimiter1 = "+";
  387. String apn = part.getSerialApn();
  388. String checkSum1 = "_";
  389. String snLeft7 = platCode3 + year1 + week2 + day1;
  390. String snMiddle5 = appleEEEE4 + rev1;
  391. String snRight = delimiter1 + apn;
  392. String snFormat = null;
  393. //区分不同的类型
  394. if ("2024".equals(codeType)) {
  395. snFormat = snLeft7 + code4 + snMiddle5 + checkSum1 + snRight;
  396. }else if("2025".equals(codeType)) {
  397. snFormat = snLeft7 + code4 + snMiddle5 + checkSum1;
  398. }
  399. return snFormat;
  400. }
  401. }