lfx 1 년 전
커밋
40803f50f8
100개의 변경된 파일1999개의 추가작업 그리고 0개의 파일을 삭제
  1. 77 0
      mjava-kuaikeli/pom.xml
  2. 19 0
      mjava-kuaikeli/src/main/java/com/malk/kuaikeli/KuaikeliApplication.java
  3. 20 0
      mjava-kuaikeli/src/main/java/com/malk/kuaikeli/config/MybatisPlusConfig.java
  4. 59 0
      mjava-kuaikeli/src/main/java/com/malk/kuaikeli/controller/CdTestController.java
  5. 137 0
      mjava-kuaikeli/src/main/java/com/malk/kuaikeli/controller/KKLController.java
  6. 66 0
      mjava-kuaikeli/src/main/java/com/malk/kuaikeli/controller/SupplierMaterialController.java
  7. 150 0
      mjava-kuaikeli/src/main/java/com/malk/kuaikeli/entity/MaterialDetail.java
  8. 30 0
      mjava-kuaikeli/src/main/java/com/malk/kuaikeli/entity/Pricing.java
  9. 165 0
      mjava-kuaikeli/src/main/java/com/malk/kuaikeli/entity/SupplierMaterial.java
  10. 90 0
      mjava-kuaikeli/src/main/java/com/malk/kuaikeli/listener/SupplierMaterialDataListener.java
  11. 11 0
      mjava-kuaikeli/src/main/java/com/malk/kuaikeli/mapper/MaterialDetailMapper.java
  12. 19 0
      mjava-kuaikeli/src/main/java/com/malk/kuaikeli/mapper/SupplierMaterialMapper.java
  13. 55 0
      mjava-kuaikeli/src/main/java/com/malk/kuaikeli/schedule/ScheduleTask.java
  14. 24 0
      mjava-kuaikeli/src/main/java/com/malk/kuaikeli/service/KKLService.java
  15. 29 0
      mjava-kuaikeli/src/main/java/com/malk/kuaikeli/service/SupplierMaterialService.java
  16. 438 0
      mjava-kuaikeli/src/main/java/com/malk/kuaikeli/service/impl/KKLImplService.java
  17. 292 0
      mjava-kuaikeli/src/main/java/com/malk/kuaikeli/service/impl/SupplierMaterialServiceImpl.java
  18. 36 0
      mjava-kuaikeli/src/main/resources/application-dev.yml
  19. 30 0
      mjava-kuaikeli/src/main/resources/application-prod.yml
  20. 17 0
      mjava-kuaikeli/src/main/resources/application.yml
  21. 61 0
      mjava-kuaikeli/src/main/resources/logback-spring.xml
  22. 51 0
      mjava-kuaikeli/src/main/resources/mapper/SupplierMaterialMapper.xml
  23. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/app.76c35fec.css
  24. BIN
      mjava-kuaikeli/src/main/resources/static/web/css/app.76c35fec.css.gz
  25. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/chunk-1a891981.86df4f93.css
  26. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/chunk-1bf96e69.8bd88a30.css
  27. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/chunk-2628d9a4.9c878275.css
  28. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/chunk-2e5c0360.eccac5fa.css
  29. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/chunk-2ef2613e.3df695f6.css
  30. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/chunk-3cdd93cb.b9fbbcdc.css
  31. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/chunk-4a1768fa.2d03b50e.css
  32. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/chunk-7e06598d.c94e184e.css
  33. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/chunk-a3d3160e.fb1aa985.css
  34. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/chunk-b443f318.cc854d2e.css
  35. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/chunk-c6c29e7e.091c991f.css
  36. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/chunk-d0213336.0ad54735.css
  37. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/chunk-d76bc3fa.b590e7f2.css
  38. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/chunk-ea283b04.e0e31ac8.css
  39. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/npm.element-ui.c3ebd9d9.css
  40. BIN
      mjava-kuaikeli/src/main/resources/static/web/css/npm.element-ui.c3ebd9d9.css.gz
  41. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/npm.quasar.490020f1.css
  42. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/npm.swiper.b050859e.css
  43. BIN
      mjava-kuaikeli/src/main/resources/static/web/css/npm.swiper.b050859e.css.gz
  44. 1 0
      mjava-kuaikeli/src/main/resources/static/web/css/npm.vant.ce05bcc0.css
  45. BIN
      mjava-kuaikeli/src/main/resources/static/web/css/npm.vant.ce05bcc0.css.gz
  46. BIN
      mjava-kuaikeli/src/main/resources/static/web/favicon.ico
  47. BIN
      mjava-kuaikeli/src/main/resources/static/web/fonts/element-icons.535877f5.woff
  48. BIN
      mjava-kuaikeli/src/main/resources/static/web/fonts/element-icons.732389de.ttf
  49. BIN
      mjava-kuaikeli/src/main/resources/static/web/fonts/flUhRq6tzZclQEJ-Vdg-IuiaDsNa.49f2e1a9.woff
  50. BIN
      mjava-kuaikeli/src/main/resources/static/web/fonts/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.37ce905a.woff2
  51. BIN
      mjava-kuaikeli/src/main/resources/static/web/img/404.0a45bba9.jpg
  52. BIN
      mjava-kuaikeli/src/main/resources/static/web/img/banner1-mob.43da6aa9.png
  53. BIN
      mjava-kuaikeli/src/main/resources/static/web/img/banner1.4c00ae4d.png
  54. BIN
      mjava-kuaikeli/src/main/resources/static/web/img/banner2-mob.732a8a2f.jpg
  55. BIN
      mjava-kuaikeli/src/main/resources/static/web/img/banner2.a04345c0.jpg
  56. BIN
      mjava-kuaikeli/src/main/resources/static/web/img/bg-login-mob.2c5c69fe.jpeg
  57. BIN
      mjava-kuaikeli/src/main/resources/static/web/img/logo-t.ebbe5a59.png
  58. BIN
      mjava-kuaikeli/src/main/resources/static/web/img/logo.4551336d.png
  59. BIN
      mjava-kuaikeli/src/main/resources/static/web/img/sample-media.765b7619.jpg
  60. BIN
      mjava-kuaikeli/src/main/resources/static/web/img/sample.791ebe2a.jpg
  61. BIN
      mjava-kuaikeli/src/main/resources/static/web/img/solution-media.316c8dfe.jpg
  62. BIN
      mjava-kuaikeli/src/main/resources/static/web/img/solution.de6bd68f.jpg
  63. 46 0
      mjava-kuaikeli/src/main/resources/static/web/index.html
  64. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/app.44cd3cec621a64ea50dd.0.1.0.js
  65. BIN
      mjava-kuaikeli/src/main/resources/static/web/js/app.44cd3cec621a64ea50dd.0.1.0.js.gz
  66. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/app.d2ec944bcc584b92f92b.0.1.0.js
  67. BIN
      mjava-kuaikeli/src/main/resources/static/web/js/app.d2ec944bcc584b92f92b.0.1.0.js.gz
  68. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-1a891981.6916d3e2acc7e84eb131.0.1.0.js
  69. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-1bf96e69.69c12d4e4345fd1b6b7e.0.1.0.js
  70. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-2628d9a4.18c9777608aba980dbec.0.1.0.js
  71. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-2d0b68f8.26f922156e6856276031.0.1.0.js
  72. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-2d0c573b.519f6e78125f4085bff5.0.1.0.js
  73. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-2d20f795.b7bd63c92ad737e8fc00.0.1.0.js
  74. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-2d237b24.a03e96be69d3ba31b703.0.1.0.js
  75. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-2e5c0360.5fba8f522cb77554e1ec.0.1.0.js
  76. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-2ef2613e.12a3d8db8b3be171ba37.0.1.0.js
  77. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-3cdd93cb.60f0ba48e64c966ab9db.0.1.0.js
  78. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-4a1768fa.232849728fb437a571ea.0.1.0.js
  79. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-7e06598d.19378760d9d2f7ee0ed3.0.1.0.js
  80. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-a3d3160e.0c5a62c4dcd3ea1f92ff.0.1.0.js
  81. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-b443f318.00d2747b8c1ab44c715e.0.1.0.js
  82. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-c6c29e7e.90a2005df26e713a0839.0.1.0.js
  83. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-d0213336.c3d7d3d2d6c3c127e0b2.0.1.0.js
  84. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-d76bc3fa.8a81344628b4810e79fa.0.1.0.js
  85. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-ea283b04.140828ef0b43fa5c77d9.0.1.0.js
  86. 2 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-vendors.1634155197efea3c3a4a.0.1.0.js
  87. 14 0
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-vendors.1634155197efea3c3a4a.0.1.0.js.LICENSE.txt
  88. BIN
      mjava-kuaikeli/src/main/resources/static/web/js/chunk-vendors.1634155197efea3c3a4a.0.1.0.js.gz
  89. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/npm.async-validator.ca9586e38d471d704f8c.0.1.0.js
  90. BIN
      mjava-kuaikeli/src/main/resources/static/web/js/npm.async-validator.ca9586e38d471d704f8c.0.1.0.js.gz
  91. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/npm.axios.1d401cc7c7d6f4c6ed74.0.1.0.js
  92. BIN
      mjava-kuaikeli/src/main/resources/static/web/js/npm.axios.1d401cc7c7d6f4c6ed74.0.1.0.js.gz
  93. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/npm.babel-runtime.f1df8292bbe4d97d3934.0.1.0.js
  94. BIN
      mjava-kuaikeli/src/main/resources/static/web/js/npm.babel-runtime.f1df8292bbe4d97d3934.0.1.0.js.gz
  95. 1 0
      mjava-kuaikeli/src/main/resources/static/web/js/npm.core-js.86f5d82bef78e8377235.0.1.0.js
  96. BIN
      mjava-kuaikeli/src/main/resources/static/web/js/npm.core-js.86f5d82bef78e8377235.0.1.0.js.gz
  97. 2 0
      mjava-kuaikeli/src/main/resources/static/web/js/npm.crypto-js.11b1e812fb36f828e617.0.1.0.js
  98. 16 0
      mjava-kuaikeli/src/main/resources/static/web/js/npm.crypto-js.11b1e812fb36f828e617.0.1.0.js.LICENSE.txt
  99. BIN
      mjava-kuaikeli/src/main/resources/static/web/js/npm.crypto-js.11b1e812fb36f828e617.0.1.0.js.gz
  100. 0 0
      mjava-kuaikeli/src/main/resources/static/web/js/npm.dom7.22141fb3b93f945443bc.0.1.0.js

+ 77 - 0
mjava-kuaikeli/pom.xml

@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.2.0.RELEASE</version> <!-- 使用最新的稳定版或其他适用版本 -->
+    </parent>
+
+    <groupId>com.malk</groupId>
+    <artifactId>mjava-kuaikeli</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.5.3.2</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.malk</groupId>
+            <artifactId>base</artifactId>
+            <version>1.1-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>io.github.biezhi</groupId>
+            <artifactId>TinyPinyin</artifactId>
+            <version>2.0.3.RELEASE</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>kuaikeli</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                    <encoding>UTF-8</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <executable>true</executable>
+                    <includeSystemScope>true</includeSystemScope>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 19 - 0
mjava-kuaikeli/src/main/java/com/malk/kuaikeli/KuaikeliApplication.java

@@ -0,0 +1,19 @@
+package com.malk.kuaikeli;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication(scanBasePackages = {"com.malk"})
+@MapperScan("com.malk.kuaikeli.mapper")
+public class KuaikeliApplication {
+
+    public static void main(String[] args) {
+        try {
+            SpringApplication.run(KuaikeliApplication.class,args);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+}

+ 20 - 0
mjava-kuaikeli/src/main/java/com/malk/kuaikeli/config/MybatisPlusConfig.java

@@ -0,0 +1,20 @@
+package com.malk.kuaikeli.config;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class MybatisPlusConfig {
+
+    @Bean
+    public MybatisPlusInterceptor mybatisPlusInterceptor() {
+        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//如果配置多个插件,切记分页最后添加
+        //interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); 如果有多数据源可以不配具体类型 否则都建议配上具体的DbType
+        return interceptor;
+    }
+
+}

+ 59 - 0
mjava-kuaikeli/src/main/java/com/malk/kuaikeli/controller/CdTestController.java

@@ -0,0 +1,59 @@
+package com.malk.kuaikeli.controller;
+
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.fastjson.JSONObject;
+import com.malk.kuaikeli.entity.SupplierMaterial;
+import com.malk.kuaikeli.listener.SupplierMaterialDataListener;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+import com.malk.server.common.McR;
+import com.malk.service.aliwork.YDClient;
+import com.malk.service.aliwork.YDService;
+import com.malk.service.dingtalk.DDClient;
+import com.malk.utils.UtilMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/test")
+public class CdTestController {
+
+    @Autowired
+    private DDClient ddClient;
+    @Autowired
+    private YDClient ydClient;
+    @Value("${server.port}")
+    private String port;
+
+    @GetMapping("/hello")
+    public McR hello(){
+        return McR.success("Hello "+ port);
+    }
+
+    @GetMapping("/dd")
+    public McR dd(){
+        return McR.success(ddClient.getAccessToken());
+    }
+
+    @PostMapping("/upload")
+    public McR upload(MultipartFile file) throws IOException {
+        System.out.println("2222222222222222");
+
+        return McR.success();
+    }
+
+    @PostMapping("/test")
+    public McR test(@RequestBody Map param){
+        // FINST-J7666B91556KOPSCBKY425M8C73I3GCT10VULEQ1
+        String id= UtilMap.getString(param,"id");
+        Object obj= ydClient.queryData(YDParam.builder().searchCondition(
+                JSONObject.toJSONString(UtilMap.map("textField_llkb7kd2",""))).build(), YDConf.FORM_QUERY.retrieve_id).getData();
+
+        return McR.success();
+    }
+}

+ 137 - 0
mjava-kuaikeli/src/main/java/com/malk/kuaikeli/controller/KKLController.java

@@ -0,0 +1,137 @@
+package com.malk.kuaikeli.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.malk.kuaikeli.service.KKLService;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+import com.malk.server.common.McR;
+import com.malk.utils.UtilMap;
+import com.malk.utils.UtilServlet;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+/**
+ * 错误抛出与拦截详见 CatchException
+ */
+@Slf4j
+@RestController
+@RequestMapping()
+public class KKLController {
+
+    @Autowired
+    private KKLService kklService;
+
+    /**
+     * [动态] 发起单据, 分供应商进行流程推送
+     */
+    @PostMapping("supplier")
+    McR supplier(HttpServletRequest request) {
+
+        Map data = UtilServlet.getParamMap(request);
+        log.info("supplier, {}", JSON.toJSONString(data));
+
+        kklService.matchSupplier(data);
+        return McR.success();
+    }
+
+    /**
+     * 菜单计划, 编辑校验
+     * -
+     * 前端提交动作: 校验是否审批通过, 是否当日之前计划, 是否当日且在16点及以后时间, 均不允许提交
+     * 后端校验返回、加任何产品都要走审批,减少20%以内直接过,每一个原材料
+     */
+    @PostMapping("validate")
+    McR validate(@RequestBody Map data) {
+
+        log.info("validate, {}", JSON.toJSONString(data));
+
+        boolean approve=kklService.validateApprove(data);
+        if(approve){
+            kklService.updateState(UtilMap.getString(data,"poid"));
+        }
+        return McR.success();
+    }
+
+    /**
+     * 定价单: 项目点 & 供应商大类, 数据匹配
+     */
+    @PostMapping("service")
+    McR service(HttpServletRequest request) {
+
+        Map data = UtilServlet.getParamMap(request);
+        log.info("service, {}", JSON.toJSONString(data));
+
+        kklService.serviceRate(data);
+        return McR.success();
+    }
+
+    /**
+     * 物料档案: 价格调整
+     */
+    @PostMapping("adjust")
+    McR adjust(HttpServletRequest request) {
+
+        Map data = UtilServlet.getParamMap(request);
+        log.info("adjust, {}", JSON.toJSONString(data));
+
+        kklService.adjustCost(data);
+        return McR.success();
+    }
+
+    /**
+     * 供应商原材料档案: 新增匹配
+     * 更新定价单
+     */
+    @PostMapping("addition")
+    McR addition(HttpServletRequest request) {
+
+        Map data = UtilServlet.getParamMap(request);
+        log.info("addition, {}", JSON.toJSONString(data));
+
+        kklService.adjustCost(data);
+        return McR.success();
+    }
+
+
+    /***
+     * 新增定价单
+     * @param request
+     * @return
+     */
+    @PostMapping("updateDjd")
+    McR updateDjd(HttpServletRequest request) {
+
+        Map data = UtilServlet.getParamMap(request);
+        log.info("addition, {}", JSON.toJSONString(data));
+
+        kklService.additionMaterial(data);
+        return McR.success();
+    }
+
+
+    /**
+     * 周日同步更新价格
+     */
+    @PostMapping("sync")
+    McR sync() {
+        log.info("sync price");
+        kklService.syncPrice();
+        return McR.success();
+    }
+
+    
+    @PostMapping("test")
+    McR test(HttpServletRequest request) {
+        Map data = UtilServlet.getParamMap(request);
+        log.info("xxxx, {}", data);
+        return McR.success();
+    }
+
+}

+ 66 - 0
mjava-kuaikeli/src/main/java/com/malk/kuaikeli/controller/SupplierMaterialController.java

@@ -0,0 +1,66 @@
+package com.malk.kuaikeli.controller;
+
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.malk.kuaikeli.entity.SupplierMaterial;
+import com.malk.kuaikeli.listener.SupplierMaterialDataListener;
+import com.malk.kuaikeli.mapper.SupplierMaterialMapper;
+import com.malk.kuaikeli.service.SupplierMaterialService;
+import com.malk.server.common.McR;
+import com.malk.server.common.Page;
+import com.malk.utils.PublicUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/***
+ * 供应商原材料
+ */
+@RestController
+@RequestMapping("/suppliermaterial")
+public class SupplierMaterialController {
+
+    @Autowired
+    private SupplierMaterialService supplierMaterialService;
+
+    @PostMapping("/upload")
+    public McR upload(@RequestParam(value="file")MultipartFile file) throws IOException {
+        if(file.isEmpty()||file.getSize()<1){
+            return McR.errorParam("文件不存在!");
+        }
+        if(!file.getOriginalFilename().endsWith("xlsx")&&!file.getOriginalFilename().endsWith("xls")) {
+            return McR.errorParam("文件格式错误!");
+        }
+        supplierMaterialService.uploadData(file);
+        supplierMaterialService.sync();// 异步执行
+        return McR.success();
+    }
+
+    @GetMapping("/sync")
+    public McR sync(){
+        supplierMaterialService.sync();
+        return McR.success();
+    }
+
+    @PostMapping("/projectSupplierChange")
+    public McR projectSupplierChange(@RequestBody JSONObject param) throws IOException {
+        if(PublicUtil.isNull(param,"projectId","oldId","newId","newName")){
+            return McR.errorNullPointer();
+        }
+        supplierMaterialService.projectSupplierChange(param.getString("projectId"),param.getString("oldId"),param.getString("newId"),param.getString("newName"));
+        return McR.success();
+    }
+
+    @GetMapping("/getList")
+    public McR selectList(@RequestParam(defaultValue = "1") Integer current,
+                          @RequestParam(defaultValue = "10") Integer size){
+        return supplierMaterialService.getList(current,size);
+    }
+
+
+}

+ 150 - 0
mjava-kuaikeli/src/main/java/com/malk/kuaikeli/entity/MaterialDetail.java

@@ -0,0 +1,150 @@
+package com.malk.kuaikeli.entity;
+
+import cn.hutool.core.annotation.Alias;
+import cn.hutool.core.bean.BeanUtil;
+import com.alibaba.excel.annotation.format.DateTimeFormat;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.malk.utils.UtilDateTime;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Map;
+
+@Data
+@EqualsAndHashCode
+@TableName("t_material_detail")
+public class MaterialDetail {
+
+    // ID
+//    @TableId(value = "id",type = IdType.INPUT)
+//    private String id;
+
+    // 供应商编号
+    @Alias("textField_llzzbyj1")
+    private String supplierId;
+
+    // 供应商名称
+    @Alias("textField_lmsli3bq")
+    private String supplierName;
+
+    // 项目编号
+    @Alias("textField_llm1vtjm")
+    private String projectId;
+
+    // 项目名称
+    @Alias("textField_loy1ep8r")
+    private String projectName;
+
+    // 物品名称
+    @Alias("textField_llkb7kd1")
+    private String materialName;
+
+    // 物品编号
+    @Alias("textField_llkb7kd2")
+    private String materialId;
+
+    // 单位
+    @Alias("textField_llkb7kd3")
+    private String unit;
+
+    // 规格
+    @Alias("textField_llkb7kd4")
+    private String specs;
+
+    // 第一分类
+    @Alias("selectField_llkb7kd5")
+    private String classifyOne;
+
+    // 第二分类
+    @Alias("selectField_llkk6cms")
+    private String classifyTwo;
+
+    // 服务费率
+    @Alias("numberField_llkb7kcy")
+    private String rate;
+
+    // 成本单价
+    @Alias("numberField_llkknd6g")
+    private String unitPrice;
+
+    // 供货价
+    @Alias("numberField_llkknd6h")
+    private String supplyPrice;
+
+    // 下周服务费率
+    @Alias("numberField_lpalgz04")
+    private String rateNext;
+
+    // 下周成本单价
+    @Alias("numberField_lpalgz05")
+    private String unitPriceNext;
+
+    // 下周供货价
+    @Alias("numberField_lpalgz0a")
+    private String supplyPriceNext;
+
+    // 其他信息
+    @Alias("textareaField_lllnl6yr")
+    private String otherInfo;
+
+    // 图片
+//    @Alias("imageField_lllnl6ys")
+    private String img;
+
+    // 品牌
+    @Alias("textField_lmkfg67e")
+    private String brand;
+
+    // 状态
+    @Alias("textField_lm4lxur8")
+    private String state="已启用";
+
+    // 期限
+    @DateTimeFormat("yyyy-MM-dd HH:mm:ss")
+    @Alias("dateField_lm4lxur7")
+    private String term;
+
+    // 包装数量
+    @Alias("numberField_lnrzzg03")
+    private String packingNumber;
+
+    // 包装单位
+    @Alias("textField_lnrzzg04")
+    private String packingUnit;
+
+    // 创建日期
+    private String createDateTime;
+
+    // 更新日期
+    private String updateDateTime;
+
+    private String formInstId;
+
+    public MaterialDetail(){}
+
+    public static MaterialDetail toBean(Map yidaFormData){
+        MaterialDetail materialDetail=BeanUtil.mapToBean(yidaFormData,MaterialDetail.class,false);
+        materialDetail.setTerm(UtilDateTime.getLocalDateTimeFromTimestamp(Long.parseLong(materialDetail.getTerm())).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        return materialDetail;
+    }
+
+    public Map toYidaFormDataMap(){
+        Map map=BeanUtil.beanToMap(this);
+        // 时间处理
+        map.put("dateField_lm4lxur7", UtilDateTime.getLocalDateTimeTimeStamp(UtilDateTime.parseLocalDateTime(this.term)));
+        return map;
+    }
+
+    public MaterialDetail create(){
+        this.createDateTime = (LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
+        return this;
+    }
+
+    public MaterialDetail update(){
+        this.updateDateTime = (LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
+        return this;
+    }
+
+}

+ 30 - 0
mjava-kuaikeli/src/main/java/com/malk/kuaikeli/entity/Pricing.java

@@ -0,0 +1,30 @@
+package com.malk.kuaikeli.entity;
+
+
+import cn.hutool.core.annotation.Alias;
+import lombok.Data;
+
+import java.util.Map;
+
+/***
+ * 定价单
+ */
+@Data
+public class Pricing {
+
+    // 供应商编号
+    @Alias("textField_llzzbai8")
+    private String supplierId;
+
+    // 项目编号
+    @Alias("textField_lllovku7")
+    private String projectId;
+
+    // 项目名称
+    @Alias("textField_loy1ep8r")
+    private String projectName;
+
+    // 相关信息
+    private Map<String,String> rateMap;
+
+}

+ 165 - 0
mjava-kuaikeli/src/main/java/com/malk/kuaikeli/entity/SupplierMaterial.java

@@ -0,0 +1,165 @@
+package com.malk.kuaikeli.entity;
+
+import cn.hutool.core.annotation.Alias;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.date.LocalDateTimeUtil;
+import cn.hutool.poi.excel.ExcelReader;
+import cn.hutool.poi.excel.ExcelUtil;
+import com.alibaba.excel.annotation.format.DateTimeFormat;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.malk.server.aliwork.YDConf;
+import com.malk.utils.UtilDateTime;
+import com.malk.utils.UtilMap;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+// 供应商原材料
+@Data
+@EqualsAndHashCode
+@TableName("t_supplier_material")
+public class SupplierMaterial {
+
+    // 供应商
+    @Alias("associationFormField_lphya7cq")
+    private String supplier;
+
+    // 供应商编号
+    @Alias("textField_llzzbyj1")
+    private String supplierId;
+
+    // 供应商名称
+    @Alias("textField_lmsli3bq")
+    private String supplierName;
+
+    // 物品名称
+    @Alias("textField_llkb7kd1")
+    private String materialName;
+
+    // 物品编号
+    @TableId(value = "material_id",type = IdType.INPUT)
+    @Alias("textField_llkb7kd2")
+    private String materialId;
+
+    // 单位
+    @Alias("textField_llkb7kd3")
+    private String unit;
+
+    // 规格
+    @Alias("textField_llkb7kd4")
+    private String specs;
+
+    // 第一分类
+    @Alias("selectField_llkb7kd5")
+    private String classifyOne;
+
+    // 第二分类
+    @Alias("selectField_llkk6cms")
+    private String classifyTwo;
+
+    // 成本单价
+    @Alias("numberField_llkknd6g")
+    private String unitPrice;
+
+    // 下周成本单价
+    @Alias("numberField_lpalgz05")
+    private String unitPriceNext;
+
+    // 其他信息
+    @Alias("textareaField_lllnl6yr")
+    private String otherInfo;
+
+    // 图片
+//    @Alias("imageField_lllnl6ys")
+    private String img;
+
+    // 品牌
+    @Alias("textField_lmkfg67e")
+    private String brand;
+
+    // 状态
+    @Alias("textField_lm4lxur8")
+    private String state="已启用";
+
+    // 期限
+    @DateTimeFormat("yyyy-MM-dd HH:mm:ss")
+    @Alias("dateField_lm4lxur7")
+    private String term;
+
+    // 包装数量
+    @Alias("numberField_lnrzzg03")
+    private String packingNumber;
+
+    // 包装单位
+    @Alias("textField_lnrzzg04")
+    private String packingUnit;
+
+    // 是否需要提供资质
+    @Alias("textField_loe2rojc")
+    private String needQualification;
+
+    // 是否已提供资质 是/否
+    @Alias("radioField_lpt4h37t")
+    private String provideQualification;
+
+    // 原材料资质
+//    @Alias("attachmentField_loe2rojd")
+    private String qualification;
+
+    // 资质到期日期
+    @DateTimeFormat("yyyy-MM-dd HH:mm:ss")
+    @Alias("dateField_lpt4h37y")
+    private String qualificationExpireDate;
+
+    private String formInstId;
+
+    // 是否需要同步到宜搭
+    private String isNeedSyncYd;
+
+    // 同步到中间表数量
+    private String materialDetailNumber;
+
+    // 创建日期
+    private String createDateTime;
+
+    // 更新日期
+    private String updateDateTime;
+
+    // 错误消息
+    private String errorMsg;
+
+    public SupplierMaterial(){}
+
+    public static SupplierMaterial toBean(Map yidaFormData){
+        return BeanUtil.mapToBean(yidaFormData,SupplierMaterial.class,false);
+    }
+
+    public Map toYidaFormDataMap(){
+        Map map=BeanUtil.beanToMap(this);
+        // 时间处理
+        map.put("dateField_lpt4h37y", UtilDateTime.getLocalDateTimeTimeStamp(UtilDateTime.parseLocalDateTime(this.qualificationExpireDate)));
+        map.put("dateField_lm4lxur7", UtilDateTime.getLocalDateTimeTimeStamp(UtilDateTime.parseLocalDateTime(this.term)));
+        // 关联表单处理
+        String instId=supplier.substring(supplier.indexOf("[FINST")+1,supplier.length()-1);
+        map.put("associationFormField_lphya7cq", Arrays.asList(UtilMap.map("title, instanceId, appType, formUuid, formType",supplierName,instId, "APP_OHSG8KMIP9SGXV32XUQJ","FORM-L8966281A3LDP5UX77OYM6LBPEUM3TODBOLLL0","receipt")));
+        return map;
+    }
+
+    public SupplierMaterial create(){
+        this.isNeedSyncYd="是";
+        this.createDateTime = (LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
+        return this;
+    }
+
+    public SupplierMaterial update(){
+        this.updateDateTime = (LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
+        return this;
+    }
+}

+ 90 - 0
mjava-kuaikeli/src/main/java/com/malk/kuaikeli/listener/SupplierMaterialDataListener.java

@@ -0,0 +1,90 @@
+package com.malk.kuaikeli.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.alibaba.fastjson.JSON;
+import com.malk.kuaikeli.entity.SupplierMaterial;
+import com.malk.kuaikeli.mapper.SupplierMaterialMapper;
+import com.malk.kuaikeli.service.SupplierMaterialService;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.ArrayList;
+import java.util.List;
+
+// 有个很重要的点 SupplierMaterialListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
+@Slf4j
+public class SupplierMaterialDataListener extends AnalysisEventListener<SupplierMaterial> {
+
+    /**
+     * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
+     */
+    private static final int BATCH_COUNT = 5;
+    List<SupplierMaterial> list = new ArrayList<SupplierMaterial>();
+
+    private SupplierMaterialMapper supplierMaterialMapper;
+
+    public SupplierMaterialDataListener() {
+    }
+
+    /**
+     * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
+     */
+    public SupplierMaterialDataListener(SupplierMaterialMapper supplierMaterialMapper) {
+        this.supplierMaterialMapper = supplierMaterialMapper;
+    }
+
+    /**
+     * 这个每一条数据解析都会来调用
+     *
+     * @param data
+     *            one row value. Is is same as {@link AnalysisContext#readRowHolder()}
+     * @param context
+     */
+    @Override
+    public void invoke(SupplierMaterial data, AnalysisContext context) {
+        log.info("解析到一条数据:{}", JSON.toJSONString(data));
+        list.add(data);
+        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
+        if (list.size() >= BATCH_COUNT) {
+            saveData();
+            // 存储完成清理 list
+            list.clear();
+        }
+    }
+
+    /**
+     * 所有数据解析完成了 都会来调用
+     *
+     * @param context
+     */
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext context) {
+        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
+        saveData();
+        log.info("所有数据解析完成!");
+    }
+
+    /**
+     * 加上存储数据库
+     */
+    private void saveData() {
+        log.info("{}条数据,开始存储数据库!", list.size());
+//        supplierMaterialService.saveOrUpdateBatch(list);
+        for(SupplierMaterial supplierMaterial:list){
+            SupplierMaterial old = supplierMaterialMapper.selectById(supplierMaterial.getMaterialId());
+            if(old!=null){
+                if(!old.getUnitPrice().equals(supplierMaterial.getUnitPrice())){
+                    old.setIsNeedSyncYd("是");
+                    old.setUnitPrice(supplierMaterial.getUnitPrice());
+                    log.info("成本单价修改。数据:{}",old);
+                    supplierMaterialMapper.updateById(supplierMaterial.update());
+                }else{
+                    log.info("成本单价相同,跳过。数据:{}",supplierMaterial);
+                }
+            }else{
+                supplierMaterialMapper.insert(supplierMaterial.create());
+            }
+        }
+        log.info("存储数据库成功!");
+    }
+}

+ 11 - 0
mjava-kuaikeli/src/main/java/com/malk/kuaikeli/mapper/MaterialDetailMapper.java

@@ -0,0 +1,11 @@
+package com.malk.kuaikeli.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.malk.kuaikeli.entity.MaterialDetail;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+@Repository
+@Mapper
+public interface MaterialDetailMapper extends BaseMapper<MaterialDetail> {
+}

+ 19 - 0
mjava-kuaikeli/src/main/java/com/malk/kuaikeli/mapper/SupplierMaterialMapper.java

@@ -0,0 +1,19 @@
+package com.malk.kuaikeli.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.malk.kuaikeli.entity.SupplierMaterial;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+@Mapper
+public interface SupplierMaterialMapper extends BaseMapper<SupplierMaterial> {
+
+    int updateUnitPrice();
+
+    List<SupplierMaterial> selectListForCopy(@Param("project_id") String project_id,@Param("supplier_id") String supplier_id);
+
+}

+ 55 - 0
mjava-kuaikeli/src/main/java/com/malk/kuaikeli/schedule/ScheduleTask.java

@@ -0,0 +1,55 @@
+package com.malk.kuaikeli.schedule;
+
+import com.malk.kuaikeli.service.KKLService;
+import com.malk.kuaikeli.service.SupplierMaterialService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+
+/**
+ * @EnableScheduling 开启定时任务 [配置参考McScheduleTask]
+ */
+@Slf4j
+@Configuration
+@EnableScheduling
+@ConditionalOnProperty(name = {"enable.scheduling"})
+public class ScheduleTask {
+
+//    @Autowired
+//    private KKLService kklService;
+
+    @Autowired
+    private SupplierMaterialService supplierMaterialService;
+
+    /**
+     * 周一凌晨1点同步 (即周日后生效)
+     */
+    @Scheduled(cron = "0 0 1 * * ?")
+    public void syncDingTalkFailedList() {
+        log.info("开始同步原材料下周单价到本周");
+        try {
+//            kklService.syncPrice();
+            supplierMaterialService.syncPrice();
+        } catch (Exception e) {
+            // 记录错误信息
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 每10分钟同步
+     */
+    @Scheduled(cron = "0 0/10 * * * ?")
+    public void sync() {
+        log.info("开始同步供应商原材料");
+        try {
+            supplierMaterialService.sync();
+        } catch (Exception e) {
+            // 记录错误信息
+            e.printStackTrace();
+        }
+    }
+}

+ 24 - 0
mjava-kuaikeli/src/main/java/com/malk/kuaikeli/service/KKLService.java

@@ -0,0 +1,24 @@
+package com.malk.kuaikeli.service;
+
+import org.springframework.scheduling.annotation.Async;
+
+import java.util.Map;
+
+public interface KKLService {
+
+    void matchSupplier(Map data);
+
+    boolean validateApprove(Map data);
+
+    @Async
+    void updateState(String id);
+
+    @Async
+    void serviceRate(Map data);
+
+    void adjustCost(Map data);
+
+    void additionMaterial(Map data);
+
+    void syncPrice();
+}

+ 29 - 0
mjava-kuaikeli/src/main/java/com/malk/kuaikeli/service/SupplierMaterialService.java

@@ -0,0 +1,29 @@
+package com.malk.kuaikeli.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.malk.kuaikeli.entity.SupplierMaterial;
+import com.malk.server.common.McR;
+import org.springframework.web.multipart.MultipartFile;
+
+public interface SupplierMaterialService extends IService<SupplierMaterial> {
+
+    void uploadData(MultipartFile file);
+
+    /***
+     * 同步
+     */
+    void sync();
+
+    /***
+     * 查询列表
+     * @param current
+     * @param size
+     * @return
+     */
+    McR getList(Integer current,Integer size);
+
+    void syncPrice();
+
+    void projectSupplierChange(String projectId,String oldId,String newId,String newName);
+
+}

+ 438 - 0
mjava-kuaikeli/src/main/java/com/malk/kuaikeli/service/impl/KKLImplService.java

@@ -0,0 +1,438 @@
+package com.malk.kuaikeli.service.impl;
+
+import cn.hutool.core.util.NumberUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.malk.kuaikeli.service.KKLService;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+import com.malk.service.aliwork.YDClient;
+import com.malk.service.aliwork.YDService;
+import com.malk.utils.UtilMap;
+import com.malk.utils.UtilMc;
+import com.malk.utils.UtilNumber;
+import lombok.SneakyThrows;
+import lombok.Synchronized;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+@Slf4j
+public class KKLImplService implements KKLService {
+
+    @Autowired
+    private YDService ydService;
+
+    /**
+     * [动态] 发起单据, 分供应商进行流程推送
+     */
+    @Override
+    public void matchSupplier(Map data) {
+
+        // ppExt: 供应商区分发起: 当前表:供应供子表组件ID,子表内供应商编号,名称,负责人
+        String[] compIds_supplier = String.valueOf(data.get("compId_supplier")).split(", ");
+        String compId_supplier = compIds_supplier[1];
+
+        Map formData = (Map) JSON.parse(String.valueOf(data.get("formData")));
+        List<Map> details = (List<Map>) formData.get(compIds_supplier[0]);
+
+        // 供应商编号, 数据去重: 提取数据区分供应商发起
+        List<Map> suppliers = UtilMc.distinctByKey(details, compId_supplier);
+        for (Map supplier : suppliers) {
+            List<Map> dataList = details.stream().filter(item -> supplier.get(compId_supplier).equals(item.get(compId_supplier))).collect(Collectors.toList());
+            formData.put(compIds_supplier[0], dataList);
+            // ppExt: 参数传递, 目标表组件ID, 对照当前表子表内的子表内供应商编号,名称,负责人已放置主表字段, 此处公共内容提前首条数据进行赋值
+            for (int i = 1; i < compIds_supplier.length; i++) {
+                formData.put(compIds_supplier[i], YDConf.getDataByCompId(dataList.get(0), compIds_supplier[i]));
+            }
+            data.put("formData", JSON.toJSONString(formData));
+            ydService.copyFormData(data); // 发起流程
+        }
+    }
+
+    @Autowired
+    private YDClient ydClient;
+
+    /**
+     * 菜单计划, 编辑校验
+     * -
+     * 前端提交动作: 校验是否审批通过, 是否当日之前计划, 是否当日且在16点及以后时间, 均不允许提交
+     * 后端校验返回、加任何产品都要走审批,减少20%以内直接过,每一个原材料
+     */
+    @Override
+    public boolean validateApprove(Map data) {
+
+        boolean approve = false;
+        List<Map> dataList = UtilMap.getList(data, "list");
+        for (Map row : dataList) {
+
+            // 匹配切配工作单, 采购
+            List<Map> formList = (List<Map>) ydClient.queryData(YDParam.builder()
+                            .formUuid("FORM-RK966E71T0LDSTW39WFHE9OQ5GU23FKRRDNLL2")
+                            .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_lmsuq8am, textField_lm8zta2z, textField_ln1ez5li", data.get("name"), data.get("area"), row.get("textField_ln1ez5li"))))
+                            .build(),
+                    YDConf.FORM_QUERY.retrieve_search_form).getData();
+
+            if (formList.size() == 0) {
+                approve = true;
+                break;
+            }
+            Map formData = (Map) formList.get(0).get("formData");
+            float cur = UtilMap.getFloat(row, "numberField_lmym5628");
+            float src = UtilMap.getFloat(formData, "numberField_lnrkgimz");
+            if (cur > src || (src - cur) / src > 0.2f) {
+                approve = true;
+                break;
+            }
+        }
+        if (approve) {
+            // 发起菜单审批
+            log.info("发起菜单审批");
+            ydClient.operateData(YDParam.builder()
+                    .formUuid("FORM-UP96637100HD036TA1M05B74GHLV3DRS54NLLC")
+                    .processCode("TPROC--UP96637100HD036TA1M05B74GHLV3ERS54NLLD")
+                    .formDataJson(JSON.toJSONString(data.get("form"))) // 前端数据组装
+                    .userId(data.get("user").toString())
+                    .build(), YDConf.FORM_OPERATION.start);
+        }
+        // 执行业务逻辑-编辑前后更新计划采购单
+        log.info("执行业务逻辑-编辑前后更新计划采购单");
+        planUpdate(UtilMap.getString(data,"poid"),dataList,data.get("user").toString());
+        return approve;
+    }
+
+    @Override
+    public void updateState(String id) {
+        try {
+            log.info("异步修改状态,休眠3s");
+            Thread.sleep(3000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        // 更新计划状态
+        ydService.operateData(YDParam.builder()
+                .formInstanceId(id)
+                .updateFormDataJson(JSON.toJSONString(UtilMap.map("textField_lm8znr9n", "执行中")))
+                .build(), YDConf.FORM_OPERATION.update);
+    }
+
+    private void planUpdate(String poid,List<Map> dataList,String userId){
+        String formUuid="FORM-XHA66881J8KDA6V3FM6LZBUP9PDE37VESDNLL6";
+        Map formData=(Map) ydClient.queryData(YDParam.builder().formInstId(poid).build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
+        List<Map> list=UtilMap.getList(formData,"tableField_lln477nw");
+        saveData(list,formData,formUuid,false,userId);// -
+        saveData(dataList,formData,formUuid,true,userId);// +
+    }
+
+    private void saveData(List<Map> list,Map formData,String formUuid,boolean isAdd,String userId){
+        for(Map map:list){
+            Map queryMap=new HashMap();
+            queryMap.put("dateField_llndtdwl", Arrays.asList(map.get("dateField_ln1ez5lg"),map.get("dateField_ln1ez5lg")));// 日期
+            queryMap.put("textField_llq9x6ov",formData.get("textField_lln477nh"));// 项目编号
+            queryMap.put("textField_lmk97m1v",map.get("textField_lmk97m1v"));// 原材料编号
+            Map upMap=new HashMap();
+            upMap.put("numberField_llojyfy3",map.get("numberField_lmsvfftq"));// 成本单价
+            upMap.put("numberField_llojyfy4",map.get("numberField_lmsvfftr"));// 服务费率
+            upMap.put("dateField_llndtdwl",map.get("dateField_ln1ez5lg"));// 计划日期
+            upMap.put("textField_llndm599",map.get("textField_llndm599"));// 原材料名称
+            upMap.put("textField_lluj4hu1",map.get("textField_lln3lmn2"));// 单位
+            upMap.put("textField_llq9x6ov",formData.get("textField_lln477nh"));// 项目编号
+            upMap.put("textField_lm5z7kvo",map.get("textField_ln1ez5li"));// 计划日期(文本)
+            upMap.put("textField_lm5z4ioi",formData.get("textField_lmsvfftp"));// 项目名称
+            upMap.put("textField_lmk97m1v",map.get("textField_lmk97m1v"));// 原材料编号
+            upMap.put("selectField_lmqclyx9",map.get("selectField_lmqclyx9"));// 第一分类
+            upMap.put("numberField_lmqclyxa",map.get("numberField_lmqclyxa"));// 供货价
+            upMap.put("textField_lnsmha2j",map.get("textField_lnwxz9ji"));// 品牌
+            upMap.put("textField_lpjet322",formData.get("textField_lpjet322"));// 档口名称
+            upMap.put("textField_lpjet321",formData.get("textField_lpjet321"));// 档口编号
+            upMap.put("textField_loe04txb",map.get("textField_lptgvips"));// 采购单位
+            List<Map> list2=(List<Map>) ydClient.queryData(YDParam.builder().formUuid(formUuid).searchFieldJson(JSONObject.toJSONString(queryMap)).build(), YDConf.FORM_QUERY.retrieve_list).getData();
+            if(list2==null||list2.size()<1){
+                if(!isAdd){
+                    log.info("未找到对应的计划采购单,退出");
+                    continue;
+                }
+                upMap.put("numberField_lln477o2", map.get("numberField_lmym5628"));// 初始采购数量(kg)
+                upMap.put("numberField_lm9008fq", map.get("numberField_lmym5628"));// 实际采购数量(kg)
+                upMap.put("numberField_lns0dkzv", map.get("numberField_lns0dkzv"));// 投料数量(kg)
+                upMap.put("numberField_loe04txa", map.get("numberField_lomyf89l"));// 采购量
+                ydClient.operateData(YDParam.builder().formUuid(formUuid).formDataJson(JSONObject.toJSONString(upMap)).userId(userId).build(), YDConf.FORM_OPERATION.create);
+            }else{
+                Map oldMap=UtilMap.getMap(list2.get(0),"formData");
+                if(isAdd){
+                    upMap.put("numberField_lln477o2", NumberUtil.add(UtilMap.getString(oldMap,"numberField_lln477o2"),UtilMap.getString(map,"numberField_lmym5628")));// 初始采购数量(kg)
+                    upMap.put("numberField_lm9008fq", NumberUtil.add(UtilMap.getString(oldMap,("numberField_lm9008fq")),UtilMap.getString(map,("numberField_lmym5628"))));// 实际采购数量(kg)
+                    upMap.put("numberField_lns0dkzv", NumberUtil.add(UtilMap.getString(oldMap,("numberField_lns0dkzv")),UtilMap.getString(map,("numberField_lns0dkzv"))));// 投料数量
+                    upMap.put("numberField_loe04txa",NumberUtil.add(UtilMap.getString(oldMap,"numberField_loe04txa"),UtilMap.getString(map,"numberField_lomyf89l")));// 采购量
+                }else {
+                    upMap.put("numberField_lln477o2", NumberUtil.sub(UtilMap.getString(oldMap, "numberField_lln477o2"), UtilMap.getString(map, "numberField_lmym5628")));// 初始采购数量(kg)
+                    upMap.put("numberField_lm9008fq", NumberUtil.sub(UtilMap.getString(oldMap, ("numberField_lm9008fq")), UtilMap.getString(map, ("numberField_lmym5628"))));// 实际采购数量(kg)
+                    upMap.put("numberField_lns0dkzv", NumberUtil.sub(UtilMap.getString(oldMap, ("numberField_lns0dkzv")), UtilMap.getString(map, ("numberField_lns0dkzv"))));// 投料数量
+                    upMap.put("numberField_loe04txa",NumberUtil.sub(UtilMap.getString(oldMap,"numberField_loe04txa"),UtilMap.getString(map,"numberField_lomyf89l")));// 采购量
+                }
+                ydClient.operateData(YDParam.builder().formInstanceId(UtilMap.getString(list2.get(0),"formInstanceId")).updateFormDataJson(JSONObject.toJSONString(upMap)).build(), YDConf.FORM_OPERATION.update);
+            }
+            if(isAdd){
+                // 保存切配工作单
+                String formUuid2="FORM-RK966E71T0LDSTW39WFHE9OQ5GU23FKRRDNLL2";
+                Map qMap=new HashMap();
+                qMap.put("textField_lmsuq8am",formData.get("textField_lln477nh"));// 项目编号
+                qMap.put("dateField_llndtdwl",Arrays.asList(map.get("dateField_ln1ez5lg"),map.get("dateField_ln1ez5lg")));// 日期
+                qMap.put("textField_lm8zta2z",formData.get("selectField_llm1i9yl"));// 餐次
+                qMap.put("selectField_lln3lmn5",map.get("textField_lm4m83rv"));// 切配类型
+                qMap.put("textField_llndm599",map.get("textField_llndm599"));// 原材料名称
+                Map addMap=new HashMap();
+                addMap.putAll(qMap);
+                String data=String.valueOf(formData.get("associationFormField_lln477nb_id"));
+                addMap.put("associationFormField_llndtdwg",JSONObject.parseArray(data.substring(1,data.length()-1).replaceAll("\\\\","")));// 项目点
+                addMap.put("numberField_lln477o2",map.get("numberField_lmym5628"));// 数量(kg)
+                addMap.put("numberField_lnrkgimz",map.get("numberField_lomyf89l"));// 初始采购数量
+                addMap.put("textField_ln1ez5li",map.get("textField_ln1ez5li"));// 计划日期(文本)
+                addMap.put("dateField_llndtdwl",map.get("dateField_ln1ez5lg"));// 日期
+                List<Map> list3=(List<Map>) ydClient.queryData(YDParam.builder().formUuid(formUuid2).searchFieldJson(JSONObject.toJSONString(qMap)).build(),
+                        YDConf.FORM_QUERY.retrieve_list).getData();
+                if(list3==null||list3.size()<1){
+                    ydClient.operateData(YDParam.builder().formUuid(formUuid2)
+                            .formDataJson(JSONObject.toJSONString(addMap))
+                            .userId(userId)
+                            .build(), YDConf.FORM_OPERATION.create);
+                }else{
+                    ydClient.operateData(YDParam.builder().formInstanceId(UtilMap.getString(list3.get(0),"formInstanceId"))
+                            .updateFormDataJson(JSONObject.toJSONString(addMap))
+                            .build(), YDConf.FORM_OPERATION.update);
+                }
+            }
+        }
+    }
+
+    /**
+     * 定价单: 项目点 & 供应商大类, 数据匹配
+     */
+    @Override
+    @SneakyThrows
+    @Synchronized
+    public void serviceRate(Map data) {
+
+        // todo2: 宜搭更新,校验的超时等待在3s, 因此方法修改为异步. 容错定时任务?匹配不一致数据
+        String supperCode = String.valueOf(data.get("code"));
+        List<String> types = (List<String>) JSON.parse(String.valueOf(data.get("type")));
+        List<String> rates = (List<String>) JSON.parse(String.valueOf(data.get("rate")));
+        List<String> rates2 = (List<String>) JSON.parse(String.valueOf(data.get("rate2")));
+        List<String> status = (List<String>) JSON.parse(String.valueOf(data.get("status")));
+
+        for (int i = 0; i < types.size(); i++) {
+
+            List<Map> materials = supperMaterials(supperCode, types.get(i));
+            List<Map> records = projectMaterials(supperCode, types.get(i));
+            log.info("定价单同步, {}, {}", materials.size(), records.size());
+            for (Map material : materials) {
+
+                // 数据处理: 服务费率与供货价, 项目信息
+                double rate = Double.valueOf(rates.get(i));
+                double rate2 = Double.valueOf(rates2.get(i));
+                material.putAll(UtilMap.map("numberField_llkb7kcy, numberField_lpalgz04, textField_lm4lxur8", rate, rate2, status.get(i)));
+                double price1 = UtilNumber.formatPrecisionValue(UtilMap.getDouble(material, "numberField_llkknd6g") * (rate + 100) / 100f);
+                double price2 = UtilNumber.formatPrecisionValue(UtilMap.getDouble(material, "numberField_lpalgz05") * (100 + rate2) / 100f);
+                material.putAll(UtilMap.map("numberField_llkknd6h, numberField_lpalgz0a", price1, price2));
+                material.putAll(UtilMap.map("textField_llm1vtjm, textField_loy1ep8r", data.get("proCode"), data.get("proName")));
+
+                YDParam ydParam = YDParam.builder()
+                        .formUuid("FORM-E6766M811CKD2PIXEAKOM9S2DKBM2PBQU1MLL5")
+                        .formDataJson(JSON.toJSONString(material))
+                        .build();
+                YDConf.FORM_OPERATION operation = YDConf.FORM_OPERATION.create;
+                // ppExt: 提交校验逻辑, 匹配定价单数若存在则匹配服务费率, 不一致执行更新
+                if (records.size() > 0) {
+                    Optional optional = records.stream().filter(item -> item.get("textField_llkb7kd2").equals(material.get("textField_llkb7kd2"))).findAny();
+                    if (optional.isPresent()) {
+                        ydParam.setUpdateFormDataJson(JSON.toJSONString(material));
+                        ydParam.setFormInstanceId(String.valueOf(((Map) optional.get()).get("formInstanceId")));
+                        operation = YDConf.FORM_OPERATION.update;
+                    }
+                }
+                ydClient.operateData(ydParam, operation);
+            }
+        }
+    }
+
+
+
+    /// 原材料: 供应商第一分类下物料
+    List<Map> supperMaterials(String code, String type) {
+        List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
+                .formUuid("FORM-12EB6BCE3C264630824721E7BBABCC03L8U9")
+                .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_llzzbyj1, selectField_llkk6cms", code, type)))
+                .build());
+        log.info("supperMaterials, {}", dataList.size());
+        return dataList;
+    }
+
+    /// 定价单: 供应商第一分类下物料
+    List<Map> projectMaterials(String code, String type) {
+        List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
+                .formUuid("FORM-E6766M811CKD2PIXEAKOM9S2DKBM2PBQU1MLL5")
+                .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_llzzbyj1, selectField_llkk6cms", code, type)))
+                .build());
+        log.info("projectMaterials, {}", dataList.size());
+        return dataList;
+    }
+
+
+    /**
+     * 物料档案: 价格调整
+     */
+    @Override
+    public void adjustCost(Map data) {
+
+        double cost1 = UtilMap.getDouble(data, "costPrice");
+        double cost2 = UtilMap.getDouble(data, "nextCostPrice");
+        String cost3 = UtilMap.getString(data,"timeLimit");
+
+        //todo2: 服务执行, 周日凌晨更新价格前, 是否重新匹配数据?
+        List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
+                .formUuid("FORM-E6766M811CKD2PIXEAKOM9S2DKBM2PBQU1MLL5")
+                .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_llkb7kd2", data.get("itemNumber"))))
+                .build());
+        log.info("adjustCost, {}", dataList.size());
+
+        for (Map record : dataList) {
+//            if (cost1 == UtilMap.getDouble(record, "numberField_llkknd6g") && cost2 == UtilMap.getDouble(record, "numberField_lpalgz05")) {
+//                continue;
+//            }
+            double rate = UtilMap.getDouble(record, "numberField_llkb7kcy");
+            double rate2 = UtilMap.getDouble(record, "numberField_lpalgz04");
+            double price1 = UtilNumber.formatPrecisionValue(cost1 * (rate + 100) / 100f);
+            double price2 = UtilNumber.formatPrecisionValue(cost2 * (100 + rate2) / 100f);
+
+            Map update = UtilMap.map("numberField_llkknd6h, numberField_lpalgz0a", price1, price2);
+            update.putAll(UtilMap.map("numberField_llkknd6g, numberField_lpalgz05, dateField_lm4lxur7", cost1, cost2, cost3 ));
+            ydClient.operateData(YDParam.builder()
+                    .formInstanceId(String.valueOf(record.get("formInstanceId")))
+                    .updateFormDataJson(JSON.toJSONString(update))
+                    .build(), YDConf.FORM_OPERATION.update);
+        }
+    }
+
+    /**
+     * 供应商原材料档案: 新增匹配
+     */
+    @Override
+    public void additionMaterial(Map data) {
+
+        // 通过供应商编号 查询项目
+        List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
+                .formUuid("FORM-W2A66Z91B4KDWDIAA7SI1BRBRTKM3XL87BKLL0")
+                .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_llzzbai8", data.get("gysNumber"))))
+                .build());
+        dataList.forEach(dataItem -> {
+            List<Map> mapList = (List<Map>) dataItem.get("tableField_llq74mwk");
+            // 这里对比第二分类  selectField_llq74mwl ==> selectField_lv3v3911
+            List<Map> maps =  mapList.stream().filter(items -> items.get("selectField_lv3v3911").equals(data.get("firstName"))).collect(Collectors.toList());
+            if(maps.size()>0){
+
+                List<Map> goodList = ydService.queryFormData_all(YDParam.builder()
+                        .formUuid("FORM-12EB6BCE3C264630824721E7BBABCC03L8U9")
+                        .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_llkb7kd2", data.get("goodNumber"))))
+                        .build());
+                Map goodMap = goodList.get(0);
+
+                Map hashMap = new HashMap();
+                hashMap.put("textField_llzzbyj1",data.get("gysNumber"));   //供应商编号
+                hashMap.put("textField_lmsli3bq",dataItem.get("textField_lmsli3bq")); //供应商名称
+                hashMap.put("textField_llm1vtjm",dataItem.get("textField_lllovku7"));  //项目编号
+                hashMap.put("textField_loy1ep8r",dataItem.get("textField_loy1ep8r"));//项目名称
+                hashMap.put("textField_llkb7kd2",data.get("goodNumber"));   //物品编号
+                hashMap.put("textField_llkb7kd1",goodMap.get("textField_llkb7kd1"));  //物品名称
+
+                hashMap.put("textField_llkb7kd3",goodMap.get("textField_llkb7kd3"));  //单位
+                hashMap.put("textField_llkb7kd4",goodMap.get("textField_llkb7kd4"));  //规格
+                hashMap.put("selectField_llkb7kd5",data.get("firstName"));              //第一分类
+                hashMap.put("selectField_llkk6cms",goodMap.get("selectField_llkk6cms"));              //第二分类
+
+
+                double rate = UtilMap.getDouble(maps.get(0), "numberField_llq74mwm");  //本周费率
+                double rate2 = UtilMap.getDouble(maps.get(0), "numberField_lpplr3im"); //下周费率
+
+                double pce1 = UtilMap.getDouble(goodMap, "numberField_llkknd6g");  //成本单价
+                double pce2 = UtilMap.getDouble(goodMap, "numberField_lpalgz05");   //下周成本单价
+
+                double price1 = UtilNumber.formatPrecisionValue(pce1 * (rate + 100) / 100f);  //下周成本价
+                double price2 = UtilNumber.formatPrecisionValue(pce2 * (rate2 + 100 ) / 100f); //下周供货价
+
+                hashMap.put("numberField_llkb7kcy",rate);       //服务费率
+                hashMap.put("numberField_lpalgz04",rate2);   //下周服务费率
+
+                hashMap.put("numberField_llkknd6g",pce1);   //成本单价
+                hashMap.put("numberField_lpalgz05",pce2);   //下周成本单价
+
+                hashMap.put("numberField_llkknd6h",price1);  //供货价
+                hashMap.put("numberField_lpalgz0a",price2); //下周供货价
+
+                hashMap.put("dateField_lm4lxur7",goodMap.get("dateField_lm4lxur7"));  //期限
+                hashMap.put("textField_lm4lxur8","已启用");  //状态
+                hashMap.put("numberField_lnrzzg03",goodMap.get("numberField_lnrzzg03")); //包装数量
+                hashMap.put("textField_lnrzzg04",goodMap.get("textField_lnrzzg04")); //包装单位
+
+
+                log.info("hashMap,{}", JSON.toJSONString(hashMap));
+
+                ydClient.operateData(YDParam.builder()
+                        .formUuid("FORM-E6766M811CKD2PIXEAKOM9S2DKBM2PBQU1MLL5")
+                        .formDataJson(JSON.toJSONString(hashMap))
+                        .build(), YDConf.FORM_OPERATION.create);
+            }
+        });
+
+
+
+
+    }
+
+    /**
+     * 周日同步更新价格
+     */
+    @Override
+    @SneakyThrows
+    public void syncPrice() {
+
+        // 定价单明细表
+        List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
+                .formUuid("FORM-E6766M811CKD2PIXEAKOM9S2DKBM2PBQU1MLL5")
+                .build());
+        for (Map record : dataList) {
+
+            double price1 = UtilMap.getDouble(record, "numberField_llkknd6h");
+            double price2 = UtilMap.getDouble(record, "numberField_lpalgz0a");
+            if (price1 == price2) {
+                continue;
+            }
+            // 本质上是对比供货价差异, 下周全覆盖
+            Map update = UtilMap.map("numberField_llkknd6h, numberField_llkb7kcy, numberField_llkknd6g", price2, record.get("numberField_lpalgz04"), record.get("numberField_lpalgz05"));
+            ydClient.operateData(YDParam.builder()
+                    .formInstanceId(String.valueOf(record.get("formInstanceId")))
+                    .updateFormDataJson(JSON.toJSONString(update))
+                    .build(), YDConf.FORM_OPERATION.update);
+        }
+        // 供应商原材料表
+        List<Map> dataList2 = ydService.queryFormData_all(YDParam.builder()
+                .formUuid("FORM-12EB6BCE3C264630824721E7BBABCC03L8U9")
+                .build());
+        for (Map record : dataList2) {
+
+            double cost1 = UtilMap.getDouble(record, "numberField_llkknd6g");
+            double cost2 = UtilMap.getDouble(record, "numberField_lpalgz05");
+            if (cost1 == cost2) {
+                continue;
+            }
+            Map update = UtilMap.map("numberField_llkknd6g", cost2);
+            ydClient.operateData(YDParam.builder()
+                    .formInstanceId(String.valueOf(record.get("formInstanceId")))
+                    .updateFormDataJson(JSON.toJSONString(update))
+                    .build(), YDConf.FORM_OPERATION.update);
+        }
+    }
+}

+ 292 - 0
mjava-kuaikeli/src/main/java/com/malk/kuaikeli/service/impl/SupplierMaterialServiceImpl.java

@@ -0,0 +1,292 @@
+package com.malk.kuaikeli.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.pinyin.PinyinUtil;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.malk.kuaikeli.entity.MaterialDetail;
+import com.malk.kuaikeli.entity.Pricing;
+import com.malk.kuaikeli.entity.SupplierMaterial;
+import com.malk.kuaikeli.listener.SupplierMaterialDataListener;
+import com.malk.kuaikeli.mapper.MaterialDetailMapper;
+import com.malk.kuaikeli.mapper.SupplierMaterialMapper;
+import com.malk.kuaikeli.service.SupplierMaterialService;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+import com.malk.server.common.McR;
+import com.malk.service.aliwork.YDClient;
+import com.malk.utils.PublicUtil;
+import com.malk.utils.UtilEnv;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.xmlbeans.impl.xb.xsdschema.Public;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.*;
+
+@Service
+@Slf4j
+public class SupplierMaterialServiceImpl extends ServiceImpl<SupplierMaterialMapper,SupplierMaterial> implements SupplierMaterialService {
+
+    @Autowired
+    private YDClient ydClient;
+    @Autowired
+    private MaterialDetailMapper materialDetailMapper;
+
+    String _matchFormUuid(String code) {
+        Map<String, String> formUuid = UtilMap.empty();
+        if (UtilEnv.getActiveProfile().equals(UtilEnv.ENV_PROD)) {
+            formUuid.put("SUPPLIERMATERIAL", "FORM-12EB6BCE3C264630824721E7BBABCC03L8U9"); // 供应商原材料档案
+            formUuid.put("PRICING", "FORM-W2A66Z91B4KDWDIAA7SI1BRBRTKM3XL87BKLL0"); // 定价单
+            formUuid.put("MATERIALDETAIL", "FORM-E6766M811CKD2PIXEAKOM9S2DKBM2PBQU1MLL5"); // 定价单明细中间表
+            formUuid.put("FOOD", "FORM-GP666M71DIGDE0ZADDLZ85VEFBD128OUH1MLLF"); // 菜品管理
+            formUuid.put("DOMAIN", "https://dcuvl8.aliwork.com/"); // 宜搭域名
+        } else {
+            formUuid.put("SUPPLIERMATERIAL", "FORM-2ADD5797EFB94A5CA18C5E553B420AA7BO75"); // 供应商原材料档案_复制
+            formUuid.put("PRICING", "FORM-W2A66Z91B4KDWDIAA7SI1BRBRTKM3XL87BKLL0"); // 定价单
+            formUuid.put("MATERIALDETAIL", "FORM-96ED86E480CB4E19851729D055474965FYAL"); // 定价单明细中间表
+            formUuid.put("FOOD", "FORM-GP666M71DIGDE0ZADDLZ85VEFBD128OUH1MLLF"); // 菜品管理
+            formUuid.put("DOMAIN", "https://dcuvl8.aliwork.com/");
+        }
+        return formUuid.get(code);
+    }
+
+    @Override
+    public void uploadData(MultipartFile file) {
+        try {
+            EasyExcel.read(file.getInputStream(), SupplierMaterial.class, new SupplierMaterialDataListener(baseMapper)).sheet().doRead();
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /***
+     * 同步服务  只查新数据(isNeedSyncYd==是)
+     * 1.保存原材料到宜搭表单
+     * 2.查询定价单组装数据保存到定价明细中间表
+     */
+    @Override
+    @Async
+    public void sync() {
+        QueryWrapper<SupplierMaterial> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(SupplierMaterial::getIsNeedSyncYd,"是");
+        List<SupplierMaterial> list=baseMapper.selectList(queryWrapper);
+        for (SupplierMaterial supplierMaterial:list){
+            try {
+                syncSupplierMaterial(supplierMaterial);
+            }catch (Exception e){
+                log.error("同步出现异常:{}",e.getMessage());
+                e.printStackTrace();
+                supplierMaterial.setIsNeedSyncYd("异常");// 更新是否需要同步到宜搭
+                supplierMaterial.setErrorMsg(e.getMessage());
+                baseMapper.updateById(supplierMaterial);
+            }
+        }
+    }
+
+    public void syncSupplierMaterial(SupplierMaterial supplierMaterial){
+        // 同步到宜搭
+        YDParam ydParam = YDParam.builder().formUuid(_matchFormUuid("SUPPLIERMATERIAL"))
+                .useLatestVersion(true).build();
+        Map formData=supplierMaterial.toYidaFormDataMap();
+        // 查询定价单数据
+        List<Pricing> pricings=getPricings(supplierMaterial.getSupplierId());
+        if(!PublicUtil.isNull(supplierMaterial.getFormInstId())){
+            // 更新
+            ydParam.setUpdateFormDataJson(JSON.toJSONString(formData));
+            ydParam.setFormInstanceId(String.valueOf(supplierMaterial.getFormInstId()));
+            ydClient.operateData(ydParam,YDConf.FORM_OPERATION.update);
+            for (Pricing pricing:pricings){
+                upsertMaterialDetail(pricing,supplierMaterial,formData);
+            }
+        }else{
+            // 新增
+            ydParam.setFormDataJson(JSON.toJSONString(formData));
+            String formInstId=(String) ydClient.operateData(ydParam,YDConf.FORM_OPERATION.create);
+            int st=0;
+            for (Pricing pricing:pricings){
+                upsertMaterialDetail(pricing,supplierMaterial,formData);
+                st++;
+            }
+            supplierMaterial.setMaterialDetailNumber(String.valueOf(st));
+            supplierMaterial.setIsNeedSyncYd("否");// 更新是否需要同步到宜搭
+            supplierMaterial.setFormInstId(formInstId);// 更新实例编号
+            baseMapper.updateById(supplierMaterial);
+        }
+    }
+
+    private void upsertMaterialDetail(Pricing pricing,SupplierMaterial supplierMaterial,Map formData){
+        YDParam ydParam2 = YDParam.builder().formUuid(_matchFormUuid("MATERIALDETAIL"))
+                .useLatestVersion(true).build();
+        QueryWrapper<MaterialDetail> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(MaterialDetail::getSupplierId,supplierMaterial.getSupplierId())
+                .eq(MaterialDetail::getProjectId,pricing.getProjectId())
+                .eq(MaterialDetail::getMaterialId,supplierMaterial.getMaterialId());
+        List<MaterialDetail> materialDetails =materialDetailMapper.selectList(queryWrapper);
+        if(materialDetails!=null&&materialDetails.size()>0){
+            MaterialDetail materialDetail=materialDetails.get(0);
+            String rate;// 服务费率
+            if(pricing.getRateMap().containsKey(materialDetail.getClassifyTwo())){// 第二分类优先匹配
+                rate=pricing.getRateMap().get(materialDetail.getClassifyTwo());
+            }else if(pricing.getRateMap().containsKey(materialDetail.getClassifyOne())){// 第一分类匹配
+                rate=pricing.getRateMap().get(materialDetail.getClassifyOne());
+            }else{
+                return;
+            }
+            String[] rates=rate.split("_");
+            materialDetail.setRate(rates[0]);
+            materialDetail.setRateNext(rates[1]);
+            materialDetail.setSupplyPrice(cal(materialDetail.getUnitPrice(),rates[0]));
+            materialDetail.setSupplyPriceNext(cal(materialDetail.getUnitPriceNext(),rates[0]));
+            // 更新明细中间表数据库
+            materialDetailMapper.updateById(materialDetail);
+            // 更新明细中间表宜搭数据
+            ydParam2.setUpdateFormDataJson(JSONObject.toJSONString(materialDetail.toYidaFormDataMap()));
+            ydParam2.setFormInstanceId(String.valueOf(materialDetail.getFormInstId()));
+            ydClient.operateData(ydParam2,YDConf.FORM_OPERATION.update);
+        }else{
+            MaterialDetail materialDetail=MaterialDetail.toBean(formData);
+            String rate;// 服务费率
+            if(pricing.getRateMap().containsKey(materialDetail.getClassifyTwo())){// 第二分类优先匹配
+                rate=pricing.getRateMap().get(materialDetail.getClassifyTwo());
+            }else if(pricing.getRateMap().containsKey(materialDetail.getClassifyOne())){// 第一分类匹配
+                rate=pricing.getRateMap().get(materialDetail.getClassifyOne());
+            }else{
+                return;
+            }
+            String[] rates=rate.split("_");
+            materialDetail.setRate(rates[0]);
+            materialDetail.setRateNext(rates[1]);
+            materialDetail.setSupplyPrice(cal(materialDetail.getUnitPrice(),rates[0]));
+            materialDetail.setSupplyPriceNext(cal(materialDetail.getUnitPriceNext(),rates[0]));
+            materialDetail.setProjectId(pricing.getProjectId());
+            materialDetail.setProjectName(pricing.getProjectName());
+            ydParam2.setFormDataJson(JSONObject.toJSONString(materialDetail.toYidaFormDataMap()));
+            String priFormInstId=(String) ydClient.operateData(ydParam2,YDConf.FORM_OPERATION.create);
+            materialDetail.setFormInstId(priFormInstId);
+            materialDetailMapper.insert(materialDetail.create());
+        }
+    }
+
+    public IPage<SupplierMaterial> getProducts(Page<SupplierMaterial> page, Map<String, Object> params) {
+        // 构造查询条件(可选)
+        QueryWrapper<SupplierMaterial> queryWrapper = new QueryWrapper<>();
+        // ... 根据params设置查询条件 ...
+        // 执行分页查询
+        return baseMapper.selectPage(page, queryWrapper);
+    }
+
+    @Override
+    public McR getList(Integer current, Integer size) {
+        Page<SupplierMaterial> page=new Page<>(current,size);
+        IPage iPage = getProducts(page,null);
+        return McR.success(iPage);
+    }
+
+    @Override
+    public void syncPrice() {
+        // 每周同步  ==> 直接修改数据库供应商原材料表 成本单价为下周成本单价、同步标识为“是”。通过供应商原材料更新业务逻辑实现同步
+        baseMapper.updateUnitPrice();
+    }
+
+    @Override
+    public void projectSupplierChange(String projectId, String oldId, String newId,String newName) {
+        Map<String,String> ID_MAP=new HashMap<>();
+        // 1.复制原材料数据到数据库?
+        List<SupplierMaterial> supplierMaterials=baseMapper.selectListForCopy(projectId,oldId);
+        int no = 1;
+        String name= PinyinUtil.getFirstLetter(newName.replace("供应商",""),"").toUpperCase();
+        for (SupplierMaterial supplierMaterial:supplierMaterials){
+            supplierMaterial.create();
+            supplierMaterial.setSupplierId(newId);
+            supplierMaterial.setSupplierName(newName);
+            String id=name+String.format("%05d",no);
+            ID_MAP.put(supplierMaterial.getMaterialId(),id);
+            supplierMaterial.setMaterialId(id);// 原材料编号怎么处理
+            baseMapper.insert(supplierMaterial);
+            no++;
+        }
+        // 等待同步
+        sync();
+        // 2.宜搭菜品管理表单  替换供应商原材料编号、供应商名称
+        List<Map> yidaList= (List<Map>) ydClient.queryData(YDParam.builder().formUuid(_matchFormUuid("FOOD")).searchCondition(
+                JSONObject.toJSONString(UtilMap.map("textField_lln3lmn1",projectId)))
+                .build(),YDConf.FORM_QUERY.retrieve_list_all).getData();
+        for (Map map:yidaList){
+            Map formData=UtilMap.getMap(map,"formData");
+            String formInstId=UtilMap.getString(map,"formInstId");
+            List<Map> list=UtilMap.getList(formData,"tableField_llm1i9yy");// 材料清单
+            for (int i = 0; i < list.size(); i++) {
+                // 查询数据库
+                String nId=ID_MAP.get(list.get(i).get("textField_lmk94yf5"));
+                QueryWrapper<MaterialDetail> queryWrapper = new QueryWrapper<>();
+                queryWrapper.lambda().eq(MaterialDetail::getSupplierId,newId)
+                        .eq(MaterialDetail::getProjectId,projectId)
+                        .eq(MaterialDetail::getMaterialId,nId);
+                List<MaterialDetail> materialDetails =materialDetailMapper.selectList(queryWrapper);
+                if(materialDetails!=null&&materialDetails.size()>0){
+                    list.get(i).put("associationFormField_lln3lmmv", Arrays.asList(UtilMap.map("title, instanceId, appType, formUuid, formType",
+                            materialDetails.get(0).getMaterialName(),materialDetails.get(0).getFormInstId(),
+                            "APP_OHSG8KMIP9SGXV32XUQJ",_matchFormUuid("MATERIALDETAIL"),"receipt")));// 关联中间表
+                }
+                list.get(i).put("textField_lmk94yf5",nId);// 原材料编号
+            }
+            YDParam ydParam = YDParam.builder().formUuid(_matchFormUuid("MATERIALDETAIL"))
+                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("tableField_llm1i9yy",list)))
+                    .formInstanceId(formInstId)
+                    .useLatestVersion(true).build();
+            ydClient.operateData(ydParam,YDConf.FORM_OPERATION.update);
+        }
+    }
+
+    // 缓存
+    private static Map<String,List<Pricing>> SUPPLIER_PRICING_MAP=new HashMap<>();
+    // 获取定价单
+    private List<Pricing> getPricings(String supplierId){
+        if(SUPPLIER_PRICING_MAP.containsKey(supplierId)){
+            return SUPPLIER_PRICING_MAP.get(supplierId);
+        }
+        List<Pricing> list=new ArrayList<>();
+        List<Map> yidaList= (List<Map>) ydClient.queryData(YDParam.builder().formUuid(_matchFormUuid("PRICING")).searchCondition(
+                JSONObject.toJSONString(UtilMap.map("textField_llzzbai8",supplierId)))
+                .build(),YDConf.FORM_QUERY.retrieve_list_all).getData();
+        for(Map map:yidaList){
+            Map formData=UtilMap.getMap(map,"formData");
+            Pricing pricing= BeanUtil.mapToBean(formData,Pricing.class,false);
+            List<Map> detailList= (List<Map>) formData.get("tableField_llq74mwk");
+            Map<String,String> data=new HashMap();
+            for(Map detailMap:detailList){
+                if("已启用".equals(String.valueOf(detailMap.get("selectField_lpw1n0af")))){
+                    data.put(String.valueOf(detailMap.get(!PublicUtil.isNull(detailMap.get("selectField_lv3v3911"))?"selectField_lv3v3911":"selectField_llq74mwl")),
+                            String.valueOf(detailMap.get("numberField_llq74mwm")).concat("_").concat(String.valueOf(detailMap.get("numberField_lpplr3im"))));
+                }
+            }
+            pricing.setRateMap(data);
+            log.info("pricing:{}",JSONObject.toJSONString(pricing));
+            list.add(pricing);
+        }
+        SUPPLIER_PRICING_MAP.put(supplierId,list);
+        return list;
+    }
+
+    private String cal(String unitPrice,String rate){
+        return NumberUtil.roundStr(NumberUtil.div(NumberUtil.mul(unitPrice,NumberUtil.add(rate,"100").toString()).toString(),"100").toString(),2);
+    }
+
+    public static void main(String[] args) {
+        System.out.println(NumberUtil.sub(5,1));
+    }
+
+}

+ 36 - 0
mjava-kuaikeli/src/main/resources/application-dev.yml

@@ -0,0 +1,36 @@
+server:
+  port: 9020
+  servlet:
+    context-path: /api/kuaikeli
+spring:
+  datasource:
+    url: jdbc:mysql://localhost:3306/floe?useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC
+    username: root
+    password: 111111
+    driver-class-name: com.mysql.cj.jdbc.Driver
+enable:
+  scheduling: false
+logging:
+  config: classpath:logback-spring.xml
+  path: /home/server/kuaikeli/log/
+  level:
+    com.malk.*: debug
+
+# dingtalk
+dingtalk:
+  agentId: 2691784047
+  appKey: dinghbynhnd2dbgypmsa
+  appSecret: Kl5Xw8x0TlEIlvcJuUkYZD18UTTShJmfdKrAIpY8oX-Q_tazyUKA28nQh7dG5-mq
+  corpId: dingcc1b1ffad0d5ca1d
+  aesKey:
+  token:
+# teambition
+teambition:
+  AppID: 63589b8bb6803e162f9a57d8
+  AppSecret: 5mB3b73OFhSwo38xEVqahCLwQVhG1MW3
+  TenantId: 5ca44db8ca4fd40001b10559
+  OperatorId: 5e698cca21f5ad70dfba7d2b    # 公共账号, 需要有操作权限 [牧语]
+# aliwork
+aliwork:
+  appType: APP_OHSG8KMIP9SGXV32XUQJ
+  systemToken: 9F766B81QHGDDLQ89X17X5GXVPYM20V729KLLPH

+ 30 - 0
mjava-kuaikeli/src/main/resources/application-prod.yml

@@ -0,0 +1,30 @@
+server:
+  port: 9020
+  servlet:
+    context-path: /api/kuaikeli
+spring:
+  datasource:
+    url: jdbc:mysql://127.0.0.1:3306/dingtalk?useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC
+    username: root
+    password: cp-root@2024++
+    driver-class-name: com.mysql.cj.jdbc.Driver
+enable:
+  scheduling: true
+logging:
+  config: classpath:logback-spring.xml
+  path: /home/server/kuaikeli/log/
+  level:
+    com.malk.*: info
+
+# dingtalk
+dingtalk:
+  agentId: 2691784047
+  appKey: dinghbynhnd2dbgypmsa
+  appSecret: Kl5Xw8x0TlEIlvcJuUkYZD18UTTShJmfdKrAIpY8oX-Q_tazyUKA28nQh7dG5-mq
+  corpId: dingcc1b1ffad0d5ca1d
+  aesKey:
+  token:
+# aliwork
+aliwork:
+  appType: APP_OHSG8KMIP9SGXV32XUQJ
+  systemToken: 9F766B81QHGDDLQ89X17X5GXVPYM20V729KLLPH

+ 17 - 0
mjava-kuaikeli/src/main/resources/application.yml

@@ -0,0 +1,17 @@
+spring:
+  profiles:
+    active: dev
+  servlet:
+    multipart:
+      max-file-size: 100MB
+      max-request-size: 100MB
+  http:
+    enabled: false
+mybatis-plus:
+  mappers-locations: mapper/*.xml
+  type-aliases-package: com.malk.kuaikeli.entity
+#  configuration:
+#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+  global-config:
+    db-config:
+      id-type: auto

+ 61 - 0
mjava-kuaikeli/src/main/resources/logback-spring.xml

@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="false" scan="false" scanPeriod="60 seconds">
+    <springProperty scope="context" name="LOG_HOME" source="logging.path" defaultValue="/home/server/log/"/>
+    <property name="FileNamePattern" value="${LOG_HOME}%d{yyyyMM}/%d{dd}"/>
+
+    <!-- 定义控制台输出 -->
+    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
+        <layout class="ch.qos.logback.classic.PatternLayout">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} - [%thread] - %-5level - %logger{50} - %msg%n</pattern>
+        </layout>
+    </appender>
+
+    <appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 指定日志文件的名称 -->
+        <!--<file>${FileNamePattern}/info.log</file>-->
+
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${FileNamePattern}/info-%i.log</fileNamePattern>
+            <MaxHistory>30</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <MaxFileSize>30MB</MaxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+
+        <layout class="ch.qos.logback.classic.PatternLayout">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern>
+        </layout>
+    </appender>
+
+    <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
+        <discriminator>
+            <Key>processid</Key>
+            <DefaultValue>sys</DefaultValue>
+        </discriminator>
+        <sift>
+            <appender name="FILE-${processid}"
+                      class="ch.qos.logback.core.rolling.RollingFileAppender">
+                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                    <FileNamePattern>
+                        ${FileNamePattern}/${processid}.log
+                    </FileNamePattern>
+                </rollingPolicy>
+                <layout class="ch.qos.logback.classic.PatternLayout">
+                    <Pattern>
+                        %d{yyyyMMdd:HH:mm:ss.SSS} [%thread] %-5level %msg%n
+                    </Pattern>
+                </layout>
+            </appender>
+        </sift>
+    </appender>
+
+
+    <!-- 日志输出级别 -->
+    <logger name="org.springframework" level="debug"  additivity="false"/>
+    <logger name="com.zitoo.connecter" level="debug"/>
+    <root level="INFO">
+        <appender-ref ref="stdout"/>
+        <appender-ref ref="appLogAppender"/>
+        <appender-ref ref="SIFT"/>
+    </root>
+</configuration>

+ 51 - 0
mjava-kuaikeli/src/main/resources/mapper/SupplierMaterialMapper.xml

@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.malk.kuaikeli.mapper.SupplierMaterialMapper">
+    <update id="updateUnitPrice">
+        UPDATE t_supplier_material
+        SET unit_price = unit_price_next,
+        is_need_sync_yd = '是'
+        WHERE
+        unit_price &lt;&gt; unit_price_next
+    </update>
+
+    <select id="selectListForCopy" resultType="com.malk.kuaikeli.entity.SupplierMaterial" parameterType="java.lang.String">
+          SELECT
+            supplier,
+            supplier_id,
+            supplier_name,
+            material_name,
+            material_id,
+            unit,
+            specs,
+            classify_one,
+            classify_two,
+            unit_price,
+            unit_price_next,
+            other_info,
+            img,
+            brand,
+            state,
+            term,
+            packing_number,
+            packing_unit,
+            need_qualification,
+            provide_qualification,
+            qualification,
+            qualification_expire_date
+        FROM
+            t_supplier_material
+        WHERE
+            material_id IN (
+                SELECT
+                    material_id
+                FROM
+                    t_material_detail
+                WHERE
+                    project_id = #{project_id}
+                AND supplier_id = #{supplier_id}
+            )
+    </select>
+</mapper>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/app.76c35fec.css


BIN
mjava-kuaikeli/src/main/resources/static/web/css/app.76c35fec.css.gz


+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/chunk-1a891981.86df4f93.css

@@ -0,0 +1 @@
+.comp[data-v-46a2638c] .el-drawer{overflow-y:auto}.comp .comp-form-oper[data-v-46a2638c]{margin-top:.4rem;text-align:center}.comp .comp-form-oper .el-button[data-v-46a2638c]{margin:0 .15rem}.van-cell[data-v-46a2638c]{overflow:hidden;border-radius:.04rem}.van-button[data-v-46a2638c]{overflow:hidden;border-radius:.08rem}

+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/chunk-1bf96e69.8bd88a30.css

@@ -0,0 +1 @@
+[data-v-d46765f6]:export{colorTheme:#3170f5}.main[data-v-d46765f6]{padding:.3rem .2rem}.scan[data-v-d46765f6]{padding-top:.2rem;background-color:#fff;padding:.3rem .2rem;position:relative;text-align:center}.scan h2[data-v-d46765f6]{font-size:.18rem;line-height:3;padding-bottom:.2rem}

+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/chunk-2628d9a4.9c878275.css

@@ -0,0 +1 @@
+[data-v-43a425a6]:export{colorTheme:#3170f5}.main[data-v-43a425a6]{text-align:center;background-color:#fff;height:100%}.guide[data-v-43a425a6]{width:100%}.guide img[data-v-43a425a6]{width:.5rem;height:.5rem;margin:auto;margin-top:7%}h2[data-v-43a425a6]{padding-top:.4rem;font-size:.24rem;text-align:justify-all}button[data-v-43a425a6]{margin-top:7%}

+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/chunk-2e5c0360.eccac5fa.css

@@ -0,0 +1 @@
+[data-v-13871c15]:export{colorTheme:#3170f5}.nav-title[data-v-13871c15]{max-width:60%;margin:0 auto;color:#323233;font-weight:500;font-size:.16rem}.nav-title-white[data-v-13871c15]{color:#fff}*{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}input,textarea{-webkit-user-select:auto;margin:0;padding:0;outline:none}

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/chunk-2ef2613e.3df695f6.css


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/chunk-3cdd93cb.b9fbbcdc.css


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/chunk-4a1768fa.2d03b50e.css


+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/chunk-7e06598d.c94e184e.css

@@ -0,0 +1 @@
+[data-v-5c7cd7f8]:export{colorTheme:#3170f5}.comp-table[data-v-5c7cd7f8]{overflow:scroll}.comp-pagination[data-v-5c7cd7f8]{padding:.3rem 0 .1rem 0}.tableStyle{background-color:#fafafa!important;font-weight:700}.paginationStyle{text-align:center}

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/chunk-a3d3160e.fb1aa985.css


+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/chunk-b443f318.cc854d2e.css

@@ -0,0 +1 @@
+[data-v-63e1cb12]:export{colorTheme:#3170f5}.main .loginout[data-v-63e1cb12]{position:absolute;width:calc(100% - .6rem);left:.3rem;bottom:20%}

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/chunk-c6c29e7e.091c991f.css


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/chunk-d0213336.0ad54735.css


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/chunk-d76bc3fa.b590e7f2.css


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/chunk-ea283b04.e0e31ac8.css


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/npm.element-ui.c3ebd9d9.css


BIN
mjava-kuaikeli/src/main/resources/static/web/css/npm.element-ui.c3ebd9d9.css.gz


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/npm.quasar.490020f1.css


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/npm.swiper.b050859e.css


BIN
mjava-kuaikeli/src/main/resources/static/web/css/npm.swiper.b050859e.css.gz


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/css/npm.vant.ce05bcc0.css


BIN
mjava-kuaikeli/src/main/resources/static/web/css/npm.vant.ce05bcc0.css.gz


BIN
mjava-kuaikeli/src/main/resources/static/web/favicon.ico


BIN
mjava-kuaikeli/src/main/resources/static/web/fonts/element-icons.535877f5.woff


BIN
mjava-kuaikeli/src/main/resources/static/web/fonts/element-icons.732389de.ttf


BIN
mjava-kuaikeli/src/main/resources/static/web/fonts/flUhRq6tzZclQEJ-Vdg-IuiaDsNa.49f2e1a9.woff


BIN
mjava-kuaikeli/src/main/resources/static/web/fonts/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.37ce905a.woff2


BIN
mjava-kuaikeli/src/main/resources/static/web/img/404.0a45bba9.jpg


BIN
mjava-kuaikeli/src/main/resources/static/web/img/banner1-mob.43da6aa9.png


BIN
mjava-kuaikeli/src/main/resources/static/web/img/banner1.4c00ae4d.png


BIN
mjava-kuaikeli/src/main/resources/static/web/img/banner2-mob.732a8a2f.jpg


BIN
mjava-kuaikeli/src/main/resources/static/web/img/banner2.a04345c0.jpg


BIN
mjava-kuaikeli/src/main/resources/static/web/img/bg-login-mob.2c5c69fe.jpeg


BIN
mjava-kuaikeli/src/main/resources/static/web/img/logo-t.ebbe5a59.png


BIN
mjava-kuaikeli/src/main/resources/static/web/img/logo.4551336d.png


BIN
mjava-kuaikeli/src/main/resources/static/web/img/sample-media.765b7619.jpg


BIN
mjava-kuaikeli/src/main/resources/static/web/img/sample.791ebe2a.jpg


BIN
mjava-kuaikeli/src/main/resources/static/web/img/solution-media.316c8dfe.jpg


BIN
mjava-kuaikeli/src/main/resources/static/web/img/solution.de6bd68f.jpg


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 46 - 0
mjava-kuaikeli/src/main/resources/static/web/index.html


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/app.44cd3cec621a64ea50dd.0.1.0.js


BIN
mjava-kuaikeli/src/main/resources/static/web/js/app.44cd3cec621a64ea50dd.0.1.0.js.gz


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/app.d2ec944bcc584b92f92b.0.1.0.js


BIN
mjava-kuaikeli/src/main/resources/static/web/js/app.d2ec944bcc584b92f92b.0.1.0.js.gz


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-1a891981.6916d3e2acc7e84eb131.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-1bf96e69.69c12d4e4345fd1b6b7e.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-2628d9a4.18c9777608aba980dbec.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-2d0b68f8.26f922156e6856276031.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-2d0c573b.519f6e78125f4085bff5.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-2d20f795.b7bd63c92ad737e8fc00.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-2d237b24.a03e96be69d3ba31b703.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-2e5c0360.5fba8f522cb77554e1ec.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-2ef2613e.12a3d8db8b3be171ba37.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-3cdd93cb.60f0ba48e64c966ab9db.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-4a1768fa.232849728fb437a571ea.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-7e06598d.19378760d9d2f7ee0ed3.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-a3d3160e.0c5a62c4dcd3ea1f92ff.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-b443f318.00d2747b8c1ab44c715e.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-c6c29e7e.90a2005df26e713a0839.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-d0213336.c3d7d3d2d6c3c127e0b2.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-d76bc3fa.8a81344628b4810e79fa.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-ea283b04.140828ef0b43fa5c77d9.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 2 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-vendors.1634155197efea3c3a4a.0.1.0.js


+ 14 - 0
mjava-kuaikeli/src/main/resources/static/web/js/chunk-vendors.1634155197efea3c3a4a.0.1.0.js.LICENSE.txt

@@ -0,0 +1,14 @@
+/**
+ * Checks if an event is supported in the current execution environment.
+ *
+ * NOTE: This will not work correctly for non-generic events such as `change`,
+ * `reset`, `load`, `error`, and `select`.
+ *
+ * Borrows from Modernizr.
+ *
+ * @param {string} eventNameSuffix Event name, e.g. "click".
+ * @param {?boolean} capture Check if the capture phase is supported.
+ * @return {boolean} True if the event is supported.
+ * @internal
+ * @license Modernizr 3.0.0pre (Custom Build) | MIT
+ */

BIN
mjava-kuaikeli/src/main/resources/static/web/js/chunk-vendors.1634155197efea3c3a4a.0.1.0.js.gz


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/npm.async-validator.ca9586e38d471d704f8c.0.1.0.js


BIN
mjava-kuaikeli/src/main/resources/static/web/js/npm.async-validator.ca9586e38d471d704f8c.0.1.0.js.gz


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/npm.axios.1d401cc7c7d6f4c6ed74.0.1.0.js


BIN
mjava-kuaikeli/src/main/resources/static/web/js/npm.axios.1d401cc7c7d6f4c6ed74.0.1.0.js.gz


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/npm.babel-runtime.f1df8292bbe4d97d3934.0.1.0.js


BIN
mjava-kuaikeli/src/main/resources/static/web/js/npm.babel-runtime.f1df8292bbe4d97d3934.0.1.0.js.gz


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
mjava-kuaikeli/src/main/resources/static/web/js/npm.core-js.86f5d82bef78e8377235.0.1.0.js


BIN
mjava-kuaikeli/src/main/resources/static/web/js/npm.core-js.86f5d82bef78e8377235.0.1.0.js.gz


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 2 - 0
mjava-kuaikeli/src/main/resources/static/web/js/npm.crypto-js.11b1e812fb36f828e617.0.1.0.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 16 - 0
mjava-kuaikeli/src/main/resources/static/web/js/npm.crypto-js.11b1e812fb36f828e617.0.1.0.js.LICENSE.txt


BIN
mjava-kuaikeli/src/main/resources/static/web/js/npm.crypto-js.11b1e812fb36f828e617.0.1.0.js.gz


+ 0 - 0
mjava-kuaikeli/src/main/resources/static/web/js/npm.dom7.22141fb3b93f945443bc.0.1.0.js


이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.