|
|
@@ -1,310 +0,0 @@ |
|
|
|
package cc.smtweb.system.bpm.core.ui.builder; |
|
|
|
|
|
|
|
import cc.smtweb.framework.core.common.SwMap; |
|
|
|
import cc.smtweb.framework.core.db.DbEngine; |
|
|
|
import cc.smtweb.framework.core.db.sqlbuilder.AbstractUpdateSqlBuilder; |
|
|
|
import cc.smtweb.framework.core.db.sqlbuilder.DeleteSqlBuilder; |
|
|
|
import cc.smtweb.framework.core.db.sqlbuilder.InsertSqlBuilder; |
|
|
|
import cc.smtweb.framework.core.db.sqlbuilder.SqlBuilder; |
|
|
|
import cc.smtweb.framework.core.session.UserSession; |
|
|
|
import cc.smtweb.framework.core.util.DateUtil; |
|
|
|
import cc.smtweb.system.bpm.core.exception.BpmFieldError; |
|
|
|
import cc.smtweb.system.bpm.core.exception.BpmValidException; |
|
|
|
import cc.smtweb.system.bpm.core.ui.IParamConst; |
|
|
|
import cc.smtweb.system.bpm.core.ui.entity.dataset.BpmDataset; |
|
|
|
import cc.smtweb.system.bpm.core.ui.entity.dataset.BpmField; |
|
|
|
import cc.smtweb.system.bpm.core.ui.entity.dataset.BpmFieldLookup; |
|
|
|
import cc.smtweb.system.bpm.engine.ui.entity.consts.UiEnum; |
|
|
|
import lombok.Getter; |
|
|
|
import org.apache.commons.lang3.StringUtils; |
|
|
|
|
|
|
|
import java.util.*; |
|
|
|
import java.util.regex.Pattern; |
|
|
|
|
|
|
|
/** |
|
|
|
* 卡片界面保存操作的SQL构建 |
|
|
|
* @author xkliu |
|
|
|
*/ |
|
|
|
public class CardDataBuilder { |
|
|
|
private DbEngine dbEngine; |
|
|
|
|
|
|
|
@Getter |
|
|
|
private long masterId; |
|
|
|
|
|
|
|
private Long masterParentId; |
|
|
|
|
|
|
|
@Getter |
|
|
|
private boolean instert; |
|
|
|
private UserSession userSession; |
|
|
|
private Long now; |
|
|
|
private CardTreeDataBuilder cardTreeDataBuilder; |
|
|
|
|
|
|
|
private List<AbstractUpdateSqlBuilder> sqlBuilders = new ArrayList<>(); |
|
|
|
private BpmDataset masterDataset; |
|
|
|
|
|
|
|
/* 字段验证错误列表 */ |
|
|
|
@Getter |
|
|
|
private List<BpmFieldError> fieldErrors; |
|
|
|
|
|
|
|
public CardDataBuilder(DbEngine dbEngine, long dataId, Long parentDataId, UserSession userSession) { |
|
|
|
this.dbEngine = dbEngine; |
|
|
|
this.masterId = dataId; |
|
|
|
this.masterParentId = parentDataId; |
|
|
|
this.instert = dataId == 0; |
|
|
|
this.userSession = userSession; |
|
|
|
} |
|
|
|
|
|
|
|
public void build(BpmDataset dataset, SwMap body, UserSession us) { |
|
|
|
masterDataset = dataset; |
|
|
|
build(dataset, body, masterId, masterParentId); |
|
|
|
List<BpmDataset> slaves = dataset.getOneToOneDataset(); |
|
|
|
if (slaves != null) { |
|
|
|
for (BpmDataset slave : slaves) { |
|
|
|
long slaveId = body.readLong(slave.getIdField().getName(), 0L); |
|
|
|
build(slave, body, slaveId, null); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void build(BpmDataset dataset, SwMap body, long dataId, Long parentDataId) { |
|
|
|
AbstractUpdateSqlBuilder sqlBuilder; |
|
|
|
if (dataId == 0) { |
|
|
|
// insert |
|
|
|
sqlBuilder = SqlBuilder.createInsert(dataset.getDatabase(), dataset.getTable()); |
|
|
|
|
|
|
|
if (masterId == 0) { |
|
|
|
masterId = dbEngine.nextId(); |
|
|
|
if (dataset.getIdField() != null) { |
|
|
|
body.put(dataset.getIdField().getName(), masterId); |
|
|
|
} |
|
|
|
} |
|
|
|
// remove: 放到后面统一处理 |
|
|
|
// sqlBuilder.add(dataset.getIdFieldName(), masterId); |
|
|
|
|
|
|
|
// if (parentDataId != null && parentDataId > 0) { |
|
|
|
// BpmField parentIdField = dataset.findFieldByRefType(UiEnum.FieldRefType.PARENT_ID); |
|
|
|
// if (parentIdField != null) { |
|
|
|
// sqlBuilder.add(parentIdField.getFieldName(), parentDataId); |
|
|
|
// } |
|
|
|
// } |
|
|
|
} else { |
|
|
|
// update |
|
|
|
sqlBuilder = SqlBuilder.createUpdate(dataset.getDatabase(), dataset.getTable()); |
|
|
|
sqlBuilder.addWhere(dataset.readIdFieldName(), masterId); |
|
|
|
} |
|
|
|
|
|
|
|
cardTreeDataBuilder = null; |
|
|
|
|
|
|
|
for (Map.Entry<String, BpmField> entry: dataset.getFields().entrySet()) { |
|
|
|
BpmField bpmField = entry.getValue(); |
|
|
|
|
|
|
|
String fieldName = bpmField.getFieldName(); |
|
|
|
// 只读和虚拟控件不进行保存 |
|
|
|
if (!bpmField.isReadonly() && StringUtils.isNotBlank(fieldName)) { |
|
|
|
if (dataset.getIdField() == bpmField) { |
|
|
|
// id字段新增才需要设置值 |
|
|
|
if (dataId == 0) { |
|
|
|
sqlBuilder.add(fieldName, masterId); |
|
|
|
} |
|
|
|
} else { |
|
|
|
Object fieldValue = body.get(bpmField.getName()); |
|
|
|
|
|
|
|
validField(bpmField, fieldValue); |
|
|
|
|
|
|
|
if (bpmField.isLookupManyToMay()) { |
|
|
|
// 中间表数据修改 |
|
|
|
buildManyToMany(dataset, bpmField, (String) fieldValue); |
|
|
|
} else { |
|
|
|
// 处理String空串为NULL值 |
|
|
|
if (fieldValue != null) { |
|
|
|
if (fieldValue instanceof String && StringUtils.isBlank((String) fieldValue)) { |
|
|
|
fieldValue = null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 处理默认值字段和计算字段 |
|
|
|
switch (bpmField.getRefType()) { |
|
|
|
case UiEnum.FieldRefType.SITE_ID: |
|
|
|
if (dataId == 0) { |
|
|
|
// 新增才保存数据 |
|
|
|
sqlBuilder.add(fieldName, userSession.getSiteId()); |
|
|
|
} |
|
|
|
break; |
|
|
|
case UiEnum.FieldRefType.CREATE_TIME: |
|
|
|
if (dataId == 0) { |
|
|
|
// 新增才保存数据 |
|
|
|
sqlBuilder.add(fieldName, loadLastTime()); |
|
|
|
} |
|
|
|
break; |
|
|
|
case UiEnum.FieldRefType.LAST_TIME: |
|
|
|
sqlBuilder.add(fieldName, loadLastTime()); |
|
|
|
break; |
|
|
|
case UiEnum.FieldRefType.PARENT_ID: |
|
|
|
sqlBuilder.add(fieldName, fieldValue); |
|
|
|
updateCardTreeData(UiEnum.FieldRefType.PARENT_ID, fieldName, fieldValue); |
|
|
|
break; |
|
|
|
case UiEnum.FieldRefType.PARENT_ID_LIST: |
|
|
|
updateCardTreeData(UiEnum.FieldRefType.PARENT_ID_LIST, fieldName, fieldValue); |
|
|
|
break; |
|
|
|
case UiEnum.FieldRefType.TREE_LEVEL: |
|
|
|
updateCardTreeData(UiEnum.FieldRefType.TREE_LEVEL, fieldName, fieldValue); |
|
|
|
break; |
|
|
|
default: |
|
|
|
sqlBuilder.add(fieldName, fieldValue); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
saveCardTreeData(dataset, dataId, sqlBuilder); |
|
|
|
|
|
|
|
sqlBuilders.add(sqlBuilder); |
|
|
|
} |
|
|
|
|
|
|
|
private void updateCardTreeData(int type, String fieldName, Object fieldValue) { |
|
|
|
if (cardTreeDataBuilder == null) { |
|
|
|
cardTreeDataBuilder = new CardTreeDataBuilder(dbEngine); |
|
|
|
} |
|
|
|
|
|
|
|
cardTreeDataBuilder.add(type, fieldName, fieldValue); |
|
|
|
} |
|
|
|
|
|
|
|
private void saveCardTreeData(BpmDataset dataset, long dataId, AbstractUpdateSqlBuilder sqlBuilder) { |
|
|
|
if (cardTreeDataBuilder != null) { |
|
|
|
AbstractUpdateSqlBuilder newSqlBuilder = cardTreeDataBuilder.save(dataset, dataId, sqlBuilder); |
|
|
|
cardTreeDataBuilder = null; |
|
|
|
|
|
|
|
if (newSqlBuilder != null) { |
|
|
|
sqlBuilders.add(newSqlBuilder); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private Long loadLastTime() { |
|
|
|
if (now == null) { |
|
|
|
now = DateUtil.nowDateTimeLong(); |
|
|
|
} |
|
|
|
|
|
|
|
return now; |
|
|
|
} |
|
|
|
|
|
|
|
private void validField(BpmField bpmField, Object fieldValue) { |
|
|
|
if (bpmField.isRequired()) { |
|
|
|
if (fieldValue == null || StringUtils.isBlank(fieldValue.toString())) { |
|
|
|
// 对应前端的验证错误对象 ValidateError(message, field) |
|
|
|
addFieldError(bpmField.getName(), bpmField.getLabel() + "必须填写"); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (fieldValue != null && StringUtils.isNotBlank(bpmField.getValidPatten())) { |
|
|
|
if (!Pattern.matches(bpmField.getValidPatten(), fieldValue.toString())) { |
|
|
|
if (StringUtils.isNotBlank(bpmField.getValidMessage())) { |
|
|
|
addFieldError(bpmField.getName(), bpmField.getValidMessage()); |
|
|
|
} else { |
|
|
|
addFieldError(bpmField.getName(), bpmField.getLabel() + "格式不正确"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void addFieldError(String field, String message) { |
|
|
|
if (this.fieldErrors == null) { |
|
|
|
this.fieldErrors = new ArrayList<>(); |
|
|
|
} |
|
|
|
|
|
|
|
this.fieldErrors.add(new BpmFieldError(field, message)); |
|
|
|
} |
|
|
|
|
|
|
|
private void buildManyToMany(BpmDataset dataset, BpmField bpmField, String newValue) { |
|
|
|
BpmFieldLookup lookup = (BpmFieldLookup) bpmField.getLookup(); |
|
|
|
|
|
|
|
// 读取旧记录 |
|
|
|
Set<String> oldIds = dbEngine.queryStringSet("SELECT " + lookup.getMiddleValueField() + " FROM " + dataset.getDatabase() + "." + lookup.getMiddleTable() |
|
|
|
+ " WHERE " + lookup.getMiddleKeyField() + "=?", masterId); |
|
|
|
Set<String> newIds = toIdSet(newValue); |
|
|
|
|
|
|
|
for (String newId: newIds) { |
|
|
|
if (!oldIds.remove(newId)) { |
|
|
|
// insert |
|
|
|
InsertSqlBuilder sqlBuilder = SqlBuilder.createInsert(dataset.getDatabase(), lookup.getMiddleTable()); |
|
|
|
sqlBuilder.add(lookup.getMiddleIdField(), dbEngine.nextId()); |
|
|
|
sqlBuilder.add(lookup.getMiddleKeyField(), masterId); |
|
|
|
sqlBuilder.add(lookup.getMiddleValueField(), newId); |
|
|
|
sqlBuilders.add(sqlBuilder); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
for (String oldId: oldIds) { |
|
|
|
// delete |
|
|
|
DeleteSqlBuilder sqlBuilder = SqlBuilder.createDelete(dataset.getDatabase(), lookup.getMiddleTable()); |
|
|
|
sqlBuilder.addWhere(lookup.getMiddleKeyField(), masterId); |
|
|
|
sqlBuilder.addWhere(lookup.getMiddleValueField(), oldId); |
|
|
|
sqlBuilders.add(sqlBuilder); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private Set<String> toIdSet(String str) { |
|
|
|
Set<String> result = new HashSet<>(); |
|
|
|
|
|
|
|
if (StringUtils.isNotBlank(str)) { |
|
|
|
Collections.addAll(result, str.split(",")); |
|
|
|
} |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
public long update() { |
|
|
|
if (sqlBuilders.size() > 1) { |
|
|
|
dbEngine.doTrans(() -> { |
|
|
|
for (AbstractUpdateSqlBuilder sqlBuilder : sqlBuilders) { |
|
|
|
sqlBuilder.update(dbEngine); |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
}); |
|
|
|
} else { |
|
|
|
for (AbstractUpdateSqlBuilder sqlBuilder : sqlBuilders) { |
|
|
|
sqlBuilder.update(dbEngine); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return masterId; |
|
|
|
} |
|
|
|
|
|
|
|
public SwMap update(SwMap data) { |
|
|
|
if (data == null) { |
|
|
|
data = new SwMap(); |
|
|
|
} |
|
|
|
|
|
|
|
for (AbstractUpdateSqlBuilder sqlBuilder : sqlBuilders) { |
|
|
|
sqlBuilder.updateMap(data); |
|
|
|
} |
|
|
|
|
|
|
|
return data; |
|
|
|
} |
|
|
|
|
|
|
|
public String getTableName() { |
|
|
|
return masterDataset.fullName(); |
|
|
|
} |
|
|
|
|
|
|
|
public boolean hasFieldErrors() { |
|
|
|
return this.fieldErrors != null; |
|
|
|
} |
|
|
|
|
|
|
|
public static CardDataBuilder create(DbEngine dbEngine, BpmDataset dataset, SwMap body, UserSession us) { |
|
|
|
long dataId = body.readLong(IParamConst.PARAM_ID, 0L); |
|
|
|
Long parentDataId = body.readLong(IParamConst.PARAM_PARENT_ID); |
|
|
|
CardDataBuilder cardDataBuilder = new CardDataBuilder(dbEngine, dataId, parentDataId, us); |
|
|
|
|
|
|
|
cardDataBuilder.build(dataset, body, us); |
|
|
|
|
|
|
|
if (cardDataBuilder.hasFieldErrors()) { |
|
|
|
throw new BpmValidException(cardDataBuilder.getFieldErrors()); |
|
|
|
} |
|
|
|
|
|
|
|
return cardDataBuilder; |
|
|
|
} |
|
|
|
} |