Przeglądaj źródła

Merge remote-tracking branch 'origin/master' into test

tanbin 5 miesięcy temu
rodzic
commit
6e5a1dcce6

+ 18 - 0
sys-api-service/src/main/java/com/xy/entity/SysDictLog.java

@@ -33,12 +33,14 @@ public class SysDictLog implements Serializable {
     @TableId(value = "id", type = IdType.ASSIGN_ID)
     private Long id;
 
+
     @ApiModelProperty(value = "父编码")
     private String paterCode;
 
     @ApiModelProperty(value = "编码")
     private String code;
 
+
     @ApiModelProperty(value = "说明")
     private String msg;
 
@@ -57,4 +59,20 @@ public class SysDictLog implements Serializable {
     private Boolean isSync;
 
 
+    /**
+     * 排序 正序
+     */
+    private Integer orders;
+
+    /**
+     * 回显样式
+     */
+    private String listClass;
+
+    /**
+     * 回显class
+     */
+    private String cssClass;
+
+
 }

+ 9 - 0
sys-api-service/src/main/java/com/xy/service/SysDictLogServiceImpl.java

@@ -14,6 +14,7 @@ import com.xy.utils.R;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
+import org.springframework.core.env.Environment;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -39,6 +40,9 @@ import static com.xy.utils.PlusBeans.toPageBean;
 @Api(tags = "字典表")
 public class SysDictLogServiceImpl extends ServiceImpl<SysDictLogMapper, SysDictLog> implements SysDictLogService {
 
+
+    private Environment environment;
+
     @PostMapping("obj")
     @ApiOperation("对象查询")
     public R<SysDictLogDto.Vo> obj(@RequestBody SysDictLogDto.Vo vo) {
@@ -58,6 +62,11 @@ public class SysDictLogServiceImpl extends ServiceImpl<SysDictLogMapper, SysDict
      * @return
      */
     public boolean handleLog(SysDictLog sysDictLog, EnumSysDictOperateType operateType) {
+        // 判断当前环境是否为测试环境
+        String activeProfile = environment.getActiveProfiles()[0];
+        if (!activeProfile.equals("uat")) {
+            return false; // 如果不是测试环境,返回false
+        }
         sysDictLog.setId(null);
         sysDictLog.setIsSync(false);
         sysDictLog.setOperateType(operateType.getIntCode());

+ 274 - 13
sys-api-service/src/main/java/com/xy/service/SysDictServiceImpl.java

@@ -2,9 +2,15 @@ package com.xy.service;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.CharsetUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.xy.annotate.Runners;
 import com.xy.collections.list.JArrayList;
@@ -13,6 +19,7 @@ import com.xy.dto.SysDictDto;
 import com.xy.entity.SysDict;
 import com.xy.entity.SysDictLog;
 import com.xy.entity.SysDictRedis;
+import com.xy.error.CommRuntimeException;
 import com.xy.mapper.SysDictMapper;
 import com.xy.sys.EnumSysDictOperateType;
 import com.xy.utils.*;
@@ -28,6 +35,7 @@ import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestHeader;
 
+import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -49,9 +57,33 @@ import static com.xy.utils.PlusBeans.toPageBean;
 @Api(tags = "系统字典")
 public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements SysDictService {
 
+    private static final String SYNC_DICT_URL = "https://api.mxrvending.com/sys/sys-dict/syncProd";
+    //    private static final String SYNC_DICT_URL = "http://119.96.194.20:9050/sys/sys-dict/syncProd";
     private RedisService<SysDictRedis> redisService;
     private SysDictLogServiceImpl sysDictLogService;
 
+    /**
+     * post请求
+     *
+     * @param url  url
+     * @param body spi参数
+     * @return {@link String}
+     */
+    static String sendPost(String url, String body) {
+        HttpResponse resultStr = HttpRequest.post(url)
+                .header("Content-Type", "application/json") // 修改为 JSON 格式
+                .charset(CharsetUtil.UTF_8)
+                .body(body) // 使用 JSON 字符串作为请求体
+                .timeout(30 * 1000)
+                .execute();
+        String responseBody = resultStr.body();
+        if (resultStr.getStatus() != 200) {
+            log.error("字典同步到生产环境异常: 状态码: {}, 响应体: {},appId:{},notifyId:{}", resultStr.getStatus(), responseBody);
+            return "fail";
+        }
+        return responseBody;
+    }
+
 
     /**
      * 全量刷新redis字典数据
@@ -62,26 +94,240 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
         SysDicts.forEach(sysDict -> refuRedis(sysDict));
     }
 
-    @ApiOperation("同步到生产环境")
+    /**
+     * 同步到生产环境,处理接收到的字典数据  nacos加白名单
+     *
+     * @param syncProd 目标字典数据
+     * @return 响应结果
+     */
+    @ApiOperation("同步到生产环境-接收处理")
     @PostMapping("syncProd")
-    public R syncProd(@RequestBody @Validated SysDictDto.SyncProd syncProd) {
+    public R syncProd(@RequestBody SysDictDto.SyncProd syncProd) {
+        log.info("字典同步数据: {}", JSONUtil.toJsonPrettyStr(syncProd));
         String paterCode = syncProd.getPaterCode();
-        LambdaQueryWrapper<SysDict> lambdaQueryWrapper = new LambdaQueryWrapper<SysDict>().eq(SysDict::getCode, paterCode);
-        SysDict sysDict = getOne(lambdaQueryWrapper);
-        if (sysDict == null) {
-            return R.ok();
+        String code = syncProd.getCode();
+        Integer operateType = syncProd.getOperateType();
+        if (SysDictDto.SYNC_PWD.equals(syncProd.getPwd())) {
+            throw new CommRuntimeException("非法请求!");
         }
-        List<SysDict> sysDictsAll = new ArrayList<>();
-        sysDictsAll.add(sysDict);
-        LambdaQueryWrapper<SysDict> lambdaQueryWrapperSub = new LambdaQueryWrapper<SysDict>().eq(SysDict::getCode, paterCode);
-        List<SysDict> sysDicts = list(lambdaQueryWrapperSub);
-        if (CollUtil.isNotEmpty(sysDicts)) {
-            sysDictsAll.addAll(sysDicts);
+        try {
+            if (StrUtil.isEmpty(paterCode)) {
+                //根字典
+                handleRootDict(syncProd, code, operateType);
+            } else {
+                //子字典
+                handleChildDict(syncProd, paterCode, operateType);
+            }
+        } catch (Exception e) {
+            log.error("同步到生产环境失败", e);
+            return R.fail("同步失败,请稍后重试");
         }
-        //TODO 同步到生产环境
+
         return R.ok();
     }
 
+    /**
+     * 处理根字典的操作,根据操作类型决定增加、更新或删除
+     *
+     * @param syncProd    目标字典数据
+     * @param code        字典代码
+     * @param operateType 操作类型
+     */
+    private void handleRootDict(SysDictDto.SyncProd syncProd, String code, Integer operateType) {
+        switch (operateType) {
+            case 1:
+                addRootDict(syncProd, code);
+                break;
+            case 2:
+                updateRootDict(syncProd);
+                break;
+            case 3:
+                deleteRootDict(syncProd.getCode());
+                break;
+            default:
+                log.warn("未知操作类型: {}", operateType);
+        }
+    }
+
+    /**
+     * 处理子字典的操作,根据操作类型决定增加、更新或删除
+     *
+     * @param syncProd    目标字典数据
+     * @param paterCode   父级字典代码
+     * @param operateType 操作类型
+     */
+    private void handleChildDict(SysDictDto.SyncProd syncProd, String paterCode, Integer operateType) {
+        switch (operateType) {
+            case 1:
+                addChildDict(syncProd, paterCode);
+                break;
+            case 2:
+                updateChildDict(syncProd, paterCode);
+                break;
+            case 3:
+                deleteChildDict(syncProd, paterCode);
+                break;
+            default:
+                log.warn("未知操作类型: {}", operateType);
+        }
+    }
+
+    /**
+     * 添加根字典,如果字典代码不存在则创建新的字典
+     *
+     * @param syncProd 目标字典数据
+     * @param code     字典代码
+     */
+    private void addRootDict(SysDictDto.SyncProd syncProd, String code) {
+        long count = count(new LambdaQueryWrapper<SysDict>().eq(SysDict::getCode, code));
+        if (count <= 0) {
+            SysDict sysDict = createSysDict(syncProd);
+            save(sysDict);
+            refuRedis(sysDict);
+        }
+    }
+
+    /**
+     * 更新根字典,若不存在则调用添加方法
+     *
+     * @param syncProd 目标字典数据
+     */
+    private void updateRootDict(SysDictDto.SyncProd syncProd) {
+        SysDict sysP = getOne(Wrappers.lambdaQuery(SysDict.class).eq(SysDict::getCode, syncProd.getCode()));
+        if (sysP == null) {
+            addRootDict(syncProd, syncProd.getCode());
+        } else {
+            updateSysDict(sysP, syncProd);
+        }
+    }
+
+    /**
+     * 删除根字典及其相关的子字典
+     *
+     * @param code 字典代码
+     */
+    private void deleteRootDict(String code) {
+        List<SysDict> sysDicts = getRelatedDicts(code);
+        remove(Wrappers.lambdaQuery(SysDict.class).eq(SysDict::getCode, code));
+        remove(Wrappers.lambdaQuery(SysDict.class).eq(SysDict::getPaterCode, code));
+        sysDicts.forEach(this::refuRedis);
+    }
+
+    /**
+     * 添加子字典,如果代码不存在则创建新的字典
+     *
+     * @param syncProd  目标字典数据
+     * @param paterCode 父级字典代码
+     */
+    private void addChildDict(SysDictDto.SyncProd syncProd, String paterCode) {
+        long count = count(new LambdaQueryWrapper<SysDict>().eq(SysDict::getCode, syncProd.getCode()).eq(SysDict::getPaterCode, paterCode));
+        if (count <= 0) {
+            SysDict sysDict = createSysDict(syncProd);
+            save(sysDict);
+            refuRedis(sysDict);
+        }
+    }
+
+    /**
+     * 更新子字典,若不存在则调用添加方法
+     *
+     * @param syncProd  目标字典数据
+     * @param paterCode 父级字典代码
+     */
+    private void updateChildDict(SysDictDto.SyncProd syncProd, String paterCode) {
+        SysDict sysP = getOne(Wrappers.lambdaQuery(SysDict.class)
+                .eq(SysDict::getCode, syncProd.getCode())
+                .eq(SysDict::getPaterCode, paterCode));
+        if (sysP == null) {
+            addChildDict(syncProd, paterCode);
+        } else {
+            updateSysDict(sysP, syncProd);
+        }
+    }
+
+    /**
+     * 删除子字典
+     *
+     * @param syncProd  目标字典数据
+     * @param paterCode 父级字典代码
+     */
+    private void deleteChildDict(SysDictDto.SyncProd syncProd, String paterCode) {
+        List<SysDict> list = new ArrayList<>();
+        SysDict sysDict = getOne(Wrappers.lambdaQuery(SysDict.class)
+                .eq(SysDict::getCode, syncProd.getCode())
+                .eq(SysDict::getPaterCode, paterCode));
+        if (sysDict != null) {
+            list.add(sysDict);
+            remove(Wrappers.lambdaQuery(SysDict.class).eq(SysDict::getPaterCode, syncProd.getCode()).eq(SysDict::getCode, syncProd.getCode()));
+            list.forEach(this::refuRedis);
+        }
+    }
+
+    /**
+     * 创建新的字典对象
+     *
+     * @param syncProd 目标字典数据
+     * @return 新创建的字典对象
+     */
+    private SysDict createSysDict(SysDictDto.SyncProd syncProd) {
+        SysDict sysDict = BeanUtil.copyProperties(syncProd, SysDict.class);
+        sysDict.setCreateTime(LocalDateTime.now());
+        sysDict.setCreateUser(1L);
+        return sysDict;
+    }
+
+    /**
+     * 更新字典对象的属性
+     *
+     * @param sysDict  需要更新的字典对象
+     * @param syncProd 目标字典数据
+     */
+    private void updateSysDict(SysDict sysDict, SysDictDto.SyncProd syncProd) {
+        sysDict.setValue(syncProd.getValue());
+        sysDict.setMsg(syncProd.getMsg());
+        sysDict.setUpdateTime(LocalDateTime.now());
+        updateById(sysDict);
+        refuRedis(sysDict);
+    }
+
+    /**
+     * 根据字典代码获取相关的字典
+     *
+     * @param code 字典代码
+     * @return 相关字典列表
+     */
+    private List<SysDict> getRelatedDicts(String code) {
+        List<SysDict> list = new ArrayList<>();
+        SysDict sysDict = getOne(Wrappers.lambdaQuery(SysDict.class).eq(SysDict::getCode, code));
+        if (sysDict != null) {
+            list.add(sysDict);
+            LambdaQueryWrapper<SysDict> lqw = Wrappers.lambdaQuery(SysDict.class).eq(SysDict::getPaterCode, code);
+            List<SysDict> sysDicts = list(lqw);
+            if (CollUtil.isNotEmpty(sysDicts)) {
+                list.addAll(sysDicts);
+            }
+        }
+        return list;
+    }
+
+    @ApiOperation("手动同步到生产环境")
+    @PostMapping("syncToProd")
+    public R syncToProd(@RequestBody @Validated SysDictDto.SyncToProd syncToProd) {
+        Long id = syncToProd.getId();
+        SysDictLog sysDictLog = sysDictLogService.getById(id);
+        // 确保获取到的字典日志不为空
+        if (sysDictLog == null) {
+            return R.fail("字典日志不存在");
+        }
+        SysDictDto.SyncProd syncProd = BeanUtil.copyProperties(sysDictLog, SysDictDto.SyncProd.class);
+        String res = sendPost(SYNC_DICT_URL, JSONUtil.toJsonStr(syncProd));
+        if ("fail".equals(res)) {
+            return R.fail("同步失败,请稍后重试");
+        }
+        return R.ok();
+    }
+
+
     @ApiOperation("添加")
     @PostMapping("save")
     public R save(@RequestBody @Validated SysDictDto.Save save) {
@@ -113,15 +359,30 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
                 return R.fail("code已存在");
             }
         }
+        //如果根字典code修改,则 子字典也要记录日志(作为新增)
+        if (StrUtil.isEmpty(sysDict.getPaterCode()) && !sysDict.getCode().equals(update.getCode())) {
+            LambdaQueryWrapper<SysDict> lambdaQueryWrapper = new LambdaQueryWrapper<SysDict>().eq(SysDict::getPaterCode, sysDict.getCode());
+            List<SysDict> sysDicts = list(lambdaQueryWrapper);
+            if (CollUtil.isNotEmpty(sysDicts)) {
+                //存在子字典,修改日志记录
+                sysDicts.forEach(sd -> {
+                    sd.setPaterCode(update.getCode());
+                    SysDictLog sysDictLog = BeanUtil.copyProperties(sd, SysDictLog.class);
+                    sysDictLogService.handleLog(sysDictLog, EnumSysDictOperateType.ADD);
+                });
+            }
+        }
         //修改字典
         SysDict obj = copy(SysDict.class, update)
                 .update(AuthorizeUtils.getLoginId(Long.class));
         updateById(obj);
+
         //修改子字典
         update(new SysDict().setPaterCode(obj.getCode()), new LambdaQueryWrapper<SysDict>().eq(SysDict::getPaterCode, sysDict.getCode()));
         //日志
         SysDictLog sysDictLog = BeanUtil.copyProperties(sysDict, SysDictLog.class);
         sysDictLogService.handleLog(sysDictLog, EnumSysDictOperateType.UPDATE);
+
         //刷新redis
         refuRedis(obj);
         return R.ok();

+ 48 - 1
sys-api/src/main/java/com/xy/dto/SysDictDto.java

@@ -21,14 +21,61 @@ import java.util.List;
 @Accessors(chain = true)
 public class SysDictDto {
 
+    public static final String SYNC_PWD = "xySyncDict1qaz@WSX";
+
     @Data
     @Accessors(chain = true)
     public static class SyncProd {
-        @NotBlank(message = "父编码不能为空")
+
+
+        @ApiModelProperty(value = "操作类型(1新增,2修改,3删除)")
+        private Integer operateType;
+
         @ApiModelProperty("父编码")
         private String paterCode;
+
+        @NotBlank(message = "code不能为空")
+        @ApiModelProperty("编码")
+        private String code;
+
+
+        @NotBlank(message = "value不能为空")
+        @ApiModelProperty("编码值")
+        private String value;
+
+        @NotBlank(message = "msg不能为空")
+        @ApiModelProperty("编码说明")
+        private String msg;
+
+        @ApiModelProperty("排序 正序")
+        private Integer orders;
+
+        @ApiModelProperty("回显样式")
+        private String listClass;
+
+        @ApiModelProperty("回显class")
+        private String cssClass;
+
+        @ApiModelProperty("等级")
+        private Integer level;
+
+
+        @ApiModelProperty("密码")
+        private String pwd;
+
+
     }
 
+    @Data
+    @Accessors(chain = true)
+    public static class SyncToProd {
+        @NotBlank(message = "logId不能为空")
+        @ApiModelProperty(value = "logId")
+        private Long id;
+
+    }
+
+
     @Data
     @Accessors(chain = true)
     public static class Save {

+ 9 - 0
sys-api/src/main/java/com/xy/dto/SysDictLogDto.java

@@ -62,6 +62,9 @@ public class SysDictLogDto {
         @ApiModelProperty(value = "id")
         private Long id;
 
+        @ApiModelProperty(value = "字典ID")
+        private Integer sysDictId;
+
         @ApiModelProperty(value = "父编码")
         private String paterCode;
 
@@ -84,6 +87,12 @@ public class SysDictLogDto {
         @ApiModelProperty(value = "是否同步生产")
         private Boolean isSync;
 
+        @ApiModelProperty(value = "旧父编码")
+        private String oldPaterCode;
+
+        @ApiModelProperty(value = "旧编码")
+        private String oldCode;
+
 
     }