leichao 9 mēneši atpakaļ
vecāks
revīzija
9353fdb9b6
37 mainītis faili ar 1841 papildinājumiem un 425 dzēšanām
  1. 0 118
      .idea/qg-springboot.iml
  2. 36 1
      pom.xml
  3. 59 15
      src/main/java/com/sy/controller/GoodsController.java
  4. 5 4
      src/main/java/com/sy/controller/OrdersController.java
  5. 41 0
      src/main/java/com/sy/controller/WebsocketController.java
  6. 4 0
      src/main/java/com/sy/entity/Goods.java
  7. 91 0
      src/main/java/com/sy/entity/Product.java
  8. 93 0
      src/main/java/com/sy/entity/ProductRequest.java
  9. 32 0
      src/main/java/com/sy/entity/ProductUnitRel.java
  10. 33 0
      src/main/java/com/sy/entity/ProductUnitRelRequest.java
  11. 46 0
      src/main/java/com/sy/entity/Warehouse.java
  12. 7 0
      src/main/java/com/sy/entity/goodsVoDto/GoodsDelVo.java
  13. 5 0
      src/main/java/com/sy/entity/goodsVoDto/GoodsInfoVo.java
  14. 4 0
      src/main/java/com/sy/entity/goodsVoDto/GoodsVoInParameter.java
  15. 15 0
      src/main/java/com/sy/entity/goodsVoDto/UnpackGoods.java
  16. 4 0
      src/main/java/com/sy/entity/orderVoDto/OrdersGoodsRefundLogInfoDTO.java
  17. 11 0
      src/main/java/com/sy/entity/orderVoDto/OrdersVo.java
  18. 11 0
      src/main/java/com/sy/entity/websocet/MessagePo.java
  19. 3 2
      src/main/java/com/sy/mapper/goods/GoodsMapper.java
  20. 10 0
      src/main/java/com/sy/mapper/goods/UnpackGoodsMapper.java
  21. 10 0
      src/main/java/com/sy/mapper/goods/WarehouseMapper.java
  22. 16 6
      src/main/java/com/sy/mapper/orders/OrdersMapper.java
  23. 38 0
      src/main/java/com/sy/redisconfig/RedisConfig.java
  24. 158 51
      src/main/java/com/sy/service/GoodsService.java
  25. 181 85
      src/main/java/com/sy/service/OrdersService.java
  26. 27 4
      src/main/java/com/sy/service/RetreatGoodsService.java
  27. 10 0
      src/main/java/com/sy/service/ShopPaymentRecordService.java
  28. 12 0
      src/main/java/com/sy/service/UnpackGoodsService.java
  29. 11 0
      src/main/java/com/sy/service/WarehouseService.java
  30. 18 0
      src/main/java/com/sy/service/WarehouseServiceImpl.java
  31. 4 3
      src/main/java/com/sy/utils/ECDSASigner.java
  32. 551 0
      src/main/java/com/sy/utils/RedisUtils.java
  33. 34 0
      src/main/java/com/sy/utils/SpringUtils.java
  34. 17 0
      src/main/java/com/sy/websocetconfig/WebSocketConfig.java
  35. 104 0
      src/main/java/com/sy/websocetconfig/WsServerEndPoint.java
  36. 9 5
      src/main/resources/application.yml
  37. 131 131
      src/test/java/com/sy/QgSdkTests.java

+ 0 - 118
.idea/qg-springboot.iml

@@ -1,118 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
-  <component name="FacetManager">
-    <facet type="web" name="Web">
-      <configuration>
-        <webroots />
-        <sourceRoots>
-          <root url="file://$MODULE_DIR$/src/main/java" />
-          <root url="file://$MODULE_DIR$/src/main/resources" />
-        </sourceRoots>
-      </configuration>
-    </facet>
-    <facet type="Spring" name="Spring">
-      <configuration />
-    </facet>
-  </component>
-  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
-    <output url="file://$MODULE_DIR$/target/classes" />
-    <output-test url="file://$MODULE_DIR$/target/test-classes" />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
-      <excludeFolder url="file://$MODULE_DIR$/target" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.5.0" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.5.0" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.5.0" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.5.0" level="project" />
-    <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.14.1" level="project" />
-    <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.14.1" level="project" />
-    <orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.30" level="project" />
-    <orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
-    <orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.28" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.5.0" level="project" />
-    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.12.3" level="project" />
-    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.12.3" level="project" />
-    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.12.3" level="project" />
-    <orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.12.3" level="project" />
-    <orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.3" level="project" />
-    <orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.12.3" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.5.0" level="project" />
-    <orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.46" level="project" />
-    <orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.46" level="project" />
-    <orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.46" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.7" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.7" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.3.7" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.7" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.7" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.7" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.5.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.5.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.5.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: com.jayway.jsonpath:json-path:2.5.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.4.7" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:2.4.7" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm:9.1" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:2.3.3" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: jakarta.activation:jakarta.activation-api:1.2.2" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:3.19.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest:2.2" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter:5.7.2" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-api:5.7.2" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.1.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.opentest4j:opentest4j:1.2.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-commons:1.7.2" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-params:5.7.2" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-engine:5.7.2" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-engine:1.7.2" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:3.9.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy:1.10.22" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.10.22" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:3.2" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-junit-jupiter:3.9.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.7" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.7" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.3.7" level="project" />
-    <orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.8.2" level="project" />
-    <orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.5.0" level="project" />
-    <orderEntry type="library" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.7" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.7" level="project" />
-    <orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.1.3" level="project" />
-    <orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.5" level="project" />
-    <orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.5" level="project" />
-    <orderEntry type="library" name="Maven: com.baomidou:dynamic-datasource-spring-boot-starter:3.5.2" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.5.0" level="project" />
-    <orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.6" level="project" />
-    <orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.20" level="project" />
-    <orderEntry type="library" scope="RUNTIME" name="Maven: org.postgresql:postgresql:42.2.20" level="project" />
-    <orderEntry type="library" scope="RUNTIME" name="Maven: org.checkerframework:checker-qual:3.5.0" level="project" />
-    <orderEntry type="library" name="Maven: org.apache.poi:poi:3.9" level="project" />
-    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
-    <orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
-    <orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
-    <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
-    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:3.9" level="project" />
-    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:3.9" level="project" />
-    <orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:2.3.0" level="project" />
-    <orderEntry type="library" name="Maven: stax:stax-api:1.0.1" level="project" />
-    <orderEntry type="library" name="Maven: dom4j:dom4j:1.6.1" level="project" />
-    <orderEntry type="library" name="Maven: xml-apis:xml-apis:1.0.b2" level="project" />
-    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-boot-starter:3.5.3.1" level="project" />
-    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus:3.5.3.1" level="project" />
-    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-extension:3.5.3.1" level="project" />
-    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-core:3.5.3.1" level="project" />
-    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-annotation:3.5.3.1" level="project" />
-    <orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:4.4" level="project" />
-    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.5.0" level="project" />
-    <orderEntry type="library" name="Maven: com.belerweb:pinyin4j:2.5.0" level="project" />
-  </component>
-</module>

+ 36 - 1
pom.xml

@@ -22,6 +22,11 @@
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
@@ -70,6 +75,21 @@
             <version>3.9</version>
         </dependency>
 
+
+        <!-- Swagger 3 依赖 -->
+        <dependency>
+            <groupId>org.springdoc</groupId>
+            <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
+            <version>2.1.0</version>
+        </dependency>
+
+
+
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>8.0.28</version>
+        </dependency>
         <dependency>
             <groupId>com.baomidou</groupId>
             <artifactId>mybatis-plus-boot-starter</artifactId>
@@ -82,6 +102,21 @@
             <artifactId>pinyin4j</artifactId>
             <version>2.5.0</version>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.vaadin.external.google</groupId>
+            <artifactId>android-json</artifactId>
+            <version>0.0.20131108.vaadin1</version>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
     </dependencies>
 
     <build>
@@ -97,7 +132,7 @@
                         </goals>
                     </execution>
                 </executions>
-            </plugin>
+            </plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>8</source><target>8</target></configuration></plugin>
         </plugins>
     </build>
 </project>

+ 59 - 15
src/main/java/com/sy/controller/GoodsController.java

@@ -2,7 +2,9 @@ package com.sy.controller;
 
 
 import com.fasterxml.jackson.core.JsonProcessingException;
+import com.sy.entity.ProductRequest;
 import com.sy.entity.goodsVoDto.GoodsVoInParameter;
+import com.sy.entity.goodsVoDto.UnpackGoods;
 import com.sy.service.GoodsService;
 import com.sy.utils.ECDSASigner;
 import com.sy.utils.vo.ResultMessage;
@@ -37,45 +39,87 @@ public class GoodsController {
     private GoodsService goodsService;
 
     @PostMapping("/push")
-    public ResultMessage<Object> batchInsertGoods(@RequestBody Map<String, Object> params) {
+    public ResultMessage<Object> batchInsertGoods(@RequestBody Map<String, Object> params) throws Exception {
         if (params.containsKey("salePrice")) {
             BigDecimal bigDecimal = new BigDecimal(String.valueOf(params.get("salePrice")));
             BigDecimal stripped = bigDecimal.stripTrailingZeros();
             params.put("salePrice",stripped);
         }
-        log.info("请求的接口:/push/   params:{}",params.toString());
+        log.info("商品推送请求的接口:goods/push/   params:{}",params.toString());
         boolean verify = ECDSASigner.verify(params,publicSig);
         if (!verify){
             return ResultUtil.error(304,"签名异常!!");
         }
-        GoodsVoInParameter goodsVoInParameter =new GoodsVoInParameter();
+        ProductRequest productRequest = new ProductRequest();
         if (params.get("shopId")==null||params.get("goodsId")==null) {
             return ResultUtil.error(304,"shopId或goodsId为空,请检查");
         }
-        goodsVoInParameter.setShopId(String.valueOf(params.get("shopId")));
-        goodsVoInParameter.setGoodsId(String.valueOf(params.get("goodsId")));
+        productRequest.setShopId(Long.valueOf(String.valueOf(params.get("shopId"))));
+        productRequest.setGoodsId(Long.valueOf(String.valueOf(params.get("goodsId"))));
+
         if (params.get("goodsName")!= null) {
-            goodsVoInParameter.setGoodsName(String.valueOf(params.get("goodsName")));
+            productRequest.setName(String.valueOf(params.get("goodsName")));
         }
+
+
         if (params.get("imgUrl")!= null) {
-            goodsVoInParameter.setImgUrl(String.valueOf(params.get("imgUrl")));
+            productRequest.setImage(String.valueOf(params.get("imgUrl")));
         }
         if (params.get("barCode")!= null) {
-            goodsVoInParameter.setBarCode(String.valueOf(params.get("barCode")));
+            productRequest.setBarcode(String.valueOf(params.get("barCode")));
         }
         if (params.get("specs")!= null) {
-            goodsVoInParameter.setSpecs(String.valueOf(params.get("specs")));
+            productRequest.setSpecification(String.valueOf(params.get("specs")));
         }
         if (params.get("salePrice")!= null) {
-            goodsVoInParameter.setSalePrice(new BigDecimal(String.valueOf(params.get("salePrice"))));
-        }
-        if (params.get("stock")!= null) {
-            goodsVoInParameter.setStock(new BigDecimal(String.valueOf(params.get("stock"))));
+            productRequest.setPrice(new BigDecimal(String.valueOf(params.get("salePrice"))));
         }
+//        if (params.get("stock")!= null) {
+//            productRequest.setStock(new BigDecimal(String.valueOf(params.get("stock"))));
+//        }
         if (params.get("status")!= null) {
-            goodsVoInParameter.setStatus(Integer.valueOf(String.valueOf(params.get("status"))));
+            productRequest.setIsDisabled(Integer.valueOf(String.valueOf(params.get("status"))));
+        }
+        if (params.get("unit")!= null) {
+            productRequest.setUnit(String.valueOf(params.get("unit")));
+        }
+        if (params.get("traceCode")!= null) {
+            productRequest.setImage(String.valueOf(params.get("traceCode")));
+        }
+        return ResultUtil.data(goodsService.batchGoods(productRequest));
+    }
+
+
+    @PostMapping("/unpackGoodsPush")
+    public ResultMessage<Object> batchInsertunpackGoods(@RequestBody Map<String, Object> params) {
+        log.info("商品拆包推送请求的接口:goods/unpackGoodsPush/   params:{}",params.toString());
+        boolean verify = ECDSASigner.verify(params,publicSig);
+        if (!verify){
+            return ResultUtil.error(304,"签名异常!!");
+        }
+        UnpackGoods unpackGoods = new UnpackGoods();
+        if (params.get("shopId")==null||params.get("goodsId")==null) {
+            return ResultUtil.error(304,"shopId或goodsId为空,请检查");
+        }
+        unpackGoods.setShopId(String.valueOf(params.get("shopId")));
+        unpackGoods.setGoodsId(Integer.valueOf((String) params.get("goodsId")));
+        if (params.get("quantityAfter")!= null) {
+            unpackGoods.setQuantityAfter(Integer.valueOf((String) params.get("goodsName")));
         }
-        return ResultUtil.data(goodsService.batchGoods(goodsVoInParameter));
+        if (params.get("quantityBefore")!= null) {
+            unpackGoods.setQuantityBefore(Integer.valueOf(String.valueOf(params.get("quantityBefore"))));
+        }
+        if (params.get("unitBefore")!= null) {
+            unpackGoods.setUnitBefore(String.valueOf(params.get("unitBefore")));
+        }
+        if (params.get("unitConversion_rate")!= null) {
+            unpackGoods.setUnitConversionRate(Integer.valueOf(String.valueOf(params.get("unitConversion_rate"))));
+        }
+        if (params.get("unitAfter")!= null) {
+            unpackGoods.setUnitAfter(String.valueOf(params.get("unitAfter")));
+        }
+
+        return ResultUtil.data(goodsService.insertUnpackGoods(unpackGoods));
     }
 
 }

+ 5 - 4
src/main/java/com/sy/controller/OrdersController.java

@@ -44,7 +44,7 @@ public class OrdersController {
      */
     @PostMapping("/list")
     public ResultMessage<Object> getOrders(@RequestBody Map<String, Object> params){
-        log.info("请求的接口:/orders/   params:{}",params.toString());
+        log.info("订单查询请求的接口:/order/list   params:{}",params.toString());
         if (!ECDSASigner.verify(params, publicSig)){
             return ResultUtil.error(304,"签名异常!!");
         }
@@ -57,12 +57,13 @@ public class OrdersController {
      */
     @PostMapping("/profit/separate/list")
     public ResultMessage<Object> getOrdersAccount(@RequestBody Map<String, Object> params){
-        log.info("请求的接口:/profit/   params:{}",params.toString());
+        log.info("请求对账的接口:profit/separate/list   params:{}",params.toString());
         if (!ECDSASigner.verify(params,publicSig)){
             return ResultUtil.error(304,"签名异常!!");
         }
         OrderInParameter argument = getArgument(params);
-        return ResultUtil.data(ordersService.getOrdersStatementOfAccount(argument));
+        return ResultUtil.data(ordersService.getOrdersStatementOfAccountNew(argument));
+
     }
 
     /**
@@ -70,7 +71,7 @@ public class OrdersController {
      */
     @PostMapping("/refund/list")
     public ResultMessage<Object> selectRefundList(@RequestBody Map<String, Object> params)  {
-        log.info("请求的接口:/refund/   params:{}",params.toString());
+        log.info("请求的退款接口:/refund/list   params:{}",params.toString());
         if (!ECDSASigner.verify(params,publicSig)){
             return ResultUtil.error(304,"签名异常!!");
         }

+ 41 - 0
src/main/java/com/sy/controller/WebsocketController.java

@@ -0,0 +1,41 @@
+package com.sy.controller;
+
+
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.sy.entity.websocet.MessagePo;
+
+import com.sy.websocetconfig.WsServerEndPoint;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.web.bind.annotation.*;
+
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.util.Map;
+
+
+@RestController
+@Slf4j
+@RequestMapping("/websocket")
+public class WebsocketController {
+    @Resource
+    private WsServerEndPoint wsServerEndPoint;// 引入websocket终端
+
+
+    @RequestMapping("/sendMsg")
+    @CrossOrigin  // 解决跨域问题
+    public void sendMsg(@RequestBody Map<String, Object> params) throws IOException {
+        if (params.get("shop_id")!= null&&params.get("user_id")!= null&&params.get("weight")!= null&&params.get("fs")!= null) {
+            ObjectMapper objectMapper = new ObjectMapper();
+            String jsonString = objectMapper.writeValueAsString(params);
+
+
+            wsServerEndPoint.sendMsgToUser(jsonString,(String)params.get("shop_id")+(String)params.get("user_id"));
+        }
+
+    }
+
+}

+ 4 - 0
src/main/java/com/sy/entity/Goods.java

@@ -118,5 +118,9 @@ public class Goods {
 
     private Integer isThirdTicket=0;
 
+    private String specsNew;//商品规格
+
+    private String traceCode;//商品溯源码
+
 }
 

+ 91 - 0
src/main/java/com/sy/entity/Product.java

@@ -0,0 +1,91 @@
+package com.sy.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Data
+@TableName("p_products")
+public class Product {
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    private Long shopId;
+    private String name;
+    private String barcode;
+    @TableField("category_id")
+    private Long categoryId;
+    private String unit;
+    private String specification;
+    private String specUnit;
+    private BigDecimal price;
+    private BigDecimal costPrice;
+    private Integer stockWarning;
+    private Boolean isMultiUnit;
+    private String baseUnit;
+    private Boolean isWeighted;
+    private BigDecimal pricePerKg;
+    private Boolean canSplit;
+    private String image;
+    private String description;
+    private String tags;
+    private Integer isDisabled;
+    private LocalDateTime createdAt;
+    private LocalDateTime updatedAt;
+    
+    @Schema(description = "仓库名称")
+    private String warehouseName;
+    
+    @Schema(description = "是否允许无库存销售:0-不允许,1-允许")
+    private Integer allowNoStock;
+    
+    @Schema(description = "默认销售单位")
+    private String defaultSaleUnit;
+    
+    @TableField(exist = false)
+    private String categoryName;
+    @TableField(exist = false)
+    private List<String> tagNames;
+    @TableField(exist = false)
+    @Schema(description = "库存信息列表")
+    private List<StockInfo> stocks;
+    
+    @TableField(exist = false)
+    @Schema(description = "商品库存")
+    private BigDecimal stock;
+    
+    @TableField(exist = false)
+    @Schema(description = "商品单位关联信息")
+    private List<ProductUnitRel> unitRels;
+    
+    @Data
+    @Schema(description = "商品库存信息")
+    public static class StockInfo {
+        @Schema(description = "库存ID")
+        private Long stockId;
+        
+        @Schema(description = "库存数量")
+        private BigDecimal stock;
+        
+        @Schema(description = "预警库存")
+        private BigDecimal warningStock;
+        
+        @Schema(description = "单位ID")
+        private Long unitId;
+        
+        @Schema(description = "单位名称")
+        private String unitName;
+        
+        @Schema(description = "仓库ID")
+        private Long warehouseId;
+        
+        @Schema(description = "更新时间")
+        private LocalDateTime updateTime;
+    }
+} 

+ 93 - 0
src/main/java/com/sy/entity/ProductRequest.java

@@ -0,0 +1,93 @@
+package com.sy.entity;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.DecimalMin;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+@Schema(description = "商品请求参数")
+public class ProductRequest {
+    @NotNull(message = "店铺id不能为空")
+    @Schema(description = "店铺id")
+    private Long shopId;
+
+
+    @NotNull(message = "商品id不能为空")
+    @Schema(description = "商品id")
+    private Long goodsId;
+
+    @NotBlank(message = "商品名称不能为空")
+    @Schema(description = "商品名称")
+    private String name;
+
+    @Schema(description = "商品条码")
+    private String barcode;
+
+    @Schema(description = "分类ID")
+    private Long categoryId;
+
+    @NotBlank(message = "商品单位不能为空")
+    @Schema(description = "商品单位")
+    private String unit;
+
+    @Schema(description = "商品规格")
+    private String specification;
+
+    @Schema(description = "规格单位")
+    private String specUnit;
+
+    @NotNull(message = "销售价不能为空")
+    @DecimalMin(value = "0.01", message = "销售价必须大于0")
+    @Schema(description = "销售价")
+    private BigDecimal price;
+
+    @Schema(description = "成本价")
+    private BigDecimal costPrice;
+
+    @Schema(description = "库存预警值")
+    private Integer stockWarning;
+
+    @Schema(description = "是否多规格")
+    private Boolean isMultiUnit;
+
+    @Schema(description = "基础单位")
+    private String baseUnit;
+
+    @Schema(description = "是否称重商品")
+    private Boolean isWeighted;
+
+    @Schema(description = "每千克价格")
+    private BigDecimal pricePerKg;
+
+    @Schema(description = "是否可拆包")
+    private Boolean canSplit;
+
+    @Schema(description = "商品图片")
+    private String image;
+
+    @Schema(description = "商品描述")
+    private String description;
+
+    @Schema(description = "商品标签ID列表,以逗号分隔")
+    private String tags;
+
+    @Schema(description = "商品上架1代表上架,0代表下架")
+    private Integer isDisabled;
+
+    @Schema(description = "商品单位列表")
+    private List<ProductUnitRelRequest> units;
+    
+    @Schema(description = "仓库名称")
+    private String warehouseName;
+    
+    @Schema(description = "是否允许无库存销售:0-不允许,1-允许")
+    private Integer allowNoStock;
+    
+    @Schema(description = "默认销售单位")
+    private String defaultSaleUnit;
+} 

+ 32 - 0
src/main/java/com/sy/entity/ProductUnitRel.java

@@ -0,0 +1,32 @@
+package com.sy.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+@TableName("p_product_unit_rel")
+public class ProductUnitRel {
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    
+    private Long shopId;
+    
+    private Long productId;
+    
+    private Long unitId;  // 关联unit表的ID
+    
+    private Integer ratio;  // 换算比例
+    
+    private BigDecimal price;  // 单位对应的价格
+    
+    private String smallUnitName;  // 小单位名称
+    
+    private LocalDateTime createTime;
+    
+    private LocalDateTime updateTime;
+} 

+ 33 - 0
src/main/java/com/sy/entity/ProductUnitRelRequest.java

@@ -0,0 +1,33 @@
+package com.sy.entity;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.DecimalMin;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Positive;
+import java.math.BigDecimal;
+
+@Data
+@Schema(description = "商品单位关联请求参数")
+public class ProductUnitRelRequest {
+    
+    @NotNull(message = "单位ID不能为空")
+    @Schema(description = "单位ID")
+    private Long unitId;
+    
+    @NotNull(message = "换算比例不能为空")
+    @Positive(message = "换算比例必须大于0")
+    @Schema(description = "换算比例")
+    private Integer ratio;
+    
+    @NotNull(message = "单位价格不能为空")
+    @DecimalMin(value = "0.01", message = "单位价格必须大于0")
+    @Schema(description = "单位价格")
+    private BigDecimal price;
+
+    @NotBlank(message = "小单位名称不能为空")
+    @Schema(description = "小单位名称")
+    private String smallUnitName;
+} 

+ 46 - 0
src/main/java/com/sy/entity/Warehouse.java

@@ -0,0 +1,46 @@
+package com.sy.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@TableName("p_warehouse")
+@Schema(description = "仓库信息")
+public class Warehouse {
+    
+    @TableId(type = IdType.AUTO)
+    @Schema(description = "主键ID")
+    private Long id;
+    
+    @Schema(description = "仓库名称")
+    private String name;
+    
+    @Schema(description = "地址")
+    private String address;
+    
+    @Schema(description = "店铺id")
+    private Long shopId;
+    
+    @Schema(description = "负责人")
+    private String manager;
+    
+    @Schema(description = "联系电话")
+    private String phone;
+    
+    @Schema(description = "状态:0禁用,1启用")
+    private Integer status;
+    
+    @Schema(description = "备注")
+    private String remark;
+    
+    @Schema(description = "创建时间")
+    private LocalDateTime createTime;
+    
+    @Schema(description = "更新时间")
+    private LocalDateTime updateTime;
+} 

+ 7 - 0
src/main/java/com/sy/entity/goodsVoDto/GoodsDelVo.java

@@ -16,4 +16,11 @@ public class GoodsDelVo {
     private BigDecimal amount;//订单总金额
     private Long refundTime;//订单创建时间
     private List<OrdersGoodsRefundLogInfoDTO> goodsInfo;
+
+    private String refundPaymentType;
+    private BigDecimal refundMemberFee;
+    private BigDecimal refundCashFee;
+    private BigDecimal refundAmountFee;
+    private BigDecimal refundPayWxFee;
+    private BigDecimal refundPayAlipayFee;
 }

+ 5 - 0
src/main/java/com/sy/entity/goodsVoDto/GoodsInfoVo.java

@@ -10,4 +10,9 @@ public class GoodsInfoVo {
     private BigDecimal price;
     private BigDecimal count;
     private BigDecimal amount;
+
+    private String goodsUnit;
+
+
+
 }

+ 4 - 0
src/main/java/com/sy/entity/goodsVoDto/GoodsVoInParameter.java

@@ -25,4 +25,8 @@ public class GoodsVoInParameter {
 
     private Integer status;//商品状态
 
+    private String unit;//库存单位
+
+    private String traceCode;//商品溯源码
+
 }

+ 15 - 0
src/main/java/com/sy/entity/goodsVoDto/UnpackGoods.java

@@ -0,0 +1,15 @@
+package com.sy.entity.goodsVoDto;
+
+import lombok.Data;
+
+@Data
+public class UnpackGoods {
+
+    private String  shopId;
+    private Integer   goodsId;
+    private Integer  quantityBefore;
+    private String  unitBefore;
+    private Integer   unitConversionRate;
+    private Integer  quantityAfter;
+    private String  unitAfter;
+}

+ 4 - 0
src/main/java/com/sy/entity/orderVoDto/OrdersGoodsRefundLogInfoDTO.java

@@ -10,4 +10,8 @@ public class OrdersGoodsRefundLogInfoDTO {
     private BigDecimal price;//退货价格	实际退款的单价
     private BigDecimal count;//商品数量
     private BigDecimal amount;//退款总金额
+
+    private String goodsUnit;
+
+
 }

+ 11 - 0
src/main/java/com/sy/entity/orderVoDto/OrdersVo.java

@@ -22,5 +22,16 @@ public class OrdersVo {
     private String paymentTime;
     private String paymentType;
     private String paymentUser;
+
+
+    private BigDecimal orderDiscountFee;
+    private BigDecimal orderEraseFee;
+    private BigDecimal orderFee;
+    private BigDecimal payMemberFee;
+    private BigDecimal payCashFee;
+    private BigDecimal payWxFee;
+    private BigDecimal payAlipayFee;
+    private BigDecimal payTagFee;
+
     private List<GoodsInfoVo> goodsInfo;
 }

+ 11 - 0
src/main/java/com/sy/entity/websocet/MessagePo.java

@@ -0,0 +1,11 @@
+package com.sy.entity.websocet;
+
+import lombok.Data;
+
+
+@Data
+public class MessagePo {
+    private String msg;
+    private String sendUser;
+    private String toUser;
+}

+ 3 - 2
src/main/java/com/sy/mapper/goods/GoodsMapper.java

@@ -4,13 +4,14 @@ import com.baomidou.dynamic.datasource.annotation.DS;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.sy.entity.Goods;
 import com.sy.entity.OrdersGoodsDel;
+import com.sy.entity.Product;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Select;
 
 import java.util.List;
 
 
-@DS("goods")
-public interface GoodsMapper extends BaseMapper<Goods> {
+@DS("mall")
+public interface GoodsMapper extends BaseMapper<Product> {
 
 }

+ 10 - 0
src/main/java/com/sy/mapper/goods/UnpackGoodsMapper.java

@@ -0,0 +1,10 @@
+package com.sy.mapper.goods;
+
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sy.entity.goodsVoDto.UnpackGoods;
+
+@DS("goods")
+public interface UnpackGoodsMapper extends BaseMapper<UnpackGoods>{
+}

+ 10 - 0
src/main/java/com/sy/mapper/goods/WarehouseMapper.java

@@ -0,0 +1,10 @@
+package com.sy.mapper.goods;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import com.sy.entity.Warehouse;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface WarehouseMapper extends BaseMapper<Warehouse> {
+} 

+ 16 - 6
src/main/java/com/sy/mapper/orders/OrdersMapper.java

@@ -15,14 +15,24 @@ import java.util.List;
 public interface OrdersMapper extends BaseMapper<Orders> {
 
 
+//    @Select("SELECT * FROM orders " +
+//            "WHERE shop_id=#{shopId,jdbcType=VARCHAR} " +
+//            "and CAST(pay_at AS TIMESTAMP) >= CAST(#{startTime, jdbcType=TIMESTAMP} AS TIMESTAMP) " +
+//            "AND CAST(pay_at AS TIMESTAMP) <= CAST(#{endTime, jdbcType=TIMESTAMP} AS TIMESTAMP)" +
+//            "AND pay_status=1 AND status=20")
+//    List<Orders> getOrdersByIdAndTimestampList(@Param("startTime") Timestamp startTime,
+//                                                        @Param("endTime") Timestamp endTime,
+//                                                        @Param("shopId") String shopId);
+
+
     @Select("SELECT * FROM orders " +
             "WHERE shop_id=#{shopId,jdbcType=VARCHAR} " +
-            "and CAST(pay_at AS TIMESTAMP) >= CAST(#{startTime, jdbcType=TIMESTAMP} AS TIMESTAMP) " +
-            "AND CAST(pay_at AS TIMESTAMP) <= CAST(#{endTime, jdbcType=TIMESTAMP} AS TIMESTAMP)" +
-            "AND pay_status=1 AND status=20")
-    List<Orders> getOrdersByIdAndTimestampList(@Param("startTime") Timestamp startTime,
-                                                        @Param("endTime") Timestamp endTime,
-                                                        @Param("shopId") String shopId);
+            "AND pay_at >= #{startTime, jdbcType=TIMESTAMP} " +
+            "AND pay_at < #{endTimePlusOneSecond, jdbcType=TIMESTAMP} ")
+    List<Orders> getOrdersByIdAndTimestampList(
+            @Param("startTime") Timestamp startTime,
+            @Param("endTimePlusOneSecond") Timestamp endTimePlusOneSecond, // 注意这里参数名的变化
+            @Param("shopId") String shopId);
 
 
 }

+ 38 - 0
src/main/java/com/sy/redisconfig/RedisConfig.java

@@ -0,0 +1,38 @@
+package com.sy.redisconfig;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializer;
+
+@Configuration
+@EnableCaching
+public class RedisConfig extends CachingConfigurerSupport {
+
+    /**
+     * RedisTemplate相关配置
+     * 使redis支持插入对象
+     *
+     * @param factory
+     * @return 方法缓存 Methods the cache
+     */
+    @Bean
+    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
+        RedisTemplate<String, Object> template = new RedisTemplate<>();
+        // 配置连接工厂
+        template.setConnectionFactory(factory);
+        // 序列化 key 和hashKey采用String序列化;value和hashValue采用JSON序列化
+        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
+        template.setKeySerializer(RedisSerializer.string());
+        template.setHashKeySerializer(RedisSerializer.string());
+        // value和hashvalue采用JSON序列化
+        template.setValueSerializer(jsonRedisSerializer);
+        template.setHashValueSerializer(jsonRedisSerializer);
+        return template;
+    }
+}

+ 158 - 51
src/main/java/com/sy/service/GoodsService.java

@@ -1,22 +1,25 @@
 package com.sy.service;
 
 
+
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.sy.entity.Category;
-import com.sy.entity.Goods;
-import com.sy.entity.GoodsUnit;
+
+import com.sy.entity.*;
 import com.sy.entity.goodsVoDto.GoodsVoInParameter;
+import com.sy.entity.goodsVoDto.UnpackGoods;
+import com.sy.enums.ResultCode;
 import com.sy.mapper.goods.GoodsMapper;
+import com.sy.mapper.goods.WarehouseMapper;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 
 /**
@@ -27,64 +30,168 @@ import java.util.List;
  */
 @Service
 public class GoodsService {
+
+
     @Autowired
-    private CategoryService categoryService;
+    WarehouseMapper warehouseService;
     @Autowired
     GoodsMapper goodsMapper;
 
     @Autowired
     GoodsUnitService goodsUnitService;
 
+    @Autowired
+    UnpackGoodsService unpackGoodsService;
+
     @Transactional
-    public Integer batchGoods(GoodsVoInParameter goodsVoInParameter){
-        LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(Goods::getId, goodsVoInParameter.getGoodsId());
-        Goods goodsUpdate = goodsMapper.selectOne(queryWrapper);
-        if (goodsUpdate != null) {
-            goodsUpdate.setName(goodsVoInParameter.getGoodsName());
-            goodsUpdate.setStatus(goodsVoInParameter.getStatus());
-            goodsUpdate.setPic(goodsVoInParameter.getImgUrl());
-            goodsUpdate.setBarcode(goodsVoInParameter.getBarCode());
-            goodsUpdate.setUnit(goodsVoInParameter.getSpecs());
-            goodsUpdate.setPrice(goodsVoInParameter.getSalePrice());
-            Integer integer = updateGoods(goodsUpdate,goodsVoInParameter);
-            return integer;
-        }else {
-            //根据店铺id创建通用类别
-            String shopId = goodsVoInParameter.getShopId();
-            Category category = new Category().getSort(shopId, categoryService.getNextSequenceValue() + 1);
-            Category exists = categoryService.exists(category);
-            if (exists == null) {
-                int i = categoryService.insertOrUpdate(category);
+    public Integer batchGoods(ProductRequest request) throws Exception {
+
+        // 检查商品是否已存在
+        Integer integer = checkProductExists(request);
+        if (integer == 0) {
+            // 1. 转换并保存商品基本信息
+            Product product = convertToEntity(request);
+            int insert = goodsMapper.insert(product);
+
+            integer=insert;
+            if (insert<0) {
+                throw new Exception("500:商品创建失败");
             }
-            Goods goods = new Goods();
-            goods.setId(String.valueOf(goodsVoInParameter.getGoodsId()));
-            goods.setName(goodsVoInParameter.getGoodsName());
-            goods.setShopId(goodsVoInParameter.getShopId());
-            goods.setPic(goodsVoInParameter.getImgUrl());
-            goods.setBarcode(goodsVoInParameter.getBarCode());
-            goods.setUnit(goodsVoInParameter.getSpecs());
-            goods.setPrice(goodsVoInParameter.getSalePrice());
-            goods.setStock(goodsVoInParameter.getStock());
-            goods.setStatus(goodsVoInParameter.getStatus());
-            goods.setOperatorName("青港商户");
-            int insert = goodsMapper.insert(goods);
-            if (insert > 0) {
-                return 1;
+        }
+        return integer;
+    }
+
+    /**
+     * 检查商品是否存在
+     */
+    private Integer checkProductExists(ProductRequest request) throws Exception {
+        Integer fg=0;
+        if (request.getGoodsId() == null) {
+            return 0; // 如果goodId为空,说明是新增商品,不需要检查
+        }
+
+        LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(Product::getId, request.getGoodsId())
+                .eq(Product::getShopId, request.getShopId());
+
+        Product existingProduct = goodsMapper.selectOne(queryWrapper);
+        if (existingProduct != null) {
+            fg=1;
+            // 商品存在,执行更新操作
+            updateExistingProduct(existingProduct, request);
+        }
+        return fg;
+    }
+
+    /**
+     * 更新已存在的商品信息
+     */
+    private Integer updateExistingProduct(Product existingProduct, ProductRequest request) {
+        try {
+            // 创建更新包装器
+            LambdaUpdateWrapper<Product> updateWrapper = new LambdaUpdateWrapper<>();
+            updateWrapper.eq(Product::getId, request.getGoodsId())
+                    .eq(Product::getShopId, request.getShopId());
+
+            // 只更新非空字段
+            if (StringUtils.isNotBlank(request.getName())) {
+                updateWrapper.set(Product::getName, request.getName());
+            }
+            if (StringUtils.isNotBlank(request.getBarcode())) {
+                updateWrapper.set(Product::getBarcode, request.getBarcode());
             }
-            return 0;
+            if (StringUtils.isNotBlank(request.getSpecification())) {
+                updateWrapper.set(Product::getSpecification, request.getSpecification());
+            }
+            if (request.getPrice() != null) {
+                updateWrapper.set(Product::getPrice, request.getPrice());
+            }
+            if (StringUtils.isNotBlank(request.getImage())) {
+                updateWrapper.set(Product::getImage, request.getImage());
+            }
+            if (request.getIsDisabled() != null) {
+                updateWrapper.set(Product::getIsDisabled, request.getIsDisabled());
+            }
+            if (StringUtils.isNotBlank(request.getUnit())) {
+                updateWrapper.set(Product::getUnit, request.getUnit());
+                updateWrapper.set(Product::getDefaultSaleUnit, request.getUnit());
+            }
+
+            // 执行更新
+            int result = goodsMapper.update(existingProduct, updateWrapper);
+            if (result <= 0) {
+                System.out.println("商品[{}]更新成功"+request.getGoodsId());
+
+            }
+            return result;
+        } catch (Exception e) {
+            throw new RuntimeException("更新商品失败: " + e.getMessage());
         }
     }
 
+
+    private Product convertToEntity(ProductRequest request) {
+        Product product = new Product();
+        product.setId(request.getGoodsId());
+        product.setShopId(request.getShopId());  // 添加店铺ID
+        product.setName(request.getName());
+        product.setBarcode(request.getBarcode());
+
+        product.setCategoryId(Long.parseLong("1"));
+
+        product.setSpecification(request.getSpecification());
+
+        product.setPrice(request.getPrice());
+
+//        product.setIsWeighted(request.getIsWeighted());
+//
+//        product.setPricePerKg(request.getPricePerKg());
+
+//        product.setCanSplit(request.getCanSplit());
+        product.setImage(request.getImage());
+
+        product.setDescription("青港系统导入商品!!");
+//        product.setTags(request.getTags());
+        product.setIsDisabled(request.getIsDisabled());
+        product.setUnit(request.getUnit());
+
+        product.setDefaultSaleUnit(request.getUnit());
+
+        product.setAllowNoStock(1);
+
+        // 构建查询条件
+        LambdaQueryWrapper<Warehouse> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(Warehouse::getShopId, request.getShopId())
+                .eq(Warehouse::getStatus, 1)  // 假设有状态字段,1表示启用
+                .last("LIMIT 1");
+
+        // 执行查询
+        Warehouse warehouse = warehouseService.selectOne(queryWrapper);
+
+        product.setWarehouseName(warehouse.getName());
+
+        product.setUnit(request.getUnit());
+
+
+        return product;
+    }
+
+
+
+    public boolean insertUnpackGoods(UnpackGoods unpackGoods){
+        boolean save = unpackGoodsService.save(unpackGoods);
+        return save;
+    }
+
     public Integer updateGoods(Goods goods,GoodsVoInParameter goodsVoInParameter) {
-        LambdaUpdateWrapper<Goods> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
-        if (goodsVoInParameter.getGoodsId() != null&&goodsVoInParameter.getShopId()!=null) {
-            lambdaUpdateWrapper.eq(Goods::getShopId, goodsVoInParameter.getShopId())
-                    .eq(Goods::getId,goodsVoInParameter.getGoodsId());// 设置更新条件
-            // 如果需要更新多个字段,可以继续使用 set 方法
-            int update = goodsMapper.update(goods, lambdaUpdateWrapper);
-            return update;
-        }
+//        LambdaUpdateWrapper<Goods> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+//        if (goodsVoInParameter.getGoodsId() != null&&goodsVoInParameter.getShopId()!=null) {
+//            lambdaUpdateWrapper.eq(Goods::getShopId, goodsVoInParameter.getShopId())
+//                    .eq(Goods::getId,goodsVoInParameter.getGoodsId());// 设置更新条件
+//            // 如果需要更新多个字段,可以继续使用 set 方法
+//            int update = goodsMapper.update(goods, lambdaUpdateWrapper);
+//            return update;
+//        }
         return 0;
     }
 }

+ 181 - 85
src/main/java/com/sy/service/OrdersService.java

@@ -13,7 +13,11 @@ import org.springframework.stereotype.Service;
 import java.math.BigDecimal;
 
 
+import java.math.MathContext;
+import java.math.RoundingMode;
 import java.sql.Timestamp;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.*;
 ;
 
@@ -42,13 +46,34 @@ public class OrdersService {
     ShopPaymentRecordService shopPaymentRecordService;
 
     public List<OrdersVo> getAllByPayAt(OrderInParameter orderInParameter) {
-        List<Orders> ordersList = getOrdersList(orderInParameter);
         List<OrdersVo> ordersVos = new ArrayList<>();
+        List<Orders> ordersList = getOrdersList(orderInParameter);
+        if (ordersList.size()==0) {
+            return ordersVos;
+        }
         for (Orders order : ordersList) {
             OrdersVo ordersVo = new OrdersVo();
             List<GoodsInfoVo> goodsInfo=new ArrayList<>();
             List<OrdersGoods> orderGoodsList = ordersGoodsService.getOrderGoodsList(order.getId());
-            ordersVo.setOrderId(order.getId());
+            ShopPaymentRecord shopPaymentRecord = shopPaymentRecordService.getShopPaymentRecordById(order.getId());
+            if (shopPaymentRecord == null||order.getStatus()==100||orderGoodsList.size()==0||order.getPayStatus()==0) {
+                continue;
+            }
+            if (!"10.00".equals(String.valueOf(order.getOrderDiscount()))){
+                BigDecimal orderDiscount = order.getOrderDiscount();
+                BigDecimal allTotalFee = calculateDiscountedPrice(order.getTotalFee(), String.valueOf(orderDiscount));
+                ordersVo.setOrderDiscountFee(allTotalFee);
+            }else {
+                ordersVo.setOrderDiscountFee(new BigDecimal("0.00"));
+            }
+            ordersVo.setOrderFee(shopPaymentRecord.getFree());
+            ordersVo.setOrderEraseFee(order.getReduceFee());
+            ordersVo.setPayMemberFee(order.getBuyerDiscount());
+            ordersVo.setPayCashFee(shopPaymentRecord.getCash());
+            ordersVo.setPayWxFee(shopPaymentRecord.getWeixin());
+            ordersVo.setPayAlipayFee(shopPaymentRecord.getAlipay());
+            ordersVo.setPayTagFee(shopPaymentRecord.getZjdcodecard());
+            ordersVo.setOrderId(order.getNumber());
             ordersVo.setShopId(order.getShopId());
             ordersVo.setCount(order.getGoodsAmount());
             ordersVo.setAmount(order.getPayFeeOrigin());
@@ -57,126 +82,158 @@ public class OrdersService {
             ordersVo.setPaymentTime(String.valueOf(order.getPayAt().getTime()));
             ordersVo.setPaymentType(order.getPayment());
             ordersVo.setPaymentUser(order.getPayPersonName());
-
             for (OrdersGoods orderGoods : orderGoodsList) {
                 GoodsInfoVo goodsInfoVo=new GoodsInfoVo();
                 goodsInfoVo.setGoodsId(orderGoods.getGoodsId());
                 goodsInfoVo.setPrice(orderGoods.getSalePrice());
                 goodsInfoVo.setCount(orderGoods.getGoodsAmount());
                 goodsInfoVo.setAmount(orderGoods.getGoodsTotalPrice());
+                goodsInfoVo.setGoodsUnit(orderGoods.getGoodsUnit());
                 goodsInfo.add(goodsInfoVo);
             }
             ordersVo.setGoodsInfo(goodsInfo);
             ordersVos.add(ordersVo);
         }
-
         return ordersVos;
     }
 
 
     @Autowired
     GoodsMapper goodsMapper;
-    public Goods getTest(){
-        return goodsMapper.selectById("05eb20dc-c38e-11eb-8816-0242ac170006");
+    public String getTest(){
+        return "测试成功";
     }
 
-    public List<OrdersStatementOfAccount> getOrdersStatementOfAccount(OrderInParameter orderInParameter) {
+
+    /**
+     *
+     * 这是一个报表,暂时是不规范的,目前只需要拼接数据,以后再改(需要单独抽取配置文件)
+     * **/
+
+    public List<OrdersStatementOfAccount> getOrdersStatementOfAccountNew(OrderInParameter orderInParameter) {
         if (orderInParameter == null) {
-            return null;
+            return Collections.emptyList(); // 返回空列表而不是null
         }
+
         List<String> dayString = printDatesBetween(orderInParameter.getStartTimestamp(), orderInParameter.getEndTimestamp());
-        ArrayList<OrdersStatementOfAccount> ordersStatementOfAccounts = new ArrayList<>();
+        if (dayString == null || dayString.isEmpty()) {
+            return Collections.emptyList(); // 如果日期列表为空,则直接返回空列表
+        }
+
         List<Shop> shopList = getShopList(orderInParameter, this.shopService);
-        BigDecimal number = new BigDecimal("0.01"); // 使用字符串来避免精度问题
+        if (shopList == null || shopList.isEmpty()) {
+            return Collections.emptyList(); // 如果店铺列表为空,则直接返回空列表
+        }
+
+        List<OrdersStatementOfAccount> ordersStatementOfAccounts = new ArrayList<>();
+        BigDecimal shopRate = new BigDecimal(0.05); // 平台固定抽成,不需要读取数据库
 
-        for (String day : dayString){
-            //一天一天的统计
-            for (Shop Shop : shopList) {
+        for (String day : dayString) {
+            for (Shop shop : shopList) {
                 OrdersStatementOfAccount ordersStatementOfAccount = new OrdersStatementOfAccount();
-                //BigDecimal lakalaRate = shopPayConfigService.getShopPayConfigById(Shop.getId()).getLakalaRate();
-                BigDecimal shopRate = shopPayConfigService.getShopPayConfigById(Shop.getId()).getShopRate();
-                ArrayList<String> startAndEndTimeStamps = getStartAndEndTimeStamps(day);
-                ArrayList<OrdersDTO> ordersDTOS = new ArrayList<>();
-                List<ShopPaymentRecord> shopPaymentRecordList = shopPaymentRecordService.getShopPaymentRecordListByDay(Shop.getId(),startAndEndTimeStamps);
-                //订单总营收  总付款-线上退款-线下退款
+                Map<String, Long> stringLongMap = convertToTimestamps(day);
+                if (stringLongMap == null || !stringLongMap.containsKey("start") || !stringLongMap.containsKey("end")) {
+                    continue; // 如果转换后的时间戳映射无效,则跳过当前循环
+                }
+
+                OrderInParameter orderInParameterTime = new OrderInParameter();
+                orderInParameterTime.setStartTimestamp(stringLongMap.get("start"));
+                orderInParameterTime.setEndTimestamp(stringLongMap.get("end"));
+                orderInParameterTime.setShopId(shop.getId());
+
+                List<OrdersVo> allByPayAt = getAllByPayAt(orderInParameterTime);
+                if (allByPayAt == null || allByPayAt.isEmpty()) {
+                    continue; // 如果没有订单,则跳过当前循环
+                }
+
                 BigDecimal amount = BigDecimal.ZERO;
-                //线上支付总额	微信、支付宝等线上渠道
                 BigDecimal online_amount = BigDecimal.ZERO;
-                //现金总收取	现金渠道
                 BigDecimal offline_amount = BigDecimal.ZERO;
-                ordersStatementOfAccount.setPlatformSeparateRate(shopRate);
-                //记录订单数量
-                Integer countOrderSize=0;
-                for (ShopPaymentRecord shopPaymentRecord : shopPaymentRecordList) {
-                    Orders orders = ordersMapper.selectById(shopPaymentRecord.getOrderId());
-                    //订单金额如果为0  表示这个订单已经退款完毕 收徒为0 不需要统计
-                    if (String.valueOf(orders.getPayFee()).equals("0.00")) {
-                        continue;
-                    }
-                    countOrderSize++;
-                    if(!orders.getPayment().equals("free")){
-                        amount=amount.add(orders.getPayFee());
-                    }
-                    if(orders.getPayment().equals("cash")){
-                        offline_amount=offline_amount.add(shopPaymentRecord.getCash().subtract(shopPaymentRecord.getReturnCash()).subtract(shopPaymentRecord.getReturnOrigin()));
-                    }
-                    if(orders.getPayment().equals("weixin")){
-                        online_amount= online_amount.add(shopPaymentRecord.getWeixin().subtract(shopPaymentRecord.getReturnCash()).subtract(shopPaymentRecord.getReturnOrigin()));
-                    }
-                    if(orders.getPayment().equals("alipay")){
-                        online_amount= online_amount.add(shopPaymentRecord.getAlipay().subtract(shopPaymentRecord.getReturnCash()).subtract(shopPaymentRecord.getReturnOrigin()));
-                    }
-                    if(orders.getPayment().equals("YunShanFu")){
-                        online_amount=online_amount.add(shopPaymentRecord.getYunshanfu().subtract(shopPaymentRecord.getReturnCash()).subtract(shopPaymentRecord.getReturnOrigin()));
-                    }
-                    if(orders.getPayment().equals("membercard")){
-                        online_amount= online_amount.add(shopPaymentRecord.getMembercard().subtract(shopPaymentRecord.getReturnCash()).subtract(shopPaymentRecord.getReturnOrigin()));
-                    }
-                    if(orders.getPayment().equals("zjdcodecard")){
-                        online_amount= online_amount.add(shopPaymentRecord.getZjdcodecard().subtract(shopPaymentRecord.getReturnCash()).subtract(shopPaymentRecord.getReturnOrigin()));
-                    }
-                    if (orders.getPayment().equals("bank")) {
-                        online_amount=  online_amount.add(shopPaymentRecord.getBank().subtract(shopPaymentRecord.getReturnCash()).subtract(shopPaymentRecord.getReturnOrigin()));
-                    }
-                    if(orders.getPayment().equals("mixed")){
-                        //获取第一次支付方式
-                        if (orders.getPayment1Name().equals("cash")&&!orders.getPayment2Name().equals("cash")) {
-                            offline_amount=  offline_amount.add(orders.getPayment1Fee());
-                            online_amount= online_amount.add(orders.getPayment2Fee());
-                        }else if (orders.getPayment2Name().equals("cash")&&!orders.getPayment1Name().equals("cash")){ //第二次支付
-                            offline_amount=  offline_amount.add(orders.getPayment2Fee());
-                            online_amount=  online_amount.add(orders.getPayment1Fee());
-                        }else {
-                            online_amount= online_amount.add(orders.getPayment2Fee()).add(orders.getPayment1Fee());
-                        }
-                    }
-                    OrdersDTO ordersDTO=new OrdersDTO();
-                    ordersDTO.setOrderId(orders.getId());
-                    ordersDTO.setOrderCreateTime(orders.getCreateAt().getTime());
+                Integer countOrderSize = allByPayAt.size();
+                ArrayList<OrdersDTO> orderDetailList = new ArrayList<>();
+
+                for (OrdersVo ordersVo : allByPayAt) {
+                    amount = amount.add(ordersVo.getPayAmount());
+                    online_amount = online_amount.add(ordersVo.getPayWxFee().add(ordersVo.getPayAlipayFee()));
+
+                    OrdersDTO ordersDTO = new OrdersDTO();
+                    ordersDTO.setOrderId(ordersVo.getOrderId());
+                    ordersDTO.setOrderCreateTime(Long.valueOf(ordersVo.getCreateTime()));
                     ordersDTO.setPlatformSeparateRate(shopRate);
-                    ordersDTO.setAmount(orders.getPayFee());
-                    //门店收入等于 订单总营业额 *费率  比如费率百分之6.8  则需要转换  成0.068
-                    ordersDTO.setShopIncome(new BigDecimal(1).subtract(shopRate.multiply(number)).multiply(orders.getPayFee()));
-                    ordersDTO.setPlatformIncome(orders.getPayFee().multiply(shopRate.multiply(number)));
-                    ordersDTOS.add(ordersDTO);
+                    ordersDTO.setAmount(ordersVo.getPayAmount());
+                    BigDecimal shopIncome =( new BigDecimal(1).subtract(shopRate)).multiply(ordersVo.getPayAmount());
+                    BigDecimal platformIncome = ordersVo.getPayAmount().multiply(shopRate);
+                    ordersDTO.setShopIncome(shopIncome);
+                    ordersDTO.setPlatformIncome(platformIncome);
+                    orderDetailList.add(ordersDTO);
                 }
+
+                offline_amount = amount.subtract(online_amount);
+
+
                 ordersStatementOfAccount.setStatisticsDate(day);
-                ordersStatementOfAccount.setShopId(Shop.getId());
+                ordersStatementOfAccount.setShopId(shop.getId());
+                ordersStatementOfAccount.setPlatformSeparateRate(shopRate);
                 ordersStatementOfAccount.setOrderCount(countOrderSize);
                 ordersStatementOfAccount.setAmount(amount);
                 ordersStatementOfAccount.setOnlineAmount(online_amount);
                 ordersStatementOfAccount.setOfflineAmount(offline_amount);
-                ordersStatementOfAccount.setOrderDetailList(ordersDTOS);
-                ordersStatementOfAccount.setShopAmount(new BigDecimal(1).subtract(shopRate.multiply(number)).multiply(amount));
-                ordersStatementOfAccount.setPlatformAmount(shopRate.multiply(number).multiply(amount));
+                MathContext mc = new MathContext(2, RoundingMode.DOWN);
+                BigDecimal shopAmount = (new BigDecimal(1).subtract(shopRate)).multiply(amount).setScale(mc.getPrecision(), mc.getRoundingMode());;
+                BigDecimal platformAmount = shopRate.multiply(amount).setScale(mc.getPrecision(), mc.getRoundingMode());;
+                ordersStatementOfAccount.setShopAmount(shopAmount);
+                ordersStatementOfAccount.setPlatformAmount(platformAmount);
                 ordersStatementOfAccounts.add(ordersStatementOfAccount);
+                ordersStatementOfAccount.setOrderDetailList(orderDetailList);
             }
-
         }
 
         return ordersStatementOfAccounts;
     }
 
+
+
+
+    /**
+     * 根据日期获取当天开始和结束的时间戳
+     * */
+    public static Map<String, Long> convertToTimestamps(String dateStr) {
+        SimpleDateFormat inputFormat = new SimpleDateFormat("yyyyMMdd");
+        inputFormat.setTimeZone(TimeZone.getTimeZone("UTC")); // Set to UTC if needed
+        Map<String, Long> timestampMap = new HashMap<>();
+        try {
+            Date date = inputFormat.parse(dateStr);
+
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTime(date);
+
+            // Set day (00:00:00)
+            calendar.set(Calendar.HOUR_OF_DAY, 0);
+            calendar.set(Calendar.MINUTE, 0);
+            calendar.set(Calendar.SECOND, 0);
+            calendar.set(Calendar.MILLISECOND, 0);
+            Date startOfDay = calendar.getTime();
+
+            // Set day (23:59:59.999)
+            calendar.set(Calendar.HOUR_OF_DAY, 23);
+            calendar.set(Calendar.MINUTE, 59);
+            calendar.set(Calendar.SECOND, 59);
+            calendar.set(Calendar.MILLISECOND, 999);
+            Date endOfDay = calendar.getTime();
+
+
+            timestampMap.put("start", startOfDay.getTime());
+            timestampMap.put("end", endOfDay.getTime());
+
+            return timestampMap;
+
+        } catch (ParseException e) {
+            e.printStackTrace();
+            return new HashMap<>();
+        }
+    }
+
+
    public Orders  getByIdOrder(String orderId){
         return ordersMapper.selectById(orderId);
    }
@@ -194,16 +251,55 @@ public class OrdersService {
     }
 
     static List<Shop> getShopList(OrderInParameter orderInParameter, ShopService shopService) {
-        List<Shop> qgShopAll=new ArrayList<>();
+        List<Shop> qgShopAll = new ArrayList<>();
+
+        // 判断shopId是否为null,并做相应处理
         if (orderInParameter.getShopId() == null) {
+            // 如果shopId为null,获取全部"qg"类型的商店列表
             List<Shop> qgShop = shopService.getShopQgList("qg");
-            qgShopAll.addAll(qgShop);
-        }
-        if (orderInParameter.getShopId()!= null) {
+            if (qgShop != null) {
+                qgShopAll.addAll(qgShop);
+            }
+        } else {
+            // 如果shopId不为null,获取单个商店
             Shop shopOne = shopService.getShopOne(orderInParameter.getShopId());
-            qgShopAll.add(shopOne);
+            if (shopOne != null) {
+                qgShopAll.add(shopOne);
+            }
         }
+
         return qgShopAll;
     }
 
+
+    /**
+     * 计算折扣后的价格
+     *
+     * @param originalPrice 原价,作为BigDecimal传入
+     * @param discountStr 折扣,作为字符串传入(可以是整数如"8"或小数如"8.00",表示80%的折扣保留,
+     *                    即原价的80%被计算为折扣后价格;也可以是"9.5"或"9.50",表示95%的折扣保留)
+     * @return 折扣后的价格,作为BigDecimal返回,保留两位小数
+     * @throws IllegalArgumentException 如果折扣格式无效或不在0到100之间
+     */
+    public static BigDecimal calculateDiscountedPrice(BigDecimal originalPrice, String discountStr) {
+        // 尝试将折扣字符串转换为BigDecimal,允许小数点但不允许其他非数字字符(除了负号,但在这里我们不需要负号)
+        try {
+            BigDecimal discount = new BigDecimal(discountStr.replaceAll("[^0-9.]", "")); // 仅保留数字和小数点
+
+            // 验证折扣值在0到100之间(包含0和100,表示无折扣和全额折扣)
+            if (discount.compareTo(BigDecimal.ZERO) < 0 || discount.compareTo(new BigDecimal("100")) > 0) {
+                throw new IllegalArgumentException("折扣必须在0到100之间(包含0和100)");
+            }
+
+            // 将折扣百分比转换为折扣因子(例如,"8"或"8.00"都转换为0.8)
+            BigDecimal discountFactor = discount.divide(new BigDecimal(10), 2, RoundingMode.HALF_UP);
+
+            // 计算并返回折扣后的价格(即原价乘以折扣因子,结果保留两位小数)
+            return originalPrice.multiply(discountFactor).setScale(2, RoundingMode.HALF_UP);
+
+        } catch (NumberFormatException e) {
+            // 如果转换失败(尽管上面的正则表达式应该已经避免了这种情况),则抛出异常
+            throw new IllegalArgumentException("折扣格式无效,必须是数字(可选包含小数点)", e);
+        }
+    }
 }

+ 27 - 4
src/main/java/com/sy/service/RetreatGoodsService.java

@@ -1,9 +1,7 @@
 package com.sy.service;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.sy.entity.Orders;
-import com.sy.entity.OrdersGoodsDel;
-import com.sy.entity.Shop;
+import com.sy.entity.*;
 import com.sy.entity.goodsVoDto.GoodsDelVo;
 import com.sy.entity.orderVoDto.OrderInParameter;
 import com.sy.entity.orderVoDto.OrdersGoodsRefundLogInfoDTO;
@@ -17,7 +15,6 @@ import java.util.*;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.sy.mapper.orders.RetreatGoodsMapper;
-import com.sy.entity.RetreatGoods;
 
 import static com.sy.utils.Utils.*;
 import static com.sy.utils.Utils.getTimeStr;
@@ -35,6 +32,9 @@ public class RetreatGoodsService extends ServiceImpl<RetreatGoodsMapper, Retreat
     @Autowired
     ShopService shopService;
 
+    @Autowired
+    ShopPaymentRecordService shopPaymentRecordService;
+
     public List<RetreatGoods> retreatGoodsList(OrderInParameter orderInParameter){
         List<RetreatGoods> retreatGoodsList = new ArrayList<>();
         List<Shop> qgShopAll = OrdersService.getShopList(orderInParameter, this.shopService);
@@ -75,6 +75,10 @@ public class RetreatGoodsService extends ServiceImpl<RetreatGoodsMapper, Retreat
             GoodsDelVo goodsDelVo = new GoodsDelVo();
             List<OrdersGoodsRefundLogInfoDTO> goods_Info = new ArrayList<>();//明细
             Orders byIdOrder = ordersService.getByIdOrder(entry.getKey());
+            ShopPaymentRecord shopPaymentRecordById = shopPaymentRecordService.getShopPaymentRecordById(byIdOrder.getId());
+            if (shopPaymentRecordById == null) {
+                continue;
+            }
             List<OrdersGoodsDel> goodsDelList = ordersGoodsDelService.getGoodsDel(entry.getKey());
             for (OrdersGoodsDel ordersGoodsDel : goodsDelList) {
                 OrdersGoodsRefundLogInfoDTO info = new OrdersGoodsRefundLogInfoDTO();
@@ -83,6 +87,7 @@ public class RetreatGoodsService extends ServiceImpl<RetreatGoodsMapper, Retreat
                 info.setGoodsId(ordersGoodsDel.getGoodsId());
                 info.setCount(ordersGoodsDel.getGoodsAmount());
                 info.setAmount(ordersGoodsDel.getGoodsTotalPrice());
+                info.setGoodsUnit(ordersGoodsDel.getGoodsUnit());
                 amountAll = amountAll.add(ordersGoodsDel.getGoodsTotalPrice());
                 countAllGoods = countAllGoods.add(ordersGoodsDel.getGoodsAmount());
                 goods_Info.add(info);
@@ -95,6 +100,24 @@ public class RetreatGoodsService extends ServiceImpl<RetreatGoodsMapper, Retreat
             goodsDelVo.setAmount(amountAll);
             goodsDelVo.setGoodsInfo(goods_Info);
             goodsDelVo.setShopId(byIdOrder.getShopId());
+
+            goodsDelVo.setRefundPaymentType(byIdOrder.getPayment());
+            //如果支付方式是单一方式 则原路退回 如果是混合支付则只退现金
+            if(!"mixed".equals(byIdOrder.getPayment())){
+                goodsDelVo.setRefundMemberFee(shopPaymentRecordById.getMembercard());
+                goodsDelVo.setRefundCashFee(shopPaymentRecordById.getReturnCash());
+                goodsDelVo.setRefundAmountFee(shopPaymentRecordById.getWeixin().add(shopPaymentRecordById.getAlipay()));
+                goodsDelVo.setRefundPayWxFee(shopPaymentRecordById.getWeixin());
+                goodsDelVo.setRefundPayAlipayFee(shopPaymentRecordById.getAlipay());
+            }else {
+                goodsDelVo.setRefundMemberFee(shopPaymentRecordById.getReturnOrigin());
+                goodsDelVo.setRefundCashFee(shopPaymentRecordById.getReturnCash());
+                goodsDelVo.setRefundAmountFee(shopPaymentRecordById.getReturnOrigin());
+                goodsDelVo.setRefundPayWxFee(shopPaymentRecordById.getReturnOrigin());
+                goodsDelVo.setRefundPayAlipayFee(shopPaymentRecordById.getReturnOrigin());
+            }
+
+
             maps.add(goodsDelVo);
 
         }

+ 10 - 0
src/main/java/com/sy/service/ShopPaymentRecordService.java

@@ -1,5 +1,7 @@
 package com.sy.service;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.sy.entity.OrdersGoods;
 import org.springframework.stereotype.Service;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -21,5 +23,13 @@ public class ShopPaymentRecordService {
                 Timestamp.valueOf(date.get(1)), shopIdOne);
         return allByPayAtAndShopIdBetween;
     }
+
+    public ShopPaymentRecord getShopPaymentRecordById(String orderId) {
+        LambdaQueryWrapper<ShopPaymentRecord> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(ShopPaymentRecord::getOrderId, orderId);
+        ShopPaymentRecord shopPaymentRecord = shopPaymentRecordMapper.selectOne(queryWrapper);
+
+        return shopPaymentRecord;
+    }
 }
 

+ 12 - 0
src/main/java/com/sy/service/UnpackGoodsService.java

@@ -0,0 +1,12 @@
+package com.sy.service;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+import com.sy.entity.goodsVoDto.UnpackGoods;
+
+import com.sy.mapper.goods.UnpackGoodsMapper;
+import org.springframework.stereotype.Service;
+
+@Service
+public class UnpackGoodsService extends ServiceImpl<UnpackGoodsMapper, UnpackGoods>{
+}

+ 11 - 0
src/main/java/com/sy/service/WarehouseService.java

@@ -0,0 +1,11 @@
+package com.sy.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import com.sy.entity.Warehouse;
+
+import java.util.List;
+
+public interface WarehouseService extends IService<Warehouse> {
+
+} 

+ 18 - 0
src/main/java/com/sy/service/WarehouseServiceImpl.java

@@ -0,0 +1,18 @@
+package com.sy.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sy.entity.Warehouse;
+import com.sy.mapper.goods.WarehouseMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+@Slf4j
+@Service
+public class WarehouseServiceImpl extends ServiceImpl<WarehouseMapper, Warehouse> implements WarehouseService {
+
+} 

+ 4 - 3
src/main/java/com/sy/utils/ECDSASigner.java

@@ -21,11 +21,11 @@ import java.util.TreeMap;
 @Component
 public class ECDSASigner {
     //本地公钥
-    //public static final String publicSig="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEwvbT7jUHDUbJzrU7oGPKIJhYw5DQ4xVMLqYcpUYeHIirlqghpXKpggeNmYVMYG6R2uJ7DmbajBU158ybMj70Gg==";
+    //public static final String publicSig="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEwdG4t_dBguZKA_m58zGrGvX258C70dUvvJ-vzetcShevNQXILaBqE_dMLZ2PiASb02K7-HT_4L2d_CgCmmfGuA==";
     //线上公钥
     public static final String publicSig="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmU7b_sdeNNDxyQUYLhWDfdQtXRLO1WD1U9CYZKSZNk44OcVcEg0xKvMQ1m2OY2oLlql9ggs7SVqkzyJ6oFYiVg==";
 
-    public static final String privateKeySig="MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCAmNynvNAl5h9Pob6BldE1U1anv8orqMc4z15XW2BzBmg==";
+    public static final String privateKeySig="MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCBJc4FXaoVpT75JURy2ylFFnG_x3HnXZH6dPwti6QaF-w==";
     private static final String SIGN = "sign";
 
     private static final String TIMESTAMP = "timestamp";
@@ -37,7 +37,7 @@ public class ECDSASigner {
     public static void main(String[] args) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
         Map<String, Object> params = new HashMap<>();
         params.put("startTimestamp",20240710);
-        params.put("endTimestamp", 20240715);
+        params.put("endTimestamp", 20250715);
         params.put("salePrice",12.0);
         extracted(params);
     }
@@ -177,4 +177,5 @@ public class ECDSASigner {
         return originStr.toString();
     }
 
+
 }

+ 551 - 0
src/main/java/com/sy/utils/RedisUtils.java

@@ -0,0 +1,551 @@
+package com.sy.utils;
+
+import org.apache.ibatis.annotations.Param;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.DependsOn;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+@Service
+public class RedisUtils {
+    @Autowired
+    private RedisTemplate redisTemplate;
+
+    public RedisUtils(RedisTemplate redisTemplate) {
+        this.redisTemplate = redisTemplate;
+    }
+    //region 基础操作
+    /**
+     * 指定缓存失效时间
+     * @param key 键
+     * @param time 时间(秒)
+     * @return
+     */
+    public  boolean expire(String key,long time){
+        try {
+            if(time > 0){
+                redisTemplate.expire(key,time, TimeUnit.SECONDS);
+            }
+            return true;
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 根据可以获取过期时间
+     * @param key 键(不能为null)
+     * @return 返回单位秒,返回 -1 代表永久有效
+     */
+    public long getExpire(String key){
+        return  redisTemplate.getExpire(key,TimeUnit.SECONDS);
+    }
+
+    /**
+     * 判断key是否存在
+     * @param key 键
+     * @return
+     */
+    public boolean hasKey(String key){
+        try{
+            return redisTemplate.hasKey(key);
+        }catch (Exception e){
+            e.printStackTrace();
+            return  false;
+        }
+    }
+
+    /**
+     * 删除1个或多个缓存
+     * @param keys
+     */
+    public long del(String ...keys){
+        if(keys != null && keys.length > 0){
+            if(keys.length ==1){
+                return  redisTemplate.delete(keys[0]) ? 1L:0L;
+            }else {
+                return redisTemplate.delete(CollectionUtils.arrayToList(keys)) ;
+            }
+        }
+        return  0L;
+    }
+
+    /**
+     * 模糊查询获取key值
+     * @param pattern
+     * @return
+     */
+    public Set keys(String pattern){
+        return  redisTemplate.keys(pattern);
+    }
+
+    /**
+     * 使用redis的消息队列
+     * @param channel
+     * @param message 消息内容
+     */
+    public  void  convertAndSend(String channel, Object message){
+        redisTemplate.convertAndSend(channel,message);
+    }
+    //endregion
+    //region String
+
+    /**
+     * 获取普通缓存获取
+     * @param key 键
+     * @return 值
+     */
+    public Object get(String key){
+        return key == null? null: redisTemplate.opsForValue().get(key);
+    }
+
+    /**
+     * 设置普通缓存
+     * @param key 键
+     * @param value 值
+     * @return
+     */
+    public boolean set(String key, Object value){
+        try{
+            redisTemplate.opsForValue().set(key,value);
+            return  true;
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 设置缓存放入,并设置时间
+     * @param key 键
+     * @param value 值
+     * @param time 时间秒(time值小于0,怎设置无限期)
+     * @return
+     */
+    public  boolean set(String key,Object value, long time){
+        try{
+            if(time > 0){
+                redisTemplate.opsForValue().set(key,value,time,TimeUnit.SECONDS);
+            }else {
+                redisTemplate.opsForValue().set(key,value);
+            }
+            return true;
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 递增
+     * @param key 键
+     * @param delta 要增加的值
+     * @return
+     */
+    public long incr(String key,long delta){
+        if(delta < 0){
+            throw new RuntimeException("递增因子,必须大于0");
+        }
+        return  redisTemplate.opsForValue().increment(key,delta);
+    }
+
+    /**
+     * 递减
+     * @param key 键
+     * @param delta 要减小的值
+     * @return
+     */
+    public long descr(String key ,long delta){
+        if(delta < 0){
+            throw new RuntimeException("递减因子,必须大于0");
+        }
+        return  redisTemplate.opsForValue().increment(key,-delta);
+    }
+    //endregion
+    //region hash
+    /**
+     * 向一张hash表中放入数据,如果不存在将创建
+     * @param key 键
+     * @param item 项
+     * @param value 值
+     * @return
+     */
+    public  boolean hset(String key, String item, Object value){
+        try{
+            redisTemplate.opsForHash().put(key,item,value);
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 向一张表中放入数据,如果不存在,则创建
+     * @param key 键
+     * @param item 项
+     * @param value 值
+     * @param time 时间(秒),如果已存在的hash表有时间,这里将会替换原有的时间
+     * @return
+     */
+    public boolean hset(String key, String item, Object value, long time){
+        try{
+            redisTemplate.opsForHash().put(key,item,value);
+            if(time > 0){
+                redisTemplate.expire(key,time, TimeUnit.SECONDS);
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 删除hash表中的值
+     * @param key 键
+     * @param items 项,可以多个,不能为空
+     */
+    public  void hdel(String key, Object ...items){
+        redisTemplate.opsForHash().delete(key, items);
+    }
+
+    /**
+     * 获取Hash值
+     * @param key 键,不能为空
+     * @param item 项目不能为空
+     * @return
+     */
+    public  Object hget(String key, String item){
+        return redisTemplate.opsForHash().get(key,item);
+    }
+
+    /**
+     * 获取HashKey的所有键值
+     * @param key 键
+     * @return
+     */
+    public  Map<Object,Object> hmget(String key){
+        return  redisTemplate.opsForHash().entries(key);
+    }
+    /**
+     * 设置HashKey的所有键值
+     * @param key 键
+     * @param map 对应多个键值
+     * @return
+     */
+    public  boolean hmset(String key, Map<String , Object> map){
+        try {
+            redisTemplate.opsForHash().putAll(key,map);
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+        return  true;
+    }
+
+    /**
+     * HashSet 并设置时间
+     * @param key 键
+     * @param map 对应多个键值
+     * @param time 时间(秒)
+     * @return
+     */
+    public  boolean hmset(String key, Map<String , Object> map,long time){
+        try {
+            redisTemplate.opsForHash().putAll(key,map);
+            if(time > 0){
+                redisTemplate.expire(key,time,TimeUnit.SECONDS);
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+        return  true;
+    }
+
+    /**
+     * 判断hash表中是否有该项值
+     * @param key 键,不能为空
+     * @param item 项,不能为空
+     * @return
+     */
+    public  boolean hHashKey(String  key,String item){
+        return  redisTemplate.opsForHash().hasKey(key,item);
+    }
+
+    /**
+     * hash递增,如果不存在就会创建一个,并把新增后的值返回
+     * @param key 键
+     * @param item 项
+     * @param by 要增大几(大于0)
+     * @return
+     */
+    public double hinc(String key, String item, double by){
+        return  redisTemplate.opsForHash().increment(key,item,by);
+    }
+
+    /**
+     * hash递减
+     * @param key 键
+     * @param item 项
+     * @param by 要减小几(大于0)
+     * @return
+     */
+    public double hdescr(String key, String item, double by){
+        return  redisTemplate.opsForHash().increment(key,item,-by);
+    }
+    //endregion
+    //region set
+    /**
+     * 根据key,获取set的所有值
+     * @param key 键
+     * @return
+     */
+    public  Set<Object> sGet(String key){
+        try {
+            return redisTemplate.opsForSet().members(key);
+        }catch (Exception e){
+            e.printStackTrace();
+            return  null;
+        }
+    }
+
+    /**
+     * 根据value一个set查询,是否存在
+     * @param key 键
+     * @param value 值
+     * @return
+     */
+    public boolean sHashKey(String key, Object value){
+        try {
+            return redisTemplate.opsForSet().isMember(key,value);
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 将数据放入set缓存
+     * @param key 键
+     * @param values 值,可以时多个
+     * @return
+     */
+    public  long sSet(String key, Object... values){
+        try {
+            return  redisTemplate.opsForSet().add(key,values);
+        }catch (Exception e){
+            e.printStackTrace();
+            return  0;
+        }
+    }
+    /**
+     * 将数据放入set缓存,并设置时间
+     * @param key 键
+     * @param time 时间(秒)
+     * @param values 值,可以时多个
+     * @return
+     */
+    public  long sSetAndTime(String key,long time, Object... values){
+        try {
+            long count =  redisTemplate.opsForSet().add(key,values);
+            if(time > 0){
+                redisTemplate.expire(key,time,TimeUnit.SECONDS);
+            }
+            return  count;
+        }catch (Exception e){
+            e.printStackTrace();
+            return  0;
+        }
+    }
+
+    /***
+     * 获取Set缓存长度
+     * @param key
+     * @return
+     */
+    public  long sGetSetSize(String key){
+        try {
+            return  redisTemplate.opsForSet().size(key);
+        }catch (Exception e){
+            e.printStackTrace();
+            return  0;
+        }
+    }
+
+    /**
+     * 移除值为value的缓存
+     * @param key
+     * @param values
+     * @return
+     */
+    public  long setRemove(String key, Object ... values){
+        try {
+            return  redisTemplate.opsForSet().remove(key,values);
+        }catch (Exception e){
+            e.printStackTrace();
+            return 0;
+        }
+    }
+    //endregion
+    //region list
+
+    /**
+     * 获取list 缓存内容
+     * @param key 键
+     * @param start 开始位置
+     * @param end 结束位置 0 到-1代表所有值
+     * @return
+     */
+    public List<Object> lGet(String key, long start, long end){
+        try {
+            return redisTemplate.opsForList().range(key,start,end);
+        }catch (Exception e){
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 获取list缓存长度
+     * @param key 键
+     * @return
+     */
+    public  long lGetListSize(String key){
+        try{
+            return  redisTemplate.opsForList().size(key);
+        }catch (Exception e){
+            e.printStackTrace();
+            return  0;
+        }
+    }
+
+    /**
+     * 通过索引获取list的值
+     * @param key 键
+     * @param index 索引(> 0,索引),-1表尾,-2倒数第二个元素,以此类推
+     * @return
+     */
+    public  Object lGetIndex(String key,long index){
+        try{
+            return redisTemplate.opsForList().index(key,index);
+        }catch (Exception e){
+            e.printStackTrace();
+            return  null;
+        }
+    }
+
+    /**
+     * 将list缓存
+     * @param key 键
+     * @param value 值
+     * @return
+     */
+    public long lSet(String key, Object value){
+        try{
+            return redisTemplate.opsForList().rightPush(key,value);
+        }catch (Exception e){
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 将list缓存,并设置时间
+     * @param key 键
+     * @param value 值
+     * @param time 时间(秒)
+     * @return
+     */
+    public  long lSet(String key, Object value, long time){
+        try{
+            long result =  redisTemplate.opsForList().rightPush(key,value);
+            if(time > 0){
+                redisTemplate.expire(key,time,TimeUnit.SECONDS);
+            }
+            return result;
+        }catch (Exception e){
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 将list放入缓存
+     * @param key 键
+     * @param value 值
+     * @return
+     */
+    public long  lSet(String key, List<Object> value){
+        try{
+            return redisTemplate.opsForList().rightPushAll(key,value);
+        }catch (Exception e){
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 将list放入缓存
+     * @param key 键
+     * @param value 值
+     * @param time 时间(秒)
+     * @return
+     */
+    public long  lSet(String key, List<Object> value,long time){
+        try{
+            long result =  redisTemplate.opsForList().rightPushAll(key,value);
+            if(time > 0){
+                redisTemplate.expire(key,time,TimeUnit.SECONDS);
+            }
+            return result;
+        }catch (Exception e){
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 根据索引修改list的某条数据
+     * @param key 键
+     * @param index 索引
+     * @param value 值
+     * @return
+     */
+    public boolean lUpdateIndex(String key,long index, Object value){
+        try{
+            redisTemplate.opsForList().set(key,index,value);
+            return  true;
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 移除N个值为value
+     * @param key 键
+     * @param count 移除多少个
+     * @param value 值
+     * @return
+     */
+    public long lRemove(String key, long count, String value){
+        try {
+            return  redisTemplate.opsForList().remove(key,count,value);
+        }catch (Exception e){
+            e.printStackTrace();
+            return  0;
+        }
+    }
+    // endregion
+}

+ 34 - 0
src/main/java/com/sy/utils/SpringUtils.java

@@ -0,0 +1,34 @@
+package com.sy.utils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class SpringUtils implements BeanFactoryPostProcessor {
+
+    //Spring应用上下文环境
+    private static ConfigurableListableBeanFactory beanFactory;
+
+    @Override
+    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+        SpringUtils.beanFactory = beanFactory;
+    }
+
+    public static ConfigurableListableBeanFactory getBeanFactory() {
+        return beanFactory;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> T getBean(String name) throws BeansException {
+        return (T) getBeanFactory().getBean(name);
+    }
+
+    public static <T> T getBean(Class<T> clz) throws BeansException {
+        T result = (T) getBeanFactory().getBean(clz);
+        return result;
+    }
+}
+

+ 17 - 0
src/main/java/com/sy/websocetconfig/WebSocketConfig.java

@@ -0,0 +1,17 @@
+//package com.sy.websocetconfig;
+//
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.Configuration;
+//import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+//
+///**
+// * @Description websocket 配置类
+// * @Date 2024/5/18 20:28
+// **/
+//@Configuration
+//public class WebSocketConfig {
+//    @Bean
+//    public ServerEndpointExporter serverendpointExporter(){
+//        return new ServerEndpointExporter();
+//    }
+//}

+ 104 - 0
src/main/java/com/sy/websocetconfig/WsServerEndPoint.java

@@ -0,0 +1,104 @@
+package com.sy.websocetconfig;
+
+
+import com.sy.utils.RedisUtils;
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.websocket.*;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @Description 监听websocket地址  /myWs
+ **/
+@ServerEndpoint("/myWs/{user_id}")
+@Component
+@Slf4j
+public class WsServerEndPoint {
+    // ConcurrentHashMap 和hashMap的区别是 ConcurrentHashMap是线程安全的
+    static Map<String, Session> sessionMap = new ConcurrentHashMap<>();
+    public static RedisUtils redisUtils;
+
+    @Autowired
+    private void WsServerEndPoint(RedisUtils redisUtils) {
+        WsServerEndPoint.redisUtils = redisUtils;
+    }
+
+    /**
+     * websocket建立链接时触发方法
+     *
+     * @param session 每一个websocket的链接 对于服务端都是一个session
+     **/
+    @OnOpen
+    public void onOpen(Session session, @PathParam("user_id") String userId) {
+        // 建立连接时,将session存入map中 使用用户ID作为sessionMap的key
+        sessionMap.put(userId, session);
+//        redisUtils.set(userId,userId);
+        log.info("websocket is open");
+        log.info(userId);
+    }
+
+    /**
+     * 收到了客户端消息时触发方法
+     *
+     * @param text 客户端传来的消息内容
+     * @return java.lang.String
+     **/
+    @OnMessage
+    public void onMessage(String text, Session session) {
+        // 解析文本消息以获取用户ID(如果需要),或处理消息内容
+        log.info("Received message: " + text + " from session: " + session.getId());
+    }
+
+    /**
+     * 连接关闭时触发方法
+     *
+     * @param session 每一个websocket的链接 对于服务端都是一个session
+     **/
+    @OnClose
+    public void onClose(Session session, @PathParam("user_id") String userId) {
+
+        sessionMap.values().removeIf(s -> s.getId().equals(session.getId()));
+//        redisUtils.del(userId);
+        log.info("WebSocket is closed for user: " + userId);
+        System.out.println(sessionMap.toString());
+    }
+
+
+    /**
+     * 发送消息
+     *
+     * @param message
+     **/
+    public void sendMsgToUser(String message, String toUserId) throws IOException {
+        // 首先从本地的 sessionMap 中尝试获取 Session 对象
+        Session session = sessionMap.get(toUserId);
+
+//        // 如果本地的 sessionMap 中没有,那么尝试从 Redis 中获取会话标识符
+//        if (session == null) {
+//            String sessionId = (String) redisUtils.get(toUserId);
+//
+//            // 如果从 Redis 中获取到了会话标识符,那么再次尝试从 sessionMap 中获取 Session 对象
+//            if (sessionId != null) {
+//                session = sessionMap.get(sessionId); // 注意这里应该是用 sessionId 而不是 toUserId
+//            }
+//        }
+
+        // 如果最终获取到了 Session 对象,那么发送消息
+        if (session != null) {
+            RemoteEndpoint.Basic basicRemote = session.getBasicRemote();
+            basicRemote.sendText(message);
+        } else {
+            // 如果没有获取到 Session 对象,那么记录日志或抛出异常
+            log.error("Unable to find WebSocket session for user ID: {}", toUserId);
+//            throw new IOException("WebSocket session not found for user ID: " + toUserId);
+        }
+    }
+
+}

+ 9 - 5
src/main/resources/application.yml

@@ -1,9 +1,13 @@
 server:
   servlet:
     context-path: /hnSy-qg-app
-  port: 8081
+  port: 8031
 
 spring:
+  redis:
+    host: 139.129.39.156
+    port: 6379
+    password: lilishop
   datasource:
     druid:
       stat-view-servlet:
@@ -12,10 +16,10 @@ spring:
       primary: goods
       datasource:
         goods:
-          url: jdbc:postgresql://47.104.78.200:54802/goods
-          username: postgres # 数据库名
-          password: hainsyDB # 数据库密码
-          driver-class-name: org.postgresql.Driver
+          url: jdbc:mysql://139.129.39.156:3306/mall?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
+          username: root
+          password: Leichao419.xcy
+          driver-class-name: com.mysql.cj.jdbc.Driver
           hikari:
             maximum-pool-size: 10
             minimum-idle: 5

+ 131 - 131
src/test/java/com/sy/QgSdkTests.java

@@ -1,131 +1,131 @@
-package com.sy;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.sy.utils.ECDSASigner;
-import lombok.extern.slf4j.Slf4j;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.http.MediaType;
-import org.springframework.test.web.servlet.MockMvc;
-
-import org.springframework.test.web.servlet.ResultActions;
-import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
-
-import java.math.BigDecimal;
-import java.nio.charset.Charset;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static com.sy.utils.ECDSASigner.*;
-
-
-@Slf4j
-@SpringBootTest
-@AutoConfigureMockMvc
-class QgSdkTests {
-
-    @Autowired
-    ECDSASigner ecdsaSigner;
-    @Autowired
-    private MockMvc mockMvc;
-    @Test
-    void orderList() throws Exception {
-        Map<String, Object> params = new HashMap<>();
-        params.put("startTimestamp","1721549280015");
-        params.put("endTimestamp", "1721605140015");
-        //params.put("shopId","20062910053879");
-        Map<String, Object> extracted = extracted(params);
-        // 遍历原始的Map,并将键和值作为Object类型添加到新的Map中
-        params.forEach((key, value) -> System.out.println("Key = " + key + ", Value = " + value));
-        ObjectMapper objectMapper = new ObjectMapper();
-        String jsonString = objectMapper.writeValueAsString(extracted);
-        System.out.println(jsonString);
-        ResultActions perform = mockMvc.perform(MockMvcRequestBuilders.post("/order/list")
-                .contentType(MediaType.APPLICATION_JSON_VALUE)
-                .content(jsonString));
-        System.out.println(perform.andReturn().getResponse().getContentAsString(Charset.forName("utf-8")));
-    }
-
-    @Test
-    void profitSeparateList() throws Exception {
-        Map<String, Object> params = new HashMap<>();
-        params.put("startTimestamp","20240819");
-        params.put("endTimestamp", "20240819");
-        params.put("shopId","24071416503101");
-        Map<String, Object> extracted = extracted(params);
-        // 遍历原始的Map,并将键和值作为Object类型添加到新的Map中
-        params.forEach((key, value) -> System.out.println("Key = " + key + ", Value = " + value));
-        ObjectMapper objectMapper = new ObjectMapper();
-        String jsonString = objectMapper.writeValueAsString(extracted);
-        System.out.println(jsonString);
-        ResultActions perform = mockMvc.perform(MockMvcRequestBuilders.post("/order/profit/separate/list")
-                .contentType(MediaType.APPLICATION_JSON_VALUE)
-                .content(jsonString));
-        System.out.println(perform.andReturn().getResponse().getContentAsString(Charset.forName("utf-8")));
-    }
-
-    @Test
-    void refundList() throws Exception {
-        Map<String, Object> params = new HashMap<>();
-        params.put("startTimestamp","1720563978000");
-        params.put("endTimestamp", "1721909568223");
-        params.put("shopId","24071416503101");
-        Map<String, Object> extracted = extracted(params);
-        // 遍历原始的Map,并将键和值作为Object类型添加到新的Map中
-        params.forEach((key, value) -> System.out.println("Key = " + key + ", Value = " + value));
-        ObjectMapper objectMapper = new ObjectMapper();
-        String jsonString = objectMapper.writeValueAsString(extracted);
-        System.out.println(jsonString);
-        ResultActions perform = mockMvc.perform(MockMvcRequestBuilders.post("/order/refund/list")
-                .contentType(MediaType.APPLICATION_JSON_VALUE)
-                .content(jsonString));
-        System.out.println(perform.andReturn().getResponse().getContentAsString(Charset.forName("utf-8")));
-    }
-
-
-
-    @Test
-    void goodsPush() throws Exception {
-        Map<String, Object> params = new HashMap<>();
-        params.put("goodsId",8);
-        //params.put("goodsName", "雷超测试海天酱油");
-        //params.put("imgUrl","https://qgdy-test.oss-cn-chengdu.aliyuncs.com/2763ff0e290c991ab2963e4a383d1917bb299ed13d7675977cb1a1721a8a48fd.png");
-        //params.put("barCode","6974063510285");
-        //params.put("specs","500g");
-        params.put("salePrice",new BigDecimal(14.00));
-        //params.put("stock",10);
-        params.put("status",1);
-        params.put("shopId","19031816333414");
-        Map<String, Object> extracted = extracted(params);
-        // 遍历原始的Map,并将键和值作为Object类型添加到新的Map中
-        params.forEach((key, value) -> System.out.println("Key = " + key + ", Value = " + value));
-        ObjectMapper objectMapper = new ObjectMapper();
-        String jsonString = objectMapper.writeValueAsString(extracted);
-        System.out.println(jsonString);
-        ResultActions perform = mockMvc.perform(MockMvcRequestBuilders.post("/goods/push")
-                .contentType(MediaType.APPLICATION_JSON_VALUE)
-                .content(jsonString));
-        System.out.println(perform.andReturn().getResponse().getContentAsString(Charset.forName("utf-8")));
-    }
-
-
-
-    @Test
-    void test3333(){
-        BigDecimal number = new BigDecimal("00");
-        BigDecimal stripped = number.stripTrailingZeros();
-
-        System.out.println(number.multiply(new BigDecimal("999")));
-        // 假设我们期望原始数字是一个整数或者小数点后都是零
-        if (stripped.compareTo(BigDecimal.valueOf(stripped.longValue())) == 0) {
-            System.out.println("The number has only zeros after the decimal point.");
-        } else {
-            System.out.println("The number has non-zero digits after the decimal point.");
-        }
-
-    }
-
-}
+//package com.sy;
+//
+//import com.fasterxml.jackson.databind.ObjectMapper;
+//import com.sy.utils.ECDSASigner;
+//import lombok.extern.slf4j.Slf4j;
+//import org.junit.jupiter.api.Test;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+//import org.springframework.boot.test.context.SpringBootTest;
+//import org.springframework.http.MediaType;
+//import org.springframework.test.web.servlet.MockMvc;
+//
+//import org.springframework.test.web.servlet.ResultActions;
+//import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+//
+//import java.math.BigDecimal;
+//import java.nio.charset.Charset;
+//
+//import java.util.HashMap;
+//import java.util.Map;
+//
+//import static com.sy.utils.ECDSASigner.*;
+//
+//
+//@Slf4j
+//@SpringBootTest
+//@AutoConfigureMockMvc
+//class QgSdkTests {
+//
+//    @Autowired
+//    ECDSASigner ecdsaSigner;
+//    @Autowired
+//    private MockMvc mockMvc;
+//    @Test
+//    void orderList() throws Exception {
+//        Map<String, Object> params = new HashMap<>();
+//        params.put("startTimestamp","1733019222000");
+//        params.put("endTimestamp", "1733055222000");
+//        //params.put("shopId","19031816333414");
+//        Map<String, Object> extracted = extracted(params);
+//        // 遍历原始的Map,并将键和值作为Object类型添加到新的Map中
+//        params.forEach((key, value) -> System.out.println("Key = " + key + ", Value = " + value));
+//        ObjectMapper objectMapper = new ObjectMapper();
+//        String jsonString = objectMapper.writeValueAsString(extracted);
+//        System.out.println(jsonString);
+//        ResultActions perform = mockMvc.perform(MockMvcRequestBuilders.post("/order/list")
+//                .contentType(MediaType.APPLICATION_JSON_VALUE)
+//                .content(jsonString));
+//        System.out.println(perform.andReturn().getResponse().getContentAsString(Charset.forName("utf-8")));
+//    }
+//
+//    @Test
+//    void profitSeparateList() throws Exception {
+//        Map<String, Object> params = new HashMap<>();
+//        params.put("startTimestamp","20241127");
+//        params.put("endTimestamp", "20241127");
+//        params.put("shopId","24102316123379");
+//        Map<String, Object> extracted = extracted(params);
+//        // 遍历原始的Map,并将键和值作为Object类型添加到新的Map中
+//        params.forEach((key, value) -> System.out.println("Key = " + key + ", Value = " + value));
+//        ObjectMapper objectMapper = new ObjectMapper();
+//        String jsonString = objectMapper.writeValueAsString(extracted);
+//        System.out.println(jsonString);
+//        ResultActions perform = mockMvc.perform(MockMvcRequestBuilders.post("/order/profit/separate/list")
+//                .contentType(MediaType.APPLICATION_JSON_VALUE)
+//                .content(jsonString));
+//        System.out.println(perform.andReturn().getResponse().getContentAsString(Charset.forName("utf-8")));
+//    }
+//
+//    @Test
+//    void refundList() throws Exception {
+//        Map<String, Object> params = new HashMap<>();
+//        params.put("startTimestamp","1733019222000");
+//        params.put("endTimestamp", "1733055222000");
+//        params.put("shopId","24102316123379");
+//        Map<String, Object> extracted = extracted(params);
+//        // 遍历原始的Map,并将键和值作为Object类型添加到新的Map中
+//        params.forEach((key, value) -> System.out.println("Key = " + key + ", Value = " + value));
+//        ObjectMapper objectMapper = new ObjectMapper();
+//        String jsonString = objectMapper.writeValueAsString(extracted);
+//        System.out.println(jsonString);
+//        ResultActions perform = mockMvc.perform(MockMvcRequestBuilders.post("/order/refund/list")
+//                .contentType(MediaType.APPLICATION_JSON_VALUE)
+//                .content(jsonString));
+//        System.out.println(perform.andReturn().getResponse().getContentAsString(Charset.forName("utf-8")));
+//    }
+//
+//
+//
+//    @Test
+//    void goodsPush() throws Exception {
+//        Map<String, Object> params = new HashMap<>();
+//        params.put("goodsId",323);
+//        params.put("goodsName", "雷超测试新的商品推送323");
+//        params.put("traceCode","https://qgdy-test.oss-cn-chengdu.aliyuncs.com/2763ff0e290c991ab2963e4a383d1917bb299ed13d7675977cb1a1721a8a48fd.png");
+//        params.put("barCode","6974063510285");
+//        params.put("specs","10kg*1袋");
+//        params.put("salePrice",new BigDecimal(33.00));
+//        params.put("unit","kg");
+//        params.put("status",1);
+//        params.put("shopId","100001");
+//        Map<String, Object> extracted = extracted(params);
+//        // 遍历原始的Map,并将键和值作为Object类型添加到新的Map中
+//        params.forEach((key, value) -> System.out.println("Key = " + key + ", Value = " + value));
+//        ObjectMapper objectMapper = new ObjectMapper();
+//        String jsonString = objectMapper.writeValueAsString(extracted);
+//        System.out.println(jsonString);
+//        ResultActions perform = mockMvc.perform(MockMvcRequestBuilders.post("/goods/push")
+//                .contentType(MediaType.APPLICATION_JSON_VALUE)
+//                .content(jsonString));
+//        System.out.println(perform.andReturn().getResponse().getContentAsString(Charset.forName("utf-8")));
+//    }
+//
+//
+//
+//    @Test
+//    void test3333(){
+//        BigDecimal number = new BigDecimal("00");
+//        BigDecimal stripped = number.stripTrailingZeros();
+//
+//        System.out.println(number.multiply(new BigDecimal("999")));
+//        // 假设我们期望原始数字是一个整数或者小数点后都是零
+//        if (stripped.compareTo(BigDecimal.valueOf(stripped.longValue())) == 0) {
+//            System.out.println("The number has only zeros after the decimal point.");
+//        } else {
+//            System.out.println("The number has non-zero digits after the decimal point.");
+//        }
+//
+//    }
+//
+//}