cuixiaodong 10 сар өмнө
parent
commit
285974002d
100 өөрчлөгдсөн 7395 нэмэгдсэн , 0 устгасан
  1. BIN
      module-erp/libs/amazon-sp-api-1.0.0-SNAPSHOT.jar
  2. 172 0
      module-erp/pom.xml
  3. 44 0
      module-erp/src/main/java/com/hys/app/controller/base/CaptchaBaseController.java
  4. 159 0
      module-erp/src/main/java/com/hys/app/controller/base/FileBaseController.java
  5. 55 0
      module-erp/src/main/java/com/hys/app/controller/base/RegionsBaseController.java
  6. 35 0
      module-erp/src/main/java/com/hys/app/controller/base/SiteShowBaseController.java
  7. 41 0
      module-erp/src/main/java/com/hys/app/controller/base/TestBaseController.java
  8. 119 0
      module-erp/src/main/java/com/hys/app/controller/base/UeditorBaseController.java
  9. 34 0
      module-erp/src/main/java/com/hys/app/controller/base/ValidatorBaseController.java
  10. 86 0
      module-erp/src/main/java/com/hys/app/controller/erp/basic/CollectingAccountController.java
  11. 70 0
      module-erp/src/main/java/com/hys/app/controller/erp/basic/MarketingManagerManagerController.java
  12. 90 0
      module-erp/src/main/java/com/hys/app/controller/erp/basic/MemberController.java
  13. 68 0
      module-erp/src/main/java/com/hys/app/controller/erp/basic/NoGenerateRuleManagerController.java
  14. 67 0
      module-erp/src/main/java/com/hys/app/controller/erp/basic/StoreManagerController.java
  15. 67 0
      module-erp/src/main/java/com/hys/app/controller/erp/basic/UserMenuController.java
  16. 59 0
      module-erp/src/main/java/com/hys/app/controller/erp/finance/FinanceItemController.java
  17. 103 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/AdminUserOperationManagerController.java
  18. 142 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/CompanyController.java
  19. 65 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/CompanyPackageController.java
  20. 74 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/CustomerController.java
  21. 148 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/DeptController.java
  22. 119 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/KdnController.java
  23. 108 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/LogisticsCompanyManagerController.java
  24. 155 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/OrderController.java
  25. 37 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/OrderItemController.java
  26. 257 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/PayController.java
  27. 102 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/ProductManagerController.java
  28. 82 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/ProductStockManagerController.java
  29. 127 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/RoleManagerController.java
  30. 214 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/SmsMailController.java
  31. 127 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/StockDamageReportManagerController.java
  32. 116 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/StockInventoryManagerController.java
  33. 90 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/StockTransferManagerController.java
  34. 141 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/WarehouseAreaController.java
  35. 115 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/WarehouseEntryManagerController.java
  36. 52 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/WarehouseEntryProductManagerController.java
  37. 79 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/WarehouseManagerController.java
  38. 45 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/WarehouseOutItemController.java
  39. 114 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/WarehouseOutManagerController.java
  40. 108 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/WeixinController.java
  41. 99 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/msg/AliSmsUtil.java
  42. 101 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/msg/MailSmtpUtil.java
  43. 37 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/msg/MessageReceiveTypeEnum.java
  44. 46 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/msg/MsgContant.java
  45. 170 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/msg/MsgUtilClient.java
  46. 15 0
      module-erp/src/main/java/com/hys/app/controller/erp/use/task/MerchantPayInfo.java
  47. 188 0
      module-erp/src/main/java/com/hys/app/controller/system/AdminUserManagerController.java
  48. 79 0
      module-erp/src/main/java/com/hys/app/controller/system/DictDataController.java
  49. 81 0
      module-erp/src/main/java/com/hys/app/controller/system/DictTypeController.java
  50. 97 0
      module-erp/src/main/java/com/hys/app/controller/system/MenuManagerController.java
  51. 75 0
      module-erp/src/main/java/com/hys/app/controller/system/PostManagerController.java
  52. 97 0
      module-erp/src/main/java/com/hys/app/controller/system/RegionsManagerController.java
  53. 84 0
      module-erp/src/main/java/com/hys/app/controller/system/SensitiveWordsManagerController.java
  54. 57 0
      module-erp/src/main/java/com/hys/app/controller/system/SiteSettingManagerController.java
  55. 58 0
      module-erp/src/main/java/com/hys/app/controller/system/SmsCallbackController.java
  56. 79 0
      module-erp/src/main/java/com/hys/app/controller/system/SmsPlatformManagerController.java
  57. 107 0
      module-erp/src/main/java/com/hys/app/controller/system/SmsTemplateManagerController.java
  58. 53 0
      module-erp/src/main/java/com/hys/app/controller/system/SystemLogsManagerController.java
  59. 54 0
      module-erp/src/main/java/com/hys/app/controller/system/TaskController.java
  60. 76 0
      module-erp/src/main/java/com/hys/app/controller/system/UploaderManagerController.java
  61. 33 0
      module-erp/src/main/java/com/hys/app/converter/erp/CollectingAccountConverter.java
  62. 21 0
      module-erp/src/main/java/com/hys/app/converter/erp/CompanyConverter.java
  63. 19 0
      module-erp/src/main/java/com/hys/app/converter/erp/CompanyPackageConverter.java
  64. 31 0
      module-erp/src/main/java/com/hys/app/converter/erp/CustomerConverter.java
  65. 32 0
      module-erp/src/main/java/com/hys/app/converter/erp/FinanceItemConverter.java
  66. 19 0
      module-erp/src/main/java/com/hys/app/converter/erp/MailSmsCompanyConverter.java
  67. 39 0
      module-erp/src/main/java/com/hys/app/converter/erp/MarketingManagerConverter.java
  68. 34 0
      module-erp/src/main/java/com/hys/app/converter/erp/MemberConverter.java
  69. 30 0
      module-erp/src/main/java/com/hys/app/converter/erp/MenusConverter.java
  70. 26 0
      module-erp/src/main/java/com/hys/app/converter/erp/NoGenerateRuleConverter.java
  71. 89 0
      module-erp/src/main/java/com/hys/app/converter/erp/OrderConverter.java
  72. 48 0
      module-erp/src/main/java/com/hys/app/converter/erp/OrderItemConverter.java
  73. 54 0
      module-erp/src/main/java/com/hys/app/converter/erp/OrderReturnConverter.java
  74. 28 0
      module-erp/src/main/java/com/hys/app/converter/erp/PostConverter.java
  75. 29 0
      module-erp/src/main/java/com/hys/app/converter/erp/ProductStockConverter.java
  76. 21 0
      module-erp/src/main/java/com/hys/app/converter/erp/SmsMailConverter.java
  77. 52 0
      module-erp/src/main/java/com/hys/app/converter/erp/StockTransferConverter.java
  78. 29 0
      module-erp/src/main/java/com/hys/app/converter/erp/StockTransferProductConverter.java
  79. 29 0
      module-erp/src/main/java/com/hys/app/converter/erp/StoreConverter.java
  80. 68 0
      module-erp/src/main/java/com/hys/app/converter/erp/SupplierSettlementItemConverter.java
  81. 34 0
      module-erp/src/main/java/com/hys/app/converter/erp/UserMenuConverter.java
  82. 33 0
      module-erp/src/main/java/com/hys/app/converter/erp/WarehouseAreaConverter.java
  83. 32 0
      module-erp/src/main/java/com/hys/app/converter/erp/WarehouseConverter.java
  84. 64 0
      module-erp/src/main/java/com/hys/app/converter/erp/WarehouseEntryProductConverter.java
  85. 79 0
      module-erp/src/main/java/com/hys/app/converter/erp/WarehouseOutConverter.java
  86. 26 0
      module-erp/src/main/java/com/hys/app/converter/erp/WarehouseOutItemConverter.java
  87. 46 0
      module-erp/src/main/java/com/hys/app/converter/system/DeptConverter.java
  88. 27 0
      module-erp/src/main/java/com/hys/app/converter/system/DictDataConverter.java
  89. 28 0
      module-erp/src/main/java/com/hys/app/converter/system/DictTypeConverter.java
  90. 29 0
      module-erp/src/main/java/com/hys/app/converter/system/TaskConverter.java
  91. 42 0
      module-erp/src/main/java/com/hys/app/framework/datapermission/DataPermissionTableCustomizer.java
  92. 27 0
      module-erp/src/main/java/com/hys/app/framework/datapermission/dept/DeptDataPermissionConfiguration.java
  93. 177 0
      module-erp/src/main/java/com/hys/app/framework/datapermission/dept/DeptDataPermissionRule.java
  94. 20 0
      module-erp/src/main/java/com/hys/app/framework/datapermission/dept/DeptDataPermissionRuleCustomizer.java
  95. 6 0
      module-erp/src/main/java/com/hys/app/framework/datapermission/dept/package-info.java
  96. 121 0
      module-erp/src/main/java/com/hys/app/framework/security/AdminAccessDecisionManager.java
  97. 40 0
      module-erp/src/main/java/com/hys/app/framework/security/AdminAuthenticationService.java
  98. 112 0
      module-erp/src/main/java/com/hys/app/framework/security/AdminSecurityMetadataSource.java
  99. 75 0
      module-erp/src/main/java/com/hys/app/framework/security/BaseSecurityConfig.java
  100. 107 0
      module-erp/src/main/java/com/hys/app/framework/security/ManagerSecurityConfig.java

BIN
module-erp/libs/amazon-sp-api-1.0.0-SNAPSHOT.jar


+ 172 - 0
module-erp/pom.xml

@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>warehouse</artifactId>
+        <groupId>com.hys.app</groupId>
+        <version>7.2.2</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>module-erp</artifactId>
+
+    <repositories>
+        <repository>
+            <id>github</id>
+            <url>https://maven.pkg.github.com/davidmoten/amazon-sp-api</url>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </repository>
+
+<!--        <repository>-->
+<!--            <id>jitpack.io</id>-->
+<!--            <url>https://jitpack.io</url>-->
+<!--        </repository>-->
+    </repositories>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.hys.app</groupId>
+            <artifactId>framework</artifactId>
+            <version>${erp-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jetbrains</groupId>
+            <artifactId>annotations</artifactId>
+            <version>RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.alipay.sdk</groupId>
+            <artifactId>alipay-sdk-java</artifactId>
+            <version>4.38.0.ALL</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.wechatpay-apiv3</groupId>
+            <artifactId>wechatpay-java</artifactId>
+            <version>0.2.12</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.binarywang</groupId>
+            <artifactId>weixin-java-pay</artifactId>
+            <version>4.6.2.B</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.wxpay</groupId>
+            <artifactId>wxpay-sdk</artifactId>
+            <version> 0.0.3</version>
+        </dependency>
+
+
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
+            <version>2.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>alibabacloud-dm20151123</artifactId>
+            <version>1.0.16</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.mail</groupId>
+            <artifactId>javax.mail</artifactId>
+            <version>1.6.2</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.activation</groupId>
+            <artifactId>activation</artifactId>
+            <version>1.1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.8.6</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>dysmsapi20170525</artifactId>
+            <version>2.0.24</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.binarywang</groupId>
+            <artifactId>weixin-java-mp</artifactId>
+            <version>4.3.0</version>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>software.amazon.awssdk</groupId>-->
+<!--            <artifactId>sdk-core</artifactId>-->
+<!--            <version>2.17.89</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>software.amazon.awssdk</groupId>-->
+<!--            <artifactId>mws</artifactId>-->
+<!--            <version>2.17.89</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>com.amazonservices.mws.orders</groupId>-->
+<!--            <artifactId>mws-orders-api</artifactId>-->
+<!--            <version>2013-09-01</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>com.amazonaws</groupId>-->
+<!--            <artifactId>aws-java-sdk</artifactId>-->
+<!--            <version>1.11.1000</version>-->
+<!--        </dependency>-->
+
+<!--        <dependency>-->
+<!--            <groupId>com.amazonservices.mws.orders</groupId>-->
+<!--            <artifactId>mws-orders-api</artifactId>-->
+<!--            <version>2013-09-01</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>com.amazonservices.mws.products</groupId>-->
+<!--            <artifactId>mws-products-api</artifactId>-->
+<!--            <version>2011-10-01</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>com.amazonservices.mws.inventory</groupId>-->
+<!--            <artifactId>mws-inventory-api</artifactId>-->
+<!--            <version>2010-10-01</version>-->
+<!--        </dependency>-->
+
+<!--        <dependency>-->
+<!--            <groupId>org.apache.httpcomponents</groupId>-->
+<!--            <artifactId>httpclient</artifactId>-->
+<!--            <version>4.5.13</version>-->
+<!--        </dependency>-->
+<!--        &lt;!&ndash; Jackson for JSON processing &ndash;&gt;-->
+<!--        <dependency>-->
+<!--            <groupId>com.fasterxml.jackson.core</groupId>-->
+<!--            <artifactId>jackson-databind</artifactId>-->
+<!--            <version>2.12.3</version>-->
+<!--        </dependency>-->
+<!--        &lt;!&ndash; AWS SDK for signing requests &ndash;&gt;-->
+<!--        <dependency>-->
+<!--            <groupId>software.amazon.awssdk</groupId>-->
+<!--            <artifactId>auth</artifactId>-->
+<!--            <version>2.16.77</version>-->
+<!--        </dependency>-->
+
+<!--        <dependency>-->
+<!--            <groupId>io.github.davidmoten</groupId>-->
+<!--            <artifactId>amazon-sp-api</artifactId>-->
+<!--            <version>2.1.60</version>-->
+<!--        </dependency>-->
+
+        <dependency>
+            <groupId>com.amazon</groupId>
+            <artifactId>sp-api</artifactId>
+            <version>1.0.0</version>
+            <scope>system</scope>
+            <systemPath>${project.basedir}/libs/amazon-sp-api-1.0.0-SNAPSHOT.jar</systemPath>
+        </dependency>
+
+    </dependencies>
+
+
+</project>

+ 44 - 0
module-erp/src/main/java/com/hys/app/controller/base/CaptchaBaseController.java

@@ -0,0 +1,44 @@
+package com.hys.app.controller.base;
+
+import com.hys.app.service.base.service.CaptchaManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+/**
+ * 验证码生成
+ *
+ * @author zh
+ * @version v7.0
+ * @since v7.0
+ * 2018年3月23日 上午10:12:12
+ */
+@RestController
+@RequestMapping("/captchas")
+@Api(description = "验证码api")
+public class CaptchaBaseController {
+
+    @Autowired
+    private CaptchaManager captchaManager;
+
+    @GetMapping(value = "/{uuid}/{scene}")
+    @ApiOperation(value = "生成验证码")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "uuid", value = "uuid客户端的唯一标识", required = true, dataType = "String", paramType = "path"),
+            @ApiImplicitParam(name = "scene", value = "业务类型", required = true, dataType = "String", paramType = "path")
+    })
+    public String getCode(@PathVariable("uuid") String uuid, @PathVariable("scene") String scene) {
+
+        //直接调取业务类,由业务类输出流到浏览器
+        this.captchaManager.writeCode(uuid, scene);
+
+        return null;
+    }
+}

+ 159 - 0
module-erp/src/main/java/com/hys/app/controller/base/FileBaseController.java

@@ -0,0 +1,159 @@
+package com.hys.app.controller.base;
+
+import cn.hutool.core.collection.ListUtil;
+import com.hys.app.framework.exception.ResourceNotFoundException;
+import com.hys.app.framework.exception.ServiceException;
+import com.hys.app.framework.util.ArrayUtils;
+import com.hys.app.framework.util.FileUtil;
+import com.hys.app.model.base.dto.FileDTO;
+import com.hys.app.model.base.vo.FileVO;
+import com.hys.app.model.errorcode.SystemErrorCode;
+import com.hys.app.service.base.service.FileManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.Locale;
+import java.util.UUID;
+
+
+/**
+ * 存储方案控制器
+ *
+ * @author zh
+ * @version v7.0.0
+ * @since v7.0.0
+ * 2018-03-22 10:54:47
+ */
+@RestController
+@RequestMapping("/uploaders")
+@Api(description = "上传图片api")
+public class FileBaseController {
+
+    @Autowired
+    private FileManager fileManager;
+
+
+    @ApiOperation(value = "文件上传", response = FileVO.class)
+    @ApiImplicitParam(name = "scene", value = "业务场景", allowableValues = "goods,shop,member,other", required = true, dataType = "String", paramType = "query")
+    @PostMapping
+    public FileVO list(MultipartFile file, String scene) throws IOException {
+        if (file != null && file.getOriginalFilename() != null) {
+            //文件类型
+            String contentType = file.getContentType();
+            //获取文件名称
+            String ext = contentType.substring(contentType.lastIndexOf("/") + 1, contentType.length());
+            //如果是图片类型 则验证不允许上传超过2M
+            if (FileUtil.isAllowUpImg(ext)) {
+                if (!FileUtil.checkFileSize(file.getSize(), 5, "M")) {
+                    throw new ServiceException(SystemErrorCode.E901.code(), "图片超过上传限制大小,请上传5M以内图片");
+                }
+            }
+            if (!FileUtil.isAllowUpFile(ext)) {
+                throw new ServiceException(SystemErrorCode.E901.code(), "不允许上传的文件格式,请上传gif,jpg,png,jpeg,mp4,pdf,mov格式文件。");
+            }
+            FileDTO input = new FileDTO();
+            input.setName(file.getOriginalFilename());
+            input.setStream(file.getInputStream());
+            input.setExt(ext);
+            return this.fileManager.upload(input, scene);
+        } else {
+            throw new ResourceNotFoundException("没有文件");
+        }
+    }
+
+    @ApiOperation(value = "文件删除")
+    @ApiImplicitParam(name = "file_path", value = "文件路径", required = true, dataType = "String", paramType = "query")
+    @DeleteMapping
+    public String delete(@ApiIgnore String filePath) {
+        this.fileManager.deleteFile(filePath);
+        return null;
+    }
+
+
+    @ApiOperation(value = "文件上传", response = FileVO.class)
+    @ApiImplicitParam(name = "scene", value = "业务场景", allowableValues = "goods,shop,member,other", required = true, dataType = "String", paramType = "query")
+    @PostMapping("uploadSmall")
+    public FileVO uploadSmall(MultipartFile file, String scene) throws IOException {
+        if (file != null && file.getOriginalFilename() != null) {
+            //文件类型
+            String contentType = file.getContentType();
+            //获取文件名称
+            String ext = contentType.substring(contentType.lastIndexOf("/") + 1, contentType.length());
+            String jpg = ext.substring(contentType.lastIndexOf(".") + 1, ext.length());
+
+            //如果是图片类型 则验证不允许上传超过2M
+            if (FileUtil.isAllowUpImg(ext)) {
+                if (!FileUtil.checkFileSize(file.getSize(), 2, "M")) {
+                    throw new ServiceException(SystemErrorCode.E901.code(), "图片超过上传限制大小,请上传2M以内图片");
+                }
+            }
+            if (!FileUtil.isAllowUpFile(ext)) {
+                throw new ServiceException(SystemErrorCode.E901.code(), "不允许上传的文件格式,请上传gif,jpg,png,jpeg,mp4,pdf,mov格式文件。");
+            }
+
+            String fileName = file.getOriginalFilename();
+            String newName = UUID.randomUUID().toString() + fileName.substring(fileName.indexOf("."));
+            // 获取当前操作系统
+            String osName = System.getProperties().get("os.name").toString().toLowerCase(Locale.ROOT);
+            String path = "";
+
+            if (osName.startsWith("win")) {
+                path = "D:\\Test\\";
+            } else {
+                path = "/mnt/test";
+            }
+            File saveFile = new File(path + newName);
+            if (!saveFile.getParentFile().exists()) {
+                saveFile.getParentFile().mkdirs();
+            }
+            file.transferTo(saveFile);
+            String path1 = saveFile.getPath();
+
+
+            File inputFile = new File(path1);
+            BufferedImage inputImage = ImageIO.read(inputFile);
+
+            // 创建一个新的缓冲图片
+            BufferedImage outputImage = new BufferedImage(80, 80, inputImage.getType());
+
+            // 绘制并缩放原图片到新图片中
+            outputImage.getGraphics().drawImage(inputImage.getScaledInstance(80, 80, BufferedImage.SCALE_SMOOTH), 0, 0, null);
+
+            // 写入到输出文件
+            String newNameSmall ="small"+ newName ;
+
+            File outputFile = new File(path + newNameSmall);
+            ImageIO.write(outputImage, jpg, outputFile); // 根据原图片格式选择"jpg", "png"等
+
+            File inputFile2 = new File(path + newNameSmall);
+            FileInputStream input2 = new FileInputStream(inputFile2);
+            MultipartFile multipartFile2 = new MockMultipartFile("file", newName, "text/plain", input2);
+            FileDTO fileDTO2 = new FileDTO();
+            fileDTO2.setName(multipartFile2.getOriginalFilename());
+            fileDTO2.setStream(multipartFile2.getInputStream());
+            fileDTO2.setExt(ext);
+            FileVO upload2 = this.fileManager.upload(fileDTO2, scene);
+            upload2.setType("small");
+            inputFile2.delete();
+            inputFile.delete();
+            return  upload2;
+        } else {
+            throw new ResourceNotFoundException("没有文件");
+        }
+    }
+}

+ 55 - 0
module-erp/src/main/java/com/hys/app/controller/base/RegionsBaseController.java

@@ -0,0 +1,55 @@
+package com.hys.app.controller.base;
+
+import com.hys.app.model.system.vo.RegionVO;
+import com.hys.app.model.system.dos.Regions;
+import com.hys.app.service.system.RegionsManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * 地区api
+ *
+ * @author zh
+ * @version v7.0
+ * @date 18/5/28 下午7:49
+ * @since v7.0
+ */
+@RestController
+@RequestMapping("/regions")
+@Api(description = "地区API")
+public class RegionsBaseController {
+
+    @Autowired
+    private RegionsManager regionsManager;
+
+    @GetMapping(value = "/{id}/children")
+    @ApiOperation(value = "获取某地区的子地区")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "地区id", required = true, dataType = "int", paramType = "path")
+    })
+    public List<Regions> getChildrenById(@PathVariable Long id) {
+
+        return regionsManager.getRegionsChildren(id);
+    }
+
+
+    @GetMapping(value = "/depth/{depth}")
+    @ApiOperation(value = "根据地区深度查询组织好地区数据结构的地区")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "depth", value = "深度", required = true, dataType = "int", paramType = "path")
+    })
+    public List<RegionVO> getRegionByDepth(@PathVariable Integer depth) {
+        return regionsManager.getRegionByDepth(depth);
+    }
+
+
+}

+ 35 - 0
module-erp/src/main/java/com/hys/app/controller/base/SiteShowBaseController.java

@@ -0,0 +1,35 @@
+package com.hys.app.controller.base;
+
+import com.hys.app.framework.util.JsonUtil;
+import com.hys.app.model.base.SettingGroup;
+import com.hys.app.model.system.vo.SiteSetting;
+import com.hys.app.service.base.service.SettingManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 站点信息首页展示控制器
+ *
+ * @author zh
+ * @version v7.0
+ * @date 18/7/13 上午11:21
+ * @since v7.0
+ */
+@RestController
+@RequestMapping("/site-show")
+@Api(description = "站点展示")
+public class SiteShowBaseController {
+
+    @Autowired
+    private SettingManager settingManager;
+    @GetMapping
+    @ApiOperation(value = "获取站点设置")
+    public SiteSetting getSiteSetting(){
+        String siteJson = settingManager.get(SettingGroup.SITE);
+        return JsonUtil.jsonToObject(siteJson,SiteSetting.class);
+    }
+}

+ 41 - 0
module-erp/src/main/java/com/hys/app/controller/base/TestBaseController.java

@@ -0,0 +1,41 @@
+package com.hys.app.controller.base;
+
+import com.hys.app.framework.util.DateUtil;
+import com.hys.app.model.shoptnt.ApiParams;
+import com.hys.app.model.shoptnt.ShopTntApiEnum;
+import com.hys.app.service.shoptnt.ShopTntHttpClint;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 地区api
+ *
+ * @author zh
+ * @version v7.0
+ * @date 18/5/28 下午7:49
+ * @since v7.0
+ */
+@RestController
+@RequestMapping("/test")
+@Api(description = "地区API")
+public class TestBaseController {
+
+    @Autowired
+    private ShopTntHttpClint shopTntHttpClint;
+
+    @GetMapping
+    @ApiOperation(value = "test")
+    public String getChildrenById(String msg) {
+        ApiParams apiParams = new ApiParams();
+        apiParams.put("msg_id", "001");
+        apiParams.put("type", "Test");
+        apiParams.put("content", msg);
+        apiParams.put("produce_time", DateUtil.getDateline());
+        return shopTntHttpClint.execute(ShopTntApiEnum.MessageReceive, apiParams).getData();
+    }
+
+}

+ 119 - 0
module-erp/src/main/java/com/hys/app/controller/base/UeditorBaseController.java

@@ -0,0 +1,119 @@
+package com.hys.app.controller.base;
+
+import com.hys.app.framework.util.FileUtil;
+import com.hys.app.model.base.dto.FileDTO;
+import com.hys.app.model.base.vo.FileVO;
+import com.hys.app.service.base.service.FileManager;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.json.JSONException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 百度Ueditor配置及文件上传支持
+ * @author kingapex
+ * @version 1.0
+ * @since 7.0.0
+ * 2018/6/6
+ */
+@RestController()
+@RequestMapping("/ueditor")
+public class UeditorBaseController {
+
+
+    /**
+     * 文件上传接口
+     */
+    @Autowired
+    private FileManager fileManager;
+
+    /**
+     * 配置内容常量,用于缓存配置信息,避免每次由硬盘读取
+     */
+    private static String config;
+
+    @GetMapping(value = "/",produces = "application/javascript")
+    @ApiOperation(value = "获取ueditor配置")
+    @ApiImplicitParam(name = "callback", value = "jsonp的callback", required = true, dataType = "String")
+    public String config(String callback) throws JSONException {
+
+       return "/**/"+callback+"("+ getConfig() +");";
+
+    }
+
+    /**
+     * 获取配置<br>
+     * 如果config中已经存在,则直接返回,否则由硬盘读取<br>
+     * 读取文件为/resource/ueditor_config.json<br><br>
+     * @return
+     */
+    private String getConfig() {
+
+        if (config == null) {
+            config = FileUtil.readFile("/ueditor_config.json");
+        }
+
+        return config;
+    }
+
+    /**
+     * 文件上传<br>
+     * 接受POST请求<br>
+     * 同时支持多择文件上传和截图上传
+     * @param upfile 文件流
+     * @return
+     * @throws JSONException
+     * @throws IOException
+     */
+    @PostMapping(value = "/")
+    @ApiOperation(value = "ueditor文件/图片上传")
+    public Map upload( MultipartFile upfile) throws JSONException, IOException {
+        Map result = new HashMap(16);
+        if (upfile != null && upfile.getOriginalFilename() != null) {
+
+            //文件类型
+            String contentType= upfile.getContentType();
+            //获取文件名称后缀
+            String ext = contentType.substring(contentType.lastIndexOf("/") + 1, contentType.length());
+
+            if(!FileUtil.isAllowUpImg(ext)){
+
+                result.put("state","不允许上传的文件格式,请上传gif,jpg,png,jpeg,mp4格式文件。");
+                return  result;
+
+            }
+
+            FileDTO input  = new FileDTO();
+            input.setName(upfile.getOriginalFilename());
+            input.setStream(upfile.getInputStream());
+            input.setExt(ext);
+            FileVO file  = this.fileManager.upload(input, "ueditor");
+            String url  = file.getUrl();
+            String title = file.getName();
+            String original = file.getName();
+            result.put("state","SUCCESS");
+            result.put("url", url);
+            result.put("title", title);
+            result.put("name", title);
+            result.put("original", original);
+            result.put("type","."+file.getExt());
+            return  result;
+
+        }else{
+
+            result.put("state","没有读取要上传的文件");
+            return  result;
+        }
+
+
+    }
+}

+ 34 - 0
module-erp/src/main/java/com/hys/app/controller/base/ValidatorBaseController.java

@@ -0,0 +1,34 @@
+package com.hys.app.controller.base;
+
+import com.hys.app.model.system.dto.ValidatorPlatformDTO;
+import com.hys.app.service.system.ValidatorPlatformManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 验证方式API
+ *
+ * @author duanmingyu
+ * @version v1.0
+ * @since v7.1.6
+ * 2019-12-18
+ */
+@RestController
+@RequestMapping("/validator")
+@Api(description = "验证方式API")
+public class ValidatorBaseController {
+
+    @Autowired
+    private ValidatorPlatformManager validatorPlatformManager;
+
+    @ApiOperation(value = "获取当前系统开启的验证平台信息")
+    @GetMapping()
+    public ValidatorPlatformDTO get() {
+
+        return this.validatorPlatformManager.getCurrentOpen();
+    }
+}

+ 86 - 0
module-erp/src/main/java/com/hys/app/controller/erp/basic/CollectingAccountController.java

@@ -0,0 +1,86 @@
+package com.hys.app.controller.erp.basic;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dto.CollectingAccountDTO;
+import com.hys.app.model.erp.dto.CollectingAccountQueryParams;
+import com.hys.app.model.erp.vo.CollectingAccountVO;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.CollectingAccountManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * 收款账户 API
+ *
+ * @author 张崧
+ * 2024-01-24 14:43:18
+ */
+@RestController
+@RequestMapping("/admin/erp/collectingAccount")
+@Api(tags = "收款账户API")
+@Validated
+public class CollectingAccountController {
+
+    @Autowired
+    private CollectingAccountManager collectingAccountManager;
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public WebPage<CollectingAccountVO> list(CollectingAccountQueryParams queryParams) {
+        return collectingAccountManager.list(queryParams);
+    }
+
+    @ApiOperation(value = "添加")
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "新增收款账户")
+    public void add(@RequestBody @Valid CollectingAccountDTO collectingAccountDTO) {
+        collectingAccountManager.add(collectingAccountDTO);
+    }
+
+    @ApiOperation(value = "修改")
+    @PutMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "修改id为[${id}]的收款账户")
+    public void edit(@PathVariable Long id, @RequestBody @Valid CollectingAccountDTO collectingAccountDTO) {
+        collectingAccountDTO.setId(id);
+        collectingAccountManager.edit(collectingAccountDTO);
+    }
+
+    @ApiOperation(value = "查询")
+    @GetMapping("/{id}")
+    public CollectingAccountVO getDetail(@PathVariable Long id) {
+        return collectingAccountManager.getDetail(id);
+    }
+
+    @ApiOperation(value = "删除")
+    @DeleteMapping("/{ids}")
+    @Log(client = LogClient.admin, detail = "删除id为[${ids}]的收款账户")
+    public void delete(@PathVariable List<Long> ids) {
+        collectingAccountManager.delete(ids);
+    }
+
+    @ApiOperation(value = "设为默认")
+    @PutMapping("/default/{id}")
+    @Log(client = LogClient.admin, detail = "将id为[${id}]的收款账户设为默认")
+    public void setDefault(@PathVariable Long id) {
+        collectingAccountManager.setDefault(id);
+    }
+
+    @ApiOperation(value = "启用/禁用")
+    @PutMapping("/enableFlag/{id}")
+    @ApiImplicitParam(name = "enable_flag", value = "true启用 false禁用", required = true, paramType = "query")
+    @Log(client = LogClient.admin, detail = "修改id为[${id}]的收款账户的启用/禁用状态")
+    public void updateEnableFlag(@PathVariable Long id, @NotNull(message = "状态不能为空") Boolean enableFlag) {
+        collectingAccountManager.updateEnableFlag(id, enableFlag);
+    }
+
+}
+

+ 70 - 0
module-erp/src/main/java/com/hys/app/controller/erp/basic/MarketingManagerManagerController.java

@@ -0,0 +1,70 @@
+package com.hys.app.controller.erp.basic;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dto.MarketingManagerDTO;
+import com.hys.app.model.erp.dto.MarketingManagerQueryParams;
+import com.hys.app.model.erp.vo.MarketingManagerVO;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.MarketingManagerManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 营销经理相关API
+ *
+ * @author 张崧
+ * @since 2023-12-11 11:25:31
+ */
+@RestController
+@RequestMapping("/admin/erp/marketingManager")
+@Api(tags = "营销经理相关API")
+@Validated
+public class MarketingManagerManagerController {
+
+    @Autowired
+    private MarketingManagerManager marketingManagerManager;
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public WebPage<MarketingManagerVO> list(MarketingManagerQueryParams queryParams) {
+        return marketingManagerManager.list(queryParams);
+    }
+
+    @ApiOperation(value = "添加")
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "新增销售经理")
+    public void add(@RequestBody @Valid MarketingManagerDTO marketingManagerDTO) {
+        marketingManagerManager.add(marketingManagerDTO);
+    }
+
+    @ApiOperation(value = "修改")
+    @PutMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "修改id为[${id}]的销售经理")
+    public void edit(@PathVariable Long id, @RequestBody @Valid MarketingManagerDTO marketingManagerDTO) {
+        marketingManagerDTO.setId(id);
+        marketingManagerManager.edit(marketingManagerDTO);
+    }
+
+    @ApiOperation(value = "查询")
+    @GetMapping("/{id}")
+    public MarketingManagerVO getDetail(@PathVariable Long id) {
+        return marketingManagerManager.getDetail(id);
+    }
+
+    @ApiOperation(value = "删除")
+    @DeleteMapping("/{ids}")
+    @Log(client = LogClient.admin, detail = "删除id为[${ids}]的销售经理")
+    public void delete(@PathVariable List<Long> ids) {
+        marketingManagerManager.delete(ids);
+    }
+
+
+}
+

+ 90 - 0
module-erp/src/main/java/com/hys/app/controller/erp/basic/MemberController.java

@@ -0,0 +1,90 @@
+package com.hys.app.controller.erp.basic;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dto.MemberDTO;
+import com.hys.app.model.erp.dto.MemberQueryParams;
+import com.hys.app.model.erp.vo.MemberVO;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.MemberManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 会员 API
+ *
+ * @author 张崧
+ * 2024-01-23 09:28:16
+ */
+@RestController
+@RequestMapping("/admin/erp/member")
+@Api(tags = "会员API")
+@Validated
+public class MemberController {
+
+    @Autowired
+    private MemberManager memberManager;
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public WebPage<MemberVO> list(MemberQueryParams queryParams) {
+        return memberManager.list(queryParams);
+    }
+
+    @ApiOperation(value = "添加")
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "新增会员")
+    public void add(@RequestBody @Valid MemberDTO memberDTO) {
+        memberManager.add(memberDTO);
+    }
+
+    @ApiOperation(value = "修改")
+    @PutMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "修改id为[${id}]的会员")
+    public void edit(@PathVariable String id, @RequestBody @Valid MemberDTO memberDTO) {
+        memberDTO.setId(id);
+        memberManager.edit(memberDTO);
+    }
+
+    @ApiOperation(value = "查询")
+    @GetMapping("/{id}")
+    public MemberVO getDetail(@PathVariable Long id) {
+        return memberManager.getDetail(id);
+    }
+
+    @ApiOperation(value = "删除")
+    @DeleteMapping("/{ids}")
+    @Log(client = LogClient.admin, detail = "删除id为[${ids}]的会员")
+    public void delete(@PathVariable List<Long> ids) {
+        memberManager.delete(ids);
+    }
+
+    @PostMapping("/import")
+    @ApiOperation(value = "导入")
+    public void importExcel(@RequestParam("file") @RequestPart MultipartFile file) {
+        memberManager.importExcel(file);
+    }
+
+    @ApiOperation(value = "禁用")
+    @PutMapping("/disable/{id}")
+    @Log(client = LogClient.admin, detail = "禁用ID为[${id}]的会员信息")
+    public void disable(@PathVariable Long id) {
+        memberManager.setDisable(id,true);
+    }
+
+    @ApiOperation(value = "恢复")
+    @PutMapping("/enable/{id}")
+    @Log(client = LogClient.admin, detail = "恢复ID为[${id}]的会员信息")
+    public void enable(@PathVariable Long id) {
+        memberManager.setDisable(id,false);
+    }
+
+}
+

+ 68 - 0
module-erp/src/main/java/com/hys/app/controller/erp/basic/NoGenerateRuleManagerController.java

@@ -0,0 +1,68 @@
+package com.hys.app.controller.erp.basic;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dto.NoGenerateRuleQueryParams;
+import com.hys.app.model.erp.vo.NoGenerateRuleVO;
+import com.hys.app.model.erp.dto.NoGenerateRuleDTO;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.NoGenerateRuleManager;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 编号生成规则相关API
+ *
+ * @author 张崧
+ * 2023-12-01 11:37:56
+ */
+@RestController
+@RequestMapping("/admin/erp/noGenerateRule")
+@Api(tags = "编号生成规则相关API")
+@Validated
+public class NoGenerateRuleManagerController {
+
+    @Autowired
+    private NoGenerateRuleManager noGenerateRuleManager;
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public WebPage<NoGenerateRuleVO> list(NoGenerateRuleQueryParams queryParams) {
+        return noGenerateRuleManager.list(queryParams);
+    }
+
+    @ApiOperation(value = "添加")
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "添加名称为[${noGenerateRuleDTO.name}]的编号生成规则")
+    public void add(@RequestBody @Valid NoGenerateRuleDTO noGenerateRuleDTO) {
+        noGenerateRuleManager.add(noGenerateRuleDTO);
+    }
+
+    @ApiOperation(value = "修改")
+    @PutMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "修改ID为[${id}]的编号生成规则")
+    public void edit(@PathVariable Long id, @RequestBody @Valid NoGenerateRuleDTO noGenerateRuleDTO) {
+        noGenerateRuleDTO.setId(id);
+        noGenerateRuleManager.edit(noGenerateRuleDTO);
+    }
+
+    @ApiOperation(value = "查询")
+    @GetMapping("/{id}")
+    public NoGenerateRuleVO getDetail(@PathVariable Long id) {
+        return noGenerateRuleManager.getDetail(id);
+    }
+
+    @ApiOperation(value = "删除")
+    @DeleteMapping("/{ids}")
+    @Log(client = LogClient.admin, detail = "删除ID为${ids}的编号生成规则")
+    public void delete(@PathVariable List<Long> ids) {
+        noGenerateRuleManager.delete(ids);
+    }
+}
+

+ 67 - 0
module-erp/src/main/java/com/hys/app/controller/erp/basic/StoreManagerController.java

@@ -0,0 +1,67 @@
+package com.hys.app.controller.erp.basic;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dto.StoreQueryParams;
+import com.hys.app.model.erp.vo.StoreVO;
+import com.hys.app.model.erp.dto.StoreDTO;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.StoreManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+/**
+ * 门店API
+ *
+ * @author 张崧
+ * @since 2023-12-11 17:47:09
+ */
+@RestController
+@RequestMapping("/admin/erp/store")
+@Api(tags = "门店API")
+@Validated
+public class StoreManagerController {
+
+    @Autowired
+    private StoreManager storeManager;
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public WebPage<StoreVO> list(StoreQueryParams queryParams) {
+        return storeManager.list(queryParams);
+    }
+
+    @ApiOperation(value = "添加")
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "新增门店")
+    public void add(@RequestBody @Valid StoreDTO storeDTO) {
+        storeManager.add(storeDTO);
+    }
+
+    @ApiOperation(value = "修改")
+    @PutMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "修改id为[${id}]的门店")
+    public void edit(@PathVariable Long id, @RequestBody @Valid StoreDTO storeDTO) {
+        storeDTO.setId(id);
+        storeManager.edit(storeDTO);
+    }
+
+    @ApiOperation(value = "查询")
+    @GetMapping("/{id}")
+    public StoreVO getDetail(@PathVariable Long id) {
+        return storeManager.getDetail(id);
+    }
+
+    @ApiOperation(value = "删除")
+    @DeleteMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "删除id为[${id}]的门店")
+    public void delete(@PathVariable Long id) {
+        storeManager.delete(id);
+    }
+}
+

+ 67 - 0
module-erp/src/main/java/com/hys/app/controller/erp/basic/UserMenuController.java

@@ -0,0 +1,67 @@
+package com.hys.app.controller.erp.basic;
+
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dto.MemberDTO;
+import com.hys.app.model.erp.dto.MemberQueryParams;
+import com.hys.app.model.erp.dto.UserMenuDto;
+import com.hys.app.model.erp.dto.UserMenuQueryParams;
+import com.hys.app.model.erp.vo.MemberVO;
+import com.hys.app.model.erp.vo.UserMenuVO;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.MemberManager;
+import com.hys.app.service.erp.UserMenuManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 会员 API
+ *
+ * @author 张崧
+ * 2024-01-23 09:28:16
+ */
+@RestController
+@RequestMapping("/admin/erp/user/menu")
+@Api(tags = "会员快捷菜单")
+@Validated
+public class UserMenuController {
+
+    @Autowired
+    private UserMenuManager userMenuManager;
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public WebPage<UserMenuDto> list(UserMenuQueryParams queryParams) {
+
+        queryParams.setUserId(AdminUserContext.getAdminUserId());
+        return userMenuManager.list(queryParams);
+    }
+
+    @ApiOperation(value = "新增菜单")
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "新增菜单")
+    public void add(@RequestBody @Valid UserMenuDto userMenuDto) {
+        userMenuDto.setUserId(AdminUserContext.getAdminUserId());
+        userMenuManager.add(userMenuDto);
+    }
+
+
+
+    @ApiOperation(value = "删除")
+    @DeleteMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "删除id为[${id}]的菜单")
+    public void delete(@PathVariable Long id) {
+        userMenuManager.delete(id);
+    }
+
+
+}
+

+ 59 - 0
module-erp/src/main/java/com/hys/app/controller/erp/finance/FinanceItemController.java

@@ -0,0 +1,59 @@
+package com.hys.app.controller.erp.finance;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dto.FinanceItemDTO;
+import com.hys.app.model.erp.dto.FinanceItemQueryParams;
+import com.hys.app.model.erp.enums.FinanceIncomeTypeEnum;
+import com.hys.app.model.erp.vo.FinanceItemVO;
+import com.hys.app.service.erp.FinanceItemManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 财务明细 API
+ *
+ * @author 张崧
+ * 2024-03-15 17:40:23
+ */
+@RestController
+@RequestMapping("/admin/erp/financeItem")
+@Api(tags = "财务明细API")
+@Validated
+public class FinanceItemController {
+
+    @Autowired
+    private FinanceItemManager financeItemManager;
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public WebPage<FinanceItemVO> list(FinanceItemQueryParams queryParams) {
+        return financeItemManager.list(queryParams);
+    }
+
+    @ApiOperation(value = "新增")
+    @PostMapping
+    public void add(@RequestBody @Valid FinanceItemDTO financeItemDTO) {
+        financeItemManager.add(financeItemDTO);
+    }
+
+    @ApiOperation(value = "查询")
+    @GetMapping("/{id}")
+    public FinanceItemVO getDetail(@PathVariable Long id) {
+        return financeItemManager.getDetail(id);
+    }
+
+    @ApiOperation(value = "删除")
+    @DeleteMapping("/{ids}")
+    public void delete(@PathVariable List<Long> ids) {
+        financeItemManager.delete(ids);
+    }
+
+
+}
+

+ 103 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/AdminUserOperationManagerController.java

@@ -0,0 +1,103 @@
+package com.hys.app.controller.erp.use;
+
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.framework.exception.ServiceException;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.model.system.dos.AdminUser;
+import com.hys.app.model.system.vo.AdminUserVO;
+import com.hys.app.service.system.AdminUserManager;
+import com.hys.app.service.system.DeptManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * 平台管理员控制器
+ *
+ * @author zh
+ * @version v7.0
+ * @since v7.0.0
+ * 2018-06-20 20:38:26
+ */
+@RestController
+@RequestMapping("/admin/systems/manager/admin-users")
+@Api(description = "平台管理员管理相关API")
+@Validated
+public class AdminUserOperationManagerController {
+
+    @Autowired
+    private AdminUserManager adminUserManager;
+
+
+    @ApiOperation(value = "查询平台管理员列表", response = AdminUser.class)
+    @GetMapping
+    public WebPage list(@ApiIgnore Long pageNo, @ApiIgnore Long pageSize, @ApiIgnore String keyword, @ApiIgnore Integer userState,@ApiIgnore Long companyId) {
+        AdminUserContext.hasSuperAdminQuery(companyId);
+        return this.adminUserManager.list(pageNo, pageSize, keyword, userState);
+    }
+
+
+    @ApiOperation(value = "添加平台管理员", response = AdminUser.class)
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "添加用户编号为[${adminUserVO.sn}]的管理员")
+    public AdminUser add(@Valid AdminUserVO adminUserVO) {
+        AdminUserContext.hasAdmin();
+        return this.adminUserManager.add(adminUserVO);
+    }
+
+    @PutMapping(value = "/{id}")
+    @ApiOperation(value = "修改平台管理员", response = AdminUser.class)
+    @Log(client = LogClient.admin, detail = "修改ID为[${id}]的管理员信息")
+    public AdminUser edit(@Valid AdminUserVO adminUserVO, @PathVariable Long id) {
+        if (!Objects.equals(AdminUserContext.getAdminUserId(), id)) {
+            throw new ServiceException("只能修改自己的账号");
+        }
+        return this.adminUserManager.edit(adminUserVO, id);
+    }
+
+    @DeleteMapping(value = "/{id}")
+    @ApiOperation(value = "删除平台管理员")
+    @Log(client = LogClient.admin, detail = "删除ID为[${id}]的管理员信息")
+    public void delete(@PathVariable Long id) {
+        AdminUserContext.hasAdmin();
+        adminUserManager.delete(id);
+    }
+
+    @PutMapping(value = "/{id}/recover")
+    @ApiOperation(value = "恢复平台管理员")
+    @Log(client = LogClient.admin, detail = "恢复ID为[${id}]的管理员信息")
+    public void recover(@PathVariable Long id) {
+        AdminUserContext.hasAdmin();
+        this.adminUserManager.recover(id);
+    }
+
+    @GetMapping(value = "/{id}")
+    @ApiOperation(value = "查询一个平台管理员")
+    public AdminUser get(@PathVariable Long id) {
+        AdminUser adminUser = this.adminUserManager.getModel(id);
+        return adminUser;
+    }
+
+    @GetMapping(value = "/getUserByDept")
+    @ApiOperation(value = "查看自己部门下的所有人员")
+    public List<AdminUser> getUserByDept() {
+        return this.adminUserManager.getUserByDept();
+    }
+
+    @GetMapping(value = "/getUserByCompany")
+    @ApiOperation(value = "查询公司下所有的人员")
+    public List<AdminUser> getUserByCompany() {
+        return this.adminUserManager.getUserByCompany();
+    }
+}

+ 142 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/CompanyController.java

@@ -0,0 +1,142 @@
+package com.hys.app.controller.erp.use;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.exception.ServiceException;
+import com.hys.app.model.erp.configs.KuangShiConfig;
+import com.hys.app.model.erp.entity.*;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.CompanyErpManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Api(tags = "公司")
+@RestController
+@RequestMapping("/admin/erp/company")
+@AllArgsConstructor
+public class CompanyController {
+
+
+    private CompanyErpManager companyManager;
+    private KuangShiConfig kuangShiConfig;
+
+    @PostMapping("createCompany")
+    @ApiOperation(value = "创建公司")
+//    @Log(client = LogClient.admin, detail = "创建名称为[${companyDO.name}]的公司信息")
+    public String createCompany(@Valid @RequestBody CompanyDO companyDO) {
+        return companyManager.createCompany(companyDO);
+    }
+
+    @PostMapping("updateCompany/{id}")
+    @ApiOperation(value = "更新公司")
+    @Log(client = LogClient.admin, detail = "修改名称为[${companyDO.name}]的公司信息")
+    public Long updateCompany(@Valid @RequestBody CompanyDO companyUpdateDO, @PathVariable Long id) {
+        return companyManager.updateCompany(companyUpdateDO, id);
+    }
+
+    @PostMapping("renewCompany/difference/{id}")
+    @ApiOperation(value = "公司续费未到期更换套餐获取差价")
+    @Log(client = LogClient.admin, detail = "名称为[${companyDO.name}]的公司进行了续费")
+    public BigDecimal renewCompanyDifference(@PathVariable Long id) {
+        return companyManager.renewCompanyDifference(id);
+    }
+
+    @PostMapping("renewCompany/{id}/{packageId}")
+    @ApiOperation(value = "公司续费")
+    @Log(client = LogClient.admin, detail = "名称为[${companyDO.name}]的公司进行了续费")
+    public Long renewCompany(@PathVariable Long id, @PathVariable Long packageId) {
+        AdminUserContext.hasCompany();
+        return companyManager.renewCompany(id, packageId);
+    }
+
+    @PostMapping("superUpdateStatus/{id}")
+    @ApiOperation(value = "公司审核")
+    @Log(client = LogClient.admin, detail = "名称为[${companyDO.name}]的公司进行了续费")
+    public Long renewCompany(@PathVariable Long id, @RequestBody CompanyStatusDO companyStatusDO) {
+        AdminUserContext.hasFound();
+        return companyManager.superUpdateStatus(id, companyStatusDO);
+    }
+
+
+    @GetMapping("getOne/{id}")
+    @ApiOperation(value = "获取公司详情")
+    public CompanyVO getOneCompany(@PathVariable Long id) {
+        return companyManager.getOneCompany(id);
+    }
+
+    @GetMapping("getPage")
+    @ApiOperation(value = "分页")
+    public IPage<CompanyVO> getPage(CompanyQuery query) {
+        return companyManager.getPage(query);
+    }
+
+
+    @PostMapping("/createCompany/checkIdCardOpposite/{type}")
+    @ApiOperation(value = "校验身份证是否合法")
+    public Object checkIdCardOpposite(@RequestBody  CompanyQuery query, @PathVariable String type) {
+        try {
+            Map<String, Object> map = new HashMap<>();
+            map.put("image_url", query.getImageUrl());
+            map.put("api_key", kuangShiConfig.getApikey());
+            map.put("api_secret", kuangShiConfig.getApiSecret());
+            String post = HttpUtil.post(kuangShiConfig.getIdCardUrl(), map);
+            Map map1 = JSON.parseObject(post, Map.class);
+            if (ObjectUtil.isNull(map1.get("cards"))){
+                if ("front".equals(type)) {
+                    throw new ServiceException("身份证正面未识别到相关信息,请重新上传");
+                } else if ("opposite".equals(type)) {
+                    throw new ServiceException("身份证反面未识别到相关信息,请重新上传");
+                }
+            }
+            List<Map> maps = JSON.parseArray(JSON.toJSONString(map1.get("cards")), Map.class);
+            return maps.get(0);
+        } catch (Exception e) {
+            if ("front".equals(type)) {
+                throw new ServiceException("身份证正面未识别到相关信息,请重新上传");
+            } else if ("opposite".equals(type)) {
+                throw new ServiceException("身份证反面未识别到相关信息,请重新上传");
+            }
+        }
+        throw new ServiceException("非法请求");
+    }
+
+    @PostMapping("/createCompany/checkLicense")
+    @ApiOperation(value = "校验营业执照是否合法")
+    public Object checkLicense(@RequestBody  CompanyQuery query) {
+        try {
+            Map<String, Object> map = new HashMap<>();
+            map.put("image_url", query.getImageUrl());
+            map.put("api_key", kuangShiConfig.getApikey());
+            map.put("api_secret", kuangShiConfig.getApiSecret());
+            String post = HttpUtil.post(kuangShiConfig.getLicenseUrl(), map);
+            Map map1 = JSON.parseObject(post, Map.class);
+            if (ObjectUtil.isNull(map1.get("business_license_content"))){
+                throw new ServiceException("未识别到营业执照相关内容,请重新上传");
+            }
+            Map<String, Object> map2 = new HashMap<>();
+            map2.put("username","{}");
+            map2.put("password","{}");
+            map2.put("time","{}");
+            map2.put("phone","{}");
+            System.out.println(JSONUtil.toJsonStr(map2)+"---------------------------");
+            return JSON.parseObject(JSON.toJSONString(map1.get("business_license_content")), Map.class);
+        } catch (Exception e) {
+            throw new ServiceException("未识别到营业执照相关内容,请重新上传");
+        }
+    }
+
+}

+ 65 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/CompanyPackageController.java

@@ -0,0 +1,65 @@
+package com.hys.app.controller.erp.use;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.hys.app.converter.erp.CompanyPackageConverter;
+import com.hys.app.framework.database.BaseQueryParam;
+import com.hys.app.model.erp.entity.*;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.CompanyPackageManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+@Api(tags = "套餐")
+@RestController
+@RequestMapping("/admin/erp/companyPackage")
+@AllArgsConstructor
+public class CompanyPackageController {
+
+    private CompanyPackageManager companyPackageManager;
+
+    @PostMapping("createCompanyPackage")
+    @ApiOperation(value = "创建套餐")
+    @Log(client = LogClient.admin, detail = "创建名称为[${companyDO.name}]的公司信息")
+    public Long createCompany(@Valid @RequestBody CompanyPackageDO packageDo) {
+        return companyPackageManager.createCompanyPackage(packageDo);
+    }
+
+    @PostMapping("updateCompanyPackage/{id}")
+    @ApiOperation(value = "修改套餐")
+    @Log(client = LogClient.admin, detail = "创建名称为[${companyDO.name}]的公司信息")
+    public Long updateCompanyPackage(@Valid @RequestBody CompanyPackageDO packageDo, @PathVariable Long id) {
+        return companyPackageManager.updateCompanyPackage(packageDo,id);
+    }
+
+    @PostMapping("disAbleUse/{id}")
+    @ApiOperation(value = "套餐启用禁用")
+    @Log(client = LogClient.admin, detail = "修改id为[${id}]套餐的状态")
+    public void disAbleUse(@PathVariable Long id) {
+        CompanyPackage byId = companyPackageManager.getById(id);
+        byId.setUseAble(!byId.getUseAble());
+        companyPackageManager.updateById(byId);
+    }
+
+    @GetMapping("{id}")
+    @ApiOperation(value = "获取套餐详情")
+    public CompanyPackageVO getPackage(@PathVariable Long id) {
+        return CompanyPackageConverter.INSTANCE.convert(companyPackageManager.getById(id));
+    }
+
+    @PostMapping()
+    @ApiOperation(value = "获取套餐列表")
+    public IPage<CompanyPackageVO> getPackageList(@RequestBody CompanyPackageQuery packageDO) {
+        return CompanyPackageConverter.INSTANCE.convert(companyPackageManager.page(new Page<>(packageDO.getPageNo(), packageDO.getPageSize()),
+                new LambdaQueryWrapper<CompanyPackage>().eq(ObjectUtil.isNotNull(packageDO.getUseAble()), CompanyPackage::getUseAble, packageDO.getUseAble())
+                        .like(StrUtil.isNotBlank(packageDO.getName()), CompanyPackage::getName, packageDO.getName()).orderByDesc(CompanyPackage::getUseAble,CompanyPackage::getCreateTime)));
+    }
+}

+ 74 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/CustomerController.java

@@ -0,0 +1,74 @@
+package com.hys.app.controller.erp.use;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dto.CustomerDTO;
+import com.hys.app.model.erp.dto.CustomerQueryParams;
+import com.hys.app.model.erp.dto.OrderDTO;
+import com.hys.app.model.erp.dto.OrderQueryParams;
+import com.hys.app.model.erp.vo.CustomerVO;
+import com.hys.app.model.erp.vo.OrderVO;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.CustomerManager;
+import com.hys.app.service.erp.OrderManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * 订单 API
+ *
+ * @author 张崧
+ * 2024-01-24 15:58:31
+ */
+@RestController
+@RequestMapping("/admin/erp/customer")
+@Api(tags = "客户相关接口")
+@Validated
+public class CustomerController {
+
+    @Autowired
+    private CustomerManager customerManager;
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public WebPage<CustomerVO> list(CustomerQueryParams queryParams) {
+        return customerManager.list(queryParams);
+    }
+
+    @ApiOperation(value = "添加")
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "创建订单")
+    public void add(@RequestBody @Valid CustomerDTO customerDTO) {
+        customerManager.add(customerDTO);
+    }
+
+    @ApiOperation(value = "修改")
+    @PutMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "修改id为[${id}]的订单")
+    public void edit(@PathVariable Long id, @RequestBody @Valid CustomerDTO customerDTO) {
+        customerDTO.setId(id);
+        customerManager.edit(customerDTO);
+    }
+
+    @ApiOperation(value = "查询")
+    @GetMapping("/{id}")
+    public CustomerVO getDetail(@PathVariable Long id) {
+        return customerManager.getDetail(id);
+    }
+
+    @ApiOperation(value = "删除")
+    @DeleteMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "删除id为[${id}]的订单")
+    public void delete(@PathVariable Long id) {
+        customerManager.delete(id);
+    }
+
+}
+

+ 148 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/DeptController.java

@@ -0,0 +1,148 @@
+package com.hys.app.controller.erp.use;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.hys.app.converter.system.DeptConverter;
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.exception.ServiceException;
+import com.hys.app.framework.util.BeanUtils;
+import com.hys.app.framework.util.JsonUtil;
+import com.hys.app.mapper.system.AdminUserMapper;
+import com.hys.app.model.base.context.Region;
+import com.hys.app.model.base.context.RegionFormat;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.model.system.dos.AdminUser;
+import com.hys.app.model.system.dos.DeptDO;
+import com.hys.app.model.system.dto.DataPermissionDTO;
+import com.hys.app.model.system.dto.DeptCreateDTO;
+import com.hys.app.model.system.dto.DeptQueryParams;
+import com.hys.app.model.system.dto.DeptUpdateDTO;
+import com.hys.app.model.system.vo.DeptBaseVO;
+import com.hys.app.model.system.vo.DeptRespVO;
+import com.hys.app.model.system.vo.DeptSimpleRespVO;
+import com.hys.app.model.system.vo.Menus;
+import com.hys.app.service.system.AdminUserManager;
+import com.hys.app.service.system.DeptManager;
+import com.hys.app.service.system.RoleManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import javax.validation.constraints.NotEmpty;
+import java.util.Comparator;
+import java.util.List;
+
+@Api(tags = "管理后台 - 部门")
+@RestController
+@RequestMapping("/admin/systems/dept")
+@Validated
+public class DeptController {
+
+    @Resource
+    private DeptManager deptManager;
+
+    @Resource
+    private RoleManager roleManager;
+
+    @Autowired
+    private DeptConverter converter;
+
+    @Autowired
+    private AdminUserMapper adminUserMapper;
+
+    @PostMapping("create")
+    @ApiOperation(value = "创建部门")
+    @ApiImplicitParam(name = "region", value = "地区", required = true, example = "1024")
+    @Log(client = LogClient.admin, detail = "创建名称为[${reqVO.name}]的部门信息")
+    public void createDept(@Valid @RequestBody DeptCreateDTO reqVO) {
+        AdminUserContext.hasAdmin();
+        deptManager.createDept(reqVO);
+    }
+
+    @PutMapping("update/{id}")
+    @ApiOperation(value = "更新部门")
+    @Log(client = LogClient.admin, detail = "修改id为[${id}]的部门信息")
+    public void updateDept(@Valid @RequestBody DeptBaseVO reqVO, @PathVariable Long id) {
+        AdminUserContext.hasAdmin();
+        deptManager.updateDept(reqVO,id);
+    }
+
+    @DeleteMapping("delete")
+    @ApiOperation(value = "删除部门")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024")
+    @Log(client = LogClient.admin, detail = "删除ID为[${id}]的部门信息")
+    public void deleteDept(@RequestParam("id") Long id) {
+        AdminUserContext.hasAdmin();
+        deptManager.deleteDept(id);
+    }
+
+    @GetMapping("/list")
+    @ApiOperation(value = "获取部门列表")
+    public List<DeptRespVO> getDeptList(DeptQueryParams reqVO) {
+        AdminUserContext.hasSuperAdminQuery(reqVO.getCompanyId());
+        List<DeptDO> list = deptManager.getDeptList(reqVO);
+        list.sort(Comparator.comparing(DeptDO::getSort));
+        return BeanUtils.toBean(list,DeptRespVO.class);
+    }
+
+    @GetMapping("/list-all-simple")
+    @ApiOperation(value = "获取部门精简信息列表")
+    public List<DeptSimpleRespVO> getSimpleDeptList(DeptQueryParams reqVO) {
+        // 只查询当前用户有权限的部门
+        if (Boolean.TRUE.equals(reqVO.getOnlyPermission())) {
+            DataPermissionDTO dataPermissionDTO = roleManager.getDataPermission(AdminUserContext.getAdminUserId());
+            if (!dataPermissionDTO.getAll()) {
+                reqVO.setDeptIds(dataPermissionDTO.getDeptIds());
+            }
+        }
+
+        List<DeptDO> list = deptManager.getDeptList(reqVO);
+        // 排序后,返回给前端
+        list.sort(Comparator.comparing(DeptDO::getSort));
+        return converter.convertList02(list);
+    }
+
+    @GetMapping("/get")
+    @ApiOperation(value = "获得部门信息")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024")
+    public DeptRespVO getDept(@RequestParam("id") Long id) {
+        return converter.convert(deptManager.getDept(id));
+    }
+
+//    @GetMapping("/getMenusByDept/{deptId}")
+//    @ApiOperation(value = "获取这个部门所有的菜单")
+//    public List<Menus> getMenusByDept(@PathVariable Long deptId) {
+//        AdminUserContext.hasCompany();
+//        if ("admin".equals(AdminUserContext.getAdminUserName()) && deptId == 0) {
+//            AdminUser user = adminUserMapper.selectById(AdminUserContext.getAdminUserId());
+//            return JsonUtil.jsonToList(user.getAuthIds(), Menus.class);
+//        }
+//        DeptDO dept = deptManager.getDept(deptId);
+//        if (ObjectUtil.isNull(dept) || StrUtil.isBlank(dept.getAuthIds())) {
+//            throw new ServiceException("未获取到相关信息");
+//        }
+//        return JsonUtil.jsonToList(dept.getAuthIds(), Menus.class);
+//    }
+
+//    @GetMapping("/getAllSubDept")
+//    @ApiOperation(value = "获取所有的子部门")
+//    public List<DeptDO> getAllSubDept(@PathVariable String type) {
+//        if ("admin".equals(AdminUserContext.getAdminUserName())) {
+//            List<DeptDO> list = deptManager.list(new LambdaQueryWrapper<DeptDO>().eq(DeptDO::getCompanyId, AdminUserContext.getCompanyId()));
+//                DeptDO deptDO = new DeptDO();
+//                deptDO.setName("公司管理员");
+//                deptDO.setId(0L);
+//                list.add(deptDO);
+//            return list;
+//        }
+//        return deptManager.getAllSubDept(AdminUserContext.getDeptId());
+//    }
+}

+ 119 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/KdnController.java

@@ -0,0 +1,119 @@
+package com.hys.app.controller.erp.use;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.hys.app.framework.database.BaseQueryParam;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.kuaidiniao.KdConstants;
+import com.hys.app.service.kuaidiniao.KuaiDiNiaoService;
+import com.hys.app.service.kuaidiniao.entity.*;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * OAuth2.0 授权 API
+ *
+ * @author 张崧
+ * @since 2024-02-20
+ */
+@Api(tags = "快递鸟")
+@RestController
+@RequestMapping("/admin/erp/kdn")
+@Validated
+@Slf4j
+@AllArgsConstructor
+public class KdnController {
+    private KuaiDiNiaoService kuaiDiNiaoService;
+
+    @PostMapping("/returnBack/instant")
+    public resReturnBackBase kdnReturnBackInstant(ReturnBackInstant returnBackBase) {
+        return kuaiDiNiaoService.kdnReturnBack(returnBackBase);
+    }
+
+    @ApiOperation(value = "快递鸟发货获取单号")
+    @PostMapping("/prePareTime/{orderId}")
+    @Log(client = LogClient.admin, detail = "订单[${orderId}]发货")
+    public String prePareTime(@PathVariable(value = "orderId") Long orderId
+            , @RequestBody @Valid PreOrderModelDTO preOrderModel
+            , @RequestBody AddressDTO addressDTO) {
+        return kuaiDiNiaoService.prePareTime(preOrderModel, orderId, addressDTO);
+    }
+
+
+    @ApiOperation(value = "快递鸟发货获取单号")
+    @PostMapping("/kdShip/{orderId}")
+    @Log(client = LogClient.admin, detail = "订单[${orderId}]发货")
+    public String kdShip(@PathVariable(value = "orderId") Long orderId
+            , @RequestBody @Valid PreOrderModelDTO preOrderModel
+            , @RequestBody AddressDTO addressDTO) {
+        return kuaiDiNiaoService.kdShip(preOrderModel, orderId, addressDTO);
+    }
+
+
+    @ApiOperation(value = "快递鸟创建门店")
+    @PostMapping("/createStore")
+    @Log(client = LogClient.admin, detail = "快递鸟创建店铺")
+    public void createStore(@RequestBody @Valid CreateStoreModel createStoreModel) {
+        kuaiDiNiaoService.createStore(createStoreModel, KdConstants.createStore);
+    }
+
+    @ApiOperation(value = "创建失败修改参数再次创建快递鸟门店")
+    @PostMapping("/updateStore")
+    @Log(client = LogClient.admin, detail = "快递鸟创建店铺")
+    public void updateStore(@RequestBody @Valid CreateStoreModel createStoreModel) {
+        kuaiDiNiaoService.createStore(createStoreModel, KdConstants.updateStore);
+    }
+
+    @ApiOperation(value = "快递鸟门店列表")
+    @GetMapping("/list")
+    @Log(client = LogClient.admin, detail = "获取快递鸟店铺列表")
+    public Page<CreateStoreModel> getStoreList(BaseQueryParam baseQueryParam) {
+        return kuaiDiNiaoService.getStoreList(baseQueryParam);
+    }
+
+    @ApiOperation(value = "selectAudit")
+    @GetMapping("/selectAudit")
+    @Log(client = LogClient.admin, detail = "获取快递鸟店铺列表")
+    public void selectAudit(CreateStoreModel createStoreModel) {
+        kuaiDiNiaoService.selectAudit(createStoreModel);
+    }
+
+
+    @ApiOperation(value = "queryLogistics")
+    @PostMapping("/queryLogistics")
+    @Log(client = LogClient.admin, detail = "订阅物流查询")
+    public void queryLogistics(@RequestBody LogisyicsTopic logisyicsTopic ) {
+        kuaiDiNiaoService.queryLogistics(logisyicsTopic);
+    }
+
+    @PostMapping("/returnBack/logistics")
+    public ReturnBackLogisticsResponse kdnReturnBackLogistics( ReturnBackInstant returnBackInstant ) {
+        ReturnBackLogistics returnBackBase = JSON.parseObject(returnBackInstant.getRequestData(), ReturnBackLogistics.class);
+        ReturnBackLogisticsResponse response = new ReturnBackLogisticsResponse();
+        if (returnBackBase.getCount() >0){
+            List<Map> maps = JSON.parseArray(returnBackBase.getData(), Map.class);
+            for (Map map : maps) {
+                Boolean b = kuaiDiNiaoService.kdnReturnBackLogistics(map);
+                if (!b){
+                    response.setSuccess(false);
+                }
+            }
+        }
+        return response;
+    }
+
+    @PostMapping("/cancelKdn/abc")
+    public String abc() {
+        return "请求成功了";
+    }
+}

+ 108 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/LogisticsCompanyManagerController.java

@@ -0,0 +1,108 @@
+package com.hys.app.controller.erp.use;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.system.dos.LogisticsCompanyDO;
+import com.hys.app.model.system.dto.FormItem;
+import com.hys.app.service.erp.LogisticsCompanyManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * 物流公司控制器
+ *
+ * @author zjp
+ * @version v7.0.0
+ * @since v7.0.0
+ * 2018-03-29 15:10:38
+ */
+@RestController
+@RequestMapping("/admin/systems/logi-companies")
+@Api(description = "物流公司相关API")
+@Validated
+public class LogisticsCompanyManagerController {
+
+    @Autowired
+    private LogisticsCompanyManager logisticsCompanyManager;
+
+    @ApiOperation(value = "查询物流公司列表", response = LogisticsCompanyDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page_no", value = "页码", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "page_size", value = "每页显示数量", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "name", value = "物流公司名称", dataType = "String", paramType = "query")
+    })
+    @GetMapping
+    public WebPage list(@ApiIgnore @NotNull(message = "页码不能为空") Long pageNo, @ApiIgnore @NotNull(message = "每页数量不能为空") Long pageSize, @ApiIgnore String name) {
+
+        return this.logisticsCompanyManager.list(pageNo, pageSize, name);
+    }
+
+
+    @ApiOperation(value = "添加物流公司", response = LogisticsCompanyDO.class)
+    @PostMapping
+    public LogisticsCompanyDO add(@Valid LogisticsCompanyDO logi,@RequestBody @Valid List<FormItem> formItems) {
+
+        logi.setForm(formItems);
+        this.logisticsCompanyManager.add(logi);
+
+        return logi;
+    }
+
+    @PutMapping(value = "/{id}")
+    @ApiOperation(value = "修改物流公司", response = LogisticsCompanyDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", required = true, dataType = "int", paramType = "path")
+    })
+    public LogisticsCompanyDO edit(@Valid LogisticsCompanyDO logi, @PathVariable("id") Long id,@RequestBody @Valid List<FormItem> formItems) {
+
+        logi.setForm(formItems);
+        this.logisticsCompanyManager.edit(logi, id);
+
+        return logi;
+    }
+
+
+    @DeleteMapping(value = "/{id}")
+    @ApiOperation(value = "删除物流公司")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "要删除的物流公司主键", required = true, dataType = "int", paramType = "path")
+    })
+    public String delete(@PathVariable("id") Long id) {
+        this.logisticsCompanyManager.delete(id);
+
+        return "";
+    }
+
+
+    @GetMapping(value = "/{id}")
+    @ApiOperation(value = "查询一个物流公司")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "要查询的物流公司主键", required = true, dataType = "int", paramType = "path")
+    })
+    public LogisticsCompanyDO get(@PathVariable("id") Long id) {
+        LogisticsCompanyDO logi = this.logisticsCompanyManager.getModel(id);
+        return logi;
+    }
+
+    @PostMapping(value = "/{id}")
+    @ApiOperation(value = "开启或禁用物流公司")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "物流公司主键ID", required = true, dataType = "int", paramType = "path"),
+            @ApiImplicitParam(name = "disabled", value = "状态 OPEN:开启,CLOSE:禁用", required = true, dataType = "String", paramType = "path", allowableValues = "OPEN,CLOSE")
+    })
+    public String openClose(@PathVariable("id") Long id, @ApiIgnore String disabled) {
+        this.logisticsCompanyManager.openCloseLogi(id, disabled);
+
+        return "";
+    }
+
+}

+ 155 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/OrderController.java

@@ -0,0 +1,155 @@
+package com.hys.app.controller.erp.use;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.database.BaseQueryParam;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.framework.security.model.Admin;
+import com.hys.app.model.erp.dos.OrderCustomerFee;
+import com.hys.app.model.erp.dos.OrderSendDO;
+import com.hys.app.model.erp.dto.OrderDTO;
+import com.hys.app.model.erp.dto.OrderQueryParams;
+import com.hys.app.model.erp.enums.ScanFormCodeTypeEnum;
+import com.hys.app.model.erp.vo.OrderVO;
+import com.hys.app.model.erp.vo.ProductVO;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.OrderManager;
+import com.hys.app.service.kuaidiniao.entity.AddressDTO;
+import com.hys.app.service.kuaidiniao.entity.PreOrderModel;
+import com.hys.app.service.kuaidiniao.entity.PreOrderModelDTO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotEmpty;
+import java.util.List;
+
+/**
+ * 订单 API
+ *
+ * @author 张崧
+ * 2024-01-24 15:58:31
+ */
+@RestController
+@RequestMapping("/admin/erp/order")
+@Api(tags = "订单API")
+@Validated
+public class OrderController {
+
+    @Autowired
+    private OrderManager orderManager;
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public WebPage<OrderVO> list(OrderQueryParams queryParams) {
+        Admin admin = AdminUserContext.getAdmin();
+        return orderManager.list(queryParams);
+    }
+
+    @ApiOperation(value = "添加")
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "创建订单")
+    public Long add(@RequestBody @Valid OrderDTO orderDTO) {
+        return orderManager.add(orderDTO);
+    }
+
+    @ApiOperation(value = "修改")
+    @PutMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "修改id为[${id}]的订单")
+    public void edit(@PathVariable Long id, @RequestBody @Valid OrderDTO orderDTO) {
+        orderDTO.setId(id);
+        orderManager.edit(orderDTO);
+    }
+
+    @ApiOperation(value = "查询")
+    @GetMapping("/{id}")
+    public OrderVO getDetail(@PathVariable Long id) {
+        return orderManager.getDetail(id);
+    }
+
+    @ApiOperation(value = "确认")
+    @PostMapping("/submit/{id}")
+    @Log(client = LogClient.admin, detail = "提交ID为[${id}]的订单")
+    public void submit(@PathVariable Long id) {
+        orderManager.submit(id);
+    }
+
+
+    @ApiOperation(value = "撤销")
+    @PostMapping("/revoke/{id}")
+    @Log(client = LogClient.admin, detail = "撤销ID为[${id}]的订单")
+    public void returnOrder(@PathVariable Long id) {
+        orderManager.returnOrder(id);
+    }
+
+    @ApiOperation(value = "删除")
+    @DeleteMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "删除id为[${id}]的订单")
+    public void delete(@PathVariable Long id) {
+        orderManager.delete(id);
+    }
+
+
+    @ApiOperation(value = "发货")
+    @PostMapping("/orderSend/{orderSendId}")
+    @Log(client = LogClient.admin, detail = "销售列表发货")
+    public void orderSend(@PathVariable(value = "orderSendId") Long orderSendId,@RequestBody PreOrderModelDTO orderSendDO) {
+         orderManager.orderSend(orderSendId,orderSendDO);
+    }
+
+    @ApiOperation(value = "保存发货单")
+    @PostMapping("/saveOrderSend/{orderSendId}")
+    @Log(client = LogClient.admin, detail = "销售列表发货")
+    public void saveOrderSend(@PathVariable(value = "orderSendId") Long orderSendId,@RequestBody PreOrderModelDTO orderSendDO) {
+        orderManager.saveOrderSend(orderSendId,orderSendDO);
+    }
+
+
+    @ApiOperation(value = "已发货分页列表")
+    @GetMapping("saleOrder/list")
+    public IPage<OrderSendDO> saleOrder(OrderQueryParams queryParams) {
+        return orderManager.hasSendOrder(queryParams);
+    }
+
+    @ApiOperation(value = "获取发货详情")
+    @GetMapping("getSendOrderDetail/{id}")
+    public OrderSendDO getSendOrderDetail( @PathVariable(value = "id") String id) {
+        return orderManager.getSendOrderDetail(id);
+    }
+
+
+    @ApiOperation(value = "getOneBySn")
+    @GetMapping("getOneBySn/{sn}")
+    public OrderVO getOneBySn(@PathVariable String sn) {
+        return orderManager.getOneBySn(sn);
+    }
+
+
+    @ApiOperation(value = "延期")
+    @PostMapping("/extension/{orderId}")
+    @Log(client = LogClient.admin, detail = "延期")
+    public void extension(@PathVariable(value = "orderId") Long orderId ,@RequestBody @Valid OrderDTO orderDTO) {
+        orderManager.extension(orderId,orderDTO);
+    }
+
+    @ApiOperation(value = "添加费用报销")
+    @PostMapping("addOrderCustomerFee")
+    @Log(client = LogClient.admin, detail = "创建订单")
+    public Long add(@RequestBody @Valid OrderCustomerFee orderCustomerFee) {
+        return orderManager.addOrderCustomerFee(orderCustomerFee);
+    }
+
+    @ApiOperation(value = "修改费用报销")
+    @PostMapping("/editOrderCustomerFee/{id}")
+    @Log(client = LogClient.admin, detail = "修改id为[${id}]的费用报销单")
+    public void edit(@PathVariable Long id, @RequestBody @Valid OrderCustomerFee orderCustomerFee) {
+        orderManager.editOrderCustomerFee(id,orderCustomerFee);
+    }
+}
+

+ 37 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/OrderItemController.java

@@ -0,0 +1,37 @@
+package com.hys.app.controller.erp.use;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dto.OrderItemQueryParams;
+import com.hys.app.model.erp.vo.OrderItemVO;
+import com.hys.app.service.erp.OrderItemManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 订单明细 API
+ *
+ * @author 张崧
+ * 2024-01-24 16:39:39
+ */
+@RestController
+@RequestMapping("/admin/erp/orderItem")
+@Api(tags = "订单明细API")
+@Validated
+public class OrderItemController {
+
+    @Autowired
+    private OrderItemManager orderItemManager;
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public WebPage<OrderItemVO> list(OrderItemQueryParams queryParams) {
+        return orderItemManager.list(queryParams);
+    }
+
+}
+

+ 257 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/PayController.java

@@ -0,0 +1,257 @@
+package com.hys.app.controller.erp.use;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
+import com.hys.app.framework.exception.ServiceException;
+import com.hys.app.framework.util.DateUtil;
+import com.hys.app.framework.util.JsonUtil;
+import com.hys.app.framework.util.ScriptUtil;
+import com.hys.app.framework.util.StringUtil;
+import com.hys.app.mapper.system.AdminUserMapper;
+import com.hys.app.mapper.system.RoleMapper;
+import com.hys.app.model.erp.configs.KuangShiConfig;
+import com.hys.app.model.erp.dos.OrderCustomerFee;
+import com.hys.app.model.erp.dos.OrderDO;
+import com.hys.app.model.erp.dto.PayTypeUrl;
+import com.hys.app.model.erp.entity.CompanyErp;
+import com.hys.app.model.system.dos.AdminUser;
+import com.hys.app.model.system.dos.RoleDO;
+import com.hys.app.model.system.vo.Menus;
+import com.hys.app.pay.ali.AliPayService;
+import com.hys.app.pay.ali.PayOrder;
+import com.hys.app.pay.ali.UserInfoWx;
+import com.hys.app.pay.wx.WxConfig;
+import com.hys.app.pay.wx.WxPayServiceMy;
+import com.hys.app.service.erp.CompanyErpManager;
+import com.hys.app.service.erp.OrderCustomerFeeManager;
+import com.hys.app.service.erp.OrderManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
+import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
+import me.chanjar.weixin.mp.bean.template.WxMpTemplateIndustry;
+import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
+import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cloud.commons.util.IdUtils;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+import java.net.URLDecoder;
+import java.net.UnknownHostException;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@RestController
+@RequestMapping("/admin/erp/pay")
+@Api(tags = "订单支付")
+@Validated
+@AllArgsConstructor
+public class PayController extends HttpServlet {
+    //    private OrderManager orderManager;
+    private AliPayService aliPayService;
+    private WxPayServiceMy wxPayServiceMy;
+    private CompanyErpManager companyManager;
+    private AdminUserMapper adminUserMapper;
+    private RoleMapper roleMapper;
+
+    private static final Logger log = LoggerFactory.getLogger(ScriptUtil.class);
+
+
+    @ApiOperation(value = "扫描完获取拉起支付的url")
+    @PostMapping("/getPayUrl")
+    public Object getListByScan(@RequestBody @Validated PayTypeUrl payTypeUrl) throws UnknownHostException, WxPayException {
+        CompanyErp company = companyManager.getById(payTypeUrl.getId());
+        AdminUser user = adminUserMapper.selectById(payTypeUrl.getUserId());
+        if (ObjectUtil.isNull(company)) {
+            throw new ServiceException("未查询到公司信息");
+        }
+        PayOrder payOrder = new PayOrder();
+//        payOrder.setTraceNo(company.getId().toString());
+        payOrder.setTraceNo(IdUtil.simpleUUID());
+        payOrder.setSubject("购买公司使用权账号");
+        payOrder.setTimeExpire(LocalDateTime.now().plusMinutes(30));
+//        payOrder.setTotalAmount(company.getThisMoney().doubleValue());
+        payOrder.setTotalAmount(0.01);
+        payOrder.setOrderPayType("company");
+        switch (payTypeUrl.getPayType()) {
+            case "ali":
+                return aliPayService.pay(payOrder);
+            case "wx":
+                if (ObjectUtil.isNotNull(user) && StrUtil.isBlank(user.getOpenid())) {
+                    throw new WxPayException("当前用户未绑定微信,请前往我的个人信息里面绑定微信后再支付");
+                }
+                payOrder.setOpenId(user.getOpenid());
+                return wxPayServiceMy.pay(payOrder);
+            default:
+                return "不支持的支付方式";
+        }
+    }
+
+    @PostMapping("/aliReturnCall")
+    @Transactional(rollbackFor = Exception.class)
+    public String aliReturnCall(HttpServletRequest request) throws Exception {
+        Map<String, String> params = new HashMap<>();
+        Map<String, String[]> requestParams = request.getParameterMap();
+        for (String name : requestParams.keySet()) {
+            String[] values = requestParams.get(name);
+            String valueStr = String.join(",", values);
+            params.put(name, valueStr);
+        }
+        if (aliPayService.checkReturnParam(params)) {
+            String passbackParams = URLDecoder.decode(params.get("passback_params"), "UTF-8");
+            if ("company".equals(passbackParams)) {
+                CompanyErp company = companyManager.getById(params.get("out_trade_no"));
+                //如果结束时间大于当前时间,那么就从现在加起
+                Date currentDate = company.getEndUseTime();
+                if (new Date().compareTo(company.getEndUseTime()) > 0) {
+                    currentDate = new Date();
+
+                }
+                // 使用 加上套餐包的天数
+                Calendar calendar = Calendar.getInstance();
+                calendar.setTime(currentDate);
+                calendar.add(Calendar.DAY_OF_MONTH, company.getThisDay());
+
+                company.setEndUseTime(calendar.getTime());
+                company.setMoney(company.getMoney().add(company.getThisMoney()));
+                company.setRoleId(company.getThisRoleId());
+                company.setUserNum(company.getThisUserNum());
+                company.setCompanyPackageId(company.getThisCompanyPackageId());
+
+                company.setThisDay(0);
+                company.setThisCompanyPackageId(0L);
+                company.setThisMoney(new BigDecimal(0));
+                company.setThisRoleId(0L);
+                company.setThisUserNum(0);
+
+                companyManager.updateById(company);
+//                //  不管换没换套餐  把新的套餐权限赋值到公司的admin账号上
+                AdminUser user = adminUserMapper.selectOne(new LambdaQueryWrapper<AdminUser>()
+                        .eq(AdminUser::getCompanyId, company.getId())
+                        .eq(AdminUser::getUsername, "admin").last("limit 1"));
+                //把这个管理员能看到的所有页面保存起来
+                RoleDO roleDO = roleMapper.selectById(company.getThisRoleId());
+                List<Menus> menusList = JsonUtil.jsonToList(roleDO.getAuthIds(), Menus.class);
+                List<Menus> list = new ArrayList<>();
+                assert menusList != null;
+                for (Menus menu : menusList) {
+                    if (CollUtil.isNotEmpty(menu.getChildren())) {
+                        list.add(menu);
+                        getMenus(list, menu);
+                    } else {
+                        list.add(menu);
+                    }
+                }
+                //这个角色所有已勾选的菜单
+                Set<Menus> collect = list.stream().filter(Menus::isChecked).collect(Collectors.toSet());
+                for (Menus menus1 : collect) {
+                    menus1.setChildren(collect.stream().filter(item -> item.getParentId().equals(menus1.getId())).collect(Collectors.toList()));
+                }
+                List<Menus> collect2 = collect.stream().filter(item -> item.getParentId() == 0).collect(Collectors.toList());
+                user.setAuthIds(JSON.toJSONString(collect2));
+                adminUserMapper.updateById(user);
+            }
+        }
+        return "success";
+    }
+
+    private void getMenus(List<Menus> list, Menus menus) {
+        for (Menus child : menus.getChildren()) {
+            list.add(child);
+            getMenus(list, child);
+        }
+    }
+
+
+    @PostMapping("/wxpay/notify")
+    public String parseOrderNotify(@RequestBody String xmlData) {
+        try {
+            System.out.println("微信支付回调来了啊+11111111111111111111111111111111111111111111111111111111111");
+            WxPayServiceImpl wxPayService = new WxPayServiceImpl();
+            // 解析支付通知结果
+            WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
+            // 处理订单逻辑
+        } catch (WxPayException e) {
+            // 处理解析异常,记录日志
+            e.printStackTrace();
+        }
+//        return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[解析失败]]></return_msg></xml>";
+        return "<xml>" +
+                "<return_code><![CDATA[" + "SUCCESS" + "]]></return_code>" +
+                "<return_msg><![CDATA[" + "OK" + "]]></return_msg>" +
+                "</xml>";
+    }
+
+    @PostMapping("getOpenIdCode/{userId}")
+    public String getOpenIdCode(@PathVariable Long userId, @RequestBody @Validated Map map) throws UnsupportedEncodingException {
+        String openIdCode = wxPayServiceMy.getOpenIdCode(userId, map.get("ip").toString());
+        System.out.println("授权地址+“--------------------------------------------------------" + openIdCode + "ip-----------------" + map.get("ip").toString());
+        return wxPayServiceMy.getOpenIdCode(userId, map.get("ip").toString());
+    }
+
+    @GetMapping("/weixin/callback/openidCode")
+    public void handleWeixinCallback(@RequestParam("code") String code, @RequestParam("state") String state, HttpSession session, HttpServletResponse response) throws Exception {
+        log.info("授权回调来了啊" +code+"----------" +state );
+        if (!state.equals(session.getAttribute("WEIXIN_OAUTH_STATE"))) {
+            log.error("用户授权,state错误");
+        }
+        AdminUser user = adminUserMapper.selectById(state);
+        if (ObjectUtil.isNull(user)) {
+            log.error("未查询到用户信息:" + state);
+        }
+        String openId = wxPayServiceMy.getOpenId(code);
+        user.setOpenid(openId);
+        adminUserMapper.updateById(user);
+//        String accessToken = wxPayServiceMy.getAccessToken(code);
+//        String userInfo = wxPayServiceMy.getUserInfo(accessToken, openId);
+//        UserInfoWx userInfoWx = JSON.parseObject(JSON.toJSONString(userInfo), UserInfoWx.class);
+//        System.out.println(userInfo+"--------------1111111111");
+//        System.out.println(userInfoWx+"--------------2222222222222222");
+    }
+
+
+    @GetMapping("/sendMsg")
+    public void sendMsg(String openid) throws WxErrorException {
+//        AdminUser user = adminUserMapper.selectById(1811346086600843265L);
+        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
+                .toUser(openid)
+                .templateId("BmtA7g2Z2KomlIvNS0OtmEVu4ySqPUlSYZNo9zBZxtc")
+                .build();
+
+        templateMessage.addData(new WxMpTemplateData("thing3", "黄理志"))
+                .addData(new WxMpTemplateData("time4", "2022-11-17 22:04:40", "#173177"))
+                .addData(new WxMpTemplateData("character_string6", "A14010001688", "#173177"))
+                .addData(new WxMpTemplateData("thing8", "贸易通订单流程待处理通知", "#173177"))
+                .addData(new WxMpTemplateData("character_string13", "202308060001!", "#173177"));
+        WxMpService wxService = new WxMpServiceImpl();
+        WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
+        config.setAppId("wx51e98f2dee35237d");  // 替换为你的 AppID
+        config.setSecret("13803c1b0d911e023c7da0b300cbce89");  // 替换为你的 AppSecret
+        wxService.setWxMpConfigStorage(config);
+        wxService.getTemplateMsgService().sendTemplateMsg(templateMessage);
+    }
+
+}

+ 102 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/ProductManagerController.java

@@ -0,0 +1,102 @@
+package com.hys.app.controller.erp.use;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dos.ProductDO;
+import com.hys.app.model.erp.dto.ProductDTO;
+import com.hys.app.model.erp.dto.ProductGroupQueryParams;
+import com.hys.app.model.erp.dto.ProductQueryParams;
+import com.hys.app.model.erp.vo.ProductVO;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.ProductManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+/**
+ * 产品相关API
+ *
+ * @author 张崧
+ * 2023-11-30 16:06:44
+ */
+@RestController
+@RequestMapping("/admin/erp/product")
+@Api(tags = "产品相关API")
+@Validated
+public class ProductManagerController {
+
+    @Autowired
+    private ProductManager productManager;
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public IPage<ProductDO> list(ProductQueryParams queryParams) {
+        AdminUserContext.hasSuperAdminQuery(queryParams.getCompanyId());
+        return productManager.list(queryParams);
+    }
+
+
+    @ApiOperation(value = "新增产品")
+    @PostMapping("/addProduct")
+    @Log(client = LogClient.admin, detail = "添加名称为[${productDTO.name}]的商品信息")
+    public void productGroup(@RequestBody @Valid ProductDTO productDTO) {
+        AdminUserContext.hasCompany();
+        productManager.addProduct(productDTO);
+    }
+
+    @ApiOperation(value = "修改产品")
+    @PostMapping("/updateProduct/{id}")
+    @Log(client = LogClient.admin, detail = "修改id为[${id}]的商品信息")
+    public void updateProduct(@RequestBody @Valid ProductDTO productDTO, @PathVariable Long id) {
+        AdminUserContext.hasCompany();
+        productManager.updateProduct(productDTO, id);
+    }
+
+    @ApiOperation(value = "删除产品")
+    @PostMapping("/deletedProduct/{id}")
+    @Log(client = LogClient.admin, detail = "删除id为[${id}]的商品信息")
+    public void deletedProduct(@PathVariable Long id) {
+        AdminUserContext.hasCompany();
+        productManager.deletedProduct(id);
+    }
+
+    @ApiOperation(value = "获取详情")
+    @PostMapping("/getProduct/{id}")
+    public void getProduct(@PathVariable Long id) {
+        productManager.getById(id);
+    }
+
+    @ApiOperation(value = "获取列表")
+    @PostMapping("/getProductList")
+    public IPage<ProductDO> getProductList(ProductQueryParams queryParams) {
+        AdminUserContext.hasSuperAdminQuery(queryParams.getCompanyId());
+        return productManager.page(new Page<>(queryParams.getPageNo(), queryParams.getPageSize()),
+                new LambdaQueryWrapper<ProductDO>()
+                        .eq(ProductDO::getCompanyId, AdminUserContext.getCompanyId())
+                        .and(StrUtil.isNotBlank(queryParams.getKeyword()), item -> item
+                                .like(ProductDO::getName, queryParams.getName())
+                                .or()
+                                .like(ProductDO::getName, queryParams.getBrand())
+                                .or()
+                                .like(ProductDO::getName, queryParams.getSn())));
+    }
+
+    @ApiOperation(value = "设置库存预警")
+    @PostMapping("/updateWarnStock")
+    @Log(client = LogClient.admin, detail = "新增入库获取所有的sku信息")
+    public void updateWarnStock( @RequestBody  ProductGroupQueryParams productGroupQueryParams) {
+        AdminUserContext.hasCompany();
+        productManager.updateWarnStock(productGroupQueryParams.getStockId(), productGroupQueryParams.getWarnNum());
+    }
+
+}
+

+ 82 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/ProductStockManagerController.java

@@ -0,0 +1,82 @@
+package com.hys.app.controller.erp.use;
+
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dto.ProductStockDeleteReq;
+import com.hys.app.model.erp.dto.ProductStockQueryParams;
+import com.hys.app.model.erp.vo.*;
+import com.hys.app.service.erp.*;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 商品库存相关API
+ *
+ * @author 张崧
+ * @since 2023-12-07 10:08:44
+ */
+@RestController
+@RequestMapping("/admin/erp/productStock")
+@Api(tags = "商品库存相关API")
+@Validated
+public class ProductStockManagerController {
+
+    @Autowired
+    private ProductStockManager productStockManager;
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public WebPage<ProductStockV1> list(ProductStockQueryParams queryParams) {
+        AdminUserContext.hasSuperAdminQuery(queryParams.getCompanyId());
+        List<ProductStockV1> productStockV1s= productStockManager.selectList(queryParams);
+        Long recordCount= productStockManager.selectCount(queryParams);
+        WebPage<ProductStockV1> voWebPage1=new WebPage<>();
+        voWebPage1.setPageSize(queryParams.getPageSize());
+        voWebPage1.setPageNo(queryParams.getPageNo());
+        voWebPage1.setDataTotal(recordCount);
+        voWebPage1.setData(productStockV1s);
+        return voWebPage1;
+    }
+
+
+//    @ApiOperation(value = "查询一条数据")
+//    @ApiImplicitParams({
+//            @ApiImplicitParam(name = "id", value = "id", dataType = "String", paramType = "query")
+//    })
+//    @GetMapping("/getOne")
+//    public ProductStockDO getOne(@RequestParam String id){
+//        return productStockManager.getOne(id);
+//    }
+
+    @ApiOperation(value = "删除库存记录")
+    @PostMapping("/delete")
+    public void delete(@RequestBody @Valid ProductStockDeleteReq request){
+//         productStockManager.deleteByIds(request.getIds());
+    }
+
+
+    @ApiOperation(value = "查询商品库存预警分页列表数据")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page_no", value = "分页数", dataType = "int", paramType = "query", required = true),
+            @ApiImplicitParam(name = "page_size", value = "每页数量", dataType = "int", paramType = "query", required = true),
+            @ApiImplicitParam(name = "warehouse_id", value = "仓库ID", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "dept_id", value = "部门ID", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "name", value = "商品名称", dataType = "String", paramType = "query")
+    })
+    @GetMapping("/list-stock-warning")
+    public WebPage<ProductStockWarningVO> listWarningStock(@ApiIgnore Long pageNo, @ApiIgnore Long pageSize,
+                                                           @ApiIgnore Long warehouseId, @ApiIgnore Long deptId, @ApiIgnore String name) {
+//        return productStockManager.listWarningStock(pageNo, pageSize, warehouseId, deptId, name);
+        return null;
+    }
+}
+

+ 127 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/RoleManagerController.java

@@ -0,0 +1,127 @@
+package com.hys.app.controller.erp.use;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.framework.exception.ServiceException;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.model.system.dos.RoleDO;
+import com.hys.app.model.system.vo.RoleVO;
+import com.hys.app.service.system.RoleManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.constraints.NotEmpty;
+import java.util.List;
+
+
+/**
+ * 角色表控制器
+ *
+ * @author admin
+ * @version v1.0.0
+ * @since v7.0.0
+ * 2018-04-17 16:48:27
+ */
+@RestController
+@RequestMapping("/admin/systems/roles")
+@Api(description = "角色表相关API")
+public class RoleManagerController {
+
+    @Autowired
+    private RoleManager roleManager;
+
+
+    @ApiOperation(value = "角色列表分页", response = RoleDO.class)
+    @GetMapping
+    public WebPage list(@ApiIgnore @NotEmpty(message = "页码不能为空") Long pageNo, @ApiIgnore @NotEmpty(message = "每页数量不能为空") Long pageSize, @ApiIgnore String keyword, @ApiIgnore Long companyId) {
+        AdminUserContext.hasSuperAdminQuery(companyId);
+        return this.roleManager.list(pageNo, pageSize, keyword,null);
+    }
+
+    @ApiOperation(value = "套餐角色列表", response = RoleDO.class)
+    @GetMapping("packageList")
+    public IPage list(@ApiIgnore @NotEmpty(message = "页码不能为空") Long pageNo, @ApiIgnore @NotEmpty(message = "每页数量不能为空") Long pageSize) {
+        return this.roleManager.page(new Page<>(pageNo,pageSize),new LambdaQueryWrapper<RoleDO>().isNull(RoleDO::getCompanyId));
+    }
+
+
+    @ApiOperation(value = "角色列表分页", response = RoleDO.class)
+    @GetMapping("packageSuper")
+    public IPage packageSuper(@ApiIgnore @NotEmpty(message = "页码不能为空") Long pageNo, @ApiIgnore @NotEmpty(message = "每页数量不能为空") Long pageSize, @ApiIgnore String keyword) {
+        return roleManager.page(new Page<>(pageNo, pageSize), new LambdaQueryWrapper<RoleDO>().isNull(RoleDO::getCompanyId));
+    }
+
+
+    @ApiOperation(value = "添加角色", response = RoleDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "roleVO", value = "角色", required = true, dataType = "RoleVO", paramType = "body")
+    })
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "添加名称为[${roleVO.roleName}]的角色信息")
+    public RoleVO add(@RequestBody @ApiIgnore RoleVO roleVO) {
+        AdminUserContext.hasAdminAndSuper();
+        return this.roleManager.add(roleVO);
+    }
+
+    @PutMapping(value = "/{id}")
+    @ApiOperation(value = "修改角色表", response = RoleDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", required = true, dataType = "int", paramType = "path"),
+            @ApiImplicitParam(name = "roleVO", value = "菜单", required = true, dataType = "RoleVO", paramType = "body")
+    })
+    @Log(client = LogClient.admin, detail = "修改ID为[${id}]的角色信息")
+    public RoleVO edit(@RequestBody @ApiIgnore RoleVO roleVO, @PathVariable Long id) {
+        AdminUserContext.hasAdminAndSuper();
+        return this.roleManager.edit(roleVO, id);
+    }
+
+
+    @DeleteMapping(value = "/{id}")
+    @ApiOperation(value = "删除角色")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "要删除的角色表主键", required = true, dataType = "int", paramType = "path")
+    })
+    @Log(client = LogClient.admin, detail = "删除ID为[${id}]的角色信息")
+    public void delete(@PathVariable Long id) {
+        AdminUserContext.hasAdminAndSuper();
+        this.roleManager.delete(id);
+    }
+
+
+    @GetMapping(value = "/{id}")
+    @ApiOperation(value = "查询一个角色表")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "要查询的角色表主键", required = true, dataType = "int", paramType = "path")
+    })
+    public RoleVO get(@PathVariable Long id) {
+        return this.roleManager.getRole(id);
+    }
+
+    @GetMapping(value = "/{id}/checked")
+    @ApiOperation(value = "根据角色id查询所拥有的菜单权限")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "要查询的角色表主键", required = true, dataType = "int", paramType = "path")
+    })
+    public List<String> getCheckedMenu(@PathVariable Long id) {
+        return this.roleManager.getRoleMenu(id);
+    }
+
+
+    @GetMapping(value = "/getRoleByDept/{deptId}")
+    @ApiOperation(value = "根据部门获取部门下所有的角色")
+    public List<RoleDO> getRoleByDept(@PathVariable String deptId) {
+        return roleManager.list(new LambdaQueryWrapper<RoleDO>()
+                .eq(RoleDO::getCompanyId, AdminUserContext.getCompanyId())
+                .eq(RoleDO::getDeptId, deptId));
+    }
+}

+ 214 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/SmsMailController.java

@@ -0,0 +1,214 @@
+package com.hys.app.controller.erp.use;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.hys.app.controller.erp.use.msg.MessageReceiveTypeEnum;
+import com.hys.app.converter.erp.SmsMailConverter;
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.database.BaseQueryParam;
+import com.hys.app.framework.exception.ServiceException;
+import com.hys.app.framework.util.BeanUtils;
+import com.hys.app.model.erp.dos.MessageReceiveDO;
+import com.hys.app.model.erp.dos.SmsMailTemplate;
+import com.hys.app.model.erp.dto.BandTemplateDTO;
+import com.hys.app.model.erp.dto.SmsMailTemplateDTO;
+import com.hys.app.model.erp.entity.CompanyBandMsg;
+import com.hys.app.model.erp.enums.MsgTypeEnum;
+import com.hys.app.model.erp.vo.SmsMailTemplateQuery;
+import com.hys.app.model.erp.vo.SmsMailTemplateVO;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+
+import com.hys.app.model.system.dos.AdminUser;
+import com.hys.app.model.system.vo.Menus;
+import com.hys.app.service.erp.*;
+import com.hys.app.service.system.AdminUserManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Api(tags = "消息  消息模板")
+@RestController
+@RequestMapping("/admin/erp/SmsMailTemplate")
+@AllArgsConstructor
+public class SmsMailController {
+
+    private SmsMailManager smsMailManager;
+    private MailSmsCountManager mailSmsCountManager;
+    private MessageReceiveManager messageReceiveManager;
+    private AdminUserManager adminUserManager;
+    private CompanyBandMsgManager companyBandMsgManager;
+    private RedisTemplate redisTemplate;
+
+    @PostMapping("createTemplate")
+    @ApiOperation(value = "创建模板")
+    @Log(client = LogClient.admin, detail = "创建名称为[${smsMailTemplateDTO.name}]的模板")
+    public Long createTemplate(@Valid @RequestBody SmsMailTemplateDTO smsMailTemplateDTO) {
+        return smsMailManager.createTemplate(smsMailTemplateDTO);
+    }
+
+    @PostMapping("updateTemplate/{id}")
+    @ApiOperation(value = "修改模板")
+    @Log(client = LogClient.admin, detail = "修改名称为[${companyDO.name}]的公司信息")
+    public Long updateTemplate(@Valid @RequestBody SmsMailTemplateDTO smsMailTemplateDTO, @PathVariable Long id) {
+        return smsMailManager.updateTemplate(smsMailTemplateDTO, id);
+    }
+
+    @GetMapping("getById/{id}")
+    @ApiOperation(value = "获取模板信息")
+    public SmsMailTemplateVO renewCompanyDifference(@PathVariable Long id) {
+        return SmsMailConverter.INSTANCE.convert(smsMailManager.getById(id));
+    }
+
+    @GetMapping()
+    @ApiOperation(value = "模板分页")
+    public IPage<SmsMailTemplateVO> queryTemplate(SmsMailTemplateQuery query) {
+        return smsMailManager.queryTemplate(query);
+    }
+
+
+    @GetMapping("getSysNotBand/{type}")
+    @ApiOperation(value = "创建邮件消息和短信消息获取未绑定的系统消息")
+    public List<SmsMailTemplate> getSysNotBand(@PathVariable MsgTypeEnum type) {
+        return smsMailManager.getSysNotBand(type);
+    }
+
+    @PostMapping("delete/{id}")
+    @ApiOperation(value = "删除模板")
+    public void delete(@PathVariable Long id) {
+        smsMailManager.delete(id);
+    }
+
+    @PostMapping("alterStatus/{id}")
+    @ApiOperation(value = "修改模板状态")
+    public void alterStatus(@PathVariable Long id) {
+        SmsMailTemplate byId = smsMailManager.getById(id);
+        byId.setEnableStatus(!byId.getEnableStatus());
+        smsMailManager.updateById(byId);
+    }
+
+//    @GetMapping("getSendNumByCompany")
+//    @ApiOperation(value = "")
+//    public IPage<MailSmsCountVO> getSendNumByCompany(MailSmsCountQuery query) {
+//        return mailSmsCountManager.getPage(query);
+//    }
+
+    @GetMapping("getSendNumByCompany")
+    @ApiOperation(value = "获取模板树状图,勾选之后和公司绑定")
+    public List<SmsMailTemplateVO> getTemplateTree() {
+        List<SmsMailTemplateVO> bean = BeanUtils.toBean(smsMailManager.list(), SmsMailTemplateVO.class);
+
+        List<CompanyBandMsg> list = companyBandMsgManager.list(new LambdaQueryWrapper<CompanyBandMsg>()
+                .eq(CompanyBandMsg::getCompanyId, AdminUserContext.getCompanyId()));
+        if (CollUtil.isNotEmpty(list)){
+            for (CompanyBandMsg msg : list) {
+                for (SmsMailTemplateVO smsMailTemplateVO : bean) {
+                    if (msg.getHasSelect() && msg.getTemplateId().equals(smsMailTemplateVO.getId())){
+                        smsMailTemplateVO.setHasSelect(true);
+                    }
+                }
+            }
+        }
+        for (SmsMailTemplateVO templateVO : bean) {
+            if (templateVO.getType().equals(MsgTypeEnum.SYSTEM)){
+                templateVO.setHasSelect(true);
+            }
+            templateVO.setChild(bean.stream().filter(item -> item.getPid().equals(templateVO.getId())).collect(Collectors.toList()));
+        }
+        return bean.stream().filter(item ->item.getPid() == 0).collect(Collectors.toList());
+    }
+
+    @PostMapping("updateSelectMsg")
+    @ApiOperation(value = "公司选中的模板")
+    @Log(client = LogClient.admin, detail = "修改了消息配置")
+    public void updateSeletMsg(@RequestBody BandTemplateDTO dto) {
+        AdminUserContext.hasSuperAdminQuery(dto.getCompanyId());
+        AdminUser model = adminUserManager.getModel(AdminUserContext.getAdminUserId());
+        if (!model.getUsername().equals("admin")) {
+            throw new ServiceException("只能admin账号才能进行此操作");
+        }
+        List<SmsMailTemplateVO> arrayList = new ArrayList<>();
+        for (SmsMailTemplateVO vo : dto.getVos()) {
+            if (CollUtil.isNotEmpty(vo.getChild())){
+                arrayList.add(vo);
+                getChild(arrayList,vo);
+            }else {
+                arrayList.add(vo);
+            }
+            if (vo.getType().equals(MsgTypeEnum.SYSTEM)) {
+                vo.setHasSelect(true);
+            }
+        }
+        Set<SmsMailTemplateVO> collect = new HashSet<>(arrayList);
+        List<CompanyBandMsg> list = new ArrayList<>();
+        for (SmsMailTemplateVO vo : collect) {
+            CompanyBandMsg companyBandMsg = new CompanyBandMsg();
+            companyBandMsg.setCompanyId(AdminUserContext.getCompanyId());
+            companyBandMsg.setTemplateId(vo.getId());
+            companyBandMsg.setTemplateCode(vo.getCode());
+            companyBandMsg.setHasSelect(vo.getHasSelect());
+            list.add(companyBandMsg);
+        }
+        companyBandMsgManager.remove(new LambdaQueryWrapper<CompanyBandMsg>().eq(CompanyBandMsg::getCompanyId,AdminUserContext.getCompanyId()));
+        companyBandMsgManager.saveBatch(list);
+        redisTemplate.opsForHash().delete("companyTemplate", model.getCompanyId().toString());
+        redisTemplate.opsForHash().put("companyTemplate",AdminUserContext.getCompanyId().toString(),list.stream().filter(CompanyBandMsg::getHasSelect).collect(Collectors.toList()));
+    }
+
+    private void getChild(List<SmsMailTemplateVO> list, SmsMailTemplateVO vo) {
+        for (SmsMailTemplateVO child : vo.getChild()) {
+            list.add(child);
+            getChild(list, child);
+        }
+    }
+
+
+
+//    @GetMapping("getMessageByTypeCompany/{type}")
+//    @ApiOperation(value = "获取各公司发的消息记录")
+//    public IPage<MessageReceiveDO> getMessageByTypeCompany(BaseQueryParam query, @PathVariable String type) {
+//        return messageReceiveManager.getPage(query, type);
+//    }
+
+    @GetMapping("countNotReadSys")
+    @ApiOperation(value = "统计自己账号所有未读的消息")
+    public long countNotReadSys() {
+        return messageReceiveManager.count(new LambdaQueryWrapper<MessageReceiveDO>()
+                .eq(MessageReceiveDO::getUserId, AdminUserContext.getAdminUserId())
+                .eq(MessageReceiveDO::getType, MessageReceiveTypeEnum.SYSTEM)
+                .eq(MessageReceiveDO::getStatus, false));
+    }
+
+    @GetMapping("getSysMsgByOwn/{type}")
+    @ApiOperation(value = "获取自己所有的消息")
+    public IPage<MessageReceiveDO> getMessageByTypeCompany(BaseQueryParam query ,  @PathVariable MessageReceiveTypeEnum type) {
+        //把自己所有的消息全部设置为已读
+        MessageReceiveDO messageReceiveDO = new MessageReceiveDO();
+        messageReceiveDO.setStatus(true);
+        messageReceiveManager.update(messageReceiveDO, new LambdaQueryWrapper<MessageReceiveDO>()
+                .eq(MessageReceiveDO::getUserId, AdminUserContext.getAdminUserId())
+                .eq(MessageReceiveDO::getType, MessageReceiveTypeEnum.SYSTEM));
+        return messageReceiveManager.page(new Page<>(query.getPageNo(), query.getPageSize()), new LambdaQueryWrapper<MessageReceiveDO>()
+                .eq(MessageReceiveDO::getUserId, AdminUserContext.getAdminUserId())
+                .eq(ObjectUtil.isNotNull(type),MessageReceiveDO::getType,type)
+                .orderByAsc(MessageReceiveDO::getStatus));
+    }
+
+
+
+
+
+
+
+}

+ 127 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/StockDamageReportManagerController.java

@@ -0,0 +1,127 @@
+package com.hys.app.controller.erp.use;
+
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dto.StockDamageReportDTO;
+import com.hys.app.model.erp.dto.StockDamageReportParam;
+import com.hys.app.model.erp.dto.StockDamageReportStatisticsParam;
+import com.hys.app.model.erp.vo.StockDamageReportVO;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.StockDamageReportManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 库存报损单相关API
+ *
+ * @author dmy
+ * 2023-12-05
+ */
+@Api(description = "库存报损单相关API")
+@RestController
+@RequestMapping("/admin/stock/damage/report")
+@Validated
+public class StockDamageReportManagerController {
+
+    @Autowired
+    private StockDamageReportManager stockDamageReportManager;
+
+    @ApiOperation(value = "查询库存报损单分页列表数据")
+    @GetMapping
+    public WebPage list(StockDamageReportParam params) {
+        AdminUserContext.hasSuperAdminQuery(params.getCompanyId());
+        return stockDamageReportManager.list(params);
+    }
+
+    @ApiOperation(value = "新增库存报损单")
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "新增库存报损单")
+    public void add(@RequestBody @Valid StockDamageReportDTO stockDamageReportDTO) {
+        AdminUserContext.hasCompany();
+        this.stockDamageReportManager.add(stockDamageReportDTO);
+    }
+
+
+    @ApiOperation(value = "确认报损单")
+    @PostMapping("/submit/{id}")
+    @Log(client = LogClient.admin, detail = "修改id为[${id}]的库存报损单")
+    public void submit(@PathVariable Long id, @RequestBody @Valid StockDamageReportDTO stockDamageReportDTO) {
+        AdminUserContext.hasCompany();
+        this.stockDamageReportManager.submit(id, stockDamageReportDTO);
+    }
+
+    @ApiOperation(value = "查询库存报损单详细信息")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "库存报损单ID", required = true, dataType = "int", paramType = "path")
+    })
+    @GetMapping("/{id}")
+    public StockDamageReportVO getDetail(@PathVariable Long id) {
+        return stockDamageReportManager.getDetail(id);
+    }
+
+
+    @ApiOperation(value = "批量删除库存报损单")
+    @DeleteMapping("/{ids}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "ids", value = "要删除的库存报损单ID集合", required = true, dataType = "int", paramType = "path", allowMultiple = true)
+    })
+    @Log(client = LogClient.admin, detail = "删除ID为[${ids}]的库存报损单")
+    public void delete(@PathVariable List<Long> ids) {
+        AdminUserContext.hasCompany();
+        this.stockDamageReportManager.delete(ids);
+    }
+
+
+
+    @ApiOperation(value = "处理报损单")
+    @PostMapping("/syncStock/{id}")
+    @Log(client = LogClient.admin, detail = "同步ID为[${ids}]的库存报损单")
+    public void syncStock(@PathVariable Long id) {
+        this.stockDamageReportManager.syncStock(id);
+    }
+
+    @ApiOperation(value = "批量撤销提交审核的库存报损单")
+    @PostMapping("/cancel/{ids}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "ids", value = "要撤销提交审核的库存报损单ID集合", required = true, dataType = "int", paramType = "path", allowMultiple = true)
+    })
+    @Log(client = LogClient.admin, detail = "将ID为[${ids}]的库存报损单撤销提交审核")
+    public void cancel(@PathVariable List<Long> ids) {
+        this.stockDamageReportManager.cancel(ids);
+    }
+
+    @ApiOperation(value = "审核库存报损单")
+    @PostMapping("/audit/{ids}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "ids", value = "要审核的库存报损单ID集合", required = true, dataType = "int", paramType = "path", allowMultiple = true),
+            @ApiImplicitParam(name = "status", value = "审核状态 PASS:审核通过,REJECT:审核驳回", required = true, dataType = "String", paramType = "query", allowableValues = "PASS,REJECT"),
+            @ApiImplicitParam(name = "reject_reason", value = "驳回原因", dataType = "String", paramType = "query")
+    })
+    @Log(client = LogClient.admin, detail = "审核ID为[${ids}]的库存报损单")
+    public void audit(@PathVariable List<Long> ids, @ApiIgnore String status, @ApiIgnore String rejectReason) {
+        this.stockDamageReportManager.audit(ids, status, rejectReason);
+    }
+
+    @ApiOperation(value = "查询库存报损单商品统计分页列表数据")
+    @GetMapping("/statistics")
+    public WebPage statistics(StockDamageReportStatisticsParam params) {
+        return stockDamageReportManager.statistics(params);
+    }
+
+    @ApiOperation(value = "导出库存报损单商品统计列表")
+    @GetMapping("/export")
+    public void export(HttpServletResponse response, StockDamageReportStatisticsParam params) {
+        this.stockDamageReportManager.export(response, params);
+    }
+}

+ 116 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/StockInventoryManagerController.java

@@ -0,0 +1,116 @@
+package com.hys.app.controller.erp.use;
+
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dto.StockInventoryDTO;
+import com.hys.app.model.erp.dto.StockInventoryParam;
+import com.hys.app.model.erp.vo.StockInventoryVO;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.StockInventoryManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 库存盘点单相关API
+ *
+ * @author dmy
+ * 2023-12-05
+ */
+@Api(description = "库存盘点单相关API")
+@RestController
+@RequestMapping("/admin/stock/inventory")
+@Validated
+public class StockInventoryManagerController {
+
+    @Autowired
+    private StockInventoryManager stockInventoryManager;
+
+    @ApiOperation(value = "查询库存盘点单分页列表数据")
+    @GetMapping
+    public WebPage list(StockInventoryParam params) {
+        AdminUserContext.hasSuperAdminQuery(params.getCompanyId());
+        return stockInventoryManager.list(params);
+    }
+
+    @ApiOperation(value = "新增库存盘点单")
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "新增库存盘点单")
+    public void add(@RequestBody @Valid StockInventoryDTO stockInventoryDTO) {
+        AdminUserContext.hasCompany();
+        this.stockInventoryManager.add(stockInventoryDTO);
+    }
+
+    @ApiOperation(value = "修改库存盘点单")
+    @PostMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "修改id为[${id}]的库存盘点单")
+    public void edit(@PathVariable Long id, @RequestBody @Valid StockInventoryDTO stockInventoryDTO) {
+        AdminUserContext.hasCompany();
+        this.stockInventoryManager.edit(id, stockInventoryDTO);
+    }
+    @ApiOperation(value = "查询库存盘点单详细信息")
+    @GetMapping("/{id}")
+    public StockInventoryVO getDetail(@PathVariable Long id) {
+        return stockInventoryManager.getDetail(id);
+    }
+
+    @ApiOperation(value = "同步库存")
+    @GetMapping("/syncStock/{id}")
+    public void syncStock(@PathVariable Long id) {
+        AdminUserContext.hasCompany();
+        stockInventoryManager.syncStock(id);
+    }
+
+
+
+
+    @ApiOperation(value = "批量删除库存盘点单")
+    @DeleteMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "删除ID为[${ids}]的库存盘点单")
+    public void delete(@PathVariable Long id) {
+        AdminUserContext.hasCompany();
+        this.stockInventoryManager.delete(id);
+    }
+
+
+    @ApiOperation(value = "批量提交审核库存盘点单")
+    @PostMapping("/submit/{ids}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "ids", value = "要提交审核的库存盘点单ID集合", required = true, dataType = "int", paramType = "path", allowMultiple = true)
+    })
+    @Log(client = LogClient.admin, detail = "提交审核ID为[${ids}]的库存盘点单")
+    public void submit(@PathVariable List<Long> ids) {
+        this.stockInventoryManager.submit(ids);
+    }
+
+    @ApiOperation(value = "批量撤销提交审核的库存盘点单")
+    @PostMapping("/cancel/{ids}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "ids", value = "要撤销提交审核的库存盘点单ID集合", required = true, dataType = "int", paramType = "path", allowMultiple = true)
+    })
+    @Log(client = LogClient.admin, detail = "将ID为[${ids}]的库存盘点单撤销提交审核")
+    public void cancel(@PathVariable List<Long> ids) {
+        this.stockInventoryManager.cancel(ids);
+    }
+
+    @ApiOperation(value = "审核库存盘点单")
+    @PostMapping("/audit/{ids}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "ids", value = "要审核的库存盘点单ID集合", required = true, dataType = "int", paramType = "path", allowMultiple = true),
+            @ApiImplicitParam(name = "status", value = "审核状态 PASS:审核通过,REJECT:审核驳回", required = true, dataType = "String", paramType = "query", allowableValues = "PASS,REJECT"),
+            @ApiImplicitParam(name = "reject_reason", value = "驳回原因", dataType = "String", paramType = "query")
+    })
+    @Log(client = LogClient.admin, detail = "审核ID为[${ids}]的库存盘点单")
+    public void audit(@PathVariable List<Long> ids, @ApiIgnore String status, @ApiIgnore String rejectReason) {
+        this.stockInventoryManager.audit(ids, status, rejectReason);
+    }
+}

+ 90 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/StockTransferManagerController.java

@@ -0,0 +1,90 @@
+package com.hys.app.controller.erp.use;
+
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dto.StockTransferDTO;
+import com.hys.app.model.erp.dto.StockTransferQueryParams;
+import com.hys.app.model.erp.dto.StockTransferStatisticsParam;
+import com.hys.app.model.erp.vo.StockTransferVO;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.StockTransferManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+
+
+/**
+ * 库存调拨API
+ *
+ * @author 张崧
+ * @since 2023-12-12 11:59:06
+ */
+@RestController
+@RequestMapping("/admin/erp/stockTransfer")
+@Api(tags = "库存调拨API")
+@Validated
+public class StockTransferManagerController {
+
+    @Autowired
+    private StockTransferManager stockTransferManager;
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public WebPage<StockTransferVO> list(StockTransferQueryParams queryParams) {
+        AdminUserContext.hasSuperAdminQuery(queryParams.getCompanyId());
+        return stockTransferManager.list(queryParams);
+    }
+
+    @ApiOperation(value = "添加")
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "创建调拨单")
+    public void add(@RequestBody @Valid StockTransferDTO stockTransferDTO) {
+        AdminUserContext.hasCompany();
+        stockTransferManager.add(stockTransferDTO);
+    }
+
+    @ApiOperation(value = "修改")
+    @PutMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "编辑ID为[${id}]的调拨单")
+    public void edit(@PathVariable String id, @RequestBody @Valid StockTransferDTO stockTransferDTO) {
+        AdminUserContext.hasCompany();
+        stockTransferDTO.setId(id);
+        stockTransferManager.edit(stockTransferDTO);
+    }
+
+    @ApiOperation(value = "查看詳情")
+    @GetMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "编辑ID为[${id}]的调拨单")
+    public StockTransferVO getDetail(@PathVariable Long id) {
+        return stockTransferManager.getDetail(id);
+    }
+
+    @ApiOperation(value = "提交调拨单")
+    @PostMapping("/{id}/submit")
+    @Log(client = LogClient.admin, detail = "提交ID为[${id}]的调拨单")
+    public void submit(@PathVariable Long id) {
+        AdminUserContext.hasCompany();
+        stockTransferManager.submit(id);
+    }
+
+    @ApiOperation(value = "撤销调拨单")
+    @PostMapping("/{id}/withdraw")
+    @Log(client = LogClient.admin, detail = "撤销ID为[${id}]的调拨单")
+    public void withdraw(@PathVariable Long id) {
+        AdminUserContext.hasCompany();
+        stockTransferManager.withdraw(id);
+    }
+
+    @ApiOperation(value = "导出库存调拨统计列表")
+    @GetMapping("/export")
+    public void export(HttpServletResponse response, StockTransferStatisticsParam params) {
+        this.stockTransferManager.export(response, params);
+    }
+}
+

+ 141 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/WarehouseAreaController.java

@@ -0,0 +1,141 @@
+package com.hys.app.controller.erp.use;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.database.BaseQueryParam;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dos.WarehouseAreaDO;
+import com.hys.app.model.erp.dos.WarehouseAreaTypeDO;
+import com.hys.app.model.erp.dto.WarehouseAreaQueryParams;
+import com.hys.app.model.erp.dto.WarehouseAreaRequest;
+import com.hys.app.model.erp.vo.ProductStockVO;
+import com.hys.app.model.erp.vo.WarehouseAreaVO;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.WarehouseAreaManager;
+import com.hys.app.service.erp.WarehouseAreaTypeManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 出库单明细相关API
+ *
+ * @author 张崧
+ * @since 2023-12-07 17:06:32
+ */
+@RestController
+@RequestMapping("/admin/erp/warehouse/area")
+@Api(tags = "库位管理相关接口")
+@Validated
+public class WarehouseAreaController {
+
+    @Autowired
+    private WarehouseAreaManager warehouseAreaManager;
+
+    @Autowired
+    private WarehouseAreaTypeManager warehouseAreaTypeManager;
+
+
+    @ApiOperation(value = "获取库位列表")
+    @GetMapping("/query")
+    public WebPage<WarehouseAreaVO> list(WarehouseAreaQueryParams queryParams) {
+        AdminUserContext.hasSuperAdminQuery(queryParams.getCompanyId());
+        return warehouseAreaManager.list(queryParams);
+    }
+
+
+    @ApiOperation(value = "添加")
+    @PostMapping("/create")
+    @Log(client = LogClient.admin, detail = "创建库位信息")
+    public void add(@RequestBody @Valid WarehouseAreaDO warehouseAreaDO) {
+        AdminUserContext.hasCompany();
+        warehouseAreaManager.add(warehouseAreaDO);
+    }
+
+    @ApiOperation(value = "更新")
+    @PostMapping("/update")
+    @Log(client = LogClient.admin, detail = "修改id为[${id}]的库位信息")
+    public void update(@RequestBody @Valid WarehouseAreaDO warehouseAreaDO) {
+        AdminUserContext.hasCompany();
+        warehouseAreaManager.edit(warehouseAreaDO);
+    }
+
+    @ApiOperation(value = "库位详情")
+    @PostMapping("/info")
+    public WarehouseAreaVO info(@RequestBody @Valid WarehouseAreaRequest request) {
+        return warehouseAreaManager.getDetail(request.getId());
+    }
+
+
+    @ApiOperation(value = "删除")
+    @DeleteMapping("/delete")
+    @Log(client = LogClient.admin, detail = "删除id为[${id}]的库位信息")
+    public void delete(@RequestBody @Valid WarehouseAreaRequest request) {
+        AdminUserContext.hasCompany();
+        warehouseAreaManager.delete(request.getId());
+    }
+
+    @ApiOperation(value = "添加库位类型")
+    @PostMapping("/createAreaType")
+    @Log(client = LogClient.admin, detail = "添加名称为[${warehouseAreaTypeDO.name}]的库位信息")
+    public void createAreaType(@RequestBody @Valid WarehouseAreaTypeDO warehouseAreaTypeDO) {
+        AdminUserContext.hasCompany();
+        warehouseAreaTypeDO.setCompanyId(AdminUserContext.getCompanyId());
+        warehouseAreaTypeManager.save(warehouseAreaTypeDO);
+    }
+
+    @ApiOperation(value = "删除库位类型")
+    @DeleteMapping("/removeAreaType/{id}")
+    @Log(client = LogClient.admin, detail = "删除id为为[${id}]的库位信息")
+    public void removeAreaType(@PathVariable Long id) {
+        AdminUserContext.hasCompany();
+        warehouseAreaTypeManager.removeById(id);
+    }
+
+    @ApiOperation(value = "修改库位类型")
+    @PutMapping("/updateAreaType/{id}")
+    @Log(client = LogClient.admin, detail = "修改id为[${id}]的库位信息")
+    public void updateAreaType(@RequestBody @Valid WarehouseAreaTypeDO warehouseAreaTypeDO, @PathVariable(value = "id") Long id) {
+        AdminUserContext.hasCompany();
+        warehouseAreaTypeDO.setId(id);
+        warehouseAreaTypeManager.updateById(warehouseAreaTypeDO);
+    }
+
+    @ApiOperation(value = "查询库位类型")
+    @GetMapping("/listAreaType")
+    public List<WarehouseAreaTypeDO> listAreaType(Long companyId) {
+        AdminUserContext.hasSuperAdminQuery(companyId);
+        return warehouseAreaTypeManager.list(new LambdaQueryWrapper<WarehouseAreaTypeDO>()
+                .eq(WarehouseAreaTypeDO::getCompanyId, AdminUserContext.getCompanyId()));
+    }
+
+    @ApiOperation(value = "根据仓库id获取所有的库存列表")
+    @GetMapping("/goodNotAreaList/{warehouseId}")
+    @Log(client = LogClient.admin, detail = "创建库位信息")
+    public Page<ProductStockVO> goodNotAreaList(BaseQueryParam baseQueryParam, @PathVariable Long warehouseId) {
+        return warehouseAreaManager.goodNotAreaList(baseQueryParam, warehouseId);
+    }
+
+    @ApiOperation(value = "根据仓库id获取所有的库位列表")
+    @GetMapping("/getAreaByWarehouse/{warehouseId}")
+    @Log(client = LogClient.admin, detail = "创建库位信息")
+    public List<WarehouseAreaDO> getAreaByWarehouse(@PathVariable Long warehouseId) {
+        return warehouseAreaManager.getAreaByWarehouse(warehouseId);
+    }
+
+    @ApiOperation(value = "新增关系")
+    @PostMapping("/bindAreaStock/{warehouseId}/{warehouseAreaId}")
+    @Log(client = LogClient.admin, detail = "创建库位信息")
+    public void bindAreaStock(@PathVariable Long warehouseId, @PathVariable(value = "warehouseAreaId") Long warehouseAreaId, @RequestBody WarehouseAreaDO warehouseAreaDO) {
+        AdminUserContext.hasCompany();
+        warehouseAreaManager.bindAreaStock(warehouseId, warehouseAreaId, warehouseAreaDO.getStockIdList());
+    }
+}
+

+ 115 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/WarehouseEntryManagerController.java

@@ -0,0 +1,115 @@
+package com.hys.app.controller.erp.use;
+
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dos.WarehouseEntryDO;
+import com.hys.app.model.erp.dto.WarehouseEntryDTO;
+import com.hys.app.model.erp.dto.WarehouseEntryQueryParams;
+import com.hys.app.model.erp.dto.WarehouseEntryStatisticsParam;
+import com.hys.app.model.erp.enums.WarehouseEntryStatusEnum;
+import com.hys.app.model.erp.vo.WarehouseAreaVO;
+import com.hys.app.model.erp.vo.WarehouseEntryVO;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.WarehouseAreaManager;
+import com.hys.app.service.erp.WarehouseEntryManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * 入库单相关API
+ *
+ * @author 张崧
+ * @since 2023-12-05 11:25:07
+ */
+@RestController
+@RequestMapping("/admin/erp/warehouseEntry")
+@Api(tags = "入库单相关API")
+@Validated
+public class WarehouseEntryManagerController {
+
+    @Autowired
+    private WarehouseEntryManager warehouseEntryManager;
+
+
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public WebPage<WarehouseEntryDO> list(WarehouseEntryQueryParams queryParams) {
+        AdminUserContext.hasSuperAdminQuery(queryParams.getCompanyId());
+        return warehouseEntryManager.list(queryParams);
+    }
+
+    @ApiOperation(value = "添加")
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "创建入库单")
+    public Long add(@RequestBody @Valid WarehouseEntryDTO warehouseEntryDTO) {
+        AdminUserContext.hasCompany();
+        return warehouseEntryManager.add(warehouseEntryDTO);
+    }
+
+    @ApiOperation(value = "修改")
+    @PutMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "编辑ID为[${id}]的入库单")
+    public void edit(@PathVariable Long id, @RequestBody @Valid WarehouseEntryDTO warehouseEntryDTO) {
+        AdminUserContext.hasCompany();
+        warehouseEntryDTO.setId(id);
+        warehouseEntryManager.edit(warehouseEntryDTO);
+    }
+
+    @ApiOperation(value = "提交入库单")
+    @PostMapping("/{ids}/submit")
+    @Log(client = LogClient.admin, detail = "提交ID为[${ids}]的入库单")
+    public void submit(@PathVariable List<Long> ids) {
+        warehouseEntryManager.submit(ids);
+    }
+
+    @ApiOperation(value = "撤销提交入库单")
+    @PostMapping("/{id}/withdraw")
+    @Log(client = LogClient.admin, detail = "撤销提交ID为[${id}]的入库单")
+    public void withdraw(@PathVariable Long id) {
+        warehouseEntryManager.withdraw(id);
+    }
+
+    @ApiOperation(value = "查询")
+    @GetMapping("/{id}")
+    public WarehouseEntryVO getDetail(@PathVariable Long id) {
+        return warehouseEntryManager.getDetail(id);
+    }
+
+    @ApiOperation(value = "删除")
+    @DeleteMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "删除ID为[${ids}]的入库单")
+    public void delete(@PathVariable Long id) {
+        warehouseEntryManager.delete(id);
+    }
+
+    @ApiOperation(value = "审核入库单")
+    @PostMapping("/{ids}/audit")
+    @Log(client = LogClient.admin, detail = "审核ID为[${ids}]的入库单")
+    public void audit(@PathVariable List<Long> ids, @NotNull WarehouseEntryStatusEnum status, String remark) {
+        warehouseEntryManager.audit(ids, status, remark);
+    }
+
+    @ApiOperation(value = "查询入库单统计分页列表数据")
+    @GetMapping("/statistics")
+    public WebPage statistics(WarehouseEntryStatisticsParam params) {
+        return warehouseEntryManager.statistics(params);
+    }
+
+    @ApiOperation(value = "导出入库单统计列表数据")
+    @GetMapping("/export")
+    public void export(HttpServletResponse response, WarehouseEntryStatisticsParam params) {
+        this.warehouseEntryManager.export(response, params);
+    }
+}
+

+ 52 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/WarehouseEntryProductManagerController.java

@@ -0,0 +1,52 @@
+package com.hys.app.controller.erp.use;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dto.WarehouseEntryProductQueryParams;
+import com.hys.app.model.erp.dto.WarehouseInQueryParams;
+import com.hys.app.model.erp.vo.WarehouseEntryItemV1;
+import com.hys.app.model.erp.vo.WarehouseEntryProductVO;
+import com.hys.app.service.erp.WarehouseEntryProductManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 入库单商品明细相关API
+ *
+ * @author 张崧
+ * @since 2023-12-05 15:30:10
+ */
+@RestController
+@RequestMapping("/admin/erp/warehouseEntryProduct")
+@Api(tags = "入库单商品明细相关API")
+@Validated
+public class WarehouseEntryProductManagerController {
+
+    @Autowired
+    private WarehouseEntryProductManager warehouseEntryProductManager;
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public WebPage<WarehouseEntryProductVO> list(WarehouseEntryProductQueryParams queryParams) {
+        return warehouseEntryProductManager.list(queryParams);
+    }
+
+
+    @ApiOperation(value = "获取入库单明细列表")
+    @PostMapping("/query")
+    public WebPage<WarehouseEntryItemV1> list(WarehouseInQueryParams queryParams) {
+        List<WarehouseEntryItemV1> list=warehouseEntryProductManager.selectList(queryParams);
+        Long count= warehouseEntryProductManager.selectCount(queryParams);
+        WebPage<WarehouseEntryItemV1> webPage=new WebPage<>();
+        webPage.setData(list);
+        webPage.setDataTotal(count);
+        webPage.setPageSize(queryParams.getPageSize());
+        webPage.setPageNo(queryParams.getPageNo());
+        return webPage;
+    }
+}
+

+ 79 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/WarehouseManagerController.java

@@ -0,0 +1,79 @@
+package com.hys.app.controller.erp.use;
+
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dto.WarehouseQueryParams;
+import com.hys.app.model.erp.vo.WarehouseVO;
+import com.hys.app.model.erp.dto.WarehouseDTO;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.WarehouseManager;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 仓库相关API
+ *
+ * @author 张崧
+ * 2023-11-30 16:35:16
+ */
+@RestController
+@RequestMapping("/admin/erp/warehouse")
+@Api(tags = "仓库相关API")
+@Validated
+public class WarehouseManagerController {
+
+    @Autowired
+    private WarehouseManager warehouseManager;
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public WebPage<WarehouseVO> list(WarehouseQueryParams queryParams) {
+        AdminUserContext.hasSuperAdminQuery(queryParams.getCompanyId());
+        return warehouseManager.list(queryParams);
+    }
+
+    @ApiOperation(value = "查询所有仓库")
+    @GetMapping("/list-all")
+    public List<WarehouseVO> listAll(Long deptId) {
+        return warehouseManager.listAll(deptId);
+    }
+
+    @ApiOperation(value = "添加")
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "添加名称为[${warehouseDTO.name}]的仓库信息")
+    public void add(@RequestBody @Valid WarehouseDTO warehouseDTO) {
+        AdminUserContext.hasCompany();
+        warehouseManager.add(warehouseDTO);
+    }
+
+    @ApiOperation(value = "修改")
+    @PutMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "编辑ID为[${id}]的仓库信息")
+    public void edit(@PathVariable String id, @RequestBody @Valid WarehouseDTO warehouseDTO) {
+        AdminUserContext.hasCompany();
+        warehouseDTO.setId(id);
+        warehouseManager.edit(warehouseDTO);
+    }
+
+    @ApiOperation(value = "查询")
+    @GetMapping("/{id}")
+    public WarehouseVO getDetail(@PathVariable Long id) {
+        return warehouseManager.getDetail(id);
+    }
+
+    @ApiOperation(value = "删除")
+    @DeleteMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "删除ID为[${id}]的仓库信息")
+    public void delete(@PathVariable Long id) {
+        AdminUserContext.hasCompany();
+        warehouseManager.delete(id);
+    }
+}
+

+ 45 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/WarehouseOutItemController.java

@@ -0,0 +1,45 @@
+package com.hys.app.controller.erp.use;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dto.WarehouseOutItemQueryParams;
+import com.hys.app.model.erp.vo.WarehouseOutItemV1;
+import com.hys.app.model.erp.vo.WarehouseOutItemVO;
+import com.hys.app.service.erp.WarehouseOutItemManager;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 出库单明细相关API
+ *
+ * @author 张崧
+ * @since 2023-12-07 17:06:32
+ */
+@RestController
+@RequestMapping("/admin/erp/warehouseOutItem")
+@Api(tags = "出库单商品明细相关API")
+@Validated
+public class WarehouseOutItemController {
+
+    @Autowired
+    private WarehouseOutItemManager warehouseOutItemManager;
+
+    @ApiOperation(value = "分页列表")
+    @PostMapping("/query")
+    public WebPage<WarehouseOutItemV1> list(WarehouseOutItemQueryParams request) {
+        Long count = warehouseOutItemManager.selectCount(request);
+        List<WarehouseOutItemV1> list = warehouseOutItemManager.selectList(request);
+        WebPage<WarehouseOutItemV1> webPage = new WebPage<>();
+        webPage.setData(list);
+        webPage.setPageNo(request.getPageNo());
+        webPage.setPageSize(request.getPageSize());
+        webPage.setDataTotal(count);
+        return webPage;
+    }
+}
+

+ 114 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/WarehouseOutManagerController.java

@@ -0,0 +1,114 @@
+package com.hys.app.controller.erp.use;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.database.BaseQueryParam;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dos.LockedStockDetailDO;
+import com.hys.app.model.erp.dto.*;
+import com.hys.app.model.erp.vo.ProductStockVO;
+import com.hys.app.model.erp.vo.WarehouseOutVO;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.WarehouseOutManager;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+
+/**
+ * 出库单相关API
+ *
+ * @author 张崧
+ * @since 2023-12-07 16:50:20
+ */
+@RestController
+@RequestMapping("/admin/erp/warehouseOut")
+@Api(tags = "出库单相关API")
+@Validated
+public class WarehouseOutManagerController {
+
+    @Autowired
+    private WarehouseOutManager warehouseOutManager;
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public WebPage<WarehouseOutVO> list(WarehouseOutQueryParams queryParams) {
+        AdminUserContext.hasSuperAdminQuery(queryParams.getCompanyId());
+        return warehouseOutManager.list(queryParams);
+    }
+
+    @ApiOperation(value = "添加")
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "创建出库单")
+    public Long add(@RequestBody @Valid WarehouseOutDTO warehouseOutDTO) {
+        AdminUserContext.hasCompany();
+        return warehouseOutManager.add(warehouseOutDTO);
+    }
+
+    @ApiOperation(value = "编辑")
+    @PutMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "编辑id为[${id}]出库单")
+    public void edit(@PathVariable Long id, @RequestBody @Valid WarehouseOutDTO warehouseOutDTO) {
+        AdminUserContext.hasCompany();
+        warehouseOutDTO.setId(id);
+        warehouseOutManager.edit(warehouseOutDTO);
+    }
+
+    @ApiOperation(value = "查询")
+    @GetMapping("/{id}")
+    public WarehouseOutVO getDetail(@PathVariable Long id) {
+        return warehouseOutManager.getDetail(id);
+    }
+
+    @ApiOperation(value = "删除")
+    @DeleteMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "删除ID为[${id}]的出库单")
+    public void delete(@PathVariable Long id) {
+        AdminUserContext.hasCompany();
+        warehouseOutManager.delete(id);
+    }
+
+    @ApiOperation(value = "导出出库单统计列表")
+    @GetMapping("/export")
+    public void export(HttpServletResponse response, WarehouseOutStatisticsParam params) {
+        this.warehouseOutManager.export(response, params);
+    }
+
+//    @ApiOperation(value = "根据仓库找到所有sku库存大于0的商品")
+//    @GetMapping("/getGoodByWarehouse/warehouseIdAndOrderType/{orderType}/{warehouseIds}")
+//    @Log(client = LogClient.admin, detail = "根据仓库找到所有sku库存大于0的商品")
+//    public IPage<ProductStockVO> getGoodByWarehouse(BaseQueryParam queryParam,
+//                                                    @PathVariable(value = "orderType") String orderType,
+//                                                    @PathVariable(value = "warehouseIds") String warehouseIds) {
+//        String[] split = warehouseIds.split(",");
+//        List<Long> list = new ArrayList<>();
+//        for (String s : split) {
+//            list.add(Long.valueOf(s));
+//        }
+//        return warehouseOutManager.getGoodByWarehouse(null, queryParam, orderType, list, queryParam.getKeyWord());
+//    }
+
+//    @ApiOperation(value = "根据仓库找到所有sku库存大于0的商品 出库调拨报损")
+//    @GetMapping("/getGoodByWarehouse/{warehouseId}")
+//    public IPage<ProductStockVO> getGoodByWarehouse(@PathVariable(value = "warehouseId") Long warehouseId, BaseQueryParam queryParam) {
+//        return warehouseOutManager.getGoodByWarehouse(warehouseId, queryParam, null, null, queryParam.getKeyWord());
+//    }
+
+    @ApiOperation(value = "根据仓库找商品  入库盘点库位绑定商品type=le 出库调拨报损 type =gt")
+    @GetMapping("/getGoodByWarehouse/{warehouseId}/{type}")
+    public IPage<ProductStockVO> getGoodByWarehouse(@PathVariable(value = "warehouseId") Long warehouseId, BaseQueryParam queryParam, @PathVariable String type) {
+        return warehouseOutManager.getGoodByWarehouseInventory(warehouseId, queryParam, queryParam.getKeyWord(),type);
+    }
+
+    @ApiOperation(value = "获取冻结库存")
+    @GetMapping("/getLockedStock")
+    public IPage<LockedStockDetailDO> getLockedStock(LockedStockParams queryParam) {
+        return warehouseOutManager.getLockedStock(queryParam);
+    }
+}
+

+ 108 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/WeixinController.java

@@ -0,0 +1,108 @@
+package com.hys.app.controller.erp.use;
+
+import com.hys.app.framework.util.ScriptUtil;
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.*;
+
+import java.security.MessageDigest;
+import java.util.Arrays;
+
+@RestController
+public class WeixinController {
+
+    private static final Logger log = LoggerFactory.getLogger(ScriptUtil.class);
+
+    private static final String TOKEN = "ryks2023weixin";  // 替换为您在微信公众平台设置的Token
+
+    @GetMapping("/weixin")
+    public String validateWeixinToken(
+            @RequestParam("signature") String signature,
+            @RequestParam("timestamp") String timestamp,
+            @RequestParam("nonce") String nonce,
+            @RequestParam("echostr") String echostr) {
+        System.out.println(echostr+"111111111111111111111111111111222222222222222222222222222-----------------------------------------");
+
+//        String[] arr = {TOKEN, timestamp, nonce};
+//        Arrays.sort(arr);
+//        StringBuilder content = new StringBuilder();
+//        for (String str : arr) {
+//            content.append(str);
+//        }
+//
+//        String generatedSignature = sha1(content.toString());
+//
+//        if (generatedSignature.equals(signature)) {
+//            return echostr;
+//        } else {
+//            return "Failed to verify";
+//        }
+        return echostr;
+    }
+
+    @PostMapping("/receive_ticket")
+    public String receiveComponentVerifyTicket(@RequestBody String requestBody,
+                                               @RequestParam("msg_signature") String msgSignature,
+                                               @RequestParam("timestamp") String timestamp,
+                                               @RequestParam("nonce") String nonce) {
+
+        log.info("验证来了啊 -----------------------------------------------------------11111111111111111---------");
+        try {
+            // 1. 验证消息的真实性
+            if (!verifySignature(msgSignature, timestamp, nonce, requestBody)) {
+                return "fail";
+            }
+
+            // 2. 解密消息
+            String decryptedMsg = decryptMsg(requestBody);
+
+            // 3. 解析 XML
+            Document document = DocumentHelper.parseText(decryptedMsg);
+            Element root = document.getRootElement();
+            String componentVerifyTicket = root.elementText("ComponentVerifyTicket");
+
+            // 4. 存储 ticket
+            saveComponentVerifyTicket(componentVerifyTicket);
+
+            // 5. 返回成功响应
+            return "success";
+        } catch (Exception e) {
+           e.printStackTrace();
+            return "fail";
+        }
+    }
+
+    private String sha1(String data) {
+        try {
+            MessageDigest md = MessageDigest.getInstance("SHA-1");
+            md.update(data.getBytes());
+            byte[] bytes = md.digest();
+            StringBuilder sb = new StringBuilder();
+            for (byte b : bytes) {
+                sb.append(String.format("%02x", b));
+            }
+            return sb.toString();
+        } catch (Exception e) {
+            return "";
+        }
+    }
+
+
+
+    public boolean verifySignature(String msgSignature, String timestamp, String nonce, String requestBody) {
+        // 实现签名验证逻辑
+        return true;
+    }
+
+    public String decryptMsg(String requestBody) {
+        // 实现消息解密逻辑
+        return null;
+    }
+
+    public void saveComponentVerifyTicket(String ticket) {
+        // 实现存储 ticket 的逻辑
+    }
+}

+ 99 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/msg/AliSmsUtil.java

@@ -0,0 +1,99 @@
+package com.hys.app.controller.erp.use.msg;
+
+
+import cn.hutool.json.JSON;
+import cn.hutool.json.JSONUtil;
+import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
+import com.aliyun.tea.TeaException;
+import com.aliyun.teautil.models.RuntimeOptions;
+import com.aliyuncs.DefaultAcsClient;
+import com.aliyuncs.IAcsClient;
+import com.aliyuncs.dysmsapi.model.v20170525.AddSmsTemplateRequest;
+import com.aliyuncs.dysmsapi.model.v20170525.AddSmsTemplateResponse;
+import com.aliyuncs.profile.DefaultProfile;
+import com.hys.app.framework.exception.ServiceException;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class AliSmsUtil {
+    private static String signName = "上海瑞赢旷视科技";
+    public static String access_id = "LTAI5t9RbXSuirMa8AkvHxQf";
+    public static String access_secret = "VCmMZvMKrcN2tBHXdenyEKJIoKbwQf";
+
+
+    /**
+     * <b>description</b> :
+     * <p>使用AK&amp;SK初始化账号Client</p>
+     *
+     * @return Client
+     * @throws Exception
+     */
+    public static com.aliyun.dysmsapi20170525.Client createClient() throws Exception {
+        // 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
+        // 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html。
+        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
+                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
+                .setAccessKeyId(access_id)
+                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
+                .setAccessKeySecret(access_secret);
+        // Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
+        config.endpoint = "dysmsapi.aliyuncs.com";
+        return new com.aliyun.dysmsapi20170525.Client(config);
+    }
+
+    /**
+     * 获取用于查询短信状态的客户端
+     *
+     * @return
+     * @throws Exception
+     */
+    public static IAcsClient getIAcsClient() throws Exception {
+        // 创建DefaultProfile实例,用于初始化客户端配置
+        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", access_id, access_secret);
+        // 创建IAcsClient实例
+        return new DefaultAcsClient(profile);
+    }
+
+    public static Boolean sendSms(String rePhone, String templateCode, String map) {
+
+        try {
+            com.aliyun.dysmsapi20170525.Client client = AliSmsUtil.createClient();
+            com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest()
+                    .setPhoneNumbers(rePhone)
+                    .setTemplateCode(templateCode)
+                    .setTemplateParam(map)
+                    .setSignName(signName);
+            // 复制代码运行请自行打印 API 的返回值
+            SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, new RuntimeOptions());
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    public static String createSmsTemplate(Integer templateType, String templateName, String templateContent, String remark) {
+        try {
+            // 设置鉴权参数,初始化客户端
+            DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", access_id, access_secret);
+            System.out.println("Gson version: ---------------------------------" + com.google.gson.Gson.class.getPackage().getImplementationVersion());
+            IAcsClient client = new DefaultAcsClient(profile);
+
+            // 创建API请求并设置参数
+            AddSmsTemplateRequest request = new AddSmsTemplateRequest();
+            request.setTemplateType(templateType); // 短信类型,0为验证码,1为短信通知,2为推广短信
+            request.setTemplateName(templateName);
+            request.setTemplateContent(templateContent);
+            request.setRemark(remark); // 模板申请的备注信息,如用途、使用场景等
+            // 发起请求并处理响应
+            AddSmsTemplateResponse response = client.getAcsResponse(request);
+            if (!"OK".equals(response.getCode())) {
+                throw new ServiceException("申请提交失败, 错误信息: " + response.getMessage());
+            }
+            return response.getTemplateCode();
+        } catch (Exception e) {
+            throw new ServiceException("短信模板创建失败");
+        }
+    }
+}

+ 101 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/msg/MailSmtpUtil.java

@@ -0,0 +1,101 @@
+package com.hys.app.controller.erp.use.msg;
+
+import javax.mail.*;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import java.util.Date;
+import java.util.Properties;
+import java.util.UUID;
+
+public class MailSmtpUtil {
+
+    private static String user="service@mail.raycos.com.cn";
+    private static String pwd="RayCos20230801";
+
+
+    /**
+     *
+     * @param toMail
+     * @param subject
+     * @param content
+     */
+
+    public static Boolean sendEmail(String toMail,String subject,String content) {
+        // 配置发送邮件的环境属性
+        final Properties props = new Properties();
+
+        // 表示SMTP发送邮件,需要进行身份验证
+        props.put("mail.smtp.auth", "true");
+        props.put("mail.smtp.host", "smtpdm.aliyun.com");
+        //设置端口:
+        props.put("mail.smtp.port", "80");//或"25", 如果使用ssl,则去掉使用80或25端口的配置,进行如下配置:
+        //加密方式:
+        //props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
+        //props.put("mail.smtp.socketFactory.port", "465");
+        //props.put("mail.smtp.port", "465");
+
+        props.put("mail.smtp.from", user);    //mailfrom 参数
+        props.put("mail.user", user);// 发件人的账号(在控制台创建的发信地址)
+        props.put("mail.password", pwd);// 发信地址的smtp密码(在控制台选择发信地址进行设置)
+        //props.setProperty("mail.smtp.ssl.enable", "true");  //请配合465端口使用
+        System.setProperty("mail.mime.splitlongparameters", "false");//用于解决附件名过长导致的显示异常
+        //props.put("mail.smtp.connectiontimeout", 1000);
+
+        // 构建授权信息,用于进行SMTP进行身份验证
+        Authenticator authenticator = new Authenticator() {
+            @Override
+            protected PasswordAuthentication getPasswordAuthentication() {
+                // 用户名、密码
+                String userName = props.getProperty("mail.user");
+                String password = props.getProperty("mail.password");
+                return new PasswordAuthentication(userName, password);
+            }
+        };
+        //使用环境属性和授权信息,创建邮件会话
+        Session mailSession = Session.getInstance(props, authenticator);
+        //mailSession.setDebug(true);//开启debug模式
+        final String messageIDValue = genMessageID(props.getProperty("mail.user"));
+        //创建邮件消息
+        MimeMessage message = new MimeMessage(mailSession) {
+            @Override
+            protected void updateMessageID() throws MessagingException {
+                //设置自定义Message-ID值
+                setHeader("Message-ID", messageIDValue);//创建Message-ID
+            }
+        };
+
+        try {
+            // 设置发件人邮件地址和名称。填写控制台配置的发信地址。和上面的mail.user保持一致。名称用户可以自定义填写。
+            InternetAddress from = new InternetAddress(user, "上海瑞赢旷视科技");//from 参数,可实现代发,注意:代发容易被收信方拒信或进入垃圾箱。
+            message.setFrom(from);
+            // 设置收件人邮件地址
+            InternetAddress to = new InternetAddress(toMail);
+            message.setRecipient(MimeMessage.RecipientType.TO, to);
+            message.setSentDate(new Date()); //设置时间
+            //设置邮件标题
+            message.setSubject(subject);
+            message.setContent(content, "text/html;charset=UTF-8");//html超文本;// "text/plain;charset=UTF-8" //纯文本。
+            // 发送邮件
+            Transport.send(message);
+            return true;
+        } catch (Exception e) {
+            String err = e.getMessage();
+            // 在这里处理message内容, 格式是固定的
+            System.out.println(err);
+            return false;
+        }
+    }
+    protected static String genMessageID(String mailFrom) {
+        // message-id 用于唯一地标识每一封邮件,其格式需要遵循RFC 5322标准,通常如 <uniquestring@example.com>,其中uniquestring是邮件服务器生成的唯一标识,可能包含时间戳、随机数等信息。
+        String[] mailInfo = mailFrom.split("@");
+        String domain = mailFrom;
+        int index = mailInfo.length - 1;
+        if (index >= 0) {
+            domain = mailInfo[index];
+        }
+        UUID uuid = UUID.randomUUID();
+        StringBuffer messageId = new StringBuffer();
+        messageId.append('<').append(uuid.toString()).append('@').append(domain).append('>');
+        return messageId.toString();
+    }
+}

+ 37 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/msg/MessageReceiveTypeEnum.java

@@ -0,0 +1,37 @@
+package com.hys.app.controller.erp.use.msg;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 消息接收类型
+ *
+ * @author 张崧
+ * @since 2023-12-19
+ */
+@Getter
+public enum MessageReceiveTypeEnum {
+
+    SYSTEM("SYSTEM", "系统消息"),
+    SMS("SMS", "手机短信"),
+    OFFICIAL("OFFICIAL", "公众号"),
+    MAIL("MAIL", "邮件消息");
+
+    MessageReceiveTypeEnum(String value, String label) {
+        this.value = value;
+        this.label = label;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    private final String value;
+
+    private final String label;
+
+}

+ 46 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/msg/MsgContant.java

@@ -0,0 +1,46 @@
+package com.hys.app.controller.erp.use.msg;
+
+public class MsgContant {
+    //公司创建成功
+    //
+    //体验账号创建成功,初始账号为:{},密码为{},使用期限到{},有任何使用问题请咨询客服:{}
+    public static final String CREATE_COMPANY_MAIL = "CREATE_COMPANY_MAIL";
+    public static final String CREATE_COMPANY_SMS = "CREATE_COMPANY_SMS";
+    public static final String CREATE_COMPANY_SYSTEM = "CREATE_COMPANY_SYSTEM";
+    public static final String CREATE_COMPANY_OFFICIAL = "CREATE_COMPANY_OFFICIAL";
+
+
+    //用户创建成功
+    //账号创建成功,快去登录体验吧。账号:{},密码:{},登录地址:https://erp.raycos.net/#/dashboard
+    public static final String CREATE_USER_MAIL = "CREATE_USER_MAIL";
+    public static final String CREATE_USER_SMS = "CREATE_USER_SMS";
+    public static final String CREATE_USER_SYSTEM = "CREATE_USER_SYSTEM";
+    public static final String CREATE_USER_OFFICIAL = "CREATE_USER_OFFICIAL";
+
+    //用户修改
+    //{}你的账号信息发生变动,新的账号为:{},密码为:{},如不是本人操作请尽快登录https://erp.raycos.net/#/dashboard进行修改
+    public static final String UPDATE_USER_MAIL = "UPDATE_USER_MAIL";
+    public static final String UPDATE_USER_SMS = "UPDATE_USER_SMS";
+    public static final String UPDATE_USER_SYSTEM = "UPDATE_USER_SYSTEM";
+    public static final String UPDATE_USER_OFFICIAL = "UPDATE_USER_OFFICIAL";
+
+
+    //盘点单创建成功,通知人同步库存
+    //${name}于${time}提交了${code},请尽快前往核定确定
+    public static final String INVENTORY_NOTICE_USER_SYSTEM = "INVENTORY_NOTICE_USER_SYSTEM";
+    public static final String INVENTORY_NOTICE_USER_SMS = "INVENTORY_NOTICE_USER_SMS";
+    public static final String INVENTORY_NOTICE_USER_MAIL = "INVENTORY_NOTICE_USER_MAIL";
+    public static final String INVENTORY_NOTICE_USER_OFFICIAL = "INVENTORY_NOTICE_USER_OFFICIAL";
+
+
+    //报损单创建成功 通知人确认
+    //{}于{}创建了报损单,请尽快到出库单里面进行确认
+    public static final String DAMAGE_NOTICE_USER_SYSTEM = "DAMAGE_NOTICE_USER_SYSTEM";
+    public static final String DAMAGE_NOTICE_USER_SMS = "DAMAGE_NOTICE_USER_SMS";
+    public static final String DAMAGE_NOTICE_USER_MAIL = "DAMAGE_NOTICE_USER_MAIL";
+    public static final String DAMAGE_NOTICE_USER_OFFICIAL = "DAMAGE_NOTICE_USER_OFFICIAL";
+
+    public static final String CHECK_CODE_SMS = "SMS_270860270";
+
+
+}

+ 170 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/msg/MsgUtilClient.java

@@ -0,0 +1,170 @@
+package com.hys.app.controller.erp.use.msg;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.hys.app.framework.exception.ServiceException;
+import com.hys.app.model.erp.dos.MessageReceiveDO;
+import com.hys.app.model.erp.dos.SmsMailTemplate;
+import com.hys.app.model.system.dos.AdminUser;
+import com.hys.app.service.erp.MessageReceiveManager;
+import com.hys.app.service.erp.SmsMailManager;
+import lombok.AllArgsConstructor;
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
+import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
+import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
+import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@AllArgsConstructor
+@Service
+public class MsgUtilClient {
+
+    private SmsMailManager smsMailManager;
+    private MessageReceiveManager messageReceiveManager;
+
+    /**
+     * 发系统消息
+     */
+    public void sendSys(String templateCode, AdminUser adminUser, Object... format) {
+        try {
+            SmsMailTemplate one = smsMailManager.getOne(new LambdaQueryWrapper<SmsMailTemplate>().eq(SmsMailTemplate::getCode, templateCode));
+            if (ObjectUtil.isNull(one)) {
+                throw new ServiceException("未找到系统消息模板");
+            }
+            String formatContent = StrUtil.format(one.getContent(), format);
+            MessageReceiveDO anEnum = new MessageReceiveDO();
+            anEnum.setType(MessageReceiveTypeEnum.SYSTEM);
+            anEnum.setContent(formatContent);
+            anEnum.setUserId(adminUser.getId());
+            anEnum.setCompanyId(adminUser.getCompanyId());
+            messageReceiveManager.save(anEnum);
+        } catch (Exception e) {
+        }
+    }
+
+    /**
+     * 发邮件
+     */
+    public void sendMail(String templateCode, AdminUser adminUser, Object... format) {
+        try {
+            SmsMailTemplate one = smsMailManager.getOne(new LambdaQueryWrapper<SmsMailTemplate>().eq(SmsMailTemplate::getCode, templateCode));
+            if (ObjectUtil.isNull(one)) {
+                throw new ServiceException("未找到邮件消息模板");
+            }
+            String formatContent = StrUtil.format(one.getContent(), format);
+            MailSmtpUtil.sendEmail(adminUser.getEmail(), one.getName(), formatContent);
+            MessageReceiveDO anEnum = new MessageReceiveDO();
+            anEnum.setType(MessageReceiveTypeEnum.MAIL);
+            anEnum.setContent(formatContent);
+            anEnum.setMail(adminUser.getEmail());
+            anEnum.setCompanyId(adminUser.getCompanyId());
+            messageReceiveManager.save(anEnum);
+        } catch (Exception e) {
+        }
+    }
+
+
+    /**
+     * 发公众号
+     */
+    public void sendOfficial(String code, AdminUser adminUser, Object... format) {
+        try {
+            SmsMailTemplate one = smsMailManager.getOne(new LambdaQueryWrapper<SmsMailTemplate>().eq(SmsMailTemplate::getTemplateCode, code));
+            if (ObjectUtil.isNull(one)) {
+                throw new ServiceException("未找到公众号消息模板");
+            }
+            if (StrUtil.isBlank(adminUser.getOpenid())) {
+                throw new ServiceException("公众号通知失败,当前用户未绑定微信(前往个人信息里面进行绑定)");
+            }
+            WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
+                    .toUser(adminUser.getOpenid())
+                    .templateId(one.getTemplateCode())
+                    .build();
+
+            //"character_string6--{}--#173177"  {}里面就是需要替换的内容
+            String formatContent = StrUtil.format(one.getRemark(), format);
+            String[] strings = formatContent.split(",");
+
+            for (String string : strings) {
+                String[] split = string.split("--");
+                //公众号平台的字段名,字段值,颜色 添加模板的时候--连接
+                WxMpTemplateData data = new WxMpTemplateData(split[0], split[1], "#173177");
+                templateMessage.addData(data);
+            }
+            WxMpService wxService = new WxMpServiceImpl();
+            WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
+            config.setAppId(AliSmsUtil.access_id);  // 替换为你的 AppID
+            config.setSecret(AliSmsUtil.access_secret);  // 替换为你的 AppSecret
+            wxService.setWxMpConfigStorage(config);
+            wxService.getTemplateMsgService().sendTemplateMsg(templateMessage);
+
+            MessageReceiveDO anEnum = new MessageReceiveDO();
+            anEnum.setType(MessageReceiveTypeEnum.OFFICIAL);
+            anEnum.setContent(formatContent);
+            anEnum.setOpenid(adminUser.getOpenid());
+            anEnum.setCompanyId(adminUser.getCompanyId());
+            messageReceiveManager.save(anEnum);
+        } catch (Exception e) {
+            System.out.println("11111111111111");
+        }
+    }
+
+
+    /**
+     * 发短信
+     */
+    public void sendSms(String templateCode, AdminUser adminUser, Object... format) {
+        SmsMailTemplate one = smsMailManager.getOne(new LambdaQueryWrapper<SmsMailTemplate>().eq(SmsMailTemplate::getCode, templateCode));
+        if (ObjectUtil.isNull(one)) {
+            throw new ServiceException("未找到短信消息模板");
+        }
+        String formatContent = StrUtil.format(one.getRemark(), format);
+        //添加模板消息的时候模板内容 应该为json格式    String aa = "{\"code\":{}\"}";
+        AliSmsUtil.sendSms(adminUser.getPhone(), one.getTemplateCode(), formatContent);
+
+        MessageReceiveDO anEnum = new MessageReceiveDO();
+        anEnum.setType(MessageReceiveTypeEnum.SMS);
+        anEnum.setContent(formatContent);
+        anEnum.setPhone(adminUser.getPhone());
+        anEnum.setCompanyId(adminUser.getCompanyId());
+        messageReceiveManager.save(anEnum);
+    }
+
+
+//    /**
+//     * 发短信 发系统消息
+//     */
+//    public static void sendSmsSys() {
+//
+//    }
+//
+//
+//    /**
+//     * 发短信 发邮件
+//     */
+//    public static void sendSmsMail() {
+//
+//    }
+//
+//
+//    /**
+//     * 发邮件 发系统消息
+//     */
+//    public static void sendSysMail() {
+//
+//    }
+//
+//    /**
+//     * 发邮件 发系统消息  发短信
+//     */
+//    public static void sendSysMailSms() {
+//
+//    }
+
+
+}

+ 15 - 0
module-erp/src/main/java/com/hys/app/controller/erp/use/task/MerchantPayInfo.java

@@ -0,0 +1,15 @@
+package com.hys.app.controller.erp.use.task;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@Data
+public class MerchantPayInfo {
+    private String bankNo = "31010260201000041831";
+    private String bank ="浙江泰隆商业银行股份有限公司上海莘庄支行";
+    private String dutyParagraph ="91310117MA7JB1TQ71";
+    private String invoice ="崴叁(上海)文化传媒有限公司";
+
+}

+ 188 - 0
module-erp/src/main/java/com/hys/app/controller/system/AdminUserManagerController.java

@@ -0,0 +1,188 @@
+package com.hys.app.controller.system;
+
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.hys.app.controller.erp.use.msg.AliSmsUtil;
+import com.hys.app.controller.erp.use.msg.MsgContant;
+import com.hys.app.controller.erp.use.msg.MsgUtilClient;
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.exception.ResourceNotFoundException;
+import com.hys.app.framework.exception.ServiceException;
+import com.hys.app.framework.util.BeanUtil;
+import com.hys.app.framework.util.StringUtil;
+import com.hys.app.framework.validation.annotation.DemoSiteDisable;
+import com.hys.app.model.erp.entity.CompanyErp;
+import com.hys.app.model.errorcode.SystemErrorCode;
+import com.hys.app.model.system.dos.AdminUser;
+import com.hys.app.model.system.vo.AdminLoginVO;
+import com.hys.app.model.system.vo.AdminUserVO;
+import com.hys.app.service.base.service.ValidatorManager;
+import com.hys.app.service.erp.CompanyErpManager;
+import com.hys.app.service.system.AdminUserManager;
+import io.jsonwebtoken.ExpiredJwtException;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 平台管理员控制器
+ *
+ * @author zh
+ * @version v7.0
+ * @since v7.0.0
+ * 2018-06-20 20:38:26
+ */
+@RestController
+@RequestMapping("/admin/systems/admin-users")
+@Api(description = "平台管理员相关API")
+@Validated
+public class AdminUserManagerController {
+
+    @Autowired
+    private AdminUserManager adminUserManager;
+    @Autowired
+    private ValidatorManager validatorManager;
+    @Autowired
+    private CompanyErpManager companyManager;
+    @Autowired
+    private RedisTemplate redisTemplate;
+
+    @Autowired
+    MsgUtilClient msgUtilClient;
+
+
+    @GetMapping("/login")
+    @ApiOperation(value = "用户名(手机号)/密码登录API")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String", paramType = "query")
+    })
+    public AdminLoginVO login(String username,
+                              String password,
+                              @NotEmpty(message = "平台登录sys,公司登录com") String type,
+                              String phone,
+                              String checkCodeKey,
+                              String checkCode,
+                              @NotEmpty(message = "账号登录 password 手机登录 phone") String loginType,
+                              String companyName) {
+        if ("password".equals(loginType)) {
+            return adminUserManager.login(username, password, companyName, type);
+        }else if ("phone".equals(loginType)){
+            String code = (String) redisTemplate.opsForValue().get(checkCodeKey);
+            if (!code.equals(checkCode)) {
+                throw new ServiceException("验证码错误");
+            }
+            return adminUserManager.loginByPhone(phone, companyName, type);
+        }
+        throw new ServiceException("不支持的登录类型");
+    }
+
+
+    @ApiOperation(value = "刷新token")
+    @PostMapping("/token")
+    @ApiImplicitParam(name = "refresh_token", value = "刷新token", required = true, dataType = "String", paramType = "query")
+    public String refreshToken(@ApiIgnore @NotEmpty(message = "刷新token不能为空") String refreshToken) {
+        try {
+            return adminUserManager.exchangeToken(refreshToken);
+        } catch (ExpiredJwtException e) {
+            throw new ServiceException("当前token已经失效");
+        }
+    }
+
+    @PutMapping
+    @ApiOperation(value = "修改管理员密码及头像", response = AdminUser.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "face", value = "头像", required = true, dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "old_passwprd", value = "原密码", required = false, dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "password", value = "新密码", required = false, dataType = "String", paramType = "query")
+    })
+    @DemoSiteDisable
+    public AdminUser edit(@NotEmpty(message = "管理员头像不能为空") String face, @ApiIgnore String oldPasswprd, String password) {
+        Long uid = AdminUserContext.getAdmin().getUid();
+        AdminUser adminUser = this.adminUserManager.getModel(uid);
+        if (adminUser == null) {
+            throw new ResourceNotFoundException("当前管理员不存在");
+        }
+        AdminUserVO adminUserVO = new AdminUserVO();
+        BeanUtil.copyProperties(adminUser, adminUserVO);
+
+        //校验密码
+        if (!StringUtil.isEmpty(oldPasswprd) && StringUtil.isEmpty(password)) {
+            throw new ServiceException(SystemErrorCode.E923.code(), "新密码不能为空");
+        }
+        if (StringUtil.isEmpty(oldPasswprd) && !StringUtil.isEmpty(password)) {
+            throw new ServiceException(SystemErrorCode.E922.code(), "原始密码不能为空");
+        }
+        if (!StringUtil.isEmpty(oldPasswprd) && !StringUtil.isEmpty(password)) {
+            String dbOldPassword = StringUtil.md5(oldPasswprd + adminUser.getUsername().toLowerCase());
+            if (!dbOldPassword.equals(adminUser.getPassword())) {
+                throw new ServiceException(SystemErrorCode.E921.code(), "原密码错误");
+            }
+            adminUserVO.setPassword(password);
+        } else {
+            adminUserVO.setPassword("");
+        }
+        adminUserVO.setFace(face);
+        AdminUser upAdminUser = adminUserManager.edit(adminUserVO, adminUser.getId());
+        this.adminUserManager.logout(uid);
+        return upAdminUser;
+    }
+
+    @ApiOperation(value = "注销管理员登录")
+    @PostMapping(value = "/logout")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "uid", value = "管理员id", dataType = "int", paramType = "query", required = true)
+    })
+    public String loginOut(@NotNull(message = "管理员id不能为空") Long uid) {
+        this.adminUserManager.logout(uid);
+        return null;
+    }
+
+    @ApiOperation(value = "查询当前管理员的信息")
+    @GetMapping(value = "/info")
+    public AdminUser info() {
+        return this.adminUserManager.getModel(AdminUserContext.getAdminUserId());
+    }
+
+
+    @GetMapping("/login/getCompany")
+    public List<CompanyErp> loginGetCompany(String key) {
+        return companyManager.list(new LambdaQueryWrapper<CompanyErp>()
+                .select(CompanyErp::getId, CompanyErp::getName)
+                .and(StrUtil.isNotBlank(key), item -> item.like(CompanyErp::getName, key)
+                        .or()
+                        .like(CompanyErp::getFirstPy, key)
+                        .or()
+                        .like(CompanyErp::getPinying, key)));
+    }
+
+    @GetMapping("/loginGetCheckCode")
+    @ApiOperation(value = "获取验证码")
+    public String getCheckCode(String phone) {
+        Map<String, Object> map = new HashMap<>();
+        String fastUUID = IdUtil.fastUUID();
+        Random random = new Random();
+        int randomNumber = 100000 + random.nextInt(900000);
+        map.put("code", randomNumber);
+        AliSmsUtil.sendSms(phone, MsgContant.CHECK_CODE_SMS, JSON.toJSONString(map));
+        redisTemplate.opsForValue().set(fastUUID, String.valueOf(randomNumber));
+        redisTemplate.expire(fastUUID, 5, TimeUnit.HOURS);
+        return fastUUID;
+    }
+}

+ 79 - 0
module-erp/src/main/java/com/hys/app/controller/system/DictDataController.java

@@ -0,0 +1,79 @@
+package com.hys.app.controller.system;
+
+import com.hys.app.converter.system.DictDataConverter;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.model.system.dos.DictDataDO;
+import com.hys.app.model.system.dto.DictDataCreateDTO;
+import com.hys.app.model.system.dto.DictDataQueryParams;
+import com.hys.app.model.system.dto.DictDataUpdateDTO;
+import com.hys.app.model.system.vo.DictDataRespVO;
+import com.hys.app.model.system.vo.DictDataSimpleRespVO;
+import com.hys.app.service.system.DictDataManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.util.List;
+
+@Api(tags = "管理后台 - 字典数据")
+@RestController
+@RequestMapping("/admin/systems/dict-data")
+@Validated
+public class DictDataController {
+
+    @Resource
+    private DictDataManager dictDataManager;
+
+    @Autowired
+    private DictDataConverter converter;
+
+    @PostMapping("/create")
+    @ApiOperation(value = "新增字典数据")
+    @Log(client = LogClient.admin, detail = "新增标签为[${reqVO.label}]的字典数据信息")
+    public void createDictData(@Valid @RequestBody DictDataCreateDTO reqVO) {
+        dictDataManager.createDictData(reqVO);
+    }
+
+    @PutMapping("/update")
+    @ApiOperation(value = "修改字典数据")
+    @Log(client = LogClient.admin, detail = "修改标签为[${reqVO.label}]的字典数据信息")
+    public void updateDictData(@Valid @RequestBody DictDataUpdateDTO reqVO) {
+        dictDataManager.updateDictData(reqVO);
+    }
+
+    @DeleteMapping("/delete")
+    @ApiOperation(value = "删除字典数据")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024")
+    @Log(client = LogClient.admin, detail = "删除ID为[${id}]的字典数据信息")
+    public void deleteDictData(Long id) {
+        dictDataManager.deleteDictData(id);
+    }
+
+    @GetMapping("/list-all-simple")
+    @ApiOperation(value = "获得全部字典数据列表", notes = "一般用于管理后台缓存字典数据在本地")
+    public List<DictDataSimpleRespVO> getSimpleDictDataList(String dictType) {
+        List<DictDataDO> list = dictDataManager.getDictDataList(dictType);
+        return converter.convertList(list);
+    }
+
+    @GetMapping("/page")
+    @ApiOperation(value = "获得字典类型的分页列表")
+    public WebPage<DictDataRespVO> getDictTypePage(@Valid DictDataQueryParams reqVO) {
+        return converter.convertPage(dictDataManager.getDictDataPage(reqVO));
+    }
+
+    @GetMapping(value = "/get")
+    @ApiOperation(value = "/查询字典数据详细")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024")
+    public DictDataRespVO getDictData(@RequestParam("id") Long id) {
+        return converter.convert(dictDataManager.getDictData(id));
+    }
+
+}

+ 81 - 0
module-erp/src/main/java/com/hys/app/controller/system/DictTypeController.java

@@ -0,0 +1,81 @@
+package com.hys.app.controller.system;
+
+import com.hys.app.converter.system.DictTypeConverter;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.model.system.dos.DictTypeDO;
+import com.hys.app.model.system.dto.DictTypeCreateDTO;
+import com.hys.app.model.system.dto.DictTypeQueryParams;
+import com.hys.app.model.system.dto.DictTypeUpdateDTO;
+import com.hys.app.model.system.vo.DictTypeRespVO;
+import com.hys.app.model.system.vo.DictTypeSimpleRespVO;
+import com.hys.app.service.system.DictTypeManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.util.List;
+
+@Api(tags = "管理后台 - 字典类型")
+@RestController
+@RequestMapping("/admin/systems/dict-type")
+@Validated
+public class DictTypeController {
+
+    @Resource
+    private DictTypeManager dictTypeManager;
+
+    @Autowired
+    private DictTypeConverter converter;
+
+    @PostMapping("/create")
+    @ApiOperation(value = "创建字典类型")
+    @Log(client = LogClient.admin, detail = "新增名称为[${reqVO.name}]的字典类型")
+    public void createDictType(@Valid @RequestBody DictTypeCreateDTO reqVO) {
+        dictTypeManager.createDictType(reqVO);
+    }
+
+    @PutMapping("/update")
+    @ApiOperation(value = "修改字典类型")
+    @Log(client = LogClient.admin, detail = "修改名称为[${reqVO.name}]的字典类型")
+    public void updateDictType(@Valid @RequestBody DictTypeUpdateDTO reqVO) {
+        dictTypeManager.updateDictType(reqVO);
+    }
+
+    @DeleteMapping("/delete")
+    @ApiOperation(value = "删除字典类型")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024")
+    @Log(client = LogClient.admin, detail = "删除ID为[${id}]的字典类型")
+    public void deleteDictType(Long id) {
+        dictTypeManager.deleteDictType(id);
+    }
+
+    @ApiOperation(value = "/获得字典类型的分页列表")
+    @GetMapping("/page")
+    public WebPage<DictTypeRespVO> pageDictTypes(@Valid DictTypeQueryParams reqVO) {
+        WebPage<DictTypeDO> dictTypePage = dictTypeManager.getDictTypePage(reqVO);
+        return converter.convertPage(dictTypePage);
+    }
+
+    @ApiOperation(value = "/查询字典类型详细")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024")
+    @GetMapping(value = "/get")
+    public DictTypeRespVO getDictType(@RequestParam("id") Long id) {
+        DictTypeDO dictTypeDO = dictTypeManager.getDictType(id);
+        return converter.convert(dictTypeDO);
+    }
+
+    @GetMapping("/list-all-simple")
+    @ApiOperation(value = "获得全部字典类型列表", notes = "包括开启 + 禁用的字典类型,主要用于前端的下拉选项")
+    public List<DictTypeSimpleRespVO> getSimpleDictTypeList() {
+        List<DictTypeDO> list = dictTypeManager.getDictTypeList();
+        return converter.convertList(list);
+    }
+
+}

+ 97 - 0
module-erp/src/main/java/com/hys/app/controller/system/MenuManagerController.java

@@ -0,0 +1,97 @@
+package com.hys.app.controller.system;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.hys.app.framework.util.BeanUtil;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.model.system.dos.Menu;
+import com.hys.app.model.system.vo.MenuVO;
+import com.hys.app.model.system.vo.MenusVO;
+import com.hys.app.service.system.MenuManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 菜单管理控制器
+ *
+ * @author zh
+ * @version v7.0
+ * @since v7.0.0
+ * 2018-06-19 09:46:02
+ */
+@RestController
+@RequestMapping("/admin/systems/menus")
+@Api(description = "菜单管理相关API")
+public class MenuManagerController {
+
+    @Autowired
+    private MenuManager menuManager;
+
+
+    @ApiOperation(value = "根据父id查询所有菜单", response = Menu.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "parent_id", value = "菜单父id,如果查询顶级菜单则传0", required = true, dataType = "int", paramType = "path")
+    })
+    @GetMapping("/children")
+    public List<MenusVO> getMenuTree() {
+        return this.menuManager.getMenuTree();
+    }
+
+
+    @ApiOperation(value = "添加菜单", response = Menu.class)
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "添加名称为[${menu.title}]的菜单信息")
+    public Menu add(@Valid MenuVO menu) {
+        return this.menuManager.add(menu);
+    }
+
+    @PutMapping(value = "/{id}")
+    @ApiOperation(value = "修改菜单", response = Menu.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", required = true, dataType = "int", paramType = "path")
+    })
+    @Log(client = LogClient.admin, detail = "修改ID为[${id}]的菜单信息")
+    public Menu edit(@Valid MenuVO menuVO, @PathVariable Long id) {
+        Menu menu = new Menu();
+        BeanUtil.copyProperties(menuVO, menu);
+        return this.menuManager.edit(menu, id);
+    }
+
+
+    @DeleteMapping(value = "/{id}")
+    @ApiOperation(value = "删除菜单")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "要删除的菜单管理主键", required = true, dataType = "int", paramType = "path")
+    })
+    @Log(client = LogClient.admin, detail = "删除ID为[${id}]的菜单信息")
+    public String delete(@PathVariable Long id) {
+        this.menuManager.delete(id);
+        return "";
+    }
+
+
+    @GetMapping(value = "/{id}")
+    @ApiOperation(value = "查询一个菜单")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "要查询的菜单管理主键", required = true, dataType = "int", paramType = "path")
+    })
+    public Menu get(@PathVariable Long id) {
+        Menu menu = this.menuManager.getModel(id);
+        return menu;
+    }
+
+    @GetMapping(value = "/getPdaMenu")
+    @ApiOperation(value = "查询pda菜单")
+    public List<Menu> getPdaMenu() {
+       return  this.menuManager.getPdaMenu();
+
+    }
+}

+ 75 - 0
module-erp/src/main/java/com/hys/app/controller/system/PostManagerController.java

@@ -0,0 +1,75 @@
+package com.hys.app.controller.system;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dto.PostQueryParams;
+import com.hys.app.model.erp.vo.PostVO;
+import com.hys.app.model.erp.dto.PostDTO;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.erp.PostManager;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 岗位相关API
+ *
+ * @author 张崧
+ * 2023-11-29 17:15:22
+ */
+@RestController
+@RequestMapping("/admin/erp/post")
+@Api(tags = "岗位相关API")
+@Validated
+public class PostManagerController {
+
+    @Autowired
+    private PostManager postManager;
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public WebPage<PostVO> list(PostQueryParams queryParams) {
+        return postManager.list(queryParams);
+    }
+
+    @ApiOperation(value = "查询全部")
+    @GetMapping("/list-all")
+    public List<PostVO> list() {
+        return postManager.listAll();
+    }
+
+    @ApiOperation(value = "添加")
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "添加名称为[${postDTO.name}]的岗位")
+    public void add(@RequestBody @Valid PostDTO postDTO) {
+        postManager.add(postDTO);
+    }
+
+    @ApiOperation(value = "修改")
+    @PutMapping("/{id}")
+    @Log(client = LogClient.admin, detail = "编辑ID为[${id}]的岗位")
+    public void edit(@PathVariable String id, @RequestBody @Valid PostDTO postDTO) {
+        postDTO.setId(id);
+        postManager.edit(postDTO);
+    }
+
+    @ApiOperation(value = "查询")
+    @GetMapping("/{id}")
+    public PostVO getDetail(@PathVariable Long id) {
+        return postManager.getDetail(id);
+    }
+
+    @ApiOperation(value = "删除")
+    @DeleteMapping("/{ids}")
+    @Log(client = LogClient.admin, detail = "删除ID为${ids}的岗位")
+    public void delete(@PathVariable Long[] ids) {
+        postManager.delete(Arrays.asList(ids));
+    }
+}
+

+ 97 - 0
module-erp/src/main/java/com/hys/app/controller/system/RegionsManagerController.java

@@ -0,0 +1,97 @@
+package com.hys.app.controller.system;
+
+import com.hys.app.framework.exception.ResourceNotFoundException;
+import com.hys.app.framework.util.BeanUtil;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.model.system.dos.Regions;
+import com.hys.app.model.system.vo.RegionsVO;
+import com.hys.app.service.system.RegionsManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+
+/**
+ * 地区控制器
+ *
+ * @author zh
+ * @version v7.0.0
+ * @since v7.0.0
+ * 2018-05-18 11:45:03
+ */
+@RestController
+@RequestMapping("/admin/systems/regions")
+@Api(description = "地区相关API")
+public class RegionsManagerController {
+
+    @Autowired
+    private RegionsManager regionsManager;
+
+    @ApiOperation(value = "添加地区", response = Regions.class)
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "添加名称为[${regionsVO.localName}]的地区信息")
+    public Regions add(@Valid RegionsVO regionsVO) {
+        return this.regionsManager.add(regionsVO);
+
+    }
+
+    @PutMapping(value = "/{id}")
+    @ApiOperation(value = "修改地区", response = Regions.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", required = true, dataType = "int", paramType = "path")
+    })
+    @Log(client = LogClient.admin, detail = "修改ID为[${id}]的地区信息")
+    public Regions edit(@Valid RegionsVO regionsVO, @PathVariable Long id) {
+        Regions regions = regionsManager.getModel(id);
+        if (regions == null) {
+            throw new ResourceNotFoundException("当前地区不存在");
+        }
+        BeanUtil.copyProperties(regionsVO, regions);
+        this.regionsManager.edit(regions, id);
+        return regions;
+    }
+
+
+    @DeleteMapping(value = "/{id}")
+    @ApiOperation(value = "删除地区")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "要删除的地区主键", required = true, dataType = "int", paramType = "path")
+    })
+    @Log(client = LogClient.admin, detail = "删除ID为[${id}]的地区信息")
+    public String delete(@PathVariable Long id) {
+        this.regionsManager.delete(id);
+        return "";
+    }
+
+
+    @GetMapping(value = "/{id}")
+    @ApiOperation(value = "查询一个地区")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "要查询的地区主键", required = true, dataType = "int", paramType = "path")
+    })
+    public Regions get(@PathVariable Long id) {
+
+        Regions regions = this.regionsManager.getModel(id);
+
+        return regions;
+    }
+
+
+    @GetMapping(value = "/{id}/children")
+    @ApiOperation(value = "获取某地区的子地区")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "地区id", required = true, dataType = "int", paramType = "path")
+    })
+    public List<Regions> getChildrenById(@PathVariable Long id) {
+
+        return regionsManager.getRegionsChildren(id);
+    }
+
+}

+ 84 - 0
module-erp/src/main/java/com/hys/app/controller/system/SensitiveWordsManagerController.java

@@ -0,0 +1,84 @@
+package com.hys.app.controller.system;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.base.dos.SensitiveWords;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.service.system.SensitiveWordsManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.Valid;
+
+/**
+ * 敏感词控制器
+ *
+ * @author fk
+ * @version v1.0
+ * @since v7.0.0
+ * 2018-08-02 11:30:59
+ */
+@RestController
+@RequestMapping("/admin/sensitive-words")
+@Api(description = "敏感词相关API")
+public class SensitiveWordsManagerController {
+
+    @Autowired
+    private SensitiveWordsManager sensitiveWordsManager;
+
+
+    @ApiOperation(value = "查询敏感词列表", response = SensitiveWords.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page_no", value = "页码", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "page_size", value = "每页显示数量", required = true, dataType = "int", paramType = "query")
+    })
+    @GetMapping
+    public WebPage list(@ApiIgnore Long pageNo, @ApiIgnore Long pageSize, String keyword) {
+
+        return this.sensitiveWordsManager.list(pageNo, pageSize, keyword);
+    }
+
+
+    @ApiOperation(value = "添加敏感词", response = SensitiveWords.class)
+    @PostMapping
+    @Log(client = LogClient.admin, detail = "添加名称为[${sensitiveWords.wordName}]的敏感词信息")
+    public SensitiveWords add(@Valid SensitiveWords sensitiveWords) {
+
+        this.sensitiveWordsManager.add(sensitiveWords);
+
+        return sensitiveWords;
+    }
+
+
+    @DeleteMapping(value = "/{id}")
+    @ApiOperation(value = "删除敏感词")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "要删除的敏感词主键", required = true, dataType = "int", paramType = "path")
+    })
+    @Log(client = LogClient.admin, detail = "删除ID为[${id}]的敏感词信息")
+    public String delete(@PathVariable Long id) {
+
+        this.sensitiveWordsManager.delete(id);
+
+        return "";
+    }
+
+
+    @GetMapping(value = "/{id}")
+    @ApiOperation(value = "查询一个敏感词")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "要查询的敏感词主键", required = true, dataType = "int", paramType = "path")
+    })
+    public SensitiveWords get(@PathVariable Long id) {
+
+        SensitiveWords sensitiveWords = this.sensitiveWordsManager.getModel(id);
+
+        return sensitiveWords;
+    }
+
+}

+ 57 - 0
module-erp/src/main/java/com/hys/app/controller/system/SiteSettingManagerController.java

@@ -0,0 +1,57 @@
+package com.hys.app.controller.system;
+
+import com.hys.app.framework.util.JsonUtil;
+import com.hys.app.model.base.SettingGroup;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.model.system.vo.SiteSetting;
+import com.hys.app.service.base.service.SettingManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+/**
+ * 站点设置api
+ *
+ * @author zh
+ * @version v7.0
+ * @date 18/5/18 下午6:55
+ * @since v7.0
+ */
+@RestController
+@RequestMapping("/admin/settings")
+@Api(description = "站点设置")
+@Validated
+public class SiteSettingManagerController {
+    @Autowired
+    private SettingManager settingManager;
+
+
+    @GetMapping(value = "/site")
+    @ApiOperation(value = "获取站点设置", response = SiteSetting.class)
+    public SiteSetting getSiteSetting() {
+        String siteSettingJson = settingManager.get(SettingGroup.SITE);
+
+        SiteSetting siteSetting = JsonUtil.jsonToObject(siteSettingJson,SiteSetting.class);
+        if (siteSetting == null) {
+            return new SiteSetting();
+        }
+        return siteSetting;
+    }
+
+    @PutMapping(value = "/site")
+    @ApiOperation(value = "修改站点设置", response = SiteSetting.class)
+    @Log(client = LogClient.admin, detail = "修改系统站点设置信息")
+    public SiteSetting editSiteSetting(@Valid SiteSetting siteSetting) {
+        settingManager.save(SettingGroup.SITE, siteSetting);
+        return siteSetting;
+    }
+
+}

+ 58 - 0
module-erp/src/main/java/com/hys/app/controller/system/SmsCallbackController.java

@@ -0,0 +1,58 @@
+package com.hys.app.controller.system;
+
+import com.hys.app.service.system.SmsTemplateManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.Map;
+
+/**
+ * 阿里云短信回调控制器
+ *
+ * @author zhangsong
+ * @version v1.0
+ * @since v7.3.0
+ * 2021-01-28 16:04:23
+ */
+@RestController
+@RequestMapping("/admin/sms/callback")
+@ApiIgnore
+public class SmsCallbackController {
+
+    private final Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Autowired
+    private SmsTemplateManager smsTemplateManager;
+
+    /**
+     * 短信模板审核回调接口 暂时支持 smsAliPlugin smsZtPlugin
+     *
+     * @param type 回调类型
+     * @param json 回调body参数
+     * @return
+     */
+    @PostMapping("/template/{type}")
+    public Map templateAuditCallback(@PathVariable("type") String type, @RequestBody String json) {
+        logger.info("短信模板审核结果回调:" + json);
+
+        Map map = this.smsTemplateManager.templateAuditCallback(json, type);
+        return map;
+    }
+
+    /**
+     * 短信发送结果回调接口
+     *
+     * @param type 回调类型  暂时支持 smsAliPlugin smsZtPlugin
+     * @param json 回调body参数
+     * @return
+     */
+    @PostMapping("/send/{type}")
+    public Map smsSendCallback(@PathVariable("type") String type, @RequestBody String json) {
+        logger.info("短信发送结果回调:" + json);
+        return this.smsTemplateManager.smsSendCallback(json, type);
+    }
+
+}

+ 79 - 0
module-erp/src/main/java/com/hys/app/controller/system/SmsPlatformManagerController.java

@@ -0,0 +1,79 @@
+package com.hys.app.controller.system;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.model.system.dos.SmsPlatformDO;
+import com.hys.app.model.system.vo.SmsPlatformVO;
+import com.hys.app.service.system.SmsPlatformManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.constraints.NotEmpty;
+
+
+/**
+ * 短信网关表控制器
+ *
+ * @author zh
+ * @version v7.0.0
+ * @since v7.0.0
+ * 2018-03-23 11:31:05
+ */
+@RestController
+@RequestMapping("/admin/systems/platforms")
+@Api(description = "短信网关相关API")
+public class SmsPlatformManagerController {
+
+    @Autowired
+    private SmsPlatformManager smsPlatformManager;
+
+
+    @ApiOperation(value = "查询短信网关列表", response = SmsPlatformDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page_no", value = "页码", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "page_size", value = "每页显示数量", required = true, dataType = "int", paramType = "query")
+    })
+    @GetMapping
+    public WebPage list(@ApiIgnore @NotEmpty(message = "页码不能为空") Long pageNo, @ApiIgnore @NotEmpty(message = "每页数量不能为空") Long pageSize) {
+        return this.smsPlatformManager.list(pageNo, pageSize);
+    }
+
+
+    @ApiOperation(value = "修改短信网关", response = SmsPlatformDO.class)
+    @PutMapping(value = "/{bean}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "bean", value = "短信网关bean id", required = true, dataType = "String", paramType = "path"),
+            @ApiImplicitParam(name = "sms_platform", value = "短信网关对象", required = true, dataType = "SmsPlatformVO", paramType = "body")
+    })
+    @Log(client = LogClient.admin, detail = "修改bean id为[${bean}]的短信网关信息")
+    public SmsPlatformVO edit(@PathVariable String bean, @RequestBody @ApiIgnore SmsPlatformVO smsPlatformVO) {
+        smsPlatformVO.setBean(bean);
+        return this.smsPlatformManager.edit(smsPlatformVO);
+    }
+
+
+    @GetMapping(value = "/{bean}")
+    @ApiOperation(value = "查询一个短信网关参数")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "bean", value = "短信网关bean id", required = true, dataType = "String", paramType = "path")
+    })
+    public SmsPlatformVO getConfig(@PathVariable String bean) {
+        return this.smsPlatformManager.getConfig(bean);
+    }
+
+    @ApiOperation(value = "开启某个短信网关", response = String.class)
+    @PutMapping("/{bean}/open")
+    @ApiImplicitParam(name = "bean", value = "bean", required = true, dataType = "String", paramType = "path")
+    @Log(client = LogClient.admin, detail = "开启bean id为[${bean}]的短信网关信息")
+    public String open(@PathVariable String bean) {
+        this.smsPlatformManager.openPlatform(bean);
+        return null;
+    }
+
+}

+ 107 - 0
module-erp/src/main/java/com/hys/app/controller/system/SmsTemplateManagerController.java

@@ -0,0 +1,107 @@
+package com.hys.app.controller.system;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.framework.exception.ServiceException;
+import com.hys.app.model.errorcode.SystemErrorCode;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.model.system.dos.SmsTemplate;
+import com.hys.app.service.system.SmsTemplateManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 短信模板控制器
+ *
+ * @author zhangsong
+ * @version v1.0
+ * @since v7.3.0
+ * 2021-01-26 16:04:23
+ */
+@RestController
+@RequestMapping("/admin/systems/sms-template")
+@Api(tags = "短信模板相关API")
+public class SmsTemplateManagerController {
+
+    @Autowired
+    private SmsTemplateManager smsTemplateManager;
+
+
+    @ApiOperation(value = "查询短信模板列表", response = SmsTemplate.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page_no", value = "页码", required = true, dataType = "long", dataTypeClass = Long.class, paramType = "query"),
+            @ApiImplicitParam(name = "page_size", value = "每页显示数量", required = true, dataType = "long", dataTypeClass = Long.class, paramType = "query"),
+            @ApiImplicitParam(name = "service_type", value = "业务类型", required = true, dataType = "String", dataTypeClass = String.class, paramType = "query", allowableValues = "SHOP,MEMBER"),
+            @ApiImplicitParam(name = "bean_id", value = "短信平台beanId", required = true, dataType = "String", dataTypeClass = String.class, paramType = "query"),
+    })
+    @GetMapping
+    public WebPage list(@ApiIgnore Long pageNo, @ApiIgnore Long pageSize, @ApiIgnore String serviceType, @ApiIgnore String beanId) {
+
+        return this.smsTemplateManager.list(pageNo, pageSize, serviceType, beanId);
+    }
+
+
+    @GetMapping(value = "/{id}")
+    @ApiOperation(value = "查询一个短信模板")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "要查询的短信模板主键", required = true, dataType = "long", dataTypeClass = Long.class, paramType = "path")
+    })
+    public SmsTemplate get(@PathVariable Long id) {
+
+        SmsTemplate smsTemplate = this.smsTemplateManager.getModel(id);
+
+        return smsTemplate;
+    }
+
+    @PutMapping(value = "/{id}/enable-status")
+    @ApiOperation(value = "修改短信模板开启状态")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", required = true, dataType = "long", dataTypeClass = Long.class, paramType = "path"),
+            @ApiImplicitParam(name = "enable_status", value = "开启状态", required = true, dataType = "String", dataTypeClass = String.class, paramType = "query", allowableValues = "OPEN,CLOSE")
+    })
+    @Log(client = LogClient.admin, detail = "修改ID为[${id}]的短信模板开启状态")
+    public void updateEnableStatus(@PathVariable Long id, @ApiIgnore String enableStatus) {
+
+        this.smsTemplateManager.updateEnableStatus(id, enableStatus);
+    }
+
+    @PutMapping(value = "/{id}")
+    @ApiOperation(value = "修改短信模板")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", required = true, dataType = "long", dataTypeClass = Long.class, paramType = "path"),
+            @ApiImplicitParam(name = "content", value = "短信模板内容", required = true, dataType = "String", dataTypeClass = String.class, paramType = "query")
+    })
+    @Log(client = LogClient.admin, detail = "修改ID为[${id}]的短信模板内容")
+    public void edit(@PathVariable Long id, @ApiIgnore @NotBlank(message = "短信模板内容不能为空") String content) {
+
+        //设置要修改的字段(可以修改的字段:模板名称,模板内容,模板类型(短信通知,验证码))
+        SmsTemplate smsTemplate = new SmsTemplate();
+        smsTemplate.setTemplateContent(content);
+
+        this.smsTemplateManager.edit(smsTemplate, id);
+    }
+
+    @GetMapping(value = "/{id}/audit")
+    @ApiOperation(value = "提交审核")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键", required = true, dataType = "long", dataTypeClass = Long.class, paramType = "path"),
+            @ApiImplicitParam(name = "remark", value = "申请说明(描述业务使用场景)", required = true, dataType = "String", dataTypeClass = String.class, paramType = "query")
+    })
+    @Log(client = LogClient.admin, detail = "将ID为[${id}]的短信模板提交审核")
+    public void audit(@PathVariable Long id, @ApiIgnore String remark) {
+
+        if (remark.length() > 30) {
+            throw new ServiceException(SystemErrorCode.E931.code(), "申请说明不能超过30个字符");
+        }
+
+        this.smsTemplateManager.audit(id, remark);
+    }
+
+}

+ 53 - 0
module-erp/src/main/java/com/hys/app/controller/system/SystemLogsManagerController.java

@@ -0,0 +1,53 @@
+package com.hys.app.controller.system;
+
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.system.dos.SystemLogs;
+import com.hys.app.model.system.dto.SystemLogsParam;
+import com.hys.app.service.system.SystemLogsManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+/**
+ * 系统日志控制器
+ * @author fk
+ * @version v2.0
+ * @since v2.0
+ * 2021-03-22 16:05:59
+ */
+@RestController
+@RequestMapping("/admin/system-logs")
+@Api(description = "系统日志相关API")
+@Validated
+public class SystemLogsManagerController {
+	
+	@Autowired
+	private SystemLogsManager systemLogsManager;
+
+	@ApiOperation(value = "查询系统日志列表", response = SystemLogs.class)
+	@GetMapping
+	public WebPage<SystemLogs> list(@Valid SystemLogsParam param)	{
+		AdminUserContext.hasSuperAdminQuery(param.getCompanyId());
+		return	this.systemLogsManager.list(param,"admin");
+	}
+
+	@GetMapping(value =	"/{id}")
+	@ApiOperation(value = "查询一个系统日志", response = SystemLogs.class)
+	@ApiImplicitParams({
+			@ApiImplicitParam(name = "id", value = "要查询的系统日志主键", required = true, dataType = "int", paramType = "path")
+	})
+	public SystemLogs get(@PathVariable Long id)	{
+		SystemLogs systemLogs = this.systemLogsManager.getModel(id);
+		return	systemLogs;
+	}
+}

+ 54 - 0
module-erp/src/main/java/com/hys/app/controller/system/TaskController.java

@@ -0,0 +1,54 @@
+package com.hys.app.controller.system;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.system.dto.TaskQueryParams;
+import com.hys.app.model.system.vo.TaskVO;
+import com.hys.app.service.system.TaskManager;
+import com.hys.app.service.system.task.TaskExecutor;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 任务 API
+ *
+ * @author 张崧
+ * 2024-01-23 10:43:35
+ */
+@RestController
+@RequestMapping("/admin/systems/task")
+@Api(tags = "任务API")
+@Validated
+public class TaskController {
+
+    @Autowired
+    private TaskManager taskManager;
+
+    @Autowired
+    private TaskExecutor taskExecutor;
+
+    @ApiOperation(value = "分页列表")
+    @GetMapping
+    public WebPage<TaskVO> list(TaskQueryParams queryParams) {
+        return taskManager.list(queryParams);
+    }
+
+    @ApiOperation(value = "查询")
+    @GetMapping("/{id}")
+    public TaskVO getDetail(@PathVariable Long id) {
+        return taskManager.getDetail(id);
+    }
+
+    @ApiOperation(value = "终止")
+    @GetMapping("/{id}/stop")
+    public void stop(@PathVariable Long id) {
+        taskExecutor.stop(id);
+    }
+
+}
+

+ 76 - 0
module-erp/src/main/java/com/hys/app/controller/system/UploaderManagerController.java

@@ -0,0 +1,76 @@
+package com.hys.app.controller.system;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.support.LogClient;
+import com.hys.app.model.support.validator.annotation.Log;
+import com.hys.app.model.system.dos.UploaderDO;
+import com.hys.app.model.system.vo.UploaderVO;
+import com.hys.app.service.system.UploaderManager;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.constraints.NotEmpty;
+
+/**
+ * 存储方案控制器
+ *
+ * @author zh
+ * @version v7.0.0
+ * @since v7.0.0
+ * 2018-03-22 09:31:56
+ */
+@RestController
+@RequestMapping("/admin/systems/uploaders")
+@Api(description = "存储方案相关API")
+public class UploaderManagerController {
+
+    @Autowired
+    private UploaderManager uploaderManager;
+
+
+    @ApiOperation(value = "查询存储方案列表", response = UploaderDO.class)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page_no", value = "页码", required = true, dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "page_size", value = "每页显示数量", required = true, dataType = "int", paramType = "query")
+    })
+    @GetMapping
+    public WebPage list(@ApiIgnore @NotEmpty(message = "页码不能为空") Long pageNo, @ApiIgnore @NotEmpty(message = "每页数量不能为空") Long pageSize) {
+        return this.uploaderManager.list(pageNo, pageSize);
+    }
+
+    @ApiOperation(value = "修改存储方案参数", response = UploaderDO.class)
+    @PutMapping(value = "/{bean}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "bean", value = "存储方案bean id", required = true, dataType = "String", paramType = "path"),
+            @ApiImplicitParam(name = "uploader", value = "存储对象", required = true, dataType = "UploaderVO", paramType = "body")
+    })
+    @Log(client = LogClient.admin, detail = "修改bean id为[${bean}]的存储方案信息")
+    public UploaderVO edit(@PathVariable String bean, @RequestBody @ApiIgnore UploaderVO uploader) {
+        uploader.setBean(bean);
+        return this.uploaderManager.edit(uploader);
+    }
+
+    @ApiOperation(value = "开启某个存储方案", response = String.class)
+    @PutMapping("/{bean}/open")
+    @ApiImplicitParam(name = "bean", value = "bean", required = true, dataType = "String", paramType = "path")
+    @Log(client = LogClient.admin, detail = "开启bean id为[${bean}]的存储方案")
+    public String open(@PathVariable String bean) {
+        this.uploaderManager.openUploader(bean);
+        return null;
+    }
+
+
+    @ApiOperation(value = "获取存储方案的配置", response = String.class)
+    @GetMapping("/{bean}")
+    @ApiImplicitParam(name = "bean", value = "存储方案bean id", required = true, dataType = "String", paramType = "path")
+    public UploaderVO getUploadSetting(@PathVariable String bean) {
+        return this.uploaderManager.getUploadConfig(bean);
+    }
+
+
+}

+ 33 - 0
module-erp/src/main/java/com/hys/app/converter/erp/CollectingAccountConverter.java

@@ -0,0 +1,33 @@
+package com.hys.app.converter.erp;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dos.CollectingAccountDO;
+import com.hys.app.model.erp.dto.CollectingAccountDTO;
+import com.hys.app.model.erp.vo.CollectingAccountExcelVO;
+import com.hys.app.model.erp.vo.CollectingAccountVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+
+import java.util.List;
+
+/**
+ * 收款账户 Converter
+ *
+ * @author 张崧
+ * 2024-01-24 14:43:18
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface CollectingAccountConverter {
+
+    CollectingAccountDO convert(CollectingAccountDTO collectingAccountDTO);
+
+    CollectingAccountVO convert(CollectingAccountDO collectingAccountDO);
+
+    List<CollectingAccountVO> convertList(List<CollectingAccountDO> list);
+
+    List<CollectingAccountExcelVO> convertExcel(List<CollectingAccountVO> list);
+
+    WebPage<CollectingAccountVO> convertPage(WebPage<CollectingAccountDO> webPage);
+
+}
+

+ 21 - 0
module-erp/src/main/java/com/hys/app/converter/erp/CompanyConverter.java

@@ -0,0 +1,21 @@
+package com.hys.app.converter.erp;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.hys.app.model.erp.entity.*;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.factory.Mappers;
+
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface CompanyConverter {
+    CompanyConverter INSTANCE = Mappers.getMapper(CompanyConverter.class);
+
+    CompanyErp convert(CompanyDO bean);
+
+    void convert(@MappingTarget CompanyErp company , CompanyDO updateDO);
+
+    CompanyVO convert(CompanyErp bean);
+
+    Page<CompanyVO> convert(Page<CompanyErp> bean);
+}

+ 19 - 0
module-erp/src/main/java/com/hys/app/converter/erp/CompanyPackageConverter.java

@@ -0,0 +1,19 @@
+package com.hys.app.converter.erp;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.hys.app.model.erp.entity.CompanyPackage;
+import com.hys.app.model.erp.entity.CompanyPackageDO;
+import com.hys.app.model.erp.entity.CompanyPackageVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+import org.mapstruct.factory.Mappers;
+
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface CompanyPackageConverter {
+    CompanyPackageConverter INSTANCE = Mappers.getMapper(CompanyPackageConverter.class);
+
+    CompanyPackage convert(CompanyPackageDO bean);
+    CompanyPackageVO convert(CompanyPackage bean);
+    Page<CompanyPackageVO> convert(Page<CompanyPackage> bean);
+
+}

+ 31 - 0
module-erp/src/main/java/com/hys/app/converter/erp/CustomerConverter.java

@@ -0,0 +1,31 @@
+package com.hys.app.converter.erp;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dos.CustomerDO;
+import com.hys.app.model.erp.dos.PostDO;
+import com.hys.app.model.erp.dto.CustomerDTO;
+import com.hys.app.model.erp.dto.PostDTO;
+import com.hys.app.model.erp.vo.CustomerVO;
+import com.hys.app.model.erp.vo.PostVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+
+import java.util.List;
+
+/**
+ * 岗位 Convert
+ *
+ * @author 张崧
+ * 2023-11-29 17:15:22
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface CustomerConverter {
+    CustomerDO convert(CustomerDTO request);
+    
+    CustomerVO convert(CustomerDO request);
+    
+    WebPage<CustomerVO> convert(WebPage<CustomerDO> webPage);
+
+    List<CustomerVO> convert(List<CustomerDTO> list);
+}
+

+ 32 - 0
module-erp/src/main/java/com/hys/app/converter/erp/FinanceItemConverter.java

@@ -0,0 +1,32 @@
+package com.hys.app.converter.erp;
+
+import org.mapstruct.Mapper;
+import com.hys.app.model.erp.dos.FinanceItemDO;
+import com.hys.app.model.erp.vo.FinanceItemVO;
+import com.hys.app.model.erp.dto.FinanceItemDTO;
+import com.hys.app.model.erp.vo.FinanceItemExcelVO;
+import org.mapstruct.MappingConstants;
+import com.hys.app.framework.database.WebPage;
+import java.util.List;
+
+/**
+ * 财务明细 Converter
+ *
+ * @author 张崧
+ * 2024-03-15 17:40:23
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface FinanceItemConverter {
+    
+    FinanceItemDO convert(FinanceItemDTO financeItemDTO);
+    
+    FinanceItemVO convert(FinanceItemDO financeItemDO);
+    
+    List<FinanceItemVO> convertList(List<FinanceItemDO> list);
+    
+    List<FinanceItemExcelVO> convertExcel(List<FinanceItemVO> list);
+    
+    WebPage<FinanceItemVO> convertPage(WebPage<FinanceItemDO> webPage);
+
+}
+

+ 19 - 0
module-erp/src/main/java/com/hys/app/converter/erp/MailSmsCompanyConverter.java

@@ -0,0 +1,19 @@
+package com.hys.app.converter.erp;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.hys.app.model.erp.dos.MailSmsCountDO;
+import com.hys.app.model.erp.vo.MailSmsCountVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+import org.mapstruct.factory.Mappers;
+
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface MailSmsCompanyConverter {
+    MailSmsCompanyConverter INSTANCE = Mappers.getMapper(MailSmsCompanyConverter.class);
+
+    MailSmsCountVO convert(MailSmsCountDO bean);
+
+
+    Page<MailSmsCountVO> convert(Page<MailSmsCountDO> page);
+
+}

+ 39 - 0
module-erp/src/main/java/com/hys/app/converter/erp/MarketingManagerConverter.java

@@ -0,0 +1,39 @@
+package com.hys.app.converter.erp;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+import com.hys.app.model.erp.dos.MarketingManagerDO;
+import com.hys.app.model.erp.vo.MarketingManagerVO;
+import com.hys.app.model.erp.dto.MarketingManagerDTO;
+import com.hys.app.framework.database.WebPage;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 营销经理 Convert
+ *
+ * @author 张崧
+ * @since 2023-12-11 11:25:31
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface MarketingManagerConverter {
+
+    MarketingManagerDO convert(MarketingManagerDTO marketingManagerDTO);
+    
+    MarketingManagerVO convert(MarketingManagerDO marketingManagerDO);
+    
+    List<MarketingManagerVO> convert(List<MarketingManagerDO> list);
+    
+    WebPage<MarketingManagerVO> convert(WebPage<MarketingManagerDO> webPage);
+
+    default WebPage<MarketingManagerVO> combination(WebPage<MarketingManagerDO> webPage, Map<Long, String> deptNameMap){
+        WebPage<MarketingManagerVO> page = convert(webPage);
+
+        for (MarketingManagerVO marketingManagerVO : page.getData()) {
+            marketingManagerVO.setDeptName(deptNameMap.get(marketingManagerVO.getDeptId()));
+        }
+
+        return page;
+    }
+}
+

+ 34 - 0
module-erp/src/main/java/com/hys/app/converter/erp/MemberConverter.java

@@ -0,0 +1,34 @@
+package com.hys.app.converter.erp;
+
+import com.hys.app.model.erp.dto.MemberExcelImport;
+import org.mapstruct.Mapper;
+import com.hys.app.model.erp.dos.MemberDO;
+import com.hys.app.model.erp.vo.MemberVO;
+import com.hys.app.model.erp.dto.MemberDTO;
+import com.hys.app.model.erp.vo.MemberExcelVO;
+import org.mapstruct.MappingConstants;
+import com.hys.app.framework.database.WebPage;
+import java.util.List;
+
+/**
+ * 会员 Converter
+ *
+ * @author 张崧
+ * 2024-01-23 09:28:16
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface MemberConverter {
+    
+    MemberDO convert(MemberDTO memberDTO);
+    
+    MemberVO convert(MemberDO memberDO);
+    
+    List<MemberVO> convertList(List<MemberDO> list);
+    
+    List<MemberExcelVO> convertExcel(List<MemberVO> list);
+    
+    WebPage<MemberVO> convertPage(WebPage<MemberDO> webPage);
+
+    List<MemberDO> convertImportList(List<MemberExcelImport> importList);
+}
+

+ 30 - 0
module-erp/src/main/java/com/hys/app/converter/erp/MenusConverter.java

@@ -0,0 +1,30 @@
+package com.hys.app.converter.erp;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dos.PostDO;
+import com.hys.app.model.erp.dto.PostDTO;
+import com.hys.app.model.erp.vo.PostVO;
+import com.hys.app.model.system.dos.Menu;
+import com.hys.app.model.system.vo.MenuVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+
+import java.util.List;
+
+/**
+ * 岗位 Convert
+ *
+ * @author 张崧
+ * 2023-11-29 17:15:22
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface MenusConverter {
+    MenuVO convert(Menu postDTO);
+    
+    PostVO convert(PostDO postDO);
+    
+    WebPage<PostVO> convert(WebPage<PostDO> webPage);
+
+    List<PostVO> convert(List<PostDO> list);
+}
+

+ 26 - 0
module-erp/src/main/java/com/hys/app/converter/erp/NoGenerateRuleConverter.java

@@ -0,0 +1,26 @@
+package com.hys.app.converter.erp;
+
+import com.hys.app.model.erp.vo.NoGenerateRuleVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+import com.hys.app.model.erp.dos.NoGenerateRuleDO;
+import com.hys.app.model.erp.dto.NoGenerateRuleDTO;
+import com.hys.app.framework.database.WebPage;
+
+/**
+ * 编号生成规则 Convert
+ *
+ * @author 张崧
+ * 2023-12-01 11:37:56
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface NoGenerateRuleConverter {
+
+    NoGenerateRuleDO convert(NoGenerateRuleDTO noGenerateRuleDTO);
+    
+    NoGenerateRuleVO convert(NoGenerateRuleDO noGenerateRuleDO);
+    
+    WebPage<NoGenerateRuleVO> convert(WebPage<NoGenerateRuleDO> webPage);
+    
+}
+

+ 89 - 0
module-erp/src/main/java/com/hys/app/converter/erp/OrderConverter.java

@@ -0,0 +1,89 @@
+package com.hys.app.converter.erp;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dos.*;
+import com.hys.app.model.erp.dto.OrderDTO;
+import com.hys.app.model.erp.enums.OrderStatusEnum;
+import com.hys.app.model.erp.enums.OrderTypeEnum;
+import com.hys.app.model.erp.vo.OrderExcelVO;
+import com.hys.app.model.erp.vo.OrderItemVO;
+import com.hys.app.model.erp.vo.OrderVO;
+import com.hys.app.service.kuaidiniao.entity.PreOrderModel;
+import com.hys.app.service.kuaidiniao.entity.PreOrderModelDTO;
+import com.hys.app.service.kuaidiniao.entity.ReceiverSender;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingConstants;
+import org.mapstruct.MappingTarget;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 订单 Converter
+ *
+ * @author 张崧
+ * 2024-01-24 15:58:31
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface OrderConverter {
+
+    OrderDO convert(OrderDTO orderDTO);
+
+    List<OrderVO> convertList(List<OrderDO> list);
+
+    WebPage<OrderVO> convertPage(WebPage<OrderDO> webPage);
+
+    default OrderStatusEnum convertAuditStatus(Boolean isPass, OrderTypeEnum type) {
+        if (isPass) {
+            return type == OrderTypeEnum.TO_C ? OrderStatusEnum.COMPLETE : OrderStatusEnum.WAIT_WAREHOUSE_OUT;
+        } else {
+            return OrderStatusEnum.AUDIT_REJECT;
+        }
+    }
+
+    @Mapping(target = "aDo.receiverProvinceName", source = "receiver.provinceName")
+    @Mapping(target = "aDo.receiverCityName", source = "receiver.cityName")
+    @Mapping(target = "aDo.receiverAreaName", source = "receiver.areaName")
+    @Mapping(target = "aDo.receiverAddress", source = "receiver.address")
+    @Mapping(target = "aDo.receiverName", source = "receiver.name")
+    @Mapping(target = "aDo.receiverPhone", source = "receiver.phone")
+    @Mapping(target = "aDo.receiverMobile", source = "receiver.mobile")
+    @Mapping(target = "aDo.receiverLatitude", source = "receiver.latitude")
+    @Mapping(target = "aDo.receiverLongitude", source = "receiver.longitude")
+    @Mapping(target = "aDo.senderProvinceName", source = "sender.provinceName")
+    @Mapping(target = "aDo.senderCityName", source = "sender.cityName")
+    @Mapping(target = "aDo.senderAreaName", source = "sender.areaName")
+    @Mapping(target = "aDo.senderAddress", source = "sender.address")
+    @Mapping(target = "aDo.senderName", source = "sender.name")
+    @Mapping(target = "aDo.senderMobile", source = "sender.mobile")
+    @Mapping(target = "aDo.senderPhone", source = "sender.phone")
+    @Mapping(target = "aDo.senderLatitude", source = "sender.latitude")
+    @Mapping(target = "aDo.senderLongitude", source = "sender.longitude")
+    @Mapping(target = "aDo.deleted", ignore = true)
+    void copyProperties(@MappingTarget OrderSendDO aDo, PreOrderModelDTO preOrderModel, ReceiverSender receiver, ReceiverSender sender);
+
+
+
+//    @Mapping(target = "preOrderModel.sender.longitude", source = "aDo.senderLongitude")
+//    @Mapping(target = "preOrderModel.sender.latitude", source = "aDo.senderLatitude")
+//    @Mapping(target = "preOrderModel.sender.phone", source = "aDo.senderPhone")
+//    @Mapping(target = "preOrderModel.sender.mobile", source = "aDo.senderMobile")
+//    @Mapping(target = "preOrderModel.sender.name", source = "aDo.senderName")
+//    @Mapping(target = "preOrderModel.sender.address", source = "aDo.senderAddress")
+//    @Mapping(target = "preOrderModel.sender.areaName", source = "aDo.senderAreaName")
+//    @Mapping(target = "preOrderModel.sender.cityName", source = "aDo.senderCityName")
+//    @Mapping(target = "preOrderModel.sender.provinceName", source = "aDo.senderProvinceName")
+//    @Mapping(target = "preOrderModel.receiver.longitude", source = "aDo.receiverLongitude")
+//    @Mapping(target = "preOrderModel.receiver.latitude", source = "aDo.receiverLatitude")
+//    @Mapping(target = "preOrderModel.receiver.mobile", source = "aDo.receiverMobile")
+//    @Mapping(target = "preOrderModel.receiver.phone", source = "aDo.receiverPhone")
+//    @Mapping(target = "preOrderModel.receiver.name", source = "aDo.receiverName")
+//    @Mapping(target = "preOrderModel.receiver.address", source = "aDo.receiverAddress")
+//    @Mapping(target = "preOrderModel.receiver.areaName", source = "aDo.receiverAreaName")
+//    @Mapping(target = "preOrderModel.receiver.cityName", source = "aDo.receiverCityName")
+//    @Mapping(target = "preOrderModel.receiver.provinceName", source = "aDo.receiverProvinceName")
+//    void copyProperties(@MappingTarget PreOrderModel preOrderModel, OrderSendDO aDo);
+}
+

+ 48 - 0
module-erp/src/main/java/com/hys/app/converter/erp/OrderItemConverter.java

@@ -0,0 +1,48 @@
+package com.hys.app.converter.erp;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dos.OrderItemDO;
+import com.hys.app.model.erp.dto.OrderItemDTO;
+import com.hys.app.model.erp.dto.StockUpdateDTO;
+import com.hys.app.model.erp.enums.StockOperateEnum;
+import com.hys.app.model.erp.vo.OrderItemExcelVO;
+import com.hys.app.model.erp.vo.OrderItemVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 订单明细 Converter
+ *
+ * @author 张崧
+ * 2024-01-24 16:39:38
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface OrderItemConverter {
+
+    OrderItemDO convert(OrderItemDTO orderItemDTO);
+
+    OrderItemVO convert(OrderItemDO orderItemDO);
+
+    List<OrderItemVO> convertList(List<OrderItemDO> list);
+
+    List<OrderItemExcelVO> convertExcel(List<OrderItemVO> list);
+
+    WebPage<OrderItemVO> convertPage(WebPage<OrderItemDO> webPage);
+
+    default List<StockUpdateDTO> convertStockUpdate(List<OrderItemDO> itemList){
+        return itemList.stream().map(orderItemDO -> {
+            StockUpdateDTO stockUpdateDTO = new StockUpdateDTO();
+
+            stockUpdateDTO.setBatchId(orderItemDO.getBatchId());
+            stockUpdateDTO.setOperate(StockOperateEnum.Reduce);
+            stockUpdateDTO.setTip(orderItemDO.getProductName());
+            stockUpdateDTO.setChangeNum(orderItemDO.getNum());
+
+            return stockUpdateDTO;
+        }).collect(Collectors.toList());
+    }
+}
+

+ 54 - 0
module-erp/src/main/java/com/hys/app/converter/erp/OrderReturnConverter.java

@@ -0,0 +1,54 @@
+package com.hys.app.converter.erp;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingConstants;
+import com.hys.app.model.erp.dos.OrderReturnDO;
+import com.hys.app.model.erp.vo.OrderReturnVO;
+import com.hys.app.model.erp.dto.OrderReturnDTO;
+import com.hys.app.framework.database.WebPage;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 订单退货 Convert
+ *
+ * @author 张崧
+ * @since 2023-12-14 15:42:07
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface OrderReturnConverter {
+    OrderReturnDO convert(OrderReturnDTO orderReturnDTO);
+
+
+    OrderReturnVO convert(OrderReturnDO orderReturnDO);
+    
+    List<OrderReturnVO> convert(List<OrderReturnDO> list);
+    
+    WebPage<OrderReturnVO> convert(WebPage<OrderReturnDO> webPage);
+
+    default WebPage<OrderReturnVO> combination(WebPage<OrderReturnDO> webPage, Map<Long, String> deptNameMap, Map<Long, String> warehouseNameMap){
+        WebPage<OrderReturnVO> page = convert(webPage);
+
+        for (OrderReturnVO orderReturnVO : page.getData()) {
+            orderReturnVO.setDeptName(deptNameMap.get(orderReturnVO.getDeptId()));
+            orderReturnVO.setWarehouseName(warehouseNameMap.get(orderReturnVO.getWarehouseId()));
+        }
+
+        return page;
+    }
+
+    default OrderReturnDO combination(OrderReturnDTO orderReturnDTO){
+        OrderReturnDO orderReturnDO = convert(orderReturnDTO);
+
+//        orderReturnDO.setDistributionName(orderReturnDTO.getOrderDO().getMarketingName());
+//        orderReturnDO.setDeptName(orderReturnDTO.getDeptDO().getName());
+//        orderReturnDO.setWarehouseName(orderReturnDTO.getWarehouseDO().getName());
+//        orderReturnDO.setHandleByName(orderReturnDTO.getHandleBy().getRealName());
+//        orderReturnDO.setOrderSn(orderReturnDTO.getOrderDO().getSn());
+//        orderReturnDO.setOrderType(orderReturnDTO.getOrderDO().getType());
+
+        return orderReturnDO;
+    }
+}
+

+ 28 - 0
module-erp/src/main/java/com/hys/app/converter/erp/PostConverter.java

@@ -0,0 +1,28 @@
+package com.hys.app.converter.erp;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+import com.hys.app.model.erp.dos.PostDO;
+import com.hys.app.model.erp.vo.PostVO;
+import com.hys.app.model.erp.dto.PostDTO;
+import com.hys.app.framework.database.WebPage;
+
+import java.util.List;
+
+/**
+ * 岗位 Convert
+ *
+ * @author 张崧
+ * 2023-11-29 17:15:22
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface PostConverter {
+    PostDO convert(PostDTO postDTO);
+    
+    PostVO convert(PostDO postDO);
+    
+    WebPage<PostVO> convert(WebPage<PostDO> webPage);
+
+    List<PostVO> convert(List<PostDO> list);
+}
+

+ 29 - 0
module-erp/src/main/java/com/hys/app/converter/erp/ProductStockConverter.java

@@ -0,0 +1,29 @@
+package com.hys.app.converter.erp;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dos.ProductStockDO;
+import com.hys.app.model.erp.dto.ProductStockIncreaseDTO;
+import com.hys.app.model.erp.dto.ProductStockReduceDTO;
+import com.hys.app.model.erp.vo.ProductStockVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+
+/**
+ * 商品库存 Convert
+ *
+ * @author 张崧
+ * @since 2023-12-07 10:08:44
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface ProductStockConverter {
+    ProductStockVO convert(ProductStockDO productStockDO);
+
+    WebPage<ProductStockVO> convert(WebPage<ProductStockDO> webPage);
+
+    Page<ProductStockVO> convert(Page<ProductStockDO> Page);
+
+    ProductStockIncreaseDTO convert(ProductStockReduceDTO stockReduceDTO);
+}
+

+ 21 - 0
module-erp/src/main/java/com/hys/app/converter/erp/SmsMailConverter.java

@@ -0,0 +1,21 @@
+package com.hys.app.converter.erp;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+import com.hys.app.model.erp.dos.SmsMailTemplate;
+import com.hys.app.model.erp.dto.SmsMailTemplateDTO;
+import com.hys.app.model.erp.vo.SmsMailTemplateVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+import org.mapstruct.factory.Mappers;
+
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface SmsMailConverter {
+    SmsMailConverter INSTANCE = Mappers.getMapper(SmsMailConverter.class);
+
+    SmsMailTemplate convert(SmsMailTemplateDTO dto);
+
+    SmsMailTemplateVO convert(SmsMailTemplate dto);
+   Page<SmsMailTemplateVO> convert(Page<SmsMailTemplate> dto);
+
+}

+ 52 - 0
module-erp/src/main/java/com/hys/app/converter/erp/StockTransferConverter.java

@@ -0,0 +1,52 @@
+package com.hys.app.converter.erp;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.framework.util.DateUtil;
+import com.hys.app.model.erp.dos.StockTransferDO;
+import com.hys.app.model.erp.dos.StockTransferProductDO;
+import com.hys.app.model.erp.dto.StockTransferDTO;
+import com.hys.app.model.erp.dto.StockUpdateDTO;
+import com.hys.app.model.erp.enums.NoBusinessTypeEnum;
+import com.hys.app.model.erp.enums.StockOperateEnum;
+import com.hys.app.model.erp.vo.StockTransferVO;
+import com.hys.app.service.erp.NoGenerateManager;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 库存调拨 Convert
+ *
+ * @author 张崧
+ * @since 2023-12-12 11:59:06
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface StockTransferConverter {
+
+    StockTransferDO convert(StockTransferDTO stockTransferDTO);
+
+    StockTransferVO convert(StockTransferDO stockTransferDO);
+
+    List<StockTransferVO> convert(List<StockTransferDO> list);
+
+    WebPage<StockTransferVO> convert(WebPage<StockTransferDO> webPage);
+
+    default List<StockUpdateDTO> convertStockUpdateList(List<StockTransferProductDO> transferProductList) {
+        return transferProductList.stream().map(transferProductDO -> {
+            StockUpdateDTO stockUpdateDTO = new StockUpdateDTO();
+
+            stockUpdateDTO.setBatchId(transferProductDO.getWarehouseEntryBatchId());
+            stockUpdateDTO.setTip(transferProductDO.getProductName());
+            stockUpdateDTO.setOperate(StockOperateEnum.Reduce);
+            stockUpdateDTO.setChangeNum(transferProductDO.getNum());
+
+            return stockUpdateDTO;
+        }).collect(Collectors.toList());
+    }
+
+
+
+}
+

+ 29 - 0
module-erp/src/main/java/com/hys/app/converter/erp/StockTransferProductConverter.java

@@ -0,0 +1,29 @@
+package com.hys.app.converter.erp;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dos.StockTransferProductDO;
+import com.hys.app.model.erp.dto.StockTransferProductDTO;
+import com.hys.app.model.erp.vo.StockTransferProductVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+
+import java.util.List;
+
+/**
+ * 调拨单商品明细 Convert
+ *
+ * @author 张崧
+ * @since 2023-12-12 16:34:15
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface StockTransferProductConverter {
+
+    StockTransferProductDO convert(StockTransferProductDTO stockTransferProductDTO);
+    
+    StockTransferProductVO convert(StockTransferProductDO stockTransferProductDO);
+    
+    List<StockTransferProductVO> convert(List<StockTransferProductDO> list);
+    
+    WebPage<StockTransferProductVO> convert(WebPage<StockTransferProductDO> webPage);
+}
+

+ 29 - 0
module-erp/src/main/java/com/hys/app/converter/erp/StoreConverter.java

@@ -0,0 +1,29 @@
+package com.hys.app.converter.erp;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+import com.hys.app.model.erp.dos.StoreDO;
+import com.hys.app.model.erp.vo.StoreVO;
+import com.hys.app.model.erp.dto.StoreDTO;
+import com.hys.app.framework.database.WebPage;
+import java.util.List;
+
+/**
+ * 门店 Convert
+ *
+ * @author 张崧
+ * @since 2023-12-11 17:47:09
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface StoreConverter {
+
+    StoreDO convert(StoreDTO storeDTO);
+    
+    StoreVO convert(StoreDO storeDO);
+    
+    List<StoreVO> convert(List<StoreDO> list);
+    
+    WebPage<StoreVO> convert(WebPage<StoreDO> webPage);
+    
+}
+

+ 68 - 0
module-erp/src/main/java/com/hys/app/converter/erp/SupplierSettlementItemConverter.java

@@ -0,0 +1,68 @@
+package com.hys.app.converter.erp;
+
+import com.hys.app.framework.util.CurrencyUtil;
+import com.hys.app.model.erp.dos.WarehouseEntryDO;
+import com.hys.app.model.erp.dos.WarehouseEntryProductDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+import com.hys.app.model.erp.dos.SupplierSettlementItemDO;
+import com.hys.app.model.erp.vo.SupplierSettlementItemVO;
+import com.hys.app.model.erp.dto.SupplierSettlementItemDTO;
+import com.hys.app.framework.database.WebPage;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 供应商结算单明细 Convert
+ *
+ * @author 张崧
+ * @since 2023-12-15 14:09:20
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface SupplierSettlementItemConverter {
+
+    SupplierSettlementItemDO convert(SupplierSettlementItemDTO supplierSettlementItemDTO);
+    
+    SupplierSettlementItemVO convert(SupplierSettlementItemDO supplierSettlementItemDO);
+    
+    List<SupplierSettlementItemVO> convert(List<SupplierSettlementItemDO> list);
+    
+    WebPage<SupplierSettlementItemVO> convert(WebPage<SupplierSettlementItemDO> webPage);
+
+    default List<SupplierSettlementItemDO> combination(List<WarehouseEntryDO> warehouseEntryList, Map<Long, List<WarehouseEntryProductDO>> warehouseEntryProductMap){
+        List<SupplierSettlementItemDO> itemList = new ArrayList<>();
+        // 循环入库单
+        for (WarehouseEntryDO warehouseEntryDO : warehouseEntryList) {
+            List<WarehouseEntryProductDO> entryProductList = warehouseEntryProductMap.get(warehouseEntryDO.getId());
+            // 循环入库单的商品
+            for (WarehouseEntryProductDO entryProductDO : entryProductList) {
+                SupplierSettlementItemDO supplierSettlementItemDO = new SupplierSettlementItemDO();
+
+                supplierSettlementItemDO.setWarehouseEntryId(warehouseEntryDO.getId());
+                supplierSettlementItemDO.setWarehouseEntrySn(warehouseEntryDO.getSn());
+                supplierSettlementItemDO.setWarehouseEntryItemId(entryProductDO.getId());
+                supplierSettlementItemDO.setGoodsId(entryProductDO.getGoodsId());
+                supplierSettlementItemDO.setProductId(entryProductDO.getProductId());
+                supplierSettlementItemDO.setProductSn(entryProductDO.getSn());
+                supplierSettlementItemDO.setProductName(entryProductDO.getName());
+                supplierSettlementItemDO.setProductSpecification(entryProductDO.getSpecification());
+                supplierSettlementItemDO.setProductUnit(entryProductDO.getUnit());
+                supplierSettlementItemDO.setProductBarcode(entryProductDO.getProductBarcode());
+                supplierSettlementItemDO.setCategoryId(entryProductDO.getCategoryId());
+                supplierSettlementItemDO.setCategoryName(entryProductDO.getCategoryName());
+                supplierSettlementItemDO.setProductPrice(entryProductDO.getContractPrice());
+                supplierSettlementItemDO.setProductCostPrice(entryProductDO.getCostPrice());
+                supplierSettlementItemDO.setTaxRate(entryProductDO.getTaxRate());
+                supplierSettlementItemDO.setProductNum(entryProductDO.getNum() - (entryProductDO.getReturnNum()==null?0:entryProductDO.getReturnNum()));
+                supplierSettlementItemDO.setTotalPrice(CurrencyUtil.mul(entryProductDO.getContractPrice(), supplierSettlementItemDO.getProductNum()));
+
+                itemList.add(supplierSettlementItemDO);
+            }
+        }
+
+        return itemList;
+    }
+}
+

+ 34 - 0
module-erp/src/main/java/com/hys/app/converter/erp/UserMenuConverter.java

@@ -0,0 +1,34 @@
+package com.hys.app.converter.erp;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dos.UserMenuDO;
+import com.hys.app.model.erp.dto.UserMenuDto;
+import com.hys.app.model.erp.vo.UserMenuVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+
+import java.util.List;
+
+import static com.hys.app.framework.util.CollectionUtils.convertMap;
+
+/**
+ * 商品 Convert
+ *
+ * @author 张崧
+ * 2023-12-26 15:56:58
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface UserMenuConverter {
+
+    UserMenuDO convert(UserMenuDto request);
+
+    UserMenuDto convert(UserMenuDO request);
+
+
+
+    List<UserMenuVO> convert(List<UserMenuDto> list);
+
+    WebPage<UserMenuDto> convert(WebPage<UserMenuDO> webPage);
+
+}
+

+ 33 - 0
module-erp/src/main/java/com/hys/app/converter/erp/WarehouseAreaConverter.java

@@ -0,0 +1,33 @@
+package com.hys.app.converter.erp;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dos.*;
+import com.hys.app.model.erp.dto.WarehouseOutDTO;
+import com.hys.app.model.erp.vo.WarehouseAreaVO;
+import com.hys.app.model.erp.vo.WarehouseOutItemVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 出库单商品明细 Convert
+ *
+ * @author 张崧
+ * @since 2023-12-07 17:06:32
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface WarehouseAreaConverter {
+
+
+    List<WarehouseAreaVO> convert(List<WarehouseAreaDO> list);
+
+    WebPage<WarehouseAreaVO> convert(WebPage<WarehouseAreaDO> webPage);
+
+    WarehouseAreaVO convert(WarehouseAreaDO warehouseAreaDO);
+
+    WarehouseAreaDO convert(WarehouseAreaVO warehouseAreaVO);
+
+}
+

+ 32 - 0
module-erp/src/main/java/com/hys/app/converter/erp/WarehouseConverter.java

@@ -0,0 +1,32 @@
+package com.hys.app.converter.erp;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dos.WarehouseDO;
+import com.hys.app.model.erp.dto.WarehouseDTO;
+import com.hys.app.model.erp.vo.WarehouseVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 仓库 Convert
+ *
+ * @author 张崧
+ * 2023-11-30 16:35:16
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface WarehouseConverter {
+
+    WarehouseDO convert(WarehouseDTO warehouseDTO);
+
+    WarehouseVO convert(WarehouseDO warehouseDO);
+
+    WebPage<WarehouseVO> convert(WebPage<WarehouseDO> webPage);
+
+    List<WarehouseVO> convert(List<WarehouseDO> list);
+
+    }
+
+

+ 64 - 0
module-erp/src/main/java/com/hys/app/converter/erp/WarehouseEntryProductConverter.java

@@ -0,0 +1,64 @@
+package com.hys.app.converter.erp;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.framework.util.CurrencyUtil;
+import com.hys.app.model.erp.dos.ProcurementContractProduct;
+import com.hys.app.model.erp.dos.WarehouseEntryProductDO;
+import com.hys.app.model.erp.dto.WarehouseEntryProductDTO;
+import com.hys.app.model.erp.vo.WarehouseEntryProductVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 入库单商品明细 Convert
+ *
+ * @author 张崧
+ * @since 2023-12-05 15:30:10
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface WarehouseEntryProductConverter {
+
+    WarehouseEntryProductDO convert(WarehouseEntryProductDTO warehouseEntryProductDTO);
+
+    WarehouseEntryProductVO convert(WarehouseEntryProductDO warehouseEntryProductDO);
+
+    List<WarehouseEntryProductVO> convert(List<WarehouseEntryProductDO> list);
+
+    WebPage<WarehouseEntryProductVO> convert(WebPage<WarehouseEntryProductDO> webPage);
+
+    default List<WarehouseEntryProductDO> combination(List<WarehouseEntryProductDTO> dtolist, Long warehouseEntryId, List<ProcurementContractProduct> contractProductList, Double priceRatio) {
+        List<WarehouseEntryProductDO> list = new ArrayList<>();
+
+        for (WarehouseEntryProductDTO warehouseEntryProductDTO : dtolist) {
+            // 合同商品信息
+            for (ProcurementContractProduct procurementContractProduct : contractProductList) {
+                if(procurementContractProduct.getGoodsId().equals(warehouseEntryProductDTO.getProductId())) {
+                    WarehouseEntryProductDO entryProductDO = convert(warehouseEntryProductDTO);
+                    entryProductDO.setWarehouseEntryId(warehouseEntryId);
+                    entryProductDO.setGoodsId(procurementContractProduct.getGoodsId());
+                    entryProductDO.setSn(procurementContractProduct.getProductSn());
+                    entryProductDO.setName(procurementContractProduct.getProductName());
+                    entryProductDO.setSpecification(procurementContractProduct.getSpecification());
+                    entryProductDO.setUnit(procurementContractProduct.getUnit());
+                    entryProductDO.setProductBarcode(procurementContractProduct.getBarcode());
+                    entryProductDO.setCategoryId(procurementContractProduct.getCategoryId());
+                    entryProductDO.setCategoryName(procurementContractProduct.getCategoryName());
+                    entryProductDO.setContractNum(procurementContractProduct.getNum());
+                    entryProductDO.setContractPrice(procurementContractProduct.getPrice());
+                    entryProductDO.setCostPrice(CurrencyUtil.mul(procurementContractProduct.getPrice(), priceRatio));
+                    entryProductDO.setTotalPrice(CurrencyUtil.mul(entryProductDO.getCostPrice(), entryProductDO.getNum()));
+                    entryProductDO.setTaxRate(procurementContractProduct.getTaxRate());
+                    list.add(entryProductDO);
+                }
+            }
+
+        }
+
+        return list;
+    }
+}
+

+ 79 - 0
module-erp/src/main/java/com/hys/app/converter/erp/WarehouseOutConverter.java

@@ -0,0 +1,79 @@
+package com.hys.app.converter.erp;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dos.*;
+import com.hys.app.model.erp.dto.StockUpdateDTO;
+import com.hys.app.model.erp.dto.WarehouseOutDTO;
+import com.hys.app.model.erp.enums.StockOperateEnum;
+import com.hys.app.model.erp.vo.WarehouseOutAllowable;
+import com.hys.app.model.erp.vo.WarehouseOutVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingConstants;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static com.hys.app.framework.util.CollectionUtils.convertList;
+import static com.hys.app.framework.util.CollectionUtils.convertMap;
+
+/**
+ * 出库单 Convert
+ *
+ * @author 张崧
+ * @since 2023-12-07 16:50:20
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface WarehouseOutConverter {
+
+    WarehouseOutDO convert(WarehouseOutDTO warehouseOutDTO);
+
+    WarehouseOutVO convert(WarehouseOutDO warehouseOutDO);
+
+    List<WarehouseOutVO> convert(List<WarehouseOutDO> warehouseOutDO);
+
+    default WebPage<WarehouseOutVO> convert(WebPage<WarehouseOutDO> webPage){
+        List<WarehouseOutVO> convert = convert(webPage.getData());
+        WebPage<WarehouseOutVO> resPage = new WebPage();
+        resPage.setData(convert);
+        resPage.setPageNo(webPage.getPageNo());
+        resPage.setPageSize(webPage.getPageSize());
+        resPage.setDataTotal(webPage.getDataTotal());
+        return resPage;
+    };
+
+    default WebPage<WarehouseOutVO> combination(WebPage<WarehouseOutDO> webPage, Map<Long, String> deptNameMap, Map<Long, String> warehouseNameMap) {
+        WebPage<WarehouseOutVO> page = convert(webPage);
+
+        for (WarehouseOutVO warehouseOutVO : page.getData()) {
+            warehouseOutVO.setDeptName(deptNameMap.get(warehouseOutVO.getDeptId()));
+            warehouseOutVO.setWarehouseName(warehouseNameMap.get(warehouseOutVO.getWarehouseId()));
+        }
+
+        return page;
+    }
+
+    default WarehouseOutAllowable getAllowable(WarehouseOutDO warehouseOutDO){
+        return new WarehouseOutAllowable(warehouseOutDO);
+    }
+
+    default List<StockUpdateDTO> convertStockUpdateList(List<WarehouseOutItemDO> itemList){
+        return itemList.stream().map(warehouseOutItemDO -> {
+            StockUpdateDTO stockUpdateDTO = new StockUpdateDTO();
+
+            stockUpdateDTO.setBatchId(warehouseOutItemDO.getWarehouseEntryBatchId());
+            stockUpdateDTO.setTip(warehouseOutItemDO.getWarehouseEntryBatchSn());
+            stockUpdateDTO.setOperate(StockOperateEnum.Reduce);
+            stockUpdateDTO.setChangeNum(warehouseOutItemDO.getOutNum());
+
+            return stockUpdateDTO;
+        }).collect(Collectors.toList());
+    }
+
+
+}
+

+ 26 - 0
module-erp/src/main/java/com/hys/app/converter/erp/WarehouseOutItemConverter.java

@@ -0,0 +1,26 @@
+package com.hys.app.converter.erp;
+
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.erp.dos.WarehouseOutItemDO;
+import com.hys.app.model.erp.vo.WarehouseOutItemVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+
+import java.util.List;
+
+/**
+ * 出库单商品明细 Convert
+ *
+ * @author 张崧
+ * @since 2023-12-07 17:06:32
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface WarehouseOutItemConverter {
+
+    WarehouseOutItemVO convert(WarehouseOutItemDO warehouseOutItemDO);
+
+    List<WarehouseOutItemVO> convert(List<WarehouseOutItemDO> list);
+
+    WebPage<WarehouseOutItemVO> convert(WebPage<WarehouseOutItemDO> webPage);
+}
+

+ 46 - 0
module-erp/src/main/java/com/hys/app/converter/system/DeptConverter.java

@@ -0,0 +1,46 @@
+package com.hys.app.converter.system;
+
+import com.hys.app.model.system.dto.DeptCreateDTO;
+import com.hys.app.model.system.vo.DeptRespVO;
+import com.hys.app.model.system.vo.DeptSimpleRespVO;
+import com.hys.app.model.system.dto.DeptUpdateDTO;
+import com.hys.app.model.base.context.Region;
+import com.hys.app.model.system.dos.DeptDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+
+import java.util.Arrays;
+import java.util.List;
+
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface DeptConverter {
+
+    List<DeptRespVO> convertList(List<DeptDO> list);
+
+    List<DeptSimpleRespVO> convertList02(List<DeptDO> list);
+
+    DeptRespVO convert(DeptDO bean);
+
+    DeptDO convert(DeptCreateDTO bean);
+
+    DeptDO convert(DeptUpdateDTO bean);
+
+    default DeptDO convert(DeptCreateDTO reqVO, Region region){
+        DeptDO deptDO = convert(reqVO);
+
+        deptDO.setRegionIds(Arrays.asList(region.getProvinceId(), region.getCityId(), region.getCountyId(), region.getTownId()));
+        deptDO.setRegionNames(Arrays.asList(region.getProvince(), region.getCity(), region.getCounty(), region.getCounty()));
+
+        return deptDO;
+    }
+
+    default DeptDO convert(DeptUpdateDTO reqVO, Region region){
+        DeptDO deptDO = convert(reqVO);
+
+        deptDO.setRegionIds(Arrays.asList(region.getProvinceId(), region.getCityId(), region.getCountyId(), region.getTownId()));
+        deptDO.setRegionNames(Arrays.asList(region.getProvince(), region.getCity(), region.getCounty(), region.getCounty()));
+
+        return deptDO;
+    }
+
+}

+ 27 - 0
module-erp/src/main/java/com/hys/app/converter/system/DictDataConverter.java

@@ -0,0 +1,27 @@
+package com.hys.app.converter.system;
+
+import com.hys.app.model.system.dto.DictDataCreateDTO;
+import com.hys.app.model.system.vo.DictDataRespVO;
+import com.hys.app.model.system.vo.DictDataSimpleRespVO;
+import com.hys.app.model.system.dto.DictDataUpdateDTO;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.system.dos.DictDataDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+
+import java.util.List;
+
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface DictDataConverter {
+
+    List<DictDataSimpleRespVO> convertList(List<DictDataDO> list);
+
+    DictDataRespVO convert(DictDataDO bean);
+
+    WebPage<DictDataRespVO> convertPage(WebPage<DictDataDO> page);
+
+    DictDataDO convert(DictDataUpdateDTO bean);
+
+    DictDataDO convert(DictDataCreateDTO bean);
+
+}

+ 28 - 0
module-erp/src/main/java/com/hys/app/converter/system/DictTypeConverter.java

@@ -0,0 +1,28 @@
+package com.hys.app.converter.system;
+
+import com.hys.app.model.system.dto.DictTypeCreateDTO;
+import com.hys.app.model.system.vo.DictTypeRespVO;
+import com.hys.app.model.system.vo.DictTypeSimpleRespVO;
+import com.hys.app.model.system.dto.DictTypeUpdateDTO;
+import com.hys.app.framework.database.WebPage;
+import com.hys.app.model.system.dos.DictTypeDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+
+import java.util.List;
+
+
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface DictTypeConverter {
+
+    WebPage<DictTypeRespVO> convertPage(WebPage<DictTypeDO> bean);
+
+    DictTypeRespVO convert(DictTypeDO bean);
+
+    DictTypeDO convert(DictTypeCreateDTO bean);
+
+    DictTypeDO convert(DictTypeUpdateDTO bean);
+
+    List<DictTypeSimpleRespVO> convertList(List<DictTypeDO> list);
+
+}

+ 29 - 0
module-erp/src/main/java/com/hys/app/converter/system/TaskConverter.java

@@ -0,0 +1,29 @@
+package com.hys.app.converter.system;
+
+import org.mapstruct.Mapper;
+import com.hys.app.model.system.dos.TaskDO;
+import com.hys.app.model.system.vo.TaskVO;
+import com.hys.app.model.system.dto.TaskDTO;
+import org.mapstruct.MappingConstants;
+import com.hys.app.framework.database.WebPage;
+import java.util.List;
+
+/**
+ * 任务 Converter
+ *
+ * @author 张崧
+ * 2024-01-23 10:43:35
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+public interface TaskConverter {
+    
+    TaskDO convert(TaskDTO taskDTO);
+    
+    TaskVO convert(TaskDO taskDO);
+    
+    List<TaskVO> convertList(List<TaskDO> list);
+    
+    WebPage<TaskVO> convertPage(WebPage<TaskDO> webPage);
+    
+}
+

+ 42 - 0
module-erp/src/main/java/com/hys/app/framework/datapermission/DataPermissionTableCustomizer.java

@@ -0,0 +1,42 @@
+package com.hys.app.framework.datapermission;
+
+import com.hys.app.framework.datapermission.dept.DeptDataPermissionRuleCustomizer;
+import com.hys.app.model.erp.dos.*;
+import com.hys.app.model.system.dos.AdminUser;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 定制哪些表需要走数据权限
+ *
+ * @author 张崧
+ */
+@Configuration
+public class DataPermissionTableCustomizer {
+
+    @Bean
+    public DeptDataPermissionRuleCustomizer deptDataPermissionRuleCustomizer() {
+        return rule -> {
+            // 用户管理
+            rule.addDeptColumn(AdminUser.class);
+            // 仓库管理
+            rule.addDeptColumn(WarehouseDO.class);
+            // 入库单管理
+            rule.addDeptColumn(WarehouseEntryDO.class);
+            // 出库单管理
+            rule.addDeptColumn(WarehouseOutDO.class);
+
+            // 订单退货
+            rule.addDeptColumn(OrderReturnDO.class);
+            // 订单
+            rule.addDeptColumn(OrderDO.class);
+            // 库存报损单
+            rule.addDeptColumn(StockDamageReport.class);
+            // 库存盘点单
+            rule.addDeptColumn(StockInventory.class);
+            // 销售经理
+            rule.addDeptColumn(MarketingManagerDO.class);
+        };
+    }
+
+}

+ 27 - 0
module-erp/src/main/java/com/hys/app/framework/datapermission/dept/DeptDataPermissionConfiguration.java

@@ -0,0 +1,27 @@
+package com.hys.app.framework.datapermission.dept;
+
+import com.hys.app.service.system.RoleManager;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.List;
+
+/**
+ * 基于部门的数据权限 AutoConfiguration
+ *
+ * @author 张崧
+ */
+@Configuration
+public class DeptDataPermissionConfiguration {
+
+    @Bean
+    public DeptDataPermissionRule deptDataPermissionRule(RoleManager roleManager,
+                                                         List<DeptDataPermissionRuleCustomizer> customizers) {
+        // 创建 DeptDataPermissionRule 对象
+        DeptDataPermissionRule rule = new DeptDataPermissionRule(roleManager);
+        // 补全表配置
+        customizers.forEach(customizer -> customizer.customize(rule));
+        return rule;
+    }
+
+}

+ 177 - 0
module-erp/src/main/java/com/hys/app/framework/datapermission/dept/DeptDataPermissionRule.java

@@ -0,0 +1,177 @@
+package com.hys.app.framework.datapermission.dept;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
+import com.hys.app.framework.context.user.AdminUserContext;
+import com.hys.app.framework.datapermission.rule.DataPermissionRule;
+import com.hys.app.framework.security.model.Admin;
+import com.hys.app.framework.util.JsonUtil;
+import com.hys.app.model.system.dto.DataPermissionDTO;
+import com.hys.app.service.system.RoleManager;
+import com.hys.app.framework.util.CollectionUtils;
+import com.hys.app.framework.util.MyBatisPlusUtils;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import net.sf.jsqlparser.expression.*;
+import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
+import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
+import net.sf.jsqlparser.expression.operators.relational.InExpression;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 基于部门的 {@link DataPermissionRule} 数据权限规则实现
+ * 使用 DeptDataPermissionRule 时,需要保证表中有 dept_id 部门编号的字段,可自定义。
+ *
+ * @author 张崧
+ */
+@AllArgsConstructor
+@Slf4j
+public class DeptDataPermissionRule implements DataPermissionRule {
+
+    /**
+     * AdminUser 的 Context 缓存 Key
+     */
+    protected static final String CONTEXT_KEY = DeptDataPermissionRule.class.getSimpleName();
+
+    private static final String DEPT_COLUMN_NAME = "dept_id";
+    private static final String USER_COLUMN_NAME = "user_id";
+
+    static final Expression EXPRESSION_NULL = new NullValue();
+
+    private final RoleManager roleManager;
+
+    /**
+     * 基于部门的表字段配置
+     * 一般情况下,每个表的部门编号字段是 dept_id,通过该配置自定义。
+     *
+     * key:表名
+     * value:字段名
+     */
+    private final Map<String, String> deptColumns = new HashMap<>();
+    /**
+     * 基于用户的表字段配置
+     * 一般情况下,每个表的部门编号字段是 dept_id,通过该配置自定义。
+     *
+     * key:表名
+     * value:字段名
+     */
+    private final Map<String, String> userColumns = new HashMap<>();
+    /**
+     * 所有表名,是 {@link #deptColumns} 和 {@link #userColumns} 的合集
+     */
+    private final Set<String> TABLE_NAMES = new HashSet<>();
+
+    @Override
+    public Set<String> getTableNames() {
+        return TABLE_NAMES;
+    }
+
+    @Override
+    public Expression getExpression(String tableName, Alias tableAlias) {
+        // 只有有登陆用户的情况下,才进行数据权限的处理
+        Admin loginUser = AdminUserContext.getAdmin();
+        if (loginUser == null) {
+            return null;
+        }
+
+        // 超级管理员拥有所有数据权限
+        if(loginUser.getFounder() == 1){
+            return null;
+        }
+
+//        // 获得数据权限
+//        DataPermissionDTO deptDataPermission = loginUser.getContext(CONTEXT_KEY, DataPermissionDTO.class);
+//        // 从上下文中拿不到,则调用逻辑进行获取
+//        if (deptDataPermission == null) {
+//            deptDataPermission = roleManager.getDataPermission(loginUser.getUid());
+//            // 添加到上下文中,避免重复计算
+//            loginUser.setContext(CONTEXT_KEY, deptDataPermission);
+//        }
+//
+//        // 情况一,如果是 ALL 可查看全部,则无需拼接条件
+//        if (deptDataPermission.getAll()) {
+//            return null;
+//        }
+//
+//        // 情况二,即不能查看部门,又不能查看自己,则说明 100% 无权限
+//        if (CollUtil.isEmpty(deptDataPermission.getDeptIds())
+//            && Boolean.FALSE.equals(deptDataPermission.getSelf())) {
+//            return new EqualsTo(null, null); // WHERE null = null,可以保证返回的数据为空
+//        }
+//
+//        // 情况三,拼接 Dept 条件,最后组合
+//        Expression deptExpression = buildDeptExpression(tableName,tableAlias, deptDataPermission.getDeptIds());
+//        if (deptExpression == null) {
+//            log.warn("[getExpression][LoginUser({}) Table({}/{}) DeptDataPermission({}) 构建的条件为空]",
+//                    JsonUtil.objectToJson(loginUser), tableName, tableAlias, JsonUtil.objectToJson(deptDataPermission));
+//            return EXPRESSION_NULL;
+//        }
+//        return deptExpression;
+        return null;
+    }
+
+
+    private Expression buildDeptExpression(String tableName, Alias tableAlias, Set<Long> deptIds) {
+        // 如果不存在配置,则无需作为条件
+        String columnName = deptColumns.get(tableName);
+        if (StrUtil.isEmpty(columnName)) {
+            return null;
+        }
+        // 如果为空,则无条件
+        if (CollUtil.isEmpty(deptIds)) {
+            return null;
+        }
+        // 拼接条件
+        return new InExpression(MyBatisPlusUtils.buildColumn(tableName, tableAlias, columnName),
+                new ExpressionList(CollectionUtils.convertList(deptIds, LongValue::new)));
+    }
+
+    private Expression buildUserExpression(String tableName, Alias tableAlias, Boolean self, Long userId) {
+        // 如果不查看自己,则无需作为条件
+        if (Boolean.FALSE.equals(self)) {
+            return null;
+        }
+        String columnName = userColumns.get(tableName);
+        if (StrUtil.isEmpty(columnName)) {
+            return null;
+        }
+        // 拼接条件
+        return new EqualsTo(MyBatisPlusUtils.buildColumn(tableName, tableAlias, columnName), new LongValue(userId));
+    }
+
+    // ==================== 添加配置 ====================
+
+    public void addDeptColumn(Class<?> entityClass) {
+        addDeptColumn(entityClass, DEPT_COLUMN_NAME);
+    }
+
+    public void addDeptColumn(Class<?> entityClass, String columnName) {
+        String tableName = TableInfoHelper.getTableInfo(entityClass).getTableName();
+       addDeptColumn(tableName, columnName);
+    }
+
+    public void addDeptColumn(String tableName, String columnName) {
+        deptColumns.put(tableName, columnName);
+        TABLE_NAMES.add(tableName);
+    }
+
+    public void addUserColumn(Class<?> entityClass) {
+        addUserColumn(entityClass, USER_COLUMN_NAME);
+    }
+
+    public void addUserColumn(Class<?> entityClass, String columnName) {
+        String tableName = TableInfoHelper.getTableInfo(entityClass).getTableName();
+        addUserColumn(tableName, columnName);
+    }
+
+    public void addUserColumn(String tableName, String columnName) {
+        userColumns.put(tableName, columnName);
+        TABLE_NAMES.add(tableName);
+    }
+
+}

+ 20 - 0
module-erp/src/main/java/com/hys/app/framework/datapermission/dept/DeptDataPermissionRuleCustomizer.java

@@ -0,0 +1,20 @@
+package com.hys.app.framework.datapermission.dept;
+
+/**
+ * {@link DeptDataPermissionRule} 的自定义配置接口
+ *
+ * @author 张崧
+ */
+@FunctionalInterface
+public interface DeptDataPermissionRuleCustomizer {
+
+    /**
+     * 自定义该权限规则
+     * 1. 调用 {@link DeptDataPermissionRule#addDeptColumn(Class, String)} 方法,配置基于 dept_id 的过滤规则
+     * 2. 调用 {@link DeptDataPermissionRule#addUserColumn(Class, String)} 方法,配置基于 user_id 的过滤规则
+     *
+     * @param rule 权限规则
+     */
+    void customize(DeptDataPermissionRule rule);
+
+}

+ 6 - 0
module-erp/src/main/java/com/hys/app/framework/datapermission/dept/package-info.java

@@ -0,0 +1,6 @@
+/**
+ * 基于部门的数据权限规则
+ *
+ * @author 张崧
+ */
+package com.hys.app.framework.datapermission.dept;

+ 121 - 0
module-erp/src/main/java/com/hys/app/framework/security/AdminAccessDecisionManager.java

@@ -0,0 +1,121 @@
+package com.hys.app.framework.security;
+
+import com.hys.app.framework.context.user.AdminUserContext;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.security.access.ConfigAttribute;
+import org.springframework.security.authentication.InsufficientAuthenticationException;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.web.FilterInvocation;
+import org.springframework.util.AntPathMatcher;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.regex.Pattern;
+
+/**
+ * 管理端访问决策控制<br/>
+ * 根据权限数据源提供的权限来判断是否可以通过
+ *
+ * @author kingapex
+ * @version 1.0
+ * @see AdminSecurityMetadataSource
+ * Created by kingapex on 2018/3/27.
+ * @since 7.0.0
+ * 2018/3/27
+ */
+public class AdminAccessDecisionManager implements org.springframework.security.access.AccessDecisionManager {
+    @Override
+    public void decide(Authentication authentication, Object object,
+                       Collection<ConfigAttribute> configAttributes)
+            throws AccessDeniedException, InsufficientAuthenticationException {
+
+        FilterInvocation filterInvocation = (FilterInvocation) object;
+        String url = filterInvocation.getRequestUrl();
+        //过滤swagger系列
+        AntPathMatcher matcher = new AntPathMatcher();
+        Boolean result = matcher.match("/swagger-ui.html", url);
+        result = result || matcher.match("/v2/api-docs**", url);
+        result = result || matcher.match("/configuration/ui", url);
+        result = result || matcher.match("/swagger-resources/**", url);
+        result = result || matcher.match("/webjars/**", url);
+        result = result || matcher.match("/configuration/security", url);
+        result = result || matcher.match("/actuator/**", url);
+        result = result || matcher.match("/import-tpl/**", url);
+        result = result || matcher.match("/admin/erp/kdn/returnBack/**", url);
+        result = result || matcher.match("/admin/erp/scancode/**", url);
+        result = result || matcher.match("/admin/erp/pay/**", url);
+        result = result || matcher.match("/weixin", url);
+        result = result || matcher.match("/admin/systems/admin-users/login/**", url);
+        result = result || matcher.match("/admin/erp/company/createCompany/**", url);
+        result = result || matcher.match("/admin/erp/companyPackage/**", url);
+        if (result) {
+            return;
+        }
+        //过滤后台管理员登录
+        result = matcher.match("/admin/systems/admin-users/login**", url);
+        result = result || matcher.match("/admin/systems/admin-users/token**", url);
+        result = result || matcher.match("/admin/systems/admin-users/logout**", url);
+        result = result || matcher.match("/weixin/**", url);
+        if (result) {
+            return;
+        }
+        if (AdminUserContext.getAdmin() != null) {
+            boolean bool = this.adminRolesChecked(url);
+            if (bool) {
+                return;
+            }
+        }
+        if (CollectionUtils.isEmpty(configAttributes)) {
+            throw new AccessDeniedException("not allow");
+        }
+        Iterator<ConfigAttribute> ite = configAttributes.iterator();
+        while (ite.hasNext()) {
+            ConfigAttribute ca = ite.next();
+            String needRole = ca.getAttribute();
+            for (GrantedAuthority ga : authentication.getAuthorities()) {
+                if ("ROLE_SUPER_ADMIN".equals(ga.getAuthority())) {
+                    return;
+                }
+                if (ga.getAuthority().equals(needRole)) {
+                    //匹配到有对应角色,则允许通过
+                    return;
+                }
+            }
+        }
+        //该url有配置权限,但是当然登录用户没有匹配到对应权限,则禁止访问
+        throw new AccessDeniedException("not allow");
+    }
+
+    /**
+     * 登录之后通用权限控制
+     *
+     * @param url api路径
+     * @return
+     */
+    private boolean adminRolesChecked(String url) {
+        //精确匹配
+        if ("/admin/index/page".equals(url)) {
+            return true;
+        }
+        //正则匹配
+        boolean isMatch = Pattern.matches("/admin/systems/roles/[1-9].*", url);
+        isMatch = isMatch || Pattern.matches("/regions/[1-9].*", url);
+        isMatch = isMatch || Pattern.matches("/uploaders.*", url);
+        isMatch = isMatch || Pattern.matches("/admin/index/page.*", url);
+        isMatch = isMatch || Pattern.matches("/admin/systems/admin-users.*", url);
+        isMatch = isMatch || Pattern.matches("/admin/systems/dict-data/list-all-simple.*", url);
+        return isMatch;
+    }
+
+    @Override
+    public boolean supports(ConfigAttribute attribute) {
+        return true;
+    }
+
+    @Override
+    public boolean supports(Class<?> clazz) {
+        return true;
+    }
+}

+ 40 - 0
module-erp/src/main/java/com/hys/app/framework/security/AdminAuthenticationService.java

@@ -0,0 +1,40 @@
+package com.hys.app.framework.security;
+
+import com.hys.app.framework.auth.AuthUser;
+import com.hys.app.framework.security.impl.AbstractAuthenticationService;
+import com.hys.app.framework.security.model.Admin;
+import com.hys.app.framework.security.model.Role;
+import com.hys.app.framework.security.model.User;
+import org.springframework.stereotype.Component;
+
+/**
+ * admin 鉴权管理
+ * v2.0: 重构鉴权机制
+ * Created by kingapex on 2018/3/12.
+ *
+ * @author kingapex
+ * @version 2.0
+ * @since 7.0.0
+ * 2018/3/12
+ */
+
+@Component
+public class AdminAuthenticationService extends AbstractAuthenticationService {
+
+
+    /**
+     * 将token解析为Admin
+     * @param token
+     * @return
+     */
+    @Override
+    protected AuthUser parseToken(String token) {
+
+        AuthUser authUser=  tokenManager.parse(Admin.class, token);
+        User user = (User) authUser;
+        checkUserDisable(Role.ADMIN, user.getUid());
+        return authUser;
+
+    }
+
+}

+ 112 - 0
module-erp/src/main/java/com/hys/app/framework/security/AdminSecurityMetadataSource.java

@@ -0,0 +1,112 @@
+package com.hys.app.framework.security;
+
+import com.hys.app.service.system.RoleManager;
+import com.hys.app.framework.cache.Cache;
+import com.hys.app.model.base.CachePrefix;
+import org.springframework.security.access.ConfigAttribute;
+import org.springframework.security.access.SecurityConfig;
+import org.springframework.security.web.FilterInvocation;
+import org.springframework.util.AntPathMatcher;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * 权限数据源提供者<br/>
+ * 提供此资源需要的角色集合
+ * Created by kingapex on 2018/3/27.
+ *
+ * @author kingapex
+ * @version 1.0
+ * @since 7.0.0
+ * 2018/3/27
+ */
+public class AdminSecurityMetadataSource implements org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource {
+
+    private final AntPathMatcher antPathMatcher = new AntPathMatcher();
+
+    private RoleManager roleManager;
+
+    private Cache cache;
+
+    public AdminSecurityMetadataSource(RoleManager roleManager, Cache cache) {
+        this.roleManager = roleManager;
+        this.cache = cache;
+    }
+
+
+    @Override
+    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
+        FilterInvocation fi = (FilterInvocation) object;
+        return this.buildAttributes(fi.getRequest().getRequestURI(), fi.getRequest().getMethod());
+
+    }
+
+
+    private Collection<ConfigAttribute> buildAttributes(String url, String method) {
+        List<String> roleList = new ArrayList<>();
+
+        //从缓存中获取各个角色分别对应的菜单权限,缓存中获取不到从数据库获取,放入缓存。
+//        Map<String, List<String>> roleMap = (Map<String, List<String>>) cache.get(CachePrefix.ADMIN_URL_ROLE.getPrefix());
+        Map<String, List<String>> roleMap = null;
+        if (roleMap == null) {
+            roleMap = roleManager.getRoleMap();
+        }
+
+        if (roleMap != null) {
+            for (String role : roleMap.keySet()) {
+                List<String> urlList = roleMap.get(role);
+                if (matchUrl(urlList, url, method)) {
+                    roleList.add("ROLE_" + role);
+                }
+            }
+        }
+
+        if (roleList.isEmpty()) {
+            //没有匹配到,默认是要超级管理员才能访问
+            return SecurityConfig.createList("ROLE_SUPER_ADMIN");
+
+        } else {
+            return SecurityConfig.createList(roleList.toArray(new String[roleList.size()]));
+        }
+
+    }
+
+
+    /**
+     * 看一个list 中是否匹配某个url
+     *
+     * @param patternList 一个含有ant表达式的list
+     * @param url         要匹配的Url
+     * @param method      请求方式,由于改为方法级别鉴权,url可能相同,需要再根据请求方式区分
+     * @return 是否有可以匹配此url的表达式, 有返回true
+     */
+    private boolean matchUrl(List<String> patternList, String url, String method) {
+//        // 遍历权限
+//        for (String expression : patternList) {
+//
+//            // 匹配权限
+//            boolean isMatch = Pattern.matches(expression, url + ":" + method);
+//
+//            if (isMatch) {
+//                return true;
+//            }
+//        }
+//        return false;
+        return true;
+    }
+
+
+    @Override
+    public Collection<ConfigAttribute> getAllConfigAttributes() {
+        return null;
+    }
+
+    @Override
+    public boolean supports(Class<?> clazz) {
+        return FilterInvocation.class.isAssignableFrom(clazz);
+    }
+}

+ 75 - 0
module-erp/src/main/java/com/hys/app/framework/security/BaseSecurityConfig.java

@@ -0,0 +1,75 @@
+package com.hys.app.framework.security;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.security.web.access.AccessDeniedHandler;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.CorsConfigurationSource;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+
+/**
+ * Created by kingapex on 2018/3/12.
+ * 买家安全配置
+ * @author kingapex
+ * @version 1.0
+ * @since 7.0.0
+ * 2018/3/12
+ */
+@Configuration
+@EnableWebSecurity
+@Order(999)
+public class BaseSecurityConfig extends WebSecurityConfigurerAdapter {
+
+
+    @Autowired
+    private AccessDeniedHandler accessDeniedHandler;
+
+    @Autowired
+    private AuthenticationEntryPoint authenticationEntryPoint;
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+
+
+        http.cors().and().csrf().disable()
+        //禁用session
+        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
+
+        //定义验权失败返回格式
+        .exceptionHandling().accessDeniedHandler( accessDeniedHandler ).authenticationEntryPoint(authenticationEntryPoint).and()
+
+        .authorizeRequests().anyRequest().anonymous().and().headers().frameOptions().disable().and().headers().cacheControl();
+
+        //过滤掉swagger的路径
+        http.authorizeRequests().antMatchers("/test/**","/v2/api-docs","/admin/pages/**", "/configuration/ui", "/swagger-resources", "/configuration/security", "/swagger-ui.html", "/webjars/**", "/qy/**").anonymous();
+
+        http.headers().contentSecurityPolicy("script-src 'self' 'unsafe-inline' 'unsafe-eval'");
+    }
+
+
+
+
+    /**
+     * 定义跨域配置
+     * @return
+     */
+    @Bean
+    CorsConfigurationSource corsConfigurationSource() {
+        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+        CorsConfiguration config = new CorsConfiguration();
+        config.setAllowCredentials(true);
+        config.addAllowedOrigin(CorsConfiguration.ALL);
+        config.addAllowedHeader(CorsConfiguration.ALL);
+        config.addAllowedMethod(CorsConfiguration.ALL);
+        source.registerCorsConfiguration("/**", config);
+        return source;
+    }
+
+}

+ 107 - 0
module-erp/src/main/java/com/hys/app/framework/security/ManagerSecurityConfig.java

@@ -0,0 +1,107 @@
+package com.hys.app.framework.security;
+
+import com.hys.app.framework.cache.Cache;
+import com.hys.app.framework.security.message.UserDisableReceiver;
+import com.hys.app.service.system.RoleManager;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.security.config.annotation.ObjectPostProcessor;
+import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.security.web.access.AccessDeniedHandler;
+import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.CorsConfigurationSource;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+
+import java.util.List;
+
+/**
+ * Created by kingapex on 2018/3/12.
+ * 管理端安全配置
+ *
+ * @author kingapex
+ * @version 1.0
+ * @since 7.0.0
+ * 2018/3/12
+ */
+@Configuration
+@EnableWebSecurity
+@Order(1)
+public class ManagerSecurityConfig extends WebSecurityConfigurerAdapter {
+
+    @Autowired
+    private AdminAuthenticationService adminAuthenticationService;
+
+    @Autowired
+    private RoleManager roleManager;
+
+    @Autowired
+    private Cache cache;
+
+    @Autowired
+    private AccessDeniedHandler accessDeniedHandler;
+
+    @Autowired
+    private AuthenticationEntryPoint authenticationEntryPoint;
+
+    @Override
+    public void configure(HttpSecurity http) throws Exception {
+        http
+                .cors().and()
+                .csrf().disable()
+                .antMatcher("/admin/**")
+                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
+                //定义验权失败返回格式
+                .exceptionHandling().accessDeniedHandler(accessDeniedHandler).authenticationEntryPoint(authenticationEntryPoint).and()
+                .authorizeRequests().anyRequest().authenticated()
+                .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
+                    @Override
+                    public <O extends FilterSecurityInterceptor> O postProcess(
+                            O fsi) {
+                        fsi.setSecurityMetadataSource(new AdminSecurityMetadataSource(roleManager,cache));
+                        fsi.setAccessDecisionManager(new AdminAccessDecisionManager());
+                        return fsi;
+                    }
+                })
+                .and().addFilterBefore(new TokenAuthenticationFilter(adminAuthenticationService), UsernamePasswordAuthenticationFilter.class);
+        //禁用缓存
+        http.headers().cacheControl()
+                .and().contentSecurityPolicy("script-src 'self' 'unsafe-inline' 'unsafe-eval'");
+
+
+    }
+
+    /**
+     * 定义跨域配置
+     *
+     * @return
+     */
+    @Bean
+    CorsConfigurationSource corsConfigurationSource() {
+        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+        CorsConfiguration config = new CorsConfiguration();
+        config.setAllowCredentials(true);
+        config.addAllowedOrigin("*");
+        config.addAllowedHeader("*");
+        config.addAllowedMethod("*");
+        source.registerCorsConfiguration("/**", config);
+        return source;
+    }
+
+    @Autowired
+    private List<AuthenticationService> authenticationServices;
+
+
+    @Bean
+    public UserDisableReceiver userDisableReceiver() {
+        return new UserDisableReceiver(authenticationServices);
+    }
+}

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно