系统数据字典同步(临时提交)

This commit is contained in:
1378012178@qq.com 2025-05-07 14:18:46 +08:00
parent b0261bc819
commit 217c5844dc
17 changed files with 352 additions and 2 deletions

View File

@ -18,7 +18,7 @@ public class AdvisoryMQExceptionHandler implements RabbitListenerErrorHandler {
// 根据异常类型选择处理策略 // 根据异常类型选择处理策略
if (isRetryable(e)) { if (isRetryable(e)) {
// 可重试异常抛出异常触发重试 // 可重试异常抛出异常触发重试
throw e; throw new AmqpRejectAndDontRequeueException("消息处理失败且禁止重试", e);
} else { } else {
// 不可恢复异常拒绝消息且不重新入队 // 不可恢复异常拒绝消息且不重新入队
throw new AmqpRejectAndDontRequeueException("消息处理失败且禁止重试", e); throw new AmqpRejectAndDontRequeueException("消息处理失败且禁止重试", e);

View File

@ -0,0 +1,73 @@
package com.nu.modules.pad.appversionconfig.api;
import cn.hutool.core.util.StrUtil;
import com.nu.modules.pad.appversionconfig.entity.AppConfig;
import com.nu.modules.pad.appversionconfig.entity.R;
import com.nu.modules.pad.appversionconfig.entity.VersionInfo;
import com.nu.modules.pad.appversionconfig.service.IAppConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/nuIpadApi/versionManage")
@CrossOrigin("*")
public class VersionManageApi {
@Autowired
private IAppConfigService appConfigService;
/**
* APP版本更新
* 请求参数中其实不止传递了一下四个更多请看插件市场作者的文档https://ext.dcloud.net.cn/plugin?id=3931
* @param platform 平台android/ios
* @param name 应用名称
* @param version 应用版本名称 主版本号.次版本号.修订号
* @param code 应用版本号
* @return
*/
@RequestMapping("/versionUpdate")
public R check(String platform,String name,String version,String code) {
Map<String, Object> map = new HashMap<>();
VersionInfo info = new VersionInfo();
info.setUpdate_flag(0);
map.put("code", 100);
map.put("data", info);
AppConfig appConfig = appConfigService.findLastVersionInfo();
if(appConfig ==null) {
map.put("msg", "无版本配置信息");
return R.ok(map);
}
if(!StrUtil.isEmptyIfStr(version) && !StrUtil.isEmptyIfStr(platform)) {
int[] oldVers = StrUtil.splitToInt(version, ".");
int[] newVers = StrUtil.splitToInt(appConfig.getVersionCode(), ".");
boolean isUpdateFlag = false;
int length = oldVers.length > newVers.length ? newVers.length : oldVers.length;
for (int i = 0; i < length; i++) {
if(newVers[i] > oldVers[i]) {
isUpdateFlag = true;
break;
}
}
if(isUpdateFlag) {
info.setUpdate_flag(1);//0不需要更新1:需要更新
info.setVersion(appConfig.getVersionCode());
info.setUpdate_url(appConfig.getVersionUrl());
info.setUpdate_tips(appConfig.getUpdateTrips());
info.setForceupdate(appConfig.getIsForceUpdate());
map.put("code", 100);
map.put("msg", "应用程序需要更新");
map.put("data", info);
}
return R.ok(map);
}else {
map.put("code", 500);
map.put("msg", "请求参数不含版本号、平台");
map.put("data", info);
return R.ok(map);
}
}
}

View File

@ -16,7 +16,7 @@ import java.util.Map;
@RestController @RestController
@RequestMapping("/api/pad") @RequestMapping("/api/pad")
@CrossOrigin("*") @CrossOrigin("*")
public class VersionUpdateApi { public class VersionManageApiBK {
@Autowired @Autowired
private IAppConfigService appConfigService; private IAppConfigService appConfigService;

View File

@ -114,6 +114,7 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/sys/getQrcodeToken/**", "anon"); //监听扫码 filterChainDefinitionMap.put("/sys/getQrcodeToken/**", "anon"); //监听扫码
filterChainDefinitionMap.put("/sys/checkAuth", "anon"); //授权接口排除 filterChainDefinitionMap.put("/sys/checkAuth", "anon"); //授权接口排除
filterChainDefinitionMap.put("/api/pad/versionUpdate", "anon");//pad端版本检测接口 filterChainDefinitionMap.put("/api/pad/versionUpdate", "anon");//pad端版本检测接口
filterChainDefinitionMap.put("/nuIpadApi/versionManage/versionUpdate", "anon");//pad端版本检测接口
//update-begin--Author:scott Date:20221116 for排除静态资源后缀 //update-begin--Author:scott Date:20221116 for排除静态资源后缀
filterChainDefinitionMap.put("/", "anon"); filterChainDefinitionMap.put("/", "anon");

View File

@ -90,4 +90,5 @@ public class RabbitMQConfig {
public Binding bindingRegEdit(Queue registerEditQueue, DirectExchange registerExchange) { public Binding bindingRegEdit(Queue registerEditQueue, DirectExchange registerExchange) {
return BindingBuilder.bind(registerEditQueue).to(registerExchange).with("register.editData"); return BindingBuilder.bind(registerEditQueue).to(registerExchange).with("register.editData");
} }
} }

View File

@ -13,4 +13,7 @@ public class StatusMQDto {
private String asyncId; private String asyncId;
//同步表子表code //同步表子表code
private String code; private String code;
private String dictId;
private String orgCode;
} }

View File

@ -0,0 +1,70 @@
package com.nu.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
*
* </p>
*
* @Author zmy
* @since 2025-5-6
*/
@Data
public class SysDictItemMQDto implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id
*/
private String id;
/**
* 字典id
*/
private String dictId;
/**
* 字典项文本
*/
private String itemText;
/**
* 字典项值
*/
private String itemValue;
/**
* 描述
*/
private String description;
/**
* 排序
*/
private Integer sortOrder;
/**
* 状态1启用 0不启用
*/
private Integer status;
private String createBy;
private Date createTime;
private String updateBy;
private Date updateTime;
/**
* 字典项颜色
*/
private String itemColor;
}

View File

@ -0,0 +1,90 @@
package com.nu.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* <p>
* 字典表
* </p>
*
* @Author zmy
* @since 2025-5-6
*/
@Data
public class SysDictMQDto implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id
*/
private String id;
/**
* [预留字段暂时无用]
* 字典类型,0 string,1 number类型,2 boolean
* 前端js对stirng类型和number类型 boolean 类型敏感需要区分在select 标签匹配的时候会用到
* 默认为string类型
*/
private Integer type;
/**
* 字典名称
*/
private String dictName;
/**
* 字典编码
*/
private String dictCode;
/**
* 描述
*/
private String description;
/**
* 标识
* sys系统字典非客户使用字典
* nu业务字典客户使用字典
*/
private String tag;
/**
* 删除状态
*/
private Integer delFlag;
/**
* 创建人
*/
private String createBy;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新人
*/
private String updateBy;
/**
* 更新时间
*/
private Date updateTime;
/**租户ID*/
private Integer tenantId;
/** 关联的低代码应用ID */
private String lowAppId;
private List<SysDictItemMQDto> sysDictItemList;
}

View File

@ -35,6 +35,10 @@ public class AsyncMain implements Serializable {
@TableId(type = IdType.ASSIGN_ID) @TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "id") @ApiModelProperty(value = "id")
private java.lang.String id; private java.lang.String id;
/**被同步数据的主键id*/
@Excel(name = "被同步数据的主键id", width = 15)
@ApiModelProperty(value = "被同步数据的主键id")
private java.lang.String primaryKey;
/**机构编码*/ /**机构编码*/
@Excel(name = "机构编码", width = 15) @Excel(name = "机构编码", width = 15)
@ApiModelProperty(value = "机构编码") @ApiModelProperty(value = "机构编码")
@ -56,6 +60,10 @@ public class AsyncMain implements Serializable {
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建日期") @ApiModelProperty(value = "创建日期")
private java.util.Date createTime; private java.util.Date createTime;
/**状态*/
@Excel(name = "状态", width = 15)
@ApiModelProperty(value = "状态")
private java.lang.String status;
@TableField(exist = false) @TableField(exist = false)
private List<AsyncStatus> asyncStatusList; private List<AsyncStatus> asyncStatusList;

View File

@ -4,6 +4,7 @@
<resultMap id="asyncResultMap" type="com.nu.modules.async.entity.AsyncMain"> <resultMap id="asyncResultMap" type="com.nu.modules.async.entity.AsyncMain">
<id property="id" column="id"/> <id property="id" column="id"/>
<result property="primaryKey" column="primaryKey"/>
<result property="orgCode" column="orgCode"/> <result property="orgCode" column="orgCode"/>
<result property="type" column="type"/> <result property="type" column="type"/>
<result property="descr" column="descr"/> <result property="descr" column="descr"/>
@ -22,6 +23,7 @@
<select id="pageList" resultMap="asyncResultMap"> <select id="pageList" resultMap="asyncResultMap">
select select
f.id as id, f.id as id,
f.primary_key as primaryKey,
f.org_code as orgCode, f.org_code as orgCode,
f.type as type, f.type as type,
f.descr as descr, f.descr as descr,

View File

@ -25,6 +25,12 @@
<artifactId>hibernate-re</artifactId> <artifactId>hibernate-re</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.nursingunit.boot</groupId>
<artifactId>nursing-unit-common</artifactId>
<version>${nursingunit.version}</version>
</dependency>
<!-- 企业微信/钉钉 api --> <!-- 企业微信/钉钉 api -->
<dependency> <dependency>
<groupId>org.jeecgframework</groupId> <groupId>org.jeecgframework</groupId>

View File

@ -792,4 +792,10 @@ public class SysDictController {
sysDictService.editDictByLowAppId(sysDictVo); sysDictService.editDictByLowAppId(sysDictVo);
return Result.ok("编辑成功"); return Result.ok("编辑成功");
} }
@PostMapping("/async")
public Result<String> async(@RequestBody SysDict sysDict){
sysDictService.async(sysDict);
return Result.ok();
}
} }

View File

@ -300,4 +300,6 @@ public interface ISysDictService extends IService<SysDict> {
* @param ids * @param ids
*/ */
boolean removeLogicDeleted(List<String> ids); boolean removeLogicDeleted(List<String> ids);
void async(SysDict sysDict);
} }

View File

@ -1,12 +1,19 @@
package org.jeecg.modules.system.service.impl; package org.jeecg.modules.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.RandomUtil;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.nu.dto.SysDictItemMQDto;
import com.nu.dto.SysDictMQDto;
import com.nu.modules.async.entity.AsyncMain;
import com.nu.modules.async.service.IAsyncMainService;
import com.nu.utils.RabbitMQUtil;
import org.jeecg.modules.system.security.DictQueryBlackListHandler; import org.jeecg.modules.system.security.DictQueryBlackListHandler;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
@ -66,6 +73,10 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
private SysDictItemMapper sysDictItemMapper; private SysDictItemMapper sysDictItemMapper;
@Autowired @Autowired
private DictQueryBlackListHandler dictQueryBlackListHandler; private DictQueryBlackListHandler dictQueryBlackListHandler;
@Autowired
private RabbitMQUtil rabbitMQUtil;
@Autowired
private IAsyncMainService asyncMainService;
@Lazy @Lazy
@Autowired @Autowired
@ -894,6 +905,21 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
return line > 0; return line > 0;
} }
@Override
public void async(SysDict sysDict) {
QueryWrapper<AsyncMain> asyncMainQueryWrapper = new QueryWrapper<>();
asyncMainQueryWrapper.eq("primary_key",sysDict.getId());
asyncMainService.remove(asyncMainQueryWrapper);
SysDict sd = baseMapper.selectById(sysDict.getId());
List<SysDictItem> sysDictItems = sysDictItemMapper.selectItemsByMainId(sysDict.getId());
SysDictMQDto sysDictMQDto = new SysDictMQDto();
BeanUtils.copyProperties(sd,sysDictMQDto);
sysDictMQDto.setSysDictItemList(BeanUtil.copyToList(sysDictItems, SysDictItemMQDto.class));
rabbitMQUtil.sendToExchange("hldy.sysdict.fanout","",sysDictMQDto);
}
/** /**
* 添加字典 * 添加字典
* *

View File

@ -0,0 +1,28 @@
package com.nu.mq.directive.exceptionhandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpRejectAndDontRequeueException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.RabbitListenerErrorHandler;
import org.springframework.amqp.rabbit.support.ListenerExecutionFailedException;
import org.springframework.stereotype.Component;
@Slf4j
@Component("dictMQErrorHandler")
public class DictMQExceptionHandler implements RabbitListenerErrorHandler {
@Override
public Object handleError(Message message, org.springframework.messaging.Message<?> message1, ListenerExecutionFailedException e) {
log.error("MQ消息处理失败 | 消息体: {} | 异常原因: {}", new String(message.getBody()), e.getCause().getMessage());
// 根据异常类型选择处理策略
// if (isRetryable(e)) {
// // 可重试异常抛出异常触发重试
// throw e;
// } else {
// 不可恢复异常拒绝消息且不重新入队
throw new AmqpRejectAndDontRequeueException("消息处理失败且禁止重试", e);
// }
}
}

View File

@ -0,0 +1,28 @@
package org.jeecg.mq.dict.listener;
import com.nu.dto.StatusMQDto;
import com.nu.modules.async.entity.AsyncMain;
import com.nu.modules.async.service.IAsyncMainService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class DictMQListener {
@Autowired
private IAsyncMainService asyncMainService;
@RabbitListener(queues = "sysdict.async.result", errorHandler = "dictMQErrorHandler")
public void handleMessage(StatusMQDto dto) {
AsyncMain asyncMain = new AsyncMain();
asyncMain.setPrimaryKey(dto.getDictId());
asyncMain.setStatus(dto.getStatus()+"");
asyncMain.setOrgCode(dto.getOrgCode());
asyncMain.setDescr(dto.getMessage());
asyncMainService.save(asyncMain);
}
}

View File

@ -186,6 +186,12 @@ spring:
host: redis host: redis
port: 6379 port: 6379
password: uUgrUus4JAYuwxzo password: uUgrUus4JAYuwxzo
rabbitmq:
host: rabbitm
prot: 5672
username: hldy
password: SJ+lhRn6nZ43KeXE
virtual-host: /hldy
#mybatis plus 设置 #mybatis plus 设置
mybatis-plus: mybatis-plus:
mapper-locations: classpath*:org/jeecg/**/xml/*Mapper.xml,classpath*:com/nu/**/xml/*Mapper.xml mapper-locations: classpath*:org/jeecg/**/xml/*Mapper.xml,classpath*:com/nu/**/xml/*Mapper.xml