|
|
|
@ -6,6 +6,7 @@ import apelet.common.core.cache.CacheConfig; |
|
|
|
import apelet.common.core.cache.CacheKey; |
|
|
|
import apelet.common.core.cache.CacheKey; |
|
|
|
import apelet.common.core.constant.AppDeviceType; |
|
|
|
import apelet.common.core.constant.AppDeviceType; |
|
|
|
import apelet.common.core.constant.ErrorCodeEnum; |
|
|
|
import apelet.common.core.constant.ErrorCodeEnum; |
|
|
|
|
|
|
|
import apelet.common.core.constant.GlobalDeletedFlag; |
|
|
|
import apelet.common.core.object.*; |
|
|
|
import apelet.common.core.object.*; |
|
|
|
import apelet.common.core.util.MyCommonUtil; |
|
|
|
import apelet.common.core.util.MyCommonUtil; |
|
|
|
import apelet.common.core.util.MyModelUtil; |
|
|
|
import apelet.common.core.util.MyModelUtil; |
|
|
|
@ -32,7 +33,6 @@ import apelet.common.online.util.WidgetFieldTypeMapping; |
|
|
|
import apelet.common.online.util.WidgetJsonUtil; |
|
|
|
import apelet.common.online.util.WidgetJsonUtil; |
|
|
|
import apelet.common.online.vo.OnlineFormVo; |
|
|
|
import apelet.common.online.vo.OnlineFormVo; |
|
|
|
import cn.hutool.core.collection.CollUtil; |
|
|
|
import cn.hutool.core.collection.CollUtil; |
|
|
|
import cn.hutool.core.map.MapUtil; |
|
|
|
|
|
|
|
import cn.hutool.core.util.BooleanUtil; |
|
|
|
import cn.hutool.core.util.BooleanUtil; |
|
|
|
import cn.hutool.core.util.ObjectUtil; |
|
|
|
import cn.hutool.core.util.ObjectUtil; |
|
|
|
import cn.hutool.core.util.StrUtil; |
|
|
|
import cn.hutool.core.util.StrUtil; |
|
|
|
@ -57,6 +57,7 @@ import org.springframework.web.bind.annotation.*; |
|
|
|
import javax.annotation.Resource; |
|
|
|
import javax.annotation.Resource; |
|
|
|
import javax.validation.groups.Default; |
|
|
|
import javax.validation.groups.Default; |
|
|
|
import java.util.*; |
|
|
|
import java.util.*; |
|
|
|
|
|
|
|
import java.util.function.Consumer; |
|
|
|
import java.util.function.Function; |
|
|
|
import java.util.function.Function; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
|
|
|
|
@ -229,116 +230,6 @@ public class OnlineFormController { |
|
|
|
.eq(OnlineDatasourceRelation::getRelationType,0) |
|
|
|
.eq(OnlineDatasourceRelation::getRelationType,0) |
|
|
|
.eq(OnlineDatasourceRelation::getDatasourceId,onlineFormDto.getDatasourceIdList().get(0))); |
|
|
|
.eq(OnlineDatasourceRelation::getDatasourceId,onlineFormDto.getDatasourceIdList().get(0))); |
|
|
|
} |
|
|
|
} |
|
|
|
// for (int i = 0; i < jsonArray.size(); i++) {
|
|
|
|
|
|
|
|
// JSONObject object = jsonArray.getJSONObject(i);
|
|
|
|
|
|
|
|
// Integer widgetType = object.getInteger("widgetType");
|
|
|
|
|
|
|
|
// //外键id
|
|
|
|
|
|
|
|
// String columnId = object.getJSONObject("bindData").getString("columnId");
|
|
|
|
|
|
|
|
// //主表id
|
|
|
|
|
|
|
|
// String tableId = object.getJSONObject("bindData").getString("tableId");
|
|
|
|
|
|
|
|
// OnlineTable onlineTable = onlineTableService.getById(tableId);
|
|
|
|
|
|
|
|
// //从表名称
|
|
|
|
|
|
|
|
// String slaveTableName = object.getJSONObject("bindData").getString("slaveTableName");
|
|
|
|
|
|
|
|
// if (402 == widgetType){
|
|
|
|
|
|
|
|
// if (object.getJSONObject("props") != null && object.getJSONObject("props").getJSONObject("relativeTable") != null){
|
|
|
|
|
|
|
|
// String relationId = object.getJSONObject("props").getJSONObject("relativeTable").getString("relationId");//关联id
|
|
|
|
|
|
|
|
// if(StringUtils.isNotEmpty(relationId)){
|
|
|
|
|
|
|
|
// OnlineDatasourceRelation onlineDatasourceRelation = onlineDatasourceRelationService.getById(Long.valueOf(relationId));
|
|
|
|
|
|
|
|
// if(onlineDatasourceRelation != null){
|
|
|
|
|
|
|
|
// OnlineTable sTable = onlineTableService.getById(onlineDatasourceRelation.getSlaveTableId());
|
|
|
|
|
|
|
|
// if( ! (onlineDatasourceRelation.getMasterColumnId() == Long.valueOf(columnId)
|
|
|
|
|
|
|
|
// && onlineDatasourceRelation.getRelationType() == 0
|
|
|
|
|
|
|
|
// && onlineDatasourceRelation.getDatasourceId() == onlineFormDto.getDatasourceIdList().get(0)
|
|
|
|
|
|
|
|
// && sTable.getTableName().equals(slaveTableName) )
|
|
|
|
|
|
|
|
// ){//已存在关联关系,不符合规则
|
|
|
|
|
|
|
|
// onlineDatasourceRelationService.remove(onlineDatasourceRelation.getRelationId());
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// OnlineDatasourceRelation onr = onlineDatasourceRelationService.getOne(new LambdaQueryWrapper<OnlineDatasourceRelation>()
|
|
|
|
|
|
|
|
// .eq(OnlineDatasourceRelation::getMasterColumnId,columnId)
|
|
|
|
|
|
|
|
// .eq(OnlineDatasourceRelation::getRelationType,0)
|
|
|
|
|
|
|
|
// .eq(OnlineDatasourceRelation::getDatasourceId,onlineFormDto.getDatasourceIdList().get(0)));
|
|
|
|
|
|
|
|
// if(slaveTableName == null){
|
|
|
|
|
|
|
|
// errorMessage = "关联控件校验失败,字段绑定表";
|
|
|
|
|
|
|
|
// return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// if(onr != null){
|
|
|
|
|
|
|
|
// OnlineTable sTable = onlineTableService.getById(onr.getSlaveTableId());
|
|
|
|
|
|
|
|
// if(onr != null && !slaveTableName.equals(sTable.getTableName())){
|
|
|
|
|
|
|
|
// errorMessage = "关联控件校验失败,字段关联多张表";
|
|
|
|
|
|
|
|
// return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// if(onr != null && slaveTableName.equals(sTable.getTableName())) {
|
|
|
|
|
|
|
|
// if (object.getJSONObject("props") != null && object.getJSONObject("props").getJSONObject("relativeTable") != null) {
|
|
|
|
|
|
|
|
// if (object.getJSONObject("props").getJSONObject("relativeTable").getString("relativeFormType").equals("2")) {//关联查询数据源\
|
|
|
|
|
|
|
|
// OnlineDatasource datasource = onlineDatasourceService.getById(onlineFormDto.getDatasourceIdList().get(0));
|
|
|
|
|
|
|
|
// object.getJSONObject("props").getJSONObject("relativeTable").put("datasourceId", onlineFormDto.getDatasourceIdList().get(0));
|
|
|
|
|
|
|
|
// object.getJSONObject("props").getJSONObject("relativeTable").put("variableName",datasource.getVariableName() );
|
|
|
|
|
|
|
|
// object.getJSONObject("props").getJSONObject("relativeTable").put("relationId",onr.getRelationId());
|
|
|
|
|
|
|
|
// object.getJSONObject("props").getJSONObject("relativeTable").put("relativeTableName",slaveTableName);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// continue;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// //先删除对应关联关系
|
|
|
|
|
|
|
|
// onlineDatasourceRelationService.remove(new LambdaQueryWrapper<OnlineDatasourceRelation>()
|
|
|
|
|
|
|
|
// .eq(OnlineDatasourceRelation::getMasterColumnId,columnId)
|
|
|
|
|
|
|
|
// .eq(OnlineDatasourceRelation::getRelationType,0)
|
|
|
|
|
|
|
|
// .eq(OnlineDatasourceRelation::getDatasourceId,onlineFormDto.getDatasourceIdList().get(0)));
|
|
|
|
|
|
|
|
// OnlineDatasourceRelationDto onlineDatasourceRelationDto = new OnlineDatasourceRelationDto();
|
|
|
|
|
|
|
|
// onlineDatasourceRelationDto.setDatasourceId(onlineFormDto.getDatasourceIdList().get(0));
|
|
|
|
|
|
|
|
// //关联名称
|
|
|
|
|
|
|
|
// onlineDatasourceRelationDto.setRelationName(object.getString("showName"));
|
|
|
|
|
|
|
|
// //关联标识-组件标识
|
|
|
|
|
|
|
|
// onlineDatasourceRelationDto.setVariableName(onlineTable.getTableName()+"_"+object.getString("variableName")+"_"+slaveTableName);
|
|
|
|
|
|
|
|
// //关联类型
|
|
|
|
|
|
|
|
// onlineDatasourceRelationDto.setRelationType(0);
|
|
|
|
|
|
|
|
// //主键字段id
|
|
|
|
|
|
|
|
// onlineDatasourceRelationDto.setMasterColumnId(Long.valueOf(columnId));
|
|
|
|
|
|
|
|
// //从表名称
|
|
|
|
|
|
|
|
// onlineDatasourceRelationDto.setSlaveTableName(slaveTableName);
|
|
|
|
|
|
|
|
// //从表字段名称
|
|
|
|
|
|
|
|
// onlineDatasourceRelationDto.setSlaveColumnName("id");
|
|
|
|
|
|
|
|
// //是否级联删除
|
|
|
|
|
|
|
|
// onlineDatasourceRelationDto.setCascadeDelete(false);
|
|
|
|
|
|
|
|
// //是否左连接查询
|
|
|
|
|
|
|
|
// onlineDatasourceRelationDto.setLeftJoin(true);
|
|
|
|
|
|
|
|
// OnlineDatasourceRelation onlineDatasourceRelation =
|
|
|
|
|
|
|
|
// MyModelUtil.copyTo(onlineDatasourceRelationDto, OnlineDatasourceRelation.class);
|
|
|
|
|
|
|
|
// SqlTable slaveTable = onlineDblinkService.getDblinkTable(
|
|
|
|
|
|
|
|
// onlineDblink, onlineDatasourceRelationDto.getSlaveTableName());
|
|
|
|
|
|
|
|
// if (slaveTable == null) {
|
|
|
|
|
|
|
|
// errorMessage = "关联控件建立一对一关系失败:数据验证失败,指定的数据表不存在!";
|
|
|
|
|
|
|
|
// return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// SqlTableColumn slaveColumn = null;
|
|
|
|
|
|
|
|
// for (SqlTableColumn column : slaveTable.getColumnList()) {
|
|
|
|
|
|
|
|
// if (column.getColumnName().equals(onlineDatasourceRelationDto.getSlaveColumnName())) {
|
|
|
|
|
|
|
|
// slaveColumn = column;
|
|
|
|
|
|
|
|
// break;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// if (slaveColumn == null) {
|
|
|
|
|
|
|
|
// errorMessage = "关联控件建立一对一关系失败:数据验证失败,指定的数据表字段 [" + onlineDatasourceRelationDto.getSlaveColumnName() + "] 不存在!";
|
|
|
|
|
|
|
|
// return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// onlineDatasourceRelation = onlineDatasourceRelationService.saveNew(onlineDatasourceRelation, slaveTable, slaveColumn);
|
|
|
|
|
|
|
|
// if (object.getJSONObject("props") != null && object.getJSONObject("props").getJSONObject("relativeTable") != null){
|
|
|
|
|
|
|
|
// if (object.getJSONObject("props").getJSONObject("relativeTable").getString("relativeFormType").equals("2")) {//关联查询数据源\
|
|
|
|
|
|
|
|
// OnlineDatasource datasource = onlineDatasourceService.getById(onlineFormDto.getDatasourceIdList().get(0));
|
|
|
|
|
|
|
|
// object.getJSONObject("props").getJSONObject("relativeTable").put("datasourceId", onlineFormDto.getDatasourceIdList().get(0));
|
|
|
|
|
|
|
|
// object.getJSONObject("props").getJSONObject("relativeTable").put("variableName",datasource.getVariableName() );
|
|
|
|
|
|
|
|
// object.getJSONObject("props").getJSONObject("relativeTable").put("relativeTableName",slaveTableName);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// object.getJSONObject("props").getJSONObject("relativeTable").put("relationId",onlineDatasourceRelation.getRelationId());
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
onlineForm.setWidgetJson(jsonObject.toJSONString()); |
|
|
|
onlineForm.setWidgetJson(jsonObject.toJSONString()); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -707,256 +598,98 @@ public class OnlineFormController { |
|
|
|
* @return 修改后的 widgetJson (含回填的 columnId/relationId),无变更则返回 null |
|
|
|
* @return 修改后的 widgetJson (含回填的 columnId/relationId),无变更则返回 null |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private JSONObject syncNewFieldsAndSubTables(OnlineForm form, OnlineFormDto dto, JSONObject widgetJson) { |
|
|
|
private JSONObject syncNewFieldsAndSubTables(OnlineForm form, OnlineFormDto dto, JSONObject widgetJson) { |
|
|
|
// 1. 获取数据源 → OnlineTable → OnlFormHead
|
|
|
|
// 1. 获取数据源 → 主表 → 主表 head
|
|
|
|
OnlineDatasource datasource = onlineDatasourceService.getById(dto.getDatasourceIdList().get(0)); |
|
|
|
OnlineDatasource datasource = onlineDatasourceService.getById(dto.getDatasourceIdList().get(0)); |
|
|
|
OnlineTable onlineTable = onlineTableService.getById(datasource.getMasterTableId()); |
|
|
|
OnlineTable masterTable = onlineTableService.getById(datasource.getMasterTableId()); |
|
|
|
|
|
|
|
OnlFormHead masterHead = onlFormHeadService.getOne(new LambdaQueryWrapper<OnlFormHead>().eq(OnlFormHead::getTableName, masterTable.getTableName())); |
|
|
|
OnlFormHead onlFormHead = onlFormHeadService.getOne( |
|
|
|
if (masterHead == null) return null; |
|
|
|
new LambdaQueryWrapper<OnlFormHead>() |
|
|
|
|
|
|
|
.eq(OnlFormHead::getTableName, onlineTable.getTableName())); |
|
|
|
|
|
|
|
if (onlFormHead == null) { |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
boolean changed = false; |
|
|
|
boolean changed = false; |
|
|
|
|
|
|
|
|
|
|
|
// === Diff 新增字段 ===
|
|
|
|
// === 统一取值:pc/mobile 所有"表-字段"绑定关系(表标识 → 字段名 → 控件) ===
|
|
|
|
// 收集 pc/mobile 端所有绑定的字段列名
|
|
|
|
Map<String, Map<String, JSONObject>> tableFieldMap = WidgetJsonUtil.buildTableFieldMap(widgetJson); |
|
|
|
Set<String> widgetColumnNames = WidgetJsonUtil.collectBindColumnNames(widgetJson); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
List<OnlFormField> existingFields = onlFormFieldService.list(new LambdaQueryWrapper<OnlFormField>().eq(OnlFormField::getHeadId, onlFormHead.getId())); |
|
|
|
// === 新增表:widgetType=100 且无 tableId(只有 tableName)的表统一先建表 ===
|
|
|
|
Set<String> existingFieldNames = existingFields.stream() |
|
|
|
Set<String> newTableNames = WidgetJsonUtil.collectNewSubTableNames(widgetJson); |
|
|
|
.map(OnlFormField::getFieldName).collect(Collectors.toSet()); |
|
|
|
if (!newTableNames.isEmpty()) changed |= createNewSubTables(widgetJson, masterHead, datasource, newTableNames); |
|
|
|
Set<String> newColumnNames = new HashSet<>(widgetColumnNames); |
|
|
|
|
|
|
|
newColumnNames.removeAll(existingFieldNames); |
|
|
|
// === 逐表 diff 新增字段 ===
|
|
|
|
// 主表/单表已有字段:如果绑定了从表(slaveTableId),同步更新 refPropert
|
|
|
|
for (Map.Entry<String, Map<String, JSONObject>> entry : tableFieldMap.entrySet()) { |
|
|
|
Map<String, JSONObject> fieldNameToWidget = WidgetJsonUtil.buildFieldNameWidgetMap(widgetJson); |
|
|
|
String tableKey = entry.getKey(); |
|
|
|
for (OnlFormField existingField : existingFields) { |
|
|
|
Map<String, JSONObject> columnWidgetMap = entry.getValue(); |
|
|
|
JSONObject widget = fieldNameToWidget.get(existingField.getFieldName()); |
|
|
|
if (columnWidgetMap.isEmpty()) continue; |
|
|
|
if (widget == null) { |
|
|
|
// 解析表:纯数字 → 已有表(主表/单表/附表统一处理);字符串 → 刚创建的新表
|
|
|
|
continue; |
|
|
|
OnlineTable table = tableKey.matches("\\d+") ? onlineTableService.getById(Long.valueOf(tableKey)) : onlineTableService.getOne(new LambdaQueryWrapper<OnlineTable>().eq(OnlineTable::getTableName, tableKey.toLowerCase())); |
|
|
|
} |
|
|
|
if (table == null) continue; |
|
|
|
JSONObject bindData = widget.getJSONObject("bindData"); |
|
|
|
OnlFormHead head = onlFormHeadService.getOne(new LambdaQueryWrapper<OnlFormHead>().eq(OnlFormHead::getTableName, table.getTableName())); |
|
|
|
if (bindData == null) { |
|
|
|
if (head == null) continue; |
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
List<OnlFormField> existingFields = onlFormFieldService.list(new LambdaQueryWrapper<OnlFormField>().eq(OnlFormField::getHeadId, head.getId())); |
|
|
|
String slaveTableId = bindData.getString("slaveTableId"); |
|
|
|
Map<String, OnlFormField> fieldByColumnName = existingFields.stream().collect(Collectors.toMap(OnlFormField::getFieldName, Function.identity(), (a, b) -> a)); |
|
|
|
if (StrUtil.isNotEmpty(slaveTableId)) { |
|
|
|
|
|
|
|
|
|
|
|
List<String> newColumnNames = new ArrayList<>(); |
|
|
|
|
|
|
|
for (Map.Entry<String, JSONObject> columnEntry : columnWidgetMap.entrySet()) { |
|
|
|
|
|
|
|
String columnName = columnEntry.getKey(); |
|
|
|
|
|
|
|
JSONObject widget = columnEntry.getValue(); |
|
|
|
|
|
|
|
OnlFormField existingField = fieldByColumnName.get(columnName); |
|
|
|
|
|
|
|
if (existingField != null) { |
|
|
|
|
|
|
|
// 已有字段:带 slaveTableId 则更新 refPropert(子表列仅关联列 comType=402 生效)
|
|
|
|
|
|
|
|
boolean isTableColumn = !widget.containsKey("bindData"); |
|
|
|
|
|
|
|
Integer comType = widget.getInteger("comType"); |
|
|
|
|
|
|
|
boolean isAssociation = !isTableColumn || (comType != null && comType == 402); |
|
|
|
|
|
|
|
String slaveTableId = extractSlaveTableId(widget); |
|
|
|
|
|
|
|
if (isAssociation && StrUtil.isNotEmpty(slaveTableId)) { |
|
|
|
existingField.setRefPropert(Long.valueOf(slaveTableId)); |
|
|
|
existingField.setRefPropert(Long.valueOf(slaveTableId)); |
|
|
|
onlFormFieldService.updateById(existingField); |
|
|
|
onlFormFieldService.updateById(existingField); |
|
|
|
|
|
|
|
changed = true; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!newColumnNames.isEmpty()) { |
|
|
|
|
|
|
|
Map<String, JSONObject> nameToWidget = WidgetJsonUtil.buildColumnNameWidgetMap(widgetJson); |
|
|
|
|
|
|
|
// 收集 mobile 端的 widget 映射(遍历 childWidgetList 路径)
|
|
|
|
|
|
|
|
Map<String, JSONObject> mobileNameToWidget = WidgetJsonUtil.buildMobileColumnNameWidgetMap(widgetJson); |
|
|
|
|
|
|
|
OnlineDblink dblink = onlineDblinkService.getById(datasource.getDblinkId()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 预校验:过滤掉 widgetType 不在映射中的控件,避免 getFieldTypeId 抛异常导致部分数据已入库
|
|
|
|
|
|
|
|
Set<String> validColumnNames = new LinkedHashSet<>(); |
|
|
|
|
|
|
|
for (String fieldName : newColumnNames) { |
|
|
|
|
|
|
|
JSONObject widget = nameToWidget.get(fieldName); |
|
|
|
|
|
|
|
if (widget == null) { |
|
|
|
|
|
|
|
widget = mobileNameToWidget.get(fieldName); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Integer widgetType = widget != null ? widget.getInteger("widgetType") : null; |
|
|
|
|
|
|
|
if (widgetType == null || !WidgetFieldTypeMapping.isDataWidget(widgetType)) { |
|
|
|
|
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
validColumnNames.add(fieldName); |
|
|
|
// 新增字段:识别"字段控件"还是"子表列",非数据控件跳过
|
|
|
|
} |
|
|
|
boolean isTableColumn = !widget.containsKey("bindData"); |
|
|
|
if (validColumnNames.isEmpty()) { |
|
|
|
Integer widgetType = widget.getInteger("widgetType"); |
|
|
|
return changed ? widgetJson : null; |
|
|
|
if (!isTableColumn && (widgetType == null || !WidgetFieldTypeMapping.isDataWidget(widgetType))) continue; |
|
|
|
} |
|
|
|
if (isTableColumn) { |
|
|
|
|
|
|
|
// 子表列:字段类型沿用现状,硬编码 750
|
|
|
|
for (String fieldName : validColumnNames) { |
|
|
|
this.saveField(750, widget.getString("showName"), null, head, columnName, extractSlaveTableId(widget)); |
|
|
|
JSONObject widget = nameToWidget.get(fieldName); |
|
|
|
} else { |
|
|
|
if (widget == null) { |
|
|
|
|
|
|
|
widget = mobileNameToWidget.get(fieldName); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// 从 widget 的 bindData.columnComment 设置字段备注
|
|
|
|
|
|
|
|
JSONObject bindData = widget.getJSONObject("bindData"); |
|
|
|
JSONObject bindData = widget.getJSONObject("bindData"); |
|
|
|
String ref = bindData.containsKey("slaveTableId") ? bindData.getString("slaveTableId") : null; |
|
|
|
String ref = bindData.containsKey("slaveTableId") ? bindData.getString("slaveTableId") : null; |
|
|
|
this.saveField(widget.getInteger("widgetType"), bindData.getString("columnComment"), widget.getString("showName"), onlFormHead, fieldName, ref); |
|
|
|
this.saveField(widgetType, bindData.getString("columnComment"), widget.getString("showName"), head, columnName, ref); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
newColumnNames.add(columnName); |
|
|
|
// ALTER TABLE ADD COLUMN
|
|
|
|
|
|
|
|
onlFormHeadService.syncDB(onlFormHead, 0L); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 批量获取所有列信息,避免 N+1 查询
|
|
|
|
|
|
|
|
List<SqlTableColumn> allColumns = onlineDblinkService.getDblinkTableColumnList( |
|
|
|
|
|
|
|
dblink, onlineTable.getTableName()); |
|
|
|
|
|
|
|
Map<String, SqlTableColumn> columnMap = new HashMap<>(); |
|
|
|
|
|
|
|
if (CollUtil.isNotEmpty(allColumns)) { |
|
|
|
|
|
|
|
for (SqlTableColumn col : allColumns) { |
|
|
|
|
|
|
|
if (col.getColumnName() != null) { |
|
|
|
|
|
|
|
columnMap.put(col.getColumnName().toLowerCase(), col); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 增量创建 OnlineColumn + 回填 columnId 到 widgetJson
|
|
|
|
|
|
|
|
for (String fieldName : validColumnNames) { |
|
|
|
|
|
|
|
SqlTableColumn sqlCol = columnMap.get(fieldName.toLowerCase()); |
|
|
|
|
|
|
|
if (sqlCol != null) { |
|
|
|
|
|
|
|
JSONObject widget = nameToWidget.get(fieldName); |
|
|
|
|
|
|
|
JSONObject mobileWidget = mobileNameToWidget.get(fieldName); |
|
|
|
|
|
|
|
String showName = widget != null ? widget.getString("showName") : (mobileWidget != null ? mobileWidget.getString("showName") : null); |
|
|
|
|
|
|
|
long columnId = onlineColumnService.saveBySqlTable(sqlCol, onlineTable.getTableId(), showName); |
|
|
|
|
|
|
|
// 回写 pc 端 widget
|
|
|
|
|
|
|
|
if (widget != null) { |
|
|
|
|
|
|
|
JSONObject bindData2 = widget.getJSONObject("bindData"); |
|
|
|
|
|
|
|
if (bindData2 != null) { |
|
|
|
|
|
|
|
bindData2.put("columnId", columnId); |
|
|
|
|
|
|
|
bindData2.put("tableId", onlineTable.getTableId()); |
|
|
|
|
|
|
|
bindData2.put("columnFieldName", fieldName); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// 回写 mobile 端 widget
|
|
|
|
|
|
|
|
if (mobileWidget != null) { |
|
|
|
|
|
|
|
JSONObject mobileBindData = mobileWidget.getJSONObject("bindData"); |
|
|
|
|
|
|
|
if (mobileBindData != null) { |
|
|
|
|
|
|
|
mobileBindData.put("columnId", columnId); |
|
|
|
|
|
|
|
mobileBindData.put("tableId", onlineTable.getTableId()); |
|
|
|
|
|
|
|
mobileBindData.put("columnFieldName", fieldName); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
redissonClient.getBucket(OnlineRedisKeyUtil.makeOnlineTableKey(onlineTable.getTableId())).delete(); |
|
|
|
|
|
|
|
redissonClient.getBucket(CacheKey.makeTableKey(onlineTable.getTableName())).delete(); |
|
|
|
|
|
|
|
redissonClient.getBucket(CacheKey.makeChildFieldListKey(onlFormHead.getId())).delete(); |
|
|
|
|
|
|
|
metaCacheService.removeData(onlineTable.getTableName()); |
|
|
|
|
|
|
|
changed = true; |
|
|
|
changed = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// === Diff 新增子表 ===
|
|
|
|
if (!newColumnNames.isEmpty()) { |
|
|
|
// 取 widgetList->bindData -> tableId 在去 zz_online_table 查询,这样就可以判断哪些是新增,哪些是 已有的表
|
|
|
|
// ALTER TABLE ADD COLUMN
|
|
|
|
// 如果存在附表
|
|
|
|
onlFormHeadService.syncDB(head, 0L); |
|
|
|
Map<String, JSONObject> tableIdAndPropMap = WidgetJsonUtil.collectSubTableProps(widgetJson); |
|
|
|
// 批量获取列信息,避免 N+1
|
|
|
|
|
|
|
|
|
|
|
|
if (MapUtil.isNotEmpty(tableIdAndPropMap)) { |
|
|
|
|
|
|
|
//搜集的所有tableId, 要么是 tableId(已存在),要么是 tableName(不存在)
|
|
|
|
|
|
|
|
Set<String> allTableIdSet = tableIdAndPropMap.keySet(); |
|
|
|
|
|
|
|
Set<String> newSubTableNames = new HashSet<>(); |
|
|
|
|
|
|
|
Set<Long> existingSubTableIdSet = new HashSet<>(); |
|
|
|
|
|
|
|
for (String tableId : allTableIdSet) { |
|
|
|
|
|
|
|
if (tableId.matches("\\d+")) { |
|
|
|
|
|
|
|
existingSubTableIdSet.add(Long.parseLong(tableId)); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
newSubTableNames.add(tableId); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
//分两步,
|
|
|
|
|
|
|
|
//step1 : 看看存在的附表,是否存在不存在的字段
|
|
|
|
|
|
|
|
if (!existingSubTableIdSet.isEmpty()) { |
|
|
|
|
|
|
|
// 拿到tableId 下面的所有字段,先查询 zz_online_table ,在根据 tableName 查询 onl_form_head 表
|
|
|
|
|
|
|
|
List<OnlineTable> tableList = onlineTableService.listByIds(existingSubTableIdSet); |
|
|
|
|
|
|
|
Map<Long, String> tableIdAndNameMap = tableList.stream().collect(Collectors.toMap(OnlineTable::getTableId, OnlineTable::getTableName)); |
|
|
|
|
|
|
|
List<String> tableNames = tableList.stream().map(OnlineTable::getTableName).collect(Collectors.toList()); |
|
|
|
|
|
|
|
List<OnlFormHead> onlFormHeadList = onlFormHeadService.list(new LambdaQueryWrapper<OnlFormHead>().in(OnlFormHead::getTableName, tableNames)); |
|
|
|
|
|
|
|
Map<String, OnlFormHead> tableNameAndHeadIdMap = onlFormHeadList.stream().collect(Collectors.toMap(OnlFormHead::getTableName, Function.identity())); |
|
|
|
|
|
|
|
//因为这里是zz_online_column.column_id 的id和 列名的混合,我只要列名
|
|
|
|
|
|
|
|
Map<String, JSONObject> nameToWidget = WidgetJsonUtil.buildSubTableColumnWidgetMap(widgetJson); |
|
|
|
|
|
|
|
Set<String> newSubColumnNameSet = nameToWidget.keySet().stream().filter(s -> !s.matches("\\d+")).collect(Collectors.toSet()); |
|
|
|
|
|
|
|
//这里要走 新增逻辑
|
|
|
|
|
|
|
|
if (!newSubColumnNameSet.isEmpty()) { |
|
|
|
|
|
|
|
// ALTER TABLE ADD COLUMN, 这里取第一个就行,因为绑定的是一个表
|
|
|
|
|
|
|
|
JSONObject columnInfo = nameToWidget.values().iterator().next(); |
|
|
|
|
|
|
|
Long tableId = columnInfo.getLong("tableId"); |
|
|
|
|
|
|
|
String tableName = tableIdAndNameMap.get(tableId); |
|
|
|
|
|
|
|
OnlFormHead entryHead = tableNameAndHeadIdMap.get(tableName); |
|
|
|
|
|
|
|
for (String newSubColumnName : newSubColumnNameSet) { |
|
|
|
|
|
|
|
//这里取出来的结构是 widgetList -》 props -》 tableColumnList
|
|
|
|
|
|
|
|
JSONObject columnInfoJson = nameToWidget.get(newSubColumnName); |
|
|
|
|
|
|
|
//step 1 : 先保存 field 表
|
|
|
|
|
|
|
|
String showName = columnInfoJson.getString("showName"); |
|
|
|
|
|
|
|
String ref = columnInfoJson.containsKey("slaveTableId") ? columnInfoJson.getString("slaveTableId") : null; |
|
|
|
|
|
|
|
// 默认是字符串类型
|
|
|
|
|
|
|
|
this.saveField(750, showName, null, entryHead, newSubColumnName, ref); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
onlFormHeadService.syncDB(entryHead, 0L); |
|
|
|
|
|
|
|
//step 2 :在保存 OnlineColumn 表
|
|
|
|
|
|
|
|
OnlineDblink dblink = onlineDblinkService.getById(datasource.getDblinkId()); |
|
|
|
OnlineDblink dblink = onlineDblinkService.getById(datasource.getDblinkId()); |
|
|
|
List<SqlTableColumn> allColumns = onlineDblinkService.getDblinkTableColumnList(dblink, tableName); |
|
|
|
List<SqlTableColumn> allColumns = onlineDblinkService.getDblinkTableColumnList(dblink, table.getTableName()); |
|
|
|
Map<String, SqlTableColumn> columnMap = new HashMap<>(); |
|
|
|
Map<String, SqlTableColumn> columnMap = new HashMap<>(); |
|
|
|
if (CollUtil.isNotEmpty(allColumns)) { |
|
|
|
if (CollUtil.isNotEmpty(allColumns)) { |
|
|
|
columnMap = allColumns.stream().collect(Collectors.toMap(SqlTableColumn::getColumnName, Function.identity())); |
|
|
|
for (SqlTableColumn col : allColumns) { |
|
|
|
|
|
|
|
if (col.getColumnName() != null) columnMap.put(col.getColumnName().toLowerCase(), col); |
|
|
|
} |
|
|
|
} |
|
|
|
for (String fieldName : newSubColumnNameSet) { |
|
|
|
|
|
|
|
SqlTableColumn sqlCol = columnMap.get(fieldName); |
|
|
|
|
|
|
|
if (sqlCol != null) { |
|
|
|
|
|
|
|
// 回填 columnId 到 widgetJson
|
|
|
|
|
|
|
|
JSONObject widget = nameToWidget.get(fieldName); |
|
|
|
|
|
|
|
String showName = widget == null ? null : widget.getString("showName"); |
|
|
|
|
|
|
|
long columnId = onlineColumnService.saveBySqlTable(sqlCol, tableId, showName); |
|
|
|
|
|
|
|
if (widget != null) { |
|
|
|
|
|
|
|
//step 3 :回填 columnId + showFieldName 到 json里面去
|
|
|
|
|
|
|
|
widget.put("columnId", columnId); |
|
|
|
|
|
|
|
widget.put("showFieldName", fieldName); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 增量创建 OnlineColumn + 回填 columnId 到所有匹配控件
|
|
|
|
|
|
|
|
for (String columnName : newColumnNames) { |
|
|
|
|
|
|
|
SqlTableColumn sqlCol = columnMap.get(columnName.toLowerCase()); |
|
|
|
|
|
|
|
if (sqlCol == null) continue; |
|
|
|
|
|
|
|
long columnId = onlineColumnService.saveBySqlTable(sqlCol, table.getTableId(), columnWidgetMap.get(columnName).getString("showName")); |
|
|
|
|
|
|
|
WidgetJsonUtil.backfillColumnId(widgetJson, columnName, columnId, table.getTableId(), table.getTableName()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
//step 4 :删除缓存
|
|
|
|
// 删除缓存
|
|
|
|
redissonClient.getBucket(OnlineRedisKeyUtil.makeOnlineTableKey(tableId)).delete(); |
|
|
|
redissonClient.getBucket(OnlineRedisKeyUtil.makeOnlineTableKey(table.getTableId())).delete(); |
|
|
|
redissonClient.getBucket(CacheKey.makeTableKey(tableName)).delete(); |
|
|
|
redissonClient.getBucket(CacheKey.makeTableKey(table.getTableName())).delete(); |
|
|
|
redissonClient.getBucket(CacheKey.makeChildFieldListKey(entryHead.getId())).delete(); |
|
|
|
redissonClient.getBucket(CacheKey.makeChildFieldListKey(head.getId())).delete(); |
|
|
|
metaCacheService.removeData(tableName); |
|
|
|
metaCacheService.removeData(table.getTableName()); |
|
|
|
changed = true; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 附表已有字段:检查 tableColumnList 中 comType=402 的列是否有 slaveTableId,同步更新 refPropert
|
|
|
|
// === mobile 端子表(widgetType=102)专用同步,保持原有逻辑 ===
|
|
|
|
for (Long tableId : existingSubTableIdSet) { |
|
|
|
changed |= syncMobileSubTables(widgetJson, masterHead, datasource); |
|
|
|
String tableName = tableIdAndNameMap.get(tableId); |
|
|
|
|
|
|
|
if (tableName == null) { |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
OnlFormHead subHead = tableNameAndHeadIdMap.get(tableName); |
|
|
|
|
|
|
|
if (subHead == null) { |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
List<OnlFormField> subFields = onlFormFieldService.list( |
|
|
|
|
|
|
|
new LambdaQueryWrapper<OnlFormField>().eq(OnlFormField::getHeadId, subHead.getId())); |
|
|
|
|
|
|
|
JSONObject props = tableIdAndPropMap.get(String.valueOf(tableId)); |
|
|
|
|
|
|
|
JSONArray tableColumnList = props != null ? props.getJSONArray("tableColumnList") : null; |
|
|
|
|
|
|
|
if (tableColumnList == null) { |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
for (OnlFormField field : subFields) { |
|
|
|
|
|
|
|
for (int i = 0; i < tableColumnList.size(); i++) { |
|
|
|
|
|
|
|
JSONObject col = tableColumnList.getJSONObject(i); |
|
|
|
|
|
|
|
// 匹配 showFieldName,兼容 showName
|
|
|
|
|
|
|
|
String showFieldName = col.getString("showFieldName"); |
|
|
|
|
|
|
|
if (StrUtil.isEmpty(showFieldName)) { |
|
|
|
|
|
|
|
showFieldName = col.getString("showName"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (!field.getFieldName().equals(showFieldName)) { |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// 只有 comType=402(关联选择器)才有 slaveTableId
|
|
|
|
|
|
|
|
Integer comType = col.getInteger("comType"); |
|
|
|
|
|
|
|
if (comType != null && comType == 402) { |
|
|
|
|
|
|
|
String slaveTableId = col.getString("slaveTableId"); |
|
|
|
|
|
|
|
if (StrUtil.isNotEmpty(slaveTableId)) { |
|
|
|
|
|
|
|
field.setRefPropert(Long.valueOf(slaveTableId)); |
|
|
|
|
|
|
|
onlFormFieldService.updateById(field); |
|
|
|
|
|
|
|
changed = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
//step2 : 不存在的附表,新增
|
|
|
|
|
|
|
|
changed |= createNewSubTables(widgetJson, onlFormHead, datasource, newSubTableNames); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
// tableIdAndPropMap 为空,说明走 tableId 取值没取到,兜底通过 tableName 收集附表并创建
|
|
|
|
|
|
|
|
changed |= createNewSubTables(widgetJson, onlFormHead, datasource, new HashSet<>()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// === Diff mobile 端子表 ===
|
|
|
|
|
|
|
|
// 路径: mobile -> widgetList -> [widgetType=102] -> bindData -> tableName/tableId
|
|
|
|
|
|
|
|
changed |= syncMobileSubTables(widgetJson, onlFormHead, datasource); |
|
|
|
|
|
|
|
return changed ? widgetJson : null; |
|
|
|
return changed ? widgetJson : null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -1009,6 +742,21 @@ public class OnlineFormController { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* 提取控件/子表列绑定的从表 id(slaveTableId)。 |
|
|
|
|
|
|
|
* 字段控件在 bindData 下;子表列对象直接挂在顶层。 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private String extractSlaveTableId(JSONObject widget) { |
|
|
|
|
|
|
|
if (widget == null) { |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
JSONObject bindData = widget.getJSONObject("bindData"); |
|
|
|
|
|
|
|
if (bindData != null) { |
|
|
|
|
|
|
|
return bindData.containsKey("slaveTableId") ? bindData.getString("slaveTableId") : null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return widget.getString("slaveTableId"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void saveField(Integer widgetType, String columnComment, String showName, OnlFormHead onlFormHead, String fieldName, String refPropert) { |
|
|
|
private void saveField(Integer widgetType, String columnComment, String showName, OnlFormHead onlFormHead, String fieldName, String refPropert) { |
|
|
|
OnlFormField field = new OnlFormField(); |
|
|
|
OnlFormField field = new OnlFormField(); |
|
|
|
field.setHeadId(onlFormHead.getId()); |
|
|
|
field.setHeadId(onlFormHead.getId()); |
|
|
|
@ -1025,6 +773,12 @@ public class OnlineFormController { |
|
|
|
field.setIsDefault(0); |
|
|
|
field.setIsDefault(0); |
|
|
|
field.setRowDisabled(0); |
|
|
|
field.setRowDisabled(0); |
|
|
|
field.setSyncFlag(0); |
|
|
|
field.setSyncFlag(0); |
|
|
|
|
|
|
|
// 逻辑删除标记:默认正常(1),onl_form_field 未配置 @TableLogic,需显式写入
|
|
|
|
|
|
|
|
field.setDeletedFlag(GlobalDeletedFlag.NORMAL); |
|
|
|
|
|
|
|
field.setCreateTime(new Date()); |
|
|
|
|
|
|
|
field.setUpdateTime(new Date()); |
|
|
|
|
|
|
|
field.setCreateUserId(TokenData.takeFromRequest().getUserId()); |
|
|
|
|
|
|
|
field.setUpdateUserId(TokenData.takeFromRequest().getUserId()); |
|
|
|
|
|
|
|
|
|
|
|
// 从 widget 的 bindData.columnComment 设置字段备注
|
|
|
|
// 从 widget 的 bindData.columnComment 设置字段备注
|
|
|
|
field.setFieldRemark(columnComment); |
|
|
|
field.setFieldRemark(columnComment); |
|
|
|
@ -1037,31 +791,41 @@ public class OnlineFormController { |
|
|
|
// ============ mobile 端子表同步相关方法 ============
|
|
|
|
// ============ mobile 端子表同步相关方法 ============
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
|
|
|
|
* 递归遍历 mobile 控件树(childWidgetList),收集所有 widgetType=102 的子表组件。 |
|
|
|
|
|
|
|
* 102 可嵌套在分组/卡片等容器内。 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private void walkMobileSubTableWidgets(JSONArray widgetList, Consumer<JSONObject> consumer) { |
|
|
|
|
|
|
|
if (CollUtil.isEmpty(widgetList)) return; |
|
|
|
|
|
|
|
for (int i = 0; i < widgetList.size(); i++) { |
|
|
|
|
|
|
|
JSONObject widget = widgetList.getJSONObject(i); |
|
|
|
|
|
|
|
if (widget == null) continue; |
|
|
|
|
|
|
|
Integer widgetType = widget.getInteger("widgetType"); |
|
|
|
|
|
|
|
if (widgetType != null && widgetType == 102) { |
|
|
|
|
|
|
|
consumer.accept(widget); |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
JSONArray childWidgetList = widget.getJSONArray("childWidgetList"); |
|
|
|
|
|
|
|
if (CollUtil.isNotEmpty(childWidgetList)) walkMobileSubTableWidgets(childWidgetList, consumer); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 同步 mobile 端的子表(新增子表 + 已有子表的新增字段)。 |
|
|
|
* 同步 mobile 端的子表(新增子表 + 已有子表的新增字段)。 |
|
|
|
|
|
|
|
* 规则:bindData 有 tableId → 已有表,向下找字段;只有 tableName → 新增表,不找字段,建表后回写 tableId。 |
|
|
|
* 子表: mobile -> widgetList -> [widgetType=102] -> bindData -> tableName/tableId |
|
|
|
* 子表: mobile -> widgetList -> [widgetType=102] -> bindData -> tableName/tableId |
|
|
|
* 字段: mobile -> widgetList -> childWidgetList -> childWidgetList -> bindData -> columnName |
|
|
|
* 字段: mobile -> widgetList -> childWidgetList -> childWidgetList -> bindData -> columnName |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private boolean syncMobileSubTables(JSONObject widgetJson, OnlFormHead onlFormHead, OnlineDatasource datasource) { |
|
|
|
private boolean syncMobileSubTables(JSONObject widgetJson, OnlFormHead onlFormHead, OnlineDatasource datasource) { |
|
|
|
JSONObject mobile = widgetJson.getJSONObject("mobile"); |
|
|
|
JSONObject mobile = widgetJson.getJSONObject("mobile"); |
|
|
|
if (mobile == null) { |
|
|
|
if (mobile == null) return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
JSONArray mobileWidgetList = mobile.getJSONArray("widgetList"); |
|
|
|
JSONArray mobileWidgetList = mobile.getJSONArray("widgetList"); |
|
|
|
if (mobileWidgetList == null) { |
|
|
|
if (mobileWidgetList == null) return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
boolean changed = false; |
|
|
|
boolean changed = false; |
|
|
|
Set<String> newSubTableNames = new LinkedHashSet<>(); |
|
|
|
Set<String> newSubTableNames = new LinkedHashSet<>(); |
|
|
|
Set<Long> existingSubTableIds = new LinkedHashSet<>(); |
|
|
|
Set<Long> existingSubTableIds = new LinkedHashSet<>(); |
|
|
|
for (int i = 0; i < mobileWidgetList.size(); i++) { |
|
|
|
walkMobileSubTableWidgets(mobileWidgetList, widget -> { |
|
|
|
JSONObject widget = mobileWidgetList.getJSONObject(i); |
|
|
|
|
|
|
|
if (widget.getInteger("widgetType") == null || widget.getInteger("widgetType") != 102) { |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
JSONObject bindData = widget.getJSONObject("bindData"); |
|
|
|
JSONObject bindData = widget.getJSONObject("bindData"); |
|
|
|
if (bindData == null) { |
|
|
|
if (bindData == null) return; |
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
String tableName = bindData.getString("tableName"); |
|
|
|
String tableName = bindData.getString("tableName"); |
|
|
|
String tableIdStr = bindData.getString("tableId"); |
|
|
|
String tableIdStr = bindData.getString("tableId"); |
|
|
|
if (StrUtil.isNotEmpty(tableName) && StrUtil.isEmpty(tableIdStr)) { |
|
|
|
if (StrUtil.isNotEmpty(tableName) && StrUtil.isEmpty(tableIdStr)) { |
|
|
|
@ -1069,7 +833,7 @@ public class OnlineFormController { |
|
|
|
} else if (StrUtil.isNotEmpty(tableIdStr)) { |
|
|
|
} else if (StrUtil.isNotEmpty(tableIdStr)) { |
|
|
|
existingSubTableIds.add(Long.valueOf(tableIdStr)); |
|
|
|
existingSubTableIds.add(Long.valueOf(tableIdStr)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
// 处理新子表: 创建后回写 tableId + masterColumnName
|
|
|
|
// 处理新子表: 创建后回写 tableId + masterColumnName
|
|
|
|
if (!newSubTableNames.isEmpty()) { |
|
|
|
if (!newSubTableNames.isEmpty()) { |
|
|
|
changed |= createNewSubTables(widgetJson, onlFormHead, datasource, newSubTableNames); |
|
|
|
changed |= createNewSubTables(widgetJson, onlFormHead, datasource, newSubTableNames); |
|
|
|
@ -1088,35 +852,21 @@ public class OnlineFormController { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private void backfillMobileSubTableId(JSONObject widgetJson, Set<String> newSubTableNames) { |
|
|
|
private void backfillMobileSubTableId(JSONObject widgetJson, Set<String> newSubTableNames) { |
|
|
|
JSONObject mobile = widgetJson.getJSONObject("mobile"); |
|
|
|
JSONObject mobile = widgetJson.getJSONObject("mobile"); |
|
|
|
if (mobile == null) { |
|
|
|
if (mobile == null) return; |
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
JSONArray mobileWidgetList = mobile.getJSONArray("widgetList"); |
|
|
|
JSONArray mobileWidgetList = mobile.getJSONArray("widgetList"); |
|
|
|
if (mobileWidgetList == null) { |
|
|
|
if (mobileWidgetList == null) return; |
|
|
|
return; |
|
|
|
walkMobileSubTableWidgets(mobileWidgetList, widget -> { |
|
|
|
} |
|
|
|
|
|
|
|
for (int i = 0; i < mobileWidgetList.size(); i++) { |
|
|
|
|
|
|
|
JSONObject widget = mobileWidgetList.getJSONObject(i); |
|
|
|
|
|
|
|
if (widget.getInteger("widgetType") == null || widget.getInteger("widgetType") != 102) { |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
JSONObject bindData = widget.getJSONObject("bindData"); |
|
|
|
JSONObject bindData = widget.getJSONObject("bindData"); |
|
|
|
if (bindData == null) { |
|
|
|
if (bindData == null) return; |
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
String tableName = bindData.getString("tableName"); |
|
|
|
String tableName = bindData.getString("tableName"); |
|
|
|
if (StrUtil.isEmpty(tableName) || !newSubTableNames.contains(tableName)) { |
|
|
|
if (StrUtil.isEmpty(tableName) || !newSubTableNames.contains(tableName)) return; |
|
|
|
continue; |
|
|
|
// createNewSubTables 只回写了 100 组件的 tableId,102 组件的在这里补
|
|
|
|
} |
|
|
|
|
|
|
|
// createNewSubTables 已通过 WidgetJsonUtil.backfillTableId 回写了 tableId,这里只需补 masterColumnName
|
|
|
|
|
|
|
|
if (!bindData.containsKey("tableId")) { |
|
|
|
if (!bindData.containsKey("tableId")) { |
|
|
|
OnlineTable subTable = onlineTableService.getOne(new LambdaQueryWrapper<OnlineTable>().eq(OnlineTable::getTableName, tableName.toLowerCase())); |
|
|
|
OnlineTable subTable = onlineTableService.getOne(new LambdaQueryWrapper<OnlineTable>().eq(OnlineTable::getTableName, tableName.toLowerCase())); |
|
|
|
if (subTable != null) { |
|
|
|
if (subTable != null) bindData.put("tableId", subTable.getTableId()); |
|
|
|
bindData.put("tableId", subTable.getTableId()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
bindData.put("masterColumnName", "id"); |
|
|
|
bindData.put("masterColumnName", "id"); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -1124,43 +874,38 @@ public class OnlineFormController { |
|
|
|
* 字段路径: mobile -> widgetList -> [widgetType=102] -> childWidgetList -> childWidgetList -> bindData -> columnName |
|
|
|
* 字段路径: mobile -> widgetList -> [widgetType=102] -> childWidgetList -> childWidgetList -> bindData -> columnName |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private boolean syncMobileSubTableNewFields(JSONObject widgetJson, OnlineDatasource datasource, Set<Long> existingSubTableIds) { |
|
|
|
private boolean syncMobileSubTableNewFields(JSONObject widgetJson, OnlineDatasource datasource, Set<Long> existingSubTableIds) { |
|
|
|
// 查询已有子表信息
|
|
|
|
|
|
|
|
List<OnlineTable> subTables = onlineTableService.listByIds(existingSubTableIds); |
|
|
|
List<OnlineTable> subTables = onlineTableService.listByIds(existingSubTableIds); |
|
|
|
if (CollUtil.isEmpty(subTables)) { |
|
|
|
if (CollUtil.isEmpty(subTables)) return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Map<Long, String> tableIdToName = subTables.stream().collect(Collectors.toMap(OnlineTable::getTableId, OnlineTable::getTableName)); |
|
|
|
Map<Long, String> tableIdToName = subTables.stream().collect(Collectors.toMap(OnlineTable::getTableId, OnlineTable::getTableName)); |
|
|
|
List<String> tableNames = subTables.stream().map(OnlineTable::getTableName).collect(Collectors.toList()); |
|
|
|
List<String> tableNames = subTables.stream().map(OnlineTable::getTableName).collect(Collectors.toList()); |
|
|
|
List<OnlFormHead> subHeads = onlFormHeadService.list(new LambdaQueryWrapper<OnlFormHead>().in(OnlFormHead::getTableName, tableNames)); |
|
|
|
List<OnlFormHead> subHeads = onlFormHeadService.list(new LambdaQueryWrapper<OnlFormHead>().in(OnlFormHead::getTableName, tableNames)); |
|
|
|
Map<String, OnlFormHead> tableNameToHead = subHeads.stream().collect(Collectors.toMap(OnlFormHead::getTableName, Function.identity())); |
|
|
|
Map<String, OnlFormHead> tableNameToHead = subHeads.stream().collect(Collectors.toMap(OnlFormHead::getTableName, Function.identity())); |
|
|
|
OnlineDblink dblink = onlineDblinkService.getById(datasource.getDblinkId()); |
|
|
|
OnlineDblink dblink = onlineDblinkService.getById(datasource.getDblinkId()); |
|
|
|
|
|
|
|
|
|
|
|
// 遍历 mobile 端已有子表 widget, 搜集新增字段
|
|
|
|
|
|
|
|
JSONObject mobile = widgetJson.getJSONObject("mobile"); |
|
|
|
JSONObject mobile = widgetJson.getJSONObject("mobile"); |
|
|
|
|
|
|
|
if (mobile == null) return false; |
|
|
|
JSONArray mobileWidgetList = mobile.getJSONArray("widgetList"); |
|
|
|
JSONArray mobileWidgetList = mobile.getJSONArray("widgetList"); |
|
|
|
boolean changed = false; |
|
|
|
if (mobileWidgetList == null) return false; |
|
|
|
for (int i = 0; i < mobileWidgetList.size(); i++) { |
|
|
|
boolean[] changed = {false}; |
|
|
|
JSONObject widget = mobileWidgetList.getJSONObject(i); |
|
|
|
walkMobileSubTableWidgets(mobileWidgetList, widget -> { |
|
|
|
if (widget.getInteger("widgetType") == null || widget.getInteger("widgetType") != 102) { |
|
|
|
if (syncMobileSubTableNewFieldForWidget(widget, tableIdToName, tableNameToHead, dblink)) changed[0] = true; |
|
|
|
continue; |
|
|
|
}); |
|
|
|
|
|
|
|
return changed[0]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* 处理单个已有子表(widgetType=102)下的新增字段,返回是否有变更。 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private boolean syncMobileSubTableNewFieldForWidget(JSONObject widget, Map<Long, String> tableIdToName, Map<String, OnlFormHead> tableNameToHead, OnlineDblink dblink) { |
|
|
|
JSONObject bindData = widget.getJSONObject("bindData"); |
|
|
|
JSONObject bindData = widget.getJSONObject("bindData"); |
|
|
|
if (bindData == null) { |
|
|
|
if (bindData == null) return false; |
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
String tableIdStr = bindData.getString("tableId"); |
|
|
|
String tableIdStr = bindData.getString("tableId"); |
|
|
|
if (StrUtil.isEmpty(tableIdStr)) { |
|
|
|
if (StrUtil.isEmpty(tableIdStr)) return false; |
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Long tableId = Long.valueOf(tableIdStr); |
|
|
|
Long tableId = Long.valueOf(tableIdStr); |
|
|
|
String tableName = tableIdToName.get(tableId); |
|
|
|
String tableName = tableIdToName.get(tableId); |
|
|
|
if (tableName == null) { |
|
|
|
if (tableName == null) return false; |
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
OnlFormHead subHead = tableNameToHead.get(tableName); |
|
|
|
OnlFormHead subHead = tableNameToHead.get(tableName); |
|
|
|
if (subHead == null) { |
|
|
|
if (subHead == null) return false; |
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// 搜集该子表下无 columnId 的字段
|
|
|
|
// 搜集该子表下无 columnId 的字段
|
|
|
|
List<JSONObject> newFieldWidgets = new ArrayList<>(); |
|
|
|
List<JSONObject> newFieldWidgets = new ArrayList<>(); |
|
|
|
JSONArray cardList = widget.getJSONArray("childWidgetList"); |
|
|
|
JSONArray cardList = widget.getJSONArray("childWidgetList"); |
|
|
|
@ -1168,9 +913,7 @@ public class OnlineFormController { |
|
|
|
for (int j = 0; j < cardList.size(); j++) { |
|
|
|
for (int j = 0; j < cardList.size(); j++) { |
|
|
|
JSONObject card = cardList.getJSONObject(j); |
|
|
|
JSONObject card = cardList.getJSONObject(j); |
|
|
|
JSONArray fieldList = card.getJSONArray("childWidgetList"); |
|
|
|
JSONArray fieldList = card.getJSONArray("childWidgetList"); |
|
|
|
if (fieldList == null) { |
|
|
|
if (fieldList == null) continue; |
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
for (int k = 0; k < fieldList.size(); k++) { |
|
|
|
for (int k = 0; k < fieldList.size(); k++) { |
|
|
|
JSONObject field = fieldList.getJSONObject(k); |
|
|
|
JSONObject field = fieldList.getJSONObject(k); |
|
|
|
JSONObject fieldBd = field.getJSONObject("bindData"); |
|
|
|
JSONObject fieldBd = field.getJSONObject("bindData"); |
|
|
|
@ -1180,9 +923,7 @@ public class OnlineFormController { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if (newFieldWidgets.isEmpty()) { |
|
|
|
if (newFieldWidgets.isEmpty()) return false; |
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// 创建字段记录
|
|
|
|
// 创建字段记录
|
|
|
|
for (JSONObject fieldWidget : newFieldWidgets) { |
|
|
|
for (JSONObject fieldWidget : newFieldWidgets) { |
|
|
|
JSONObject fieldBd = fieldWidget.getJSONObject("bindData"); |
|
|
|
JSONObject fieldBd = fieldWidget.getJSONObject("bindData"); |
|
|
|
@ -1197,9 +938,7 @@ public class OnlineFormController { |
|
|
|
Map<String, SqlTableColumn> columnMap = new HashMap<>(); |
|
|
|
Map<String, SqlTableColumn> columnMap = new HashMap<>(); |
|
|
|
if (CollUtil.isNotEmpty(allColumns)) { |
|
|
|
if (CollUtil.isNotEmpty(allColumns)) { |
|
|
|
for (SqlTableColumn col : allColumns) { |
|
|
|
for (SqlTableColumn col : allColumns) { |
|
|
|
if (col.getColumnName() != null) { |
|
|
|
if (col.getColumnName() != null) columnMap.put(col.getColumnName().toLowerCase(), col); |
|
|
|
columnMap.put(col.getColumnName().toLowerCase(), col); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// 创建 OnlineColumn + 回写
|
|
|
|
// 创建 OnlineColumn + 回写
|
|
|
|
@ -1220,9 +959,7 @@ public class OnlineFormController { |
|
|
|
redissonClient.getBucket(CacheKey.makeTableKey(tableName)).delete(); |
|
|
|
redissonClient.getBucket(CacheKey.makeTableKey(tableName)).delete(); |
|
|
|
redissonClient.getBucket(CacheKey.makeChildFieldListKey(subHead.getId())).delete(); |
|
|
|
redissonClient.getBucket(CacheKey.makeChildFieldListKey(subHead.getId())).delete(); |
|
|
|
metaCacheService.removeData(tableName); |
|
|
|
metaCacheService.removeData(tableName); |
|
|
|
changed = true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
return changed; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
|