Просмотр исходного кода

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

tanbin 5 месяцев назад
Родитель
Сommit
1a12e19d3e

+ 19 - 0
sys-api-cloud/src/main/java/com/xy/feign/SysDictLogFeign.java

@@ -0,0 +1,19 @@
+package com.xy.feign;
+
+import com.xy.service.SysDictLogService;
+import com.xy.FeignInterceptor;
+import com.xy.consts.ServiceConsts;
+import org.springframework.cloud.openfeign.FeignClient;
+
+/**
+ * <p>
+ * 字典表 feign
+ * </p>
+ *
+ * @author 谭斌
+ * @since 2024-10-09
+ */
+@FeignClient(value = ServiceConsts.SERVICE_NAME, configuration = FeignInterceptor.class)
+public interface SysDictLogFeign extends SysDictLogService {
+
+}

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

@@ -0,0 +1,78 @@
+package com.xy.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 字典表
+ * </p>
+ *
+ * @author 谭斌
+ * @since 2024-10-09
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "SysDictLog对象", description = "字典表")
+public class SysDictLog implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "id")
+    @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;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(value = "创建人")
+    @TableField(fill = FieldFill.INSERT)
+    private Long createUser;
+
+    @ApiModelProperty(value = "操作类型(1新增,2修改,3删除)")
+    private Integer operateType;
+
+    @ApiModelProperty(value = "是否同步生产")
+    private Boolean isSync;
+
+
+    /**
+     * 排序 正序
+     */
+    private Integer orders;
+
+    /**
+     * 回显样式
+     */
+    private String listClass;
+
+    /**
+     * 回显class
+     */
+    private String cssClass;
+
+
+}

+ 16 - 0
sys-api-service/src/main/java/com/xy/mapper/SysDictLogMapper.java

@@ -0,0 +1,16 @@
+package com.xy.mapper;
+
+import com.xy.entity.SysDictLog;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 字典表 Mapper 接口
+ * </p>
+ *
+ * @author 谭斌
+ * @since 2024-10-09
+ */
+public interface SysDictLogMapper extends BaseMapper<SysDictLog> {
+
+}

+ 17 - 0
sys-api-service/src/main/java/com/xy/mapper/mapper/SysDictLogMapper.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.xy.mapper.SysDictLogMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.xy.entity.SysDictLog">
+        <id column="id" property="id" />
+        <result column="pater_code" property="paterCode" />
+        <result column="code" property="code" />
+        <result column="msg" property="msg" />
+        <result column="create_time" property="createTime" />
+        <result column="create_user" property="createUser" />
+        <result column="operate_type" property="operateType" />
+        <result column="is_sync" property="isSync" />
+    </resultMap>
+
+</mapper>

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

@@ -0,0 +1,107 @@
+package com.xy.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.xy.dto.SysDictLogDto;
+import com.xy.entity.SysDictLog;
+import com.xy.mapper.SysDictLogMapper;
+import com.xy.sys.EnumSysDictOperateType;
+import com.xy.utils.Emptys;
+import com.xy.utils.MybatisPlusQuery;
+import com.xy.utils.PageBean;
+import com.xy.utils.R;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
+
+import static com.xy.utils.Beans.copy;
+import static com.xy.utils.PlusBeans.toIPage;
+import static com.xy.utils.PlusBeans.toPageBean;
+
+
+/**
+ * <p>
+ * 字典表 服务实现类
+ * </p>
+ *
+ * @author 谭斌
+ * @since 2024-10-09
+ */
+@Slf4j
+@Service
+@AllArgsConstructor
+@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) {
+        SysDictLogDto.SelectList selectList = copy(SysDictLogDto.SelectList.class, vo);
+        List<SysDictLogDto.Vo> list = list(selectList).getData();
+        if (Emptys.check(list)) {
+            return R.ok(list.get(0));
+        }
+        return R.ok();
+    }
+
+    /**
+     * 处理日志
+     *
+     * @param sysDictLog
+     * @param operateType
+     * @return
+     */
+    public boolean handleLog(SysDictLog sysDictLog, EnumSysDictOperateType operateType) {
+        sysDictLog.setId(null);
+        sysDictLog.setIsSync(false);
+        sysDictLog.setOperateType(operateType.getIntCode());
+        this.save(sysDictLog);
+        return true;
+    }
+
+    @PostMapping("list")
+    @ApiOperation("集合查询")
+    public R<List<SysDictLogDto.Vo>> list(@RequestBody SysDictLogDto.SelectList selectList) {
+        LambdaQueryWrapper<SysDictLog> lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(selectList, SysDictLog.class).build();
+        List<SysDictLog> list = list(lambdaQueryWrapper);
+        return R.ok(copy(SysDictLogDto.Vo.class, list));
+    }
+
+    @PostMapping("page")
+    @ApiOperation("分页查询")
+    public R<PageBean<SysDictLogDto.Vo>> page(@RequestBody SysDictLogDto.Page page) {
+        PageBean pageBean = page.getPage();
+        LambdaQueryWrapper<SysDictLog> lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(page, SysDictLog.class).build()
+                .ge(page.getBeginTime() != null, SysDictLog::getCreateTime, page.getBeginTime()).le(page.getEndTime() != null, SysDictLog::getCreateTime, page.getEndTime());
+        IPage<SysDictLog> iPage = page(toIPage(pageBean), lambdaQueryWrapper);
+        return R.ok(toPageBean(SysDictLogDto.Vo.class, iPage));
+    }
+
+    @PostMapping("save")
+    @ApiOperation("添加")
+    public R save(@RequestBody @Validated SysDictLogDto.Save save) {
+        SysDictLog saveInfo = copy(SysDictLog.class, save);
+        save(saveInfo);
+        return R.ok();
+    }
+
+    @PostMapping("update")
+    @ApiOperation("修改")
+    public R update(@RequestBody @Validated SysDictLogDto.Update update) {
+        SysDictLog updateInfo = copy(SysDictLog.class, update);
+        updateById(updateInfo);
+        return R.ok();
+    }
+}

+ 308 - 16
sys-api-service/src/main/java/com/xy/service/SysDictServiceImpl.java

@@ -1,17 +1,27 @@
 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;
 import com.xy.collections.list.JList;
 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.*;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -25,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;
 
@@ -46,7 +57,32 @@ 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;
+    }
 
 
     /**
@@ -58,26 +94,243 @@ 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();
-        }
-        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);
-        }
-        //TODO 同步到生产环境
+        String code = syncProd.getCode();
+        Integer operateType = syncProd.getOperateType();
+        if (SysDictDto.SYNC_PWD.equals(syncProd.getPwd())) {
+            throw new CommRuntimeException("非法请求!");
+        }
+        try {
+            if (StrUtil.isEmpty(paterCode)) {
+                //根字典
+                handleRootDict(syncProd, code, operateType);
+            } else {
+                //子字典
+                handleChildDict(syncProd, paterCode, operateType);
+            }
+        } catch (Exception e) {
+            log.error("同步到生产环境失败", e);
+            return R.fail("同步失败,请稍后重试");
+        }
+
+        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("同步失败,请稍后重试");
+        } else {
+            sysDictLog.setIsSync(true);
+            sysDictLogService.updateById(sysDictLog);
+        }
         return R.ok();
     }
 
+
     @ApiOperation("添加")
     @PostMapping("save")
     public R save(@RequestBody @Validated SysDictDto.Save save) {
@@ -90,6 +343,9 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
         SysDict sysDict = copy(SysDict.class, save)
                 .createUserTime(AuthorizeUtils.getLoginId(Long.class));
         save(sysDict);
+        //日志
+        SysDictLog sysDictLog = BeanUtil.copyProperties(sysDict, SysDictLog.class);
+        sysDictLogService.handleLog(sysDictLog, EnumSysDictOperateType.ADD);
         //刷新redis
         refuRedis(sysDict);
         return R.ok();
@@ -106,12 +362,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();
@@ -125,6 +399,14 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
         List<Integer> ids = del.getId();
         List<SysDict> list = list(new LambdaQueryWrapper<SysDict>().in(SysDict::getId, ids));
         removeBatchByIds(ids);
+        //日志
+        if (CollUtil.isNotEmpty(list)) {
+            list.forEach(sysDict -> {
+                SysDictLog sysDictLog = BeanUtil.copyProperties(sysDict, SysDictLog.class);
+                sysDictLogService.handleLog(sysDictLog, EnumSysDictOperateType.DEL);
+            });
+        }
+
         //删除子字典
         JList<SysDict> paters = new JArrayList<>(list).filter().isNull(SysDict::getPaterCode).list();
         JList<SysDict> paters2 = new JArrayList<>(list).filter().eq(SysDict::getPaterCode, "").list();
@@ -133,7 +415,17 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
         }
         if (Emptys.check(paters)) {
             JList<String> codes = paters.getProperty(SysDict::getCode);
-            remove(new LambdaQueryWrapper<SysDict>().in(SysDict::getPaterCode, codes));
+            LambdaQueryWrapper<SysDict> lqw = new LambdaQueryWrapper<SysDict>().in(SysDict::getPaterCode, codes);
+            List<SysDict> sysDicts = list(lqw);
+            if (CollUtil.isNotEmpty(sysDicts)) {
+                removeBatchByIds(sysDicts);
+                sysDicts.forEach(sysDict -> {
+                    SysDictLog sysDictLog = BeanUtil.copyProperties(sysDict, SysDictLog.class);
+                    sysDictLogService.handleLog(sysDictLog, EnumSysDictOperateType.DEL);
+                });
+            }
+
+
         }
         //刷新redis
         list.forEach(sysDict -> refuRedis(sysDict));

+ 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 {

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

@@ -0,0 +1,99 @@
+package com.xy.dto;
+
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.xy.utils.PageBean;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 字典表
+ * </p>
+ *
+ * @author 谭斌
+ * @since 2024-10-09
+ */
+public class SysDictLogDto {
+
+    @Data
+    @Accessors(chain = true)
+    public static class SelectList extends Vo {
+
+    }
+
+    @Data
+    @Accessors(chain = true)
+    public static class Page extends Vo {
+
+        @ApiModelProperty(value = "分页对象", required = true)
+        private PageBean page;
+
+
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+        @ApiModelProperty(value = "创建时间-起")
+        private LocalDateTime beginTime;
+
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+        @ApiModelProperty(value = "创建时间-始")
+        private LocalDateTime endTime;
+
+    }
+
+    @Data
+    @Accessors(chain = true)
+    public static class Save extends Vo {
+
+    }
+
+    @Data
+    @Accessors(chain = true)
+    public static class Update extends Vo {
+
+    }
+
+    @Data
+    @Accessors(chain = true)
+    public static class Vo {
+
+        @ApiModelProperty(value = "id")
+        private Long id;
+
+        @ApiModelProperty(value = "字典ID")
+        private Integer sysDictId;
+
+        @ApiModelProperty(value = "父编码")
+        private String paterCode;
+
+        @ApiModelProperty(value = "编码")
+        private String code;
+
+        @ApiModelProperty(value = "说明")
+        private String msg;
+
+        @ApiModelProperty(value = "创建时间")
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+        private LocalDateTime createTime;
+
+        @ApiModelProperty(value = "创建人")
+        private Long createUser;
+
+        @ApiModelProperty(value = "操作类型(1新增,2修改,3删除)")
+        private Integer operateType;
+
+        @ApiModelProperty(value = "是否同步生产")
+        private Boolean isSync;
+
+        @ApiModelProperty(value = "旧父编码")
+        private String oldPaterCode;
+
+        @ApiModelProperty(value = "旧编码")
+        private String oldCode;
+
+
+    }
+
+}

+ 16 - 0
sys-api/src/main/java/com/xy/service/SysDictLogService.java

@@ -0,0 +1,16 @@
+package com.xy.service;
+
+import com.xy.annotate.RestMappingController;
+
+/**
+ * <p>
+ * 字典表 服务类
+ * </p>
+ *
+ * @author 谭斌
+ * @since 2024-10-09
+ */
+@RestMappingController("/sys-dict-log")
+public interface SysDictLogService {
+
+}