Browse Source

fix(tenant): 修复租户同步中tenantId类型错误及健壮性问题

- 将OnlCgreportHead和OnlFormHead的tenantId字段类型从String改为Long
- 修正同步处理中错误使用transId作为tenantId的问题,改为从消息体正确获取
- 新增parseRelativeFormCodes方法安全解析widgetJson,避免非法JSON抛异常
- 对in查询的空集合做防护,避免MyBatis-Plus传入空列表导致SQL异常
- 消息体中显式传递tenantId字段确保同步端可正确识别租户
- 角色查询中过滤null的roleId并使用LinkedHashSet去重
- 组织未配置角色时新增fallback机制回退到用户自身角色
- 表单元数据同步查询条件增加tenantId过滤确保租户隔离
feature/tenant-sync-online
chenchuchuan 2 days ago
parent
commit
937bdddea6
  1. 41
      application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/service/impl/OnlineFormTenantSyncServiceImpl.java
  2. 34
      application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/service/impl/SysTenantRoleServiceImpl.java
  3. 28
      application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/service/impl/SysUserServiceImpl.java
  4. 39
      application-tenant/tenant-sync/src/main/java/apelet/tenantsync/online/service/SysTenantOnlCgreporHeadServiceImpl.java
  5. 50
      application-tenant/tenant-sync/src/main/java/apelet/tenantsync/online/service/SysTenantOnlFormHeadServiceImpl.java
  6. 4
      common/common-generator/src/main/java/apelet/common/generator/model/OnlCgreportHead.java
  7. 3
      common/common-generator/src/main/java/apelet/common/generator/model/OnlFormHead.java

41
application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/service/impl/OnlineFormTenantSyncServiceImpl.java

@ -16,6 +16,7 @@ import com.alibaba.fastjson.JSONObject; @@ -16,6 +16,7 @@ import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jayway.jsonpath.JsonPath;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.redisson.api.RBucket;
@ -99,17 +100,24 @@ public class OnlineFormTenantSyncServiceImpl implements OnlineFormTenantSyncServ @@ -99,17 +100,24 @@ public class OnlineFormTenantSyncServiceImpl implements OnlineFormTenantSyncServ
}
// 根据表单json中的relativeFormCode获取到对应的查询数据源数据
String widgetJson = onlineForm.getWidgetJson();
List<String> relativeFormCodeList = JsonPath.read(widgetJson, "$..relativeFormCode");
List<OnlCgreportHead> onlCgreportHeadList = iOnlCgreportHeadService.list(new LambdaQueryWrapper<OnlCgreportHead>()
List<String> relativeFormCodeList = parseRelativeFormCodes(widgetJson);
List<OnlCgreportHead> onlCgreportHeadList = relativeFormCodeList.isEmpty()
? Collections.emptyList()
: iOnlCgreportHeadService.list(new LambdaQueryWrapper<OnlCgreportHead>()
.in(OnlCgreportHead::getCode, relativeFormCodeList));
List<String> onlCgreportHeadIdList = onlCgreportHeadList.stream().map(OnlCgreportHead::getId).collect(Collectors.toList());
List<OnlCgreportItem> onlCgreportItemList = iOnlCgreportItemService.list(new LambdaQueryWrapper<OnlCgreportItem>()
List<OnlCgreportItem> onlCgreportItemList = onlCgreportHeadIdList.isEmpty()
? Collections.emptyList()
: iOnlCgreportItemService.list(new LambdaQueryWrapper<OnlCgreportItem>()
.in(OnlCgreportItem::getCgrheadId, onlCgreportHeadIdList));
List<OnlCgreportParam> onlCgreportParamList = iOnlCgreportParamService.list(new LambdaQueryWrapper<OnlCgreportParam>()
List<OnlCgreportParam> onlCgreportParamList = onlCgreportHeadIdList.isEmpty()
? Collections.emptyList()
: iOnlCgreportParamService.list(new LambdaQueryWrapper<OnlCgreportParam>()
.in(OnlCgreportParam::getCgrheadId, onlCgreportHeadIdList));
for (Long tenantId : tenantIdSet) {
// 表单更新同步通知
JSONObject formMsgJsonData = new JSONObject();
formMsgJsonData.put("tenantId", tenantId);
formMsgJsonData.put("adminOnlineForm", onlineForm);
formMsgJsonData.put("originalOnlineForm", lastUpdateOnlineForm);
formMsgJsonData.put("datasourceIdSet", datasourceIdSet);
@ -122,6 +130,7 @@ public class OnlineFormTenantSyncServiceImpl implements OnlineFormTenantSyncServ @@ -122,6 +130,7 @@ public class OnlineFormTenantSyncServiceImpl implements OnlineFormTenantSyncServ
TenantConstant.MESSAGE_QUEUE_SELECTOR_KEY);
//表单数据源更新同步新增
JSONObject onlCgreportHeadMsgJsonData = new JSONObject();
onlCgreportHeadMsgJsonData.put("tenantId", tenantId);
onlCgreportHeadMsgJsonData.put("onlCgreportHeadList", onlCgreportHeadList);
onlCgreportHeadMsgJsonData.put("onlCgreportItemList", onlCgreportItemList);
onlCgreportHeadMsgJsonData.put("onlCgreportParamList", onlCgreportParamList);
@ -146,6 +155,7 @@ public class OnlineFormTenantSyncServiceImpl implements OnlineFormTenantSyncServ @@ -146,6 +155,7 @@ public class OnlineFormTenantSyncServiceImpl implements OnlineFormTenantSyncServ
// 表单元数据通知更新新增
for(Long tenantId : tenantIdSet){
JSONObject messageJsonData = new JSONObject();
messageJsonData.put("tenantId", tenantId);
messageJsonData.put("onlFormHeadList", headList);
messageJsonData.put("onlFormFindList", findList);
messageJsonData.put("onlFormFieldList", fieldList);
@ -165,8 +175,27 @@ public class OnlineFormTenantSyncServiceImpl implements OnlineFormTenantSyncServ @@ -165,8 +175,27 @@ public class OnlineFormTenantSyncServiceImpl implements OnlineFormTenantSyncServ
return true;
}
private static @NotNull String getOnlFormHeadByPageIdSQL(Long pageId) {
String placeholders = pageId.toString();
/**
* 从 widgetJson 中提取所有的 relativeFormCode(查询数据源编码)。
* widgetJson 为空、非法 JSON 或没有该节点时返回空集合,不抛异常。
*/
private List<String> parseRelativeFormCodes(String widgetJson) {
if (StrUtil.isBlank(widgetJson)) {
return Collections.emptyList();
}
try {
List<String> codes = JsonPath.read(widgetJson, "$..relativeFormCode");
if (codes == null) {
return Collections.emptyList();
}
return codes.stream().filter(StrUtil::isNotBlank).distinct().collect(Collectors.toList());
} catch (Exception e) {
log.warn("解析 widgetJson 的 relativeFormCode 失败,按无查询数据源处理:{}", e.getMessage());
return Collections.emptyList();
}
}
private static @NotNull String getOnlFormHeadByPageIdSQL(Long pageId) { String placeholders = pageId.toString();
String sql = "WITH RECURSIVE form_tree AS (" +
"SELECT fh.* FROM onl_form_head fh " +
"LEFT JOIN zz_online_page p ON p.master_table_id = fh.id " +

34
application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/tenant/service/impl/SysTenantRoleServiceImpl.java

@ -532,17 +532,23 @@ public class SysTenantRoleServiceImpl extends BaseService<SysTenantRole, Long> i @@ -532,17 +532,23 @@ public class SysTenantRoleServiceImpl extends BaseService<SysTenantRole, Long> i
for (OnlineForm onlineForm : onlineFormListByPageIds) {
// 根据表单json中的relativeFormCode获取到对应的查询数据源数据
String widgetJson = onlineForm.getWidgetJson();
List<String> relativeFormCodeList = JsonPath.read(widgetJson, "$..relativeFormCode");
List<String> relativeFormCodeList = parseRelativeFormCodes(widgetJson);
if (!relativeFormCodeList.isEmpty()) {
List<OnlCgreportHead> onlCgreportHeadList = iOnlCgreportHeadService.list(new LambdaQueryWrapper<OnlCgreportHead>()
.in(OnlCgreportHead::getCode, relativeFormCodeList));
List<String> onlCgreportHeadIdList = onlCgreportHeadList.stream().map(OnlCgreportHead::getId).collect(Collectors.toList());
List<OnlCgreportItem> onlCgreportItemList = iOnlCgreportItemService.list(new LambdaQueryWrapper<OnlCgreportItem>()
List<OnlCgreportItem> onlCgreportItemList = onlCgreportHeadIdList.isEmpty()
? Collections.emptyList()
: iOnlCgreportItemService.list(new LambdaQueryWrapper<OnlCgreportItem>()
.in(OnlCgreportItem::getCgrheadId, onlCgreportHeadIdList));
List<OnlCgreportParam> onlCgreportParamList = iOnlCgreportParamService.list(new LambdaQueryWrapper<OnlCgreportParam>()
List<OnlCgreportParam> onlCgreportParamList = onlCgreportHeadIdList.isEmpty()
? Collections.emptyList()
: iOnlCgreportParamService.list(new LambdaQueryWrapper<OnlCgreportParam>()
.in(OnlCgreportParam::getCgrheadId, onlCgreportHeadIdList));
for (Long tenantId : tenantIds) {
//表单数据源更新同步新增
JSONObject onlCgreportHeadMsgJsonData = new JSONObject();
onlCgreportHeadMsgJsonData.put("tenantId", tenantId);
onlCgreportHeadMsgJsonData.put("onlCgreportHeadList", onlCgreportHeadList);
onlCgreportHeadMsgJsonData.put("onlCgreportItemList", onlCgreportItemList);
onlCgreportHeadMsgJsonData.put("onlCgreportParamList", onlCgreportParamList);
@ -555,6 +561,7 @@ public class SysTenantRoleServiceImpl extends BaseService<SysTenantRole, Long> i @@ -555,6 +561,7 @@ public class SysTenantRoleServiceImpl extends BaseService<SysTenantRole, Long> i
TenantConstant.MESSAGE_QUEUE_SELECTOR_KEY);
}
}
}
//根据页面ID获取表单元数据列表
String sql = getOnlFormHeadByPageIdSQL(pageIds);
List<OnlFormHead> headList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(OnlFormHead.class), pageIds);
@ -567,6 +574,7 @@ public class SysTenantRoleServiceImpl extends BaseService<SysTenantRole, Long> i @@ -567,6 +574,7 @@ public class SysTenantRoleServiceImpl extends BaseService<SysTenantRole, Long> i
// 表单元数据通知更新新增
for(Long tenantId : tenantIds){
JSONObject messageJsonData1 = new JSONObject();
messageJsonData1.put("tenantId", tenantId);
messageJsonData1.put("onlFormHeadList", headList);
messageJsonData1.put("onlFormFindList", findList);
messageJsonData1.put("onlFormFieldList", fieldList);
@ -744,6 +752,26 @@ public class SysTenantRoleServiceImpl extends BaseService<SysTenantRole, Long> i @@ -744,6 +752,26 @@ public class SysTenantRoleServiceImpl extends BaseService<SysTenantRole, Long> i
return resultMenuIdSet;
}
/**
* 从 widgetJson 中提取所有的 relativeFormCode(查询数据源编码)。
* widgetJson 为空、非法 JSON 或没有该节点时返回空集合,不抛异常。
*/
private List<String> parseRelativeFormCodes(String widgetJson) {
if (StrUtil.isBlank(widgetJson)) {
return Collections.emptyList();
}
try {
List<String> codes = JsonPath.read(widgetJson, "$..relativeFormCode");
if (codes == null) {
return Collections.emptyList();
}
return codes.stream().filter(StrUtil::isNotBlank).distinct().collect(Collectors.toList());
} catch (Exception e) {
log.warn("解析 widgetJson 的 relativeFormCode 失败,按无查询数据源处理:{}", e.getMessage());
return Collections.emptyList();
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor

28
application-tenant/tenant-admin/src/main/java/apelet/tenantadmin/upms/service/impl/SysUserServiceImpl.java

@ -806,22 +806,25 @@ public class SysUserServiceImpl extends BaseService<SysUser, Long> implements Sy @@ -806,22 +806,25 @@ public class SysUserServiceImpl extends BaseService<SysUser, Long> implements Sy
}
// 2. 查询当前用户的角色记录(含deptId)
List<SysUserRole> userRoleList = sysUserRoleMapper.selectList(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
Set<Long> userRoleIdSet = userRoleList.stream().map(SysUserRole::getRoleId).collect(Collectors.toSet());
Set<Long> userRoleIdSet = userRoleList.stream().map(SysUserRole::getRoleId).filter(Objects::nonNull).collect(Collectors.toCollection(LinkedHashSet::new));
Set<Long> userDeptIdSet = userRoleList.stream().map(SysUserRole::getDeptId).filter(Objects::nonNull).collect(Collectors.toSet());
// 3. 批量查询所有组织的角色关联(通过SysUserRole.deptId)
// 3. 批量查询所有组织的角色关联(通过SysUserRole.deptId),同一组织内按roleId去重
List<Long> allDeptIds = allDepts.stream().map(SysDept::getDeptId).collect(Collectors.toList());
LambdaQueryWrapper<SysUserRole> roleDeptQuery = new LambdaQueryWrapper<>();
roleDeptQuery.in(SysUserRole::getDeptId, allDeptIds);
List<SysUserRole> allRoleDeptList = sysUserRoleMapper.selectList(roleDeptQuery);
Map<Long, List<Long>> deptRoleMap = new HashMap<>();
Set<Long> allRoleIdSet = new HashSet<>();
Map<Long, Set<Long>> deptRoleMap = new HashMap<>();
if (CollUtil.isNotEmpty(allRoleDeptList)) {
for (SysUserRole ur : allRoleDeptList) {
deptRoleMap.computeIfAbsent(ur.getDeptId(), k -> new ArrayList<>()).add(ur.getRoleId());
allRoleIdSet.add(ur.getRoleId());
if (ur.getRoleId() == null) {
continue;
}
deptRoleMap.computeIfAbsent(ur.getDeptId(), k -> new LinkedHashSet<>()).add(ur.getRoleId());
}
}
// 4. 批量查询所有角色
// 4. 批量查询所有角色,兜底角色一并查出来
Set<Long> allRoleIdSet = new HashSet<>(userRoleIdSet);
deptRoleMap.values().forEach(allRoleIdSet::addAll);
Map<Long, SysRole> roleMap = Collections.emptyMap();
if (CollUtil.isNotEmpty(allRoleIdSet)) {
List<SysRole> allRoleList = sysRoleMapper.selectBatchIds(allRoleIdSet);
@ -835,8 +838,13 @@ public class SysUserServiceImpl extends BaseService<SysUser, Long> implements Sy @@ -835,8 +838,13 @@ public class SysUserServiceImpl extends BaseService<SysUser, Long> implements Sy
deptInfo.put("deptId", dept.getDeptId());
deptInfo.put("deptName", dept.getDeptName());
item.put("deptinfo", deptInfo);
List<Long> roleIds = deptRoleMap.getOrDefault(dept.getDeptId(), Collections.emptyList());
boolean deptCheck = userDeptIdSet.contains(dept.getDeptId()) || roleIds.stream().anyMatch(userRoleIdSet::contains);
// 该组织尚未配置任何角色时,回退到用户自身的角色,打破"没配置就选不到角色"的死循环
Set<Long> roleIds = deptRoleMap.get(dept.getDeptId());
boolean fallback = CollUtil.isEmpty(roleIds);
if (fallback) {
roleIds = userRoleIdSet;
}
boolean deptCheck = userDeptIdSet.contains(dept.getDeptId()) || (!fallback && roleIds.stream().anyMatch(userRoleIdSet::contains));
deptInfo.put("check", deptCheck);
List<Map<String, Object>> roleInfoList = new ArrayList<>();
for (Long roleId : roleIds) {
@ -845,7 +853,7 @@ public class SysUserServiceImpl extends BaseService<SysUser, Long> implements Sy @@ -845,7 +853,7 @@ public class SysUserServiceImpl extends BaseService<SysUser, Long> implements Sy
Map<String, Object> roleInfo = new HashMap<>();
roleInfo.put("roleId", role.getRoleId());
roleInfo.put("roleName", role.getRoleName());
roleInfo.put("check", userRoleIdSet.contains(roleId));
roleInfo.put("check", fallback || userRoleIdSet.contains(roleId));
roleInfoList.add(roleInfo);
}
}

39
application-tenant/tenant-sync/src/main/java/apelet/tenantsync/online/service/SysTenantOnlCgreporHeadServiceImpl.java

@ -33,20 +33,29 @@ public class SysTenantOnlCgreporHeadServiceImpl implements BaseDataSyncConsumerS @@ -33,20 +33,29 @@ public class SysTenantOnlCgreporHeadServiceImpl implements BaseDataSyncConsumerS
@Override
public void doHandle(String transId, String messageCommand, JSONObject messageJsonData) {
if (StrUtil.equals(messageCommand, TenantConstant.INSERT_TENANT_ONL_FORM_HEAD_COMMAND)) {
List<OnlCgreportHead> onlCgreportHeadList = messageJsonData.getJSONArray("onlCgreportHeadList").toJavaList(OnlCgreportHead.class);
List<OnlCgreportItem> onlCgreportItemList = messageJsonData.getJSONArray("onlCgreportItemList").toJavaList(OnlCgreportItem.class);
List<OnlCgreportParam> onlCgreportParamList = messageJsonData.getJSONArray("onlCgreportParamList").toJavaList(OnlCgreportParam.class);
if (StrUtil.equals(messageCommand, TenantConstant.INSERT_TENANT_ONL_CGREPORT_HEAD_COMMAND)) {
// transId 是消息流水号,不是租户Id,必须从消息体取
Long tenantId = messageJsonData.getLong("tenantId");
if (tenantId == null) {
log.warn("查询数据源同步缺少 tenantId,已跳过。transId={}", transId);
return;
}
List<OnlCgreportHead> onlCgreportHeadList = toList(messageJsonData, "onlCgreportHeadList", OnlCgreportHead.class);
List<OnlCgreportItem> onlCgreportItemList = toList(messageJsonData, "onlCgreportItemList", OnlCgreportItem.class);
List<OnlCgreportParam> onlCgreportParamList = toList(messageJsonData, "onlCgreportParamList", OnlCgreportParam.class);
if (onlCgreportHeadList.isEmpty()) {
log.warn("查询数据源同步内容为空,已跳过。transId={}, tenantId={}", transId, tenantId);
return;
}
//对需要同步的查询数据源数据进行多租户处理
onlCgreportHeadList.stream().map(onlCgreportHead -> {
onlCgreportHead.setTenantId(transId);
return onlCgreportHead;
}).collect(Collectors.toList());
for (OnlCgreportHead onlCgreportHead : onlCgreportHeadList) {
onlCgreportHead.setTenantId(tenantId);
}
for (OnlCgreportHead onlCgreportHead : onlCgreportHeadList) {
//判断对应租户是否已经存在相同名称的查询数据源
OnlCgreportHead one = iOnlCgreportHeadService.getOne(new LambdaQueryWrapper<OnlCgreportHead>()
.eq(OnlCgreportHead::getCode, onlCgreportHead.getCode())
.eq(OnlCgreportHead::getTenantId, transId));
.eq(OnlCgreportHead::getTenantId, tenantId));
if (one == null) {
// 把onlCgreportItemList、onlCgreportParamList中headId和onlCgreportHead的id匹配的数据过滤出来
List<OnlCgreportItem> matchedItemList = onlCgreportItemList.stream()
@ -72,11 +81,19 @@ public class SysTenantOnlCgreporHeadServiceImpl implements BaseDataSyncConsumerS @@ -72,11 +81,19 @@ public class SysTenantOnlCgreporHeadServiceImpl implements BaseDataSyncConsumerS
iOnlCgreportParamService.saveBatch(matchedParamList);
}
}
} else if (StrUtil.equals(messageCommand, TenantConstant.DELETE_TENANT_ONL_FORM_HEAD_COMMAND)) {
} else if (StrUtil.equals(messageCommand, TenantConstant.DELETE_TENANT_ONL_CGREPORT_HEAD_COMMAND)) {
// 保留骨架:管理端查询数据源 tab 不再建设,本期不实现删除同步。
}
}
/**
* 安全地取集合字段:字段缺失或为空时返回空集合,避免 NPE。
*/
private <T> List<T> toList(JSONObject messageJsonData, String key, Class<T> clazz) {
com.alibaba.fastjson.JSONArray array = messageJsonData.getJSONArray(key);
return array == null ? java.util.Collections.emptyList() : array.toJavaList(clazz);
}
@Override
public String handleMessageType() {
return OnlCgreportHead.class.getSimpleName();

50
application-tenant/tenant-sync/src/main/java/apelet/tenantsync/online/service/SysTenantOnlFormHeadServiceImpl.java

@ -39,23 +39,33 @@ public class SysTenantOnlFormHeadServiceImpl implements BaseDataSyncConsumerServ @@ -39,23 +39,33 @@ public class SysTenantOnlFormHeadServiceImpl implements BaseDataSyncConsumerServ
@Override
public void doHandle(String transId, String messageCommand, JSONObject messageJsonData) {
if (StrUtil.equals(messageCommand, TenantConstant.INSERT_TENANT_ONL_FORM_HEAD_COMMAND)) {
List<OnlFormHead> onlFormHeadList = messageJsonData.getJSONArray("onlFormHeadList").toJavaList(OnlFormHead.class);
List<OnlFormFind> onlFormFindList = messageJsonData.getJSONArray("onlFormFindList").toJavaList(OnlFormFind.class);
List<OnlFormField> onlFormFieldList = messageJsonData.getJSONArray("onlFormFieldList").toJavaList(OnlFormField.class);
List<OnlFormCheck> onlFormCheckList = messageJsonData.getJSONArray("onlFormCheckList").toJavaList(OnlFormCheck.class);
List<OnlFormIndex> onlFormIndexList = messageJsonData.getJSONArray("onlFormIndexList").toJavaList(OnlFormIndex.class);
List<OnlFormKey> onlFormKeyList = messageJsonData.getJSONArray("onlFormKeyList").toJavaList(OnlFormKey.class);
List<OnlFormPage> onlFormPageList = messageJsonData.getJSONArray("onlFormPageList").toJavaList(OnlFormPage.class);
// transId 是消息流水号(形如 "100-1234-OnlFormHead-INSERT-1761700000000"),不是租户Id,必须从消息体取
Long tenantId = messageJsonData.getLong("tenantId");
if (tenantId == null) {
log.warn("表单元数据同步缺少 tenantId,已跳过。transId={}", transId);
return;
}
List<OnlFormHead> onlFormHeadList = toList(messageJsonData, "onlFormHeadList", OnlFormHead.class);
List<OnlFormFind> onlFormFindList = toList(messageJsonData, "onlFormFindList", OnlFormFind.class);
List<OnlFormField> onlFormFieldList = toList(messageJsonData, "onlFormFieldList", OnlFormField.class);
List<OnlFormCheck> onlFormCheckList = toList(messageJsonData, "onlFormCheckList", OnlFormCheck.class);
List<OnlFormIndex> onlFormIndexList = toList(messageJsonData, "onlFormIndexList", OnlFormIndex.class);
List<OnlFormKey> onlFormKeyList = toList(messageJsonData, "onlFormKeyList", OnlFormKey.class);
List<OnlFormPage> onlFormPageList = toList(messageJsonData, "onlFormPageList", OnlFormPage.class);
if (onlFormHeadList.isEmpty()) {
log.warn("表单元数据同步内容为空,已跳过。transId={}, tenantId={}", transId, tenantId);
return;
}
//对需要同步的表单元数据进行多租户处理
onlFormHeadList.stream().map(onlFormHead -> {
onlFormHead.setTenantId(transId);
onlFormHead.setTableName(onlFormHead.getTableName() + "_" + transId);
return onlFormHead;
}).collect(Collectors.toList());
for (OnlFormHead onlFormHead : onlFormHeadList) {
onlFormHead.setTenantId(tenantId);
onlFormHead.setTableName(onlFormHead.getTableName() + "_" + tenantId);
}
for (OnlFormHead onlFormHead : onlFormHeadList) {
//判断对应租户是否已经存在相同名称的表单元数据
OnlFormHead one = onlFormHeadService.getOne(new LambdaQueryWrapper<OnlFormHead>()
.eq(OnlFormHead::getTableName, onlFormHead.getTableName()));
.eq(OnlFormHead::getTableName, onlFormHead.getTableName())
.eq(OnlFormHead::getTenantId, tenantId));
if (one == null) {
// 把onlFormFindList、onlFormFieldList、onlFormCheckList、onlFormIndexList、onlFormKeyList、onlFormPageList
// 中headId和onlFormHead的id匹配的数据过滤出来
@ -114,13 +124,25 @@ public class SysTenantOnlFormHeadServiceImpl implements BaseDataSyncConsumerServ @@ -114,13 +124,25 @@ public class SysTenantOnlFormHeadServiceImpl implements BaseDataSyncConsumerServ
onlFormPageService.saveBatch(matchedPageList);
//表单元数据同步
onlFormHeadService.syncDB(onlFormHead, 0L);
} else {
// TODO 去重同步策略待定:当前表已存在则整段跳过,
// 导致管理端后续新增的字段无法下发到租户,未来需改为字段级 diff + ALTER TABLE ADD COLUMN。
log.info("表单元数据已存在,跳过同步。tenantId={}, tableName={}", tenantId, onlFormHead.getTableName());
}
}
} else if (StrUtil.equals(messageCommand, TenantConstant.DELETE_TENANT_ONL_FORM_HEAD_COMMAND)) {
// 保留骨架:管理端表单元数据 tab 不再建设,本期不实现删除同步。
}
}
/**
* 安全地取集合字段:字段缺失或为空时返回空集合,避免 NPE。
*/
private <T> List<T> toList(JSONObject messageJsonData, String key, Class<T> clazz) {
com.alibaba.fastjson.JSONArray array = messageJsonData.getJSONArray(key);
return array == null ? java.util.Collections.emptyList() : array.toJavaList(clazz);
}
@Override
public String handleMessageType() {
return OnlFormHead.class.getSimpleName();

4
common/common-generator/src/main/java/apelet/common/generator/model/OnlCgreportHead.java

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
package apelet.common.generator.model;
import apelet.common.core.base.model.BaseModel;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@ -52,5 +53,6 @@ public class OnlCgreportHead extends BaseModel implements Serializable { @@ -52,5 +53,6 @@ public class OnlCgreportHead extends BaseModel implements Serializable {
private Integer deletedFlag;
@Schema(description = "租户id")
private String tenantId;
@TableField(value = "tenant_id")
private Long tenantId;
}

3
common/common-generator/src/main/java/apelet/common/generator/model/OnlFormHead.java

@ -115,7 +115,8 @@ public class OnlFormHead extends BaseModel implements Serializable { @@ -115,7 +115,8 @@ public class OnlFormHead extends BaseModel implements Serializable {
private String metaTable;
@Schema(description = "租户id")
private String tenantId;
@TableField(value = "tenant_id")
private Long tenantId;
@Schema(description = "数据库属性分录")
@TableField(exist = false)

Loading…
Cancel
Save