@ -3,6 +3,7 @@ package apelet.common.online.controller;
@@ -3,6 +3,7 @@ package apelet.common.online.controller;
import apelet.common.core.annotation.MyRequestBody ;
import apelet.common.core.annotation.NoAuthInterface ;
import apelet.common.core.cache.CacheConfig ;
import apelet.common.core.cache.CacheKey ;
import apelet.common.core.constant.AppDeviceType ;
import apelet.common.core.constant.ErrorCodeEnum ;
import apelet.common.core.object.* ;
@ -17,6 +18,7 @@ import apelet.common.generator.model.OnlFormHead;
@@ -17,6 +18,7 @@ import apelet.common.generator.model.OnlFormHead;
import apelet.common.generator.service.IOnlFormFieldService ;
import apelet.common.generator.service.IOnlFormHeadService ;
import apelet.common.generator.utils.CustomUtil ;
import apelet.common.generator.utils.cache.MetaCacheService ;
import apelet.common.log.annotation.OperationLog ;
import apelet.common.log.model.constant.SysOperationLogType ;
import apelet.common.online.config.OnlineProperties ;
@ -53,6 +55,7 @@ import javax.annotation.Resource;
@@ -53,6 +55,7 @@ import javax.annotation.Resource;
import javax.validation.groups.Default ;
import java.util.* ;
import java.util.function.Consumer ;
import java.util.function.Function ;
import java.util.stream.Collectors ;
/ * *
@ -95,6 +98,9 @@ public class OnlineFormController {
@@ -95,6 +98,9 @@ public class OnlineFormController {
@Resource ( name = "caffeineCacheManager" )
private CacheManager cacheManager ;
@Autowired
private MetaCacheService metaCacheService ;
/ * *
* 新增在线表单数据 。
*
@ -750,31 +756,9 @@ public class OnlineFormController {
@@ -750,31 +756,9 @@ public class OnlineFormController {
for ( String fieldName : validColumnNames ) {
JSONObject widget = nameToWidget . get ( fieldName ) ;
Integer widgetType = widget . getInteger ( "widgetType" ) ;
OnlFormField field = new OnlFormField ( ) ;
field . setHeadId ( onlFormHead . getId ( ) ) ;
field . setFieldName ( fieldName ) ;
field . setFieldType ( WidgetFieldTypeMapping . getFieldTypeId ( widgetType ) ) ;
Integer length = WidgetFieldTypeMapping . getDefaultLength ( widgetType ) ;
if ( length ! = null ) {
field . setFieldLength ( length ) ;
}
field . setIsEmpty ( 1 ) ;
field . setIsDefault ( 0 ) ;
field . setRowDisabled ( 0 ) ;
field . setSyncFlag ( 0 ) ;
// 从 widget 的 bindData.columnComment 设置字段备注
JSONObject bindData = widget . getJSONObject ( "bindData" ) ;
if ( bindData ! = null & & bindData . containsKey ( "columnComment" ) ) {
field . setFieldRemark ( bindData . getString ( "columnComment" ) ) ;
}
String showName = widget . getString ( "showName" ) ;
if ( StringUtils . isNotBlank ( showName ) & & ( StringUtils . isBlank ( field . getFieldRemark ( ) ) | | StringUtils . equals ( "null" , field . getFieldRemark ( ) ) ) ) {
field . setFieldRemark ( showName ) ;
}
onlFormFieldService . save ( field ) ;
this . saveField ( widget . getInteger ( "widgetType" ) , bindData . getString ( "columnComment" ) , widget . getString ( "showName" ) , onlFormHead , fieldName ) ;
}
// ALTER TABLE ADD COLUMN
@ -798,7 +782,8 @@ public class OnlineFormController {
@@ -798,7 +782,8 @@ public class OnlineFormController {
if ( sqlCol ! = null ) {
// 回填 columnId 到 widgetJson
JSONObject widget = nameToWidget . get ( fieldName ) ;
long columnId = onlineColumnService . saveBySqlTable ( sqlCol , onlineTable . getTableId ( ) , widget . getString ( "showName" ) ) ;
String showName = widget = = null ? null : widget . getString ( "showName" ) ;
long columnId = onlineColumnService . saveBySqlTable ( sqlCol , onlineTable . getTableId ( ) , showName ) ;
if ( widget ! = null ) {
JSONObject bindData2 = widget . getJSONObject ( "bindData" ) ;
if ( bindData2 ! = null ) {
@ -808,75 +793,141 @@ public class OnlineFormController {
@@ -808,75 +793,141 @@ public class OnlineFormController {
}
}
}
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 ;
}
// === Diff 新增子表 ===
Set < String > widgetSubTables = collectSubTableNames ( widgetJson ) ;
List < OnlFormHead > existingSubTables = onlFormHeadService . list (
new LambdaQueryWrapper < OnlFormHead > ( )
. eq ( OnlFormHead : : getSort , onlFormHead . getTableName ( ) )
. eq ( OnlFormHead : : getLine , 1 ) ) ;
Set < String > existingSubTableNames = existingSubTables . stream ( )
. map ( OnlFormHead : : getTableName ) . collect ( Collectors . toSet ( ) ) ;
Set < String > newSubTableNames = new HashSet < > ( widgetSubTables ) ;
newSubTableNames . removeAll ( existingSubTableNames ) ;
if ( ! newSubTableNames . isEmpty ( ) ) {
// 获取主表的主键字段(id)作为关联字段
OnlineColumn masterPkColumn = onlineColumnService . getOne (
new LambdaQueryWrapper < OnlineColumn > ( )
. eq ( OnlineColumn : : getTableId , onlineTable . getTableId ( ) )
. eq ( OnlineColumn : : getColumnName , "id" ) ) ;
for ( String subTableName : newSubTableNames ) {
OnlFormHead subHead = onlFormHeadService . createMetaAndSync (
subTableName ,
onlFormHead . getTableTxt ( ) + "附表" ,
CustomUtil . MetaType_Entry ,
onlFormHead . getTableName ( ) ) ;
// 获取子表的 OnlineTable
OnlineTable subOnlineTable = onlineTableService . getOne (
new LambdaQueryWrapper < OnlineTable > ( )
. eq ( OnlineTable : : getTableName , subTableName . toLowerCase ( ) ) ) ;
if ( subOnlineTable = = null ) {
// 从DB获取表结构并创建 OnlineTable
SqlTable subSqlTable = onlineDblinkService . getDblinkTable (
onlineDblinkService . getById ( datasource . getDblinkId ( ) ) , subTableName ) ;
if ( subSqlTable ! = null ) {
subOnlineTable = onlineTableService . saveNewFromSqlTable ( subSqlTable ) ;
}
}
// 取 widgetList->bindData -> tableId 在去 zz_online_table 查询,这样就可以判断哪些是新增,哪些是 已有的表
// 如果存在附表
Map < String , JSONObject > tableIdAndPropMap = collectSubTableAndPropMap ( widgetJson ) ;
// 创建子表数据源
OnlineDatasource subDatasource = new OnlineDatasource ( ) ;
subDatasource . setDblinkId ( datasource . getDblinkId ( ) ) ;
if ( subOnlineTable ! = null ) {
subDatasource . setMasterTableId ( subOnlineTable . getTableId ( ) ) ;
}
onlineDatasourceService . save ( subDatasource ) ;
// 创建 1:N 关系
OnlineDatasourceRelation relation = new OnlineDatasourceRelation ( ) ;
relation . setDatasourceId ( datasource . getDatasourceId ( ) ) ;
relation . setRelationType ( 1 ) ;
if ( subOnlineTable ! = null ) {
relation . setSlaveTableId ( subOnlineTable . getTableId ( ) ) ;
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 ) ;
}
if ( masterPkColumn ! = null ) {
relation . setMasterColumnId ( masterPkColumn . getColumnId ( ) ) ;
}
//分两步,
//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 = mapColumnIdAndWidget ( 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" ) ;
// 默认是字符串类型
this . saveField ( 750 , showName , null , entryHead , newSubColumnName ) ;
}
onlFormHeadService . syncDB ( entryHead , 0L ) ;
//step 2 :在保存 OnlineColumn 表
OnlineDblink dblink = onlineDblinkService . getById ( datasource . getDblinkId ( ) ) ;
List < SqlTableColumn > allColumns = onlineDblinkService . getDblinkTableColumnList ( dblink , tableName ) ;
Map < String , SqlTableColumn > columnMap = new HashMap < > ( ) ;
if ( CollUtil . isNotEmpty ( allColumns ) ) {
columnMap = allColumns . stream ( ) . collect ( Collectors . toMap ( SqlTableColumn : : getColumnName , Function . identity ( ) ) ) ;
}
for ( String fieldName : newSubColumnNameSet ) {
SqlTableColumn sqlCol = columnMap . get ( fieldName . toLowerCase ( ) ) ;
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 ) ;
}
}
}
//step 4 :删除缓存
redissonClient . getBucket ( OnlineRedisKeyUtil . makeOnlineTableKey ( tableId ) ) . delete ( ) ;
redissonClient . getBucket ( CacheKey . makeTableKey ( tableName ) ) . delete ( ) ;
redissonClient . getBucket ( CacheKey . makeChildFieldListKey ( entryHead . getId ( ) ) ) . delete ( ) ;
metaCacheService . removeData ( tableName ) ;
changed = true ;
}
onlineDatasourceRelationService . save ( relation ) ;
}
//step2 : 不存在的附表,新增
if ( newSubTableNames . isEmpty ( ) ) {
//如果他为空,说明我们走tableId取值没取到,我们就去一下 tableName;
newSubTableNames = this . collectSubTableName ( widgetJson ) ;
}
if ( ! newSubTableNames . isEmpty ( ) ) {
for ( String subTableName : newSubTableNames ) {
OnlFormHead subHead = onlFormHeadService . createMetaAndSync ( subTableName , onlFormHead . getTableTxt ( ) + "附表" , CustomUtil . MetaType_Entry , onlFormHead . getTableName ( ) ) ;
// 获取子表的 OnlineTable
OnlineTable subOnlineTable = onlineTableService . getOne ( new LambdaQueryWrapper < OnlineTable > ( ) . eq ( OnlineTable : : getTableName , subTableName . toLowerCase ( ) ) ) ;
if ( subOnlineTable = = null ) {
// 从DB获取表结构并创建 OnlineTable
SqlTable subSqlTable = onlineDblinkService . getDblinkTable ( onlineDblinkService . getById ( datasource . getDblinkId ( ) ) , subTableName ) ;
if ( subSqlTable ! = null ) {
subOnlineTable = onlineTableService . saveNewFromSqlTable ( subSqlTable ) ;
}
}
OnlineDblink dblink = onlineDblinkService . getById ( datasource . getDblinkId ( ) ) ;
onlineDatasourceRelationService . addOnlineDatasourceRelation ( onlFormHead , datasource , null , dblink ) ;
backfillRelationId ( widgetJson , subTableName , relation . getRelationId ( ) ) ;
if ( subOnlineTable ! = null ) {
backfillRelationId ( widgetJson , subTableName , subOnlineTable . getTableId ( ) ) ;
}
}
changed = true ;
}
changed = true ;
}
return changed ? widgetJson : null ;
}
private void saveField ( Integer widgetType , String columnComment , String showName , OnlFormHead onlFormHead , String fieldName ) {
OnlFormField field = new OnlFormField ( ) ;
field . setHeadId ( onlFormHead . getId ( ) ) ;
field . setFieldName ( fieldName ) ;
field . setFieldType ( WidgetFieldTypeMapping . getFieldTypeId ( widgetType ) ) ;
Integer length = WidgetFieldTypeMapping . getDefaultLength ( widgetType ) ;
if ( length ! = null ) {
field . setFieldLength ( length ) ;
}
field . setIsEmpty ( 1 ) ;
field . setIsDefault ( 0 ) ;
field . setRowDisabled ( 0 ) ;
field . setSyncFlag ( 0 ) ;
// 从 widget 的 bindData.columnComment 设置字段备注
field . setFieldRemark ( columnComment ) ;
if ( StringUtils . isNotBlank ( showName ) & & ( StringUtils . isBlank ( field . getFieldRemark ( ) ) | | StringUtils . equals ( "null" , field . getFieldRemark ( ) ) ) ) {
field . setFieldRemark ( showName ) ;
}
onlFormFieldService . save ( field ) ;
}
/ * *
* 遍历 pc / mobile 的 widget 树 , 收集所有 bindData . columnName 值 。
* /
@ -895,22 +946,66 @@ public class OnlineFormController {
@@ -895,22 +946,66 @@ public class OnlineFormController {
}
/ * *
* 遍历 pc / mobile 的 widget 树 , 收集 widgetType = 403 ( TableContainer ) 的 props . tableName 值 。
* 遍历 pc / mobile 的 widget 树 , 收集 widgetType = 100 ( TableContainer ) 的 bindData 下的 tableId
* /
private Set < String > collectSubTableNames ( JSONObject widgetJson ) {
Set < String > names = new HashSet < > ( ) ;
private Map < String , JSONObject > collectSubTableAndPropMap ( JSONObject widgetJson ) {
Map < String , JSONObject > resultMap = new HashMap < > ( ) ;
walkAllModes ( widgetJson , widget - > {
if ( widget . getInteger ( "widgetType" ) ! = null & & 403 = = widget . getInteger ( "widgetType" ) ) {
JSONObject props = widget . getJSONObject ( "props" ) ;
if ( props ! = null & & props . containsKey ( "tableName" ) ) {
String tn = props . getString ( "tableName" ) ;
if ( StrUtil . isNotEmpty ( tn ) ) {
names . add ( tn ) ;
JSONArray widgetList = widget . getJSONArray ( "widgetList" ) ;
if ( widgetList ! = null ) {
for ( int i = 0 ; i < widgetList . size ( ) ; i + + ) {
JSONObject childWidget = widgetList . getJSONObject ( i ) ;
// 只处理widgetType为100的子表
Integer widgetType = childWidget . getInteger ( "widgetType" ) ;
if ( widgetType = = null | | widgetType ! = 100 ) {
continue ;
}
JSONObject bindData = childWidget . getJSONObject ( "bindData" ) ;
if ( bindData = = null ) {
continue ;
}
String tableId = bindData . getString ( "tableId" ) ;
if ( StrUtil . isBlank ( tableId ) ) {
continue ;
}
JSONObject props = childWidget . getJSONObject ( "props" ) ;
if ( props ! = null ) {
resultMap . put ( tableId , props ) ;
}
}
}
} ) ;
return names ;
return resultMap ;
}
private Set < String > collectSubTableName ( JSONObject widgetJson ) {
Set < String > tableNameSet = new HashSet < > ( ) ;
walkAllModes ( widgetJson , widget - > {
JSONArray widgetList = widget . getJSONArray ( "widgetList" ) ;
if ( widgetList ! = null ) {
for ( int i = 0 ; i < widgetList . size ( ) ; i + + ) {
JSONObject childWidget = widgetList . getJSONObject ( i ) ;
// 只处理widgetType为100的子表
Integer widgetType = childWidget . getInteger ( "widgetType" ) ;
if ( widgetType = = null | | widgetType ! = 100 ) {
continue ;
}
JSONObject bindData = childWidget . getJSONObject ( "bindData" ) ;
if ( bindData = = null ) {
continue ;
}
if ( bindData . containsKey ( "tableName" ) ) {
tableNameSet . add ( bindData . getString ( "tableName" ) ) ;
}
}
}
} ) ;
return tableNameSet ;
}
/ * *
@ -930,15 +1025,53 @@ public class OnlineFormController {
@@ -930,15 +1025,53 @@ public class OnlineFormController {
return map ;
}
private Map < String , JSONObject > mapColumnIdAndWidget ( JSONObject widgetJson ) {
Map < String , JSONObject > resultMap = new HashMap < > ( ) ;
walkAllModes ( widgetJson , widget - > {
JSONArray widgetList = widget . getJSONArray ( "widgetList" ) ;
if ( widgetList ! = null ) {
for ( int i = 0 ; i < widgetList . size ( ) ; i + + ) {
JSONObject childWidget = widgetList . getJSONObject ( i ) ;
// 只处理widgetType为100的子表
Integer widgetType = childWidget . getInteger ( "widgetType" ) ;
if ( widgetType = = null | | widgetType ! = 100 ) {
continue ;
}
JSONObject bindData = childWidget . getJSONObject ( "bindData" ) ;
if ( bindData = = null ) {
continue ;
}
String tableId = bindData . getString ( "tableId" ) ;
if ( StrUtil . isBlank ( tableId ) ) {
continue ;
}
JSONObject props = childWidget . getJSONObject ( "props" ) ;
if ( props = = null ) {
continue ;
}
JSONArray tableColumnList = props . getJSONArray ( "tableColumnList" ) ;
for ( int j = 0 ; j < tableColumnList . size ( ) ; j + + ) {
JSONObject tableColumn = tableColumnList . getJSONObject ( j ) ;
resultMap . put ( tableColumn . getString ( "columnId" ) , tableColumn ) ;
}
}
}
} ) ;
return resultMap ;
}
/ * *
* 在 widgetJson 中查找匹配 tableName 的 TableContainer 控件 , 回填 relationId 。
* 在 widgetJson 中查找匹配 tableName 的 TableContainer 控件 , 回填 table Id。
* /
private void backfillRelationId ( JSONObject widgetJson , String tableName , Long relationId ) {
private void backfillRelationId ( JSONObject widgetJson , String tableName , Long table Id) {
walkAllModes ( widgetJson , widget - > {
if ( widget . getInteger ( "widgetType" ) ! = null & & 403 = = widget . getInteger ( "widgetType" ) ) {
JSONObject props = widget . getJSONObject ( "props" ) ;
if ( widget . getInteger ( "widgetType" ) ! = null & & 100 = = widget . getInteger ( "widgetType" ) ) {
JSONObject props = widget . getJSONObject ( "bindData " ) ;
if ( props ! = null & & tableName . equals ( props . getString ( "tableName" ) ) ) {
props . put ( "relationId" , relationId ) ;
props . put ( "tableId" , table Id ) ;
}
}
} ) ;