shiqian 4 лет назад
Родитель
Сommit
150963e0c6
59 измененных файлов с 5581 добавлено и 4 удалено
  1. 80 0
      boman-modules/boman-gen/src/main/java/com/boman/gen/controller/MyController.java
  2. 9 0
      boman-modules/boman-gen/src/main/java/com/boman/gen/mapper/GenTableColumnMapper.java
  3. 18 2
      boman-modules/boman-gen/src/main/java/com/boman/gen/service/GenTableColumnServiceImpl.java
  4. 8 0
      boman-modules/boman-gen/src/main/java/com/boman/gen/service/IGenTableColumnService.java
  5. 10 1
      boman-modules/boman-gen/src/main/resources/mapper/generator/GenTableColumnMapper.xml
  6. 3 0
      boman-modules/boman-gen/src/main/resources/mapper/generator/GenTableMapper.xml
  7. 19 1
      boman-modules/boman-system/pom.xml
  8. 43 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/ApplicationContextHandle.java
  9. 23 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/BaseFilter.java
  10. 493 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/BaseSaveService.java
  11. 70 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/BaseTableDTO.java
  12. 61 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/BaseTableSaveDTO.java
  13. 79 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/BaseTableService.java
  14. 325 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/BusinessResult.java
  15. 190 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/Column.java
  16. 962 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/ColumnImpl.java
  17. 17 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/DbRowAction.java
  18. 24 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/DefaultTableService.java
  19. 24 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/ExceptionFilter.java
  20. 94 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/Feature.java
  21. 87 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/FeatureManager.java
  22. 12 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/Filter.java
  23. 171 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/MainTableRecord.java
  24. 9 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/NDSException.java
  25. 46 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/OverlayJSONObject.java
  26. 47 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/QueryUtils.java
  27. 69 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/RequestUtil.java
  28. 57 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/Resources.java
  29. 12 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/ResultCode.java
  30. 147 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/RowRecord.java
  31. 81 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/RowResult.java
  32. 114 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/StoredProcedureService.java
  33. 62 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/SubTableRecord.java
  34. 21 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/Table.java
  35. 18 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/TableService.java
  36. 218 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/TableServiceCmdService.java
  37. 287 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/TableServiceContext.java
  38. 191 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/User.java
  39. 54 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/ValidationResults.java
  40. 8 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/Validator.java
  41. 130 0
      boman-modules/boman-system/src/main/java/com/boman/system/common/ValueHolder.java
  42. 31 0
      boman-modules/boman-system/src/main/java/com/boman/system/controller/ObjSaveController.java
  43. 360 0
      boman-modules/boman-system/src/main/java/com/boman/system/mapper/StandardlyMapper.java
  44. 50 0
      boman-modules/boman-system/src/main/java/com/boman/system/mapper/StoredProcedureMapper.java
  45. 1 0
      boman-modules/boman-system/src/main/java/com/boman/system/mapper/SysConfigMapper.java
  46. 1 0
      boman-modules/boman-system/src/main/java/com/boman/system/mapper/SysPostMapper.java
  47. 20 0
      boman-modules/boman-system/src/main/resources/mapper/system/SysConfigMapper.xml
  48. 22 0
      boman-modules/boman-system/src/main/resources/mapper/system/SysPostMapper.xml
  49. 151 0
      boman-save/pom.xml
  50. 31 0
      boman-save/src/main/java/com/boman/save/BomanSaveApplication.java
  51. 73 0
      boman-save/src/main/java/com/boman/save/controller/ObjSaveController.java
  52. 112 0
      boman-save/src/main/java/com/boman/save/domain/SysConfig.java
  53. 70 0
      boman-save/src/main/java/com/boman/save/mapper/SysConfigMapper.java
  54. 23 0
      boman-save/src/main/java/com/boman/save/proxy/MyInvocationHandler.java
  55. 20 0
      boman-save/src/main/java/com/boman/save/utils/ClassUtils.java
  56. 10 0
      boman-save/src/main/resources/banner.txt
  57. 27 0
      boman-save/src/main/resources/bootstrap.yml
  58. 74 0
      boman-save/src/main/resources/logback.xml
  59. 112 0
      boman-save/src/main/resources/mapper.system/SysConfigMapper.xml

+ 80 - 0
boman-modules/boman-gen/src/main/java/com/boman/gen/controller/MyController.java

@@ -0,0 +1,80 @@
+package com.boman.gen.controller;
+
+import com.boman.common.core.web.controller.BaseController;
+import com.boman.common.core.web.domain.AjaxResult;
+import com.boman.common.redis.service.RedisService;
+import com.boman.gen.domain.GenTable;
+import com.boman.gen.domain.GenTableColumn;
+import com.boman.gen.service.IGenTableColumnService;
+import com.boman.gen.service.IGenTableService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * @author shiqian
+ * @description 获取gen_table
+ * @date 2021年03月17日 16:44
+ **/
+@RestController
+@RequestMapping("/my")
+public class MyController extends BaseController {
+
+    @Autowired
+    private IGenTableService genTableService;
+    @Autowired
+    private IGenTableColumnService genTableColumnService;
+    @Autowired
+    private RedisService redisService;
+
+    /**
+     * 功能描述: 查询代码生成列表,table中封装columnList
+     *
+     * @param genTable 查询条件
+     * @return AjaxResult
+     */
+    @GetMapping("/loadTable")
+    public AjaxResult loadTable(GenTable genTable) throws ClassNotFoundException {
+        List<GenTable> tableList = genTableService.selectGenTableList(genTable);
+        if (null == tableList || tableList.isEmpty()) {
+            return AjaxResult.success();
+        }
+
+        List<Long> tableIdList = tableList.stream().map(GenTable::getTableId).collect(Collectors.toList());
+        List<GenTableColumn> genTableColumns = genTableColumnService.listByTableIdList(tableIdList);
+        if (null == genTableColumns || genTableColumns.isEmpty()) {
+            return AjaxResult.success();
+        }
+
+        packTableAndInsertToRedis(tableList, genTableColumns);
+        return AjaxResult.success(tableList);
+    }
+
+    /**
+     * 功能描述: 把table中塞入对应的column, 同时把所有的信息塞到redis中
+     *
+     * @param tableList       tableList
+     * @param genTableColumns 所有的列
+     */
+    private void packTableAndInsertToRedis(List<GenTable> tableList, List<GenTableColumn> genTableColumns) {
+        for (GenTable table : tableList) {
+            List<GenTableColumn> columnList = new ArrayList<>(16);
+            for (GenTableColumn tableColumn : genTableColumns) {
+                if (table.getTableId().equals(tableColumn.getTableId())) {
+                    columnList.add(tableColumn);
+                }
+            }
+
+            table.setColumns(columnList);
+            redisService.setCacheObject("table:" + table.getTableName(), table, 12L, TimeUnit.DAYS);
+        }
+    }
+
+
+}

+ 9 - 0
boman-modules/boman-gen/src/main/java/com/boman/gen/mapper/GenTableColumnMapper.java

@@ -2,6 +2,7 @@ package com.boman.gen.mapper;
 
 import java.util.List;
 import com.boman.gen.domain.GenTableColumn;
+import org.apache.ibatis.annotations.Param;
 
 /**
  * 业务字段 数据层
@@ -26,6 +27,14 @@ public interface GenTableColumnMapper
      */
     public List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId);
 
+    /**
+     * 查询业务字段列表
+     *
+     * @param tableIdList 业务字段编号List
+     * @return 业务字段集合
+     */
+    List<GenTableColumn> listByTableIdList(@Param("tableIdList") List<Long> tableIdList);
+
     /**
      * 新增业务字段
      * 

+ 18 - 2
boman-modules/boman-gen/src/main/java/com/boman/gen/service/GenTableColumnServiceImpl.java

@@ -1,5 +1,6 @@
 package com.boman.gen.service;
 
+import java.util.Collections;
 import java.util.List;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -29,8 +30,23 @@ public class GenTableColumnServiceImpl implements IGenTableColumnService
 	{
 	    return genTableColumnMapper.selectGenTableColumnListByTableId(tableId);
 	}
-	
-    /**
+
+	/**
+	 * 查询业务字段列表
+	 *
+	 * @param tableIdList 业务字段编号List
+	 * @return 业务字段集合
+	 */
+	@Override
+	public List<GenTableColumn> listByTableIdList(List<Long> tableIdList) {
+		if (null == tableIdList || tableIdList.isEmpty()) {
+			return Collections.emptyList();
+		}
+
+		return genTableColumnMapper.listByTableIdList(tableIdList);
+	}
+
+	/**
      * 新增业务字段
      * 
      * @param genTableColumn 业务字段信息

+ 8 - 0
boman-modules/boman-gen/src/main/java/com/boman/gen/service/IGenTableColumnService.java

@@ -18,6 +18,14 @@ public interface IGenTableColumnService
      */
     public List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId);
 
+    /**
+     * 查询业务字段列表
+     *
+     * @param tableIdList 业务字段编号List
+     * @return 业务字段集合
+     */
+    public List<GenTableColumn> listByTableIdList(List<Long> tableIdList);
+
     /**
      * 新增业务字段
      * 

+ 10 - 1
boman-modules/boman-gen/src/main/resources/mapper/generator/GenTableColumnMapper.xml

@@ -38,7 +38,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         where table_id = #{tableId}
         order by sort
     </select>
-    
+
+    <select id="listByTableIdList" parameterType="GenTableColumn" resultMap="GenTableColumnResult">
+        <include refid="selectGenTableColumnVo"/>
+        where table_id in
+        <foreach collection="tableIdList" open="(" close=")" separator="," item="tableId">
+            #{tableId}
+        </foreach>
+        order by sort
+    </select>
+
     <select id="selectDbTableColumnsByName" parameterType="String" resultMap="GenTableColumnResult">
 		select column_name, (case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else null end) as is_required, (case when column_key = 'PRI' then '1' else '0' end) as is_pk, ordinal_position as sort, column_comment, (case when extra = 'auto_increment' then '1' else '0' end) as is_increment, column_type
 		from information_schema.columns where table_schema = (select database()) and table_name = (#{tableName})

+ 3 - 0
boman-modules/boman-gen/src/main/resources/mapper/generator/GenTableMapper.xml

@@ -60,6 +60,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <select id="selectGenTableList" parameterType="GenTable" resultMap="GenTableResult">
 		<include refid="selectGenTableVo"/>
 		<where>
+			<if test="tableId != null and tableId != ''">
+				AND table_id = #{tableId}
+			</if>
 			<if test="tableName != null and tableName != ''">
 				AND lower(table_name) like lower(concat('%', #{tableName}, '%'))
 			</if>

+ 19 - 1
boman-modules/boman-system/pom.xml

@@ -14,7 +14,7 @@
     <description>
         boman-modules-system系统模块
     </description>
-	
+
     <dependencies>
     	
     	<!-- SpringCloud Ailibaba Nacos -->
@@ -78,6 +78,24 @@
             <artifactId>boman-common-swagger</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>commons-beanutils</groupId>
+            <artifactId>commons-beanutils</artifactId>
+            <version>1.9.4</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.boman</groupId>
+            <artifactId>boman-modules-gen</artifactId>
+            <version>2.5.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.4</version>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 43 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/ApplicationContextHandle.java

@@ -0,0 +1,43 @@
+package com.boman.system.common;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 15:27
+ **/
+public class ApplicationContextHandle implements ApplicationContextAware {
+
+    private static ApplicationContext applicationContext;
+
+    public ApplicationContextHandle() {
+    }
+
+    public static Object getBean(String name) throws BeansException {
+        return applicationContext.getBean(name);
+    }
+
+    public static ApplicationContext getApplicationContext() {
+        return applicationContext;
+    }
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        if (ApplicationContextHandle.applicationContext == null) {
+            ApplicationContextHandle.applicationContext = applicationContext;
+        }
+
+        System.out.println("========ApplicationContext配置成功,在普通类可以通过调用SpringUtils.getAppContext()获取applicationContext对象,applicationContext=" + ApplicationContextHandle.applicationContext + "========");
+    }
+
+    public static <T> T getBean(Class<T> clazz) {
+        return getApplicationContext().getBean(clazz);
+    }
+
+    public static <T> T getBean(String name, Class<T> clazz) {
+        return getApplicationContext().getBean(name, clazz);
+    }
+}

+ 23 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/BaseFilter.java

@@ -0,0 +1,23 @@
+package com.boman.system.common;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 11:02
+ **/
+public class BaseFilter {
+
+    private static final Logger log = LoggerFactory.getLogger(BaseFilter.class);
+
+    public BaseFilter() {
+    }
+
+    public void before(TableServiceContext context, MainTableRecord row) {
+    }
+
+    public void after(TableServiceContext context, MainTableRecord row) {
+    }
+}

+ 493 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/BaseSaveService.java

@@ -0,0 +1,493 @@
+package com.boman.system.common;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.boman.system.mapper.StandardlyMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.sql.Timestamp;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 11:25
+ **/
+@Component("baseSaveService-one")
+public class BaseSaveService {
+    private static final Logger LOGGER = LoggerFactory.getLogger(TableService.class);
+
+
+    @Resource
+    StoredProcedureService storedProcedureService;
+    @Autowired
+    private StandardlyMapper mapper;
+
+    public RowResult insertRow(TableServiceContext context, MainTableRecord row, Timestamp currentTime) {
+
+        // todo
+        Long id =/* insertMtable(context, row, currentTime)*/0L;
+        BusinessResult businessResult = new BusinessResult(id);
+        List<BusinessResult.Error> errorList = new LinkedList<>();
+        int successCount = 0;
+        Iterator var8 = row.getSubTables().values().iterator();
+
+        while(true) {
+            while(true) {
+                SubTableRecord itemTable;
+                JSONArray joItem;
+                do {
+                    do {
+                        if (!var8.hasNext()) {
+                            businessResult.setErrors(errorList);
+//                            GenTable table = context.getTable();
+                             // todo
+                            // storedProcedureService.storedProcedure(table.getHasTrigAc(), table.getTrigAc(), id, 0L, table.getName());
+                            if (errorList.size() > 0) {
+                                return RowResult.error(Resources.getMessage("新增成功" + successCount + "条,新增失败:" + errorList.size() + "条", /*context.getLocale() */null, new Object[0]), businessResult);
+                            }
+
+                            return RowResult.ok(Resources.getMessage("新增成功", /*context.getLocale() */null, new Object[0]), businessResult);
+                        }
+
+                        itemTable = (SubTableRecord)var8.next();
+                        joItem = itemTable.getCommitDatas();
+                    } while(joItem == null);
+                } while(joItem.size() <= 0);
+
+                String fkKey = /*itemTable.getFKColumnName()*/null;
+                if (!context.isInsertBacth()) {
+                    for(int i = 0; i < joItem.size(); ++i) {
+                        JSONObject insertKeys = joItem.getJSONObject(i);
+                        insertKeys.put(fkKey, id);
+                        BusinessResult.Error error = insertStable(itemTable.getRealTableName(), insertKeys, context, currentTime, itemTable.getTable());
+                        if (error != null) {
+                            errorList.add(error);
+                        } else {
+                            ++successCount;
+                        }
+                    }
+                } else {
+//                    BusinessResult.Error error = this.insertStableBatch(itemTable.getRealTableName(), joItem, context, currentTime, fkKey, id);
+//                    if (error != null) {
+//                        errorList.add(error);
+//                    } else {
+//                        ++successCount;
+//                    }
+                }
+            }
+        }
+    }
+
+//    private BusinessResult.Error insertStableBatch(String tableName, JSONArray joItem, TableServiceContext context, Timestamp currentTime, String fkKey, long fkId) {
+//
+//        BusinessResult.Error error = null;
+//
+//        try {
+//            //100条每次
+//            int pageSize = 100;
+//            int count = joItem.size();
+//            int page = count % pageSize == 0 ? count / pageSize : (count / pageSize) + 1;
+//            Table table = context.getTable();
+//            for (int n = 0; n < page; n++) {
+//                //起始位置
+//                int index = (n * pageSize);
+//                //每页行数是否大于剩余行数
+//                if (pageSize > count - index) {
+//                    //设置成总数量
+//                    pageSize = count - index;
+//                }
+//                //数组每次从0开始
+//                JSONObject[] insertKeysList = new JSONObject[pageSize];
+//                for (int i = 0; i < pageSize; i++) {
+//                    JSONObject insertKeys = joItem.getJSONObject(index + i);
+//                    insertKeys.put(fkKey, fkId);
+//                    // 新增明细表
+//                    User currentUser = context.getUser();
+//                    if (!insertKeys.containsKey("ID")
+//                            || insertKeys.getLong("ID") == null || insertKeys.getLong("ID") <= 0L) {
+//                        long id = ModelUtil.getSequence(tableName).longValue();
+//                        insertKeys.put("ID", id);
+//                    }
+//                    if (null != currentUser) {
+//                        if (null != table.getColumn("AD_CLIENT_ID")) {
+////                            if (!insertKeys.containsKey("AD_CLIENT_ID") || Validator.isNull(insertKeys.getLong("AD_CLIENT_ID"))) {
+////                                insertKeys.put("AD_CLIENT_ID", Long.valueOf(currentUser.getAdClientId()).longValue());
+////                            }
+//                        }
+//                        if (null != table.getColumn("CID")) {
+////                            if (!insertKeys.containsKey("CID") || Validator.isNull(insertKeys.getLong("CID"))) {
+////                                insertKeys.put("CID", Long.valueOf(currentUser.getCid()).longValue());
+////                            }
+//                        }
+//                        if (null != table.getColumn("AD_ORG_ID")) {
+//                            //insertKeys.put("AD_ORG_ID", Long.valueOf(currentUser.getAdOrgId()).longValue());
+//                        }
+//                        if (null != table.getColumn("OWNERNAME")) {
+//                            insertKeys.put("OWNERNAME", currentUser.getName());
+//                        }
+//                        if (null != table.getColumn("MODIFIERNAME")) {
+//                            insertKeys.put("MODIFIERNAME", currentUser.getName());
+//                        }
+//                        if (null != table.getColumn("CREATENAME")) {
+//                            insertKeys.put("CREATENAME", currentUser.getName());
+//                        }
+//                        if (null != table.getColumn("MODIFYNAME")) {
+//                            insertKeys.put("MODIFYNAME", currentUser.getName());
+//                        }
+//                        if (null != table.getColumn("CREATEID")) {
+//                            insertKeys.put("CREATEID", currentUser.getId());
+//                        }
+//                        if (null != table.getColumn("MODIFYID")) {
+//                            insertKeys.put("MODIFYID", currentUser.getId());
+//                        }
+//                    }
+//                    if (null != table.getColumn("MODIFIEDDATE")) {
+//                        insertKeys.put("MODIFIEDDATE", currentTime);
+//                    }
+//                    if (null != table.getColumn("CREATIONDATE")) {
+//                        insertKeys.put("CREATIONDATE", currentTime);
+//                    }
+//                    if (null != table.getColumn("MODIFYTIME")) {
+//                        insertKeys.put("MODIFYTIME", currentTime);
+//                    }
+//                    if (null != table.getColumn("CREATETIME")) {
+//                        insertKeys.put("CREATETIME", currentTime);
+//                    }
+//                    if (null != table.getColumn("STATUS")) {
+//                        insertKeys.put("STATUS", 1);
+//                    }
+//                    if (null != table.getColumn("ISACTIVE") && !insertKeys.containsKey("ISACTIVE")) {
+//                        insertKeys.put("ISACTIVE", table.getColumn("ISDEL").getDefaultValue());
+//                    }
+//                    if (null != table.getColumn("ISDEL") && !insertKeys.containsKey("ISDEL")) {
+//                        insertKeys.put("ISDEL", table.getColumn("ISDEL").getDefaultValue());
+//                    }
+////                    if (null != currentUser) {
+////                        if (!insertKeys.containsKey("AD_CLIENT_ID") || Validator.isNull(insertKeys.getLong("AD_CLIENT_ID"))) {
+////                            insertKeys.put("AD_CLIENT_ID", Long.valueOf(currentUser.getAdClientId()).longValue());
+////                        }
+////                        insertKeys.put("AD_ORG_ID", Long.valueOf(currentUser.getAdOrgId()).longValue());
+////                        //外键关联字段
+////                        insertKeys.put("MODIFIERID", currentUser.getId().longValue());
+////                        insertKeys.put("OWNERID", currentUser.getId().longValue());
+////                        insertKeys.put("OWNERNAME", currentUser.getName());
+////                        insertKeys.put("MODIFIERNAME", currentUser.getName());
+////                    }
+////                    insertKeys.put("MODIFIEDDATE", currentTime);
+////                    insertKeys.put("CREATIONDATE", currentTime);
+////                    if (!insertKeys.containsKey("isactive") && !insertKeys.containsKey("ISACTIVE")) {
+////                        insertKeys.put("ISACTIVE", "Y");//默认可用
+////                    }
+//                    //
+//                    insertKeysList[i] = insertKeys;
+//                }
+//
+//                int ret = mapper.inserts(tableName, insertKeysList, null);
+//                if (ret <= 0) {
+//                    throw new NDSException(Resources.getMessage("明细批量新增失败!", /*context.getLocale() */null));
+//                }
+//            }
+//
+//        } catch (NDSException e) {
+//            // 将错误信息存入dataArrayJson中
+//            error = getData(e);
+//        }
+//
+//        return error;
+//    }
+
+    /**
+     * 获取明细表新增错误信息并插入dataJson
+     *
+     * @param e 异常信息
+     * @return JSONObject
+     */
+//    private BusinessResult.Error getData(NDSException e) {
+//        return getData(e, 0L);
+//    }
+
+    /**
+     * 获取明细表更新错误信息并插入dataJson
+     *
+     * @param e      异常信息
+     * @param itemId 明细ID
+     * @return JSONObject
+     */
+//    private BusinessResult.Error getData(NDSException e, Long itemId) {
+//        return new BusinessResult.Error(itemId, -1, e.getMessage());
+//    }
+
+//    /**
+//     * 新增主表
+//     *
+//     * @return Long
+//     */
+//    private Long insertMtable(TableServiceContext context, MainTableRecord row, Timestamp currentTime) {
+//        // 新增主表
+//        //设置单号
+//        handlerSequenceNumber(context, row);
+//        //设置默认值
+//        handlerDefaultValue(context, row);
+//        //
+//        User currentUser = context.getUser();
+//        Long id = row.getCommitData().getLong("ID");
+//        if (id == null || id <= 0L) {
+//            id = ModelUtil.getSequence(row.getMainData().getRealTableName());
+//        }
+//        row.getCommitData().put("ID", id);
+//        row.setId(id);
+//        Table table = context.getTable();
+//        //List<Column> allColumns = table.getAllColumns();
+//        if (null != currentUser) {
+////            if (null != table.getColumn("AD_CLIENT_ID")) {
+////                if (!row.getCommitData().containsKey("AD_CLIENT_ID") || Validator.isNull(row.getCommitData().getLong("AD_CLIENT_ID"))) {
+////                    row.getCommitData().put("AD_CLIENT_ID", Long.valueOf(currentUser.getAdClientId()).longValue());
+////                }
+////            }
+//            if (null != table.getColumn("CID")) {
+////                if (!row.getCommitData().containsKey("CID") || Validator.isNull(row.getCommitData().getLong("CID"))) {
+////                    row.getCommitData().put("CID", Long.valueOf(currentUser.getCid()).longValue());
+////                }
+//            }
+//            if (null != table.getColumn("AD_ORG_ID")) {
+//                //row.getCommitData().put("AD_ORG_ID", Long.valueOf(currentUser.getAdOrgId()).longValue());
+//            }
+//            if (null != table.getColumn("OWNERNAME")) {
+//                row.getCommitData().put("OWNERNAME", currentUser.getName());
+//            }
+//            if (null != table.getColumn("MODIFIERNAME")) {
+//                row.getCommitData().put("MODIFIERNAME", currentUser.getName());
+//            }
+//            if (null != table.getColumn("CREATENAME")) {
+//                row.getCommitData().put("CREATENAME", currentUser.getName());
+//            }
+//            if (null != table.getColumn("MODIFYNAME")) {
+//                row.getCommitData().put("MODIFYNAME", currentUser.getName());
+//            }
+//            if (null != table.getColumn("CREATEID")) {
+//                row.getCommitData().put("CREATEID", currentUser.getId());
+//            }
+//            if (null != table.getColumn("MODIFYID")) {
+//                row.getCommitData().put("MODIFYID", currentUser.getId());
+//            }
+//
+//        }
+//        if (null != table.getColumn("MODIFIEDDATE")) {
+//            row.getCommitData().put("MODIFIEDDATE", currentTime);
+//        }
+//        if (null != table.getColumn("CREATIONDATE")) {
+//            row.getCommitData().put("CREATIONDATE", currentTime);
+//        }
+//        if (null != table.getColumn("MODIFYTIME")) {
+//            row.getCommitData().put("MODIFYTIME", currentTime);
+//        }
+//        if (null != table.getColumn("CREATETIME")) {
+//            row.getCommitData().put("CREATETIME", currentTime);
+//        }
+//        if (null != table.getColumn("STATUS")) {
+//            row.getCommitData().put("STATUS", 1);
+//        }
+//        if (null != table.getColumn("ISACTIVE") && !row.getCommitData().containsKey("ISACTIVE")) {
+//            row.getCommitData().put("ISACTIVE", "Y");
+//        }
+//        if (null != table.getColumn("ISDEL") && !row.getCommitData().containsKey("ISDEL")) {
+//            row.getCommitData().put("ISDEL", table.getColumn("ISDEL").getDefaultValue());
+//        }
+//
+//        JSONObject commitData = row.getCommitData();
+//        try {
+//            int ret = mapper.insert(context.getRealTableName(), commitData);
+//            if (ret <= 0) {
+//                throw new NDSException(Resources.getMessage("主表新增失败!", /*context.getLocale() */null));
+//            } else {
+//                //新增成功后 调用存储过程 AC-- wmc
+//                storedProcedureService.storedProcedure(table.getHasTrigAc(), table.getTrigAc(), id, 1L, table.getName());
+//            }
+//        } catch (Exception e) {
+//            LOGGER.error(commitData.toJSONString());
+//            throw e;
+//        }
+//
+//        return id;
+//    }
+
+//    private JSONObject handlerSequenceNumber(TableServiceContext context, MainTableRecord row) {
+//
+//        JSONObject jo = row.getCommitData();
+//        if (jo == null || jo.size() <= 0) {
+//            throw new NDSException("没有主表数据需要新增");
+//        }
+//
+//        Table table = context.getTable();
+//
+//        // 判断主表是否存在序列生成器
+//        ArrayList columns = table.getAllColumns();
+//        for (int i = 0; i < columns.size(); i++) {
+//            Column column = (Column) columns.get(i);
+//            if (column != null) {
+//                //赋值方式
+//                String obtainManner = column.getObtainManner();
+//                //赋值方式是否是【单据编号】
+//                if (!"sheetNo".equals(obtainManner)) {
+//                    continue;
+//                }
+//                //生成规则
+//                String sequenceHead = column.getSequenceHead();
+//                if (sequenceHead == null || "".equals(sequenceHead)) {
+//                    continue;
+//                }
+//                //按照规则生成编号
+//                String sequenceNumber = Optional.ofNullable(row.getCommitData().getString(column.getName()))
+//                        .orElse(ModelUtil.generateSerialNumber(sequenceHead, row.getCommitData(), /*context.getLocale() */null));
+//                jo.put(column.getName(), sequenceNumber);
+//            }
+//        }
+//
+//        return jo;
+//    }
+
+    /**
+     * 新增子表
+     *
+     * @return JSONObject
+     */
+    private BusinessResult.Error insertStable(String tableName, JSONObject insertKeys, TableServiceContext context, Timestamp currentTime, Table table) {
+        /*BusinessResult.Error error = null;
+        try {
+            // 新增明细表
+            // todo 设置默认值
+            //handlerDefaultValue(context, insertKeys);
+            User currentUser = context.getUser();
+            //Table table = context.getTable();
+            if (!insertKeys.containsKey("ID")
+                    || insertKeys.getLong("ID") == null || insertKeys.getLong("ID") <= 0L) {
+                long id = ModelUtil.getSequence(tableName).longValue();
+                insertKeys.put("ID", id);
+            }
+
+            if (null != currentUser) {
+                if (null != table.getColumn("AD_CLIENT_ID")) {
+//                    if (!insertKeys.containsKey("AD_CLIENT_ID") || Validator.isNull(insertKeys.getLong("AD_CLIENT_ID"))) {
+//                        insertKeys.put("AD_CLIENT_ID", Long.valueOf(currentUser.getAdClientId()).longValue());
+//                    }
+                }
+                if (null != table.getColumn("CID")) {
+//                    if (!insertKeys.containsKey("CID") || Validator.isNull(insertKeys.getLong("CID"))) {
+//                        insertKeys.put("CID", Long.valueOf(currentUser.getCid()).longValue());
+//                    }
+                }
+                if (null != table.getColumn("AD_ORG_ID")) {
+                    //insertKeys.put("AD_ORG_ID", Long.valueOf(currentUser.getAdOrgId()).longValue());
+                }
+                if (null != table.getColumn("OWNERNAME")) {
+                    insertKeys.put("OWNERNAME", currentUser.getName());
+                }
+                if (null != table.getColumn("MODIFIERNAME")) {
+                    insertKeys.put("MODIFIERNAME", currentUser.getName());
+                }
+                if (null != table.getColumn("CREATENAME")) {
+                    insertKeys.put("CREATENAME", currentUser.getName());
+                }
+                if (null != table.getColumn("MODIFYNAME")) {
+                    insertKeys.put("MODIFYNAME", currentUser.getName());
+                }
+                if (null != table.getColumn("CREATEID")) {
+                    insertKeys.put("CREATEID", currentUser.getId());
+                }
+                if (null != table.getColumn("MODIFYID")) {
+                    insertKeys.put("MODIFYID", currentUser.getId());
+                }
+            }
+
+            if (null != table.getColumn("MODIFIEDDATE")) {
+                insertKeys.put("MODIFIEDDATE", currentTime);
+            }
+            if (null != table.getColumn("CREATIONDATE")) {
+                insertKeys.put("CREATIONDATE", currentTime);
+            }
+            if (null != table.getColumn("MODIFYTIME")) {
+                insertKeys.put("MODIFYTIME", currentTime);
+            }
+            if (null != table.getColumn("CREATETIME")) {
+                insertKeys.put("CREATETIME", currentTime);
+            }
+            if (null != table.getColumn("STATUS")) {
+                insertKeys.put("STATUS", 1);
+            }
+            if (null != table.getColumn("ISACTIVE") && !insertKeys.containsKey("ISACTIVE")) {
+                insertKeys.put("ISACTIVE", table.getColumn("ISDEL").getDefaultValue());
+            }
+            if (null != table.getColumn("ISDEL") && !insertKeys.containsKey("ISDEL")) {
+                insertKeys.put("ISDEL", table.getColumn("ISDEL").getDefaultValue());
+            }
+//            if (null != currentUser) {
+//                if (!insertKeys.containsKey("AD_CLIENT_ID") || Validator.isNull(insertKeys.getLong("AD_CLIENT_ID"))) {
+//                    insertKeys.put("AD_CLIENT_ID", Long.valueOf(currentUser.getAdClientId()).longValue());
+//                }
+//                insertKeys.put("AD_ORG_ID", Long.valueOf(currentUser.getAdOrgId()).longValue());
+//                //外键关联字段
+//                insertKeys.put("MODIFIERID", currentUser.getId().longValue());
+//                insertKeys.put("OWNERID", currentUser.getId().longValue());
+//                insertKeys.put("OWNERNAME", currentUser.getName());
+//                insertKeys.put("MODIFIERNAME", currentUser.getName());
+//            }
+
+//            insertKeys.put("MODIFIEDDATE", currentTime);
+//            insertKeys.put("CREATIONDATE", currentTime);
+//            if (!insertKeys.containsKey("isactive") && !insertKeys.containsKey("ISACTIVE")) {
+//                insertKeys.put("ISACTIVE", "Y");//默认可用
+//            }
+
+            int ret = mapper.insert(tableName, insertKeys);
+
+            if (ret <= 0) {
+                throw new IllegalArgumentException(Resources.getMessage("明细新增失败!", *//*context.getLocale() *//*null));
+            }else {
+                // todo 新增成功  调用明细的新增存储过程
+                // storedProcedureService.storedProcedure(table.getHasTrigAc(), table.getTrigAc(), insertKeys.getLong("ID"), 1L, table.getName());
+            }
+        } catch (RuntimeException e) {
+            // 将错误信息存入dataArrayJson中
+//            error = getData(e);
+        }
+
+        return error;*/
+        return null;
+    }
+
+//    private void handlerDefaultValue(TableServiceContext context, MainTableRecord row) {
+//        JSONObject jo = row.getCommitData();
+//        handlerDefaultValue(context, jo);
+//
+//    }
+
+//    private void handlerDefaultValue(TableServiceContext context, JSONObject jo) {
+//
+//        if (jo == null || jo.size() <= 0) {
+//            throw new NDSException("没有主表数据需要新增");
+//        }
+//
+//        Table table = context.getTable();
+//
+//        //增加界面不显示字段默认值传入,识别第6位
+//        ArrayList columns = table.getColumns(new int[]{6}, false, 0, true);
+//
+//        columns.forEach(item -> {
+//            String val = ((Column) item).getDefaultValue();
+//            //if(val.contains("$")){
+//            val = QueryUtils.replaceVariables(val, context.getUser());
+//            //}
+//            jo.put(((Column) item).getName(), val);
+//        });
+//
+//    }
+
+
+}

+ 70 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/BaseTableDTO.java

@@ -0,0 +1,70 @@
+package com.boman.system.common;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.annotation.JSONField;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 09:53
+ **/
+public class BaseTableDTO {
+
+    @JSONField(name = "objId")
+    private Long objId;
+
+    @JSONField(name = "fixedData")
+    private JSONObject fixedData;
+
+    /**
+     * 前台传参中的表名
+     */
+    @JSONField(name = "table")
+    private String table;
+
+    @JSONField(name = "delMTable")
+    private Boolean delMTable;
+
+    @JSONField(name = "tabItem")
+    private JSONObject tabItem;
+
+    public Long getObjId() {
+        return objId;
+    }
+
+    public void setObjId(Long objId) {
+        this.objId = objId;
+    }
+
+    public JSONObject getFixedData() {
+        return fixedData;
+    }
+
+    public void setFixedData(JSONObject fixedData) {
+        this.fixedData = fixedData;
+    }
+
+    public String getTable() {
+        return table;
+    }
+
+    public void setTable(String table) {
+        this.table = table;
+    }
+
+    public Boolean getDelMTable() {
+        return delMTable;
+    }
+
+    public void setDelMTable(Boolean delMTable) {
+        this.delMTable = delMTable;
+    }
+
+    public JSONObject getTabItem() {
+        return tabItem;
+    }
+
+    public void setTabItem(JSONObject tabItem) {
+        this.tabItem = tabItem;
+    }
+}

+ 61 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/BaseTableSaveDTO.java

@@ -0,0 +1,61 @@
+package com.boman.system.common;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.annotation.JSONField;
+
+import java.io.Serializable;
+
+/**
+ * @author:zc
+ * @since:2018/12/27
+ * @createat:2018/12/274:41 PM
+ */
+public class BaseTableSaveDTO implements Serializable {
+
+    private static final long serialVersionUID = -8653990707913725671L;
+    @JSONField(name = "objId")
+    private Long objId;
+
+    @JSONField(name = "fixedData")
+    private JSONObject fixedData;
+
+    @JSONField(name = "table")
+    private String table;
+
+    public static long getSerialVersionUID() {
+        return serialVersionUID;
+    }
+
+    public Long getObjId() {
+        return objId;
+    }
+
+    public void setObjId(Long objId) {
+        this.objId = objId;
+    }
+
+    public JSONObject getFixedData() {
+        return fixedData;
+    }
+
+    public void setFixedData(JSONObject fixedData) {
+        this.fixedData = fixedData;
+    }
+
+    public String getTable() {
+        return table;
+    }
+
+    public void setTable(String table) {
+        this.table = table;
+    }
+
+    @Override
+    public String toString() {
+        return "BaseTableSaveDTO{" +
+                "objId=" + objId +
+                ", fixedData=" + fixedData +
+                ", table='" + table + '\'' +
+                '}';
+    }
+}

+ 79 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/BaseTableService.java

@@ -0,0 +1,79 @@
+package com.boman.system.common;
+
+import lombok.Getter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 10:30
+ **/
+public abstract class BaseTableService  implements TableService{
+
+
+    @Autowired
+    @Qualifier("baseSaveService-one")
+    private BaseSaveService baseSaveService;
+    @Getter
+    private String tableName;
+
+    private boolean isInitialized;
+
+    public BaseTableService() {
+    }
+
+    protected BaseTableService(String tableName) {
+        this.tableName = tableName;
+        isInitialized = false;
+    }
+
+    @Override
+    public final void configure(TableServiceContext context) {
+        if (!isInitialized) {
+            doConfigure(context);
+            isInitialized = true;
+        }
+    }
+
+    protected void doConfigure(TableServiceContext context) {
+        //每个业务可以在自己所在的自定义服务实现内部调整下自己的上下文(针对validators/filters的调整)
+        //本方法一个表只会执行一次才对
+    }
+
+    @Override
+    public RowResult executeAction(TableServiceContext context, MainTableRecord row) {
+        LOGGER.debug("action====>" + context.getActionName());
+        return baseSaveService.insertRow(context, row, context.getCurrentTime());
+
+
+//        switch (context.getActionName()) {
+//            case Constants.ACTION_SAVE:
+//                switch (row.getAction()) {
+//                    case INSERT:
+//                        return baseSaveService.insertRow(context, row, context.getCurrentTime());
+//                    case UPDATE:
+//                        //return baseSaveService.updateRow(context, row, context.getCurrentTime());
+//                    default:
+//                }
+//                throw new NDSException("不应该执行到这里吧!");
+//            case Constants.ACTION_DELETE:
+//                //return baseDelService.delete(context, row);
+//            case Constants.ACTION_VOID:
+//                //return baseVoidService.execute(context, row);
+//            case Constants.ACTION_SUBMIT:
+//                //return baseSubmitService.isFlow(context, row);
+//            case Constants.ACTION_UNSUBMIT:
+//                //return baseUnSubmitService.execute(context, row);
+//
+//            default:
+////            default:
+////                return RowResult.error("未知动作:" + context.getActionName());
+//        }
+//        return RowResult.ok(context.getLocale());
+
+//        return RowResult.ok("");
+    }
+
+
+}

+ 325 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/BusinessResult.java

@@ -0,0 +1,325 @@
+package com.boman.system.common;
+
+import com.alibaba.fastjson.JSONObject;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 13:51
+ **/
+public class BusinessResult implements Serializable {
+    private static final long serialVersionUID = 5882709765648149444L;
+    private Long objId;
+    private List<BusinessResult.Error> errors;
+    private BusinessResult.ExtAttr extAttr;
+    private JSONObject notice;
+
+    public BusinessResult() {
+    }
+
+    public BusinessResult(Long objId) {
+        this.objId = objId;
+    }
+
+    public BusinessResult(Long objId, List<BusinessResult.Error> error) {
+        this.objId = objId;
+        this.errors = error;
+    }
+
+    public void putErrorItem(Long id, Integer code, String message) {
+        if (this.errors == null) {
+            this.errors = new ArrayList();
+        }
+
+        this.errors.add(new BusinessResult.Error(id, code, message));
+    }
+
+    public Long getObjId() {
+        return this.objId;
+    }
+
+    public List<BusinessResult.Error> getErrors() {
+        return this.errors;
+    }
+
+    public BusinessResult.ExtAttr getExtAttr() {
+        return this.extAttr;
+    }
+
+    public JSONObject getNotice() {
+        return this.notice;
+    }
+
+    public void setObjId(final Long objId) {
+        this.objId = objId;
+    }
+
+    public void setErrors(final List<BusinessResult.Error> errors) {
+        this.errors = errors;
+    }
+
+    public void setExtAttr(final BusinessResult.ExtAttr extAttr) {
+        this.extAttr = extAttr;
+    }
+
+    public void setNotice(final JSONObject notice) {
+        this.notice = notice;
+    }
+
+    public boolean equals(final Object o) {
+        if (o == this) {
+            return true;
+        } else if (!(o instanceof BusinessResult)) {
+            return false;
+        } else {
+            BusinessResult other = (BusinessResult)o;
+            if (!other.canEqual(this)) {
+                return false;
+            } else {
+                label59: {
+                    Object this$objId = this.getObjId();
+                    Object other$objId = other.getObjId();
+                    if (this$objId == null) {
+                        if (other$objId == null) {
+                            break label59;
+                        }
+                    } else if (this$objId.equals(other$objId)) {
+                        break label59;
+                    }
+
+                    return false;
+                }
+
+                Object this$errors = this.getErrors();
+                Object other$errors = other.getErrors();
+                if (this$errors == null) {
+                    if (other$errors != null) {
+                        return false;
+                    }
+                } else if (!this$errors.equals(other$errors)) {
+                    return false;
+                }
+
+                Object this$extAttr = this.getExtAttr();
+                Object other$extAttr = other.getExtAttr();
+                if (this$extAttr == null) {
+                    if (other$extAttr != null) {
+                        return false;
+                    }
+                } else if (!this$extAttr.equals(other$extAttr)) {
+                    return false;
+                }
+
+                Object this$notice = this.getNotice();
+                Object other$notice = other.getNotice();
+                if (this$notice == null) {
+                    if (other$notice != null) {
+                        return false;
+                    }
+                } else if (!this$notice.equals(other$notice)) {
+                    return false;
+                }
+
+                return true;
+            }
+        }
+    }
+
+    protected boolean canEqual(final Object other) {
+        return other instanceof BusinessResult;
+    }
+
+    @Override
+    public int hashCode() {
+        boolean PRIME = true;
+        int result = 1;
+        Object $objId = this.getObjId();
+        result = result * 59 + ($objId == null ? 43 : $objId.hashCode());
+        Object $errors = this.getErrors();
+        result = result * 59 + ($errors == null ? 43 : $errors.hashCode());
+        Object $extAttr = this.getExtAttr();
+        result = result * 59 + ($extAttr == null ? 43 : $extAttr.hashCode());
+        Object $notice = this.getNotice();
+        result = result * 59 + ($notice == null ? 43 : $notice.hashCode());
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "BusinessResult(objId=" + this.getObjId() + ", errors=" + this.getErrors() + ", extAttr=" + this.getExtAttr() + ", notice=" + this.getNotice() + ")";
+    }
+
+    public static class Error {
+        private Long id;
+        private Integer code;
+        private String message;
+
+        public Error() {
+        }
+
+        public Error(Long id, Integer code, String message) {
+            this.id = id;
+            this.code = code;
+            this.message = message;
+        }
+
+        public Long getId() {
+            return this.id;
+        }
+
+        public Integer getCode() {
+            return this.code;
+        }
+
+        public String getMessage() {
+            return this.message;
+        }
+
+        public void setId(final Long id) {
+            this.id = id;
+        }
+
+        public void setCode(final Integer code) {
+            this.code = code;
+        }
+
+        public void setMessage(final String message) {
+            this.message = message;
+        }
+
+        public boolean equals(final Object o) {
+            if (o == this) {
+                return true;
+            } else if (!(o instanceof BusinessResult.Error)) {
+                return false;
+            } else {
+                BusinessResult.Error other = (BusinessResult.Error)o;
+                if (!other.canEqual(this)) {
+                    return false;
+                } else {
+                    label47: {
+                        Object this$id = this.getId();
+                        Object other$id = other.getId();
+                        if (this$id == null) {
+                            if (other$id == null) {
+                                break label47;
+                            }
+                        } else if (this$id.equals(other$id)) {
+                            break label47;
+                        }
+
+                        return false;
+                    }
+
+                    Object this$code = this.getCode();
+                    Object other$code = other.getCode();
+                    if (this$code == null) {
+                        if (other$code != null) {
+                            return false;
+                        }
+                    } else if (!this$code.equals(other$code)) {
+                        return false;
+                    }
+
+                    Object this$message = this.getMessage();
+                    Object other$message = other.getMessage();
+                    if (this$message == null) {
+                        if (other$message != null) {
+                            return false;
+                        }
+                    } else if (!this$message.equals(other$message)) {
+                        return false;
+                    }
+
+                    return true;
+                }
+            }
+        }
+
+        protected boolean canEqual(final Object other) {
+            return other instanceof BusinessResult.Error;
+        }
+
+        public int hashCode() {
+            boolean PRIME = true;
+            int result = 1;
+            Object $id = this.getId();
+            result = result * 59 + ($id == null ? 43 : $id.hashCode());
+            Object $code = this.getCode();
+            result = result * 59 + ($code == null ? 43 : $code.hashCode());
+            Object $message = this.getMessage();
+            result = result * 59 + ($message == null ? 43 : $message.hashCode());
+            return result;
+        }
+
+        @Override
+        public String toString() {
+            return "BusinessResult.Error(id=" + this.getId() + ", code=" + this.getCode() + ", message=" + this.getMessage() + ")";
+        }
+    }
+
+    public static class ExtAttr {
+        private Integer msgType;
+
+        public ExtAttr() {
+        }
+
+        public ExtAttr(Integer msgType) {
+            this.msgType = msgType;
+        }
+
+        public Integer getMsgType() {
+            return this.msgType;
+        }
+
+        public void setMsgType(final Integer msgType) {
+            this.msgType = msgType;
+        }
+
+        public boolean equals(final Object o) {
+            if (o == this) {
+                return true;
+            } else if (!(o instanceof BusinessResult.ExtAttr)) {
+                return false;
+            } else {
+                BusinessResult.ExtAttr other = (BusinessResult.ExtAttr)o;
+                if (!other.canEqual(this)) {
+                    return false;
+                } else {
+                    Object this$msgType = this.getMsgType();
+                    Object other$msgType = other.getMsgType();
+                    if (this$msgType == null) {
+                        if (other$msgType != null) {
+                            return false;
+                        }
+                    } else if (!this$msgType.equals(other$msgType)) {
+                        return false;
+                    }
+
+                    return true;
+                }
+            }
+        }
+
+        protected boolean canEqual(final Object other) {
+            return other instanceof BusinessResult.ExtAttr;
+        }
+
+        public int hashCode() {
+            boolean PRIME = true;
+            int result = 1;
+            Object $msgType = this.getMsgType();
+            result = result * 59 + ($msgType == null ? 43 : $msgType.hashCode());
+            return result;
+        }
+
+        @Override
+        public String toString() {
+            return "BusinessResult.ExtAttr(msgType=" + this.getMsgType() + ")";
+        }
+    }
+}
+

+ 190 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/Column.java

@@ -0,0 +1,190 @@
+package com.boman.system.common;
+
+import java.io.Serializable;
+import java.util.Locale;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 16:16
+ **/
+public interface Column extends Serializable {
+
+    int NUMBER = 0;
+    int DATE = 1;
+    int STRING = 2;
+    int DATENUMBER = 3;
+    int TIME = 4;
+    int OTHER = 9;
+    int ADD = 0;
+    int MODIFY = 1;
+    int QUERY_LIST = 2;
+    int QUERY_SUBLIST = 3;
+    int QUERY_OBJECT = 4;
+    int PRINT_LIST = 5;
+    int PRINT_SUBLIST = 6;
+    int PRINT_OBJECT = 7;
+    int MASK_CREATE_SHOW = 0;
+    int MASK_CREATE_EDIT = 1;
+    int MASK_MODIFIY_SHOW = 2;
+    int MASK_MODIFY_EDIT = 3;
+    int MASK_QUERY_LIST = 4;
+    int MASK_QUERY_SUBLIST = 5;
+    int MASK_QUERY_OBJECTVIEW = 6;
+    int MASK_PRINT_LIST = 7;
+    int MASK_PRINT_SUBLIST = 8;
+    int MASK_PRINT_OBJECTVIEW = 9;
+    int ON_DELETE_NOACTION = 0;
+    int ON_DELETE_SETNULL = 1;
+    int ON_DELETE_CASCADE = 2;
+
+//    boolean isAlternateKey();
+//
+//    boolean isAlternateKey2();
+//
+//    boolean isDisplayKey();
+//
+//    String getComment();
+//
+//    String getShowcomment();
+//
+//    Boolean getIsorder();
+//
+//    Boolean getShowtitle();
+//
+//    Boolean getRowspan();
+//
+//    String getLimitValueGroupName();
+//
+//    boolean isShowable(int action);
+//
+//    boolean isMaskSet(int maskPosition);
+//
+//    boolean isMaskequls(int maskPosition);
+//
+//    boolean isModifiable(int action);
+//
+//    boolean isNullable();
+//
+//    boolean isValueLimited();
+
+//    PairTable getValues(Locale locale);
+//
+//    int getLength();
+//
+//    int getScale();
+//
+//    int getStatSize();
+//
+//    Table getReferenceTable();
+//
+//    Column getReferenceColumn();
+//
+//    Table getReferenceTable(boolean tryDateNumberAsFK, TableManager tm);
+//
+//    Column getReferenceColumn(boolean tryDateNumberAsFK, TableManager tm);
+//
+//    int getDisplayOrder();
+//
+//    String getValueInterpeter();
+//
+//    Object getUIConstructor();
+//
+//    int getId();
+//
+//    String getName();
+//
+//    String getDescription(Locale locale);
+//
+//    int getSQLType();
+//
+//    int getType();
+//
+//    Table getTable();
+//
+//    String getLimit();
+//
+//    String getMoney();
+//
+//    boolean getModifiable();
+//
+//    String getObtainManner();
+//
+//    String getDefaultValue();
+//
+//    String getDefaultValue(boolean eval);
+//
+//    String getReferenceColumnName();
+//
+//    String getTableColumnName();
+//
+//    Table getObjectTable();
+//
+//    String getRegExpression();
+//
+//    Properties getProperties();
+//
+//    String getErrorMessage();
+//
+//    boolean isVirtual();
+//
+//    boolean isComputed();
+//
+//    String getSubTotalMethod();
+//
+//    String getSubTotalDesc();
+//
+//    String getFilter();
+//
+//    DisplaySetting getDisplaySetting();
+//
+//    String getSequenceHead();
+//
+//    boolean isFilteredByWildcard();
+//
+//    List getReferenceColumnsInWildcardFilter();
+//
+//    boolean isColumnLink(TableManager tm);
+//
+//    ColumnLink getColumnLink(TableManager tm) throws QueryException;
+//
+//    Object getUIAlerter();
+//
+//    boolean isUpperCase();
+//
+//    boolean isIndexed();
+//
+//    boolean isAutoComplete();
+//
+//    int getSecurityGrade();
+//
+//    /** @deprecated */
+//    @Deprecated
+//    int getOnDeleteAction();
+//
+//    JSONObject toJSONSimpleObject() throws JSONException;
+//
+//    JSONObject toJSONObject(Locale locale) throws JSONException;
+//
+//    JSONObject getJSONProps();
+//
+//    String getFkdisplay();
+//
+//    String getQuerydefval();
+//
+//    LimitvalueGroup getLimitvalueGroup();
+//
+//    String getSearchtype();
+//
+//    boolean getIsremote();
+//
+//    String getSearchmodel();
+//
+//    String getCommentstp();
+//
+//    Boolean getIsagfilter();
+//
+//    String getAgfilter();
+//
+//    ColumnMeta getColumnMeta();
+}

+ 962 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/ColumnImpl.java

@@ -0,0 +1,962 @@
+package com.boman.system.common;
+
+import com.alibaba.fastjson.JSONException;
+import com.alibaba.fastjson.JSONObject;
+import io.seata.rm.datasource.sql.struct.ColumnMeta;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+import java.util.regex.Pattern;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 16:17
+ **/
+public class ColumnImpl implements Column {
+    private static final Logger log = LoggerFactory.getLogger(ColumnImpl.class);
+    private static final long serialVersionUID = -5809782578272943999L;
+    private static Pattern msgKeyPattern = Pattern.compile("\\p{Punct}");
+    private static Pattern spaceKeyPattern = Pattern.compile(" ");
+    private int id = -1;
+    private String name;
+    private String description;
+    private String description2 = null;
+    private boolean isNullable;
+    private String limit = null;
+    private String money = null;
+    private boolean modifiable;
+    private String obtainManner;
+    private String defaultValue;
+    private String refColumnName;
+    private String tableColumnName;
+    private Table objectTable;
+    private String regExpression;
+    private String errorMessage;
+    private String comment = null;
+    private String filter;
+//    private DisplaySetting displaySetting;
+    private boolean isUpperCase;
+    private int sqltype;
+    private int type;
+    private boolean isAlternateKey;
+    private boolean isAlternateKey2;
+    private boolean isDisplayKey;
+    private String mask;
+    private boolean isValueLimited;
+//    private PairTable values = null;
+    private int length;
+    private Table rTable = null;
+    private Column rColumn = null;
+    private Table table = null;
+    private int displayOrder;
+    private String valueInterpreter = null;
+    private boolean isVirtual = false;
+    private String sumMethod = null;
+    private String sumMethodDesc = "";
+    private int scale = 0;
+    private String sequenceHead = null;
+    private String command = null;
+    private String valueGroupName;
+    private boolean isIndexed = false;
+    private int onDeleteAction = 0;
+    private int statSize = -1;
+    private boolean isFilteredByWildcard = false;
+    private List referenceColumnsInWildcardFilter = null;
+    private Properties props = null;
+    private boolean isAutoComplete = false;
+    private JSONObject jsonProps = null;
+    private String strProps = null;
+    private String showcomment;
+    private int securityGrade = 0;
+    private Boolean showtitle;
+    private boolean isorder = false;
+    private String fkdisplay = null;
+    private String querydefval = null;
+//    private LimitvalueGroup limitvalueGroup;
+    private String searchtype;
+    private Boolean isremote;
+    private String searchmodel;
+    private String commentstp;
+    private Boolean isagfilter;
+    private String agfilter;
+    private boolean isRowspan = false;
+    private Locale defaultlocal = new Locale("zh", "CN");
+    private ColumnMeta columnMeta;
+
+//    public ColumnMeta getColumnMeta() {
+//        return this.columnMeta;
+//    }
+//
+//    public void setColumnMeta(ColumnMeta columnMeta) {
+//        this.columnMeta = columnMeta;
+//    }
+//
+//    public ColumnImpl() {
+//    }
+//
+//    public ColumnImpl(int id, Table table, String columnName, String desc, int sqltype, boolean isNull) {
+//        this.id = id;
+//        this.table = table;
+//        this.name = columnName;
+//        this.description = desc;
+//        this.sqltype = sqltype;
+//        this.type = toGrossType(sqltype);
+//        this.isNullable = isNull;
+//        this.isVirtual = this.checkVirtual();
+//    }
+//
+//    public static int toGrossType(int type) {
+//        byte jType;
+//        switch(type) {
+//            case 1:
+//            case 12:
+//            case 13:
+//            case 22:
+//            case 24:
+//            case 25:
+//                jType = 2;
+//                break;
+//            case 2:
+//            case 3:
+//            case 4:
+//            case 5:
+//            case 6:
+//            case 7:
+//            case 8:
+//            case 9:
+//            case 10:
+//            case 16:
+//                jType = 0;
+//                break;
+//            case 11:
+//            case 14:
+//                jType = 1;
+//                break;
+//            case 15:
+//                jType = 4;
+//                break;
+//            case 17:
+//            case 18:
+//            case 19:
+//            case 20:
+//            case 21:
+//            default:
+//                jType = 9;
+//                break;
+//            case 23:
+//                jType = 3;
+//        }
+//
+//        return jType;
+//    }
+//
+//    public void setIsIndexed(boolean b) {
+//        this.isIndexed = b;
+//    }
+//
+//    public boolean isFilteredByWildcard() {
+//        return this.isFilteredByWildcard;
+//    }
+//
+//    public final Properties getProperties() {
+//        return this.props;
+//    }
+//
+//    public boolean isIndexed() {
+//        return this.isIndexed;
+//    }
+//
+//    public boolean isAutoComplete() {
+//        return this.isAutoComplete;
+//    }
+//
+//    public boolean setIsAutoComplete(boolean b) {
+//        return this.isAutoComplete = b;
+//    }
+//
+//    /** @deprecated */
+//    @Deprecated
+//    public int getOnDeleteAction() {
+//        return this.onDeleteAction;
+//    }
+//
+//    /** @deprecated */
+//    @Deprecated
+//    public void setOnDeleteAction(String s) {
+//        if ("SETNULL".equalsIgnoreCase(s)) {
+//            this.onDeleteAction = 1;
+//        } else if ("CASCADE".equalsIgnoreCase(s)) {
+//            this.onDeleteAction = 2;
+//        }
+//
+//    }
+//
+//    public void setIsNullable(boolean n) {
+//        this.isNullable = n;
+//    }
+//
+//    public String getLimitValueGroupName() {
+//        return this.valueGroupName;
+//    }
+//
+//    public int getScale() {
+//        return this.scale;
+//    }
+//
+//    public void setScale(int scale) {
+//        this.scale = scale;
+//    }
+//
+//    private boolean checkVirtual() {
+//        char[] cs = this.name.toCharArray();
+//
+//        for(int i = 0; i < cs.length; ++i) {
+//            if ((cs[i] < '0' || cs[i] > '9') && cs[i] != '_' && cs[i] != '-' && (cs[i] < 'a' || cs[i] > 'z') && (cs[i] < 'A' || cs[i] > 'Z')) {
+//                return true;
+//            }
+//        }
+//
+//        return false;
+//    }
+//
+//    public int getStatSize() {
+//        return this.statSize;
+//    }
+//
+//    public void setStatSize(int size) {
+//        this.statSize = size;
+//    }
+//
+//    public String getComment() {
+//        return this.comment;
+//    }
+//
+//    public void setComment(String s) {
+//        this.comment = s;
+//    }
+//
+//    public void setIsAlternateKey(boolean ak) {
+//        this.isAlternateKey = ak;
+//    }
+//
+//    public void setIsAlternateKey2(boolean ak2) {
+//        this.isAlternateKey2 = ak2;
+//    }
+//
+//    public void setIsDisplayKey(boolean dk) {
+//        this.isDisplayKey = dk;
+//    }
+//
+//    public boolean isDisplayKey() {
+//        return this.isDisplayKey;
+//    }
+//
+//    public void setMask(String mask) {
+//        this.mask = mask;
+//    }
+//
+//    public void setIsValueLimited(boolean limit) {
+//        this.isValueLimited = limit;
+//    }
+//
+//    public void setValues(String valueGroupName, PairTable vs, Locale locale) {
+//        this.valueGroupName = valueGroupName.toLowerCase();
+//        if (this.values == null) {
+//            this.values = new PairTable();
+//        }
+//
+//        this.values.put(locale, vs);
+//    }
+//
+//    public void setValueInterpreter(String interpreter) {
+//        if (interpreter == null) {
+//            this.valueInterpreter = null;
+//        } else {
+//            this.valueInterpreter = interpreter;
+//        }
+//    }
+//
+//    public boolean isAlternateKey() {
+//        return this.isAlternateKey;
+//    }
+//
+//    public boolean isAlternateKey2() {
+//        return this.isAlternateKey2;
+//    }
+//
+//    public boolean isNullable() {
+//        return this.isNullable || this.displaySetting.getObjectType() == 5;
+//    }
+//
+//    public boolean isMaskSet(int maskPosition) {
+//        if (maskPosition >= 0 && maskPosition < this.mask.length()) {
+//            try {
+//                return this.mask.charAt(maskPosition) == '1';
+//            } catch (IndexOutOfBoundsException var3) {
+//                throw new IllegalArgumentException("mask position out of range:" + maskPosition + ",mask:" + this.mask);
+//            }
+//        } else {
+//            return false;
+//        }
+//    }
+//
+//    public boolean isMaskequls(int maskPosition) {
+//        if (maskPosition >= 0 && maskPosition < this.mask.length()) {
+//            try {
+//                return this.mask.equals(Tools.replaceCharAt("0000000000", maskPosition, '1'));
+//            } catch (IndexOutOfBoundsException var3) {
+//                throw new IllegalArgumentException("mask position out of range:" + maskPosition + ",mask:" + this.mask);
+//            }
+//        } else {
+//            return false;
+//        }
+//    }
+//
+//    public boolean isShowable(int action) {
+//        char c = true;
+//        char c;
+//        switch(action) {
+//            case 0:
+//                c = this.mask.charAt(0);
+//                break;
+//            case 1:
+//                c = this.mask.charAt(2);
+//                break;
+//            case 2:
+//                c = this.mask.charAt(4);
+//                break;
+//            case 3:
+//                c = this.mask.charAt(5);
+//                break;
+//            case 4:
+//                c = this.mask.charAt(6);
+//                break;
+//            case 5:
+//                c = this.mask.charAt(7);
+//                break;
+//            case 6:
+//                c = this.mask.charAt(8);
+//                break;
+//            case 7:
+//                c = this.mask.charAt(9);
+//                break;
+//            default:
+//                throw new IllegalArgumentException("action is not valid:" + action);
+//        }
+//
+//        return c == '1';
+//    }
+//
+//    public boolean isModifiable(int action) {
+//        char c = true;
+//        char c;
+//        switch(action) {
+//            case 0:
+//                c = this.mask.charAt(1);
+//                break;
+//            case 1:
+//                c = this.mask.charAt(3);
+//                break;
+//            case 2:
+//                c = this.mask.charAt(1);
+//                break;
+//            case 3:
+//                c = this.mask.charAt(3);
+//                break;
+//            case 4:
+//                c = '0';
+//                break;
+//            default:
+//                throw new IllegalArgumentException("action is not valid:" + action);
+//        }
+//
+//        return c == '1';
+//    }
+//
+//    public boolean isValueLimited() {
+//        return this.isValueLimited;
+//    }
+//
+//    public PairTable getValues(Locale locale) {
+//        if (this.values == null) {
+//            return null;
+//        } else {
+//            PairTable pt = (PairTable)this.values.get(locale);
+//            if (pt == null) {
+//                pt = new PairTable();
+//                Iterator it = this.getValues(this.defaultlocal).keys();
+//
+//                while(it.hasNext()) {
+//                    Object value = it.next();
+//                    pt.put(value, Resources.getMessage("lmt_" + this.valueGroupName + "_" + value, new Object[0]).toLowerCase());
+//                }
+//
+//                this.values.put(locale, pt);
+//            }
+//
+//            return pt;
+//        }
+//    }
+//
+//    public int getLength() {
+//        return this.length;
+//    }
+//
+//    public void setLength(int leng) {
+//        this.length = leng;
+//    }
+//
+//    public Table getReferenceTable() {
+//        return this.rTable;
+//    }
+//
+//    public void setReferenceTable(Table rt) {
+//        this.rTable = rt;
+//    }
+//
+//    public Column getReferenceColumn() {
+//        return this.rColumn;
+//    }
+//
+//    public void setReferenceColumn(Column rc) {
+//        this.rColumn = rc;
+//    }
+//
+//    public Table getReferenceTable(boolean tryDateNumberAsFK, TableManager tm) {
+//        if (this.rTable != null) {
+//            return this.rTable;
+//        } else {
+//            return tryDateNumberAsFK && this.type == 3 ? tm.getDateTable() : null;
+//        }
+//    }
+//
+//    public Column getReferenceColumn(boolean tryDateNumberAsFK, TableManager tm) {
+//        if (this.rColumn != null) {
+//            return this.rColumn;
+//        } else {
+//            if (tryDateNumberAsFK && this.type == 3) {
+//                Table tb = tm.getDateTable();
+//                if (tb != null) {
+//                    return tb.getPrimaryKey();
+//                }
+//            }
+//
+//            return null;
+//        }
+//    }
+//
+//    public int getDisplayOrder() {
+//        return this.displayOrder;
+//    }
+//
+//    public void setDisplayOrder(int order) {
+//        this.displayOrder = order;
+//    }
+//
+//    public String getValueInterpeter() {
+//        return this.valueInterpreter;
+//    }
+//
+//    public int getId() {
+//        return this.id;
+//    }
+//
+//    public String getName() {
+//        return this.name;
+//    }
+//
+//    public String getDescription() {
+//        return this.description;
+//    }
+//
+//    public String getDescription(Locale locale) {
+//        try {
+//            return Resources.getMessage("adcolumn_" + this.id, locale, new Object[]{this.description});
+//        } catch (MissingResourceException var3) {
+//            return this.description;
+//        }
+//    }
+//
+//    public void setDescription(String desc) {
+//        this.description = desc;
+//    }
+//
+//    private String toMessageKey(String s) {
+//        return spaceKeyPattern.matcher(msgKeyPattern.matcher(s).replaceAll("_")).replaceAll("");
+//    }
+//
+//    public void setDescription2(String desc2) {
+//        this.description2 = desc2;
+//    }
+//
+//    public int getSQLType() {
+//        return this.sqltype;
+//    }
+//
+//    public void setSQLType(int sqlType) {
+//        this.sqltype = sqlType;
+//        this.type = toGrossType(this.sqltype);
+//    }
+//
+//    public int getType() {
+//        return this.type;
+//    }
+//
+//    public Table getTable() {
+//        return this.table;
+//    }
+//
+//    public int hashCode() {
+//        return this.id;
+//    }
+//
+//    public boolean equals(Object c) {
+//        return c instanceof Column && ((Column)c).getId() == this.id;
+//    }
+//
+//    public String toString() {
+//        return this.table.toString() + "." + this.name;
+//    }
+//
+//    public void clone(Object obj) {
+//        if (!(obj instanceof ColumnImpl)) {
+//            throw new IllegalArgumentException("Not a ColumnImpl");
+//        } else {
+//            ColumnImpl ci = (ColumnImpl)obj;
+//            this.description = ci.description;
+//            this.description2 = ci.description2;
+//            this.displayOrder = ci.displayOrder;
+//            this.id = ci.id;
+//            this.isAlternateKey = ci.isAlternateKey;
+//            this.isAlternateKey2 = ci.isAlternateKey2;
+//            this.mask = ci.mask;
+//            this.isValueLimited = ci.isValueLimited;
+//            this.length = ci.length;
+//            this.name = ci.name;
+//            this.rTable = ci.rTable;
+//            this.sqltype = ci.sqltype;
+//            this.table = ci.table;
+//            this.type = ci.type;
+//            this.valueInterpreter = ci.valueInterpreter;
+//            this.values = ci.values;
+//            this.obtainManner = ci.obtainManner;
+//            this.modifiable = ci.modifiable;
+//            this.refColumnName = ci.refColumnName;
+//            this.tableColumnName = ci.tableColumnName;
+//            this.objectTable = ci.objectTable;
+//            this.jsonProps = ci.jsonProps;
+//        }
+//    }
+//
+//    public String getLimit() {
+//        return this.limit;
+//    }
+//
+//    public void setLimit(String limit) {
+//        this.limit = limit;
+//    }
+//
+//    public String getMoney() {
+//        return this.money;
+//    }
+//
+//    public void setMoney(String money) {
+//        this.money = money;
+//    }
+//
+//    public boolean getModifiable() {
+//        return this.modifiable;
+//    }
+//
+//    public void setModifiable(boolean modifiable) {
+//        this.modifiable = modifiable;
+//    }
+//
+//    public String getObtainManner() {
+//        return this.obtainManner;
+//    }
+//
+//    public void setObtainManner(String obtainManner) {
+//        this.obtainManner = obtainManner;
+//    }
+//
+//    public String getDefaultValue() {
+//        return this.getDefaultValue(true);
+//    }
+//
+//    public void setDefaultValue(String defaultValue) {
+//        this.defaultValue = defaultValue;
+//    }
+//
+//    public String getDefaultValue(boolean eval) {
+//        if (eval && this.defaultValue != null && "=".equals(this.defaultValue.substring(0, 1))) {
+//        }
+//
+//        return this.defaultValue;
+//    }
+//
+//    public String getReferenceColumnName() {
+//        return this.refColumnName;
+//    }
+//
+//    public void setReferenceColumnName(String columnName) {
+//        this.refColumnName = columnName;
+//    }
+//
+//    public String getTableColumnName() {
+//        return this.tableColumnName;
+//    }
+//
+//    public void setTableColumnName(String columnName) {
+//        this.tableColumnName = columnName;
+//    }
+//
+//    public Table getObjectTable() {
+//        return this.objectTable;
+//    }
+//
+//    public void setObjectTable(Table objectTable) {
+//        this.objectTable = objectTable;
+//    }
+//
+//    public void setRegExpresion(String regExpression) {
+//        if (Validator.isNotNull(regExpression)) {
+//            if (this.displaySetting == null) {
+//                throw new NDSRuntimeException("Must call setDisplaySetting before setRegExpresion for Column");
+//            }
+//
+//            if (this.displaySetting.getObjectType() == 12) {
+//                try {
+//                    JSONObject jo = JSONObject.parseObject(regExpression);
+//                    this.props = new Properties();
+//                    Iterator var3 = jo.keySet().iterator();
+//
+//                    while(var3.hasNext()) {
+//                        String key = (String)var3.next();
+//                        this.props.setProperty(key, jo.getString(key));
+//                    }
+//                } catch (Throwable var5) {
+//                    throw new NDSRuntimeException("Could not load regExpression as json object:" + var5, var5);
+//                }
+//            } else {
+//                this.regExpression = regExpression;
+//            }
+//        }
+//
+//    }
+//
+//    public String getRegExpression() {
+//        return this.regExpression;
+//    }
+//
+//    public String getErrorMessage() {
+//        return this.errorMessage;
+//    }
+//
+//    public void setErrorMessage(String errorMessage) {
+//        this.errorMessage = errorMessage;
+//    }
+//
+//    public boolean isVirtual() {
+//        return this.isVirtual;
+//    }
+//
+//    public String getSubTotalMethod() {
+//        return this.sumMethod;
+//    }
+//
+//    public void setSubTotalMethod(String method) {
+//        this.sumMethod = method;
+//    }
+//
+//    public String getSubTotalDesc() {
+//        return this.sumMethodDesc;
+//    }
+//
+//    void setIsFilteredByWildcard(boolean b) {
+//        this.isFilteredByWildcard = b;
+//    }
+//
+//    public List getReferenceColumnsInWildcardFilter() {
+//        return this.referenceColumnsInWildcardFilter;
+//    }
+//
+//    public void setReferenceColumnsInWildcardFilter(List columns) {
+//        this.referenceColumnsInWildcardFilter = columns;
+//    }
+//
+//    public String getFilter() {
+//        return this.filter;
+//    }
+//
+//    public void setFilter(String filter) {
+//        this.filter = filter;
+//        if (Validator.isNotNull(filter) && (this.getReferenceTable() != null || this.getDisplaySetting().getObjectType() == 12) && filter.indexOf(64) > -1) {
+//            this.isFilteredByWildcard = true;
+//        }
+//
+//    }
+//
+//    public DisplaySetting getDisplaySetting() {
+//        return this.displaySetting;
+//    }
+//
+//    public void setDisplaySetting(DisplaySetting setting) {
+//        this.displaySetting = setting;
+//    }
+//
+//    public String getSequenceHead() {
+//        return this.sequenceHead;
+//    }
+//
+//    public void setSequenceHead(String s) {
+//        this.sequenceHead = s;
+//    }
+//
+//    public boolean isColumnLink(TableManager tm) {
+//        if (this.name.indexOf(";") > -1) {
+//            try {
+//                this.getColumnLink(tm);
+//                return true;
+//            } catch (Exception var3) {
+//                return false;
+//            }
+//        } else {
+//            return false;
+//        }
+//    }
+//
+//    public ColumnLink getColumnLink(TableManager tm) throws QueryException {
+//        return new ColumnLink(this.table.getName() + "." + this.name, tm);
+//    }
+//
+//    public Object getUIConstructor() {
+//        Object uiConstructor = null;
+//        if (this.getDisplaySetting().getObjectType() == 10) {
+//            if (Validator.isNull(this.getValueInterpeter())) {
+//                throw new NDSRuntimeException("Not found interpreter of button column " + this);
+//            }
+//
+//            try {
+//                uiConstructor = ApplicationContextHandle.getBean(this.getValueInterpeter());
+//            } catch (Exception var5) {
+//                try {
+//                    uiConstructor = ApplicationContextHandle.getBean(InstanceUtil.getClass(this.getValueInterpeter()));
+//                } catch (Exception var4) {
+//                    log.debug("Found error in get ui constructor:" + var4);
+//                }
+//            }
+//        }
+//
+//        return uiConstructor;
+//    }
+//
+//    public Object getUIAlerter() {
+//        Object uiAlerter = null;
+//        if (Validator.isNotNull(this.getValueInterpeter())) {
+//            try {
+//                uiAlerter = ApplicationContextHandle.getBean(this.getValueInterpeter());
+//            } catch (Exception var5) {
+//                try {
+//                    uiAlerter = ApplicationContextHandle.getBean(InstanceUtil.getClass(this.getValueInterpeter()));
+//                } catch (Exception var4) {
+//                    log.debug("Found error in get ui alerter:" + var4);
+//                }
+//            }
+//        }
+//
+//        return uiAlerter;
+//    }
+//
+//    public void setIsUpperCase(boolean b) {
+//        this.isUpperCase = b;
+//    }
+//
+//    public boolean isUpperCase() {
+//        return this.isUpperCase;
+//    }
+//
+//    public int getSecurityGrade() {
+//        return this.securityGrade;
+//    }
+//
+//    public JSONObject toJSONSimpleObject() throws JSONException {
+//        JSONObject jo = new JSONObject();
+//        jo.put("id", this.id);
+//        jo.put("description", this.getDescription());
+//        jo.put("isNullable", this.isNullable);
+//        jo.put("refColumnId", this.getReferenceColumn() == null ? -1 : this.getReferenceColumn().getId());
+//        if (this.getReferenceColumn() != null) {
+//            jo.put("refTableAK", this.getReferenceTable().getAlternateKey().toJSONSimpleObject());
+//        }
+//
+//        jo.put("mask", this.mask);
+//        jo.put("isValueLimited", this.isValueLimited);
+//        jo.put("type", this.type);
+//        return jo;
+//    }
+//
+//    public JSONObject toJSONObject(Locale locale) throws JSONException {
+//        JSONObject jo = new JSONObject();
+//        jo.put("id", this.id);
+//        jo.put("name", this.name);
+//        jo.put("description", this.getDescription());
+//        jo.put("isNullable", this.isNullable);
+//        jo.put("obtainManner", this.obtainManner);
+//        jo.put("defaultValue", this.defaultValue);
+//        jo.put("refColumnId", this.getReferenceColumn() == null ? -1 : this.getReferenceColumn().getId());
+//        if (this.getReferenceColumn() != null) {
+//            jo.put("refTableAK", this.getReferenceTable().getAlternateKey().toJSONObject(locale));
+//        }
+//
+//        jo.put("refTableId", this.getReferenceTable() == null ? -1 : this.getReferenceTable().getId());
+//        jo.put("isAlternateKey", this.isAlternateKey);
+//        jo.put("mask", this.mask);
+//        jo.put("isValueLimited", this.isValueLimited);
+//        jo.put("values", this.values);
+//        jo.put("isUpperCase", this.isUpperCase);
+//        jo.put("filter", this.filter);
+//        jo.put("displaySetting", this.displaySetting.getObjectTypeString());
+//        jo.put("type", this.type);
+//        jo.put("length", this.length);
+//        jo.put("scale", this.scale);
+//        jo.put("valueInterpreter", this.valueInterpreter);
+//        jo.put("table", this.table.getId());
+//        jo.put("isVirtual", this.isVirtual);
+//        jo.put("isIndexed", this.isIndexed);
+//        jo.put("isAutoComplete", this.isAutoComplete);
+//        jo.put("props", this.jsonProps);
+//        return jo;
+//    }
+//
+//    public JSONObject getJSONProps() {
+//        return this.jsonProps;
+//    }
+//
+//    public void setJSONProps(JSONObject jo) {
+//        this.jsonProps = jo;
+//        if (jo != null) {
+//            this.securityGrade = jo.getIntValue("sgrade");
+//        }
+//
+//    }
+//
+//    public String getStrProps() {
+//        if (this.jsonProps == null) {
+//            this.jsonProps = new JSONObject();
+//        }
+//
+//        return this.jsonProps.toString();
+//    }
+//
+//    public String getShowcomment() {
+//        return this.showcomment;
+//    }
+//
+//    public Boolean getIsorder() {
+//        return this.isorder;
+//    }
+//
+//    public void setIsorder(Boolean isorder) {
+//        this.isorder = isorder;
+//    }
+//
+//    public void setShowcomment(String shcomment) {
+//        this.showcomment = shcomment;
+//    }
+//
+//    public Boolean getShowtitle() {
+//        return this.showtitle;
+//    }
+//
+//    public void setShowtitle(Boolean ishowtite) {
+//        this.showtitle = ishowtite;
+//    }
+//
+//    public Boolean getRowspan() {
+//        return this.isRowspan;
+//    }
+//
+//    public void setRowspan(Boolean isRowspan) {
+//        this.isRowspan = isRowspan;
+//    }
+//
+//    public String getFkdisplay() {
+//        return this.fkdisplay;
+//    }
+//
+//    public void setFkdisplay(String fkdisplay) {
+//        this.fkdisplay = fkdisplay;
+//    }
+//
+//    public String getQuerydefval() {
+//        return this.querydefval;
+//    }
+//
+//    public void setQuerydefval(String querydefval) {
+//        this.querydefval = querydefval;
+//    }
+//
+//    public boolean isComputed() {
+//        return "computed".equals(this.obtainManner);
+//    }
+//
+//    public LimitvalueGroup getLimitvalueGroup() {
+//        return this.limitvalueGroup;
+//    }
+//
+//    public void setLimitvalueGroup(LimitvalueGroup limitvalueGroup) {
+//        this.limitvalueGroup = limitvalueGroup;
+//    }
+//
+//    public String getSearchtype() {
+//        return this.searchtype;
+//    }
+//
+//    public void setSearchtype(String searchtype) {
+//        this.searchtype = searchtype;
+//    }
+//
+//    public boolean getIsremote() {
+//        return this.isremote;
+//    }
+//
+//    public void setIsremote(Boolean isremote) {
+//        this.isremote = isremote;
+//    }
+//
+//    public String getSearchmodel() {
+//        return this.searchmodel;
+//    }
+//
+//    public void setSearchmodel(String searchmodel) {
+//        this.searchmodel = searchmodel;
+//    }
+//
+//    public String getCommentstp() {
+//        return Tools.nvl(this.commentstp, "list");
+//    }
+//
+//    public void setCommentstp(String commentstp) {
+//        this.commentstp = commentstp;
+//    }
+//
+//    public Boolean getIsagfilter() {
+//        return this.isagfilter;
+//    }
+//
+//    public void setIsagfilter(Boolean isagfilter) {
+//        this.isagfilter = isagfilter;
+//    }
+//
+//    public String getAgfilter() {
+//        return this.agfilter;
+//    }
+//
+//    public void setAgfilter(String agfilter) {
+//        this.agfilter = agfilter;
+//    }
+}
+

+ 17 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/DbRowAction.java

@@ -0,0 +1,17 @@
+package com.boman.system.common;
+
+/**
+ * @author lzm
+ * @date 2018/9/21
+ */
+public enum DbRowAction {
+    INSERT(0, "插入"), UPDATE(1, "更新"), DELETE(2, "删除");
+
+    private int value;
+    private String desc;
+
+    DbRowAction(int value, String desc) {
+        this.value = value;
+        this.desc = desc;
+    }
+}

+ 24 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/DefaultTableService.java

@@ -0,0 +1,24 @@
+//package com.boman.system.common;
+//
+//
+//import org.springframework.stereotype.Component;
+//
+///**
+// * @author shiqian
+// * @description
+// * @date 2021年03月22日 10:21
+// **/
+//@Component("defaultTableService-one")
+//public class DefaultTableService extends BaseTableService {
+//    public DefaultTableService() {
+//    }
+//
+//    public DefaultTableService(String tableName) {
+//        super(tableName);
+//    }
+//
+//    @Override
+//    public RowResult executeAction(TableServiceContext context, MainTableRecord row) {
+//        return null;
+//    }
+//}

+ 24 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/ExceptionFilter.java

@@ -0,0 +1,24 @@
+package com.boman.system.common;
+
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 11:01
+ **/
+public abstract class ExceptionFilter extends BaseFilter {
+
+    public ExceptionFilter() {
+    }
+
+    /**
+     * 异常处理Filter,返回null,则表示本Filter不处理该异常(异常继续往下传递,如所有异常处理Filter都不处理,则往外抛出)
+     * 返回非null值,则表示本Filter处理了改异常,不往下传递(异常被吞)
+     *
+     * @param context
+     * @param row
+     * @param exception
+     * @return
+     */
+    public abstract RowResult handleException(TableServiceContext context, MainTableRecord row, Exception exception);
+}

+ 94 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/Feature.java

@@ -0,0 +1,94 @@
+package com.boman.system.common;
+
+
+import com.google.common.collect.Lists;
+import org.apache.commons.collections4.keyvalue.DefaultMapEntry;
+import org.springframework.beans.factory.InitializingBean;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.function.BiPredicate;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 10:42
+ **/
+public abstract class Feature implements InitializingBean {
+    public static final BiPredicate<String, String> matchAll = (tableName, actionName) -> {
+        return true;
+    };
+    private String name;
+    private String description;
+    private boolean isSystem;
+    private Collection<Map.Entry<BiPredicate<String, String>, Validator>> validates;
+    private Collection<Map.Entry<BiPredicate<String, String>, Filter>> filters;
+
+    protected Feature() {
+        this.validates = Lists.newArrayList();
+        this.filters = Lists.newArrayList();
+        this.isSystem = false;
+    }
+
+    protected Feature(String name, String description, boolean isSystem) {
+        this();
+        this.name = name;
+        this.description = description;
+        this.isSystem = isSystem;
+    }
+
+    @Override
+    public final void afterPropertiesSet() throws Exception {
+        this.initialization();
+    }
+
+    protected abstract void initialization();
+
+    protected final void addValidator(Validator validator, BiPredicate<String, String> condition) {
+        this.validates.add(new DefaultMapEntry(condition, validator));
+    }
+
+    protected final void addFilter(Filter filter, BiPredicate<String, String> condition) {
+        this.filters.add(new DefaultMapEntry(condition, filter));
+    }
+
+    protected final void addGlobalValidator(Validator validator) {
+        this.addValidator(validator, matchAll);
+    }
+
+    protected final void addGlobalFilter(Filter filter) {
+        this.addFilter(filter, matchAll);
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    protected void setName(final String name) {
+        this.name = name;
+    }
+
+    public String getDescription() {
+        return this.description;
+    }
+
+    protected void setDescription(final String description) {
+        this.description = description;
+    }
+
+    public boolean isSystem() {
+        return this.isSystem;
+    }
+
+    protected void setSystem(final boolean isSystem) {
+        this.isSystem = isSystem;
+    }
+
+    public Collection<Map.Entry<BiPredicate<String, String>, Validator>> getValidates() {
+        return this.validates;
+    }
+
+    public Collection<Map.Entry<BiPredicate<String, String>, Filter>> getFilters() {
+        return this.filters;
+    }
+}

+ 87 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/FeatureManager.java

@@ -0,0 +1,87 @@
+package com.boman.system.common;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.BiPredicate;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 10:02
+ **/
+public class FeatureManager {
+
+    private static final Map<String, Feature> features = Maps.newHashMap();
+
+    private static final Map<String, Collection<Validator>> validatorCache = Maps.newHashMap();
+
+    private static final Map<String, Collection<Filter>> filterCache = Maps.newHashMap();
+
+    public static void addFeature(Feature feature) {
+        if (!features.containsKey(feature.getName())) {
+            features.put(feature.getName(), feature);
+            validatorCache.clear();
+            filterCache.clear();
+        }
+    }
+
+    public static void removeFeature(String featureName) {
+        if (null != features.remove(featureName)) {
+            validatorCache.clear(); //TODO:注意这里面要获取下写锁
+            filterCache.clear();
+        }
+    }
+
+    static Collection<Validator> getValidators(String tableName, String actionName) {
+        String cacheKey = getCacheKey(tableName, actionName);
+        Collection<Validator> result = validatorCache.get(cacheKey);
+        if (result == null) {
+            Set<Integer> temp = Sets.newHashSet();
+            result = Lists.newArrayList();
+            Collection<Feature> allFeatures = features.values();
+            for (Feature feature : allFeatures) {
+                for (Map.Entry<BiPredicate<String, String>, Validator> item : feature.getValidates()) {
+                    if (item.getKey() == null || item.getKey().test(tableName, actionName)) {
+                        Validator value = item.getValue();
+                        if (!temp.contains(value.hashCode())) {
+                            temp.add(value.hashCode());
+                            result.add(value);
+                        }
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    static Collection<Filter> getFilters(String tableName, String actionName) {
+        String cacheKey = getCacheKey(tableName, actionName);
+        Collection<Filter> result = filterCache.get(cacheKey);
+        if (result == null) {
+            Set<Integer> temp = Sets.newHashSet();
+            result = Lists.newArrayList();
+            Collection<Feature> allFeatures = features.values();
+            for (Feature feature : allFeatures) {
+                for (Map.Entry<BiPredicate<String, String>, Filter> item : feature.getFilters()) {
+                    if (item.getKey() == null || item.getKey().test(tableName, actionName)) {
+                        Filter value = item.getValue();
+                        if (!temp.contains(value.hashCode())) {
+                            temp.add(value.hashCode());
+                            result.add(value);
+                        }
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    private static String getCacheKey(String tableName, String actionName) {
+        return String.format("%s.%s", tableName, actionName);
+    }
+}

+ 12 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/Filter.java

@@ -0,0 +1,12 @@
+package com.boman.system.common;
+
+
+/**
+ * @author lzm
+ * @date 2018/9/27
+ */
+public interface Filter {
+    void before(TableServiceContext context, MainTableRecord row);
+
+    void after(TableServiceContext context, MainTableRecord row);
+}

+ 171 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/MainTableRecord.java

@@ -0,0 +1,171 @@
+package com.boman.system.common;
+
+import com.alibaba.fastjson.JSONObject;
+import com.boman.gen.domain.GenTable;
+import com.google.common.collect.Maps;
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+import java.util.Map;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 10:04
+ **/
+@Data
+public class MainTableRecord {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(MainTableRecord.class);
+
+    private TableServiceContext context;
+    private RowRecord mainData;
+    private Map<String, SubTableRecord> subTables;
+
+    /**
+     * 子表和对应的外健
+     */
+    private JSONObject fkColumns;
+
+    @Setter
+    @Getter
+    private RowResult result;
+
+
+    public MainTableRecord(TableServiceContext context, GenTable genTable, Long id, JSONObject fkColumns, JSONObject fixedData, JSONObject delTables) {
+        this.context = context;
+        this.subTables = Maps.newHashMap();
+
+        //获取提交数据rowData
+        JSONObject rowData = fixedData;
+//        if (fixedData != null) {
+//            rowData = fixedData.getJSONObject("columns");
+////            rowData = fixedData.getJSONArray("columns");
+//        }
+//        if (rowData == null) {
+//            rowData = new JSONObject();
+//        }
+        if (fixedData == null) {
+            fixedData = new JSONObject();
+        }
+
+        if (fkColumns == null) {
+            //伪造下外键
+            fkColumns = new JSONObject();
+        }
+        this.fkColumns = fkColumns;
+
+        if (delTables == null) {
+            delTables = new JSONObject();
+        }
+        this.mainData = new RowRecord(id, genTable, fixedData);
+
+//        for (String subTableName : fixedData.keySet()) {
+//            if (!subTableName.equalsIgnoreCase(genTable.getTableName())) {
+//                Table subTable = TableServiceContext.getTableByName(subTableName);
+//                String fkColumnName = fkColumns.getString(subTableName);
+//                SubTableRecord subRow = new SubTableRecord(subTable, fkColumnName, fixedData.getJSONArray(subTableName));
+//                subTables.put(subTableName, subRow);
+//            }
+//        }
+
+    }
+
+
+    public MainTableRecord(TableServiceContext context, Table table, Long id, JSONObject fkColumns, JSONObject tables, JSONObject delTables) {
+        this.context = context;
+        this.subTables = Maps.newHashMap();
+
+        //获取提交数据rowData
+        JSONObject rowData = null;
+        if (tables != null) {
+            rowData = tables.getJSONObject(table.getName());
+        }
+        if (rowData == null) {
+            rowData = new JSONObject();
+        }
+        if (tables == null) {
+            tables = new JSONObject();
+        }
+
+        if (fkColumns == null) {
+            //伪造下外键
+            fkColumns = new JSONObject();
+        }
+        this.fkColumns = fkColumns;
+
+        if (delTables == null) {
+            delTables = new JSONObject();
+        }
+
+//        if (Constants.ACTION_DELETE.equals(context.getActionName())) {
+//            LOGGER.debug("====>" + delTables.keySet());
+//            this.mainData = new RowRecord(id, table, rowData);
+//            for (String subTableName : delTables.keySet()) {
+//                if (!subTableName.equalsIgnoreCase(table.getName())) {
+//                    Table subTable = com.eboss.sys.srv.service.basetable.TableServiceContext.getTableByName(subTableName);
+//                    //外健
+//                    String fkColumnName = fkColumns.getString(subTableName);
+//                    if (fkColumnName == null || fkColumnName.isEmpty()) {
+//                        fkColumnName = findFkColumnName(subTable, table.getName());
+//                    }
+//                    SubTableRecord subRow = new SubTableRecord(subTable, fkColumnName, delTables.getJSONArray(subTableName));
+//                    subTables.put(subTableName, subRow);
+//                }
+//            }
+//        } else {
+            this.mainData = new RowRecord(id, table, rowData);
+            for (String subTableName : tables.keySet()) {
+                if (!subTableName.equalsIgnoreCase(table.getName())) {
+                    Table subTable = TableServiceContext.getTableByName(subTableName);
+//                    //外健
+                    String fkColumnName = fkColumns.getString(subTableName);
+//                    if (fkColumnName == null || fkColumnName.isEmpty()) {
+//                        fkColumnName = findFkColumnName(subTable, table.getName());
+//                    }
+                    SubTableRecord subRow = new SubTableRecord(subTable, fkColumnName, tables.getJSONArray(subTableName));
+                    subTables.put(subTableName, subRow);
+                }
+            }
+//        }
+    }
+
+//    private String findFkColumnName(Table subtable, String mainTableName) {
+//        ArrayList<Column> columns = subtable.getAllColumns();
+//        for (Column col : columns) {
+//            Table refTable = col.getReferenceTable();
+//            if (refTable != null && mainTableName.equalsIgnoreCase(refTable.getName())) {
+//                return col.getName();
+//            }
+//        }
+//        return null;
+//    }
+
+    public Long getId() {
+        return mainData.getId();
+    }
+
+    public void setId(Long value) {
+        mainData.setId(value);
+    }
+
+    public GenTable getTable() {
+        return mainData.getGenTable();
+    }
+
+    public DbRowAction getAction() {
+        return mainData.getAction();
+    }
+
+    public JSONObject getCommitData() {
+        return mainData.getCommitData();
+    }
+
+    public JSONObject getOrignalData() {
+        return mainData.getOrignalData();
+    }
+}

+ 9 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/NDSException.java

@@ -0,0 +1,9 @@
+package com.boman.system.common;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 14:57
+ **/
+public class NDSException {
+}

+ 46 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/OverlayJSONObject.java

@@ -0,0 +1,46 @@
+package com.boman.system.common;
+
+import com.alibaba.fastjson.JSONObject;
+
+import java.util.AbstractMap;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * @author lzm
+ * @date 2018/10/29
+ * 可被覆盖的
+ */
+public class OverlayJSONObject extends AbstractMap {
+    private JSONObject baseData;
+    private JSONObject data;
+
+    public OverlayJSONObject(JSONObject base, JSONObject data) {
+        if (data == null) {
+            throw new IllegalArgumentException("入口的新集合不可为空!");
+        }
+        this.baseData = base;
+        this.data = data;
+    }
+
+    @Override
+    public Object remove(Object key) {
+        return data.remove(key);
+    }
+
+    @Override
+    public Object put(Object key, Object value) {
+        return data.put((String) key, value);
+    }
+
+    @Override
+    public Set<Entry<String, Object>> entrySet() {
+        if (this.baseData == null) {
+            return this.data.entrySet();
+        } else {
+            return Stream.concat(this.data.entrySet().stream(), this.baseData.entrySet().stream()
+                    .filter(pair -> !this.data.containsKey(pair.getKey()))).collect(Collectors.toSet());
+        }
+    }
+}

+ 47 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/QueryUtils.java

@@ -0,0 +1,47 @@
+package com.boman.system.common;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 11:42
+ **/
+public class QueryUtils {
+
+    public static String replaceVariables(String sql, User user) {
+        if (user == null) {
+            return sql;
+        } else if (sql == null) {
+            return null;
+        } else {
+            StringBuilder sb = new StringBuilder();
+            int p = 0;
+
+            while (p < sql.length()) {
+                int p1 = sql.indexOf("$", p);
+                if (p1 > -1) {
+                    int p2 = sql.indexOf("$", p1 + 1);
+                    if (p2 > -1) {
+                        String n = sql.substring(p1, p2 + 1);
+                        Object v = user.getAttribute(n);
+                        if (v != null) {
+                            sb.append(sql.substring(p, p1)).append(v);
+                            p = p2 + 1;
+                        } else {
+                            sb.append(sql.substring(p, p2));
+                            p = p2;
+                        }
+                        continue;
+                    }
+
+                    sb.append(sql.substring(p));
+                    break;
+                }
+
+                sb.append(sql.substring(p));
+                break;
+            }
+
+            return sb.toString();
+        }
+    }
+}

+ 69 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/RequestUtil.java

@@ -0,0 +1,69 @@
+package com.boman.system.common;
+
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 09:38
+ **/
+public class RequestUtil {
+
+    public RequestUtil() {
+    }
+
+    public static User getUser() {
+        ServletRequestAttributes attrs = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
+        if (attrs != null) {
+            HttpServletRequest request = attrs.getRequest();
+            if (request.getAttribute("user") != null) {
+                return (User)request.getAttribute("user");
+            }
+        }
+
+        return null;
+    }
+
+    public static HttpServletRequest getRequest() {
+        ServletRequestAttributes attrs = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
+        if (attrs != null) {
+            return attrs.getRequest();
+        } else {
+            return null;
+        }
+    }
+
+    public static Object getAttribute(String name) {
+        ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        if (attrs != null) {
+            HttpServletRequest request = attrs.getRequest();
+            return request.getAttribute(name);
+        } else {
+            return null;
+        }
+    }
+
+    public static String getParameter(String name) {
+        ServletRequestAttributes attrs = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
+        if (attrs != null) {
+            HttpServletRequest request = attrs.getRequest();
+            return request.getParameter(name);
+        } else {
+            return null;
+        }
+    }
+
+    public static HttpServletRequest getRequet() {
+        ServletRequestAttributes attrs = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
+        return attrs != null ? attrs.getRequest() : null;
+    }
+
+    public static HttpServletResponse getResponse() {
+        ServletRequestAttributes attrs = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
+        return attrs != null ? attrs.getResponse() : null;
+    }
+}

+ 57 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/Resources.java

@@ -0,0 +1,57 @@
+package com.boman.system.common;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 13:54
+ **/
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.PropertySource;
+
+@PropertySource(
+        value = {"classpath:application.properties", "classpath:config/email.properties", "classpath:config/thirdParty.properties", "classpath:config/ebossCloud.properties", "classpath:i18n/messages*.properties"},
+        ignoreResourceNotFound = true
+)
+public final class Resources {
+    private static final Logger log = LoggerFactory.getLogger(Resources.class);
+    private static final Map<String, ResourceBundle> MESSAGES = new HashMap();
+
+    public Resources() {
+    }
+
+    public static String getMessage(String key, Object... params) {
+        return getMessage(key, (Locale)null, params);
+    }
+
+    public static String getMessage(String key, Locale plocale, Object... params) {
+        ResourceBundle pp = ResourceBundle.getBundle("application");
+        String defaultLocal = pp.getString("spring.locale.default");
+//        Locale locale = plocale != null ? plocale : Tools.getLocale("zh_CN");
+        Locale locale =  Locale.getDefault();
+        ResourceBundle message = (ResourceBundle)MESSAGES.get(locale.getLanguage());
+        if (message == null) {
+            synchronized(MESSAGES) {
+                message = (ResourceBundle)MESSAGES.get(locale.getLanguage());
+                if (message == null) {
+                    message = ResourceBundle.getBundle("i18n/messages", locale);
+                    MESSAGES.put(locale.getLanguage(), message);
+                }
+            }
+        }
+
+        try {
+            return params != null ? String.format(message.getString(key), params) : message.getString(key);
+        } catch (Exception var10) {
+            return locale.toString().equals(defaultLocal) && params.length == 1 ? String.valueOf(params[0]) : key;
+        }
+    }
+
+    public static void flushMessage() {
+        MESSAGES.clear();
+    }
+}

+ 12 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/ResultCode.java

@@ -0,0 +1,12 @@
+package com.boman.system.common;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 15:41
+ **/
+public class ResultCode {
+
+    public static final int SUCCESS = 0;
+    public static final int FAIL = -1;
+}

+ 147 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/RowRecord.java

@@ -0,0 +1,147 @@
+package com.boman.system.common;
+
+import com.alibaba.fastjson.JSONObject;
+import com.boman.gen.domain.GenTable;
+import com.boman.system.mapper.StandardlyMapper;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @author zc
+ * @date 2019/02/19
+ */
+@Getter
+@Slf4j
+public class RowRecord {
+
+    private GenTable genTable;
+
+    private Table table;
+
+    @Setter
+    private Long id;
+    private DbRowAction action;
+
+    //提交过来的数据
+    private JSONObject postData;
+
+    //原数据
+    private JSONObject orignalData;
+
+    //新数据
+    private JSONObject newData;
+
+    //将要提交到数据库中的数据
+    private JSONObject commitData;
+
+    public RowRecord(Long id, GenTable genTable, JSONObject fixedData) {
+        this.id = id;
+        this.genTable = genTable;
+        postData = new JSONObject();
+        orignalData = new JSONObject();
+        commitData = new JSONObject();
+
+        if (fixedData == null) {
+            fixedData = new JSONObject();
+        }
+        if (!fixedData.containsKey("ID") || fixedData.getLong("ID") == null || fixedData.getLong("ID") <= 0) {
+            fixedData.put("ID", this.id);
+        }else{
+            //modify by nathan 导入修改
+            this.id = fixedData.getLong("ID");
+        }
+
+        action = (this.id == null || this.id <= 0) ? DbRowAction.INSERT : DbRowAction.UPDATE;
+        fixedData.forEach((fieldName, fieldValue)->{
+            postData.put(fieldName.toUpperCase(), fieldValue);
+        });
+
+        for (String key : postData.keySet()) {
+            commitData.put(key, postData.get(key));
+        }
+
+        newData = new JSONObject(new OverlayJSONObject(orignalData, commitData));
+    }
+
+    public RowRecord(Long id, Table table, JSONObject postRow) {
+        this.id = id;
+        this.table = table;
+        postData = new JSONObject();
+        orignalData = new JSONObject();
+        commitData = new JSONObject();
+
+        if (postRow == null) {
+            postRow = new JSONObject();
+        }
+        if (!postRow.containsKey("ID") || postRow.getLong("ID") == null || postRow.getLong("ID") <= 0) {
+            postRow.put("ID", this.id);
+        }else{
+            //modify by nathan 导入修改
+            this.id = postRow.getLong("ID");
+        }
+        action = (this.id == null || this.id <= 0) ? DbRowAction.INSERT : DbRowAction.UPDATE;
+//        log.debug("postRow:" + postRow.toJSONString());
+//        log.debug("allColumns:" + table.getAllColumns().toString());
+        for (String key : postRow.keySet()) {
+            Column column = /*table.getColumn(key)*/null;
+            int type = -1;
+            if (column != null) {
+                type = /*column.getType()*/0;
+            } else {
+                log.debug("column is null key===>" + key);
+            }
+            try {
+                switch (type) {
+                    case Column.DATE:
+                        postData.put(key.toUpperCase(), postRow.getDate(key));
+                        break;
+//                    case Column.DATENUMBER:
+//                        postData.put(key.toUpperCase(), postRow.getDate(key));
+//                        break;
+//                    case Column.TIME:
+//                        postData.put(key.toUpperCase(), postRow.get(key));
+//                        break;
+                    case Column.NUMBER:
+                        postData.put(key.toUpperCase(), postRow.getBigDecimal(key));
+                        break;
+
+                    default:
+                        postData.put(key.toUpperCase(), postRow.get(key));
+                }
+            } catch (Exception e) {
+                //log.error(String.format("%s填充字段%s-%s出错,错误信息为%s", this.id, table.getRealTableName(), key, e.getMessage()));
+                throw e;
+            }
+        }
+
+        for (String key : postData.keySet()) {
+            commitData.put(key, postData.get(key));
+        }
+
+        if (this.getAction() == DbRowAction.UPDATE) {
+            StandardlyMapper mapper = ApplicationContextHandle.getBean(StandardlyMapper.class);
+            JSONObject oldData = mapper.getById(this.getRealTableName(), this.getId());
+            if (oldData != null) {
+                for (String key : oldData.keySet()) {
+//                    key = key.toUpperCase();
+                    orignalData.put(key.toUpperCase(), oldData.get(key));
+                }
+            }
+        }
+
+        newData = new JSONObject(new OverlayJSONObject(orignalData, commitData));
+    }
+
+    public String getTableName() {
+        return genTable.getTableName();
+    }
+
+    public String getRealTableName() {
+        String realTableName = /*table.getRealTableName()*/"";
+        if (realTableName == null || realTableName.isEmpty()) {
+            realTableName = table.getName();
+        }
+        return realTableName;
+    }
+}

+ 81 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/RowResult.java

@@ -0,0 +1,81 @@
+package com.boman.system.common;
+
+import java.util.Locale;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 10:59
+ **/
+public class RowResult {
+
+    private Integer code;
+    private String message;
+    private Object data;
+
+    public RowResult() {
+    }
+
+    public boolean isOk() {
+        return this.code >= 0;
+    }
+
+    public static RowResult ok(Locale locale) {
+        return ok(Resources.getMessage("成功", locale, new Object[0]));
+    }
+
+    public static RowResult ok(String message) {
+        return create(0, message);
+    }
+
+    public static RowResult ok(String message, Object data) {
+        return create(0, message, data);
+    }
+
+    public static RowResult error(String message) {
+        return create(-1, message);
+    }
+
+    public static RowResult error(String message, Object data) {
+        return create(-1, message, data);
+    }
+
+    public static RowResult create(Integer errorCode, String message) {
+        return create(errorCode, message, (Object)null);
+    }
+
+    public static RowResult create(Integer errorCode, String message, Object data) {
+        RowResult result = new RowResult();
+        result.code = errorCode;
+        result.message = message;
+        result.data = data;
+        return result;
+    }
+
+    public ValueHolder toValueHolder() {
+        ValueHolder result = new ValueHolder();
+        result.setCode(this.code);
+        result.setMessage(this.message == null ? "" : this.message);
+        if (this.data != null) {
+            result.setData(this.data);
+        }
+
+        return result;
+    }
+
+    public Integer getCode() {
+        return this.code;
+    }
+
+    public String getMessage() {
+        return this.message;
+    }
+
+    public Object getData() {
+        return this.data;
+    }
+
+    public void setData(final Object data) {
+        this.data = data;
+    }
+}

+ 114 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/StoredProcedureService.java

@@ -0,0 +1,114 @@
+package com.boman.system.common;
+
+import com.boman.system.mapper.StoredProcedureMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author wmc
+ * @date 2020/8/26 9:13
+ */
+@Service
+@Slf4j
+public class StoredProcedureService {
+
+    @Autowired
+    private StoredProcedureMapper storedProcedureMapper;
+
+    /**
+     * 增删改提交 统一存储过程
+     *
+     * @param state      是否启用存储过程
+     * @param storedName 存储过程名
+     * @param pId        对象ID
+     * @param tableName  表名
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void storedProcedure(String state, String storedName, Long pId, Long pIsAdd, String tableName) {
+        if (StringUtils.isNotBlank(state)) {
+            if ("Y".equalsIgnoreCase(state)) {
+                if (StringUtils.isBlank(storedName)) {
+                    throw new IllegalArgumentException("启用存储过程,但未设置存储过程名称");
+                } else {
+                    if (pId == null) {
+                        throw new IllegalArgumentException("storedProcedure==>pId为空");
+                    } else {
+                        //判断调用哪种存储过程 storedProcedure两个入参 storedProcedure2两个入参 两个出参
+                        if ("2".equalsIgnoreCase(storedName.substring(storedName.length() - 1))) {
+                            Map<String, Object> map = new HashMap<>();
+                            map.put("pId", pId);
+                            map.put("pIsAdd", pIsAdd);
+                            map.put("storedName", storedName);
+                            map.put("p_code", null);
+                            map.put("p_message", null);
+                            //storedProcedureMapper.storedProcedure2(map);
+                            if ("-1".equalsIgnoreCase(map.get("p_code").toString())) {
+                                //throw new NDSException("存储过程"+storedName+"异常:"+map.get("p_message").toString());
+//                                throw new NDSException(map.get("p_message").toString());
+                                throw new IllegalArgumentException(map.get("p_message").toString());
+                            }
+                        } else {
+                            //判断一下表名  因为数据库 表的存储过程参数不一样
+                            if ("C_PAYWAY".contains(tableName)) {
+                                //storedProcedureMapper.storedProcedure(pId, storedName);
+                            } else {
+                                //调用存储过程
+                               // storedProcedureMapper.storedProcedure1(pId, pIsAdd, storedName);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 页面调用存储过程
+     */
+//    @Transactional(rollbackFor = Exception.class)
+//    public ValueHolder storedProcedure(JSONObject json) {
+//        //json里包含   isreturn是否有返回值  storedName存储过程名   params参数
+//        if (!json.containsKey("storedName")) {
+//            throw new NDSException("未找到存储过程名称");
+//        }
+//        if (!json.containsKey("isReturn")) {
+//            throw new NDSException("未找到存储过程是否需要返回值");
+//        }
+//        if (!json.containsKey("params")) {
+//            throw new NDSException("未找到存储过程参数");
+//        }
+//
+//        Boolean isReturn = json.getBoolean("isReturn");
+//        String storedName = json.getString("storedName");
+//        JSONObject params = json.getJSONObject("params");
+//        User user = RequestUtil.getUser();
+//        params.put("USERID", user == null ? "未找到用户id" : user.getId());
+//
+//        Map<String, Object> parmMap = new HashMap<>();
+//        parmMap.put("storedName", storedName);
+//        parmMap.put("params", params.toJSONString());
+//        ValueHolder valueHolder = new ValueHolder();
+//        if (isReturn) {
+//            //有返回值
+//            parmMap.put("datas", null);
+//            storedProcedureMapper.procedureGetValue(parmMap);
+//            try {
+//                JSONObject datas = JSONObject.parseObject(parmMap.get("datas").toString());
+//                valueHolder.setData(datas);
+//            } catch (Exception e) {
+//                throw new NDSException("存储过程返回值非标准json字符串");
+//            }
+//        } else {
+//            //没有返回值
+//            storedProcedureMapper.procedureNoValue(parmMap);
+//        }
+//        valueHolder.setCode(ResultCode.SUCCESS);
+//        return valueHolder;
+//    }
+}

+ 62 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/SubTableRecord.java

@@ -0,0 +1,62 @@
+package com.boman.system.common;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.Lists;
+import lombok.Getter;
+
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+/**
+ * @author lzm
+ * @date 2018/10/29
+ */
+@Getter
+public class SubTableRecord {
+    private Table table;
+//    private Column FK;
+    private Collection<RowRecord> rows;
+
+    public SubTableRecord(Table table, String fkColumnName, JSONArray jo) {
+        this.table = table;
+//        if (fkColumnName != null && !fkColumnName.isEmpty()) {
+//            this.FK = table.getColumn(fkColumnName);
+//        }
+        this.rows = Lists.newArrayList();
+        for (Integer i = 0; i < jo.size(); i++) {
+            try {
+                Long id = jo.getLong(i);
+                //只有id上传上来了
+                JSONObject tempPostData = new JSONObject();
+                tempPostData.put("ID", id);
+                RowRecord row = new RowRecord(id, table, tempPostData);
+                rows.add(row);
+            } catch (Exception e) {
+                JSONObject tempPostData = jo.getJSONObject(i);
+                RowRecord row = new RowRecord(tempPostData.getLong("ID"), table, tempPostData);
+                rows.add(row);
+            }
+        }
+    }
+
+//    public String getFKColumnName() {
+//        return FK.getName();
+//    }
+
+    public String getTableName() {
+        return table.getName();
+    }
+
+    public String getRealTableName() {
+//        String realTableName = table.getRealTableName();
+//        if (realTableName == null || realTableName.isEmpty()) {
+        String realTableName = table.getName();
+//        }
+        return realTableName;
+    }
+
+    public JSONArray getCommitDatas() {
+        return rows.stream().map(row -> row.getCommitData()).collect(Collectors.toCollection(JSONArray::new));
+    }
+}

+ 21 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/Table.java

@@ -0,0 +1,21 @@
+package com.boman.system.common;
+
+import com.boman.gen.domain.GenTableColumn;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 15:06
+ **/
+@Data
+public class Table {
+
+    private Object id;
+
+    private String name;
+
+    private List<GenTableColumn> columns;
+}

+ 18 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/TableService.java

@@ -0,0 +1,18 @@
+package com.boman.system.common;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 10:13
+ **/
+public interface TableService {
+
+    Logger LOGGER = LoggerFactory.getLogger(TableService.class);
+
+    void configure(TableServiceContext context);
+
+    RowResult executeAction(TableServiceContext context, MainTableRecord row);
+}

+ 218 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/TableServiceCmdService.java

@@ -0,0 +1,218 @@
+package com.boman.system.common;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.boman.gen.domain.GenTable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.lang.reflect.Method;
+import java.util.Collection;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 09:51
+ **/
+@Component("tableServiceCmdService-one")
+public class TableServiceCmdService {
+
+    @Autowired
+    private TableServiceContext tableServiceContext;
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(TableServiceCmdService.class);
+
+    public final ValueHolder execute(BaseTableSaveDTO baseTableSaveDTO, String actionName) throws Exception {
+        BaseTableDTO baseTableDTO = new BaseTableDTO();
+        baseTableDTO.setFixedData(baseTableSaveDTO.getFixedData());
+        baseTableDTO.setObjId(baseTableSaveDTO.getObjId());
+        baseTableDTO.setTable(baseTableSaveDTO.getTable());
+        return execute(baseTableDTO, actionName);
+    }
+
+    public final ValueHolder execute(BaseTableDTO baseTableDTO, String actionName) throws Exception {
+        TableServiceContext context = TableServiceContext.createFrom(baseTableDTO, actionName);
+
+        TableService service = getServiceByBusinessName(context.getTable());
+
+        service.configure(context);
+//        try {
+        executeAction(context, service);
+
+
+        return buildResult(context);
+//        } catch (Exception e) {
+//            LOGGER.error(e.getMessage(), e);
+//            LOGGER.error(Arrays.toString(e.getStackTrace()));
+//            return buildErrorResult(context, e);
+//        }
+
+//        return null;
+    }
+
+    public TableService getServiceByBusinessName(GenTable table){
+       return ApplicationContextHandle.getBean(table.getBusinessName() + "Service", TableService.class);
+    }
+
+//    protected TableServiceContext buildContext(BaseTableDTO baseTableDTO,String actionName) {
+//        return TableServiceContext.createFrom(baseTableDTO,actionName);
+//    }
+
+//    private TableService getServiceByTable(TableServiceContext context) {
+//        String tableName = context.getTableName();
+//        TableService service = null;
+//        try {
+//            service = ApplicationContextHandle.getBean(tableName + "Service", TableService.class);
+//        } catch (Exception e) {
+//            LOGGER.debug(e.getMessage());
+//        }
+////        if (service == null) {
+////            service = ApplicationContextHandle.getBean("defaultTableService-one");
+////            if (service == null) {
+////                throw new NDSException("defaultTableService 初始化失败!");
+////            }
+////        }
+//
+//        return service;
+//    }
+
+    private void executeAction(TableServiceContext context, TableService service) throws Exception {
+        Collection<Filter> filters = context.getFilters();
+        for (MainTableRecord row : context.getRows()) {
+//            ValidationResults validateResults = validate(context, row);
+//            if (validateResults.isOk()) {
+//                executeActionOnRow(context, service, row);
+//            } else {
+//                row.setResult(validateResults.toRowResult(row));
+//            }
+            executeActionOnRow(context, service, row);
+        }
+    }
+
+    private ValidationResults validate(TableServiceContext context, MainTableRecord row) {
+        Collection<Validator> validators = context.getValidators();
+        ValidationResults result = new ValidationResults();
+        for (Validator validator : validators) {
+            try {
+                validator.validate(context, row);
+            } catch (Exception e) {
+//                result.addError(e);
+            }
+        }
+        return result;
+    }
+
+//    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
+//    public void executeActionOnRow(TableServiceContext context, MainTableRecord row) throws Exception {
+//        try {
+//            Method customAction = null;
+//            Class serviceClazz = service.getClass();
+//            String actionName = context.getActionName();
+//            try {
+//                if (serviceClazz != DefaultTableService.class) {
+//                    customAction = serviceClazz.getMethod(actionName, TableServiceContext.class, MainTableRecord.class);
+//                }
+//            } catch (Exception e) {
+//                LOGGER.warn(String.format("试图在类%s中查找%s方法失败!", serviceClazz, actionName));
+//            }
+//            if (customAction != null) {
+//                LOGGER.debug(String.format("调用类%s的%s方法.", serviceClazz, actionName));
+//                row.setResult((RowResult) customAction.invoke(service, context, row));
+//            } else {
+//                LOGGER.debug(String.format("调用类%s的executeAction方法.", serviceClazz));
+//                row.setResult(service.executeAction(context, row));
+//            }
+//
+//            for (Filter filter : filters) {
+//                filter.after(context, row);
+//            }
+//        } catch (Exception e) {
+//            for (Filter filter : filters) {
+//                if (filter instanceof ExceptionFilter) {
+//                    ExceptionFilter tempFilter = (ExceptionFilter) filter;
+//                    RowResult exceptionHandleResult = tempFilter.handleException(context, row, e);
+//                    if (exceptionHandleResult != null) {
+//                        row.setResult(exceptionHandleResult);
+//                        return;
+//                    }
+//                }
+//            }
+//            //该异常没人处理了
+//            throw e;
+//        }
+//    }
+
+    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
+    public void executeActionOnRow(TableServiceContext context, TableService service, MainTableRecord row) throws Exception {
+        try {
+            Method customAction = null;
+            Class serviceClazz = service.getClass();
+            String actionName = context.getActionName();
+            try {
+//                if (serviceClazz != DefaultTableService.class) {
+                customAction = serviceClazz.getMethod(actionName, TableServiceContext.class, MainTableRecord.class);
+//                }
+            } catch (Exception e) {
+                LOGGER.warn(String.format("试图在类%s中查找%s方法失败!", serviceClazz, actionName));
+            }
+            if (customAction != null) {
+                LOGGER.debug(String.format("调用类%s的%s方法.", serviceClazz, actionName));
+                row.setResult((RowResult) customAction.invoke(service, context, row));
+            } else {
+                LOGGER.debug(String.format("调用类%s的executeAction方法.", serviceClazz));
+                row.setResult(service.executeAction(context, row));
+            }
+        } catch (Exception e) {
+//            for (Filter filter : filters) {
+//                if (filter instanceof ExceptionFilter) {
+//                    ExceptionFilter tempFilter = (ExceptionFilter) filter;
+//                    RowResult exceptionHandleResult = tempFilter.handleException(context, row, e);
+//                    if (exceptionHandleResult != null) {
+//                        row.setResult(exceptionHandleResult);
+//                        return;
+//                    }
+//                }
+//            }
+            //该异常没人处理了
+            throw e;
+        }
+    }
+
+    private ValueHolder buildResult(TableServiceContext context) {
+        ValueHolder valueHolder = new ValueHolder();
+        boolean code = context.getRows().stream().noneMatch(v -> -1 == v.getResult().getCode());
+        long errorSize = context.getRows().stream().filter(v -> -1 == v.getResult().getCode()).count();
+
+        if (context.getRows().size() == 1) {
+            return context.getRows().get(0).getResult().toValueHolder();
+        } else if (code) {
+            valueHolder.setCode(ResultCode.SUCCESS);
+            valueHolder.setMessage("操作成功" + context.getRows().size() + "条!");
+        } else {
+            valueHolder.setCode(ResultCode.FAIL);
+            valueHolder.setMessage("操作成功" + (context.getRows().size() - errorSize) + "条!,操作失败" + errorSize + "条!");
+            JSONArray datas = new JSONArray();
+            context.getRows().stream().filter(v -> -1 == v.getResult().getCode()).forEach(
+                    rowPostData -> {
+                        JSONObject row = new JSONObject();
+                        row.put("objid", rowPostData.getId());
+                        row.put("message", rowPostData.getResult().getMessage());
+                        datas.add(row);
+                    }
+            );
+
+            valueHolder.setData(datas);
+        }
+
+        return valueHolder;
+    }
+
+    private ValueHolder buildErrorResult(TableServiceContext context, Exception e) {
+        return new ValueHolder(ResultCode.FAIL,/* ExceptionUtil.getMessage(e)*/e.getMessage());
+    }
+}

+ 287 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/TableServiceContext.java

@@ -0,0 +1,287 @@
+package com.boman.system.common;
+
+import com.alibaba.fastjson.JSONObject;
+import com.boman.common.core.utils.SpringUtils;
+import com.boman.common.redis.service.RedisService;
+import com.boman.gen.domain.GenTable;
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.Resource;
+import java.sql.Timestamp;
+import java.util.*;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 09:58
+ **/
+@Service
+public class TableServiceContext {
+
+    private final static String PREFIX = "Controller:/event/do";
+
+    /**
+     * 当前表
+     */
+    private GenTable table;
+
+    /**
+     * 真实表名
+     */
+    private String realTableName;
+
+    /**
+     * 动作名(ADD,SAVE,SUBMIT,VOID,UNSUBMIT)
+     */
+    private String actionName;   //Controller:/event/doAdd
+
+    /**
+     * 业务发生的时间戳
+     */
+    private Timestamp currentTime;
+
+    /**
+     * 上行的数据
+     * 每个row对象对应到一条单据(如果存在事务,应该在这个级别上体现)
+     */
+    private List<MainTableRecord> rows;
+
+    /**
+     * 本次请求存放的临时数据
+     * !!慎用,最好不要在各个对象间传递
+     */
+    private Map<String, Object> values;
+
+    private boolean isDelMtable;
+
+    /**
+     * 是否批量新增
+     */
+    private boolean isInsertBacth = false;
+
+    private TableServiceContext() {
+        values = Maps.newHashMap();
+    }
+
+//    /**
+//     * 表名
+//     * 与realTableName的含义有差异
+//     */
+//    public String getTableName() {
+//        return table.getName();
+//    }
+
+    private User user;
+
+    /**
+     * 附加的校验器
+     */
+    private Collection<Validator> validators;
+
+    /**
+     * 附加的过滤器
+     */
+    private Collection<Filter> filters;
+
+
+    @Resource
+    private RedisService redisService;
+
+    public static TableServiceContext createFrom(BaseTableDTO baseTableDTO, String actionName) {
+        TableServiceContext result = new TableServiceContext();
+        result.user = RequestUtil.getUser();
+        result.actionName = actionName.replace(PREFIX, "").toUpperCase();
+        if (StringUtils.isEmpty(result.actionName)) {
+            throw new IllegalArgumentException("actionName不能为空");
+        }
+
+        String tableName = baseTableDTO.getTable();
+        if (StringUtils.isEmpty(tableName)) {
+            throw new IllegalArgumentException("表名参数不能为空");
+        }
+
+        //从redis中获取表信息
+        RedisService redisService = SpringUtils.getBean(RedisService.class);
+        result.table = redisService.getCacheObject("table:" + tableName);
+
+        if (result.table == null) {
+            throw new IllegalArgumentException(tableName + "表信息不存在");
+        }
+
+
+        result.realTableName = result.table.getTableName();
+        if (Strings.isNullOrEmpty(result.realTableName)) {
+            throw new IllegalArgumentException(tableName + "表名不存在");
+        }
+
+        // 前台传过来的数据
+        JSONObject fixedData = baseTableDTO.getFixedData();
+        //获取FK
+         JSONObject fkColumn = /*getFKColumn(fixColumn, tableName)*/null;
+        //删除
+        Boolean isdelmtable = baseTableDTO.getDelMTable();
+        JSONObject tabItem = baseTableDTO.getTabItem();
+        if (isdelmtable != null) {
+            result.isDelMtable = isdelmtable;
+        }
+
+        result.currentTime = new Timestamp(System.currentTimeMillis());
+
+        // 获取objid判断 新增或更新
+        Long objid = baseTableDTO.getObjId();
+        MainTableRecord mainRowData = new MainTableRecord(result, result.table, objid, fkColumn, fixedData, tabItem);
+        result.rows = Lists.newArrayList();
+        result.rows.add(mainRowData);
+
+        return result;
+    }
+
+    public static Table getTableByName(String tableName) {
+//        return TableManagerCache.getTableManager().getTable(tableName);
+        return null;
+    }
+//
+//    /**
+//     * 获取子表外健
+//     * @param fixColumn
+//     * @param tableName
+//     * @return
+//     */
+//    private static JSONObject getFKColumn(JSONObject fixColumn, String tableName) {
+//
+//        Table table = getTableByName(tableName);
+//        if (fixColumn == null || table == null) {
+//            return null;
+//        }
+//        //获取对应外键
+//        JSONObject fkcolumn = new JSONObject();
+//        Set<String> fixTable = fixColumn.keySet();
+//        Iterator it = fixTable.iterator();
+//        while (it.hasNext()) {
+//            tableName = (String) it.next();
+//            ArrayList<RefByTable> list = table.getRefByTables();
+//            for (int j = 0; j < list.size(); j++) {
+//                if (list.get(j).getReftable().getName().equals(tableName)) {
+//                    fkcolumn.put(tableName, TableManagerCache.getTableManager().getColumn(list.get(j).getRefByColumnId()).getName());
+//                }
+//            }
+//        }
+//
+//        return fkcolumn;
+//    }
+
+//    /**
+//     * 获取主表的明细表和外健
+//     *
+//     * @param tableName
+//     * @return
+//     */
+//    private static JSONObject getMainTableFKColumn(String tableName) {
+//
+//        Table table = getTableByName(tableName);
+//        if (table == null) {
+//            return null;
+//        }
+//        JSONObject fkcolumn = new JSONObject();
+//        //获取对应外键
+//        ArrayList<RefByTable> list = table.getRefByTables();
+//        for (int j = 0; j < list.size(); j++) {
+//            fkcolumn.put(list.get(j).getReftable().getName(), TableManagerCache.getTableManager().getColumn(list.get(j).getRefByColumnId()).getName());
+//        }
+//
+//        return fkcolumn;
+//    }
+
+
+    public GenTable getTable() {
+        return table;
+    }
+
+    public void setTable(GenTable table) {
+        this.table = table;
+    }
+
+    public String getRealTableName() {
+        return realTableName;
+    }
+
+    public void setRealTableName(String realTableName) {
+        this.realTableName = realTableName;
+    }
+
+    public String getActionName() {
+        return actionName;
+    }
+
+    public void setActionName(String actionName) {
+        this.actionName = actionName;
+    }
+
+    public Timestamp getCurrentTime() {
+        return currentTime;
+    }
+
+    public void setCurrentTime(Timestamp currentTime) {
+        this.currentTime = currentTime;
+    }
+
+    public List<MainTableRecord> getRows() {
+        return rows;
+    }
+
+    public void setRows(List<MainTableRecord> rows) {
+        this.rows = rows;
+    }
+
+    public Map<String, Object> getValues() {
+        return values;
+    }
+
+    public void setValues(Map<String, Object> values) {
+        this.values = values;
+    }
+
+    public boolean isDelMtable() {
+        return isDelMtable;
+    }
+
+    public void setDelMtable(boolean delMtable) {
+        isDelMtable = delMtable;
+    }
+
+    public boolean isInsertBacth() {
+        return isInsertBacth;
+    }
+
+    public void setInsertBacth(boolean insertBacth) {
+        isInsertBacth = insertBacth;
+    }
+
+    public User getUser() {
+        return user;
+    }
+
+    public void setUser(User user) {
+        this.user = user;
+    }
+
+    public Collection<Validator> getValidators() {
+        return validators;
+    }
+
+    public void setValidators(Collection<Validator> validators) {
+        this.validators = validators;
+    }
+
+    public Collection<Filter> getFilters() {
+        return filters;
+    }
+
+    public void setFilters(Collection<Filter> filters) {
+        this.filters = filters;
+    }
+}

+ 191 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/User.java

@@ -0,0 +1,191 @@
+package com.boman.system.common;
+
+//import com.eboss.sys.util.DateUtil;
+
+import java.util.*;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 09:44
+ **/
+public class User {
+
+    private Long id;
+    private String name;
+    private String eName;
+    private String trueName;
+    private String passwordHash;
+    private int isEnabled;
+    private Boolean isActive;
+    private int isEmployee;
+    private Boolean isAdmin;
+    private String description;
+    private String email;
+    private String phone;
+    private String lastLoginIp;
+    private String headImg;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String geteName() {
+        return eName;
+    }
+
+    public void seteName(String eName) {
+        this.eName = eName;
+    }
+
+    public String getTrueName() {
+        return trueName;
+    }
+
+    public void setTrueName(String trueName) {
+        this.trueName = trueName;
+    }
+
+    public String getPasswordHash() {
+        return passwordHash;
+    }
+
+    public void setPasswordHash(String passwordHash) {
+        this.passwordHash = passwordHash;
+    }
+
+    public int getIsEnabled() {
+        return isEnabled;
+    }
+
+    public void setIsEnabled(int isEnabled) {
+        this.isEnabled = isEnabled;
+    }
+
+    public Boolean getActive() {
+        return isActive;
+    }
+
+    public void setActive(Boolean active) {
+        isActive = active;
+    }
+
+    public int getIsEmployee() {
+        return isEmployee;
+    }
+
+    public void setIsEmployee(int isEmployee) {
+        this.isEmployee = isEmployee;
+    }
+
+    public Boolean getAdmin() {
+        return isAdmin;
+    }
+
+    public void setAdmin(Boolean admin) {
+        isAdmin = admin;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public String getLastLoginIp() {
+        return lastLoginIp;
+    }
+
+    public void setLastLoginIp(String lastLoginIp) {
+        this.lastLoginIp = lastLoginIp;
+    }
+
+    public String getHeadImg() {
+        return headImg;
+    }
+
+    public void setHeadImg(String headImg) {
+        this.headImg = headImg;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof User)) {
+            return false;
+        }
+        User user = (User) o;
+        return getIsEnabled() == user.getIsEnabled() &&
+                getIsEmployee() == user.getIsEmployee() &&
+                Objects.equals(getId(), user.getId()) &&
+                Objects.equals(getName(), user.getName()) &&
+                Objects.equals(geteName(), user.geteName()) &&
+                Objects.equals(getTrueName(), user.getTrueName()) &&
+                Objects.equals(getPasswordHash(), user.getPasswordHash()) &&
+                Objects.equals(isActive, user.isActive) &&
+                Objects.equals(isAdmin, user.isAdmin) &&
+                Objects.equals(getDescription(), user.getDescription()) &&
+                Objects.equals(getEmail(), user.getEmail()) &&
+                Objects.equals(getPhone(), user.getPhone()) &&
+                Objects.equals(getLastLoginIp(), user.getLastLoginIp()) &&
+                Objects.equals(getHeadImg(), user.getHeadImg());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getId(), getName(), geteName(), getTrueName(), getPasswordHash(), getIsEnabled(), isActive, getIsEmployee(), isAdmin, getDescription(), getEmail(), getPhone(), getLastLoginIp(), getHeadImg());
+    }
+
+    public Object getAttribute(String name) {
+//        name = name.toUpperCase().trim();
+//        if (this.userEnv == null) {
+//            return null;
+//        } else {
+//            Object o = this.userEnv.get(name);
+//            if (o == null) {
+//                if ("$SYSDATE$".equals(name)) {
+//                    o = DateUtil.dateFormatter.format(new Date());
+//                } else if ("$SYSDATENUM$".equals(name)) {
+//                    o = DateUtil.dateNumberFormatter.format(new Date());
+//                } else if ("$SYSDATETIME$".equals(name)) {
+//                    o = DateUtil.dateTimeSecondsFormatter.format(new Date());
+//                }
+//            }
+//
+//            return o;
+
+        return null;
+    }
+}

+ 54 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/ValidationResults.java

@@ -0,0 +1,54 @@
+package com.boman.system.common;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 10:50
+ **/
+public class ValidationResults {
+    private static final Logger log = LoggerFactory.getLogger(ValidationResults.class);
+    private static ValidationResults okResult = new ValidationResults();
+    private Collection<String> errors = new ArrayList();
+
+    public ValidationResults() {
+    }
+
+    public static ValidationResults ok() {
+        return okResult;
+    }
+
+    public boolean isOk() {
+        return this.errors == null || this.errors.size() <= 0;
+    }
+
+//    public RowResult toRowResult(MainTableRecord row) {
+//        return RowResult.error(String.join("\r\n", this.errors));
+//    }
+
+//    public void addError(Exception e) {
+//        String message = getMessage(e);
+//        this.errors.add(message);
+//    }
+
+//    private static String getMessage(Exception ex) {
+//        String message = ex.getMessage();
+//        if (!(ex instanceof NDSException)) {
+//            StringWriter sw = new StringWriter();
+//            PrintWriter pw = new PrintWriter(sw);
+//            ex.printStackTrace(pw);
+//            message = sw.toString().replace("\n", "<br/>").replace("\tat", "");
+//        }
+//
+//        return message;
+//    }
+
+    public Collection<String> getErrors() {
+        return this.errors;
+    }
+}

+ 8 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/Validator.java

@@ -0,0 +1,8 @@
+package com.boman.system.common;
+
+
+
+
+public interface Validator {
+    void validate(TableServiceContext context, MainTableRecord currentRow);
+}

+ 130 - 0
boman-modules/boman-system/src/main/java/com/boman/system/common/ValueHolder.java

@@ -0,0 +1,130 @@
+package com.boman.system.common;
+
+import com.alibaba.fastjson.JSONObject;
+import java.io.Serializable;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 09:26
+ **/
+public class ValueHolder<T> implements Serializable {
+
+    private T data;
+    private int code;
+    private String message;
+
+    public ValueHolder() {
+    }
+
+    public ValueHolder(T data, int code, String message) {
+        this.data = data;
+        this.code = code;
+        this.message = message;
+    }
+
+    public ValueHolder(int code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public JSONObject toJSONObject() {
+        JSONObject obj = new JSONObject();
+        obj.put("code", this.code);
+        obj.put("message", this.message);
+        obj.put("data", this.data);
+        return obj;
+    }
+
+    public boolean isOK() {
+        return this.code == 0;
+    }
+
+    public String toDebugString() {
+        return this.toJSONObject().toString();
+    }
+
+    public T getData() {
+        return this.data;
+    }
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getMessage() {
+        return this.message;
+    }
+
+    public void setData(final T data) {
+        this.data = data;
+    }
+
+    public void setCode(final int code) {
+        this.code = code;
+    }
+
+    public void setMessage(final String message) {
+        this.message = message;
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (o == this) {
+            return true;
+        } else if (!(o instanceof ValueHolder)) {
+            return false;
+        } else {
+            ValueHolder<?> other = (ValueHolder)o;
+            if (!other.canEqual(this)) {
+                return false;
+            } else {
+                label39: {
+                    Object this$data = this.getData();
+                    Object other$data = other.getData();
+                    if (this$data == null) {
+                        if (other$data == null) {
+                            break label39;
+                        }
+                    } else if (this$data.equals(other$data)) {
+                        break label39;
+                    }
+
+                    return false;
+                }
+
+                if (this.getCode() != other.getCode()) {
+                    return false;
+                } else {
+                    Object this$message = this.getMessage();
+                    Object other$message = other.getMessage();
+                    if (this$message == null) {
+                        return other$message == null;
+                    } else return this$message.equals(other$message);
+
+                }
+            }
+        }
+    }
+
+    protected boolean canEqual(final Object other) {
+        return other instanceof ValueHolder;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = 1;
+        Object $data = this.getData();
+        result = result * 59 + ($data == null ? 43 : $data.hashCode());
+        result = result * 59 + this.getCode();
+        Object $message = this.getMessage();
+        result = result * 59 + ($message == null ? 43 : $message.hashCode());
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "ValueHolder(data=" + this.getData() + ", code=" + this.getCode() + ", message=" + this.getMessage() + ")";
+    }
+}
+

+ 31 - 0
boman-modules/boman-system/src/main/java/com/boman/system/controller/ObjSaveController.java

@@ -0,0 +1,31 @@
+package com.boman.system.controller;
+
+import com.boman.system.common.BaseTableSaveDTO;
+import com.boman.system.common.TableServiceCmdService;
+import com.boman.system.common.ValueHolder;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.web.bind.annotation.*;
+
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 09:19
+ **/
+@RestController
+@RequestMapping("/obj")
+public class ObjSaveController {
+
+    @Autowired
+    @Qualifier("tableServiceCmdService-one")
+    private TableServiceCmdService tableServiceCmdService;
+
+    @ApiOperation(value = "单对象保存")
+    @PostMapping("/objectSave")
+    public ValueHolder doSave(@RequestBody BaseTableSaveDTO baseTableSaveDTO) throws Exception {
+        return tableServiceCmdService.execute(baseTableSaveDTO, "SAVE");
+    }
+
+}

+ 360 - 0
boman-modules/boman-system/src/main/java/com/boman/system/mapper/StandardlyMapper.java

@@ -0,0 +1,360 @@
+package com.boman.system.mapper;
+
+import com.alibaba.fastjson.JSONObject;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.ibatis.annotations.*;
+import org.apache.ibatis.jdbc.SQL;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.function.Consumer;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月22日 11:36
+ **/
+@Mapper
+@Component
+public interface StandardlyMapper {
+    @UpdateProvider(
+            type = StandardlyMapper.SqlProvider.class,
+            method = "update"
+    )
+    int updateById(@Param("tableName") String var1, @Param("model") JSONObject var2);
+
+    @UpdateProvider(
+            type = StandardlyMapper.SqlProvider.class,
+            method = "update"
+    )
+    int newUpdateById(@Param("tableName") String var1, @Param("model") long var2);
+
+
+    @DeleteProvider(
+            type = StandardlyMapper.SqlProvider.class,
+            method = "delete"
+    )
+    int deleteByIds(@Param("tableName") String var1, @Param("ids") long[] var2);
+
+    @Delete({"DELETE FROM ${tableName} where ID = #{id}"})
+    int deleteById(@Param("tableName") String var1, @Param("id") long var2);
+
+    @Select({"select * FROM ${tableName} where ID = #{id}"})
+    JSONObject getById(@Param("tableName") String var1, @Param("id") long var2);
+
+    @Select({"select ${columns} FROM ${tableName} where ID = #{id}"})
+    JSONObject getColumnsById(@Param("tableName") String var1, @Param("columns") String var2, @Param("id") long var3);
+
+    @InsertProvider(
+            type = StandardlyMapper.SqlProvider.class,
+            method = "insert"
+    )
+    int insert(@Param("tableName") String var1, @Param("model") JSONObject var2);
+
+    @InsertProvider(
+            type = StandardlyMapper.SqlProvider.class,
+            method = "inserts"
+    )
+    int inserts(@Param("tableName") String var1, @Param("models") JSONObject[] var2, @Param("processor") Consumer<JSONObject> var3);
+
+    @Select({"select count(1) FROM ${tableName} where ${column} = #{value} limit 1"})
+    boolean exists(@Param("tableName") String var1, @Param("column") String var2, @Param("value") Object var3);
+
+    @Select({"select count(1) FROM ${tableName} where ID = #{id} limit 1"})
+    boolean existsById(@Param("tableName") String var1, @Param("id") long var2);
+
+    @Select({"select count(1) FROM ${tableName} where id <> #{id} and ${column} = #{value} limit 1"})
+    boolean existsWithoutId(@Param("tableName") String var1, @Param("id") long var2, @Param("column") String var4, @Param("value") Object var5);
+
+    @UpdateProvider(
+            type = StandardlyMapper.SqlProvider.class,
+            method = "updates"
+    )
+    int updates(@Param("tableName") String var1, @Param("models") Collection<Object> var2, @Param("processor") Consumer<JSONObject> var3);
+
+    @Select("select id from ${tableName} where ${akColumnName} = #{akColumnValue}")
+    Long selectIdByAkColumn(@Param("tableName") String tableName, @Param("akColumnName") String akColumnName, @Param("akColumnValue") String akColumnValue);
+
+    public static class SqlProvider {
+        static final String[] READONLY_COLUMNS = new String[]{"OWNERID", "OWNERNAME", "OWNERENAME", "CREATIONDATE", "ID"};
+
+        public SqlProvider() {
+        }
+
+        private static boolean isReadOnly(String column) {
+            String[] var1 = READONLY_COLUMNS;
+            int var2 = var1.length;
+
+            for (int var3 = 0; var3 < var2; ++var3) {
+                String readonlyColumn = var1[var3];
+                if (readonlyColumn.equals(column)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        private static boolean isNullOrEmpty(String str) {
+            return str == null || str.length() == 0 || str.trim().length() == 0;
+        }
+
+        private static boolean isNullOrEmpty(JSONObject json) {
+            return json == null || json.isEmpty();
+        }
+
+        private static void keyToUpper(JSONObject json) {
+            String[] keys = new String[json.size()];
+            json.keySet().toArray(keys);
+            String[] var2 = keys;
+            int var3 = keys.length;
+
+            for (int var4 = 0; var4 < var3; ++var4) {
+                String key = var2[var4];
+                if (!key.equals(key.toUpperCase())) {
+                    json.put(key.toUpperCase(), json.get(key));
+                    json.remove(key);
+                }
+            }
+
+        }
+
+        public String update(Map<String, Object> para) {
+            String tableName = (String) para.get("tableName");
+            JSONObject model = (JSONObject) para.get("model");
+            //if (isNullOrEmpty(tableName)) {
+            if (StringUtils.isBlank(tableName)) {
+                throw new IllegalArgumentException("tableName 无效");
+            } else if (!model.isEmpty()) {
+                keyToUpper(model);
+                SQL sql = new SQL();
+                sql.UPDATE(tableName);
+                Iterator var5 = model.keySet().iterator();
+
+                while (var5.hasNext()) {
+                    String key = (String) var5.next();
+                    if (!isReadOnly(key)) {
+                        sql.SET(key + "= #{model." + key + "}");
+                    }
+                }
+
+                sql.WHERE("ID = #{model.ID}");
+                return sql.toString();
+            } else {
+                throw new IllegalArgumentException("model 无效");
+            }
+        }
+
+        public String inserts(Map<String, Object> para) {
+            String tableName = (String) para.get("tableName");
+            JSONObject[] models = (JSONObject[]) ((JSONObject[]) para.get("models"));
+            Consumer<JSONObject> processor = (Consumer) para.get("processor");
+            if (isNullOrEmpty(tableName)) {
+                throw new IllegalArgumentException("tableName 无效");
+            } else if (models != null && models.length != 0) {
+                Set<String> columns = new HashSet();
+
+                for (int i = 0; i < models.length; ++i) {
+                    JSONObject model = models[i];
+                    if (model == null) {
+                        models[i] = model = new JSONObject();
+                    }
+
+                    if (processor != null) {
+                        processor.accept(model);
+                    }
+
+                    keyToUpper(model);
+                    columns.addAll(model.keySet());
+                }
+
+                StringBuffer sql = new StringBuffer();
+                sql.append("INSERT INTO ");
+                sql.append(tableName);
+                sql.append("(");
+                sql.append(String.join(",", columns));
+                sql.append(") VALUES");
+
+                for (int i = 0; i < models.length; ++i) {
+                    sql.append("(");
+
+                    for (Iterator var8 = columns.iterator(); var8.hasNext(); sql.append(",")) {
+                        String column = (String) var8.next();
+                        if (models[i].containsKey(column)) {
+                            sql.append(String.format("#{models[%d].%s}", i, column));
+                        } else {
+                            sql.append("default");
+                        }
+                    }
+
+                    sql.setCharAt(sql.length() - 1, ')');
+                    sql.append(",");
+                }
+
+                sql.deleteCharAt(sql.length() - 1);
+                return sql.toString();
+            } else {
+                throw new IllegalArgumentException("model 无效");
+            }
+        }
+
+        public String insert(Map<String, Object> para) {
+            JSONObject model = (JSONObject) para.get("model");
+            String tableName = (String) para.get("tableName");
+            if (isNullOrEmpty(tableName)) {
+                throw new IllegalArgumentException("tableName 无效");
+            } else if (isNullOrEmpty(model)) {
+                throw new IllegalArgumentException("model 无效");
+            } else {
+                SQL sql = new SQL();
+                Set<String> keySet = model.keySet();
+                sql.INSERT_INTO(tableName);
+
+                for (int i = 0; i < model.size(); ++i) {
+                    String key = (String) keySet.toArray()[i];
+                    sql.VALUES(key, "#{model." + key + "}");
+                }
+
+                return sql.toString();
+            }
+        }
+
+        public String delete(Map<String, Object> para) {
+            long[] ids = (long[]) ((long[]) para.get("ids"));
+            String tableName = (String) para.get("tableName");
+            if (isNullOrEmpty(tableName)) {
+                throw new IllegalArgumentException("tableName 无效");
+            } else if (ids == null) {
+                throw new IllegalArgumentException("ids 无效");
+            } else if (ids.length == 0) {
+                return "";
+            } else if (ids.length == 1) {
+                return "DELETE FROM " + tableName + " where ID = #{ids[0]}";
+            } else {
+                StringBuffer sql = new StringBuffer();
+                sql.append("DELETE FROM ");
+                sql.append(tableName);
+                sql.append(" WHERE ");
+                sql.append("ID in (");
+
+                for (int i = 0; i < ids.length; ++i) {
+                    sql.append(String.format("#{ids[%d]}", i));
+                    sql.append(",");
+                }
+
+                sql.setCharAt(sql.length() - 1, ')');
+                return sql.toString();
+            }
+        }
+
+        public String updates(Map<String, Object> para) {
+            String tableName = (String) para.get("tableName");
+            Collection<Object> models = (Collection) para.get("models");
+            Consumer<JSONObject> processor = (Consumer) para.get("processor");
+            Boolean first = true;
+            if (isNullOrEmpty(tableName)) {
+                throw new IllegalArgumentException("tableName 无效");
+            } else if (models != null && models.size() != 0) {
+                JSONObject columnall = new JSONObject(true);
+                Iterator var7 = models.iterator();
+
+                while (var7.hasNext()) {
+                    Object obj = var7.next();
+                    JSONObject columnpart = (JSONObject) obj;
+                    if (columnpart == null) {
+                        columnpart = new JSONObject(true);
+                    }
+
+                    if (processor != null) {
+                        processor.accept(columnpart);
+                    }
+
+                    keyToUpper(columnpart);
+                    columnall.putAll(columnpart);
+                }
+
+                JSONObject clonekeyobj = (JSONObject) columnall.clone();
+                Set<String> keys = columnall.keySet();
+                Iterator var19 = keys.iterator();
+
+                while (var19.hasNext()) {
+                    String column = (String) var19.next();
+                    if (isReadOnly(column)) {
+                        clonekeyobj.remove(column);
+                    }
+                }
+
+                Set<String> firstkeys = clonekeyobj.keySet();
+                StringBuffer sql = new StringBuffer("");
+                sql.append("UPDATE ").append(tableName).append(" a");
+                sql.append(" right join (");
+                int i = -1;
+                Iterator var12 = models.iterator();
+
+                while (true) {
+                    while (var12.hasNext()) {
+                        Object obj = var12.next();
+                        ++i;
+                        JSONObject model = (JSONObject) obj;
+                        Iterator var15;
+                        String key;
+                        if (first.booleanValue()) {
+                            sql.append(" SELECT #{models[0].ID} `ID`,");
+                            var15 = firstkeys.iterator();
+
+                            while (var15.hasNext()) {
+                                key = (String) var15.next();
+                                if (model.get(key) == null) {
+                                    model.put(key, (Object) null);
+                                }
+
+                                sql.append(String.format("#{models[%d].%s} ", i, key));
+                                sql.append("`").append(key).append("`").append(",");
+                            }
+
+                            sql.deleteCharAt(sql.length() - 1);
+                            if (models.size() > 0) {
+                                sql.append(" union all");
+                            }
+
+                            first = false;
+                        } else {
+                            sql.append(" SELECT ");
+                            sql.append(String.format("#{models[%d].%s} ", i, "ID")).append(",");
+                            var15 = firstkeys.iterator();
+
+                            while (var15.hasNext()) {
+                                key = (String) var15.next();
+                                if (model.get(key) == null) {
+                                    model.put(key, (Object) null);
+                                }
+
+                                sql.append(String.format("#{models[%d].%s} ", i, key));
+                                sql.append(",");
+                            }
+
+                            sql.deleteCharAt(sql.length() - 1);
+                            if (i < models.size() - 1) {
+                                sql.append(" union all");
+                            }
+                        }
+                    }
+
+                    sql.append(") b on a.ID=b.ID ");
+                    sql.append(" SET ");
+                    var12 = firstkeys.iterator();
+
+                    while (var12.hasNext()) {
+                        String value = (String) var12.next();
+                        sql.append(" a.").append(value).append("=").append("IFNULL(b.").append(value).append(",").append("a.").append(value).append(")").append(",");
+                    }
+
+                    sql.deleteCharAt(sql.length() - 1);
+                    return sql.toString();
+                }
+            } else {
+                throw new IllegalArgumentException("model 无效");
+            }
+        }
+    }
+}

+ 50 - 0
boman-modules/boman-system/src/main/java/com/boman/system/mapper/StoredProcedureMapper.java

@@ -0,0 +1,50 @@
+package com.boman.system.mapper;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Options;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.mapping.StatementType;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * @author wmc
+ * @date 2020/8/24 17:08
+ */
+@Mapper
+@Component
+public interface StoredProcedureMapper {
+
+    @Options(statementType = StatementType.CALLABLE)
+    @Select("{call ${storedName} (#{pId,jdbcType=BIGINT,mode=IN})}")
+    void storedProcedure(@Param(value = "pId") Long pid, @Param("storedName") String storedName);
+
+    @Options(statementType = StatementType.CALLABLE)
+    @Select("{call ${storedName} (#{pId,jdbcType=BIGINT,mode=IN},#{pIsAdd,jdbcType=BIGINT,mode=IN})}")
+    void storedProcedure1(@Param(value = "pId") Long pid,
+                          @Param(value = "pIsAdd") Long pIsAdd,
+                          @Param(value = "storedName") String storedName);
+
+    @Options(statementType = StatementType.CALLABLE)
+    @Select("{call ${storedName} (#{pId,jdbcType=BIGINT,mode=IN},#{pIsAdd,jdbcType=BIGINT,mode=IN},#{p_code,jdbcType=VARCHAR,mode=OUT},#{p_message,jdbcType=VARCHAR,mode=OUT})}")
+    void storedProcedure2(Map map);
+
+    //xxl-job 调用的存储过程
+    @Options(statementType = StatementType.CALLABLE)
+    @Select("{call ${storedName} (#{timeId,jdbcType=BIGINT,mode=IN},#{param,jdbcType=VARCHAR,mode=IN})}")
+    void storedProcedureXXLJOB(@Param(value = "timeId") Long timeId,
+                               @Param(value = "param") String param,
+                               @Param(value = "storedName") String storedName);
+
+
+    @Options(statementType = StatementType.CALLABLE)
+    @Select("{call ${storedName} (#{params,jdbcType=VARCHAR,mode=IN},#{datas,jdbcType=VARCHAR,mode=OUT})}")
+    void procedureGetValue(Map map);
+
+    @Options(statementType = StatementType.CALLABLE)
+    @Select("{call ${storedName} (#{params,jdbcType=VARCHAR,mode=IN})}")
+    void procedureNoValue(Map map);
+
+}

+ 1 - 0
boman-modules/boman-system/src/main/java/com/boman/system/mapper/SysConfigMapper.java

@@ -42,6 +42,7 @@ public interface SysConfigMapper
      * @return 结果
      */
     public int insertConfig(SysConfig config);
+    public int insert(SysConfig config);
 
     /**
      * 修改参数配置

+ 1 - 0
boman-modules/boman-system/src/main/java/com/boman/system/mapper/SysPostMapper.java

@@ -81,6 +81,7 @@ public interface SysPostMapper
      * @return 结果
      */
     public int insertPost(SysPost post);
+    public int insert(SysPost post);
 
     /**
      * 校验岗位名称

+ 20 - 0
boman-modules/boman-system/src/main/resources/mapper/system/SysConfigMapper.xml

@@ -83,6 +83,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  			sysdate()
 		)
     </insert>
+
+    <insert id="insert" parameterType="SysConfig">
+        insert into sys_config (
+        <if test="configName != null and configName != '' ">config_name,</if>
+        <if test="configKey != null and configKey != '' ">config_key,</if>
+        <if test="configValue != null and configValue != '' ">config_value,</if>
+        <if test="configType != null and configType != '' ">config_type,</if>
+        <if test="createBy != null and createBy != ''">create_by,</if>
+        <if test="remark != null and remark != ''">remark,</if>
+        create_time
+        )values(
+        <if test="configName != null and configName != ''">#{configName},</if>
+        <if test="configKey != null and configKey != ''">#{configKey},</if>
+        <if test="configValue != null and configValue != ''">#{configValue},</if>
+        <if test="configType != null and configType != ''">#{configType},</if>
+        <if test="createBy != null and createBy != ''">#{createBy},</if>
+        <if test="remark != null and remark != ''">#{remark},</if>
+        sysdate()
+        )
+    </insert>
 	 
     <update id="updateConfig" parameterType="SysConfig">
         update sys_config 

+ 22 - 0
boman-modules/boman-system/src/main/resources/mapper/system/SysPostMapper.xml

@@ -107,6 +107,28 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  			sysdate()
  		)
 	</insert>
+
+	<insert id="insert" parameterType="SysPost" useGeneratedKeys="true" keyProperty="postId">
+		insert into sys_post(
+		<if test="postId != null and postId != 0">post_id,</if>
+		<if test="postCode != null and postCode != ''">post_code,</if>
+		<if test="postName != null and postName != ''">post_name,</if>
+		<if test="postSort != null and postSort != ''">post_sort,</if>
+		<if test="status != null and status != ''">status,</if>
+		<if test="remark != null and remark != ''">remark,</if>
+		<if test="createBy != null and createBy != ''">create_by,</if>
+		create_time
+		)values(
+		<if test="postId != null and postId != 0">#{postId},</if>
+		<if test="postCode != null and postCode != ''">#{postCode},</if>
+		<if test="postName != null and postName != ''">#{postName},</if>
+		<if test="postSort != null and postSort != ''">#{postSort},</if>
+		<if test="status != null and status != ''">#{status},</if>
+		<if test="remark != null and remark != ''">#{remark},</if>
+		<if test="createBy != null and createBy != ''">#{createBy},</if>
+		sysdate()
+		)
+	</insert>
 	
 	<delete id="deletePostById" parameterType="Long">
 		delete from sys_post where post_id = #{postId}

+ 151 - 0
boman-save/pom.xml

@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <parent>
+        <groupId>com.boman</groupId>
+        <artifactId>boman</artifactId>
+        <version>2.5.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>boman-save</artifactId>
+
+    <description>
+        boman-save
+    </description>
+
+    <properties>
+        <e5.version>2.0.0-SNAPSHOT</e5.version>
+    </properties>
+
+    <dependencies>
+
+        <!-- SpringCloud Ailibaba Nacos -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+
+        <!-- SpringCloud Ailibaba Nacos Config -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+
+        <!-- SpringCloud Ailibaba Sentinel -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
+        </dependency>
+
+        <!-- SpringBoot Actuator -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+
+        <!-- Swagger UI -->
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+            <version>${swagger.fox.version}</version>
+        </dependency>
+
+        <!-- Mysql Connector -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+
+        <!-- RuoYi Common DataSource -->
+        <dependency>
+            <groupId>com.boman</groupId>
+            <artifactId>boman-common-datasource</artifactId>
+        </dependency>
+
+        <!-- RuoYi Common DataScope -->
+        <dependency>
+            <groupId>com.boman</groupId>
+            <artifactId>boman-common-datascope</artifactId>
+        </dependency>
+
+        <!-- RuoYi Common Log -->
+        <dependency>
+            <groupId>com.boman</groupId>
+            <artifactId>boman-common-log</artifactId>
+        </dependency>
+
+        <!-- RuoYi Common Swagger -->
+        <dependency>
+            <groupId>com.boman</groupId>
+            <artifactId>boman-common-swagger</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-beanutils</groupId>
+            <artifactId>commons-beanutils</artifactId>
+            <version>1.9.4</version>
+        </dependency>
+
+        <!-- e5 dependences -->
+        <dependency>
+            <groupId>com.eboss</groupId>
+            <artifactId>e5-web-util</artifactId>
+            <version>${e5.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.eboss</groupId>
+            <artifactId>e5-permission-springcloud-util</artifactId>
+            <version>2.2.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>com.eboss</groupId>
+            <artifactId>eboss-jdbc</artifactId>
+            <version>${e5.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.eboss</groupId>
+            <artifactId>eboss-es</artifactId>
+            <version>${e5.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.eboss</groupId>
+            <artifactId>eboss-oss</artifactId>
+            <version>${e5.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.eboss</groupId>
+            <artifactId>eboss-model-util</artifactId>
+            <version>2.2.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>com.eboss</groupId>
+            <artifactId>eboss-model-query</artifactId>
+            <version>2.2.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>com.eboss</groupId>
+            <artifactId>e5-flow-springcloud-srv</artifactId>
+            <version>2.0.0-SNAPSHOT</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 31 - 0
boman-save/src/main/java/com/boman/save/BomanSaveApplication.java

@@ -0,0 +1,31 @@
+package com.boman.save;
+
+import com.boman.common.security.annotation.EnableCustomConfig;
+import com.boman.common.security.annotation.EnableRyFeignClients;
+import com.boman.common.swagger.annotation.EnableCustomSwagger2;
+import org.springframework.boot.SpringApplication;
+import org.springframework.cloud.client.SpringCloudApplication;
+
+/**
+ * @author shiqian
+ */
+@EnableCustomConfig
+@EnableCustomSwagger2
+@EnableRyFeignClients
+@SpringCloudApplication
+public class BomanSaveApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(BomanSaveApplication.class, args);
+        System.out.println("(♥◠‿◠)ノ゙  若依保存启动成功   ლ(´ڡ`ლ)゙  \n" +
+                " .-------.       ____     __        \n" +
+                " |  _ _   \\      \\   \\   /  /    \n" +
+                " | ( ' )  |       \\  _. /  '       \n" +
+                " |(_ o _) /        _( )_ .'         \n" +
+                " | (_,_).' __  ___(_ o _)'          \n" +
+                " |  |\\ \\  |  ||   |(_,_)'         \n" +
+                " |  | \\ `'   /|   `-'  /           \n" +
+                " |  |  \\    /  \\      /           \n" +
+                " ''-'   `'-'    `-..-'              ");
+    }
+}

+ 73 - 0
boman-save/src/main/java/com/boman/save/controller/ObjSaveController.java

@@ -0,0 +1,73 @@
+package com.boman.save.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.boman.common.core.utils.SpringUtils;
+import com.boman.common.core.utils.StringUtils;
+import com.boman.common.core.web.controller.BaseController;
+import com.boman.common.core.web.domain.AjaxResult;
+import com.boman.common.redis.service.RedisService;
+import com.boman.save.proxy.MyInvocationHandler;
+import com.boman.save.utils.ClassUtils;
+import org.apache.commons.beanutils.BeanUtils;
+import org.apache.ibatis.session.SqlSession;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Map;
+
+/**
+ * @author shiqian
+ * @description objSave保存
+ * @date 2021年03月18日 10:57
+ **/
+@RequestMapping("/objSave")
+@RestController
+public class ObjSaveController extends BaseController {
+
+    @Autowired
+    private RedisService redisService;
+    @Autowired
+    private SqlSession sqlSession;
+
+    @PostMapping
+    @SuppressWarnings("unchecked")
+    public AjaxResult objSave(@RequestBody Map<String, Object> param) throws IllegalAccessException
+            , InstantiationException, InvocationTargetException, ClassNotFoundException, NoSuchMethodException {
+        String tableName = (String) param.get("table");
+        if (StringUtils.isEmpty(tableName)) {
+            return AjaxResult.error();
+        }
+
+        JSONObject json = redisService.getCacheObject(packTableKey(tableName.toLowerCase()));
+        String entityClassName = "com.boman.save.domain." + json.getString("className");
+        Class<?> entityClass = ClassUtils.getClass(entityClassName);
+        Object entity = entityClass.newInstance();
+        Map<String, Object> fixedData = (Map<String, Object>) param.get("fixedData");
+        BeanUtils.populate(entity, fixedData);
+
+        String mapperClassName = "com.boman.save.mapper." + json.getString("className") + "Mapper";
+        Class<?> mapperClass = ClassUtils.getClass(mapperClassName);
+
+        Object instance = Proxy.newProxyInstance(
+                mapperClass.getClassLoader(),
+                new Class[]{mapperClass},
+                new MyInvocationHandler(sqlSession.getMapper(mapperClass))
+        );
+
+        Method method = instance.getClass().getMethod("insert", entityClass);
+        method.invoke(instance,entity);
+
+        return AjaxResult.success();
+    }
+
+    public String packTableKey(String tableName){
+        return "table:"+ tableName;
+    }
+
+}

+ 112 - 0
boman-save/src/main/java/com/boman/save/domain/SysConfig.java

@@ -0,0 +1,112 @@
+package com.boman.save.domain;
+
+import com.boman.common.core.annotation.Excel;
+import com.boman.common.core.annotation.Excel.ColumnType;
+import com.boman.common.core.web.domain.BaseEntity;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+
+/**
+ * 参数配置表 sys_config
+ * 
+ * @author ruoyi
+ */
+public class SysConfig extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 参数主键 */
+    @Excel(name = "参数主键", cellType = ColumnType.NUMERIC)
+    private Long configId;
+
+    /** 参数名称 */
+    @Excel(name = "参数名称")
+    private String configName;
+
+    /** 参数键名 */
+    @Excel(name = "参数键名")
+    private String configKey;
+
+    /** 参数键值 */
+    @Excel(name = "参数键值")
+    private String configValue;
+
+    /** 系统内置(Y是 N否) */
+    @Excel(name = "系统内置", readConverterExp = "Y=是,N=否")
+    private String configType;
+
+    public Long getConfigId()
+    {
+        return configId;
+    }
+
+    public void setConfigId(Long configId)
+    {
+        this.configId = configId;
+    }
+
+    @NotBlank(message = "参数名称不能为空")
+    @Size(min = 0, max = 100, message = "参数名称不能超过100个字符")
+    public String getConfigName()
+    {
+        return configName;
+    }
+
+    public void setConfigName(String configName)
+    {
+        this.configName = configName;
+    }
+
+    @NotBlank(message = "参数键名长度不能为空")
+    @Size(min = 0, max = 100, message = "参数键名长度不能超过100个字符")
+    public String getConfigKey()
+    {
+        return configKey;
+    }
+
+    public void setConfigKey(String configKey)
+    {
+        this.configKey = configKey;
+    }
+
+    @NotBlank(message = "参数键值不能为空")
+    @Size(min = 0, max = 500, message = "参数键值长度不能超过500个字符")
+    public String getConfigValue()
+    {
+        return configValue;
+    }
+
+    public void setConfigValue(String configValue)
+    {
+        this.configValue = configValue;
+    }
+
+    public String getConfigType()
+    {
+        return configType;
+    }
+
+    public void setConfigType(String configType)
+    {
+        this.configType = configType;
+    }
+    
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("configId", getConfigId())
+            .append("configName", getConfigName())
+            .append("configKey", getConfigKey())
+            .append("configValue", getConfigValue())
+            .append("configType", getConfigType())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .append("remark", getRemark())
+            .toString();
+    }
+}

+ 70 - 0
boman-save/src/main/java/com/boman/save/mapper/SysConfigMapper.java

@@ -0,0 +1,70 @@
+package com.boman.save.mapper;
+
+import com.boman.save.domain.SysConfig;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 参数配置 数据层
+ *
+ * @author ruoyi
+ */
+public interface SysConfigMapper
+{
+    /**
+     * 查询参数配置信息
+     *
+     * @param config 参数配置信息
+     * @return 参数配置信息
+     */
+    public SysConfig selectConfig(SysConfig config);
+
+    /**
+     * 查询参数配置列表
+     *
+     * @param config 参数配置信息
+     * @return 参数配置集合
+     */
+    public List<SysConfig> selectConfigList(SysConfig config);
+
+    /**
+     * 根据键名查询参数配置信息
+     *
+     * @param configKey 参数键名
+     * @return 参数配置信息
+     */
+    public SysConfig checkConfigKeyUnique(String configKey);
+
+    /**
+     * 新增参数配置
+     *
+     * @param config 参数配置信息
+     * @return 结果
+     */
+    public int insert(@Param("config") SysConfig config);
+
+    /**
+     * 修改参数配置
+     *
+     * @param config 参数配置信息
+     * @return 结果
+     */
+    public int updateConfig(SysConfig config);
+
+    /**
+     * 删除参数配置
+     *
+     * @param configId 参数ID
+     * @return 结果
+     */
+    public int deleteConfigById(Long configId);
+
+    /**
+     * 批量删除参数信息
+     *
+     * @param configIds 需要删除的参数ID
+     * @return 结果
+     */
+    public int deleteConfigByIds(Long[] configIds);
+}

+ 23 - 0
boman-save/src/main/java/com/boman/save/proxy/MyInvocationHandler.java

@@ -0,0 +1,23 @@
+package com.boman.save.proxy;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月19日 11:04
+ **/
+public class MyInvocationHandler  implements InvocationHandler {
+
+    private Object target;
+
+    public MyInvocationHandler(Object target) {
+        this.target = target;
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        return method.invoke(target,args);
+    }
+}

+ 20 - 0
boman-save/src/main/java/com/boman/save/utils/ClassUtils.java

@@ -0,0 +1,20 @@
+package com.boman.save.utils;
+
+import com.boman.common.core.utils.StringUtils;
+
+/**
+ * @author shiqian
+ * @description
+ * @date 2021年03月18日 14:22
+ **/
+public class ClassUtils {
+
+    public static Class<?> getClass(String classPath) throws ClassNotFoundException {
+        if (StringUtils.isEmpty(classPath)) {
+            throw new IllegalArgumentException(String.format("参数[%s]非法", classPath));
+        }
+
+        return Class.forName(classPath);
+    }
+
+}

+ 10 - 0
boman-save/src/main/resources/banner.txt

@@ -0,0 +1,10 @@
+Spring Boot Version: ${spring-boot.version}
+Spring Application Name: ${spring.application.name}
+                            _                        _                                 
+                           (_)                      | |                                
+ _ __  _   _   ___   _   _  _  ______   __ _   __ _ | |_   ___ __      __  __ _  _   _ 
+| '__|| | | | / _ \ | | | || ||______| / _` | / _` || __| / _ \\ \ /\ / / / _` || | | |
+| |   | |_| || (_) || |_| || |        | (_| || (_| || |_ |  __/ \ V  V / | (_| || |_| |
+|_|    \__,_| \___/  \__, ||_|         \__, | \__,_| \__| \___|  \_/\_/   \__,_| \__, |
+                      __/ |             __/ |                                     __/ |
+                     |___/             |___/                                     |___/ 

+ 27 - 0
boman-save/src/main/resources/bootstrap.yml

@@ -0,0 +1,27 @@
+# Tomcat
+server:
+  port: 8088
+
+# Spring
+spring: 
+  application:
+    # 应用名称
+    name: boman-save
+  profiles:
+    # 环境配置
+    active: dev
+  main:
+    allow-bean-definition-overriding: true
+  cloud:
+    nacos:
+      discovery:
+        # 服务注册地址
+        server-addr: 192.168.101.10:8848
+      config:
+        # 配置中心地址
+        server-addr: 192.168.101.10:8848
+        # 配置文件格式
+        file-extension: yml
+        # 共享配置
+        shared-configs:
+          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

+ 74 - 0
boman-save/src/main/resources/logback.xml

@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="60 seconds" debug="false">
+    <!-- 日志存放路径 -->
+	<property name="log.path" value="logs/boman-save" />
+   <!-- 日志输出格式 -->
+	<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
+
+    <!-- 控制台输出 -->
+	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+	</appender>
+
+    <!-- 系统日志输出 -->
+	<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+	    <file>${log.path}/info.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+			<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>60</maxHistory>
+		</rollingPolicy>
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>INFO</level>
+            <!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+	</appender>
+
+    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+	    <file>${log.path}/error.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+            <fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>ERROR</level>
+			<!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+			<!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 系统模块日志级别控制  -->
+	<logger name="com.boman" level="info" />
+	<!-- Spring日志级别控制  -->
+	<logger name="org.springframework" level="warn" />
+
+	<root level="info">
+		<appender-ref ref="console" />
+	</root>
+	
+	<!--系统操作日志-->
+    <root level="info">
+        <appender-ref ref="file_info" />
+        <appender-ref ref="file_error" />
+    </root>
+</configuration>

+ 112 - 0
boman-save/src/main/resources/mapper.system/SysConfigMapper.xml

@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.boman.save.mapper.SysConfigMapper">
+
+    <resultMap type="com.boman.save.domain.SysConfig" id="SysConfigResult">
+    	<id     property="configId"      column="config_id"      />
+        <result property="configName"    column="config_name"    />
+        <result property="configKey"     column="config_key"     />
+        <result property="configValue"   column="config_value"   />
+        <result property="configType"    column="config_type"    />
+        <result property="createBy"      column="create_by"      />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateBy"      column="update_by"      />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectConfigVo">
+        select config_id, config_name, config_key, config_value, config_type, create_by, create_time, update_by, update_time, remark
+		from sys_config
+    </sql>
+
+    <!-- 查询条件 -->
+	<sql id="sqlwhereSearch">
+		<where>
+			<if test="configId !=null">
+				and config_id = #{configId}
+			</if>
+			<if test="configKey !=null and configKey != ''">
+				and config_key = #{configKey}
+			</if>
+		</where>
+	</sql>
+
+    <select id="selectConfig" parameterType="SysConfig" resultMap="SysConfigResult">
+        <include refid="selectConfigVo"/>
+        <include refid="sqlwhereSearch"/>
+    </select>
+
+    <select id="selectConfigList" parameterType="SysConfig" resultMap="SysConfigResult">
+        <include refid="selectConfigVo"/>
+        <where>
+			<if test="configName != null and configName != ''">
+				AND config_name like concat('%', #{configName}, '%')
+			</if>
+			<if test="configType != null and configType != ''">
+				AND config_type = #{configType}
+			</if>
+			<if test="configKey != null and configKey != ''">
+				AND config_key like concat('%', #{configKey}, '%')
+			</if>
+			<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
+				and date_format(create_time,'%y%m%d') &gt;= date_format(#{params.beginTime},'%y%m%d')
+			</if>
+			<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
+				and date_format(create_time,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')
+			</if>
+		</where>
+    </select>
+
+    <select id="checkConfigKeyUnique" parameterType="String" resultMap="SysConfigResult">
+        <include refid="selectConfigVo"/>
+        where config_key = #{configKey} limit 1
+    </select>
+
+    <insert id="insert" parameterType="SysConfig">
+        insert into sys_config (
+			<if test="configName != null and configName != '' ">config_name,</if>
+			<if test="configKey != null and configKey != '' ">config_key,</if>
+			<if test="configValue != null and configValue != '' ">config_value,</if>
+			<if test="configType != null and configType != '' ">config_type,</if>
+			<if test="createBy != null and createBy != ''">create_by,</if>
+			<if test="remark != null and remark != ''">remark,</if>
+ 			create_time
+        )values(
+			<if test="configName != null and configName != ''">#{config.configName},</if>
+			<if test="configKey != null and configKey != ''">#{config.configKey},</if>
+			<if test="configValue != null and configValue != ''">#{config.configValue},</if>
+			<if test="configType != null and configType != ''">#{config.configType},</if>
+			<if test="createBy != null and createBy != ''">#{config.createBy},</if>
+			<if test="remark != null and remark != ''">#{config.remark},</if>
+ 			sysdate()
+		)
+    </insert>
+
+    <update id="updateConfig" parameterType="SysConfig">
+        update sys_config
+        <set>
+            <if test="configName != null and configName != ''">config_name = #{configName},</if>
+            <if test="configKey != null and configKey != ''">config_key = #{configKey},</if>
+            <if test="configValue != null and configValue != ''">config_value = #{configValue},</if>
+            <if test="configType != null and configType != ''">config_type = #{configType},</if>
+            <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
+            <if test="remark != null">remark = #{remark},</if>
+ 			update_time = sysdate()
+        </set>
+        where config_id = #{configId}
+    </update>
+
+    <delete id="deleteConfigById" parameterType="Long">
+        delete from sys_config where config_id = #{configId}
+    </delete>
+
+    <delete id="deleteConfigByIds" parameterType="Long">
+        delete from sys_config where config_id in
+        <foreach item="configId" collection="array" open="(" separator="," close=")">
+        	#{configId}
+        </foreach>
+    </delete>
+
+</mapper>