Prechádzať zdrojové kódy

1、新建表用于存储产品目录;
2、uniapp推送消息

wany 1 rok pred
rodič
commit
d422ef429d
21 zmenil súbory, kde vykonal 1226 pridanie a 30 odobranie
  1. 144 0
      src/main/java/com/kingtom/shengtai/api/controller/ProductDirController.java
  2. 12 8
      src/main/java/com/kingtom/shengtai/api/controller/SrmCooperateController.java
  3. 6 6
      src/main/java/com/kingtom/shengtai/api/controller/SrmSupplierController.java
  4. 65 0
      src/main/java/com/kingtom/shengtai/api/controller/SystemExtController.java
  5. 81 0
      src/main/java/com/kingtom/shengtai/api/mapper/ProductDirMapper.java
  6. 68 0
      src/main/java/com/kingtom/shengtai/api/model/ProductDirDTO.java
  7. 74 0
      src/main/java/com/kingtom/shengtai/api/model/ProductDirTreeDTO.java
  8. 2 2
      src/main/java/com/kingtom/shengtai/app/affair/service/SupplierJoinHandler.java
  9. 2 2
      src/main/java/com/kingtom/shengtai/app/affair/service/UserJoinOrgHandler.java
  10. 46 0
      src/main/java/com/kingtom/shengtai/app/message/util/UniAppUtils.java
  11. 21 3
      src/main/java/com/kingtom/shengtai/app/message/ws/WsSendService.java
  12. 17 0
      src/main/java/com/kingtom/shengtai/app/product/dao/IProductDirDao.java
  13. 191 0
      src/main/java/com/kingtom/shengtai/app/product/model/ProductDir.java
  14. 101 0
      src/main/java/com/kingtom/shengtai/app/product/model/table/ProductDirTableDef.java
  15. 110 0
      src/main/java/com/kingtom/shengtai/app/product/service/IProductDirService.java
  16. 222 0
      src/main/java/com/kingtom/shengtai/app/product/service/impl/ProductDirServiceImpl.java
  17. 2 1
      src/main/java/com/kingtom/shengtai/app/srm/service/impl/SrmSupplierServiceImpl.java
  18. 4 1
      src/main/resources/application-dev-conf.yml
  19. 7 4
      src/main/resources/application-local-conf.yml
  20. 33 0
      src/main/resources/db/V2.03__20240117_initdir.sql
  21. 18 3
      src/main/resources/init/auth/auth.json

+ 144 - 0
src/main/java/com/kingtom/shengtai/api/controller/ProductDirController.java

@@ -0,0 +1,144 @@
+package com.kingtom.shengtai.api.controller;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.kingtom.kirin.app.system.utils.SystemUtils;
+import com.kingtom.kirin.core.common.base.PageInfo;
+import com.kingtom.kirin.core.common.base.Result;
+import com.kingtom.kirin.core.common.utils.CollectionUtils;
+import com.kingtom.kirin.core.common.utils.JsonUtils;
+import com.kingtom.shengtai.api.mapper.ProductDirMapper;
+import com.kingtom.shengtai.api.model.ProductDirDTO;
+import com.kingtom.shengtai.api.model.ProductDirTreeDTO;
+import com.kingtom.shengtai.app.product.model.ProductDir;
+import com.kingtom.shengtai.app.product.service.IProductDirService;
+import com.mybatisflex.core.paginate.Page;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Parameters;
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 应用模块名称</p>
+ * 产品目录表 控制层。</p>
+ * Copyright: Copyright (C) 2024 , Inc. All rights reserved. <p>
+ * Company: 成都诚唐科技有限责任公司</p>
+ *
+ * @author wany
+ * @since 2024/01/17
+ */
+@RestController
+@Tag(name = "产品目录表接口")
+@RequestMapping("/product_dirs")
+public class ProductDirController{
+
+    @Autowired
+    private IProductDirService productDirService;
+
+    @Operation(summary = "新建产品目录表")
+    @PostMapping("/")
+    @SaCheckPermission(value = {"AuthMenu:srm_products:Execute"})
+    public Result<ProductDirDTO> addProductDir(@RequestBody ProductDirDTO dto){
+        ProductDir productDir = ProductDirMapper.INSTANCE.convert(dto);
+        productDir.setSysId(SystemUtils.getCurrentSystemId());
+        productDir = productDirService.create(productDir);
+        if(productDir == null){
+            Result.ok(null);
+        }
+        return Result.ok(ProductDirMapper.INSTANCE.convert(productDir));
+    }
+
+    @Operation(summary = "更新产品目录表")
+    @PostMapping("/{id}/info")
+    @SaCheckPermission(value = {"AuthMenu:srm_products:Execute"})
+    public Result<ProductDirDTO> updateProductDir(@PathVariable("id") String id, @RequestBody ProductDirDTO dto){
+        ProductDir productDir = ProductDirMapper.INSTANCE.convert(dto);
+        productDir.setId(id);
+        productDir = productDirService.update(productDir);
+        if(productDir == null){
+            Result.ok(null);
+        }
+        return Result.ok(ProductDirMapper.INSTANCE.convert(productDir));
+    }
+
+    @Parameter(name = "id", description = "产品目录表Id", in = ParameterIn.PATH, required = true)
+    @Operation(summary = "删除产品目录表")
+    @PostMapping("/{id}/")
+    @SaCheckPermission(value = {"AuthMenu:srm_products:Execute"})
+    public Result<String> deleteProductDir(@PathVariable("id") String id){
+        productDirService.deleteById(id);
+        return Result.ok("操作成功!");
+    }
+
+    @Operation(summary = "批量删除产品目录表")
+    @PostMapping("/delete/")
+    @SaCheckPermission(value = {"AuthMenu:srm_products:Execute"})
+    public Result<String> deleteProductDirs(@RequestBody String json){
+        List<String> ids = JsonUtils.toObjectList(json, String.class);
+        productDirService.deleteByIds(ids);
+        return Result.ok("操作成功!");
+    }
+
+    @Parameter(name = "id", description = "产品目录表Id", in = ParameterIn.PATH, required = true)
+    @Operation(summary = "根据id查找产品目录表")
+    @GetMapping("/{id}/info")
+    @SaCheckPermission(value = {"AuthMenu:srm_products:Execute"})
+    public Result<ProductDirDTO> findProductDir(@PathVariable("id") String id){
+        ProductDir productDir = productDirService.findById(id);
+        return Result.ok(ProductDirMapper.INSTANCE.convert(productDir));
+    }
+
+    @Operation(summary = "分页查询产品目录表")
+    @Parameters({@Parameter(name = "query", description = "搜索内容", in = ParameterIn.QUERY, required = false),
+            @Parameter(name = "pageNum", description = "当前页", in = ParameterIn.QUERY, required = true),
+            @Parameter(name = "pageSize", description = "每页数据条数", in = ParameterIn.QUERY, required = true)})
+    @GetMapping("/page")
+    @SaCheckPermission(value = {"AuthMenu:srm_products:Execute"})
+    public Result<PageInfo<ProductDirDTO>> getProductDirPage(String query, int pageNum, int pageSize){
+        String search = null;
+        if(StringUtils.isNotBlank(query)){
+            Map<String, String> map = JsonUtils.toObject(query, Map.class);
+            search = map.get("search");
+        }
+        Page<ProductDir> page = productDirService.page(search, pageNum, pageSize);
+        PageInfo<ProductDirDTO> r = CollectionUtils.convertPage(page, ProductDirMapper.INSTANCE::convert);
+        return Result.ok(r);
+    }
+
+    @Operation(summary = "产品目录树")
+    @GetMapping("/tree")
+    @SaCheckPermission(value = {"AuthMenu:srm_products:Execute"})
+    public Result<List<ProductDirTreeDTO>> getProductDirTree(){
+        List<ProductDir> list = productDirService.list();
+        List<ProductDirDTO> dtoList =
+                list.stream().map(ProductDirMapper.INSTANCE::convert).collect(Collectors.toList());
+        return Result.ok(ProductDirTreeDTO.build(dtoList));
+    }
+
+    @Operation(summary = "产品目录树")
+    @GetMapping("/tree_noauth")
+    public Result<List<ProductDirTreeDTO>> getProductDirTreeWithOutAuth(){
+        List<ProductDir> list = productDirService.list();
+        List<ProductDirDTO> dtoList =
+                list.stream().map(ProductDirMapper.INSTANCE::convert).collect(Collectors.toList());
+        return Result.ok(ProductDirTreeDTO.build(dtoList));
+    }
+
+    @Operation(summary = "产品目录对应的供应商数量")
+    @Parameter(name = "filterNoSupplier", description = "是否过滤总数为0的数据,默认为true", in = ParameterIn.QUERY,
+            required = false)
+    @GetMapping("/supplierCountGroupByProduct")
+    public Result<List<Map<String, Object>>> getSupplierCountGroupByProduct(
+            @RequestParam(name = "filterNoSupplier", defaultValue = "true") Boolean filterNoSupplier){
+        List<Map<String, Object>> map = productDirService.findSupplierCountGroupByProduct(filterNoSupplier);
+        return Result.ok(map);
+    }
+
+}

+ 12 - 8
src/main/java/com/kingtom/shengtai/api/controller/SrmCooperateController.java

@@ -41,7 +41,7 @@ public class SrmCooperateController{
     private ISrmCooperateService iSrmCooperateService;
 
     @Autowired
-    private ISrmSupplierService  iSrmSupplierService;
+    private ISrmSupplierService iSrmSupplierService;
 
     /**
      * 添加 供应商合作记录表。
@@ -51,7 +51,7 @@ public class SrmCooperateController{
      */
     @Operation(summary = "添加 供应商合作记录表。", description = "添加 供应商合作记录表。")
     @PostMapping("/")
-    @SaCheckPermission(value = {"AuthMenu:organization_supplier:Execute"})
+    @SaCheckPermission(value = {"AuthMenu:srm_supplier:Execute"})
     public Result<SrmCooperateDTO> save(@RequestBody SrmCooperateDTO dto){
         SrmCooperate convert = SrmMapper.INSTANCE.convert(dto);
         SrmCooperateDO srmCooperateDO = iSrmCooperateService.create(convert);
@@ -67,7 +67,7 @@ public class SrmCooperateController{
     @Parameter(name = "id", description = "主键", in = ParameterIn.PATH, required = true)
     @Operation(summary = "根据主键删除 供应商合作记录表。", description = "根据主键删除 供应商合作记录表。")
     @PostMapping("/{id}/")
-    @SaCheckPermission(value = {"AuthMenu:organization_supplier:Execute"})
+    @SaCheckPermission(value = {"AuthMenu:srm_supplier:Execute"})
     public Result<String> remove(@PathVariable String id){
         iSrmCooperateService.deleteById(id);
         return Result.ok(null);
@@ -81,7 +81,7 @@ public class SrmCooperateController{
      */
     @Operation(summary = "根据主键批量删除供应商信息表。", description = "根据主键批量删除供应商信息表。")
     @PostMapping("/remove_batch")
-    @SaCheckPermission(value = {"AuthMenu:organization_supplier:Execute"})
+    @SaCheckPermission(value = {"AuthMenu:srm_supplier:Execute"})
     public Result<String> remove(@RequestBody List<String> ids){
         iSrmCooperateService.deleteByIds(ids);
         return Result.ok(null);
@@ -95,7 +95,7 @@ public class SrmCooperateController{
      */
     @Operation(description = "根据id更新供应商合作记录")
     @PostMapping("/{id}/info")
-    @SaCheckPermission(value = {"AuthMenu:organization_supplier:Execute"})
+    @SaCheckPermission(value = {"AuthMenu:srm_supplier:Execute"})
     public Result<SrmCooperateDTO> update(@RequestBody SrmCooperateDTO dto){
         SrmCooperate convert = SrmMapper.INSTANCE.convert(dto);
         SrmCooperateDO srmCooperateDO = iSrmCooperateService.update(convert);
@@ -110,7 +110,7 @@ public class SrmCooperateController{
      */
     @Operation(description = "根据id获取供应商合作记录")
     @GetMapping("/{id}/info")
-    @SaCheckPermission(value = {"AuthMenu:organization_supplier:Execute"})
+    @SaCheckPermission(value = {"AuthMenu:srm_supplier:Execute"})
     public Result<SrmCooperateDTO> getInfo(@PathVariable String id){
         SrmCooperateDO srmCooperateDO = iSrmCooperateService.findById(id);
         return Result.ok(SrmCooperateDTO.convert(srmCooperateDO));
@@ -126,7 +126,7 @@ public class SrmCooperateController{
      */
     @Operation(description = "分页查询供应商合作记录")
     @GetMapping("/page")
-    @SaCheckPermission(value = {"AuthMenu:organization_supplier:Execute"})
+    @SaCheckPermission(value = {"AuthMenu:srm_supplier:Execute"})
     public Result<PageInfo<SrmCooperateDTO>> page(String query, Integer pageNum, Integer pageSize){
         Map<String, Object> object = JsonUtils.toObject(query, Map.class);
         String search = object.get("search") == null ? null : object.get("search").toString();
@@ -142,9 +142,13 @@ public class SrmCooperateController{
         SessionData sessionData = SaSecurityUtils.findSessionData();
         String userId = sessionData.getUserId();
         SrmSupplier supplier = iSrmSupplierService.findByPerson(userId);
+        Page<SrmCooperateDO> page = new Page<>();
+        if(supplier == null){
+            return Result.ok(CollectionUtils.convertPage(page, SrmCooperateDTO::convert));
+        }
         Map<String, Object> object = JsonUtils.toObject(query, Map.class);
         String search = object.get("search") == null ? null : object.get("search").toString();
-        Page<SrmCooperateDO> page = iSrmCooperateService.page(search, supplier.getId(), pageNum, pageSize);
+        page = iSrmCooperateService.page(search, supplier.getId(), pageNum, pageSize);
         return Result.ok(CollectionUtils.convertPage(page, SrmCooperateDTO::convert));
     }
 

+ 6 - 6
src/main/java/com/kingtom/shengtai/api/controller/SrmSupplierController.java

@@ -52,7 +52,7 @@ public class SrmSupplierController{
      */
     @Operation(summary = "添加供应商信息表。", description = "添加供应商信息表。")
     @PostMapping("/")
-    @SaCheckPermission(value = {"AuthMenu:organization_supplier:Execute"})
+    @SaCheckPermission(value = {"AuthMenu:srm_supplier:Execute"})
     public Result<SrmSupplierDTO> save(@RequestBody SrmSupplierDTO dto){
         SrmSupplier convert = SrmMapper.INSTANCE.convert(dto);
         SrmSupplierDO supplierDO = iSrmSupplierService.create(convert);
@@ -68,7 +68,7 @@ public class SrmSupplierController{
     @Parameter(name = "id", description = "主键", in = ParameterIn.PATH, required = true)
     @Operation(summary = "根据主键删除供应商信息表。", description = "根据主键删除供应商信息表。")
     @PostMapping("/{id}/")
-    @SaCheckPermission(value = {"AuthMenu:organization_supplier:Execute"})
+    @SaCheckPermission(value = {"AuthMenu:srm_supplier:Execute"})
     public Result<String> remove(@PathVariable String id){
         iSrmSupplierService.deleteById(id);
         return Result.ok(null);
@@ -82,7 +82,7 @@ public class SrmSupplierController{
      */
     @Operation(summary = "根据主键批量删除供应商信息表。", description = "根据主键批量删除供应商信息表。")
     @PostMapping("/remove_batch")
-    @SaCheckPermission(value = {"AuthMenu:organization_supplier:Execute"})
+    @SaCheckPermission(value = {"AuthMenu:srm_supplier:Execute"})
     public Result<String> remove(@RequestBody List<String> ids){
         iSrmSupplierService.deleteByIds(ids);
         return Result.ok(null);
@@ -97,7 +97,7 @@ public class SrmSupplierController{
     @Parameter(name = "id", description = "", in = ParameterIn.PATH, required = true)
     @Operation(summary = "根据主键更新供应商信息表。", description = "根据主键更新供应商信息表。")
     @PostMapping("/{id}/info")
-    @SaCheckPermission(value = {"AuthMenu:organization_supplier:Execute"})
+    @SaCheckPermission(value = {"AuthMenu:srm_supplier:Execute"})
     public Result<SrmSupplierDTO> update(@RequestBody SrmSupplierDTO dto, @PathVariable String id){
         SrmSupplier convert = SrmMapper.INSTANCE.convert(dto);
         convert.setId(id);
@@ -114,7 +114,7 @@ public class SrmSupplierController{
     @Parameter(name = "id", description = "供应商信息表主键", in = ParameterIn.PATH, required = true)
     @Operation(summary = "根据供应商信息表主键获取详细信息。", description = "根据供应商信息表主键获取详细信息。")
     @GetMapping("/{id}/info")
-    @SaCheckPermission(value = {"AuthMenu:organization_supplier:Execute"})
+    @SaCheckPermission(value = {"AuthMenu:srm_supplier:Execute"})
     public Result<SrmSupplierDTO> getInfo(@PathVariable String id){
         SrmSupplierDO supplierDO = iSrmSupplierService.findById(id);
         return Result.ok(SrmSupplierDTO.convert(supplierDO));
@@ -130,7 +130,7 @@ public class SrmSupplierController{
      */
     @Operation(summary = "分页查询供应商信息表。", description = "分页查询供应商信息表。")
     @GetMapping("/page")
-    @SaCheckPermission(value = {"AuthMenu:organization_supplier:Execute"})
+    @SaCheckPermission(value = {"AuthMenu:srm_supplier:Execute"})
     public Result<PageInfo<SrmSupplierDTO>> page(String query, Integer pageNum, Integer pageSize){
         Map<String, Object> object = JsonUtils.toObject(query, Map.class);
         String name = object.get("name") instanceof String ? object.get("name").toString() : null;

+ 65 - 0
src/main/java/com/kingtom/shengtai/api/controller/SystemExtController.java

@@ -0,0 +1,65 @@
+package com.kingtom.shengtai.api.controller;
+
+import java.util.Date;
+
+import com.kingtom.kirin.api.security.SaSecurityUtils;
+import com.kingtom.kirin.app.system.model.SystemUser;
+import com.kingtom.kirin.app.system.service.ISystemUserService;
+import com.kingtom.kirin.core.common.base.Result;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 应用模块名称</p>
+ * 代码描述</p>
+ * Copyright: Copyright (C) 2024 , Inc. All rights reserved. <p>
+ * Company: 成都诚唐科技有限责任公司</p>
+ *
+ * @author wany
+ * @since 2024/1/18
+ */
+@RestController
+@RequestMapping("/system_ext")
+@Tag(name = "SystemExtController", description = "系统相关扩展接口。")
+public class SystemExtController{
+
+    @Autowired
+    private ISystemUserService systemUserService;
+
+    @Operation(summary = "更新用户的uniapp客户端Id")
+    @PostMapping("/user/client_info")
+    public Result<String> updateUserClientId(@RequestBody String clientId){
+        String userId = SaSecurityUtils.findSessionData().getUserId();
+        SystemUser update = new SystemUser();
+        update.setId(userId);
+        update.setExt1(clientId);
+        update.setGmtModified(new Date());
+        boolean b = systemUserService.updateById(update);
+        if(b){
+            return Result.ok("操作成功!");
+        } else{
+            return Result.fail("操作失败!");
+        }
+    }
+    @Operation(summary = "更新用户的uniapp客户端Id")
+    @PostMapping("/user/client")
+    public Result<String> removeUserClientId(@RequestBody String clientId){
+        String userId = SaSecurityUtils.findSessionData().getUserId();
+        SystemUser update = new SystemUser();
+        update.setId(userId);
+        update.setExt1("");
+        update.setGmtModified(new Date());
+        boolean b = systemUserService.updateById(update);
+        if(b){
+            return Result.ok("操作成功!");
+        } else{
+            return Result.fail("操作失败!");
+        }
+    }
+
+}

+ 81 - 0
src/main/java/com/kingtom/shengtai/api/mapper/ProductDirMapper.java

@@ -0,0 +1,81 @@
+package com.kingtom.shengtai.api.mapper;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.kingtom.kirin.core.common.utils.JsonUtils;
+import com.kingtom.shengtai.api.model.ProductDirDTO;
+import com.kingtom.shengtai.api.model.ProductDirTreeDTO;
+import com.kingtom.shengtai.app.product.model.ProductDir;
+import org.apache.commons.lang3.StringUtils;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.Named;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * 应用模块名称</p>
+ * 产品目录表 dto 和 entity之间的转换类。</p>
+ * Copyright: Copyright (C) 2024 , Inc. All rights reserved. <p>
+ * Company: 成都诚唐科技有限责任公司</p>
+ *
+ * @author wany
+ * @since 2024/01/17
+ */
+@Mapper
+public interface ProductDirMapper{
+
+    public static final ProductDirMapper INSTANCE = Mappers.getMapper(ProductDirMapper.class);
+
+    @Mapping(target = "ext3", qualifiedByName = "mapToString")
+    @Mapping(target = "gmtCreate", dateFormat = "yyyy-MM-dd HH:mm:ss")
+    @Mapping(target = "gmtModified", dateFormat = "yyyy-MM-dd HH:mm:ss")
+    @Mapping(target = "path", qualifiedByName = "listToString")
+    ProductDir convert(ProductDirDTO dto);
+
+    @Mapping(target = "ext3", qualifiedByName = "stringToMap")
+    @Mapping(target = "gmtCreate", dateFormat = "yyyy-MM-dd HH:mm:ss")
+    @Mapping(target = "gmtModified", dateFormat = "yyyy-MM-dd HH:mm:ss")
+    @Mapping(target = "path", qualifiedByName = "stringToList")
+    ProductDirDTO convert(ProductDir productDir);
+
+
+    @Mapping(target = "children", ignore = true)
+    ProductDirTreeDTO convertDTOToTree(ProductDirDTO menu);
+
+
+    @Named("stringToList")
+    default List<String> stringToList(String str){
+        if(StringUtils.isEmpty(str)){
+            return new ArrayList<>();
+        }
+        return JsonUtils.toObjectList(str, String.class);
+    }
+
+    @Named("listToString")
+    default String listToString(List<String> list){
+        if(list == null){
+            list = new ArrayList<>();
+        }
+        return JsonUtils.toJson(list);
+    }
+
+    @Named("mapToString")
+    default String mapToString(Map<String, Object> map){
+        if(map == null){
+            map = new HashMap<>();
+        }
+        return JsonUtils.toJson(map);
+    }
+
+    @Named("stringToMap")
+    default Map<String, Object> stringToMap(String str){
+        if(StringUtils.isEmpty(str)){
+            return new HashMap<>();
+        }
+        return JsonUtils.toObject(str, Map.class);
+    }
+
+}

+ 68 - 0
src/main/java/com/kingtom/shengtai/api/model/ProductDirDTO.java

@@ -0,0 +1,68 @@
+package com.kingtom.shengtai.api.model;
+
+import java.util.List;
+import java.util.Map;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+
+/**
+ * 应用模块名称</p>
+ * 产品目录表 前后端数据传输类。</p>
+ * Copyright: Copyright (C) 2024 , Inc. All rights reserved. <p>
+ * Company: 成都诚唐科技有限责任公司</p>
+ *
+ * @author wany
+ * @since 2024/01/17
+ */
+
+@Data
+@SuperBuilder
+@NoArgsConstructor
+@AllArgsConstructor
+@Schema(description = "产品目录表")
+public class ProductDirDTO{
+
+    @Schema(description = "id")
+    private String id;
+
+    @Schema(description = "标识符")
+    private String code;
+
+    @Schema(description = "名称")
+    private String name;
+
+    @Schema(description = "父目录Id")
+    private String parentId;
+
+    @Schema(description = "路径")
+    private List<String> path;
+
+    @Schema(description = "图片")
+    private String image;
+
+    @Schema(description = "备注")
+    private String remark;
+
+    @Schema(description = "扩展字段1")
+    private String ext1;
+
+    @Schema(description = "扩展字段2")
+    private String ext2;
+
+    @Schema(description = "扩展字段3")
+    private Map<String, Object> ext3;
+
+    @Schema(description = "创建时间")
+    private String gmtCreate;
+
+    @Schema(description = "更新时间")
+    private String gmtModified;
+
+    @Schema(description = "系统ID")
+    private String sysId;
+
+}

+ 74 - 0
src/main/java/com/kingtom/shengtai/api/model/ProductDirTreeDTO.java

@@ -0,0 +1,74 @@
+package com.kingtom.shengtai.api.model;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import com.kingtom.kirin.core.common.CommonConst;
+import com.kingtom.kirin.core.common.utils.CollectionUtils;
+import com.kingtom.shengtai.api.mapper.ProductDirMapper;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.experimental.SuperBuilder;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * 应用模块名称</p>
+ * 代码描述</p>
+ * Copyright: Copyright (C) 2024 , Inc. All rights reserved. <p>
+ * Company: 成都诚唐科技有限责任公司</p>
+ *
+ * @author wany
+ * @since 2024/1/17
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@SuperBuilder
+@NoArgsConstructor
+@AllArgsConstructor
+@Schema(description = "产品目录树")
+public class ProductDirTreeDTO extends ProductDirDTO{
+
+    @Schema(description = "父目录名称")
+    private String parentName;
+
+    @Schema(description = "子目录集合")
+    private List<ProductDirTreeDTO> children;
+
+    /**
+     * 根据集合构建出多棵树.
+     *
+     * @param list the list
+     * @return the list
+     */
+    public static List<ProductDirTreeDTO> build(List<ProductDirDTO> list){
+        if(CollectionUtils.isEmpty(list)){
+            return new ArrayList<>();
+        }
+        list = new ArrayList<>(list);
+        list.sort(Comparator.comparing(e -> StringUtils.join(e.getPath(), CommonConst.EMPTY_STRING)));
+        Map<String, List<ProductDirDTO>> map = list.stream().collect(Collectors.groupingBy(ProductDirDTO::getParentId));
+        return buildChildren(map, list.get(0).getSysId(), CommonConst.EMPTY_STRING);
+    }
+
+    private static List<ProductDirTreeDTO> buildChildren(Map<String, List<ProductDirDTO>> map, String key,
+            String parentName){
+        List<ProductDirDTO> dirs = map.remove(key);
+        if(CollectionUtils.isEmpty(dirs)){
+            return null;
+        }
+        return dirs.stream().map(dir -> {
+            ProductDirTreeDTO dto = ProductDirMapper.INSTANCE.convertDTOToTree(dir);
+            dto.setChildren(buildChildren(map, dir.getId(), dir.getName()));
+            dto.setParentName(parentName);
+            return dto;
+        }).sorted(Comparator.comparing(ProductDirTreeDTO::getGmtCreate)).collect(Collectors.toList());
+    }
+
+}

+ 2 - 2
src/main/java/com/kingtom/shengtai/app/affair/service/SupplierJoinHandler.java

@@ -140,7 +140,7 @@ public class SupplierJoinHandler extends AbstractAffairOneHandler{
         AuthRole role = roleService.findRoleByCode("supplier", SystemUtils.getCurrentSystemId());
         authService.updateRoleAddUsers(role.getId(), List.of(info.getSourceId()));
 
-        wsSendService.sendMsg(msgSummary.getType(), info.getSourceId());
+        wsSendService.sendMsg(info.getSourceId(), JsonUtils.toJson(msgSummary));
     }
 
     @Override
@@ -152,7 +152,7 @@ public class SupplierJoinHandler extends AbstractAffairOneHandler{
         msgSummary.setContent("成为供应商审核不通过!");
         msgSummary.setExt1(info.getId());
         msgSummaryService.createMsg(msgSummary, List.of(info.getSourceId()));
-        wsSendService.sendMsg(msgSummary.getType(), info.getSourceId());
+        wsSendService.sendMsg(info.getSourceId(), JsonUtils.toJson(msgSummary));
     }
 
 

+ 2 - 2
src/main/java/com/kingtom/shengtai/app/affair/service/UserJoinOrgHandler.java

@@ -145,7 +145,7 @@ public class UserJoinOrgHandler extends AbstractAffairOneHandler{
         msgSummary.setContent("用户加入组织审核通过!");
         msgSummary.setExt1(info.getId());
         msgSummaryService.createMsg(msgSummary, List.of(info.getSourceId()));
-        wsSendService.sendMsg(msgSummary.getType(), info.getSourceId());
+        wsSendService.sendMsg(info.getSourceId(), JsonUtils.toJson(msgSummary));
     }
 
     @Override
@@ -157,7 +157,7 @@ public class UserJoinOrgHandler extends AbstractAffairOneHandler{
         msgSummary.setContent("用户加入组织审核不通过!");
         msgSummary.setExt1(info.getId());
         msgSummaryService.createMsg(msgSummary, List.of(info.getSourceId()));
-        wsSendService.sendMsg(msgSummary.getType(), info.getSourceId());
+        wsSendService.sendMsg(info.getSourceId(), JsonUtils.toJson(msgSummary));
     }
 
     @lombok.Data

+ 46 - 0
src/main/java/com/kingtom/shengtai/app/message/util/UniAppUtils.java

@@ -0,0 +1,46 @@
+package com.kingtom.shengtai.app.message.util;
+
+import java.util.Map;
+
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.HttpUtil;
+import com.kingtom.kirin.core.common.utils.JsonUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * 应用模块名称</p>
+ * uniapp 云推送消息</p>
+ * Copyright: Copyright (C) 2024 , Inc. All rights reserved. <p>
+ * Company: 成都诚唐科技有限责任公司</p>
+ *
+ * @author wany
+ * @since 2024/1/18
+ */
+@Slf4j
+@Component
+public class UniAppUtils{
+
+    private static String url;
+
+    @Value("${uniapp.cloud.url}")
+    public void setUrl(String url){
+        UniAppUtils.url = url;
+    }
+
+    public static void sendCloudMessage(String clientId, String body){
+        if(StringUtils.isAnyEmpty(url, clientId, body)){
+            return;
+        }
+        Map<String, Object> message = JsonUtils.toObject(body, Map.class);
+        message.put("clientId", clientId);
+        try(HttpResponse response = HttpUtil.createPost(url).body(JsonUtils.toJson(message)).contentType("application/json").execute()){
+            if(response.getStatus() == 200){
+                log.info("给客户端发送消息成功,消息内容:" + JsonUtils.toJson(message));
+            }
+        }
+    }
+
+}

+ 21 - 3
src/main/java/com/kingtom/shengtai/app/message/ws/WsSendService.java

@@ -3,6 +3,9 @@ package com.kingtom.shengtai.app.message.ws;
 import java.text.MessageFormat;
 import java.util.List;
 
+import com.kingtom.kirin.app.system.model.SystemUser;
+import com.kingtom.kirin.app.system.service.ISystemUserService;
+import com.kingtom.shengtai.app.message.util.UniAppUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -26,14 +29,29 @@ public class WsSendService{
     @Autowired
     private WsHandler wsHandler;
 
-    public void sendMsg(String text, List<String> userIds){
-        userIds.forEach(e -> sendMsg(text, e));
+    @Autowired
+    private ISystemUserService systemUserService;
+
+    public void sendMsg(List<String> userIds, String text){
+        userIds.forEach(e -> sendMsg(e, text));
     }
 
-    public void sendMsg(String text, String userId){
+    public void sendMsg(String userId, String text){
         if(StringUtils.isAnyBlank(text, userId)){
             return;
         }
+        sendWebSocketMsg(userId, text);
+        sendUniAppCloudMsg(userId, text);
+    }
+
+    private void sendUniAppCloudMsg(String userId, String text){
+        SystemUser systemUser = systemUserService.getById(userId);
+        if(systemUser != null && StringUtils.isNotEmpty(systemUser.getExt1())){
+            UniAppUtils.sendCloudMessage(systemUser.getExt1(), text);
+        }
+    }
+
+    private void sendWebSocketMsg(String userId, String text){
         WebSocketSession webSocketSession = WsSessionManager.get(userId);
         if(webSocketSession == null){
             return;

+ 17 - 0
src/main/java/com/kingtom/shengtai/app/product/dao/IProductDirDao.java

@@ -0,0 +1,17 @@
+package com.kingtom.shengtai.app.product.dao;
+
+import com.kingtom.kirin.core.common.base.dao.IBaseDao;
+import com.kingtom.shengtai.app.product.model.ProductDir;
+
+/**
+ * 应用模块名称</p>
+ * 产品目录表 映射层。</p>
+ * Copyright: Copyright (C) 2024 , Inc. All rights reserved. <p>
+ * Company: 成都诚唐科技有限责任公司</p>
+ *
+ * @author wany
+ * @since 2024/01/17
+ */
+public interface IProductDirDao extends IBaseDao<ProductDir> {
+
+}

+ 191 - 0
src/main/java/com/kingtom/shengtai/app/product/model/ProductDir.java

@@ -0,0 +1,191 @@
+package com.kingtom.shengtai.app.product.model;
+
+import com.mybatisflex.annotation.Id;
+import com.mybatisflex.annotation.Table;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 应用模块名称</p>
+ * 产品目录表 实体类。</p>
+ * Copyright: Copyright (C) 2024 , Inc. All rights reserved. <p>
+ * Company: 成都诚唐科技有限责任公司</p>
+ *
+ * @author 86181
+ * @since 2024/01/17
+ */
+
+@Table(value = "product_dir", schema = "public")
+public class ProductDir implements Serializable {
+
+    /**
+     * id
+     */
+    @Id
+    private String id;
+
+    /**
+     * 标识符
+     */
+    private String code;
+
+    /**
+     * 名称
+     */
+    private String name;
+
+    /**
+     * 父目录Id
+     */
+    private String parentId;
+
+    /**
+     * 路径
+     */
+    private String path;
+
+    /**
+     * 图片
+     */
+    private String image;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 扩展字段1
+     */
+    private String ext1;
+
+    /**
+     * 扩展字段2
+     */
+    private String ext2;
+
+    /**
+     * 扩展字段3
+     */
+    private String ext3;
+
+    /**
+     * 创建时间
+     */
+    private Date gmtCreate;
+
+    /**
+     * 更新时间
+     */
+    private Date gmtModified;
+
+    /**
+     * 系统ID
+     */
+    private String sysId;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(String parentId) {
+        this.parentId = parentId;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getImage() {
+        return image;
+    }
+
+    public void setImage(String image) {
+        this.image = image;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public String getExt1() {
+        return ext1;
+    }
+
+    public void setExt1(String ext1) {
+        this.ext1 = ext1;
+    }
+
+    public String getExt2() {
+        return ext2;
+    }
+
+    public void setExt2(String ext2) {
+        this.ext2 = ext2;
+    }
+
+    public String getExt3() {
+        return ext3;
+    }
+
+    public void setExt3(String ext3) {
+        this.ext3 = ext3;
+    }
+
+    public Date getGmtCreate() {
+        return gmtCreate;
+    }
+
+    public void setGmtCreate(Date gmtCreate) {
+        this.gmtCreate = gmtCreate;
+    }
+
+    public Date getGmtModified() {
+        return gmtModified;
+    }
+
+    public void setGmtModified(Date gmtModified) {
+        this.gmtModified = gmtModified;
+    }
+
+    public String getSysId() {
+        return sysId;
+    }
+
+    public void setSysId(String sysId) {
+        this.sysId = sysId;
+    }
+
+}

+ 101 - 0
src/main/java/com/kingtom/shengtai/app/product/model/table/ProductDirTableDef.java

@@ -0,0 +1,101 @@
+package com.kingtom.shengtai.app.product.model.table;
+
+import com.mybatisflex.core.query.QueryColumn;
+import com.mybatisflex.core.table.TableDef;
+
+/**
+ * 应用模块名称</p>
+ * 产品目录表 表定义层。</p>
+ * Copyright: Copyright (C) 2024 , Inc. All rights reserved. <p>
+ * Company: 成都诚唐科技有限责任公司</p>
+ *
+ * @author 86181
+ * @since 2024/01/17
+ */
+public class ProductDirTableDef extends TableDef {
+
+    /**
+     * 产品目录表
+     */
+    public static final ProductDirTableDef PRODUCT_DIR = new ProductDirTableDef();
+
+    /**
+     * id
+     */
+    public final QueryColumn ID = new QueryColumn(this, "id");
+
+    /**
+     * 标识符
+     */
+    public final QueryColumn CODE = new QueryColumn(this, "code");
+
+    /**
+     * 名称
+     */
+    public final QueryColumn NAME = new QueryColumn(this, "name");
+
+    /**
+     * 父目录Id
+     */
+    public final QueryColumn PARENT_ID = new QueryColumn(this, "parent_id");
+
+    /**
+     * 路径
+     */
+    public final QueryColumn PATH = new QueryColumn(this, "path");
+
+    /**
+     * 图片
+     */
+    public final QueryColumn IMAGE = new QueryColumn(this, "image");
+
+    /**
+     * 备注
+     */
+    public final QueryColumn REMARK = new QueryColumn(this, "remark");
+
+    /**
+     * 扩展字段1
+     */
+    public final QueryColumn EXT1 = new QueryColumn(this, "ext1");
+
+    /**
+     * 扩展字段2
+     */
+    public final QueryColumn EXT2 = new QueryColumn(this, "ext2");
+
+    /**
+     * 扩展字段3
+     */
+    public final QueryColumn EXT3 = new QueryColumn(this, "ext3");
+
+    /**
+     * 创建时间
+     */
+    public final QueryColumn GMT_CREATE = new QueryColumn(this, "gmt_create");
+
+    /**
+     * 更新时间
+     */
+    public final QueryColumn GMT_MODIFIED = new QueryColumn(this, "gmt_modified");
+
+    /**
+     * 系统ID
+     */
+    public final QueryColumn SYS_ID = new QueryColumn(this, "sys_id");
+
+    /**
+     * 所有字段。
+     */
+    public final QueryColumn ALL_COLUMNS = new QueryColumn(this, "*");
+
+    /**
+     * 默认字段,不包含逻辑删除或者 large 等字段。
+     */
+    public final QueryColumn[] DEFAULT_COLUMNS = new QueryColumn[]{ID, CODE, NAME, PARENT_ID, PATH, IMAGE, REMARK, EXT1, EXT2, EXT3, GMT_CREATE, GMT_MODIFIED, SYS_ID};
+
+    public ProductDirTableDef() {
+        super("public", "product_dir");
+    }
+
+}

+ 110 - 0
src/main/java/com/kingtom/shengtai/app/product/service/IProductDirService.java

@@ -0,0 +1,110 @@
+package com.kingtom.shengtai.app.product.service;
+
+import java.util.List;
+import java.util.Map;
+
+import com.kingtom.kirin.core.common.base.service.IBaseService;
+import com.kingtom.shengtai.app.product.model.ProductDir;
+import com.mybatisflex.core.paginate.Page;
+
+/**
+ * 应用模块名称</p>
+ * 产品目录表 服务层。</p>
+ * Copyright: Copyright (C) 2024 , Inc. All rights reserved. <p>
+ * Company: 成都诚唐科技有限责任公司</p>
+ *
+ * @author wany
+ * @since 2024 /01/17
+ */
+public interface IProductDirService extends IBaseService<ProductDir>{
+
+    /**
+     * 新建 产品目录表.
+     *
+     * @param productDir the productDir
+     * @return the productDir
+     */
+    ProductDir create(ProductDir productDir);
+
+    /**
+     * 根据Id更新 产品目录表.
+     *
+     * @param productDir the productDir
+     * @return the productDir
+     */
+    ProductDir update(ProductDir productDir);
+
+    /**
+     * 根据id删除 产品目录表.
+     *
+     * @param id the id
+     */
+    void deleteById(String id);
+
+    /**
+     * 根据id批量删除 产品目录表
+     *
+     * @param ids the ids
+     */
+    void deleteByIds(List<String> ids);
+
+    /**
+     * 根据id查询 产品目录表.
+     *
+     * @param id the id
+     * @return the product dir
+     */
+    ProductDir findById(String id);
+
+    /**
+     * 根据id集合查询 产品目录表
+     *
+     * @param ids the ids
+     * @return the list
+     */
+    List<ProductDir> findByIds(List<String> ids);
+
+    /**
+     * 根据name查询 产品目录表
+     *
+     * @param name the name
+     * @return product dir
+     */
+    ProductDir findByName(String name);
+
+    /**
+     * 根据code查询 产品目录表
+     *
+     * @param code the code
+     * @return product dir
+     */
+    ProductDir findByCode(String code);
+
+    /**
+     * Find child list.
+     *
+     * @param id the id
+     * @return the list
+     */
+    List<ProductDir> findChild(String id);
+
+    /**
+     * 分页查询 产品目录表
+     *
+     * @param search   the search
+     * @param pageNum  the page num
+     * @param pageSize the page size
+     * @return the page
+     */
+    Page<ProductDir> page(String search, int pageNum, int pageSize);
+
+    /**
+     * 分组查询每个产品有多少个供应商可以提供
+     *
+     * @param filterCount0 是否过滤总数为零的餐品
+     * @return map list
+     */
+    List<Map<String, Object>> findSupplierCountGroupByProduct(boolean filterCount0);
+
+
+}

+ 222 - 0
src/main/java/com/kingtom/shengtai/app/product/service/impl/ProductDirServiceImpl.java

@@ -0,0 +1,222 @@
+package com.kingtom.shengtai.app.product.service.impl;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import com.kingtom.kirin.app.system.utils.SystemUtils;
+import com.kingtom.kirin.core.common.CommonConst;
+import com.kingtom.kirin.core.common.base.service.impl.BaseServiceImpl;
+import com.kingtom.kirin.core.common.exception.AppException;
+import com.kingtom.kirin.core.common.utils.CollectionUtils;
+import com.kingtom.kirin.core.common.utils.IDUtils;
+import com.kingtom.kirin.core.common.utils.JsonUtils;
+import com.kingtom.shengtai.app.product.dao.IProductDirDao;
+import com.kingtom.shengtai.app.product.model.ProductDir;
+import com.kingtom.shengtai.app.product.service.IProductDirService;
+import com.mybatisflex.core.paginate.Page;
+import com.mybatisflex.core.query.QueryCondition;
+import com.mybatisflex.core.query.QueryWrapper;
+import com.mybatisflex.core.row.Row;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+import static com.kingtom.shengtai.app.product.model.table.ProductDirTableDef.PRODUCT_DIR;
+
+/**
+ * 应用模块名称</p>
+ * 产品目录表 服务层实现。</p>
+ * Copyright: Copyright (C) 2024 , Inc. All rights reserved. <p>
+ * Company: 成都诚唐科技有限责任公司</p>
+ *
+ * @author wany
+ * @since 2024/01/17
+ */
+@Service
+public class ProductDirServiceImpl extends BaseServiceImpl<IProductDirDao, ProductDir> implements IProductDirService{
+
+    @Override
+    public ProductDir create(ProductDir productDir){
+        checkBeforeCreate(productDir);
+        fillBeforeCreate(productDir);
+        boolean f = mapper.insertSelective(productDir) == 1;
+        if(!f){
+            throw new AppException("落库出错,新建产品目录失败!");
+        }
+        return findById(productDir.getId());
+    }
+
+    private void checkBeforeCreate(ProductDir productDir){
+        if(productDir == null){
+            throw new AppException("产品目录表为空,新建失败!");
+        }
+        if(StringUtils.isBlank(productDir.getName())){
+            throw new AppException("名称为空,新建失败!");
+        } else{
+            ProductDir byName = findByName(productDir.getName());
+            if(byName != null){
+                throw new AppException("标识符重复,新建失败!").setM(productDir.getName());
+            }
+        }
+        if(StringUtils.isBlank(productDir.getCode())){
+            throw new AppException("标识符为空,新建失败!");
+        } else{
+            ProductDir dbByCode = findByCode(productDir.getCode());
+            if(dbByCode != null){
+                throw new AppException("标识符重复,新建失败!").setM(productDir.getCode());
+            }
+        }
+        if(StringUtils.isBlank(productDir.getSysId())){
+            throw new AppException("系统Id为空,新建失败!");
+        }
+    }
+
+    private void fillBeforeCreate(ProductDir productDir){
+        if(productDir.getId() == null){
+            productDir.setId(IDUtils.newUUID());
+        }
+        if(StringUtils.isEmpty(productDir.getSysId())){
+            productDir.setSysId(SystemUtils.getCurrentSystemId());
+        }
+        if(StringUtils.isEmpty(productDir.getExt3())){
+            productDir.setExt3(CommonConst.EMPTY_OBJECT_STRING);
+        }
+        if(productDir.getPath() == null){
+            productDir.setPath(CommonConst.EMPTY_ARRAY_STRING);
+        }
+        //path填充
+        if(StringUtils.isBlank(productDir.getParentId())){
+            productDir.setParentId(productDir.getSysId());
+            productDir.setPath(JsonUtils.toJson(List.of(productDir.getSysId(), productDir.getId())));
+        } else{
+            ProductDir parent = findById(productDir.getParentId());
+            if(parent == null){
+                throw new AppException("父目录不存在,新建失败!");
+            }
+            List<String> parentPath = JsonUtils.toObjectList(parent.getPath(), String.class);
+            parentPath.add(productDir.getId());
+            productDir.setPath(JsonUtils.toJson(parentPath));
+        }
+        productDir.setGmtCreate(new Date());
+        productDir.setGmtModified(productDir.getGmtCreate());
+    }
+
+    @Override
+    public ProductDir update(ProductDir productDir){
+        checkBeforeUpdate(productDir);
+        ProductDir dir = new ProductDir();
+        dir.setId(productDir.getId());
+        dir.setGmtModified(new Date());
+        dir.setCode(productDir.getCode());
+        dir.setName(productDir.getName());
+        dir.setImage(productDir.getImage());
+        dir.setRemark(productDir.getRemark());
+        boolean f = mapper.update(dir) == 1;
+        if(!f){
+            throw new AppException("落库出错,更新产品目录表失败!");
+        }
+        return findById(productDir.getId());
+    }
+
+    private void checkBeforeUpdate(ProductDir productDir){
+        if(productDir == null){
+            throw new AppException("产品目录为空,更新失败!");
+        }
+        if(StringUtils.isEmpty(productDir.getId())){
+            throw new AppException("产品目录id为空,更新失败!");
+        }
+        if(StringUtils.isNotEmpty(productDir.getName())){
+            ProductDir byName = findByName(productDir.getName());
+            if(byName != null && !byName.getId().equals(productDir.getId())){
+                throw new AppException("标识符重复,更新失败!").setM(productDir.getName());
+            }
+        }
+        if(StringUtils.isNotEmpty(productDir.getCode())){
+            ProductDir byCode = findByCode(productDir.getCode());
+            if(byCode != null && !byCode.getId().equals(productDir.getId())){
+                throw new AppException("标识符重复,更新失败!").setM(productDir.getCode());
+            }
+        }
+    }
+
+    @Override
+    public void deleteById(String id){
+        if(id == null){
+            return;
+        }
+        //同步删除子目录
+        int i = mapper.deleteByCondition(QueryCondition.createEmpty().and("path::jsonb ?? '" + id + "'"));
+        if(i <= 0){
+            throw new AppException("落库出错,删除产品目录表失败!");
+        }
+    }
+
+    @Override
+    public void deleteByIds(List<String> ids){
+        if(CollectionUtils.isEmpty(ids)){
+            return;
+        }
+        for(String id : ids){
+            deleteById(id);
+        }
+    }
+
+    @Override
+    public ProductDir findById(String id){
+        if(id == null){
+            return null;
+        }
+        return mapper.selectOneById(id);
+    }
+
+    @Override
+    public List<ProductDir> findByIds(List<String> ids){
+        if(CollectionUtils.isEmpty(ids)){
+            return new ArrayList<>();
+        }
+        return mapper.selectListByIds(ids);
+    }
+
+    @Override
+    public ProductDir findByName(String name){
+        return mapper.selectOneByCondition(PRODUCT_DIR.NAME.eq(name));
+    }
+
+    @Override
+    public ProductDir findByCode(String code){
+        return mapper.selectOneByCondition(PRODUCT_DIR.CODE.eq(code));
+    }
+
+    @Override
+    public List<ProductDir> findChild(String id){
+        if(StringUtils.isEmpty(id)){
+            return new ArrayList<>();
+        }
+        QueryCondition condition =
+                QueryCondition.createEmpty().and("path::jsonb ?? '" + id + "'").and(PRODUCT_DIR.ID.ne(id));
+        return mapper.selectListByCondition(condition);
+    }
+
+    @Override
+    public Page<ProductDir> page(String search, int pageNum, int pageSize){
+        QueryWrapper wrapper = QueryWrapper.create();
+        //todo 查询条件构造
+        return mapper.paginate(pageNum, pageSize, wrapper);
+    }
+
+    @Override
+    public List<Map<String, Object>> findSupplierCountGroupByProduct(boolean filterCount0){
+        //SELECT a.id,A.name,COUNT ( b.sid ) AS c FROM product_dir AS a LEFT JOIN ( SELECT SUBSTRING (
+        // json_array_elements ( product :: json ) :: TEXT, 2, 36 ) AS pid, id AS sid FROM srm_supplier ) AS b ON a
+        // .id = b.pid GROUP BY a.id, a.name HAVING COUNT ( b.sid ) > 0;
+        QueryWrapper wrapper =
+                QueryWrapper.create().select("a.id", "A.name", "COUNT ( b.sid ) AS c").from(PRODUCT_DIR).as("a")
+                        .leftJoin(QueryWrapper.create()
+                                .select("SUBSTRING ( json_array_elements ( product :: json ) :: TEXT, 2, 36 ) AS pid",
+                                        "id AS sid").from("srm_supplier")).as("b").on("a.id = b.pid")
+                        .groupBy("a.id", "a.name")
+                        .having(QueryCondition.createEmpty().and("COUNT ( b.sid ) > 0").when(filterCount0));
+        List<Row> objects = mapper.selectRowsByQuery(wrapper);
+        return objects.stream().map(HashMap::new).collect(Collectors.toList());
+    }
+
+}

+ 2 - 1
src/main/java/com/kingtom/shengtai/app/srm/service/impl/SrmSupplierServiceImpl.java

@@ -19,6 +19,7 @@ import com.kingtom.kirin.core.common.base.service.impl.BaseServiceImpl;
 import com.kingtom.kirin.core.common.exception.AppException;
 import com.kingtom.kirin.core.common.utils.CollectionUtils;
 import com.kingtom.kirin.core.common.utils.IDUtils;
+import com.kingtom.kirin.core.common.utils.JsonUtils;
 import com.kingtom.shengtai.app.message.model.MsgSummary;
 import com.kingtom.shengtai.app.message.service.IMsgSummaryService;
 import com.kingtom.shengtai.app.message.ws.WsSendService;
@@ -198,7 +199,7 @@ public class SrmSupplierServiceImpl extends BaseServiceImpl<ISrmSupplierDao, Srm
         List<String> userIds = people.stream().map(OrgPerson::getUserId).collect(Collectors.toList());
         if(CollectionUtils.isNotEmpty(userIds)){
             msgSummaryService.createMsg(msgSummary, userIds);
-            wsSendService.sendMsg(msgSummary.getType(), userIds);
+            wsSendService.sendMsg(userIds, JsonUtils.toJson(msgSummary));
         }
     }
 

+ 4 - 1
src/main/resources/application-dev-conf.yml

@@ -34,4 +34,7 @@ app:
       app-secret:
     pubnum:
       app-id:
-      app-secret:
+      app-secret:
+uniapp:
+  cloud: #云推送消息地址
+    url: https://fc-mp-8aebd649-838c-4859-a7f9-2df57bc08f83.next.bspapp.com/test

+ 7 - 4
src/main/resources/application-local-conf.yml

@@ -1,9 +1,9 @@
 env:
   server:
     port: 8080
-#    ssl-key-store: gift_dev.pkcs12
-#    ssl-key-store-password: 123456
-#    ssl-store-type: pkcs12
+    #    ssl-key-store: gift_dev.pkcs12
+    #    ssl-key-store-password: 123456
+    #    ssl-store-type: pkcs12
     pool-min-spare: 10
   db:
     ip: 127.0.0.1
@@ -34,4 +34,7 @@ app:
       app-secret:
     pubnum:
       app-id:
-      app-secret:
+      app-secret:
+uniapp:
+  cloud: #云推送消息地址
+    url: https://fc-mp-8aebd649-838c-4859-a7f9-2df57bc08f83.next.bspapp.com/test

+ 33 - 0
src/main/resources/db/V2.03__20240117_initdir.sql

@@ -0,0 +1,33 @@
+-- ----------------------------
+-- Table structure for product_dir
+-- ----------------------------
+DROP TABLE IF EXISTS "public"."product_dir";
+CREATE TABLE "public"."product_dir" (
+    "id"           VARCHAR(36) COLLATE "pg_catalog"."default"  NOT NULL PRIMARY KEY,
+    "code"           VARCHAR(128) COLLATE "pg_catalog"."default" NOT NULL,
+    "name"         VARCHAR(128) COLLATE "pg_catalog"."default" NOT NULL,
+    "parent_id"    VARCHAR(64) COLLATE "pg_catalog"."default",
+    "path"         TEXT COLLATE "pg_catalog"."default" DEFAULT '[]',
+    "image"        VARCHAR(64) COLLATE "pg_catalog"."default",
+    "remark"       VARCHAR(256) COLLATE "pg_catalog"."default",
+    "ext1"         VARCHAR(1024) COLLATE "pg_catalog"."default",
+    "ext2"         VARCHAR(1024) COLLATE "pg_catalog"."default",
+    "ext3"         TEXT COLLATE "pg_catalog"."default" DEFAULT '{}',
+    "gmt_create"   TIMESTAMP(3)                                NOT NULL,
+    "gmt_modified" TIMESTAMP(3)                                NOT NULL,
+    "sys_id"       VARCHAR(36) COLLATE "pg_catalog"."default"  NOT NULL
+);
+COMMENT ON TABLE "public"."product_dir" IS '产品目录表';
+COMMENT ON COLUMN "public"."product_dir"."id" IS 'id';
+COMMENT ON COLUMN "public"."product_dir"."code" IS '标识符';
+COMMENT ON COLUMN "public"."product_dir"."name" IS '名称';
+COMMENT ON COLUMN "public"."product_dir"."parent_id" IS '父目录Id';
+COMMENT ON COLUMN "public"."product_dir"."path" IS '路径';
+COMMENT ON COLUMN "public"."product_dir"."image" IS '图片';
+COMMENT ON COLUMN "public"."product_dir"."remark" IS '备注';
+COMMENT ON COLUMN "public"."product_dir"."ext1" IS '扩展字段1';
+COMMENT ON COLUMN "public"."product_dir"."ext2" IS '扩展字段2';
+COMMENT ON COLUMN "public"."product_dir"."ext3" IS '扩展字段3';
+COMMENT ON COLUMN "public"."product_dir"."gmt_create" IS '创建时间';
+COMMENT ON COLUMN "public"."product_dir"."gmt_modified" IS '更新时间';
+COMMENT ON COLUMN "public"."product_dir"."sys_id" IS '系统ID';

+ 18 - 3
src/main/resources/init/auth/auth.json

@@ -9,11 +9,26 @@
     ],
     "menus":[
         {
-            "name":"组织管理:供应商管理",
+            "name":"SRM管理",
+            "otherName":"SRM管理",
+            "code":"srm",
+            "icon": "profile",
+            "routeUri":"srm",
+            "orderNum":7
+        },
+        {
+            "name":"SRM管理:供应商管理",
             "otherName":"供应商管理",
-            "code":"organization_supplier",
+            "code":"srm_supplier",
             "routeUri":"supplier",
-            "orderNum":25
+            "orderNum":71
+        },
+        {
+            "name":"SRM管理:产品目录",
+            "otherName":"产品目录",
+            "code":"srm_products",
+            "routeUri":"products",
+            "orderNum":72
         }
     ]
 }