Commit 02e48b771ddd76300e4ff78f0a88e39b51ff4b55

Authored by 房远帅
1 parent 573c26a3

试样订单:跟踪单-导出

1 1 package com.lframework.xingyun.sc.controller.sample;
2 2
  3 +import cn.hutool.core.io.resource.ClassPathResource;
3 4 import com.lframework.xingyun.sc.bo.sample.tracking.GetSampleResultTrackingBo;
4 5 import com.lframework.xingyun.sc.bo.sample.tracking.QuerySampleResultTrackingBo;
5 6 import com.lframework.xingyun.sc.entity.SampleFeedbackTrackingDetail;
6 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 10 import com.lframework.xingyun.sc.vo.sample.tracking.QuerySampleFeedbackTrackingDetailVo;
8 11 import com.lframework.xingyun.sc.vo.sample.tracking.QuerySampleResultTrackingVo;
9 12 import com.lframework.xingyun.sc.service.sample.SampleResultTrackingService;
... ... @@ -12,21 +15,33 @@ import com.lframework.starter.web.core.utils.PageResultUtil;
12 15 import com.lframework.starter.web.core.components.resp.PageResult;
13 16 import com.lframework.starter.web.core.components.resp.InvokeResult;
14 17 import javax.annotation.Resource;
  18 +import javax.servlet.http.HttpServletResponse;
15 19 import javax.validation.constraints.NotBlank;
  20 +import com.lframework.xingyun.sc.vo.sample.tracking.UpdateSampleResultTrackingVo;
16 21 import io.swagger.annotations.ApiImplicitParam;
17 22 import com.lframework.starter.web.core.components.resp.InvokeResultBuilder;
18 23 import com.lframework.starter.common.exceptions.impl.DefaultClientException;
19 24 import io.swagger.annotations.ApiOperation;
20 25 import com.lframework.starter.common.utils.CollectionUtil;
21 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 34 import org.springframework.web.bind.annotation.DeleteMapping;
23 35 import com.lframework.starter.web.core.controller.DefaultBaseController;
24 36 import com.lframework.starter.web.core.annotations.security.HasPermission;
25 37 import org.springframework.validation.annotation.Validated;
26 38 import org.springframework.web.bind.annotation.*;
27   -
28 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 45 import java.util.stream.Collectors;
31 46
32 47 /**
... ... @@ -34,6 +49,7 @@ import java.util.stream.Collectors;
34 49 *
35 50 */
36 51 @Api(tags = "产品试样结果跟踪单")
  52 +@Slf4j
37 53 @Validated
38 54 @RestController
39 55 @RequestMapping("/sample/tracking")
... ... @@ -49,7 +65,7 @@ public class SampleResultTrackingController extends DefaultBaseController {
49 65 * 查询列表
50 66 */
51 67 @ApiOperation("查询列表")
52   - @HasPermission({"sample:tracking:query"})
  68 + @HasPermission({"sample-order:follow-up-form:query"})
53 69 @GetMapping("/query")
54 70 public InvokeResult<PageResult<QuerySampleResultTrackingBo>> query(@Valid QuerySampleResultTrackingVo vo) {
55 71 PageResult<SampleResultTracking> pageResult = sampleResultTrackingService.query(getPageIndex(vo), getPageSize(vo), vo);
... ... @@ -66,7 +82,7 @@ public class SampleResultTrackingController extends DefaultBaseController {
66 82 */
67 83 @ApiOperation("根据ID查询")
68 84 @ApiImplicitParam(value = "id", name = "id", paramType = "query", required = true)
69   - @HasPermission({"sample:tracking:query"})
  85 + @HasPermission({"sample-order:follow-up-form:query"})
70 86 @GetMapping
71 87 public InvokeResult<GetSampleResultTrackingBo> get(@NotBlank(message = "id不能为空!") String id) {
72 88 SampleResultTracking data = sampleResultTrackingService.findById(id);
... ... @@ -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 115 * 根据ID删除
87 116 */
88 117 @ApiOperation("根据ID删除")
89 118 @ApiImplicitParam(value = "id", name = "id", paramType = "query", required = true)
90   - @HasPermission({"sample:tracking:delete"})
  119 + @HasPermission({"sample-order:follow-up-form:delete"})
91 120 @DeleteMapping
92 121 public InvokeResult<Void> deleteById(@NotBlank(message = "id不能为空!") String id) {
93 122 sampleResultTrackingService.deleteById(id);
94 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 69 * 订单编码
70 70 */
71 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 24 * 表面描述
25 25 */
26 26 @ApiModelProperty("表面描述")
27   - @Length(message = "表面描述最多允许200个字符!")
28 27 private String surface;
29 28
30 29 /**
31 30 * 性能描述
32 31 */
33 32 @ApiModelProperty("性能描述")
34   - @Length(message = "性能描述最多允许200个字符!")
35 33 private String performance;
36 34
37 35 /**
38 36 * 公差描述
39 37 */
40 38 @ApiModelProperty("公差描述")
41   - @Length(message = "公差描述最多允许200个字符!")
42 39 private String tolerance;
43 40
44 41 /**
45 42 * 带型描述
46 43 */
47 44 @ApiModelProperty("带型描述")
48   - @Length(message = "带型描述最多允许200个字符!")
49 45 private String bandingPattern;
50 46
51 47 /**
52 48 * 包装描述
53 49 */
54 50 @ApiModelProperty("包装描述")
55   - @Length(message = "包装描述最多允许200个字符!")
56 51 private String packaging;
57 52
58 53 /**
59 54 * 件重描述
60 55 */
61 56 @ApiModelProperty("件重描述")
62   - @Length(message = "件重描述最多允许200个字符!")
63 57 private String weight;
64 58
65 59 /**
66 60 * 其它描述
67 61 */
68 62 @ApiModelProperty("其它描述")
69   - @Length(message = "其它描述最多允许200个字符!")
70 63 private String other;
71 64
72 65 /**
... ...