Commit 6d28c6f25bc1a1fe16f7ea58d329925dfa34d6c8

Authored by chenhang4442024
1 parent 8015840e

fix:1.邮件发送时图片加载不出的情况

2.首页订单趋势图的订单完成
feat:新增问题列表。
Showing 29 changed files with 1266 additions and 60 deletions
... ... @@ -47,6 +47,7 @@
47 47 <jjwt.version>0.10.6</jjwt.version>
48 48 <easyexcel.version>2.2.3</easyexcel.version>
49 49 <x-easypdf-pdfbox.version>2.11.10</x-easypdf-pdfbox.version>
  50 + <html-sanitizer-version>20220608.1</html-sanitizer-version>
50 51 </properties>
51 52  
52 53 <dependencies>
... ... @@ -317,6 +318,16 @@
317 318 <groupId>org.springframework.boot</groupId>
318 319 <artifactId>spring-boot-starter-freemarker</artifactId>
319 320 </dependency>
  321 +
  322 + <!--过滤HTML危险标签-->
  323 + <dependency>
  324 + <groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
  325 + <artifactId>owasp-java-html-sanitizer</artifactId>
  326 + <version>${html-sanitizer-version}</version>
  327 + </dependency>
  328 +
  329 +
  330 +
320 331 </dependencies>
321 332 <build>
322 333 <finalName>order-erp.service-1.0-SNAPSHOT</finalName>
... ...
src/main/java/com/order/erp/common/utils/EmailSendUtils.java
... ... @@ -20,6 +20,7 @@ import com.order.erp.service.admin.AdminUserRoleService;
20 20 import com.order.erp.service.admin.AdminUserService;
21 21 import freemarker.template.Template;
22 22 import freemarker.template.TemplateException;
  23 +import org.joda.time.DateTime;
23 24 import org.springframework.beans.factory.annotation.Value;
24 25 import org.springframework.mail.javamail.JavaMailSender;
25 26 import org.springframework.mail.javamail.MimeMessageHelper;
... ... @@ -51,6 +52,8 @@ public class EmailSendUtils {
51 52 private AdminUserService adminUserService;
52 53 @Resource
53 54 private AdminUserRoleService adminUserRoleService;
  55 + @Resource
  56 + private OssPicUrl ossPicUrl;
54 57  
55 58 /**
56 59 * @Description: 发送邮件 发送尾期验货报告,中期验货报告,邮件提醒事件。
... ... @@ -60,11 +63,25 @@ public class EmailSendUtils {
60 63 * @throws MessagingException
61 64 * @throws IOException
62 65 */
63   -
  66 + @Async
64 67 public void sendEmail(EmailTemplateEnum emailTemplateEnum, List<String> receiveemailList, OrderEventJobVO orderEventJobVO) {
65 68 if(CollectionUtils.isEmpty(receiveemailList) && emailTemplateEnum ==null && ObjectUtils.isNull(orderEventJobVO)){
66 69 throw new BusinessException(ServerResultCode.PARAM_ERROR);
67 70 }
  71 + //由于这里是异步,所以在这里进行图片oss的获取,这样不会影响主要逻辑。
  72 + String smallPicUrl = orderEventJobVO.getBaseInfo().getSmallPicUrl();
  73 + //防止里面已经被惊醒了oss加密处理,不能在嵌套一层,所以需要解开。
  74 + if(smallPicUrl.contains("Expires") && smallPicUrl.contains("OSSAccessKeyId")){
  75 + //如果里面有?并且里面有%3F就代表被多次oss嵌套了,就只需要获取%3F前面的内容。
  76 + String[] parts = smallPicUrl.split("\\?");
  77 + smallPicUrl = parts[0];
  78 + }
  79 + //这里需要获取多个,防止发送邮件时有的oss加载不出来。采用轮序判定是否能够加载成功。
  80 + String url1=AliOssUtil.createUrl(SplitUrlGetBucketName.getBucket(smallPicUrl), SplitUrlGetBucketName.getFileName(smallPicUrl), new DateTime().plusYears(Constant.FIVE).toDate());
  81 + //correctOssPic是已经经过检查之后的oss资源,应该是能够访问的。
  82 + String correctOssPic = ossPicUrl.getCorrectOssPic(url1, smallPicUrl);
  83 + orderEventJobVO.getBaseInfo().setSmallPicUrl(correctOssPic);
  84 + //重新设置到orderEventJobVO中。
68 85 MimeMessage mimeMessage = javaMailSender.createMimeMessage();
69 86 MimeMessageHelper helper= null;
70 87 Map<String, Object> map = new HashMap<>();
... ... @@ -114,6 +131,20 @@ public class EmailSendUtils {
114 131 if(CollectionUtils.isEmpty(receiveemailList) && emailTemplateEnum ==null && ObjectUtils.isNull(orderEventJobVO)){
115 132 throw new BusinessException(ServerResultCode.PARAM_ERROR);
116 133 }
  134 + //由于这里是异步,所以在这里进行图片oss的获取,这样不会影响主要逻辑。
  135 + String smallPicUrl = orderEventJobVO.getBaseInfo().getSmallPicUrl();
  136 + //防止里面已经被惊醒了oss加密处理,不能在嵌套一层,所以需要解开。
  137 + if(smallPicUrl.contains("Expires") && smallPicUrl.contains("OSSAccessKeyId")){
  138 + //如果里面有?并且里面有%3F就代表被多次oss嵌套了,就只需要获取%3F前面的内容。
  139 + String[] parts = smallPicUrl.split("\\?");
  140 + smallPicUrl = parts[0];
  141 + }
  142 + //这里需要获取多个,防止发送邮件时有的oss加载不出来。采用轮序判定是否能够加载成功。
  143 + String url1=AliOssUtil.createUrl(SplitUrlGetBucketName.getBucket(smallPicUrl), SplitUrlGetBucketName.getFileName(smallPicUrl), new DateTime().plusYears(Constant.FIVE).toDate());
  144 + //correctOssPic是已经经过检查之后的oss资源,应该是能够访问的。
  145 + String correctOssPic = ossPicUrl.getCorrectOssPic(url1, smallPicUrl);
  146 + //重新设置到orderEventJobVO中。
  147 + orderEventJobVO.getBaseInfo().setSmallPicUrl(correctOssPic);
117 148 MimeMessage mimeMessage = javaMailSender.createMimeMessage();
118 149 MimeMessageHelper helper= null;
119 150 Map<String, Object> map = new HashMap<>();
... ... @@ -251,6 +282,20 @@ public class EmailSendUtils {
251 282 if(CollectionUtils.isEmpty(receiveemailList) && emailTemplateEnum ==null && ObjectUtils.isNull(orderEventJobVO)){
252 283 throw new BusinessException(ServerResultCode.PARAM_ERROR);
253 284 }
  285 + //由于这里是异步,所以在这里进行图片oss的获取,这样不会影响主要逻辑。
  286 + String smallPicUrl = orderEventJobVO.getBaseInfo().getSmallPicUrl();
  287 + //防止里面已经被惊醒了oss加密处理,不能在嵌套一层,所以需要解开。
  288 + if(smallPicUrl.contains("Expires") && smallPicUrl.contains("OSSAccessKeyId")){
  289 + //如果里面有?并且里面有%3F就代表被多次oss嵌套了,就只需要获取%3F前面的内容。
  290 + String[] parts = smallPicUrl.split("\\?");
  291 + smallPicUrl = parts[0];
  292 + }
  293 + //这里需要获取多个,防止发送邮件时有的oss加载不出来。采用轮序判定是否能够加载成功。
  294 + String url1=AliOssUtil.createUrl(SplitUrlGetBucketName.getBucket(smallPicUrl), SplitUrlGetBucketName.getFileName(smallPicUrl), new DateTime().plusYears(Constant.FIVE).toDate());
  295 + //correctOssPic是已经经过检查之后的oss资源,应该是能够访问的。
  296 + String correctOssPic = ossPicUrl.getCorrectOssPic(url1, smallPicUrl);
  297 + //重新设置到orderEventJobVO中。
  298 + orderEventJobVO.getBaseInfo().setSmallPicUrl(correctOssPic);
254 299 MimeMessage mimeMessage = javaMailSender.createMimeMessage();
255 300 MimeMessageHelper helper= null;
256 301 Map<String, Object> map = new HashMap<>();
... ...
src/main/java/com/order/erp/common/utils/HtmlSanitizerUtil.java 0 → 100644
  1 +package com.order.erp.common.utils;
  2 +
  3 +import org.owasp.html.PolicyFactory;
  4 +import org.owasp.html.HtmlPolicyBuilder;
  5 +import org.owasp.html.AttributePolicy;
  6 +
  7 +import java.util.regex.Pattern;
  8 +
  9 +public class HtmlSanitizerUtil {
  10 + // 允许的 CSS 属性:color, background-color, font-size
  11 + private static final Pattern SAFE_STYLE_PATTERN = Pattern.compile(
  12 + "\\s*(color|background-color|font-size)\\s*:\\s*[^;]+\\s*", Pattern.CASE_INSENSITIVE);
  13 +
  14 + private static final AttributePolicy STYLE_POLICY = (elementName, attributeName, value) -> {
  15 + // 解析 style 内容,保留 color、background-color、font-size
  16 + String[] styles = value.split(";");
  17 + StringBuilder safeStyles = new StringBuilder();
  18 + for (String style : styles) {
  19 + style = style.trim();
  20 + if (SAFE_STYLE_PATTERN.matcher(style).matches()) {
  21 + if (safeStyles.length() > 0) {
  22 + safeStyles.append("; ");
  23 + }
  24 + safeStyles.append(style);
  25 + }
  26 + }
  27 + return safeStyles.length() > 0 ? safeStyles.toString() : null;
  28 + };
  29 +
  30 + private static final PolicyFactory POLICY = new HtmlPolicyBuilder()
  31 + // 允许的标签
  32 + .allowElements("p", "b", "i", "u", "strong", "em", "s", "mark",
  33 + "ol", "ul", "li", "blockquote", "code", "pre",
  34 + "br", "hr", "a", "span", "div")
  35 +
  36 + // 允许 <a> 标签的安全属性
  37 + .allowAttributes("href", "target", "title").onElements("a")
  38 + .allowStandardUrlProtocols() // 仅允许 http:// 和 https://
  39 +
  40 + // 允许 <span> 和 <div> 使用 style,并进行安全性检查
  41 + .allowAttributes("style").matching(STYLE_POLICY).onElements("span", "div")
  42 + .toFactory();
  43 +
  44 + /**
  45 + * 过滤 HTML,确保安全
  46 + * @param html 用户输入的 HTML 字符串
  47 + * @return 过滤后的 HTML
  48 + */
  49 + public static String sanitizeHtml(String html) {
  50 + return POLICY.sanitize(html);
  51 + }
  52 +}
... ...
src/main/java/com/order/erp/common/utils/OssPicUrl.java 0 → 100644
  1 +package com.order.erp.common.utils;
  2 +
  3 +import com.order.erp.common.constant.Constant;
  4 +import org.joda.time.DateTime;
  5 +import org.springframework.stereotype.Component;
  6 +
  7 +import java.net.HttpURLConnection;
  8 +import java.net.URL;
  9 +//用于获取的oss失败重新尝试生成,最多只能尝试两次。
  10 +@Component
  11 +public class OssPicUrl {
  12 +
  13 + /**
  14 + * @param ossUrl 这个是第一次获取oss的实时链接
  15 + * @param pic 这个是图片资源名,用于当第一次获取oss的实时链接失去作用时,重新生成。
  16 + * @return 返回正确的oss图片链接
  17 + */
  18 + public String getCorrectOssPic(String ossUrl,String pic){
  19 + if (isImageAvailable(ossUrl)) {
  20 + return ossUrl; // 原 URL 可用,直接返回
  21 + }
  22 + // 重新生成一个新的 OSS 直链
  23 + String url = AliOssUtil.createUrl(
  24 + SplitUrlGetBucketName.getBucket(pic),
  25 + SplitUrlGetBucketName.getFileName(pic),
  26 + new DateTime().plusYears(Constant.FOUR).toDate() // 重新生成新的 five 年有效 URL
  27 + );
  28 + if(isImageAvailable(url)){
  29 + return url;
  30 + }
  31 + String url1 = AliOssUtil.createUrl(
  32 + SplitUrlGetBucketName.getBucket(pic),
  33 + SplitUrlGetBucketName.getFileName(pic),
  34 + new DateTime().plusYears(Constant.THREE).toDate());
  35 + return url1; // 重新生成新的 five 年有效 URL
  36 +
  37 + }
  38 +
  39 + public static boolean isImageAvailable(String imageUrl) {
  40 + try {
  41 + URL url = new URL(imageUrl);
  42 + HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  43 + connection.setRequestMethod("GET"); // 仅请求头,减少流量消耗
  44 + connection.setConnectTimeout(8000); // 8秒超时
  45 + connection.setReadTimeout(8000);
  46 + connection.setRequestProperty("User-Agent", "Mozilla/5.0");
  47 + connection.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
  48 + int responseCode = connection.getResponseCode();
  49 + connection.disconnect();
  50 + return (responseCode >= 200 && responseCode < 400); // 2xx 或 3xx 说明可访问
  51 + } catch (Exception e) {
  52 + System.out.println("响应码错误:错误的响应码!");
  53 + return false; // 出现异常,说明图片不可访问
  54 + }
  55 + }
  56 +}
... ...
src/main/java/com/order/erp/controller/InvoiceBillOrderController.java
... ... @@ -205,7 +205,7 @@ public class InvoiceBillOrderController {
205 205 return invoiceBillOrderService.deleteDeductUrlById(deleteVo);
206 206 }
207 207  
208   - /** 删除
  208 + /** 最终状态
209 209 *最后一步,确认是否已经完成最终收款,即使审核通过之后,invoice的状态从未收款转化为待收款,,这里的作用是在待收款状态的基础上,最后手动确认是否完成收款。人工校验,状态为已收款。
210 210 * @param invoiceBillDeductInfoVO id
211 211 * @return
... ...
src/main/java/com/order/erp/controller/LocalStorageController.java
... ... @@ -42,6 +42,7 @@ public class LocalStorageController {
42 42 @PostMapping(value = "/upload_file_oss")
43 43 @AnonymousAccess
44 44 public ServerResult uploadFile2oss(@RequestParam String name, @RequestParam("file") MultipartFile file) {
  45 + System.out.println("name"+name);
45 46 return localStorageService.uploadFileByAliOss(name, file);
46 47 }
47 48  
... ...
src/main/java/com/order/erp/controller/QuestController.java 0 → 100644
  1 +package com.order.erp.controller;
  2 +
  3 +import com.order.erp.common.constant.ServerResult;
  4 +import com.order.erp.domain.vo.order.RichTextContentVO;
  5 +import com.order.erp.domain.vo.order.RichTextListQueryPageVO;
  6 +import com.order.erp.service.order.RichTextContentService;
  7 +import org.springframework.web.bind.annotation.PostMapping;
  8 +import org.springframework.web.bind.annotation.RequestBody;
  9 +import org.springframework.web.bind.annotation.RequestMapping;
  10 +import org.springframework.web.bind.annotation.RestController;
  11 +
  12 +import javax.annotation.Resource;
  13 +
  14 +/**
  15 +* 问题列表Controller
  16 + * */
  17 +@RestController
  18 +@RequestMapping("/order/erp/quest/")
  19 +public class QuestController {
  20 + @Resource
  21 + private RichTextContentService richTextContentService;
  22 + @PostMapping("/list_by_page")
  23 + public ServerResult list_by_page(@RequestBody RichTextListQueryPageVO richTextListQueryPageVO){
  24 + return richTextContentService.listByPage(richTextListQueryPageVO);
  25 + }
  26 +
  27 + @PostMapping("/delete_by_id")
  28 + public ServerResult delete_by_id(@RequestBody RichTextContentVO richTextContentVO){
  29 + return richTextContentService.deleteById(richTextContentVO);
  30 + }
  31 +
  32 + @PostMapping("/edit")
  33 + public ServerResult edit(@RequestBody RichTextContentVO richTextContentVO){
  34 + return richTextContentService.edit(richTextContentVO);
  35 + }
  36 +
  37 + @PostMapping("/add")
  38 + public ServerResult add(@RequestBody RichTextContentVO richTextContentVO){
  39 + return richTextContentService.add(richTextContentVO);
  40 + }
  41 + @PostMapping("/setStatus")
  42 + public ServerResult setStatus(@RequestBody RichTextContentVO richTextContentVO){
  43 + return richTextContentService.setStatus(richTextContentVO);
  44 + }
  45 + /**
  46 + *查看已通过的版本。
  47 + **/
  48 + @PostMapping("/realseList")
  49 + public ServerResult getRealseList(@RequestBody RichTextContentVO richTextContentVO){
  50 + return richTextContentService.getRealseList(richTextContentVO);
  51 + }
  52 + /**
  53 + * 获取所有的问题列表的id与title与扣款金额。
  54 + * */
  55 + @PostMapping("/get_all")
  56 + public ServerResult getAll(@RequestBody RichTextContentVO richTextContentVO){
  57 + return richTextContentService.getAll(richTextContentVO);
  58 + }
  59 + /**
  60 + * 模糊查询获取title以及deduct_amount。
  61 + * */
  62 + @PostMapping("/queryTitle")
  63 + public ServerResult queryTitle(@RequestBody RichTextContentVO richTextContentVO){
  64 + return richTextContentService.queryTitle(richTextContentVO);
  65 + }
  66 + /**
  67 + * 根据id去获取对应给的单个问题列表。
  68 + * */
  69 + @PostMapping("/queryRichText_by_id")
  70 + public ServerResult queryRichTextById(@RequestBody RichTextContentVO richTextContentVO){
  71 + return richTextContentService.queryRichTextById(richTextContentVO);
  72 + }
  73 +
  74 + /**
  75 + * 统计财务专用的扣款金额。
  76 + * */
  77 + @PostMapping("/getSumDeductAmount_by_ids")
  78 + public ServerResult getSumDeductAmount(@RequestBody RichTextContentVO richTextContentVO){
  79 + return richTextContentService.getSumDeductAmount(richTextContentVO);
  80 + }
  81 +}
... ...
src/main/java/com/order/erp/domain/dto/order/InvoiceBillOrderDO.java
... ... @@ -74,7 +74,7 @@ public class InvoiceBillOrderDO extends BaseDO implements Serializable {
74 74 */
75 75 private BigDecimal otherAmount;
76 76 /**
77   - * 状态 -1:未创建、0:未收款,10:待收款 20:已收款
  77 + * 状态 -1:未创建、0:未收款,10:待收款 40:已收款
78 78 */
79 79 private Integer status;
80 80 //需要在表中添加字段。
... ... @@ -114,4 +114,8 @@ public class InvoiceBillOrderDO extends BaseDO implements Serializable {
114 114 * 扣款单状态 状态 0:待审批,10:已通过 20:已驳回
115 115 * */
116 116 private Integer invoiceDeductUrlStatus;
  117 + /**
  118 + * 关联文章id
  119 + * */
  120 + private Long richTextId;
117 121 }
... ...
src/main/java/com/order/erp/domain/dto/order/ProducePaymentCheckBillOrderDO.java
... ... @@ -76,7 +76,7 @@ public class ProducePaymentCheckBillOrderDO extends BaseDO implements Serializab
76 76 */
77 77 private BigDecimal actualPayedAmount3;
78 78 /**
79   - * 总经理审核状态 0:待审核、1:审核通过,2:审核驳回
  79 + * 状态 -1:未创建、0:未收款,10:待收款, 40:已收款
80 80 */
81 81 private Integer status;
82 82 //需要在表中添加三个字段。
... ... @@ -121,6 +121,8 @@ public class ProducePaymentCheckBillOrderDO extends BaseDO implements Serializab
121 121 * 扣款单状态 0:待审核 10:已通过 20:已驳回
122 122 * */
123 123 private Integer checkDeductUrlStatus;
124   -
125   -
  124 + /**
  125 + * 关联文章id
  126 + * */
  127 + private Long richTextId;
126 128 }
... ...
src/main/java/com/order/erp/domain/dto/order/RichTextContentDO.java 0 → 100644
  1 +package com.order.erp.domain.dto.order;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.TableName;
  4 +import com.order.erp.domain.dto.BaseDO;
  5 +import lombok.*;
  6 +import lombok.experimental.SuperBuilder;
  7 +
  8 +import java.io.Serializable;
  9 +import java.math.BigDecimal;
  10 +import java.util.List;
  11 +
  12 +@TableName("rich_text_content")
  13 +@Data
  14 +@AllArgsConstructor
  15 +@ToString
  16 +@NoArgsConstructor
  17 +@EqualsAndHashCode(callSuper = false)
  18 +@SuperBuilder
  19 +public class RichTextContentDO extends BaseDO implements Serializable {
  20 + private Long id ;
  21 + /**
  22 + * 标题
  23 + * */
  24 + private String title;
  25 + /**
  26 + * 文本内容
  27 + * */
  28 + private String contentText;
  29 + /**
  30 + * 文本中图片资源
  31 + * */
  32 + private String contentImages;
  33 + /**
  34 + * 文件中附件内容
  35 + * */
  36 + private String files;
  37 + /**
  38 + * 旧版本id,用于关联这个内容的上一个版本
  39 + * */
  40 + private String oldId;
  41 + /**
  42 + * 状态 0:待审核,10:已通过,20:已驳回
  43 + * */
  44 + private Integer status;
  45 + /**
  46 + * 文章类型
  47 + * */
  48 + private String questType;
  49 + /**
  50 + * 扣款金额
  51 + * */
  52 + private BigDecimal deductAmount;
  53 + /**
  54 + * 引用该文章的invoice的id
  55 + * */
  56 + private String invoiceId;
  57 + /**
  58 + * 引用改文章的check的id
  59 + * */
  60 + private String checkId;
  61 + /**
  62 + * 货币符号 美元/人民币
  63 + * */
  64 + private String isRmb;
  65 + /**
  66 + * 是否作为模版问题 0 正常问题 1 模版经验问题
  67 + * */
  68 + private Boolean isTemplate;
  69 + /**
  70 + * 是否为跟单必选编辑板块,0:不属于跟单必选编辑板块 1:属于跟单必选编辑板块 如果为跟单必选编辑板块则在选择扣款原因时是不会进行展示的,主要目的是让跟单人员选择扣款原因时无法选择财务中的管理费,税费等等。
  71 + * */
  72 + private Boolean isTrackerBlock;
  73 +
  74 +}
... ...
src/main/java/com/order/erp/domain/vo/order/FinanceOrderResultVO.java
... ... @@ -118,6 +118,11 @@ public class FinanceOrderResultVO extends OrderBaseInfoVO {
118 118 * 备注信息
119 119 * */
120 120 private String invoiceNotes;
  121 + /**
  122 + * 关联文章id
  123 + * */
  124 + private Long invoiceRichTextId;
  125 +
121 126  
122 127 //应付款信息
123 128 // private ProducePaymentCheckBillOrderDO producePaymentCheckBillOrderDO;
... ... @@ -186,6 +191,10 @@ public class FinanceOrderResultVO extends OrderBaseInfoVO {
186 191 * 备注。
187 192 * */
188 193 private String checkNotes;
  194 + /**
  195 + * 关联文章id。
  196 + * */
  197 + private Long checkRichTextId;
189 198  
190 199  
191 200 //利润信息
... ...
src/main/java/com/order/erp/domain/vo/order/InvoiceBillDeductInfoVO.java
... ... @@ -36,5 +36,9 @@ public class InvoiceBillDeductInfoVO implements Serializable {
36 36 * 扣款单url地址
37 37 */
38 38 private String deductUrl;
  39 + /**
  40 + * 扣款原因关联问题列表id
  41 + */
  42 + private Long questId;
39 43  
40 44 }
... ...
src/main/java/com/order/erp/domain/vo/order/ProducePaymentCheckBillDeductInfoVO.java
... ... @@ -40,6 +40,9 @@ public class ProducePaymentCheckBillDeductInfoVO implements Serializable {
40 40 * 扣款单url地址
41 41 */
42 42 private String deductUrl;
43   -
  43 + /**
  44 + * 关联扣款原因列表id
  45 + */
  46 + private Long questId;
44 47  
45 48 }
... ...
src/main/java/com/order/erp/domain/vo/order/RichTextAllTitleResultVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import lombok.*;
  4 +import lombok.experimental.SuperBuilder;
  5 +
  6 +import java.math.BigDecimal;
  7 +
  8 +@Data
  9 +@AllArgsConstructor
  10 +@ToString
  11 +@NoArgsConstructor
  12 +@EqualsAndHashCode(callSuper = false)
  13 +@SuperBuilder
  14 +public class RichTextAllTitleResultVO {
  15 + private Long id;
  16 + /**
  17 + * 标题
  18 + * */
  19 + private String title;
  20 + /**
  21 + * 扣款金额
  22 + * */
  23 + private BigDecimal deductAmount;
  24 + /**
  25 + * 是否为模板
  26 + * */
  27 + private Boolean isTemplate;
  28 +}
... ...
src/main/java/com/order/erp/domain/vo/order/RichTextContentResultVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import lombok.*;
  4 +import lombok.experimental.SuperBuilder;
  5 +
  6 +import java.math.BigDecimal;
  7 +import java.util.List;
  8 +
  9 +@Data
  10 +@AllArgsConstructor
  11 +@ToString
  12 +@NoArgsConstructor
  13 +@EqualsAndHashCode(callSuper = false)
  14 +@SuperBuilder
  15 +public class RichTextContentResultVO {
  16 + private Long id;
  17 + /**
  18 + * 标题。
  19 + * */
  20 + private String title;
  21 + /**
  22 + * 文本内容。
  23 + * */
  24 + private String contentText;
  25 + /**
  26 + * 文本中图片资源。
  27 + * */
  28 + private List<String> contentImages;
  29 + /**
  30 + * 文件中附件内容。
  31 + * */
  32 + private List<String> files;
  33 + /**
  34 + * 最后修改人。
  35 + * */
  36 + private String modifyBy;
  37 + /**
  38 + * 这篇文章的上一版id。
  39 + * */
  40 + private String oldId;
  41 + /**
  42 + * 状态 0:待审批 10:已通过 20:驳回。
  43 + * */
  44 + private Integer status;
  45 + /**
  46 + * 文章类型。
  47 + * */
  48 + private String questType;
  49 + /**
  50 + * 扣款金额。
  51 + * */
  52 + private BigDecimal deductAmount;
  53 + /**
  54 + * 货币类型。
  55 + * */
  56 + private String isRmb;
  57 + /**
  58 + * 是否作为模板
  59 + * */
  60 + private Boolean isTemplate;
  61 + /**
  62 + * 是否作为跟单必选编辑板块
  63 + * */
  64 + private Boolean isTrackerBlock;
  65 +
  66 +}
... ...
src/main/java/com/order/erp/domain/vo/order/RichTextContentVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import lombok.*;
  4 +import lombok.experimental.SuperBuilder;
  5 +
  6 +import java.math.BigDecimal;
  7 +import java.util.List;
  8 +
  9 +@Data
  10 +@AllArgsConstructor
  11 +@ToString
  12 +@NoArgsConstructor
  13 +@EqualsAndHashCode(callSuper = false)
  14 +@SuperBuilder
  15 +public class RichTextContentVO {
  16 + /**
  17 + * id
  18 + * */
  19 + private Long id;
  20 + /**
  21 + * id
  22 + * */
  23 + private List<Long> ids;
  24 +
  25 + /**
  26 + * 标题
  27 + * */
  28 + private String title;
  29 + /**
  30 + * 文本内容
  31 + * */
  32 + private String contentText;
  33 + /**
  34 + * 文本中图片资源
  35 + * */
  36 + private String contentImages;
  37 + /**
  38 + * 文件中附件内容
  39 + * */
  40 + private String files;
  41 + /**
  42 + * 状态 0:待审核,10:已通过,20:已驳回
  43 + * */
  44 + private Integer status;
  45 + /**
  46 + * 文章类型
  47 + * */
  48 + private String questType;
  49 + /**
  50 + * 扣款金额
  51 + * */
  52 + private BigDecimal deductAmount;
  53 + /**
  54 + * 货币符号 美元/人民币
  55 + * */
  56 + private String isRmb;
  57 + /**
  58 + * 是否作为模版问题
  59 + * */
  60 + private Boolean isTemplate;
  61 + /**
  62 + * 是否为跟单必选编辑板块,如果为跟单必选编辑板块则在选择扣款原因时是不会进行展示的,主要目的是让跟单人员选择扣款原因时无法选择财务中的管理费,税费等等。
  63 + * */
  64 + private Boolean isTrackerBlock;
  65 +}
... ...
src/main/java/com/order/erp/domain/vo/order/RichTextListQueryPageVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.order;
  2 +
  3 +import com.order.erp.domain.vo.BasePageVO;
  4 +import lombok.*;
  5 +import lombok.experimental.SuperBuilder;
  6 +
  7 +@Data
  8 +@AllArgsConstructor
  9 +@ToString
  10 +@NoArgsConstructor
  11 +@EqualsAndHashCode(callSuper = false)
  12 +@SuperBuilder
  13 +public class RichTextListQueryPageVO extends BasePageVO {
  14 + /**
  15 + * 标题
  16 + * */
  17 + private String title;
  18 + /**
  19 + * 关键字
  20 + * */
  21 + private String contentText;
  22 + /**
  23 + * 创建人
  24 + * */
  25 + private String createBy;
  26 + /**
  27 + * 状态
  28 + * */
  29 + private Integer status;
  30 + /**
  31 + * 文章类型
  32 + * */
  33 + private String questType;
  34 + /**
  35 + * 开始时间
  36 + * */
  37 + private String createStartTime;
  38 + /**
  39 + * 结束时间
  40 + * */
  41 + private String createEndTime;
  42 +}
... ...
src/main/java/com/order/erp/job/OrderJob.java
... ... @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
5 5 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
6 6 import com.order.erp.common.constant.Constant;
7 7 import com.order.erp.common.utils.DateUtils;
  8 +import com.order.erp.common.utils.StringUtils;
8 9 import com.order.erp.common.utils.TransactionHelper;
9 10 import com.order.erp.domain.ApplyStatusEnum;
10 11 import com.order.erp.domain.OrderStatusEnum;
... ... @@ -60,7 +61,6 @@ public class OrderJob {
60 61 log.info("执行开始时间:{}", DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
61 62 LambdaQueryWrapper<OrderBaseInfoDO> queryWrapper = new LambdaQueryWrapper<OrderBaseInfoDO>()
62 63 .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
63   - //这里如果要改的话,就改成不是扫三个月的,而是全部扫一遍。
64 64 .ge(OrderBaseInfoDO::getCreateTime, DateUtils.format(DateTime.now().minusMonths(Constant.ONE).toDate(), DateUtils.DATE_TIME))
65 65 .le(OrderBaseInfoDO::getCreateTime, DateUtils.format(DateTime.now().toDate(), DateUtils.DATE_TIME))
66 66 .ne(OrderBaseInfoDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
... ... @@ -68,29 +68,36 @@ public class OrderJob {
68 68 List<OrderInfoResultVO> orderInfoResultVOS = orderBaseInfoService.wrapperOrderResultList(false, ordersDOS);
69 69 //遍历一下这个集合的数据,如果尾期尾期验货结果为PASS,pass 2ND,PASS 3ND,FAIL RELEASE就为订单完成。
70 70 Set<String> validResults = new HashSet<>(Arrays.asList("PASS", "PASS 2ND", "PASS 3RD", "FAIL RELEASE"));
  71 + //没有进行innerNo与customerCode联合排查。
71 72 List<OrderInfoResultVO> filteredOrders = orderInfoResultVOS.stream()
72 73 .filter(order -> order.getInspectionStageInfo() != null &&
73 74 validResults.contains(order.getInspectionStageInfo().getEndCheckResult()))
74 75 .collect(Collectors.toList());
75   - if (CollectionUtils.isNotEmpty(filteredOrders)) {
76   - Set<Long> orderIds = filteredOrders.stream().map(OrderInfoResultVO::getId).collect(Collectors.toSet());
77   -
78   - //不再使用上述的方式,
79   - if (CollectionUtils.isNotEmpty(orderIds)) {
  76 + //获取订单的innerNo和customerCode。
  77 + Set<String> uniqueCombination = filteredOrders.stream().map(order -> order.getProjectNo() + "-" + order.getInnerNo()).collect(Collectors.toSet());
  78 +
  79 + List<OrderInfoResultVO> finishStatusOrderBaseInfoResultVO = orderInfoResultVOS.stream().filter(order -> {
  80 + String combination = order.getProjectNo() + "-" + order.getInnerNo();
  81 + return uniqueCombination.contains(combination);
  82 + }).collect(Collectors.toList());
  83 + Set<Long> finishStatusOrderIds = finishStatusOrderBaseInfoResultVO.stream().map(order -> order.getId()).collect(Collectors.toSet());
  84 + if (CollectionUtils.isNotEmpty(finishStatusOrderIds)) {
  85 + //不再使用上述的方式,而是采用内部编号与项目编号进行排查。
  86 + if (CollectionUtils.isNotEmpty(finishStatusOrderIds)) {
80 87 LambdaUpdateWrapper<OrderBaseInfoDO> orderBaseUpdateWrapper = new LambdaUpdateWrapper<OrderBaseInfoDO>()
81   - .in(OrderBaseInfoDO::getId, orderIds).set(OrderBaseInfoDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
  88 + .in(OrderBaseInfoDO::getId, finishStatusOrderIds).set(OrderBaseInfoDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
82 89  
83 90 LambdaUpdateWrapper<OrderCompletionReportDO> reportUpdateWrapper = new LambdaUpdateWrapper<OrderCompletionReportDO>()
84   - .in(OrderCompletionReportDO::getOrderId, orderIds).set(OrderCompletionReportDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
  91 + .in(OrderCompletionReportDO::getOrderId, finishStatusOrderIds).set(OrderCompletionReportDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
85 92  
86 93 LambdaUpdateWrapper<OrderProfitAnalysisDO> profitUpdateWrapper = new LambdaUpdateWrapper<OrderProfitAnalysisDO>()
87   - .in(OrderProfitAnalysisDO::getOrderId, orderIds).set(OrderProfitAnalysisDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
  94 + .in(OrderProfitAnalysisDO::getOrderId, finishStatusOrderIds).set(OrderProfitAnalysisDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
88 95  
89 96 LambdaUpdateWrapper<OrderTrackStageDO> trackUpdateWrapper = new LambdaUpdateWrapper<OrderTrackStageDO>()
90   - .in(OrderTrackStageDO::getOrderId, orderIds).set(OrderTrackStageDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
  97 + .in(OrderTrackStageDO::getOrderId, finishStatusOrderIds).set(OrderTrackStageDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
91 98  
92 99 LambdaUpdateWrapper<OrderInspectionStageDO> inspectUpdateWrapper = new LambdaUpdateWrapper<OrderInspectionStageDO>()
93   - .in(OrderInspectionStageDO::getOrderId, orderIds).set(OrderInspectionStageDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
  100 + .in(OrderInspectionStageDO::getOrderId, finishStatusOrderIds).set(OrderInspectionStageDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
94 101  
95 102 transactionHelper.run(() -> {
96 103 orderBaseInfoService.update(orderBaseUpdateWrapper);
... ... @@ -263,4 +270,70 @@ public void orderStatusFinishCheck() {
263 270 orderBaseInfoService.updateBatchById(finishStatusOrderBaseinfoList);
264 271 }
265 272  
  273 + //查询一下所有的信息,对于质检信息中尾期验货为PASS,PASS 2ND,PASS 3RD,或者为FAIL RELEASE,那么它就设置为订单完成状态,设置为订单完成之后,再去查看已经为订单完成的订单,对于相同的innerNo和customerCode就也进行设置为质检信息。
  274 + //模仿上面的每十分钟扫描一次的方法,找到这些订单后,还需要对这些订单的跟单,质检等也设置为订单完成状态。
  275 + @Scheduled(cron = "0 0 4 16 4 ?", zone = "Asia/Shanghai")
  276 + public void checkChargeOrderCount1() {
  277 + List<OrderBaseInfoDO> orderBaseInfoDOS = orderBaseInfoService.list(new LambdaQueryWrapper<OrderBaseInfoDO>().eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN).ne(OrderBaseInfoDO::getOrderStatus,OrderStatusEnum.ORDER_FINISH.getStatus()));
  278 + //转化为map集合。
  279 + Map<Long, OrderBaseInfoDO> orderBaseInfoDOMap = orderBaseInfoDOS.stream().collect(Collectors.toMap(OrderBaseInfoDO::getId,OrderBaseInfoDO -> OrderBaseInfoDO,(existing,replacement) -> existing));
  280 + List<Long> orderIds = orderBaseInfoDOS.stream().map(orderBaseInfoDO -> orderBaseInfoDO.getId()).collect(Collectors.toList());
  281 +
  282 + List<OrderInspectionStageDO> inspectionStageDOList = inspectionStageService.list(new LambdaQueryWrapper<OrderInspectionStageDO>().eq(BaseDO::getEnableFlag,Constant.ENABLE_TEN).in(OrderInspectionStageDO::getOrderId,orderIds));
  283 + //转化为map集合。
  284 + Map<Long, OrderInspectionStageDO> inspectionStageDOMap = inspectionStageDOList.stream().collect(Collectors.toMap(OrderInspectionStageDO::getOrderId,OrderInspectionStageDO -> OrderInspectionStageDO,(existing,replacement) -> existing));
  285 + //获取所有尾期验货为PASS,PASS 2ND,PASS 3RD,或者为FAIL RELEASE的订单。返回的订单代表订单通过。
  286 + List<Long> finishOrderIdList = inspectionStageDOList.stream()
  287 + .filter(orderInspectionStageDO ->
  288 + Objects.nonNull(orderInspectionStageDO) &&
  289 + StringUtils.isNotBlank(orderInspectionStageDO.getEndCheckResult()) &&
  290 + (orderInspectionStageDO.getEndCheckResult().equals("PASS") ||
  291 + orderInspectionStageDO.getEndCheckResult().equals("PASS 2ND") ||
  292 + orderInspectionStageDO.getEndCheckResult().equals("PASS 3RD") ||
  293 + orderInspectionStageDO.getEndCheckResult().equals("FAIL RELEASE"))
  294 + )
  295 + .map(orderInspectionStageDO -> orderInspectionStageDO.getOrderId())
  296 + .filter(Objects::nonNull) // 确保 orderId 不为 null
  297 + .collect(Collectors.toList());
  298 +
  299 + Map<Long, OrderBaseInfoDO> finishOrderBaseInfoMap = orderBaseInfoDOMap.entrySet().stream()
  300 + .filter(entry -> finishOrderIdList.contains(entry.getKey()))
  301 + .collect(Collectors.toMap(
  302 + Map.Entry::getKey,
  303 + Map.Entry::getValue
  304 + ));
  305 + //取出map中的value。 这些都为订单完成的。
  306 + List<OrderBaseInfoDO> finishOrderBaseInfoList = finishOrderBaseInfoMap.values().stream().collect(Collectors.toList());
  307 + //获取相同的innerNo和CustomerCode。
  308 + Set<String> uniqueCombinations=finishOrderBaseInfoList.stream().map(order -> order.getProjectNo()+"-"+order.getInnerNo()).collect(Collectors.toSet());
  309 +
  310 + List<OrderBaseInfoDO> finishStatusOrderBaseinfoList = orderBaseInfoDOS.stream().filter(order -> {
  311 + String combination = order.getProjectNo() + "-" + order.getInnerNo();
  312 + return uniqueCombinations.contains(combination);
  313 + })
  314 + .collect(Collectors.toList());
  315 + finishStatusOrderBaseinfoList.forEach(orderBaseInfoDO -> orderBaseInfoDO.setOrderStatus(OrderStatusEnum.ORDER_FINISH.getStatus()));
  316 + List<Long> allFinishOrderIdList = finishStatusOrderBaseinfoList.stream().map(orderBaseInfoDO -> orderBaseInfoDO.getId()).collect(Collectors.toList());
  317 + //保存
  318 +
  319 + //对于质检和跟单也进行设置状态为订单完成。
  320 + Map<Long, OrderInspectionStageDO> allFinishInspectMap = inspectionStageDOMap.entrySet().stream()
  321 + .filter(entry -> allFinishOrderIdList.contains(entry.getKey()))
  322 + .collect(Collectors.toMap(
  323 + Map.Entry::getKey,
  324 + Map.Entry::getValue
  325 + ));
  326 + List<OrderInspectionStageDO> allInspectionStageDOList = allFinishInspectMap.values().stream().collect(Collectors.toList());
  327 + LambdaUpdateWrapper<OrderTrackStageDO> trackUpdateWrapper = new LambdaUpdateWrapper<OrderTrackStageDO>().in(OrderTrackStageDO::getOrderId, allFinishOrderIdList).set(OrderTrackStageDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
  328 + LambdaUpdateWrapper<OrderCompletionReportDO> reportUpdateWrapper = new LambdaUpdateWrapper<OrderCompletionReportDO>().in(OrderCompletionReportDO::getOrderId, allFinishOrderIdList).set(OrderCompletionReportDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
  329 + LambdaUpdateWrapper<OrderProfitAnalysisDO> profitUpdateWrapper = new LambdaUpdateWrapper<OrderProfitAnalysisDO>().in(OrderProfitAnalysisDO::getOrderId, allFinishOrderIdList).set(OrderProfitAnalysisDO::getOrderStatus, OrderStatusEnum.ORDER_FINISH.getStatus());
  330 +
  331 + transactionHelper.run(() ->{
  332 + trackStageService.update(trackUpdateWrapper);
  333 + reportService.update(reportUpdateWrapper);
  334 + profitAnalysisService.update(profitUpdateWrapper);
  335 + inspectionStageService.updateBatchById(allInspectionStageDOList);
  336 + orderBaseInfoService.updateBatchById(finishStatusOrderBaseinfoList);
  337 + });
  338 + }
266 339 }
... ...
src/main/java/com/order/erp/job/OrderOverTimeEventJob.java
... ... @@ -140,7 +140,7 @@ public class OrderOverTimeEventJob {
140 140 OrderBaseInfoVO orderBaseInfoFormat = getDateFormat(orderEventJob.getBaseInfo().getProductionDepartmentConsignTime(), orderEventJob.getBaseInfo().getOrderHodTime());
141 141 orderEventJob.getBaseInfo().setProductionDepartmentConsignTime(orderBaseInfoFormat.getProductionDepartmentConsignTime());
142 142 orderEventJob.getBaseInfo().setOrderHodTime(orderBaseInfoFormat.getOrderHodTime());
143   - orderEventJob.getBaseInfo().setSmallPicUrl(AliOssUtil.createUrl(SplitUrlGetBucketName.getBucket(orderEventJob.getBaseInfo().getSmallPicUrl()), SplitUrlGetBucketName.getFileName(orderEventJob.getBaseInfo().getSmallPicUrl()), new DateTime().plusYears(Constant.ENABLE_TEN).toDate()));
  143 +// orderEventJob.getBaseInfo().setSmallPicUrl(AliOssUtil.createUrl(SplitUrlGetBucketName.getBucket(orderEventJob.getBaseInfo().getSmallPicUrl()), SplitUrlGetBucketName.getFileName(orderEventJob.getBaseInfo().getSmallPicUrl()), new DateTime().plusYears(Constant.ENABLE_TEN).toDate()));
144 144 String productionDepartment = orderEventJob.getBaseInfo().getProductionDepartment();
145 145 //根据订单的生产科得到生产科用户信息。
146 146 AdminUserDO productionDepartmentUser = adminUserService.getOne(new LambdaQueryWrapper<AdminUserDO>()
... ... @@ -232,7 +232,7 @@ public class OrderOverTimeEventJob {
232 232 OrderBaseInfoVO orderBaseInfoFormat = getDateFormat(orderEventJob.getBaseInfo().getProductionDepartmentConsignTime(), orderEventJob.getBaseInfo().getOrderHodTime());
233 233 orderEventJob.getBaseInfo().setProductionDepartmentConsignTime(orderBaseInfoFormat.getProductionDepartmentConsignTime());
234 234 orderEventJob.getBaseInfo().setOrderHodTime(orderBaseInfoFormat.getOrderHodTime());
235   - orderEventJob.getBaseInfo().setSmallPicUrl(AliOssUtil.createUrl(SplitUrlGetBucketName.getBucket(orderEventJob.getBaseInfo().getSmallPicUrl()), SplitUrlGetBucketName.getFileName(orderEventJob.getBaseInfo().getSmallPicUrl()), new DateTime().plusYears(Constant.ENABLE_TEN).toDate()));
  235 +// orderEventJob.getBaseInfo().setSmallPicUrl(AliOssUtil.createUrl(SplitUrlGetBucketName.getBucket(orderEventJob.getBaseInfo().getSmallPicUrl()), SplitUrlGetBucketName.getFileName(orderEventJob.getBaseInfo().getSmallPicUrl()), new DateTime().plusYears(Constant.ENABLE_TEN).toDate()));
236 236 emailSendUtils.sendEmail(EmailTemplateEnum.byTemplate(eventEnum.getTemplateId()),
237 237 map.get(map.keySet().iterator().next()), orderEventJob);
238 238 redisUtils.set(EmailTemplateEnum.byTemplate(
... ...
src/main/java/com/order/erp/mapper/order/RichTextContentMapper.java 0 → 100644
  1 +package com.order.erp.mapper.order;
  2 +
  3 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  4 +import com.order.erp.domain.dto.order.RichTextContentDO;
  5 +import com.order.erp.domain.vo.order.RichTextAllTitleResultVO;
  6 +import com.order.erp.domain.vo.order.RichTextContentVO;
  7 +import org.apache.ibatis.annotations.Param;
  8 +
  9 +import java.util.List;
  10 +
  11 +public interface RichTextContentMapper extends BaseMapper<RichTextContentDO> {
  12 + List<RichTextAllTitleResultVO> queryTitle(@Param("richTextContentVO")RichTextContentVO richTextContentVO);
  13 +}
... ...
src/main/java/com/order/erp/service/impl/LocalStorageServiceImpl.java
... ... @@ -55,8 +55,14 @@ public class LocalStorageServiceImpl extends ServiceImpl&lt;LocalStorageMapper, Loc
55 55 @Override
56 56 public ServerResult uploadFileByAliOss(String name, MultipartFile file) {
57 57 FileUtil.checkSize(maxSize, file.getSize());
  58 + if (name.endsWith(",")) {
  59 + name = name.substring(0, name.length() - 1); // 去除最后一个字符
  60 + }
58 61 String fileName = AliOssUtil.getUniqueFileName(name);
  62 + System.out.println("文件原始名称"+name);
  63 + System.out.println("fileName"+fileName);
59 64 String tempFileName = "Thumbnails" + Constant.CROSS_BAR_CHARACTER + fileName;
  65 + System.out.println("tempFileName"+tempFileName);
60 66 FileRespVO fileRespVO = new FileRespVO();
61 67 try {
62 68 File tempFile = new File(path + "files" + File.separator + tempFileName);
... ...
src/main/java/com/order/erp/service/impl/SystemSettingServiceImpl.java
... ... @@ -123,6 +123,7 @@ public class SystemSettingServiceImpl extends ServiceImpl&lt;SystemSettingMapper, S
123 123 if (Objects.nonNull(systemSettingVO.getId())) {
124 124 systemSettingVO.setId(null);
125 125 }
  126 + //Constant.THREE和Constant.FOUR代表成本配置和提成配置。
126 127 if (systemSettingVO.getSettingType() == Constant.THREE || systemSettingVO.getSettingType() == Constant.FOUR) {
127 128 if (CollectionUtils.isEmpty(systemSettingVO.getCostSettingItemVOS())) {
128 129 throw new BusinessException("成本配置项不能为空");
... ...
src/main/java/com/order/erp/service/order/RichTextContentService.java 0 → 100644
  1 +package com.order.erp.service.order;
  2 +
  3 +import com.baomidou.mybatisplus.extension.service.IService;
  4 +import com.order.erp.common.constant.ServerResult;
  5 +import com.order.erp.domain.dto.order.RichTextContentDO;
  6 +import com.order.erp.domain.vo.order.RichTextContentResultVO;
  7 +import com.order.erp.domain.vo.order.RichTextContentVO;
  8 +import com.order.erp.domain.vo.order.RichTextListQueryPageVO;
  9 +
  10 +public interface RichTextContentService extends IService<RichTextContentDO> {
  11 + ServerResult listByPage(RichTextListQueryPageVO richTextListQueryPageVO);
  12 + ServerResult deleteById(RichTextContentVO richTextContentVO);
  13 + ServerResult edit(RichTextContentVO richTextContentVO);
  14 + ServerResult add(RichTextContentVO richTextContentVO);
  15 + ServerResult setStatus(RichTextContentVO richTextContentVO);
  16 + ServerResult getRealseList(RichTextContentVO richTextContentVO);
  17 + ServerResult getAll(RichTextContentVO richTextContentVO);
  18 + ServerResult queryTitle(RichTextContentVO richTextContentVO);
  19 + ServerResult queryRichTextById(RichTextContentVO richTextContentVO);
  20 + ServerResult getSumDeductAmount(RichTextContentVO richTextContentVO);
  21 +}
... ...
src/main/java/com/order/erp/service/order/impl/InvoiceBillOrderServiceImpl.java
... ... @@ -80,6 +80,8 @@ public class InvoiceBillOrderServiceImpl extends ServiceImpl&lt;InvoiceBillOrderMap
80 80 private EmailSendUtils emailSendUtils;
81 81 @Resource
82 82 private RedisUtils redisUtils;
  83 + @Resource
  84 + private RichTextContentService richTextContentService;
83 85  
84 86  
85 87 /**
... ... @@ -1160,6 +1162,20 @@ public class InvoiceBillOrderServiceImpl extends ServiceImpl&lt;InvoiceBillOrderMap
1160 1162 invoiceBillOrderDo.setDeductAmount((deductInfoVO.getDeductAmount()==null?BigDecimal.ZERO:deductInfoVO.getDeductAmount()).setScale(2, RoundingMode.HALF_UP));
1161 1163 //客户总金额减去发生扣款金额。
1162 1164 invoiceBillOrderDo.setActualReceivableAmount((invoiceBillOrderDo.getTotalCustomerAmount().subtract(deductInfoVO.getDeductAmount()==null?BigDecimal.ZERO:deductInfoVO.getDeductAmount())).setScale(2, RoundingMode.HALF_UP));
  1165 + if(Objects.nonNull(deductInfoVO.getQuestId())){
  1166 + invoiceBillOrderDo.setRichTextId(deductInfoVO.getQuestId());
  1167 + //还需要把引用该文章的invoice保存到对应的文章的invoice中,防止编辑或者删除文章之后,没有引用到新的文章上。
  1168 + RichTextContentDO richTextContentDO = richTextContentService.getById(deductInfoVO.getQuestId());
  1169 + String invoiceId = richTextContentDO.getInvoiceId();
  1170 + String newId = String.valueOf(deductInfoVO.getId());
  1171 + if(StringUtils.isNotBlank(invoiceId)){
  1172 + invoiceId=invoiceId+","+newId;
  1173 + }else{
  1174 + invoiceId=newId;
  1175 + }
  1176 + richTextContentDO.setInvoiceId(invoiceId);
  1177 + richTextContentService.updateById(richTextContentDO);
  1178 + }
1163 1179 if(StringUtils.isNotBlank(deductInfoVO.getDeductUrl())){
1164 1180 invoiceBillOrderDo.setInvoiceDeductUrlStatus(ApplyStatusEnum.WAIT_AUDIT.getStatus());
1165 1181 }
... ...
src/main/java/com/order/erp/service/order/impl/OrderBaseInfoServiceImpl.java
... ... @@ -262,7 +262,7 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
262 262 // 填充跟单信息
263 263 fillTrackStageInfo(resultVOList);
264 264  
265   - // 填充质检信息 在上述的利润分析中已经填充了,这里不需要填充。
  265 + // 填充质检信息 在上述的利润分析中已经填充了,这里不需要填充。把填充质检信息放到填充利润分析里面一起了。
266 266 // fillInspectionStageInfo(resultVOList);
267 267  
268 268 // 填充发票信息 对于填充发票信息和填充生产科对账单号,其实不需要在这里写了,而且这里只是填充了invoice号和check号,这里的代码是填充数据,达到一个进度条的效果,既然没有根据是否填充发票来填充进度条,这里就不需要写。
... ... @@ -2734,19 +2734,8 @@ end
2734 2734 //邮箱收集完毕。
2735 2735 OrderEventJobVO orderEventJobVO = new OrderEventJobVO();
2736 2736 orderEventJobVO.setInspectionStageInfo(updateVO.getInspectionStageInfo());
2737   - OrderBaseInfoVO orderBaseInfoVo = BeanUtil.copyProperties(orderBaseInfoDO, OrderBaseInfoVO.class,"smallPicUrl");
2738   - String smallPicUrl="";
2739   - if(com.order.erp.common.utils.StringUtils.isNotEmpty(orderBaseInfoDO.getSmallPicUrl())){
2740   - String smallPicUrlKey=Constant.OSS_SMALL_PIC_URL+orderBaseInfoDO.getSmallPicUrl();
2741   - smallPicUrl=(String)redisUtils.get(smallPicUrlKey);
2742   - if(StringUtils.isBlank(smallPicUrl)){
2743   - smallPicUrl= AliOssUtil.createUrl(SplitUrlGetBucketName.getBucket(orderBaseInfoDO.getSmallPicUrl()), SplitUrlGetBucketName.getFileName(orderBaseInfoDO.getSmallPicUrl()), new DateTime().plusHours(Constant.TWO).toDate());
2744   - redisUtils.set(smallPicUrlKey,smallPicUrl,Constant.ONEPOINTNINE_HOURS,TimeUnit.SECONDS);
2745   - }
2746   - }
2747   - orderBaseInfoVo.setSmallPicUrl(smallPicUrl);
  2737 + OrderBaseInfoVO orderBaseInfoVo = BeanUtil.copyProperties(orderBaseInfoDO, OrderBaseInfoVO.class);
2748 2738 orderEventJobVO.setBaseInfo(orderBaseInfoVo);
2749   -
2750 2739 //一旦修改完质检信息就自动发送邮件对应的生产科。多次编辑保存多次发送。 只有当这次的尾期结果与上一次不一样才不会发送。
2751 2740 if (StringUtils.isNotBlank(updateVO.getInspectionStageInfo().getEndCheckResult()) && !(updateVO.getInspectionStageInfo().getEndCheckResult().equals(endCheckResult))) {
2752 2741 String EndCheckApplyTime = StringUtils.isNotBlank(updateVO.getInspectionStageInfo().getEndCheckApplyTime()) ?
... ... @@ -2787,17 +2776,7 @@ end
2787 2776 List<String> allEmails=new ArrayList<>(emailsSet);
2788 2777 OrderEventJobVO orderEventJobVO = new OrderEventJobVO();
2789 2778 orderEventJobVO.setInspectionStageInfo(inspectionStageVO);
2790   - OrderBaseInfoVO orderBaseInfoVo = BeanUtil.copyProperties(orderBaseInfoDO, OrderBaseInfoVO.class,"smallPicUrl");
2791   - String smallPicUrl="";
2792   - if(com.order.erp.common.utils.StringUtils.isNotEmpty(orderBaseInfoDO.getSmallPicUrl())){
2793   - String smallPicUrlKey=Constant.OSS_SMALL_PIC_URL+orderBaseInfoDO.getSmallPicUrl();
2794   - smallPicUrl=(String)redisUtils.get(smallPicUrlKey);
2795   - if(StringUtils.isBlank(smallPicUrl)){
2796   - smallPicUrl= AliOssUtil.createUrl(SplitUrlGetBucketName.getBucket(orderBaseInfoDO.getSmallPicUrl()),SplitUrlGetBucketName.getFileName(orderBaseInfoDO.getSmallPicUrl()),new DateTime().plusHours(Constant.TWO).toDate());
2797   - redisUtils.set(smallPicUrlKey,smallPicUrl,Constant.ONEPOINTNINE_HOURS,TimeUnit.SECONDS);
2798   - }
2799   - }
2800   - orderBaseInfoVo.setSmallPicUrl(smallPicUrl);
  2779 + OrderBaseInfoVO orderBaseInfoVo = BeanUtil.copyProperties(orderBaseInfoDO, OrderBaseInfoVO.class);
2801 2780 orderEventJobVO.setBaseInfo(orderBaseInfoVo);
2802 2781 emailSendUtils.sendCheckResultEmail(EmailTemplateEnum.END_CHECK_REPORT_TEMPLATE, allEmails, orderEventJobVO);
2803 2782 }else{
... ... @@ -2885,16 +2864,8 @@ end
2885 2864 orderEventJobVO.getBaseInfo().setCustomerPo(orderBaseInfoDo.getCustomerPo());
2886 2865 orderEventJobVO.getBaseInfo().setCustomerStyle(orderBaseInfoDo.getCustomerStyle());
2887 2866 orderEventJobVO.getBaseInfo().setPoColor(orderBaseInfoDo.getPoColor());
2888   - String smallPicUrl="";
2889   - if(com.order.erp.common.utils.StringUtils.isNotEmpty(orderBaseInfoDo.getSmallPicUrl())){
2890   - String smallPicUrlKey=Constant.OSS_SMALL_PIC_URL+orderBaseInfoDo.getSmallPicUrl();
2891   - smallPicUrl=(String)redisUtils.get(smallPicUrlKey);
2892   - if(StringUtils.isBlank(smallPicUrl)){
2893   - smallPicUrl= AliOssUtil.createUrl(SplitUrlGetBucketName.getBucket(orderBaseInfoDo.getSmallPicUrl()),SplitUrlGetBucketName.getFileName(orderBaseInfoDo.getSmallPicUrl()),new DateTime().plusHours(Constant.TWO).toDate());
2894   - redisUtils.set(smallPicUrlKey,smallPicUrl,Constant.ONEPOINTNINE_HOURS,TimeUnit.SECONDS);
2895   - }
2896   - }
2897   - orderEventJobVO.getBaseInfo().setSmallPicUrl(smallPicUrl);
  2867 + //实时链接 本来在这里通过多次创建实时链接来进行获取图片资源。现在在邮件发送处进行实时链接获取,因为异步,所以不会影响主要逻辑。此时 orderEventJobVO.getBaseInfo().getSmallPicUrl还是没有oss的图片资源。
  2868 + orderEventJobVO.getBaseInfo().setSmallPicUrl(orderBaseInfoDo.getSmallPicUrl());
2898 2869 orderEventJobVO.getBaseInfo().setOrderCount(orderBaseInfoDo.getOrderCount());
2899 2870 // String[] split = productionComment.split("\n");
2900 2871 // String[] split1 = split[split.length - 1].split("[::]+");
... ... @@ -2927,7 +2898,9 @@ end
2927 2898 if (TimePeriod.YEAR.getDescription().equals(dateTimeVO.getPeriod())) {
2928 2899 //查询每一年份的已完成订单数据。
2929 2900 //查询所有年份的完成订单数据。
  2901 + //计算不是返单的数据,对于不是返单的数据,需要对innerNo和customerCode进行去重。 (订单完成状态)
2930 2902 long allYearCountNoReturn = this.baseMapper.countAllYearByOrderStatus(OrderStatusEnum.ORDER_FINISH.getStatus());
  2903 + // 计算返单的数据 ,对于返单的数据不需要对innerNo和customerCode进行去重的。 (订单完成状态)
2931 2904 long allYearCountReturn = this.count(new LambdaQueryWrapper<OrderBaseInfoDO>().eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN).eq(OrderBaseInfoDO::getReturnOrder, Constant.STRING_ONE).eq(OrderBaseInfoDO::getOrderStatus,OrderStatusEnum.ORDER_FINISH.getStatus()));
2932 2905 /* 查询所有年份的跟单和质检中的数据。
2933 2906 long tracking = orderTrackStageService.countRecentYearByOrderStatus(OrderStatusEnum.TRACK_ING.getStatus());
... ... @@ -2943,11 +2916,13 @@ end
2943 2916 long report = orderFieldLockApplyService.countAllYearByOrderStatus(ApplyTypeEnum.ORDER_REPORT_APPLY.getType());
2944 2917  
2945 2918 //查询所有年份的订单初始化的数据。
  2919 + // 计算不是返单的数据,对于不是返单的数据,需要对innerNo和customerCode进行去重。 (订单初始化,只要被创建就会被计算)
2946 2920 long orderInit = this.baseMapper.countRecentYearByOrderInit();
2947   -
  2921 +// 计算是返单的数据,对于返单的数据不需要对innerNo和customerCode进行去重的。 (订单初始化,只要被创建就会被计算)
2948 2922 long returnOrderBaseInfoNumber = this.count(new LambdaQueryWrapper<OrderBaseInfoDO>().eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN).eq(OrderBaseInfoDO::getReturnOrder, Constant.STRING_ONE));
2949 2923 Datecount datecount = new Datecount();
2950 2924 datecount.setAllCount(allYearCountNoReturn+allYearCountReturn);
  2925 + // 跟单和质检中的计算方式为 订单初始化之和减去订单完成状态数据就为跟单和质检状态。
2951 2926 datecount.setTrackingAndInspectingList(orderInit+returnOrderBaseInfoNumber-allYearCountNoReturn-allYearCountReturn);
2952 2927 datecount.setProfitList(rofit);
2953 2928 datecount.setReportList(report);
... ... @@ -2962,7 +2937,9 @@ end
2962 2937 LocalDate endOfYear = startOfYear.plusYears(1);
2963 2938 //如果为月,则需要前端传递year,然后得到这个year的数据。
2964 2939 //查询这个年每一个月的数据
  2940 + //计算不是返单的数据,对于不是返单的数据,需要对innerNo和customerCode进行去重。 (订单完成状态)
2965 2941 long allMonthCountNoReturn=this.baseMapper.countAllMonthByOrderStatus(OrderStatusEnum.ORDER_FINISH.getStatus(),(long) (dateTime % 100));
  2942 + // 计算返单的数据 ,对于返单的数据不需要对innerNo和customerCode进行去重的。 (订单完成状态)
2966 2943 long allMonthCountReturn = this.count(new LambdaQueryWrapper<OrderBaseInfoDO>()
2967 2944 .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
2968 2945 .eq(OrderBaseInfoDO::getReturnOrder, Constant.STRING_ONE)
... ... @@ -2974,15 +2951,16 @@ end
2974 2951 System.out.println("质检中:"+inspecting);*/
2975 2952 long profit = orderFieldLockApplyService.countRecentMonthValueByOrderStatus(ApplyTypeEnum.ORDER_PROFIT_APPLY.getType(),startOfYear,endOfYear);
2976 2953 long report = orderFieldLockApplyService.countRecentMonthValueByOrderStatus(ApplyTypeEnum.ORDER_REPORT_APPLY.getType(),startOfYear,endOfYear);
2977   -
  2954 + // 计算不是返单的数据,对于不是返单的数据,需要对innerNo和customerCode进行去重。 (订单初始化,只要被创建就会被计算)
2978 2955 long orderInit=this.baseMapper.countRecentMonthValueByOrderInit((long) (dateTime % 100));
2979   -
  2956 + // 计算是返单的数据,对于返单的数据不需要对innerNo和customerCode进行去重的。 (订单初始化,只要被创建就会被计算)
2980 2957 long returnOrderBaseInfoNumber = this.count(new LambdaQueryWrapper<OrderBaseInfoDO>()
2981 2958 .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
2982 2959 .eq(OrderBaseInfoDO::getReturnOrder, Constant.STRING_ONE)
2983 2960 .likeRight(OrderBaseInfoDO::getInnerNo, "_____" + dateTime % 100));
2984 2961  
2985 2962 Datecount datecount = new Datecount();
  2963 + // 跟单和质检中的计算方式为 订单初始化之和减去订单完成状态数据就为跟单和质检状态。
2986 2964 datecount.setTrackingAndInspectingList(orderInit+returnOrderBaseInfoNumber-allMonthCountNoReturn-allMonthCountReturn);
2987 2965 datecount.setAllCount(allMonthCountNoReturn+allMonthCountReturn);
2988 2966 datecount.setProfitList(profit);
... ... @@ -2996,7 +2974,9 @@ end
2996 2974 int year = currentDate.getYear();
2997 2975 LocalDate startDate = LocalDate.of(year, currentMonth, 1);
2998 2976 LocalDate endDate = startDate.plusMonths(1);
  2977 + //计算不是返单的数据,对于不是返单的数据,需要对innerNo和customerCode进行去重。 (订单完成状态)
2999 2978 long allDayCountNoReturn=this.baseMapper.countAllDayvalueByOrderStatus(OrderStatusEnum.ORDER_FINISH.getStatus(),startDate,endDate,(long)year % 100);
  2979 + // 计算返单的数据 ,对于返单的数据不需要对innerNo和customerCode进行去重的。 (订单完成状态)
3000 2980 long allDayCountReturn = this.count(new LambdaQueryWrapper<OrderBaseInfoDO>()
3001 2981 .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
3002 2982 .eq(OrderBaseInfoDO::getReturnOrder, Constant.STRING_ONE)
... ... @@ -3010,8 +2990,9 @@ end
3010 2990 System.out.println("质检中:"+inspecting);*/
3011 2991 long profit= orderFieldLockApplyService.countRecentDayvalueByOrderStatus(ApplyTypeEnum.ORDER_PROFIT_APPLY.getType(),startDate,endDate);
3012 2992 long report=orderFieldLockApplyService.countRecentDayvalueByOrderStatus(ApplyTypeEnum.ORDER_REPORT_APPLY.getType(),startDate,endDate);
3013   -
  2993 + // 计算不是返单的数据,对于不是返单的数据,需要对innerNo和customerCode进行去重。 (订单初始化,只要被创建就会被计算)
3014 2994 long orderInit=this.baseMapper.countRecentDayByOrderInit(startDate,endDate, (long) (year % 100));
  2995 + // 计算是返单的数据,对于返单的数据不需要对innerNo和customerCode进行去重的。 (订单初始化,只要被创建就会被计算)
3015 2996 long returnOrderBaseInfoNumber = this.count(new LambdaQueryWrapper<OrderBaseInfoDO>()
3016 2997 .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
3017 2998 .eq(OrderBaseInfoDO::getReturnOrder, Constant.STRING_ONE)
... ... @@ -3019,6 +3000,7 @@ end
3019 3000 .lt(OrderBaseInfoDO::getCreateTime,endDate)
3020 3001 .likeRight(OrderBaseInfoDO::getInnerNo, "_____" + year % 100));
3021 3002 Datecount datecount = new Datecount();
  3003 + // 跟单和质检中的计算方式为 订单初始化之和减去订单完成状态数据就为跟单和质检状态。
3022 3004 datecount.setTrackingAndInspectingList(orderInit+returnOrderBaseInfoNumber-allDayCountNoReturn-allDayCountReturn);
3023 3005 datecount.setAllCount(allDayCountNoReturn+allDayCountReturn);
3024 3006 datecount.setProfitList(profit);
... ...
src/main/java/com/order/erp/service/order/impl/ProducePaymentCheckBillOrderServiceImpl.java
... ... @@ -81,6 +81,8 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
81 81 private InvoiceBillOrderMapper invoiceBillOrderMapper;
82 82 @Resource
83 83 private EmailSendUtils emailSendUtils;
  84 + @Resource
  85 + private RichTextContentService richTextContentService;
84 86  
85 87  
86 88 /**
... ... @@ -917,7 +919,21 @@ public class ProducePaymentCheckBillOrderServiceImpl extends ServiceImpl&lt;Produce
917 919 checkBillOrderDO.setDeductAmount((deductInfoVO.getDeductAmount()==null? BigDecimal.ZERO:deductInfoVO.getDeductAmount()).setScale(2, BigDecimal.ROUND_HALF_UP));
918 920 checkBillOrderDO.setActualPayedAmount((checkBillOrderDO.getTotalProductionAmount().subtract(deductInfoVO.getDeductAmount()==null? BigDecimal.ZERO:deductInfoVO.getDeductAmount())).setScale(2, BigDecimal.ROUND_HALF_UP));
919 921 checkBillOrderDO.setUnPayedAmount((checkBillOrderDO.getTotalProductionAmount().subtract(checkBillOrderDO.getDeductAmount()).subtract(checkBillOrderDO.getTotalActualPayedAmount())).setScale(2, BigDecimal.ROUND_HALF_UP));
920   - if(StringUtils.isNotBlank(deductInfoVO.getDeductUrl())){
  922 + if(Objects.nonNull(deductInfoVO.getQuestId())){
  923 + checkBillOrderDO.setRichTextId(deductInfoVO.getQuestId());
  924 + //还需要把引用该文章的checkId保存到对应的文章的checkId中,防止编辑或者删除文章之后,没有引用到新的文章上。
  925 + RichTextContentDO richTextContentDO = richTextContentService.getById(deductInfoVO.getQuestId());
  926 + String checkId = richTextContentDO.getCheckId();
  927 + String newId = String.valueOf(deductInfoVO.getId());
  928 + if(StringUtils.isNotBlank(checkId)){
  929 + checkId=checkId+","+newId;
  930 + }else{
  931 + checkId=newId;
  932 + }
  933 + richTextContentDO.setCheckId(checkId);
  934 + richTextContentService.updateById(richTextContentDO);
  935 + }
  936 + if(StringUtils.isNotBlank(deductInfoVO.getDeductUrl())){
921 937 checkBillOrderDO.setCheckDeductUrlStatus(ApplyStatusEnum.WAIT_AUDIT.getStatus());
922 938 }
923 939 updateById(checkBillOrderDO);
... ...
src/main/java/com/order/erp/service/order/impl/RichTextContentServiceImpl.java 0 → 100644
  1 +package com.order.erp.service.order.impl;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  5 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  6 +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
  7 +import com.baomidou.mybatisplus.core.metadata.IPage;
  8 +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
  9 +import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  10 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  11 +import com.order.erp.common.constant.Constant;
  12 +import com.order.erp.common.constant.ServerResult;
  13 +import com.order.erp.common.constant.ServerResultCode;
  14 +import com.order.erp.common.exception.BusinessException;
  15 +import com.order.erp.common.utils.AliOssUtil;
  16 +import com.order.erp.common.utils.HtmlSanitizerUtil;
  17 +import com.order.erp.common.utils.SplitUrlGetBucketName;
  18 +import com.order.erp.common.utils.StringUtils;
  19 +import com.order.erp.config.DataScope;
  20 +import com.order.erp.domain.ApplyStatusEnum;
  21 +import com.order.erp.domain.RoleEnum;
  22 +import com.order.erp.domain.dto.BaseDO;
  23 +import com.order.erp.domain.dto.SystemSettingDO;
  24 +import com.order.erp.domain.dto.order.InvoiceBillOrderDO;
  25 +import com.order.erp.domain.dto.order.ProducePaymentCheckBillOrderDO;
  26 +import com.order.erp.domain.dto.order.RichTextContentDO;
  27 +import com.order.erp.domain.vo.order.RichTextAllTitleResultVO;
  28 +import com.order.erp.domain.vo.order.RichTextContentVO;
  29 +import com.order.erp.domain.vo.order.RichTextListQueryPageVO;
  30 +import com.order.erp.domain.vo.order.RichTextContentResultVO;
  31 +import com.order.erp.mapper.order.RichTextContentMapper;
  32 +import com.order.erp.service.SystemSettingService;
  33 +import com.order.erp.service.order.InvoiceBillOrderService;
  34 +import com.order.erp.service.order.ProducePaymentCheckBillOrderService;
  35 +import com.order.erp.service.order.RichTextContentService;
  36 +import lombok.extern.slf4j.Slf4j;
  37 +import org.joda.time.DateTime;
  38 +import org.springframework.beans.BeanUtils;
  39 +import org.springframework.stereotype.Service;
  40 +import org.springframework.web.bind.annotation.RequestBody;
  41 +
  42 +import javax.annotation.Resource;
  43 +import java.math.BigDecimal;
  44 +import java.math.RoundingMode;
  45 +import java.util.*;
  46 +import java.util.stream.Collectors;
  47 +
  48 +@Slf4j
  49 +@Service
  50 +public class RichTextContentServiceImpl extends ServiceImpl<RichTextContentMapper, RichTextContentDO> implements RichTextContentService {
  51 + @Resource
  52 + private InvoiceBillOrderService invoiceBillOrderService;
  53 + @Resource
  54 + private ProducePaymentCheckBillOrderService producePaymentCheckBillOrderService;
  55 + @Resource
  56 + private SystemSettingService systemSettingService;
  57 + @Resource
  58 + private DataScope dataScope;
  59 +
  60 + @Override
  61 + public ServerResult listByPage(RichTextListQueryPageVO richTextListQueryPageVO) {
  62 +
  63 + // 构建查询
  64 + LambdaQueryWrapper<RichTextContentDO> richTextContentDOLambdaQueryWrapper = buildQueryByParam(richTextListQueryPageVO);
  65 + Page<RichTextContentDO> page = new Page<>(richTextListQueryPageVO.getPage(), richTextListQueryPageVO.getPageSize());
  66 + IPage<RichTextContentDO> ipage = page(page, richTextContentDOLambdaQueryWrapper);
  67 + Page<RichTextContentResultVO> webPage = new Page<>();
  68 + BeanUtils.copyProperties(ipage, webPage, "records");
  69 +
  70 + List<RichTextContentResultVO> processedRecords = ipage.getRecords().stream().map(x -> {
  71 + RichTextContentResultVO resultVO = new RichTextContentResultVO();
  72 + BeanUtils.copyProperties(x, resultVO);
  73 + // 处理 contentImages
  74 + if (StringUtils.isNotBlank(x.getContentImages())) {
  75 + List<String> ossImagesUrl = Arrays.stream(x.getContentImages().split(","))
  76 + .map(fileUrl -> AliOssUtil.createUrl(
  77 + SplitUrlGetBucketName.getBucket(fileUrl),
  78 + SplitUrlGetBucketName.getFileName(fileUrl),
  79 + new DateTime().plusHours(Constant.TWO).toDate()))
  80 + .collect(Collectors.toList());
  81 +
  82 + // 将转换后的 URL 重新赋值
  83 + resultVO.setContentImages( ossImagesUrl);
  84 + }
  85 + // 处理 files
  86 + if (StringUtils.isNotBlank(x.getFiles())) {
  87 + List<String> ossFileUrl = Arrays.stream(x.getFiles().split(","))
  88 + .map(fileUrl -> AliOssUtil.createUrl(
  89 + SplitUrlGetBucketName.getBucket(fileUrl),
  90 + SplitUrlGetBucketName.getFileName(fileUrl),
  91 + new DateTime().plusHours(Constant.TWO).toDate()))
  92 + .collect(Collectors.toList());
  93 + // 将转换后的 URL 重新赋值
  94 + resultVO.setFiles( ossFileUrl);
  95 + }
  96 + return resultVO;
  97 + }).collect(Collectors.toList());
  98 + webPage.setRecords(processedRecords);
  99 +
  100 + return ServerResult.success(webPage);
  101 +
  102 + }
  103 +
  104 + @Override
  105 + public ServerResult deleteById(RichTextContentVO richTextContentVO) {
  106 + if (CollectionUtils.isEmpty(richTextContentVO.getIds())) {
  107 + return ServerResult.fail("ids 参数不能为空");
  108 + }
  109 + LambdaUpdateWrapper<RichTextContentDO> updateWrapper = new LambdaUpdateWrapper<RichTextContentDO>()
  110 + .in(RichTextContentDO::getId, richTextContentVO.getIds())
  111 + .set(RichTextContentDO::getEnableFlag, Constant.UNABLE_TWENTY);
  112 + update(updateWrapper);
  113 + return ServerResult.success();
  114 + }
  115 +
  116 + @Override
  117 + public ServerResult edit(RichTextContentVO richTextContentVO) {
  118 + if (Objects.isNull(richTextContentVO.getId())) {
  119 + return ServerResult.fail("id 参数不能为空");
  120 + }
  121 + RichTextContentDO richTextContentDO = getById(richTextContentVO.getId());
  122 + if (Objects.isNull(richTextContentDO)) {
  123 + throw new BusinessException(ServerResultCode.EMPTY_RESULT);
  124 + }
  125 + String sanitizeHtml = HtmlSanitizerUtil.sanitizeHtml(richTextContentVO.getContentText());
  126 + RichTextContentDO newRichTextContentDO=new RichTextContentDO();
  127 + if (StringUtils.isNotEmpty(richTextContentVO.getContentImages())) {
  128 + List<String> contentList=JSON.parseArray(richTextContentVO.getContentImages(), String.class);
  129 + String contentImages = String.join(",", contentList);
  130 + //检查是否是有多个文件同时上传。
  131 + if (contentImages.contains(",")) {
  132 + List<String> processedFileNames = new ArrayList<>();
  133 + //获取每一个url的文件名称
  134 + String[] fileUrl = contentImages.split(",");
  135 + for (String fileName : fileUrl) {
  136 + String urlFileName = SplitUrlGetBucketName.getUrlFileName(fileName);
  137 + processedFileNames.add(urlFileName);
  138 + }
  139 + String result = String.join(",", processedFileNames);
  140 + newRichTextContentDO.setContentImages(result);
  141 + } else {
  142 + newRichTextContentDO.setContentImages(SplitUrlGetBucketName.getUrlFileName(contentImages));
  143 + }
  144 + }
  145 + if (StringUtils.isNotBlank(richTextContentVO.getFiles())) {
  146 + List<String> contentList=JSON.parseArray(richTextContentVO.getFiles(), String.class);
  147 + String files = String.join(",", contentList);
  148 + //检查是否是有多个文件同时上传。
  149 + if (files.contains(",")) {
  150 + List<String> processedFileNames = new ArrayList<>();
  151 + //获取每一个url的文件名称
  152 + String[] fileUrl = files.split(",");
  153 + for (String fileName : fileUrl) {
  154 + String urlFileName = SplitUrlGetBucketName.getUrlFileName(fileName);
  155 + processedFileNames.add(urlFileName);
  156 + }
  157 + String result = String.join(",", processedFileNames);
  158 + newRichTextContentDO.setFiles(result);
  159 + } else {
  160 + newRichTextContentDO.setFiles(SplitUrlGetBucketName.getUrlFileName(files));
  161 + }
  162 + }
  163 + newRichTextContentDO.setTitle(richTextContentVO.getTitle());
  164 + newRichTextContentDO.setContentText(sanitizeHtml);
  165 + newRichTextContentDO.setStatus(ApplyStatusEnum.WAIT_AUDIT.getStatus());
  166 + newRichTextContentDO.setQuestType(richTextContentVO.getQuestType());
  167 + newRichTextContentDO.setDeductAmount(richTextContentVO.getDeductAmount());
  168 + newRichTextContentDO.setIsRmb(richTextContentVO.getIsRmb());
  169 + newRichTextContentDO.setIsTemplate(richTextContentVO.getIsTemplate());
  170 + newRichTextContentDO.setIsTrackerBlock(richTextContentVO.getIsTrackerBlock());
  171 + List<Long> oldIdList = new ArrayList<>();
  172 + String oldId = richTextContentDO.getOldId();
  173 + if (oldId != null && !oldId.isEmpty()) {
  174 + oldIdList = Arrays.stream(oldId.split(","))
  175 + .map(Long::parseLong)
  176 + .collect(Collectors.toCollection(ArrayList::new));
  177 + }
  178 + oldIdList.add(richTextContentDO.getId());
  179 + newRichTextContentDO.setOldId(String.join(",", oldIdList.stream()
  180 + .map(String::valueOf)
  181 + .toArray(String[]::new)));
  182 + if(StringUtils.isNotBlank(richTextContentDO.getCheckId())){
  183 + newRichTextContentDO.setCheckId(richTextContentDO.getCheckId());
  184 + }
  185 + if(StringUtils.isNotBlank(richTextContentDO.getInvoiceId())){
  186 + newRichTextContentDO.setInvoiceId(richTextContentDO.getInvoiceId());
  187 + }
  188 + save(newRichTextContentDO);
  189 + return ServerResult.success();
  190 + }
  191 +
  192 + @Override
  193 + public ServerResult add(RichTextContentVO richTextContentVO) {
  194 + if (Objects.nonNull(richTextContentVO.getId())) {
  195 + richTextContentVO.setId(null);
  196 + }
  197 + String sanitizeHtml = HtmlSanitizerUtil.sanitizeHtml(richTextContentVO.getContentText());
  198 + RichTextContentDO richTextContentDO = new RichTextContentDO();
  199 + richTextContentDO.setTitle(richTextContentVO.getTitle());
  200 + richTextContentDO.setContentText(sanitizeHtml);
  201 + richTextContentDO.setQuestType(richTextContentVO.getQuestType());
  202 + richTextContentDO.setDeductAmount(richTextContentVO.getDeductAmount());
  203 + richTextContentDO.setIsRmb(richTextContentVO.getIsRmb());
  204 + richTextContentDO.setIsTemplate(richTextContentVO.getIsTemplate());
  205 + richTextContentDO.setIsTrackerBlock(richTextContentVO.getIsTrackerBlock());
  206 +
  207 + if (StringUtils.isNotEmpty(richTextContentVO.getContentImages())) {
  208 + List<String> contentList=JSON.parseArray(richTextContentVO.getContentImages(), String.class);
  209 + String contentImages = String.join(",", contentList);
  210 + //检查是否是有多个文件同时上传。
  211 + if (contentImages.contains(",")) {
  212 + List<String> processedFileNames = new ArrayList<>();
  213 + //获取每一个url的文件名称
  214 + String[] fileUrl = contentImages.split(",");
  215 + for (String fileName : fileUrl) {
  216 + String urlFileName = SplitUrlGetBucketName.getUrlFileName(fileName);
  217 + processedFileNames.add(urlFileName);
  218 + }
  219 + String result = String.join(",", processedFileNames);
  220 + richTextContentDO.setContentImages(result);
  221 + } else {
  222 + richTextContentDO.setContentImages(SplitUrlGetBucketName.getUrlFileName(contentImages));
  223 + }
  224 + }
  225 + if (StringUtils.isNotBlank(richTextContentVO.getFiles())) {
  226 + List<String> contentList=JSON.parseArray(richTextContentVO.getFiles(), String.class);
  227 + String files = String.join(",", contentList);
  228 + //检查是否是有多个文件同时上传。
  229 + if (files.contains(",")) {
  230 + List<String> processedFileNames = new ArrayList<>();
  231 + //获取每一个url的文件名称
  232 + String[] fileUrl = files.split(",");
  233 + for (String fileName : fileUrl) {
  234 + String urlFileName = SplitUrlGetBucketName.getUrlFileName(fileName);
  235 + processedFileNames.add(urlFileName);
  236 + }
  237 + String result = String.join(",", processedFileNames);
  238 + richTextContentDO.setFiles(result);
  239 + } else {
  240 + richTextContentDO.setFiles(SplitUrlGetBucketName.getUrlFileName(files));
  241 + }
  242 + }
  243 + richTextContentDO.setStatus(ApplyStatusEnum.WAIT_AUDIT.getStatus());
  244 + save(richTextContentDO);
  245 + return ServerResult.success();
  246 +
  247 + }
  248 +
  249 + @Override
  250 + public ServerResult setStatus(RichTextContentVO richTextContentVO) {
  251 + if (Objects.isNull(richTextContentVO.getId())) {
  252 + return ServerResult.fail("id 参数不能为空");
  253 + }
  254 + RichTextContentDO richTextContentDO = getById(richTextContentVO.getId());
  255 + if (Objects.isNull(richTextContentDO)) {
  256 + throw new BusinessException(ServerResultCode.EMPTY_RESULT);
  257 + }
  258 + richTextContentDO.setStatus(richTextContentVO.getStatus());
  259 +
  260 + List<Long> oldIdList = Optional.ofNullable(richTextContentDO.getOldId())
  261 + .filter(str -> !str.isEmpty())
  262 + .map(str -> Arrays.stream(str.split(","))
  263 + .map(Long::parseLong)
  264 + .collect(Collectors.toList()))
  265 + .orElse(new ArrayList<>());
  266 + if (CollectionUtils.isEmpty(oldIdList)) {
  267 + updateById(richTextContentDO);
  268 + return ServerResult.success();
  269 + }
  270 + if (ApplyStatusEnum.AUDIT_PASS.getStatus().equals(richTextContentVO.getStatus())) {
  271 + updateById(richTextContentDO);
  272 + //通过之后旧的RichTextContent就会被删除,所以需要新的RichTextContent对invoiceId和checkId进行关联。防止之前关联的check和invoice没有关联的文章。
  273 + if(StringUtils.isNotEmpty(richTextContentDO.getInvoiceId())){
  274 + List<Long> idList = Arrays.stream(richTextContentDO.getInvoiceId().split(","))
  275 + .map(Long::valueOf) // 转换为 Long 类型
  276 + .collect(Collectors.toList());
  277 + LambdaUpdateWrapper<InvoiceBillOrderDO> invoiceBillOrderDOLambdaUpdateWrapper = new LambdaUpdateWrapper<InvoiceBillOrderDO>()
  278 + .in(InvoiceBillOrderDO::getId, idList)
  279 + .set(InvoiceBillOrderDO::getRichTextId, richTextContentDO.getId());
  280 + invoiceBillOrderService.update(invoiceBillOrderDOLambdaUpdateWrapper);
  281 + }
  282 + if(StringUtils.isNotEmpty(richTextContentDO.getCheckId())){
  283 + List<Long> idList = Arrays.stream(richTextContentDO.getCheckId().split(","))
  284 + .map(Long::valueOf) // 转换为 Long 类型
  285 + .collect(Collectors.toList());
  286 + LambdaUpdateWrapper<ProducePaymentCheckBillOrderDO> producePaymentCheckBillOrderDOLambdaUpdateWrapper = new LambdaUpdateWrapper<ProducePaymentCheckBillOrderDO>()
  287 + .in(ProducePaymentCheckBillOrderDO::getId, idList)
  288 + .set(ProducePaymentCheckBillOrderDO::getRichTextId, richTextContentDO.getId());
  289 + producePaymentCheckBillOrderService.update(producePaymentCheckBillOrderDOLambdaUpdateWrapper);
  290 + }
  291 + //由于逻辑删除,所以无法直接通过updateById进行更新。
  292 + LambdaUpdateWrapper<RichTextContentDO> updateWrapper = new LambdaUpdateWrapper<RichTextContentDO>()
  293 + .in(RichTextContentDO::getId, oldIdList)
  294 + .set(RichTextContentDO::getEnableFlag, Constant.UNABLE_TWENTY);
  295 + update(updateWrapper);
  296 + } else {
  297 + updateById(richTextContentDO);
  298 + }
  299 + return ServerResult.success();
  300 + }
  301 +
  302 + @Override
  303 + public ServerResult getRealseList(RichTextContentVO richTextContentVO) {
  304 + if (Objects.isNull(richTextContentVO.getId())) {
  305 + return ServerResult.fail("id 参数不能为空");
  306 + }
  307 + RichTextContentDO richTextContentDO = getById(richTextContentVO.getId());
  308 + if (Objects.isNull(richTextContentDO)) {
  309 + throw new BusinessException(ServerResultCode.EMPTY_RESULT);
  310 + }
  311 + if(StringUtils.isNotBlank(richTextContentDO.getOldId())){
  312 + List<Long> idList = Arrays.stream(richTextContentDO.getOldId().split(","))
  313 + .map(Long :: parseLong)
  314 + .collect(Collectors.toList());
  315 + List<RichTextContentDO> oldRichTextContentDOList = list(new LambdaQueryWrapper<RichTextContentDO>().eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN).in(RichTextContentDO::getId, idList));
  316 + if(CollectionUtils.isNotEmpty(oldRichTextContentDOList)){
  317 + List<RichTextContentResultVO> passRichTextContentList = oldRichTextContentDOList.stream().filter(r -> ApplyStatusEnum.AUDIT_PASS.getStatus().equals(r.getStatus())).map(x ->{
  318 + RichTextContentResultVO richTextContentResultVO = new RichTextContentResultVO();
  319 + BeanUtils.copyProperties(x,richTextContentResultVO);
  320 + //需要对返回的文件进行文件实时链接。
  321 + if (StringUtils.isNotBlank(x.getContentImages())) {
  322 + List<String> ossImagesUrl = Arrays.stream(x.getContentImages().split(","))
  323 + .map(fileUrl -> AliOssUtil.createUrl(
  324 + SplitUrlGetBucketName.getBucket(fileUrl),
  325 + SplitUrlGetBucketName.getFileName(fileUrl),
  326 + new DateTime().plusHours(Constant.TWO).toDate()))
  327 + .collect(Collectors.toList());
  328 +
  329 + // 将转换后的 URL 重新赋值
  330 + richTextContentResultVO.setContentImages( ossImagesUrl);
  331 + }
  332 + // 处理 files
  333 + if (StringUtils.isNotBlank(x.getFiles())) {
  334 + List<String> ossFileUrl = Arrays.stream(x.getFiles().split(","))
  335 + .map(fileUrl -> AliOssUtil.createUrl(
  336 + SplitUrlGetBucketName.getBucket(fileUrl),
  337 + SplitUrlGetBucketName.getFileName(fileUrl),
  338 + new DateTime().plusHours(Constant.TWO).toDate()))
  339 + .collect(Collectors.toList());
  340 + // 将转换后的 URL 重新赋值
  341 + richTextContentResultVO.setFiles( ossFileUrl);
  342 + }
  343 + return richTextContentResultVO;
  344 + }).collect(Collectors.toList());
  345 + return ServerResult.success(passRichTextContentList);
  346 + }
  347 + }
  348 + return ServerResult.success();
  349 + }
  350 +
  351 + @Override
  352 + public ServerResult getAll(@RequestBody RichTextContentVO richTextContentVO) {
  353 + List<RichTextContentDO> richTextContentDOList = list(
  354 + new LambdaQueryWrapper<RichTextContentDO>()
  355 + .select(RichTextContentDO::getId, RichTextContentDO::getTitle,RichTextContentDO::getDeductAmount,RichTextContentDO::getIsTemplate) // 只查询 id 和 title和扣款金额。
  356 + .eq(Objects.nonNull(richTextContentVO.getIsTrackerBlock()),RichTextContentDO::getIsTrackerBlock,richTextContentVO.getIsTrackerBlock())
  357 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  358 + .eq(RichTextContentDO::getStatus,ApplyStatusEnum.AUDIT_PASS.getStatus()));
  359 + return ServerResult.success(richTextContentDOList);
  360 + }
  361 +
  362 + @Override
  363 + public ServerResult queryTitle(RichTextContentVO richTextContentVO) {
  364 + if(StringUtils.isEmpty(richTextContentVO.getTitle())){
  365 + throw new BusinessException("title 参数不能为空");
  366 + }
  367 + List<RichTextAllTitleResultVO> allTitle = baseMapper.queryTitle(richTextContentVO);
  368 + return ServerResult.success(allTitle);
  369 + }
  370 +
  371 + @Override
  372 + public ServerResult queryRichTextById(RichTextContentVO richTextContentVO) {
  373 + if(Objects.isNull(richTextContentVO.getId())){
  374 + throw new BusinessException(ServerResultCode.PARAM_ERROR);
  375 + }
  376 + RichTextContentDO richTextContentDO = getById(richTextContentVO.getId());
  377 + if(Objects.nonNull(richTextContentDO)){
  378 + RichTextContentResultVO richTextContentResultVO = new RichTextContentResultVO();
  379 + BeanUtils.copyProperties(richTextContentDO,richTextContentResultVO,"contentImages","files");
  380 + if (StringUtils.isNotBlank(richTextContentDO.getContentImages())) {
  381 + List<String> ossImagesUrl = Arrays.stream(richTextContentDO.getContentImages().split(","))
  382 + .map(fileUrl -> AliOssUtil.createUrl(
  383 + SplitUrlGetBucketName.getBucket(fileUrl),
  384 + SplitUrlGetBucketName.getFileName(fileUrl),
  385 + new DateTime().plusHours(Constant.TWO).toDate()))
  386 + .collect(Collectors.toList());
  387 + // 将转换后的 URL 重新赋值
  388 + richTextContentResultVO.setContentImages( ossImagesUrl);
  389 + }
  390 + // 处理 files
  391 + if (StringUtils.isNotBlank(richTextContentDO.getFiles())) {
  392 + List<String> ossFileUrl = Arrays.stream(richTextContentDO.getFiles().split(","))
  393 + .map(fileUrl -> AliOssUtil.createUrl(
  394 + SplitUrlGetBucketName.getBucket(fileUrl),
  395 + SplitUrlGetBucketName.getFileName(fileUrl),
  396 + new DateTime().plusHours(Constant.TWO).toDate()))
  397 + .collect(Collectors.toList());
  398 + // 将转换后的 URL 重新赋值
  399 + richTextContentResultVO.setFiles( ossFileUrl);
  400 + }
  401 + return ServerResult.success(richTextContentResultVO);
  402 + }
  403 + return ServerResult.success("问题列表不存在或者已被删除");
  404 + }
  405 +
  406 + @Override
  407 + public ServerResult getSumDeductAmount(RichTextContentVO richTextContentVO) {
  408 + if(CollectionUtils.isEmpty(richTextContentVO.getIds())){
  409 + throw new BusinessException(ServerResultCode.PARAM_ERROR);
  410 + }
  411 + HashMap<String, Object> deductAmountMap = new HashMap<>();
  412 + List<RichTextContentDO> richTextContentDOList=list(new LambdaQueryWrapper<RichTextContentDO>()
  413 + .select(RichTextContentDO::getId, RichTextContentDO::getDeductAmount,RichTextContentDO::getIsRmb)
  414 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  415 + .in(RichTextContentDO::getId,richTextContentVO.getIds()));
  416 + if(CollectionUtils.isNotEmpty(richTextContentDOList)){
  417 + //去重
  418 + int distinctIdCount = richTextContentDOList.stream()
  419 + .map(RichTextContentDO::getId)
  420 + .collect(Collectors.toSet())
  421 + .size();
  422 + //合计
  423 + BigDecimal sumDeductAmount = richTextContentDOList.stream()
  424 + .map(RichTextContentDO::getDeductAmount)
  425 + .filter(Objects::nonNull)
  426 + .reduce(BigDecimal::add)
  427 + .orElse(BigDecimal.ZERO)
  428 + .setScale(Constant.TWO, RoundingMode.HALF_UP);
  429 + deductAmountMap.put("distinctIdCount", distinctIdCount);
  430 + deductAmountMap.put("sumDeductAmount", sumDeductAmount);
  431 + }
  432 + //是否只有一种货币符号
  433 + boolean isAllSame = richTextContentDOList.stream()
  434 + .map(RichTextContentDO::getIsRmb)
  435 + .distinct()
  436 + .count() <= 1;
  437 + if(isAllSame){
  438 + String isRmb = richTextContentDOList.get(0).getIsRmb();
  439 + deductAmountMap.put("isRmb", isRmb);
  440 + //既有人民币也有美元。
  441 + }else{
  442 + deductAmountMap.put("isRmb", Constant.STRING_ZERO);
  443 + //通过系统汇率去计算。
  444 + BigDecimal totalRmbDeductAmount = richTextContentDOList.stream()
  445 + .filter(richTextContentDO -> Constant.STRING_ONE.equals(richTextContentDO.getIsRmb()))
  446 + .map(RichTextContentDO::getDeductAmount)
  447 + .filter(Objects::nonNull)
  448 + .reduce(BigDecimal.ZERO, BigDecimal::add)
  449 + .setScale(2, RoundingMode.HALF_UP);
  450 + BigDecimal totalUsdDeductAmount = richTextContentDOList.stream()
  451 + .filter(richTextContentDO -> Constant.ZERO_STRING.equals(richTextContentDO.getIsRmb()))
  452 + .map(RichTextContentDO::getDeductAmount)
  453 + .filter(Objects::nonNull)
  454 + .reduce(BigDecimal::add)
  455 + .orElse(BigDecimal.ZERO)
  456 + .setScale(Constant.TWO, RoundingMode.HALF_UP);
  457 + //获取系统中的汇率配置。
  458 + BigDecimal exchangeRate = new BigDecimal(systemSettingService.getOne(new LambdaQueryWrapper<SystemSettingDO>()
  459 + .eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  460 + .eq(SystemSettingDO::getSettingCode, "exchangeRate")
  461 + .last("limit 1")).getSettingValue());
  462 + deductAmountMap.put("sumDeductAmount", totalUsdDeductAmount.add(totalRmbDeductAmount.divide(exchangeRate, Constant.TWO, RoundingMode.HALF_UP)));
  463 + }
  464 + return ServerResult.success(deductAmountMap);
  465 + }
  466 +
  467 + private LambdaQueryWrapper<RichTextContentDO> buildQueryByParam(RichTextListQueryPageVO richTextListQueryPageVO) {
  468 + RoleEnum roleEnum = dataScope.getRole();
  469 +
  470 + if(StringUtils.isNotEmpty(richTextListQueryPageVO.getCreateStartTime())){
  471 + richTextListQueryPageVO.setCreateStartTime(richTextListQueryPageVO.getCreateStartTime().substring(0,10)+" 00:00:00");
  472 + }
  473 + if(StringUtils.isNotEmpty(richTextListQueryPageVO.getCreateEndTime())){
  474 + richTextListQueryPageVO.setCreateEndTime(richTextListQueryPageVO.getCreateEndTime().substring(0,10)+" 23:59:59");
  475 + }
  476 +
  477 + LambdaQueryWrapper<RichTextContentDO> queryWrapper = new LambdaQueryWrapper<RichTextContentDO>().eq(BaseDO::getEnableFlag, Constant.ENABLE_TEN)
  478 + .eq(StringUtils.isNotBlank(richTextListQueryPageVO.getCreateBy()), RichTextContentDO::getCreateBy, richTextListQueryPageVO.getCreateBy())
  479 + .eq(StringUtils.isNotBlank(richTextListQueryPageVO.getQuestType()), RichTextContentDO::getQuestType, richTextListQueryPageVO.getQuestType())
  480 + .gt(StringUtils.isNotEmpty(richTextListQueryPageVO.getCreateStartTime()),RichTextContentDO::getCreateTime,richTextListQueryPageVO.getCreateStartTime())
  481 + .lt(StringUtils.isNotEmpty(richTextListQueryPageVO.getCreateEndTime()),RichTextContentDO::getCreateTime,richTextListQueryPageVO.getCreateEndTime());
  482 + //只有管理员和财务能够看到所有订单。其他角色只能看到跟单编辑必选编辑模块。
  483 + if(!RoleEnum.ADMIN.getCode().equals(roleEnum.getCode()) && !RoleEnum.FINANCE_USER.getCode().equals(roleEnum.getCode())){
  484 + queryWrapper.eq(RichTextContentDO::getIsTrackerBlock, true);
  485 + }
  486 + if(Objects.nonNull(richTextListQueryPageVO.getStatus())){
  487 + if(ApplyStatusEnum.AUDIT_PASS.getStatus().equals(richTextListQueryPageVO.getStatus())){
  488 + queryWrapper.eq(RichTextContentDO::getStatus, richTextListQueryPageVO.getStatus());
  489 + }else{
  490 + queryWrapper.in(RichTextContentDO::getStatus, ApplyStatusEnum.AUDIT_REFUSE.getStatus(), ApplyStatusEnum.WAIT_AUDIT.getStatus());
  491 + }
  492 + }
  493 + //当用户查询的数据是以逗号分隔时,使用 MATCH AGAINST 。
  494 + if (StringUtils.isNotBlank(richTextListQueryPageVO.getContentText()) &&
  495 + (richTextListQueryPageVO.getContentText().contains(",") || richTextListQueryPageVO.getContentText().contains(","))) {
  496 + List<String> keywordList = Arrays.stream(richTextListQueryPageVO.getContentText().split("[,,]"))
  497 + .map(String::trim)
  498 + .filter(StringUtils::isNotEmpty)
  499 + .distinct()
  500 + .collect(Collectors.toList());
  501 + if (!keywordList.isEmpty()) {
  502 + String searchKeywords = String.join(" ", keywordList);
  503 + //必须给context创建全文索引。
  504 + queryWrapper.apply("MATCH(content_text) AGAINST({0} IN BOOLEAN MODE) ", searchKeywords);
  505 +
  506 + }
  507 + } else {
  508 + queryWrapper.like(StringUtils.isNotBlank(richTextListQueryPageVO.getContentText()), RichTextContentDO::getContentText, richTextListQueryPageVO.getContentText());
  509 + }
  510 + queryWrapper.like(StringUtils.isNotBlank(richTextListQueryPageVO.getTitle()), RichTextContentDO::getTitle, richTextListQueryPageVO.getTitle());
  511 +
  512 + queryWrapper.orderByDesc(RichTextContentDO::getId);
  513 + return queryWrapper;
  514 + }
  515 +}
... ...
src/main/resources/mapper/InvoiceBillOrderMapper.xml
... ... @@ -99,6 +99,7 @@
99 99 i.deduct_amount AS invoiceDeductAmount, -- 扣款金额
100 100 i.notes AS invoiceNotes, -- invoice备注
101 101 i.invoice_deduct_url_status AS invoiceDeductUrlStatus,
  102 + i.rich_text_id AS invoiceRichTextId,
102 103 -- 生产科付款信息
103 104 p.id AS checkId,
104 105 p.check_no AS checkNo, -- checkNo编号
... ... @@ -115,7 +116,8 @@
115 116 p.deduct_url AS checkDeductUrl, -- 扣款单
116 117 p.notes AS checkNotes, -- checkNo备注
117 118 p.invoice_url AS checkInvoiceUrl, -- 发票
118   - p.check_deduct_url_status AS checkDeductUrlStatus
  119 + p.check_deduct_url_status AS checkDeductUrlStatus,
  120 + p.rich_text_id AS checkRichTextId
119 121 FROM order_base_info o
120 122 LEFT JOIN invoice_bill_order AS i
121 123 ON o.id = i.order_id AND i.enable_flag = 10
... ...
src/main/resources/mapper/RichTextConteMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +<mapper namespace="com.order.erp.mapper.order.RichTextContentMapper">
  4 + <select id="queryTitle" resultType="com.order.erp.domain.vo.order.RichTextAllTitleResultVO">
  5 + SELECT id, title, deduct_amount , is_template
  6 + FROM rich_text_content
  7 + <where>
  8 + enable_flag = 10
  9 + <if test="richTextContentVO.title != null and richTextContentVO.title != ''">
  10 + AND title like concat('%',#{richTextContentVO.title},'%')
  11 + </if>
  12 + <if test="richTextContentVO.isTrackerBlock != null">
  13 + AND is_tracker_block = #{richTextContentVO.isTrackerBlock}
  14 + </if>
  15 + AND status = 10
  16 + </where>
  17 + </select>
  18 +</mapper>
... ...