Commit 02e48b771ddd76300e4ff78f0a88e39b51ff4b55

Authored by 房远帅
1 parent 573c26a3

试样订单:跟踪单-导出

1 package com.lframework.xingyun.sc.controller.sample; 1 package com.lframework.xingyun.sc.controller.sample;
2 2
  3 +import cn.hutool.core.io.resource.ClassPathResource;
3 import com.lframework.xingyun.sc.bo.sample.tracking.GetSampleResultTrackingBo; 4 import com.lframework.xingyun.sc.bo.sample.tracking.GetSampleResultTrackingBo;
4 import com.lframework.xingyun.sc.bo.sample.tracking.QuerySampleResultTrackingBo; 5 import com.lframework.xingyun.sc.bo.sample.tracking.QuerySampleResultTrackingBo;
5 import com.lframework.xingyun.sc.entity.SampleFeedbackTrackingDetail; 6 import com.lframework.xingyun.sc.entity.SampleFeedbackTrackingDetail;
6 import com.lframework.xingyun.sc.service.sample.SampleFeedbackTrackingDetailService; 7 import com.lframework.xingyun.sc.service.sample.SampleFeedbackTrackingDetailService;
  8 +import com.lframework.xingyun.sc.utils.ExcelUtil;
  9 +import com.lframework.xingyun.sc.utils.LatexFormulaExcelExporterUtil;
7 import com.lframework.xingyun.sc.vo.sample.tracking.QuerySampleFeedbackTrackingDetailVo; 10 import com.lframework.xingyun.sc.vo.sample.tracking.QuerySampleFeedbackTrackingDetailVo;
8 import com.lframework.xingyun.sc.vo.sample.tracking.QuerySampleResultTrackingVo; 11 import com.lframework.xingyun.sc.vo.sample.tracking.QuerySampleResultTrackingVo;
9 import com.lframework.xingyun.sc.service.sample.SampleResultTrackingService; 12 import com.lframework.xingyun.sc.service.sample.SampleResultTrackingService;
@@ -12,21 +15,33 @@ import com.lframework.starter.web.core.utils.PageResultUtil; @@ -12,21 +15,33 @@ import com.lframework.starter.web.core.utils.PageResultUtil;
12 import com.lframework.starter.web.core.components.resp.PageResult; 15 import com.lframework.starter.web.core.components.resp.PageResult;
13 import com.lframework.starter.web.core.components.resp.InvokeResult; 16 import com.lframework.starter.web.core.components.resp.InvokeResult;
14 import javax.annotation.Resource; 17 import javax.annotation.Resource;
  18 +import javax.servlet.http.HttpServletResponse;
15 import javax.validation.constraints.NotBlank; 19 import javax.validation.constraints.NotBlank;
  20 +import com.lframework.xingyun.sc.vo.sample.tracking.UpdateSampleResultTrackingVo;
16 import io.swagger.annotations.ApiImplicitParam; 21 import io.swagger.annotations.ApiImplicitParam;
17 import com.lframework.starter.web.core.components.resp.InvokeResultBuilder; 22 import com.lframework.starter.web.core.components.resp.InvokeResultBuilder;
18 import com.lframework.starter.common.exceptions.impl.DefaultClientException; 23 import com.lframework.starter.common.exceptions.impl.DefaultClientException;
19 import io.swagger.annotations.ApiOperation; 24 import io.swagger.annotations.ApiOperation;
20 import com.lframework.starter.common.utils.CollectionUtil; 25 import com.lframework.starter.common.utils.CollectionUtil;
21 import io.swagger.annotations.Api; 26 import io.swagger.annotations.Api;
  27 +import lombok.extern.slf4j.Slf4j;
  28 +import org.apache.commons.collections.CollectionUtils;
  29 +import org.apache.commons.lang3.StringUtils;
  30 +import org.apache.poi.ss.usermodel.Sheet;
  31 +import org.apache.poi.ss.usermodel.Workbook;
  32 +import org.apache.poi.util.IOUtils;
  33 +import org.apache.poi.xssf.usermodel.XSSFWorkbook;
22 import org.springframework.web.bind.annotation.DeleteMapping; 34 import org.springframework.web.bind.annotation.DeleteMapping;
23 import com.lframework.starter.web.core.controller.DefaultBaseController; 35 import com.lframework.starter.web.core.controller.DefaultBaseController;
24 import com.lframework.starter.web.core.annotations.security.HasPermission; 36 import com.lframework.starter.web.core.annotations.security.HasPermission;
25 import org.springframework.validation.annotation.Validated; 37 import org.springframework.validation.annotation.Validated;
26 import org.springframework.web.bind.annotation.*; 38 import org.springframework.web.bind.annotation.*;
27 -  
28 import javax.validation.Valid; 39 import javax.validation.Valid;
29 -import java.util.List; 40 +import java.io.FileNotFoundException;
  41 +import java.io.IOException;
  42 +import java.io.InputStream;
  43 +import java.net.URLEncoder;
  44 +import java.util.*;
30 import java.util.stream.Collectors; 45 import java.util.stream.Collectors;
31 46
32 /** 47 /**
@@ -34,6 +49,7 @@ import java.util.stream.Collectors; @@ -34,6 +49,7 @@ import java.util.stream.Collectors;
34 * 49 *
35 */ 50 */
36 @Api(tags = "产品试样结果跟踪单") 51 @Api(tags = "产品试样结果跟踪单")
  52 +@Slf4j
37 @Validated 53 @Validated
38 @RestController 54 @RestController
39 @RequestMapping("/sample/tracking") 55 @RequestMapping("/sample/tracking")
@@ -49,7 +65,7 @@ public class SampleResultTrackingController extends DefaultBaseController { @@ -49,7 +65,7 @@ public class SampleResultTrackingController extends DefaultBaseController {
49 * 查询列表 65 * 查询列表
50 */ 66 */
51 @ApiOperation("查询列表") 67 @ApiOperation("查询列表")
52 - @HasPermission({"sample:tracking:query"}) 68 + @HasPermission({"sample-order:follow-up-form:query"})
53 @GetMapping("/query") 69 @GetMapping("/query")
54 public InvokeResult<PageResult<QuerySampleResultTrackingBo>> query(@Valid QuerySampleResultTrackingVo vo) { 70 public InvokeResult<PageResult<QuerySampleResultTrackingBo>> query(@Valid QuerySampleResultTrackingVo vo) {
55 PageResult<SampleResultTracking> pageResult = sampleResultTrackingService.query(getPageIndex(vo), getPageSize(vo), vo); 71 PageResult<SampleResultTracking> pageResult = sampleResultTrackingService.query(getPageIndex(vo), getPageSize(vo), vo);
@@ -66,7 +82,7 @@ public class SampleResultTrackingController extends DefaultBaseController { @@ -66,7 +82,7 @@ public class SampleResultTrackingController extends DefaultBaseController {
66 */ 82 */
67 @ApiOperation("根据ID查询") 83 @ApiOperation("根据ID查询")
68 @ApiImplicitParam(value = "id", name = "id", paramType = "query", required = true) 84 @ApiImplicitParam(value = "id", name = "id", paramType = "query", required = true)
69 - @HasPermission({"sample:tracking:query"}) 85 + @HasPermission({"sample-order:follow-up-form:query"})
70 @GetMapping 86 @GetMapping
71 public InvokeResult<GetSampleResultTrackingBo> get(@NotBlank(message = "id不能为空!") String id) { 87 public InvokeResult<GetSampleResultTrackingBo> get(@NotBlank(message = "id不能为空!") String id) {
72 SampleResultTracking data = sampleResultTrackingService.findById(id); 88 SampleResultTracking data = sampleResultTrackingService.findById(id);
@@ -83,14 +99,148 @@ public class SampleResultTrackingController extends DefaultBaseController { @@ -83,14 +99,148 @@ public class SampleResultTrackingController extends DefaultBaseController {
83 } 99 }
84 100
85 /** 101 /**
  102 + * 修改
  103 + */
  104 + @ApiOperation("修改")
  105 + @HasPermission({"sample-order:follow-up-form:modify"})
  106 + @PutMapping
  107 + public InvokeResult<Void> update(@Valid @RequestBody UpdateSampleResultTrackingVo vo) {
  108 +
  109 + sampleResultTrackingService.update(vo);
  110 +
  111 + return InvokeResultBuilder.success();
  112 + }
  113 +
  114 + /**
86 * 根据ID删除 115 * 根据ID删除
87 */ 116 */
88 @ApiOperation("根据ID删除") 117 @ApiOperation("根据ID删除")
89 @ApiImplicitParam(value = "id", name = "id", paramType = "query", required = true) 118 @ApiImplicitParam(value = "id", name = "id", paramType = "query", required = true)
90 - @HasPermission({"sample:tracking:delete"}) 119 + @HasPermission({"sample-order:follow-up-form:delete"})
91 @DeleteMapping 120 @DeleteMapping
92 public InvokeResult<Void> deleteById(@NotBlank(message = "id不能为空!") String id) { 121 public InvokeResult<Void> deleteById(@NotBlank(message = "id不能为空!") String id) {
93 sampleResultTrackingService.deleteById(id); 122 sampleResultTrackingService.deleteById(id);
94 return InvokeResultBuilder.success(); 123 return InvokeResultBuilder.success();
95 } 124 }
  125 +
  126 + @ApiOperation("产品试样结果跟踪单打印")
  127 + @HasPermission({"sample-order:follow-up-form:export"})
  128 + @GetMapping("/printResultTracking")
  129 + public void printResultTracking(@NotBlank(message = "id不能为空") String id, HttpServletResponse response) throws IOException {
  130 + SampleResultTracking data = sampleResultTrackingService.findById(id);
  131 + if (data == null) {
  132 + throw new DefaultClientException("产品试样结果跟踪单不存在!");
  133 + }
  134 + QuerySampleFeedbackTrackingDetailVo vo = new QuerySampleFeedbackTrackingDetailVo();
  135 + vo.setTrackingId(id);
  136 + List<SampleFeedbackTrackingDetail> detailList = sampleFeedbackTrackingDetailService.query(vo);
  137 + // 设置响应头
  138 + setupResponse(response, data.getCustomerName() + "-产品试样结果跟踪单打印.xlsx");
  139 +
  140 + try {
  141 + // 加载模板文件
  142 + ClassPathResource templateResource = new ClassPathResource("templates/confirmationSlipTemplate.xlsx");
  143 + try (InputStream inputStream = templateResource.getStream();
  144 + Workbook workbook = new XSSFWorkbook(inputStream)) {
  145 + try {
  146 + Sheet sheet = workbook.getSheetAt(0);
  147 + int startRow = 4; // 产品开始行
  148 + if (CollectionUtils.isNotEmpty(detailList)) {
  149 + for (int i = startRow + 1; i < startRow + detailList.size(); i++) {
  150 + ExcelUtil.copyRow(workbook, sheet, startRow, i);
  151 + }
  152 + for (SampleFeedbackTrackingDetail detail : detailList) {
  153 + ExcelUtil.setCellValue(sheet, startRow, 1, detail.getBrand());
  154 +
  155 + List<LatexFormulaExcelExporterUtil.FormulaComponent> formulaComponentList = new ArrayList<>(3);
  156 + if (detail.getThickness() != null) {
  157 + LatexFormulaExcelExporterUtil.FormulaComponent formulaComponent = new LatexFormulaExcelExporterUtil.FormulaComponent();
  158 + formulaComponent.setBase(detail.getThickness());
  159 + formulaComponent.setSup(detail.getThicknessTolPos());
  160 + formulaComponent.setSub(detail.getThicknessTolNeg());
  161 + formulaComponentList.add(formulaComponent);
  162 + }
  163 +
  164 + if (detail.getWidth() != null) {
  165 + LatexFormulaExcelExporterUtil.FormulaComponent formulaComponent = new LatexFormulaExcelExporterUtil.FormulaComponent();
  166 + formulaComponent.setBase(detail.getWidth());
  167 + formulaComponent.setSup(detail.getWidthTolPos());
  168 + formulaComponent.setSub(detail.getWidthTolNeg());
  169 + formulaComponentList.add(formulaComponent);
  170 + }
  171 +
  172 + if (detail.getLength() != null) {
  173 + LatexFormulaExcelExporterUtil.FormulaComponent formulaComponent = new LatexFormulaExcelExporterUtil.FormulaComponent();
  174 + formulaComponent.setBase(detail.getLength());
  175 + formulaComponent.setSup(detail.getLengthTolPos());
  176 + formulaComponent.setSub(detail.getLengthTolNeg());
  177 + formulaComponentList.add(formulaComponent);
  178 + }
  179 +
  180 + String latex = LatexFormulaExcelExporterUtil.convertToLatex(formulaComponentList);
  181 + if (StringUtils.isNotBlank(latex)) {
  182 + LatexFormulaExcelExporterUtil.insertLatexImageToCell(workbook, sheet, latex, startRow, 4, 2, 3);
  183 + }
  184 +
  185 + ExcelUtil.setCellValue(sheet, startRow, 4, detail.getStatus());
  186 + ExcelUtil.setCellValue(sheet, startRow, 5, detail.getShipmentDate());
  187 + ExcelUtil.setCellValue(sheet, startRow, 6, detail.getQuantity());
  188 + ExcelUtil.setCellValue(sheet, startRow, 7, detail.getYieldBatchNo());
  189 + startRow++;
  190 + }
  191 + }
  192 +
  193 + Map<String, Object> dataMap = new HashMap<>();
  194 + dataMap.put("customerName", data.getCustomerName() == null ? "" : data.getCustomerName());
  195 + dataMap.put("workshopName", data.getWorkshopName() == null ? "" : data.getWorkshopName());
  196 + dataMap.put("orderCode", data.getOrderCode() == null ? "" : data.getOrderCode());
  197 + dataMap.put("surface", data.getWorkshopName() == null ? "" : data.getWorkshopName());
  198 + dataMap.put("performance", data.getPerformance() == null ? "" : data.getPerformance());
  199 + dataMap.put("tolerance", data.getTolerance() == null ? "" : data.getTolerance());
  200 + dataMap.put("bandingPattern", data.getBandingPattern() == null ? "" : data.getBandingPattern());
  201 + dataMap.put("packaging", data.getPackaging() == null ? "" : data.getPackaging());
  202 + dataMap.put("weight", data.getWeight() == null ? "" : data.getWeight());
  203 + dataMap.put("other", data.getOther() == null ? "" : data.getOther());
  204 + dataMap.put("sampleSucces", data.isSampleSuccess() ? "☑试样成功" : "□试样成功");
  205 + dataMap.put("bulkOrder", data.isBulkOrder() ? "☑批量订货" : "□批量订货");
  206 + dataMap.put("sampleFailure", data.isSampleFailure() ? "☑试样不成功" : "□试样不成功");
  207 + dataMap.put("continueSample", data.isContinueSample() ? "☑继续试样" : "□继续试样");
  208 + dataMap.put("stopSample", data.isStopSample() ? "☑停止再试样" : "□停止再试样");
  209 + dataMap.put("customerReviewsFileName", data.getCustomerReviewsFileName() == null ? "" : data.getCustomerReviewsFileName());
  210 + dataMap.put("officeSupervisorOpinion", data.getOfficeSupervisorOpinion() == null ? "" : data.getOfficeSupervisorOpinion());
  211 + dataMap.put("qualitySupervisorOpinion", data.getQualitySupervisorOpinion() == null ? "" : data.getQualitySupervisorOpinion());
  212 + dataMap.put("qualityManagerOpinion", data.getQualityManagerOpinion() == null ? "" : data.getQualityManagerOpinion());
  213 + dataMap.put("operationsDepartmentSupervisorOpinion", data.getOperationsDepartmentSupervisorOpinion() == null ? "" : data.getOperationsDepartmentSupervisorOpinion());
  214 + dataMap.put("marketingDeputyDirectorOpinion", data.getMarketingDeputyDirectorOpinion() == null ? "" : data.getMarketingDeputyDirectorOpinion());
  215 + ExcelUtil.processTemplate(workbook, dataMap);
  216 +
  217 + // 写入响应流
  218 + workbook.write(response.getOutputStream());
  219 + response.getOutputStream().flush();
  220 + } finally {
  221 + IOUtils.closeQuietly(workbook);
  222 + }
  223 +
  224 + } catch (FileNotFoundException e) {
  225 + throw new RuntimeException("模板文件不存在: templates/confirmationSlipTemplate.xlsx", e);
  226 + } catch (IOException e) {
  227 + throw new RuntimeException("无法读取模板文件: templates/confirmationSlipTemplate.xlsx", e);
  228 + }
  229 + } catch (Exception e) {
  230 + log.error("产品试样结果跟踪单打印: {}", e.getMessage(), e);
  231 + throw e;
  232 + }
  233 + }
  234 +
  235 + /**
  236 + * 设置HTTP响应头
  237 + */
  238 + private void setupResponse(HttpServletResponse response, String fileName) throws IOException {
  239 + String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
  240 +
  241 + response.setContentType("application/vnd.ms-excel");
  242 + response.setCharacterEncoding("UTF-8");
  243 + response.setHeader("Content-Disposition", "attachment;filename=" + encodedFileName);
  244 + response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
  245 + }
96 } 246 }
@@ -69,7 +69,7 @@ public class SampleResultTracking extends BaseEntity implements BaseDto { @@ -69,7 +69,7 @@ public class SampleResultTracking extends BaseEntity implements BaseDto {
69 * 订单编码 69 * 订单编码
70 */ 70 */
71 @TableField(exist = false) 71 @TableField(exist = false)
72 - private String orderNo; 72 + private String orderCode;
73 73
74 /** 74 /**
75 * 表面描述 75 * 表面描述
@@ -24,49 +24,42 @@ public class UpdateSampleResultTrackingVo implements BaseVo, Serializable { @@ -24,49 +24,42 @@ public class UpdateSampleResultTrackingVo implements BaseVo, Serializable {
24 * 表面描述 24 * 表面描述
25 */ 25 */
26 @ApiModelProperty("表面描述") 26 @ApiModelProperty("表面描述")
27 - @Length(message = "表面描述最多允许200个字符!")  
28 private String surface; 27 private String surface;
29 28
30 /** 29 /**
31 * 性能描述 30 * 性能描述
32 */ 31 */
33 @ApiModelProperty("性能描述") 32 @ApiModelProperty("性能描述")
34 - @Length(message = "性能描述最多允许200个字符!")  
35 private String performance; 33 private String performance;
36 34
37 /** 35 /**
38 * 公差描述 36 * 公差描述
39 */ 37 */
40 @ApiModelProperty("公差描述") 38 @ApiModelProperty("公差描述")
41 - @Length(message = "公差描述最多允许200个字符!")  
42 private String tolerance; 39 private String tolerance;
43 40
44 /** 41 /**
45 * 带型描述 42 * 带型描述
46 */ 43 */
47 @ApiModelProperty("带型描述") 44 @ApiModelProperty("带型描述")
48 - @Length(message = "带型描述最多允许200个字符!")  
49 private String bandingPattern; 45 private String bandingPattern;
50 46
51 /** 47 /**
52 * 包装描述 48 * 包装描述
53 */ 49 */
54 @ApiModelProperty("包装描述") 50 @ApiModelProperty("包装描述")
55 - @Length(message = "包装描述最多允许200个字符!")  
56 private String packaging; 51 private String packaging;
57 52
58 /** 53 /**
59 * 件重描述 54 * 件重描述
60 */ 55 */
61 @ApiModelProperty("件重描述") 56 @ApiModelProperty("件重描述")
62 - @Length(message = "件重描述最多允许200个字符!")  
63 private String weight; 57 private String weight;
64 58
65 /** 59 /**
66 * 其它描述 60 * 其它描述
67 */ 61 */
68 @ApiModelProperty("其它描述") 62 @ApiModelProperty("其它描述")
69 - @Length(message = "其它描述最多允许200个字符!")  
70 private String other; 63 private String other;
71 64
72 /** 65 /**