Parcourir la source

建表

master
郑根木 il y a 2 ans
Parent
révision
2ac5b5fb6d
20 fichiers modifiés avec 778 ajouts et 932 suppressions
  1. +4
    -0
      smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/CoreApplicationStartedListener.java
  2. +2
    -0
      smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/AbstractCache.java
  3. +35
    -1
      smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/SwEnum.java
  4. +0
    -2
      smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/DbEngine.java
  5. +5
    -0
      smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/cache/ModelDatabaseCache.java
  6. +556
    -0
      smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/DatabaseUtil.java
  7. +2
    -2
      smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/IDatabaseInfo.java
  8. +158
    -0
      smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/UtilTime.java
  9. +11
    -4
      smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelTable.java
  10. +0
    -191
      smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/DbQueryDatasetService.java
  11. +0
    -21
      smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/dict/DictTypeListService.java
  12. +0
    -10
      smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/dict/entity/DictTypePO.java
  13. +5
    -3
      smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormHelper.java
  14. +0
    -131
      smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/model/AspDbCardService.java
  15. +0
    -306
      smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/model/AspModelCardService.java
  16. +0
    -54
      smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/model/AspModelConfigService.java
  17. +0
    -69
      smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/model/AspModelExportService.java
  18. +0
    -25
      smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/model/AspModelListService.java
  19. +0
    -103
      smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/model/AspModelTreeService.java
  20. +0
    -10
      smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/model/entity/TreeMoveVO.java

+ 4
- 0
smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/CoreApplicationStartedListener.java Voir le fichier

@@ -1,6 +1,7 @@
package cc.smtweb.framework.core;

import cc.smtweb.framework.core.cache.CacheManager;
import cc.smtweb.framework.core.db.impl.DatabaseUtil;
import cc.smtweb.framework.core.mvc.controller.scan.ApplicationScanner;
import cc.smtweb.framework.core.systask.TaskStartEvent;
import cc.smtweb.framework.core.systask.WebStartedEvent;
@@ -24,10 +25,13 @@ public class CoreApplicationStartedListener implements ApplicationListener<Appli
applicationContext.publishEvent(new TaskStartEvent());
//包扫描
ApplicationScanner.scan(applicationContext);
//初始化数据库
new DatabaseUtil(true, false).checkDb();
//初始化缓存
CacheManager.getIntance().init();

// 通知 controller 正式使用
applicationContext.publishEvent(new WebStartedEvent());
System.out.println("start end=============");
}
}

+ 2
- 0
smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/cache/AbstractCache.java Voir le fichier

@@ -109,9 +109,11 @@ public abstract class AbstractCache<T extends Serializable> implements ISwCache<
*/
protected void init() {
if (RedisManager.getInstance().exists(getIdent())) {
log.info("从redis同步缓存!(" + getTitle() + ")");
//从缓存服务器下载到本地
syncCache();
} else if (!lazy) {
log.info("从数据库同步缓存!(" + getTitle() + ")");
refresh();
}
}


+ 35
- 1
smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/common/SwEnum.java Voir le fichier

@@ -96,6 +96,11 @@ public interface SwEnum {
this.defaultValue = defaultValue;
this.editor = editor;
}

public String getSqlTypeCreate() {
if (dataLength > 0) return sqlType + "(" + dataLength + ")";
return sqlType;
}
}

/**
@@ -139,6 +144,36 @@ public interface SwEnum {
}

/**
* 数据字段类型Bean
*/
class IndexTypeBean extends AbstractEnum.StrEnumBean {
public String fullName;

public IndexTypeBean(String value, String name, String fullName) {
super(value, name);
this.fullName = fullName;
}
}

class IndexType extends AbstractEnum<String, IndexTypeBean> {
public static IndexType instance = new IndexType();
public static IndexTypeBean PK = instance.addEnum("P", "主键", "prim-key");
public static IndexTypeBean I = instance.addEnum("I", "一般索引", "");
public static IndexTypeBean U = instance.addEnum("U", "唯一索引", "unique");

@Override
protected IndexTypeBean buildBean(String value, String name) {
return null;
}

public IndexTypeBean addEnum(String value, String name, String fullName) {
final IndexTypeBean bean = new IndexTypeBean(value, name, fullName);
mapAll.put(value, bean);
return bean;
}
}

/**
* 表类型
*/
class TableType extends IntEnum {
@@ -149,7 +184,6 @@ public interface SwEnum {
public static AbstractEnum.IntEnumBean TYPE_CODE = instance.addEnum(2, "编码表");
public static AbstractEnum.IntEnumBean TYPE_ABSTRACT = instance.addEnum(3, "虚拟抽象表");
public static AbstractEnum.IntEnumBean TYPE_VIEW = instance.addEnum(4, "视图");

}

/**


+ 0
- 2
smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/DbEngine.java Voir le fichier

@@ -1,13 +1,11 @@
package cc.smtweb.framework.core.db;

import cc.smtweb.framework.core.db.impl.BaseBean;
import cc.smtweb.framework.core.db.impl.DefaultEntity;
import cc.smtweb.framework.core.db.jdbc.IdGenerator;
import cc.smtweb.framework.core.db.jdbc.JdbcEngine;
import cc.smtweb.framework.core.mvc.controller.scan.BeanManager;
import cc.smtweb.framework.core.util.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;



+ 5
- 0
smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/cache/ModelDatabaseCache.java Voir le fichier

@@ -38,4 +38,9 @@ public class ModelDatabaseCache extends AbstractCache<ModelDatabase> {
public final ModelDatabase getByName(String key) {
return getByKey(mk, key);
}

public final String getName(long id) {
ModelDatabase db = get(id);
return db != null ? db.getName() : "";
}
}

+ 556
- 0
smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/DatabaseUtil.java Voir le fichier

@@ -0,0 +1,556 @@
package cc.smtweb.framework.core.db.impl;

import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.cache.ModelTableCache;
import cc.smtweb.framework.core.db.vo.ModelField;
import cc.smtweb.framework.core.db.vo.ModelIndex;
import cc.smtweb.framework.core.db.vo.ModelTable;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.text.MessageFormat;
import java.util.*;

/**
* Created with IntelliJ IDEA.
* User: AKhh
* Date: 12-12-21 下午2:41
* 启动时检查数据库并自动建表、字段、索引;
*/
@Slf4j
@SuppressWarnings("UnusedDeclaration")
public class DatabaseUtil {
private static final int INDEX_NAME_MAX_LENGTH = 30; //索引名称长度;
private static final String MODULE = DatabaseUtil.class.getName();
private IDatabaseInfo databaseInfo;
//是否需要根据实体定义清理数据库字段
private boolean is_db_clean_field = false;
//是否需要根据实体定义清理数据库表
private boolean is_db_clean_table = false;

public DatabaseUtil(boolean is_db_clean_field, boolean is_db_clean_table) {
this.is_db_clean_field = is_db_clean_field;
this.is_db_clean_table = is_db_clean_table;
this.databaseInfo = new DefaultDatabaseInfoImpl();
}

/**
* 检测数据库结构和配置是否一致,根据配置增加表或字段信息;
*/
public void checkDb() {
UtilTime timer = new UtilTime();
timer.setLog(true);
timer.timerString("Start - 开始获取连接的数据库的元信息!");
this.databaseInfo.printDatabaseInfo();
// get ALL tables from this database
Map<String, IDatabaseInfo.TableCheckInfo> tableNames = this.databaseInfo.getTables();
//Set<IDatabaseInfo.TableCheckInfo> fkTableNames = (tableNames == null ? null : new HashSet<IDatabaseInfo.TableCheckInfo>(tableNames.values()));
//Set<IDatabaseInfo.TableCheckInfo> indexTableNames = (tableNames == null ? null : new HashSet<IDatabaseInfo.TableCheckInfo>(tableNames.values()));
if (tableNames == null) {
String message = "不能从数据库获取表名信息,将被跳过...";
log.error(message, MODULE);
return;
}
timer.timerString("已从数据库获取所有的表名信息!");
// get ALL column info, put into hashmap by table name
Map<String, List<IDatabaseInfo.ColumnCheckInfo>> colInfo = this.databaseInfo.getColumnInfo(tableNames);
if (colInfo == null) {
String message = "不能从数据库获取字段列信息,将被跳过...";
log.error(message, MODULE);
return;
}
timer.timerString("已获取所有的数据库字段列信息。");
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
timer.timerString("开始检查表,列定义信息.....................................");
Collection<ModelTable> ModelTableDefList = ModelTableCache.getInstance().getAll();
Iterator<ModelTable> ModelTableIter = ModelTableDefList.iterator();
int curEnt = 0;
int totalEnt = ModelTableDefList.size();
List<ModelTable> entitiesAdded = new LinkedList<>(); // 数据库中没有的实体, 通过建表
// 数据库中有表, 也有对应的实体
Map<IDatabaseInfo.TableCheckInfo, ModelTable> entitiesExist = new HashMap<>();
while (ModelTableIter.hasNext()) {
curEnt++;
ModelTable entity = ModelTableIter.next();
String entMessage = "(" + timer.timeSinceLast() + "ms) Checking #" + curEnt + "/" + totalEnt + " Entity " + entity.getName();
log.info(entMessage, MODULE);
String k = entity.getName(); //表名
// -make sure all entities have a corresponding table
if (tableNames.containsKey(k)) {
IDatabaseInfo.TableCheckInfo table = tableNames.remove(k);
entitiesExist.put(table, entity);
if (colInfo != null) {
List<String> delCols = new ArrayList<>();
Map<String, ModelField> fieldColNames = new HashMap<>();
for (int fnum = 0, len = entity.getFields().size(); fnum < len; fnum++) {
ModelField field = entity.getFields().get(fnum);
fieldColNames.put(field.getName().toUpperCase(), field); // XML读出来是小写,数据库读取来是大写.
}
List<IDatabaseInfo.ColumnCheckInfo> colList = colInfo.get(entity.getName());
int numCols = 0;
if (colList != null) {
for (; numCols < colList.size(); numCols++) {
IDatabaseInfo.ColumnCheckInfo ccInfo = colList.get(numCols);
ccInfo.columnName = ccInfo.columnName.toUpperCase();
// -list all columns that do not have a corresponding field
if (fieldColNames.containsKey(ccInfo.columnName)) {
ModelField field = fieldColNames.remove(ccInfo.columnName);
SwEnum.DataTypeBean modelFieldType = SwEnum.DataType.instance.getByValue(field.getDataType());
if (modelFieldType != null) {
// make sure each corresponding column is of the correct type
if (!ccInfo.typeName.equalsIgnoreCase(modelFieldType.sqlType)) {
String message = "警告: 表[" + entity.getName() + "]字段[" + ccInfo.columnName + "] 字段类型不一致:::数据库:[" + ccInfo.typeName + "], " +
"实体定义:[" + modelFieldType.sqlType + "]!";
log.error(message, MODULE);
}
if (modelFieldType.dataLength != -1 && ccInfo.columnSize != -1 && modelFieldType.dataLength != ccInfo.columnSize) {
String message = "警告: 表[" + entity.getName() + "]字段[" + ccInfo.columnName + "] 字段长度不一致:::数据库:[" + ccInfo.columnSize + "], " +
"实体定义:[" + modelFieldType.dataLength + "]!";
log.debug(message, MODULE);
}
/*if (decimalDigits != -1 && decimalDigits != ccInfo.decimalDigits) {
String message = "警告: 表[" + entity.getName() + "]字段[" + ccInfo.columnName + "] 小数位数不一致:::数据库:[" + ccInfo.decimalDigits + "], " +
"实体定义:[" + decimalDigits + "]!";
log.debug(message, MODULE);
}*/
} else {
String message = "警告: 表[" + entity.getName() + "]字段[" + ccInfo.columnName + "] 字段类型定义错误[" + field.getDataType() + "]!";

log.error(message, MODULE);
}
} else {
String message = "表\"" + entity.getName() + "\"字段\"" + ccInfo.columnName + "\"没有定义!";
log.debug(message, MODULE);
if (is_db_clean_field) {
delCols.add(ccInfo.columnName);
}
}
}
}
// -display message if number of table columns does not match number of entity fields
if (!is_db_clean_field) {
if (numCols != entity.getFields().size()) {
String message = "表[" + entity.getName() + "]定义了" + entity.getFields().size() + "个字段,但数据库有" + numCols + "个字段!";
log.debug(message, MODULE);
}
} else if (delCols.size() > 0) {
String errMsg = dropColumn(entity, delCols);
String message;
if (errMsg != null && errMsg.length() > 0) {
message = "清理字段出错,表:\"" + entity.getName() + "\": " + errMsg;
log.error(message, MODULE);
} else {
message = "清理字段成功,表:\"" + entity.getName() + "\"";
log.debug(message, MODULE);
}
}
// -list all fields that do not have a corresponding column
for (String colName : fieldColNames.keySet()) {
ModelField field = fieldColNames.get(colName);
String message = "Field \"" + field.getName() + "\" of entity \"" + entity.getName() + "\" is missing its corresponding column \"" + field.getName() + "\"";
log.debug(message, MODULE);
// add the column
String errMsg = addColumn(entity, field);
if (errMsg != null && errMsg.length() > 0) {
message = "加字段出错,表:\"" + entity.getName() + "\".\"" + field.getName() + "\": " + errMsg;
log.error(message, MODULE);
} else {
message = "加字段成功,表:\"" + entity.getName() + "\".\"" + field.getName() + "\"";
log.debug(message, MODULE);
}
}
//修复主键
if (StringUtils.isEmpty(table.pk)) {
String errMsg = addPk(entity);
String message;
if (errMsg != null && errMsg.length() > 0) {
message = "修复主键出错,表:\"" + entity.getName() + "\": " + errMsg;
log.error(message, MODULE);
} else {
message = "修复主键成功,表:\"" + entity.getName() + "\"";
log.debug(message, MODULE);
}
}
}
} else {
String message = "数据库没有找到表\"" + entity.getName() + "\"";
log.debug(message, MODULE);
// create the table
String errMsg = createTable(entity);
if (StringUtils.isNotEmpty(errMsg)) {
message = "建表\"" + entity.getName() + "\"出错: " + errMsg;
log.error(message, MODULE);
} else {
entitiesAdded.add(entity);
message = "建表成功\"" + entity.getName() + "\"";
log.debug(message, MODULE);
}
}
}
timer.timerString("After Individual Table/Column Check");
// -list all tables that do not have a corresponding entity
Iterator<String> tableNamesIter = tableNames.keySet().iterator();
while (tableNamesIter != null && tableNamesIter.hasNext()) {
String tableName = tableNamesIter.next();
if (!is_db_clean_table) {
String message = "表\"" + tableName + "\"没有实体定义文件!";
log.debug(message, MODULE);
} else {
String message, errMsg = dropTable(tableNames.get(tableName).catalog, tableName);
if (StringUtils.isNotEmpty(errMsg)) {
message = "删除表\"" + tableName + "\"出错: " + errMsg;
log.error(message, MODULE);
} else {
message = "删除表成功\"" + tableName + "\"";
log.debug(message, MODULE);
}
}
}

// for each newly added table, add declared indexes
for (ModelTable curEntity : entitiesAdded) {
String indErrMsg = this.createDeclaredIndices(curEntity);
if (indErrMsg != null && indErrMsg.length() > 0) {
String message = "建索引出错,表\"" + curEntity.getName() + "\": " + indErrMsg;
log.error(message, MODULE);
} else {
String message = "建索引成功,表 \"" + curEntity.getName() + "\"";
log.debug(message, MODULE);
}
}
// 补充索引 get ALL column info, put into hashmap by table name
Map<String, Map<String, Set<String>>> tableIndexListMap = this.databaseInfo.getIndexInfo(entitiesExist.keySet(), true);
for (ModelTable entity : entitiesExist.values()) {
// 实体未定义索引.
if (entity.getIndexes().isEmpty())
continue;
// get existing index map for this table
Map<String, Set<String>> exists_indexes = tableIndexListMap.get(entity.getName());
Set<String> setEnabled = new HashSet<>();//有效的索引
for (ModelIndex mi: entity.getIndexes()) {
if (SwEnum.IndexType.PK.value.equalsIgnoreCase(mi.getType())) continue;

Set<String> dbfields = null;
String indexName = getDbIndexName(entity, mi);
if (exists_indexes != null) dbfields = exists_indexes.get(indexName);
setEnabled.add(mi.getName());
if (!hasDiff(mi.getFields(), dbfields)) {//没有变化,不管
continue;
}
if (dbfields != null) deleteDeclaredIndex(entity.getSchemaTableName(), indexName);

// 建数据库已经有表的不存在的索引
String indErrMsg = this.createDeclaredIndex(entity, mi);
if (indErrMsg != null && indErrMsg.length() > 0) {
String message = "建索引出错,表:\"" + entity.getName() + "\".\"" + mi.getName() + "\": " + indErrMsg;
log.error(message, MODULE);
} else {
String message = "Created declared index [" + mi.getName() + "] for entity \"" + entity.getName() + "\"";
log.debug(message, MODULE);
}
}
for (String indexName : exists_indexes.keySet()) {
if (!setEnabled.contains(indexName)) deleteDeclaredIndex(entity.getSchemaTableName(), indexName);
}
}
timer.timerString("数据库结构检测和同步完成!");
}

//顺序不一致,也要重建
private boolean hasDiff(String fields1, Set<String> fields2) {
if (StringUtils.isEmpty(fields1) || fields2 == null) return true;
String[] f1 = fields1.split(",");
if (fields1.length() != fields2.size()) return true;
int n = 0;
for (String s : fields2) {
if (!s.equalsIgnoreCase(f1[n].toLowerCase())) return true;
n++;
}
return false;
}

/**
* 建表
*
* @param entity ModelTable
* @return String 错误消息
*/
public String createTable(ModelTable entity) {
if (entity == null) {
return "ModelTable was null and is required to create a table";
}

// entity.setCurCreated(true);
StringBuilder sqlBuf = new StringBuilder("CREATE TABLE ");
sqlBuf.append(entity.getSchemaTableName());
sqlBuf.append(" (");
for (ModelField field : entity.getFields()) {
SwEnum.DataTypeBean type = SwEnum.DataType.instance.getByValue(field.getDataType());

if (type == null) {
return "Field type [" + field.getDataType() + "] not found for field [" + field.getName() + "] of entity [" + entity.getName() + "], not creating table.";
}

sqlBuf.append(field.getName());
sqlBuf.append(" ");
sqlBuf.append(type.getSqlTypeCreate());

if (field.getName().equalsIgnoreCase(entity.getIdField())) {
sqlBuf.append(" NOT NULL , ");
} else {
if (!StringUtils.isEmpty(field.getDefaultValue())) {
sqlBuf.append(" DEFAULT '").append(field.getDefaultValue()).append("'");
}
sqlBuf.append(" , ");
}
}
String pkName = "PK_" + entity.getName();
if (pkName.length() > INDEX_NAME_MAX_LENGTH) {
pkName = pkName.substring(0, INDEX_NAME_MAX_LENGTH);
}
sqlBuf.append("CONSTRAINT ");
sqlBuf.append(pkName);
sqlBuf.append(" PRIMARY KEY (");
sqlBuf.append(entity.getIdField());
sqlBuf.append("))");

try {
DbEngine.getInstance().update(sqlBuf.toString());
} catch (Exception e) {
return e.getMessage();
}
addTableComment(entity);
//加上字段注解:
for (ModelField field : entity.getFields()) {
addColumnComment(entity, field);
}
return null;
}

public String addColumn(ModelTable entity, ModelField field) {
if (entity == null || field == null) {
return "ModelTable or ModelField where null, cannot add column";
}
SwEnum.DataTypeBean type = SwEnum.DataType.instance.getByValue(field.getDataType());
if (type == null) {
return "Field type not found for field [" + field.getName() + "] of entity [" + entity.getName() + "], not adding column.";
}
StringBuilder sqlBuf = new StringBuilder(128);
sqlBuf.append(MessageFormat.format("ALTER TABLE {0} ADD {1} {2}", entity.getSchemaTableName(), field.getName(), type.getSqlTypeCreate()));
if (!StringUtils.isEmpty(field.getDefaultValue())) {
sqlBuf.append(" DEFAULT '").append(field.getDefaultValue()).append("'");
}
log.debug("正在增加字段" + entity.getName() + "." + field.getName());
try {
DbEngine.getInstance().update(sqlBuf.toString());
} catch (Exception e) {
sqlBuf.setLength(0);
sqlBuf.append("ALTER TABLE ").append(entity.getSchemaTableName()).append(" ADD COLUMN ").append(field.getName()).append(" ").append(type.getSqlTypeCreate());
if (StringUtils.isNotEmpty(field.getDefaultValue())) {
sqlBuf.append(" DEFAULT '").append(field.getDefaultValue()).append("'");
}
try {
DbEngine.getInstance().update(sqlBuf.toString());
} catch (Exception e1) {
return e.getMessage();
}
}
//加上字段注解:
addColumnComment(entity, field);
return null;
}

public String addPk(ModelTable entity) {
if (entity == null) {
return "实体为null!";
}
if (StringUtils.isEmpty(entity.getPkFieldName())) {
return "表" + entity.getName() + "没有定义主键!";
}
String pkName = "PK_" + entity.getName();
if (pkName.length() > INDEX_NAME_MAX_LENGTH) {
pkName = pkName.substring(0, INDEX_NAME_MAX_LENGTH);
}
StringBuilder sqlBuf = new StringBuilder(128);
sqlBuf.append("ALTER TABLE ").append(entity.getSchemaTableName()).append(" ADD CONSTRAINT ")
.append(pkName).append(" PRIMARY KEY (").append(entity.getIdField()).append(")");
try {
DbEngine.getInstance().update(sqlBuf.toString());
} catch (Exception e) {
return e.getMessage();
}
return null;
}

//删除表列
public String dropColumn(ModelTable entity, List<String> delCols) {
if (delCols.isEmpty()) return null;
StringBuilder sql = new StringBuilder(128);
sql.append("ALTER TABLE " + entity.getSchemaTableName()).append("\nDROP COLUMN(");
for (String col : delCols) {
sql.append(col).append(",");
}

log.debug("正在删除表字段" + entity.getName());
try {
DbEngine.getInstance().update(sql.substring(0, sql.length() - 1) + ")");
} catch (Exception e) {
return e.getMessage();
}
return null;
}

//删除表
public String dropTable(String catalog, String tableName) {
if (StringUtils.isNotEmpty(catalog)) tableName = catalog + "." + tableName;
log.debug("正在删除表" + tableName);
try {
DbEngine.getInstance().update("drop table " + tableName);
} catch (Exception e) {
return e.getMessage();
}
return null;
}

private String addTableComment(ModelTable entity) {
log.debug("正在增加表说明" + entity.getName());
try {
DbEngine.getInstance().update("ALTER TABLE " + entity.getSchemaTableName() + " COMMENT '" + entity.getTitle() + "'");
} catch (Exception e) {
return e.getMessage();
}
return null;
}

private String addColumnComment(ModelTable entity, ModelField field) {
log.debug("正在增加字段说明" + entity.getName() + "." + field.getName());
// comment on column BASE_ENUM.DESCRIPTION is
SwEnum.DataTypeBean type = SwEnum.DataType.instance.getByValue(field.getDataType());
if (type == null) return null;
try {
String defValue = StringUtils.isNotEmpty(field.getDefaultValue()) ? "'" + field.getDefaultValue() + "'" : "";
String dvs = StringUtils.isNotEmpty(field.getDefaultValue()) ? " DEFAULT '" + field.getDefaultValue() + "'" : "";
String sql = "ALTER TABLE " + entity.getSchemaTableName() + " MODIFY COLUMN " + field.getName() + " " + type.getSqlTypeCreate() + dvs + " COMMENT '" + field.getRemark() + "'";
DbEngine.getInstance().update(sql);
} catch (Exception e) {
return e.getMessage();
}
return null;
}

/**
* 建立索引
*
* @param entity 实体定义对象;
* @return 错误消息,处理正确会返回null
*/
public String createDeclaredIndices(ModelTable entity) {
if (entity == null) {
return "ModelTable was null and is required to create declared indices for a table";
}
StringBuilder retMsgsBuffer = new StringBuilder();
// go through the indexes to see if any need to be added
Iterator<ModelIndex> indexesIter = entity.getIndexes().iterator();
for (ModelIndex modelIndex : entity.getIndexes()) {
String retMsg = createDeclaredIndex(entity, modelIndex);
if (retMsg != null && retMsg.length() > 0) {
if (retMsgsBuffer.length() > 0) {
retMsgsBuffer.append("\n");
}
retMsgsBuffer.append(retMsg);
}
}
if (retMsgsBuffer.length() > 0) {
return retMsgsBuffer.toString();
} else {
return null;
}
}

private String createDeclaredIndex(ModelTable entity, ModelIndex modelIndex) {
log.debug("正在创建索引" + entity.getName() + "." + modelIndex.getName() + ".....");
String createIndexSql = makeIndexClause(entity, modelIndex);
if (StringUtils.isEmpty(createIndexSql)) return null;
try {
DbEngine.getInstance().update(createIndexSql);
} catch (Exception sqle) {
return "SQL Exception while executing the following:\n" + createIndexSql + "\nError was: " + sqle.toString();
}
return null;
}

/**
* 构造建立索引的脚本
*
* @param entity 实体
* @param modelIndex 索引定义;
* @return 脚本;
*/
private String makeIndexClause(ModelTable entity, ModelIndex modelIndex) {
if (SwEnum.IndexType.PK.value.equalsIgnoreCase(modelIndex.getType())) return null;
SwEnum.IndexTypeBean type = SwEnum.IndexType.instance.getByValue(modelIndex.getType());
return "CREATE " + (SwEnum.IndexType.U.value.equalsIgnoreCase(modelIndex.getType()) ? SwEnum.IndexType.U.fullName : "") +
" INDEX " + entity.getAbbr() + "_" + getDbIndexName(entity, modelIndex) +
" ON " + entity.getSchemaTableName() + " (" + modelIndex.getFields() + ")";
}

/**
* 删除已经实体已经定义的索引
*
* @param entity 实体
* @return sql
*/
private String deleteDeclaredIndices(ModelTable entity) {
if (entity == null) {
return "ModelTable was null and is required to delete foreign keys indices for a table";
}
StringBuilder retMsgsBuffer = new StringBuilder();
// go through the relationships to see if any foreign keys need to be added
for (ModelIndex modelIndex : entity.getIndexes()) {
String retMsg = deleteDeclaredIndex(entity, modelIndex);
if (retMsg != null && retMsg.length() > 0) {
if (retMsgsBuffer.length() > 0) {
retMsgsBuffer.append("\n");
}
retMsgsBuffer.append(retMsg);
}
}
if (retMsgsBuffer.length() > 0) {
return retMsgsBuffer.toString();
} else {
return null;
}
}

/**
* 删除已经定义的索引
*
* @param entity 实体
* @param modelIndex 索引;
* @return sql
*/
private String deleteDeclaredIndex(ModelTable entity, ModelIndex modelIndex) {
String deleteIndexSql = "DROP INDEX " + entity.getSchemaTableName() + "." + getDbIndexName(entity, modelIndex);
try {
DbEngine.getInstance().update(deleteIndexSql);
} catch (Exception sqle) {
return "SQL Exception while executing the following:\n" + deleteIndexSql + "\nError was: " + sqle.toString();
}
return null;
}

private String deleteDeclaredIndex(String tableName, String indexName) {
String deleteIndexSql = "DROP INDEX " + indexName + " ON " + tableName;
try {
DbEngine.getInstance().update(deleteIndexSql);
} catch (Exception sqle) {
return "SQL Exception while executing the following:\n" + deleteIndexSql + "\nError was: " + sqle.toString();
}
return null;
}

private String getDbIndexName(ModelTable entity, ModelIndex modelIndex) {
return entity.getAbbr() + "_" + modelIndex;
}
}

+ 2
- 2
smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/IDatabaseInfo.java Voir le fichier

@@ -20,13 +20,13 @@ public interface IDatabaseInfo {

Map<String, Map<String, Set<String>>> getIndexInfo(Collection<TableCheckInfo> tableNames, boolean include_nounique);

public static class TableCheckInfo {
class TableCheckInfo {
public String tableName;
public String catalog;
public String pk;
}

public static class ColumnCheckInfo {
class ColumnCheckInfo {
public String tableName;
public String columnName;
public String typeName;


+ 158
- 0
smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/impl/UtilTime.java Voir le fichier

@@ -0,0 +1,158 @@
package cc.smtweb.framework.core.db.impl;

/**
* Created with IntelliJ IDEA.
* User: AKhh
* Date: 12-12-21 下午10:04
* To change this template use File | Settings | File Templates.
*/
public class UtilTime {
long realStartTime;
long startTime;
long lastMessageTime;
String lastMessage = null;
boolean log = false;

/**
* Default constructor. Starts the timer.
*/
public UtilTime() {
lastMessageTime = realStartTime = startTime = System.currentTimeMillis();
lastMessage = "Begin";
}

/**
* Creates a string with information including the passed message, the last passed message and the time since the last call, and the time since the beginning
*
* @param message A message to put into the timer String
* @return A String with the timing information, the timer String
*/
public String timerString(String message) {
return timerString(message, this.getClass().getName());
}

/**
* Creates a string with information including the passed message, the last passed message and the time since the last call, and the time since the beginning
*
* @param message A message to put into the timer String
* @param module The debug/log module/thread to use, can be null for root module
* @return A String with the timing information, the timer String
*/
public String timerString(String message, String module) {
// time this call to avoid it interfering with the main timer
long tsStart = System.currentTimeMillis();

String retString = "[[" + message + "- total:" + secondsSinceStart() +
",since last(" + ((lastMessage.length() > 20) ? (lastMessage.substring(0, 17) + "..."): lastMessage) + "):" +
secondsSinceLast() + "]]";

lastMessage = message;
if (log) {
System.out.println(retString);
}
// have lastMessageTime come as late as possible to just time what happens between calls
lastMessageTime = System.currentTimeMillis();
// update startTime to disclude the time this call took
startTime += (lastMessageTime - tsStart);
return retString;
}

/**
* Returns the number of seconds since the timer started
*
* @return The number of seconds since the timer started
*/
public double secondsSinceStart() {
return ((double) timeSinceStart()) / 1000.0;
}

/**
* Returns the number of seconds since the last time timerString was called
*
* @return The number of seconds since the last time timerString was called
*/
public double secondsSinceLast() {
return ((double) timeSinceLast()) / 1000.0;
}

/**
* Returns the number of milliseconds since the timer started
*
* @return The number of milliseconds since the timer started
*/
public long timeSinceStart() {
long currentTime = System.currentTimeMillis();

return currentTime - startTime;
}

/**
* Returns the number of milliseconds since the last time timerString was called
*
* @return The number of milliseconds since the last time timerString was called
*/
public long timeSinceLast() {
long currentTime = System.currentTimeMillis();

return currentTime - lastMessageTime;
}

/**
* Sets the value of the log member, denoting whether log output is off or not
*
* @param log The new value of log
*/
public void setLog(boolean log) {
this.log = log;
}

/**
* Gets the value of the log member, denoting whether log output is off or not
*
* @return The value of log
*/
public boolean getLog() {
return log;
}

/**
* Creates a string with information including the passed message, the time since the last call,
* and the time since the beginning. This version allows an integer level to be specified to
* improve readability of the output.
*
* @param level Integer specifying how many levels to indent the timer string so the output can be more easily read through nested method calls.
* @param message A message to put into the timer String
* @return A String with the timing information, the timer String
*/
public String timerString(int level, String message) {
StringBuffer retStringBuf = new StringBuffer();
for (int i = 0; i < level; i++) {
retStringBuf.append("| ");
}
retStringBuf.append("(");

String timeSinceStartStr = String.valueOf(timeSinceStart());

// int spacecount = 5 - timeSinceStartStr.length();
// for (int i=0; i < spacecount; i++) { retStringBuf.append(' '); }
retStringBuf.append(timeSinceStartStr + ",");

String timeSinceLastStr = String.valueOf(timeSinceLast());

// spacecount = 4 - timeSinceLastStr.length();
// for (int i=0; i < spacecount; i++) { retStringBuf.append(' '); }
retStringBuf.append(timeSinceLastStr);

retStringBuf.append(")");
int spacecount = 12 + (2 * level) - retStringBuf.length();

for (int i = 0; i < spacecount; i++) {
retStringBuf.append(' ');
}
retStringBuf.append(message);
// lastMessageTime = (new Date()).getTime();
lastMessageTime = System.currentTimeMillis();
// lastMessage = message;
return retStringBuf.toString();
}
}

+ 11
- 4
smtweb-framework/sw-framework-core/src/main/java/cc/smtweb/framework/core/db/vo/ModelTable.java Voir le fichier

@@ -4,6 +4,8 @@ import cc.smtweb.framework.core.annotation.SwTable;
import cc.smtweb.framework.core.common.AbstractEnum;
import cc.smtweb.framework.core.common.IntEnum;
import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.cache.ModelDatabaseCache;
import cc.smtweb.framework.core.db.cache.ModelTableCache;
import cc.smtweb.framework.core.db.impl.DefaultEntity;
import cc.smtweb.framework.core.util.JsonUtil;
@@ -16,11 +18,11 @@ import java.util.List;

@SwTable(value = "ASP_MODEL_TABLE")
public class ModelTable extends DefaultEntity {
public final static String DEF_DB_NAME = "sys";
public final static String ENTITY_NAME = "ASP_MODEL_TABLE";

/*冗余*/
private String idField;
private String dbName;

private List<ModelField> fields = new ArrayList<>();
private List<ModelIndex> indexes = new ArrayList<>();
@@ -151,7 +153,7 @@ public class ModelTable extends DefaultEntity {
}

public String getDbName() {
return dbName;
return ModelDatabaseCache.getInstance().getName(getDbId());
}

public List<ModelField> getFields() {
@@ -184,7 +186,7 @@ public class ModelTable extends DefaultEntity {
}

public String fullName() {
return dbName + '.' + getName();
return getDbName() + '.' + getName();
}

public void addIndex(ModelIndex modelIndex) {
@@ -270,10 +272,15 @@ public class ModelTable extends DefaultEntity {
this.fields = bean.fields;
this.indexes = bean.indexes;
this.caches = bean.caches;

ModelIndex i = findPrimaryIndex();
if (i != null) {
this.idField = i.getFields();
}
}

public String getSchemaTableName() {
String dbName = getDbName();
if (StringUtils.isEmpty(dbName) || dbName.equals(DEF_DB_NAME)) return getName();
return DbEngine.getInstance().getDbSchema() + "_" + dbName + "." + getName();
}
}

+ 0
- 191
smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/db/DbQueryDatasetService.java Voir le fichier

@@ -1,191 +0,0 @@
package cc.smtweb.system.bpm.web.design.db;

import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.annotation.SwBody;
import cc.smtweb.framework.core.annotation.SwParam;
import cc.smtweb.framework.core.annotation.SwService;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.cache.ModelDatabaseCache;
import cc.smtweb.framework.core.db.cache.ModelTableCache;
import cc.smtweb.framework.core.db.vo.ModelDatabase;
import cc.smtweb.framework.core.db.vo.ModelField;
import cc.smtweb.framework.core.db.vo.ModelTable;
import cc.smtweb.system.bpm.engine.ui.entity.vo.dataset.FzDatasetPropsVO;
import cc.smtweb.system.bpm.engine.ui.entity.vo.dataset.FzDatasetVO;
import cc.smtweb.system.bpm.engine.ui.entity.vo.dataset.FzFieldVO;
import cc.smtweb.system.bpm.engine.ui.entity.vo.widiget.UiControlPropsVO;
import cc.smtweb.system.bpm.util.CodeGenUtil;
import org.apache.commons.lang3.StringUtils;

import java.sql.ResultSetMetaData;
import java.sql.Types;
import java.util.*;

@SwService
public class DbQueryDatasetService {
@SwParam
private DbEngine dbEngine;

public R query(@SwBody SwMap body) {
String sql = body.readString("sql");

if (StringUtils.isBlank(sql)) {
return R.error("sql参数为空");
}

if(!sql.trim().toLowerCase().startsWith("select ")){
return R.error("sql必须是查询语句");
}

if (sql.endsWith(";")) {
return R.error("sql语句需要去掉结束符合';'");
}

ModelDatabase modelDatabase = getModelDatabase(sql);

FzDatasetVO uiDataset = new FzDatasetVO();
uiDataset.setType("fz-dataset");
uiDataset.setProps(new FzDatasetPropsVO());

dbEngine.query(sql + " limit 1", resultSet -> {
// 解析数据库中的库名
ModelTable modelTable = null;
ResultSetMetaData rsmd = resultSet.getMetaData();
int columnCount = rsmd.getColumnCount();
List<FzFieldVO> fields = new ArrayList<>();
String masterTableName = null;
String masterTableLabel = null;

for (int index = 1; index <= columnCount; ++index) {
FzFieldVO uiField = new FzFieldVO();
UiControlPropsVO props = new UiControlPropsVO();
uiField.setProps(props);

String fieldName = rsmd.getColumnName(index);
String name = rsmd.getColumnLabel(index);
int size = rsmd.getColumnDisplaySize(index);
uiField.setId(name);
props.put("fieldName", fieldName);
props.put("name", CodeGenUtil.underlineToHump(name));
props.put("length", size);

switch (rsmd.getColumnType(index)) {
case Types.BIGINT:
uiField.setType("fz-field-long");
props.put("dataType", "id");
break;
case Types.INTEGER:
case Types.SMALLINT:
case Types.TINYINT:
uiField.setType("fz-field-int");
props.put("dataType", "int");
break;
case Types.CHAR:
case Types.NCHAR:
case Types.VARCHAR:
case Types.NVARCHAR:
uiField.setType("fz-field-string");
props.put("dataType", "string");
break;
case Types.FLOAT:
uiField.setType("fz-field-float");
props.put("dataType", "float");
break;
case Types.DATE:
case Types.TIME:
case Types.TIMESTAMP:
uiField.setType("fz-field-date");
props.put("dataType", "date");
break;
default:
throw new IllegalStateException("Unexpected value: " + rsmd.getColumnType(index));
}

String tableName = rsmd.getTableName(index);

if (modelDatabase != null) {
modelTable = findModelTable(modelDatabase, modelTable, tableName);

if (modelTable != null) {
ModelField modelField = modelTable.findFieldByName(name);

if (modelField != null) {
props.put("label", modelField.getTitle());
}
if (masterTableName == null) {
masterTableName = tableName;
masterTableLabel = modelTable.getTitle();
}
}
}

if (masterTableName == null) {
masterTableName = tableName;
masterTableLabel = tableName;
}

fields.add(uiField);
}

uiDataset.getProps().setFields(fields.toArray(new FzFieldVO[0]));
uiDataset.getProps().setName(masterTableName);
uiDataset.getProps().setLabel(masterTableLabel);

return null;
});

return R.success(uiDataset);
}

private ModelDatabase getModelDatabase(String sql) {
ModelDatabase modelDatabase = null;
String dbName = extractSqlDbName(sql);
Long modelId = dbEngine.queryLong("select model_id from sw_bpm.asp_model where model_key=? and model_type=1", dbName);
if (modelId != null) {
modelDatabase = ModelDatabaseCache.getInstance().get(modelId);
}

return modelDatabase;
}

private ModelTable findModelTable(ModelDatabase modelDatabase, ModelTable modelTable, String tableName) {
if (tableName != null) {
if (modelTable != null && tableName.equalsIgnoreCase(modelTable.getName())) {
return modelTable;
}

return ModelTableCache.getInstance().getByName(tableName);
}

return null;
}

private static final Set<String> KEYWORD_SET = new HashSet<String>(){{
this.add("from");
this.add("join");
}};

public static String extractSqlDbName(String sql) {
StringTokenizer st = new StringTokenizer(sql, " ");

int step = 0;
while (st.hasMoreTokens()) {
String token = st.nextToken();
if (step == 0) {
if (KEYWORD_SET.contains(token.toLowerCase())) {
step = 1;
}
} else {
String[] ary = token.split("\\.");
if (ary.length > 1) {
return ary[0];
}

step = 0;
}
}

return null;
}
}

+ 0
- 21
smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/dict/DictTypeListService.java Voir le fichier

@@ -1,21 +0,0 @@
package cc.smtweb.system.bpm.web.design.dict;

import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.annotation.SwParam;
import cc.smtweb.framework.core.annotation.SwService;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.system.bpm.web.design.dict.entity.DictTypePO;

import java.util.List;

@SwService
public class DictTypeListService {
@SwParam
private DbEngine dbEngine;

public R list() {
List<DictTypePO> list = dbEngine.query("select dt_id, dt_name, dt_desc from sw_user.sys_dict_type order by dt_name",
DictTypePO.class);
return R.success(list);
}
}

+ 0
- 10
smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/dict/entity/DictTypePO.java Voir le fichier

@@ -1,10 +0,0 @@
package cc.smtweb.system.bpm.web.design.dict.entity;

import lombok.Data;

@Data
public class DictTypePO {
private Long dtId;
private String dtName;
private String dtDesc;
}

+ 5
- 3
smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/form/ModelFormHelper.java Voir le fichier

@@ -263,10 +263,12 @@ public class ModelFormHelper {
for (long id : widgetIds) {
ModelForm widgetForm = getFromCache(id);
if (widgetForm == null) throw new SwException("没有找到指定的控件定义!id=" + id);
SwMap w = new SwMap();
widget.put("w" + id, w);
SwMap widgetOpts = parseFormOption(widgetForm.getOption());
widget.put("service", widgetForm.getService());
if (widgetOpts != null) widget.putAll(widgetOpts);
widget.put("define", widgetForm.getContent());
w.put("service", widgetForm.getService());
if (widgetOpts != null) w.putAll(widgetOpts);
w.put("define", widgetForm.getContent());
}
//构建变量
SwMap mapVar = new SwMap();


+ 0
- 131
smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/model/AspDbCardService.java Voir le fichier

@@ -1,131 +0,0 @@
package cc.smtweb.system.bpm.web.design.model;

import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.annotation.SwBody;
import cc.smtweb.framework.core.annotation.SwParam;
import cc.smtweb.framework.core.annotation.SwService;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.cache.ModelDatabaseCache;
import cc.smtweb.framework.core.db.cache.ModelTableCache;
import cc.smtweb.framework.core.db.sqlbuilder.InsertSqlBuilder;
import cc.smtweb.framework.core.db.sqlbuilder.SqlBuilder;
import cc.smtweb.framework.core.db.sqlbuilder.UpdateSqlBuilder;
import cc.smtweb.framework.core.db.vo.ModelDatabase;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.framework.core.util.DateUtil;
import cc.smtweb.system.bpm.spring.dao.DatasetConfigDao;
import org.apache.commons.lang3.StringUtils;

//@Api(tags = "数据库设计")
@SwService
public class AspDbCardService {
@SwParam
private DbEngine dbEngine;

@SwParam
private ModelDatabaseCache bpmDbCache;
private ModelTableCache bpmTableCache;

@SwParam
protected DatasetConfigDao datasetConfigDao;

// @ApiOperation(value = "读取数据模型数据")
public R load(@SwParam("id") long id, UserSession us) {
ModelDatabase db = bpmDbCache.get(id);
if (db == null) {
return R.error("没有找到指定数据库定义(" + id + ")!");
}

return R.success(db);
}

public R loadByKey(@SwParam("key") String key, @SwParam("type") String type, UserSession us) {
ModelDatabase db = bpmDbCache.getByName(key);
if (db == null) {
return R.error("没有找到指定数据库定义(" + key + ")!");
}
return R.success(db);
}

private boolean isNullId(Long id) {
return id == null || id == 0;
}

// @ApiOperation(value = "创建数据模型")
public R save(@SwBody ModelDatabase modelPo, UserSession us) {

if (StringUtils.isBlank(modelPo.getName())) {
return R.error("库名不能为空");
}
if (StringUtils.isBlank(modelPo.getTitle())) {
return R.error("库标题不能为空");
}

modelPo.setUpdateAt(DateUtil.nowDateTimeLong());

// 保存数据到部署表和部署历史表
if (isNullId(modelPo.getId())) {
dbEngine.doTrans(() -> {
modelPo.setId(dbEngine.nextId());

InsertSqlBuilder sqlBuilder = SqlBuilder.createInsert("sw_bpm.asp_model_database");
sqlBuilder.add("db_id", modelPo.getId())
.add("db_name", modelPo.getName())
.add("db_title", modelPo.getTitle())
.add("db_status", modelPo.getStatus())
.add("db_version", modelPo.getVersion())
.add("db_create_at", modelPo.getCreateAt())
.add("db_update_at", modelPo.getUpdateAt())
.add("db_create_uid", us.getUserId())
.add("db_update_uid", us.getUserId());
sqlBuilder.update(dbEngine);

return true;
});

bpmDbCache.put(modelPo);

return R.success(modelPo.getId());
} else {
modelPo.setVersion(modelPo.getVersion() + 1);

// 更新数据
boolean r = dbEngine.doTrans(() -> {

UpdateSqlBuilder sqlBuilder = SqlBuilder.createUpdate("sw_bpm.asp_model_database");

sqlBuilder.add("db_name", modelPo.getName())
.add("db_title", modelPo.getTitle())
.add("db_status", modelPo.getStatus())
.add("db_version", modelPo.getVersion())
.add("db_update_at", modelPo.getUpdateAt())
.add("db_update_uid", us.getUserId());

int ret = sqlBuilder.update(dbEngine);

if (ret > 0) {
bpmDbCache.put(modelPo);
return true;
} else {
bpmDbCache.reset(modelPo);
}

return false;
});


return R.error("保存失败,未找到记录");
}
}

// @ApiOperation(value = "删除数据模型")
public R delete(@SwBody ModelDatabase modelPo, UserSession us) {
String sql = "delete from sw_bpm.asp_model_database where model_id=?";
if (dbEngine.update(sql, modelPo.getId()) > 0) {
bpmDbCache.remove(modelPo.getId());
return R.success();
}

return R.error("删除失败");
}
}

+ 0
- 306
smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/model/AspModelCardService.java Voir le fichier

@@ -1,306 +0,0 @@
package cc.smtweb.system.bpm.web.design.model;

import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.annotation.SwBody;
import cc.smtweb.framework.core.annotation.SwParam;
import cc.smtweb.framework.core.annotation.SwService;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.sqlbuilder.InsertSqlBuilder;
import cc.smtweb.framework.core.db.sqlbuilder.SqlBuilder;
import cc.smtweb.framework.core.db.sqlbuilder.UpdateSqlBuilder;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.framework.core.util.DateUtil;
import cc.smtweb.system.bpm.core.ui.entity.BpmPage;
import cc.smtweb.system.bpm.engine.AbstractLoader;
import cc.smtweb.system.bpm.engine.entity.AspModelPO;
import cc.smtweb.system.bpm.engine.entity.AspModelTreeVO;
import cc.smtweb.system.bpm.engine.process.loader.FlowLoader;
import cc.smtweb.system.bpm.engine.ui.loader.IPageRouter;
import cc.smtweb.system.bpm.engine.ui.loader.TreePageRouter;
import cc.smtweb.system.bpm.engine.ui.loader.UiMobileLoader;
import cc.smtweb.system.bpm.engine.ui.loader.UiPcLoader;
import cc.smtweb.system.bpm.spring.cache.BpmFlowCache;
import cc.smtweb.system.bpm.spring.cache.BpmPageCache;
import cc.smtweb.system.bpm.spring.dao.DatasetConfigDao;
import cc.smtweb.system.bpm.util.ITreeDataLevelHandler;
import cc.smtweb.system.bpm.util.TreeDataUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

//@Api(tags = "数据模型")
@SwService
public class AspModelCardService {
@SwParam
private DbEngine dbEngine;

@SwParam
private BpmFlowCache bpmFlowCache;

@SwParam
private BpmPageCache bpmPageCache;

@SwParam
protected DatasetConfigDao datasetConfigDao;

// @ApiOperation(value = "读取数据模型数据")
public R load(@SwParam("id") long id, UserSession us) {
String sql = "select model_id, model_parent_id, model_mc_id, model_site_id, model_key, model_name, model_status, model_content, model_type, model_version, model_create_uid, model_update_uid, model_create_time, model_last_time from sw_bpm.asp_model" +
" where model_id=? and model_site_id=?";
AspModelPO po = dbEngine.queryEntity(sql, AspModelPO.class, id, us.getSiteId());
return R.success(po);
}

public R loadByKey(@SwParam("key") String key, @SwParam("type") String type, UserSession us) {
String sql = "select model_id, model_parent_id, model_mc_id, model_site_id, model_key, model_name, model_status, model_content, model_type, model_version, model_create_uid, model_update_uid, model_create_time, model_last_time from sw_bpm.asp_model" +
" where model_key=? and model_type=? and model_site_id=?";
AspModelPO po = dbEngine.queryEntity(sql, AspModelPO.class, key, type, us.getSiteId());
return R.success(po);
}

private boolean isNullId(Long id) {
return id == null || id == 0;
}

// @ApiOperation(value = "创建数据模型")
public R save(@SwParam("commit") boolean commit, @SwBody AspModelPO modelPo, UserSession us) {
String modelContent = modelPo.getModelContent();
if (StringUtils.isBlank(modelContent)) {
return R.error("内容不能为空");
}

if (commit) {
// 检查数据
AbstractLoader loader = null;
switch (modelPo.getModelType()) {
case AspModelPO.TYPE_FLOW:
loader = new FlowLoader();
break;
case AspModelPO.TYPE_UI_PC:
loader = new UiPcLoader(loadTree(modelPo.getModelId()));
break;
case AspModelPO.TYPE_UI_MOBILE:
loader = new UiMobileLoader(loadTree(modelPo.getModelId()));
break;
default:
return R.error("error model type: " + modelPo.getModelType());
}

Object page = loader.load(modelContent);

if (loader.getLastError() != null) {
return R.error(loader.getLastError()).put("modelErrors", loader.getErrors());
}

// 检测 modern + path
if (page instanceof BpmPage) {
// 检测和读取页面目录
BpmPage uiPage = (BpmPage)page;
uiPage.setId(modelPo.getModelId());
// uiPage.getForm().setKey(modelPo.getModelKey());
// uiPage.getForm().setTitle(modelPo.getModelName());
// uiPage.setParentId(modelPo.getModelParentId());

List<String> names = datasetConfigDao.loadPagePath(uiPage, true);
modelPo.setModelFullName(String.join(".", names));
}

modelPo.setModelStatus(0);
// 计算签名
modelPo.setModelContentSign(DigestUtils.sha256Hex(modelContent) + "," + modelContent.length());
} else {
modelPo.setModelStatus(-1);
}

modelPo.setModelLastTime(DateUtil.nowDateTimeLong());

// 保存数据到部署表和部署历史表
if (isNullId(modelPo.getModelId())) {
if (isNullId(modelPo.getModelMcId()) && isUiType(modelPo)) {
return R.error("页面缺少分类ID");
}

dbEngine.doTrans(() -> {
modelPo.setModelId(dbEngine.nextId());
modelPo.setModelVersion(commit ? 1 : 0);

InsertSqlBuilder sqlBuilder = SqlBuilder.createInsert("sw_bpm.asp_model");
sqlBuilder.add("model_id", modelPo.getModelId())
.add("model_parent_id", modelPo.getModelParentId())
.add("model_mc_id", modelPo.getModelMcId())
.add("model_site_id", us.getSiteId())
.add("model_key", modelPo.getModelKey())
.add("model_name", modelPo.getModelName())
.add("model_status", modelPo.getModelStatus())
.add("model_content", modelContent)
// .add("model_content_sign", contentSign)
.add("model_type", modelPo.getModelType())
.add("model_sub_type", modelPo.getModelSubType())
.add("model_version", modelPo.getModelVersion())
.add("model_create_time", modelPo.getModelLastTime())
.add("model_last_time", modelPo.getModelLastTime())
.add("model_create_uid", us.getUserId())
.add("model_update_uid", us.getUserId());
sqlBuilder.update(dbEngine);

if (commit) {
this.insertDeployLog(modelPo, us);
}

return true;
});

updateCache(modelPo.getModelId(), modelPo.getModelType());

return R.success(modelPo.getModelId());
} else {
if (commit) {
// 比较签名
AspModelPO old = dbEngine.queryEntity("select model_version, model_content_sign from sw_bpm.bpm_model where model_id=?", AspModelPO.class, modelPo.getModelId());
if (old != null) {
if (old.getModelContentSign() != null && old.getModelContentSign().equals(modelPo.getModelContentSign())) {
return R.success();
}

modelPo.setModelVersion(old.getModelVersion() + 1);
} else {
modelPo.setModelVersion(1);
}
}

// 更新数据
boolean r = dbEngine.doTrans(() -> {
// Timestamp now = new Timestamp(System.currentTimeMillis());
UpdateSqlBuilder sqlBuilder = SqlBuilder.createUpdate("sw_bpm.asp_model");
// .add("model_parent_id", modelPo.getModelParentId())
// .add("model_mc_id", modelPo.getModelMcId())
sqlBuilder.add("model_key", modelPo.getModelKey())
.add("model_name", modelPo.getModelName())
.add("model_content", modelContent)
// .add("model_content_sign", contentSign)
.add("model_status", modelPo.getModelStatus())
.add("model_update_uid", us.getUserId())
.add("model_last_time", modelPo.getModelLastTime())
.addWhere("model_id", modelPo.getModelId())
.addWhere("model_site_id", us.getSiteId());

if (commit) {
sqlBuilder.add("model_version", modelPo.getModelVersion());
}

int ret = sqlBuilder.update(dbEngine);

if (ret > 0) {
if (commit) {
this.insertDeployLog(modelPo, us);
}

return true;
}

return false;
});

if (r) {
updateCache(modelPo.getModelId(), modelPo.getModelType());
return R.success();
}

return R.error("保存失败,未找到记录");
}
}

private IPageRouter loadTree(Long pageId) {
ITreeDataLevelHandler<AspModelTreeVO> handler = AspModelTreeVO.createTreeHandler();

List<AspModelTreeVO> list = dbEngine.query("select model_id, model_parent_id, model_key, model_name from sw_bpm.asp_model where model_mc_id in" +
" (select model_mc_id from sw_bpm.asp_model where model_id=?)",
AspModelTreeVO.class, pageId);
AspModelTreeVO root = new AspModelTreeVO();
TreeDataUtil.buildLevelTree(root, list, handler);
return new TreePageRouter(root, null);
}

private boolean isUiType(@SwBody AspModelPO modelPo) {
return modelPo.getModelType() == AspModelPO.TYPE_UI_PC || modelPo.getModelType() == AspModelPO.TYPE_UI_MOBILE;
}

private void insertDeployLog(AspModelPO modelPo, UserSession us) {
// 部署
Long oldId = dbEngine.queryLong("select model_id from sw_bpm.bpm_model where model_id=?", modelPo.getModelId());

if (oldId != null) {
UpdateSqlBuilder sqlBuilder = SqlBuilder.createUpdate("sw_bpm.bpm_model");
sqlBuilder.add("model_full_name", modelPo.getModelFullName())
.add("model_name", modelPo.getModelName())
.add("model_status", 0)
.add("model_use_vue", modelPo.getModelUseVue())
.add("model_use_yaml", modelPo.getModelUseYaml())
.add("model_content", modelPo.getModelContent())
.add("model_content_sign", modelPo.getModelContentSign())
.add("model_version", modelPo.getModelVersion())
.add("model_last_time", modelPo.getModelLastTime())
.addWhere("model_id", modelPo.getModelId());
sqlBuilder.update(dbEngine);
} else {
InsertSqlBuilder sqlBuilder = SqlBuilder.createInsert("sw_bpm.bpm_model");
sqlBuilder.add("model_id", modelPo.getModelId())
.add("model_full_name", modelPo.getModelFullName())
.add("model_site_id", us.getSiteId())
.add("model_name", modelPo.getModelName())
.add("model_status", 0)
.add("model_content", modelPo.getModelContent())
.add("model_content_sign", modelPo.getModelContentSign())
.add("model_type", modelPo.getModelType())
.add("model_version", modelPo.getModelVersion())
.add("model_create_time", modelPo.getModelLastTime())
.add("model_last_time", modelPo.getModelLastTime());
sqlBuilder.update(dbEngine);
}

// 产生部署日志
Long dmId = dbEngine.nextId();
InsertSqlBuilder sqlBuilder = SqlBuilder.createInsert("sw_bpm.asp_model_deploy");
sqlBuilder.add("md_id", dmId)
.add("md_model_id", modelPo.getModelId())
.add("md_model_key", modelPo.getModelKey())
.add("md_name", modelPo.getModelName())
.add("md_status", modelPo.getModelStatus())
.add("md_content", modelPo.getModelContent())
.add("md_type", modelPo.getModelType())
.add("md_version", modelPo.getModelVersion())
.add("md_create_uid", us.getUserId());
sqlBuilder.update(dbEngine);
}

private void updateCache(Long modelId, byte modelType) {
switch (modelType) {
case AspModelPO.TYPE_FLOW:
bpmFlowCache.remove(modelId);
break;
case AspModelPO.TYPE_UI_PC:
case AspModelPO.TYPE_UI_MOBILE:
bpmPageCache.remove(modelId);
break;
default:
}
}

// @ApiOperation(value = "删除数据模型")
public R delete(@SwBody AspModelPO modelPo, UserSession us) {
String sql = "delete from sw_bpm.asp_model where model_id=? and model_site_id=?";
if (dbEngine.update(sql, modelPo.getModelId(), us.getSiteId()) > 0) {
updateCache(modelPo.getModelId(), modelPo.getModelType());
return R.success();
}

return R.error("删除失败");
}

// 修改子类型
public R saveSubType(@SwBody AspModelPO modelPo, UserSession us) {
dbEngine.update("update sw_bpm.asp_model set model_sub_type=? where model_id=? and model_site_id=?", modelPo.getModelSubType(), modelPo.getModelId(), us.getSiteId());
return R.success();
}
}

+ 0
- 54
smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/model/AspModelConfigService.java Voir le fichier

@@ -1,54 +0,0 @@
package cc.smtweb.system.bpm.web.design.model;

import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.annotation.SwParam;
import cc.smtweb.framework.core.annotation.SwService;
import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.system.bpm.spring.BpmConfigBean;
import cc.smtweb.system.bpm.util.YamlUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@SwService
@Deprecated
public class AspModelConfigService {

@SwParam
private BpmConfigBean bpmConfigBean;

public R load() {
R result = R.success().put("dataType", SwEnum.DataType.instance.values());
String configUiPath = bpmConfigBean.getConfigUiPath();

if (StringUtils.isNotBlank(configUiPath)) {
File file = new File(configUiPath);
if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null) {
Map<String, SwMap> config = new HashMap<>();
for (File yamlFile: files) {
String fileName = yamlFile.getName();
if (fileName.endsWith(".yaml") && fileName.startsWith("fx-")) {
SwMap meta = YamlUtil.readValue(yamlFile, SwMap.class);
config.put(fileName.substring(0, fileName.length() - 5), meta);
}
}

if (!config.isEmpty()) {
result.put("schema", config);
}
}
} else {
log.error("not find path:" + configUiPath);
}
}

return result;
}
}

+ 0
- 69
smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/model/AspModelExportService.java Voir le fichier

@@ -1,69 +0,0 @@
package cc.smtweb.system.bpm.web.design.model;

import cc.smtweb.framework.core.annotation.SwParam;
import cc.smtweb.framework.core.annotation.SwService;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.jdbc.IdGenerator;
import cc.smtweb.system.bpm.spring.cache.BpmFlowCache;
import cc.smtweb.system.bpm.spring.cache.BpmPageCache;

@SwService
public class AspModelExportService {
@SwParam
private DbEngine dbEngine;

@SwParam
private BpmFlowCache bpmFlowCache;

@SwParam
private BpmPageCache bpmPageCache;

@SwParam
private IdGenerator idGenerator;

/*// @ApiOperation(value = "读取数据模型数据")
public R mysql(@SwBody SwMap body, UserSession us) {
String sql = "select model_id, model_parent_id, model_mc_id, model_site_id, model_key, model_name, model_status, model_content, model_type, model_version, model_create_uid, model_update_uid, model_create_time, model_last_time from sw_bpm.asp_model" +
" where model_id=? and model_site_id=?";
AspModelPO po = dbEngine.queryEntity(sql, AspModelPO.class, body.readLong("modelId"), us.getSiteId());

DbLoader loader = new DbLoader(designConfig.getDataType());

ModelDatabase modelDatabase = loader.load(po.getModelContent());

if (loader.getLastError() != null) {
return R.error(loader.getLastError()).put("modelErrors", loader.getErrors());
}

// 创建数据库
HikariDataSource datasource = new HikariDataSource();

String host = body.readString("host", "127.0.0.1");
Integer port = body.readInt("port", 3306);
String dbName = body.readString("database", modelDatabase.getName());
modelDatabase.setName(dbName);

datasource.setJdbcUrl("jdbc:mysql://" + host + ":" + port + "/" + dbName + "?serverTimezone=UTC&allowMultiQueries=true&useSSL=false");
datasource.setDriverClassName("com.mysql.cj.jdbc.Driver");
datasource.setUsername(body.readString("username"));
datasource.setPassword(body.readString("password"));

try {
JdbcTemplate jdbcTemplate = new JdbcTemplate(datasource);
DbEngine dynDbEngine = new DbEngine(jdbcTemplate, idGenerator);

// 导入数据库结构
SqlImport sqlImport = new SqlImport(dynDbEngine);
ModelDatabase oldDb = sqlImport.importDb(dbName);

SqlExport sqlExport = new SqlExport();

// 导出数据库结构
sqlExport.export(modelDatabase, oldDb, dynDbEngine::update);
} finally {
datasource.close();
}

return R.success();
}*/
}

+ 0
- 25
smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/model/AspModelListService.java Voir le fichier

@@ -1,25 +0,0 @@
package cc.smtweb.system.bpm.web.design.model;

import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.annotation.SwParam;
import cc.smtweb.framework.core.annotation.SwService;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.system.bpm.engine.entity.AspModelPO;

import java.util.List;

// @Api(tags = "数据模型")
@SwService
public class AspModelListService {
@SwParam
private DbEngine dbEngine;

// @ApiOperation(value = "数据模型列表")
public R list(@SwParam("type") long type, UserSession us) {
String sql = "select model_id, model_mc_id, model_site_id, model_name, model_key, model_status, model_type, model_sub_type, model_version, model_create_uid, model_update_uid, model_create_time, model_last_time from sw_bpm.asp_model" +
" where model_site_id=? and model_type=?";
List<AspModelPO> list = dbEngine.query(sql, AspModelPO.class,us.getSiteId(), type);
return R.success(list);
}
}

+ 0
- 103
smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/model/AspModelTreeService.java Voir le fichier

@@ -1,103 +0,0 @@
package cc.smtweb.system.bpm.web.design.model;

import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.annotation.SwBody;
import cc.smtweb.framework.core.annotation.SwParam;
import cc.smtweb.framework.core.annotation.SwService;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.system.bpm.engine.entity.AspModelCatalogPO;
import cc.smtweb.system.bpm.engine.entity.AspModelPO;
import cc.smtweb.system.bpm.engine.entity.AspModelTreeVO;
import cc.smtweb.system.bpm.util.TreeDataUtil;
import cc.smtweb.system.bpm.web.design.model.entity.TreeMoveVO;

import java.util.ArrayList;
import java.util.List;

@SwService
public class AspModelTreeService {
@SwParam
private DbEngine dbEngine;

public R treeAll(@SwParam("mcId") long mcId, @SwParam("modelType") long modelType, UserSession us) {
return R.success(loadTreeAll(mcId, modelType, us));
}

private List<AspModelTreeVO> loadTreeAll(@SwParam("mcId") long mcId, @SwParam("modelType") long modelType, UserSession us) {
String sql = "select model_id, model_parent_id, model_key, model_name, model_status, model_type, model_sub_type, model_version, model_create_time, model_last_time from sw_bpm.asp_model" +
" where model_mc_id=? and model_type=? and model_site_id=? order by model_order, model_id";
List<AspModelTreeVO> list = dbEngine.query(sql, AspModelTreeVO.class, mcId, modelType, us.getSiteId());

AspModelTreeVO root = new AspModelTreeVO();
root.setModelName("项目");

return TreeDataUtil.buildTree(root, list, AspModelTreeVO.createTreeHandler());
}

public R menu(@SwParam("mcId") long mcId, @SwParam("modelType") long modelType, UserSession us) {
List<AspModelTreeVO> tree = loadTreeAll(mcId, modelType, us);

// 强制只显示2级
if (tree != null) {
for (AspModelTreeVO item : tree) {
List<AspModelTreeVO> children = item.getChildren();

if (children != null) {
for (AspModelTreeVO child : item.getChildren()) {
child.setChildren(null);
}
}
}
}

return R.success(tree);
}

/** 动态Tree数据 */
public R tree(@SwParam("type") long type, @SwParam("catalog") long catalog, @SwParam("parentId") Long parentId, UserSession us) {
R result = null;
if (parentId == null) {
String sql = "select model_id, model_mc_id, model_key, model_name, model_status, model_version, model_create_uid, model_update_uid, model_create_time, model_last_time from sw_bpm.asp_model" +
" where model_mc_id=? and model_parent_id is null and model_site_id=? and model_type=? order by model_order, model_id";
List<AspModelPO> list = dbEngine.query(sql, AspModelPO.class, catalog, us.getSiteId(), type);
result = R.success(list);

sql = "select mc_id, mc_parent_id, mc_code, mc_site_id, mc_name, mc_create_time, mc_last_time from sw_bpm.asp_model_catalog" +
" where mc_id=? and mc_site_id=?";
AspModelCatalogPO po = dbEngine.queryEntity(sql, AspModelCatalogPO.class, catalog, us.getSiteId());
result.put("catalog", po);
} else {
String sql = "select model_id, model_mc_id, model_key, model_name, model_status, model_version, model_create_uid, model_update_uid, model_create_time, model_last_time from sw_bpm.asp_model" +
" where model_mc_id=? and model_parent_id=? and model_site_id=? and model_type=? order by model_order, model_id";
List<AspModelPO> list = dbEngine.query(sql, AspModelPO.class, catalog, parentId, us.getSiteId(), type);
result = R.success(list);

AspModelPO parent = dbEngine.queryEntity("select model_id, model_mc_id, model_parent_id, model_key, model_name, model_status, model_version, model_create_time, model_last_time from sw_bpm.asp_model" +
" where model_id=?",AspModelPO.class, parentId);

result.put("parent", parent);
}

return result;
}

public R move(@SwBody TreeMoveVO vo, UserSession us) {
if (vo.getId() != null && vo.getOrders() != null) {
List<Object[]> params = new ArrayList<>();

int index = 0;
for (Long order: vo.getOrders()) {
params.add(new Object[]{vo.getParentId(), ++index, order});
}

int[] ret = dbEngine.batchUpdate("update sw_bpm.asp_model set model_parent_id=?, model_order=? where model_id=?", params);

if (ret.length > 0) {
return R.success();
}
}

return R.error();
}
}

+ 0
- 10
smtweb-system/sw-system-bpm/src/main/java/cc/smtweb/system/bpm/web/design/model/entity/TreeMoveVO.java Voir le fichier

@@ -1,10 +0,0 @@
package cc.smtweb.system.bpm.web.design.model.entity;

import lombok.Data;

@Data
public class TreeMoveVO {
private Long id;
private Long parentId;
private Long[] orders;
}

Chargement…
Annuler
Enregistrer