@@ -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============="); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} | |||
@@ -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, "视图"); | |||
} | |||
/** | |||
@@ -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; | |||
@@ -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() : ""; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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; | |||
} |
@@ -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(); | |||
@@ -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("删除失败"); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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(); | |||
}*/ | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
} |