Add executable business blueprint workflow
This commit is contained in:
@@ -280,6 +280,9 @@ public interface I${ClassName}Service
|
||||
(910108, 9101, 'serviceImpl.java.vm', NULL, 'serviceImpl.java.vm',
|
||||
'package ${packageName}.service.impl;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Resource;
|
||||
@@ -374,6 +377,24 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service
|
||||
#foreach($field in $action.requestFields)
|
||||
requireBusinessParam(params, "${field}");
|
||||
#end
|
||||
#end
|
||||
#if($action.ruleChecks)
|
||||
#foreach($rule in $action.ruleChecks)
|
||||
#set($conditionFields = $rule.conditionFields)
|
||||
#if($rule.type == "EXISTS")
|
||||
assertExists(params, "${rule.targetTable}", new String[] {#foreach($field in $conditionFields)"${field}"#if($foreach.hasNext), #end#end}, "${rule.message}");
|
||||
#elseif($rule.type == "NOT_EXISTS")
|
||||
assertNotExists(params, "${rule.targetTable}", new String[] {#foreach($field in $conditionFields)"${field}"#if($foreach.hasNext), #end#end}, "${rule.message}");
|
||||
#elseif($rule.type == "FIELD_EQUALS")
|
||||
assertFieldEquals(params, "${rule.targetTable}", "${rule.targetField}", "${rule.expectedValue}", new String[] {#foreach($field in $conditionFields)"${field}"#if($foreach.hasNext), #end#end}, "${rule.message}");
|
||||
#elseif($rule.type == "FIELD_NOT_EQUALS")
|
||||
assertFieldNotEquals(params, "${rule.targetTable}", "${rule.targetField}", "${rule.expectedValue}", new String[] {#foreach($field in $conditionFields)"${field}"#if($foreach.hasNext), #end#end}, "${rule.message}");
|
||||
#elseif($rule.type == "FIELD_IN")
|
||||
assertFieldIn(params, "${rule.targetTable}", "${rule.targetField}", new String[] {#foreach($value in $rule.expectedValues)"${value}"#if($foreach.hasNext), #end#end}, new String[] {#foreach($field in $conditionFields)"${field}"#if($foreach.hasNext), #end#end}, "${rule.message}");
|
||||
#elseif($rule.type == "NUMBER_GTE")
|
||||
assertNumberGte(params, "${rule.targetTable}", "${rule.targetField}", "${rule.compareValue}", new String[] {#foreach($field in $conditionFields)"${field}"#if($foreach.hasNext), #end#end}, "${rule.message}");
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
int rows = 0;
|
||||
#if($action.effects)
|
||||
@@ -384,6 +405,30 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service
|
||||
#set($conditionFields = $action.requestFields)
|
||||
#end
|
||||
rows += executeUpdateFieldEffect(params, "${effect.targetTable}", "${effect.targetField}", "${effect.value}", new String[] {#foreach($field in $conditionFields)"${field}"#if($foreach.hasNext), #end#end});
|
||||
#elseif($effect.type == "INSERT_ROW")
|
||||
#set($effectIndex = $foreach.index)
|
||||
Map<String, Object> insertValues${effectIndex} = new java.util.LinkedHashMap<String, Object>();
|
||||
#foreach($entry in $effect.values.entrySet())
|
||||
insertValues${effectIndex}.put("${entry.key}", resolveBusinessValue(params, "${entry.value}"));
|
||||
#end
|
||||
rows += insertRow("${effect.targetTable}", insertValues${effectIndex});
|
||||
#elseif($effect.type == "UPDATE_FIELDS")
|
||||
#set($conditionFields = $effect.conditionFields)
|
||||
#set($effectIndex = $foreach.index)
|
||||
Map<String, Object> updateValues${effectIndex} = new java.util.LinkedHashMap<String, Object>();
|
||||
#foreach($entry in $effect.values.entrySet())
|
||||
updateValues${effectIndex}.put("${entry.key}", resolveBusinessValue(params, "${entry.value}"));
|
||||
#end
|
||||
rows += updateFields(params, "${effect.targetTable}", updateValues${effectIndex}, new String[] {#foreach($field in $conditionFields)"${field}"#if($foreach.hasNext), #end#end});
|
||||
#elseif($effect.type == "SET_STATUS")
|
||||
#set($conditionFields = $effect.conditionFields)
|
||||
rows += setStatus(params, "${effect.targetTable}", "${effect.targetField}", resolveBusinessValue(params, "${effect.value}"), new String[] {#foreach($field in $conditionFields)"${field}"#if($foreach.hasNext), #end#end});
|
||||
#elseif($effect.type == "INCREASE_NUMBER")
|
||||
#set($conditionFields = $effect.conditionFields)
|
||||
rows += increaseNumberField(params, "${effect.targetTable}", "${effect.targetField}", "${effect.amount}", new String[] {#foreach($field in $conditionFields)"${field}"#if($foreach.hasNext), #end#end});
|
||||
#elseif($effect.type == "DECREASE_NUMBER")
|
||||
#set($conditionFields = $effect.conditionFields)
|
||||
rows += decreaseNumberField(params, "${effect.targetTable}", "${effect.targetField}", "${effect.amount}", "${effect.minValue}", new String[] {#foreach($field in $conditionFields)"${field}"#if($foreach.hasNext), #end#end}, "${effect.message}");
|
||||
#else
|
||||
// Unsupported effect type ${effect.type}: ${effect.description}
|
||||
#end
|
||||
@@ -400,6 +445,143 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service
|
||||
}
|
||||
}
|
||||
|
||||
private void assertExists(Map<String, Object> params, String tableName, String[] conditionFields, String message)
|
||||
{
|
||||
if (countRows(params, tableName, conditionFields) <= 0) {
|
||||
throw new ServiceException(defaultMessage(message, "Business record does not exist"));
|
||||
}
|
||||
}
|
||||
|
||||
private void assertNotExists(Map<String, Object> params, String tableName, String[] conditionFields, String message)
|
||||
{
|
||||
if (countRows(params, tableName, conditionFields) > 0) {
|
||||
throw new ServiceException(defaultMessage(message, "Business record already exists"));
|
||||
}
|
||||
}
|
||||
|
||||
private void assertFieldEquals(Map<String, Object> params, String tableName, String targetField, String expectedValue,
|
||||
String[] conditionFields, String message)
|
||||
{
|
||||
Object value = querySingleField(params, tableName, targetField, conditionFields);
|
||||
if (value == null || !String.valueOf(resolveBusinessValue(params, expectedValue)).equals(String.valueOf(value))) {
|
||||
throw new ServiceException(defaultMessage(message, "Business rule check failed"));
|
||||
}
|
||||
}
|
||||
|
||||
private void assertFieldNotEquals(Map<String, Object> params, String tableName, String targetField, String expectedValue,
|
||||
String[] conditionFields, String message)
|
||||
{
|
||||
Object value = querySingleField(params, tableName, targetField, conditionFields);
|
||||
if (value != null && String.valueOf(resolveBusinessValue(params, expectedValue)).equals(String.valueOf(value))) {
|
||||
throw new ServiceException(defaultMessage(message, "Business rule check failed"));
|
||||
}
|
||||
}
|
||||
|
||||
private void assertFieldIn(Map<String, Object> params, String tableName, String targetField, String[] expectedValues,
|
||||
String[] conditionFields, String message)
|
||||
{
|
||||
Object value = querySingleField(params, tableName, targetField, conditionFields);
|
||||
String current = value == null ? "" : String.valueOf(value);
|
||||
for (String expectedValue : expectedValues) {
|
||||
if (String.valueOf(resolveBusinessValue(params, expectedValue)).equals(current)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new ServiceException(defaultMessage(message, "Business rule check failed"));
|
||||
}
|
||||
|
||||
private void assertNumberGte(Map<String, Object> params, String tableName, String targetField, String compareValue,
|
||||
String[] conditionFields, String message)
|
||||
{
|
||||
Object value = querySingleField(params, tableName, targetField, conditionFields);
|
||||
BigDecimal current = toBigDecimal(value, "Business numeric value is invalid");
|
||||
BigDecimal expected = resolveBusinessNumber(params, compareValue);
|
||||
if (current.compareTo(expected) < 0) {
|
||||
throw new ServiceException(defaultMessage(message, "Business numeric rule check failed"));
|
||||
}
|
||||
}
|
||||
|
||||
private int insertRow(String tableName, Map<String, Object> values)
|
||||
{
|
||||
String safeTableName = requireSafeIdentifier(tableName, "Business effect target table is invalid");
|
||||
if (values == null || values.isEmpty()) {
|
||||
throw new ServiceException("Business insert values cannot be empty");
|
||||
}
|
||||
StringBuilder fields = new StringBuilder();
|
||||
StringBuilder placeholders = new StringBuilder();
|
||||
List<Object> args = new ArrayList<Object>();
|
||||
for (Map.Entry<String, Object> entry : values.entrySet()) {
|
||||
if (fields.length() > 0) {
|
||||
fields.append(", ");
|
||||
placeholders.append(", ");
|
||||
}
|
||||
fields.append(requireSafeIdentifier(entry.getKey(), "Business effect value field is invalid"));
|
||||
placeholders.append("?");
|
||||
args.add(entry.getValue());
|
||||
}
|
||||
return jdbcTemplate.update("insert into " + safeTableName + " (" + fields + ") values (" + placeholders + ")", args.toArray());
|
||||
}
|
||||
|
||||
private int updateFields(Map<String, Object> params, String tableName, Map<String, Object> values, String[] conditionFields)
|
||||
{
|
||||
String safeTableName = requireSafeIdentifier(tableName, "Business effect target table is invalid");
|
||||
if (values == null || values.isEmpty()) {
|
||||
throw new ServiceException("Business update values cannot be empty");
|
||||
}
|
||||
StringBuilder sets = new StringBuilder();
|
||||
List<Object> args = new ArrayList<Object>();
|
||||
for (Map.Entry<String, Object> entry : values.entrySet()) {
|
||||
if (sets.length() > 0) {
|
||||
sets.append(", ");
|
||||
}
|
||||
sets.append(requireSafeIdentifier(entry.getKey(), "Business effect value field is invalid")).append(" = ?");
|
||||
args.add(entry.getValue());
|
||||
}
|
||||
String whereClause = buildWhereClause(params, conditionFields);
|
||||
appendConditionValues(args, params, conditionFields);
|
||||
return jdbcTemplate.update("update " + safeTableName + " set " + sets + " where " + whereClause, args.toArray());
|
||||
}
|
||||
|
||||
private int setStatus(Map<String, Object> params, String tableName, String targetField, Object value, String[] conditionFields)
|
||||
{
|
||||
Map<String, Object> values = new java.util.LinkedHashMap<String, Object>();
|
||||
values.put(targetField, value);
|
||||
return updateFields(params, tableName, values, conditionFields);
|
||||
}
|
||||
|
||||
private int increaseNumberField(Map<String, Object> params, String tableName, String targetField, String amountExpression,
|
||||
String[] conditionFields)
|
||||
{
|
||||
String safeTableName = requireSafeIdentifier(tableName, "Business effect target table is invalid");
|
||||
String safeTargetField = requireSafeIdentifier(targetField, "Business effect target field is invalid");
|
||||
BigDecimal amount = resolveBusinessNumber(params, amountExpression);
|
||||
String whereClause = buildWhereClause(params, conditionFields);
|
||||
List<Object> args = new ArrayList<Object>();
|
||||
args.add(amount);
|
||||
appendConditionValues(args, params, conditionFields);
|
||||
return jdbcTemplate.update("update " + safeTableName + " set " + safeTargetField + " = " + safeTargetField + " + ? where " + whereClause, args.toArray());
|
||||
}
|
||||
|
||||
private int decreaseNumberField(Map<String, Object> params, String tableName, String targetField, String amountExpression,
|
||||
String minValueExpression, String[] conditionFields, String message)
|
||||
{
|
||||
String safeTableName = requireSafeIdentifier(tableName, "Business effect target table is invalid");
|
||||
String safeTargetField = requireSafeIdentifier(targetField, "Business effect target field is invalid");
|
||||
BigDecimal amount = resolveBusinessNumber(params, amountExpression);
|
||||
BigDecimal minValue = resolveBusinessNumber(params, minValueExpression == null || minValueExpression.length() == 0 ? "0" : minValueExpression);
|
||||
String whereClause = buildWhereClause(params, conditionFields);
|
||||
List<Object> args = new ArrayList<Object>();
|
||||
args.add(amount);
|
||||
appendConditionValues(args, params, conditionFields);
|
||||
args.add(amount);
|
||||
args.add(minValue);
|
||||
int rows = jdbcTemplate.update("update " + safeTableName + " set " + safeTargetField + " = " + safeTargetField + " - ? where " + whereClause + " and " + safeTargetField + " - ? >= ?", args.toArray());
|
||||
if (rows == 0) {
|
||||
throw new ServiceException(defaultMessage(message, "Business numeric decrease failed"));
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
private int executeUpdateFieldEffect(Map<String, Object> params, String tableName, String targetField,
|
||||
String valueExpression, String[] conditionFields)
|
||||
{
|
||||
@@ -438,6 +620,68 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service
|
||||
return values;
|
||||
}
|
||||
|
||||
private int countRows(Map<String, Object> params, String tableName, String[] conditionFields)
|
||||
{
|
||||
String safeTableName = requireSafeIdentifier(tableName, "Business rule target table is invalid");
|
||||
String whereClause = buildWhereClause(params, conditionFields);
|
||||
Integer count = jdbcTemplate.queryForObject("select count(1) from " + safeTableName + " where " + whereClause, conditionValues(params, conditionFields), Integer.class);
|
||||
return count == null ? 0 : count.intValue();
|
||||
}
|
||||
|
||||
private Object querySingleField(Map<String, Object> params, String tableName, String targetField, String[] conditionFields)
|
||||
{
|
||||
String safeTableName = requireSafeIdentifier(tableName, "Business rule target table is invalid");
|
||||
String safeTargetField = requireSafeIdentifier(targetField, "Business rule target field is invalid");
|
||||
String whereClause = buildWhereClause(params, conditionFields);
|
||||
List<Map<String, Object>> rows = jdbcTemplate.queryForList("select " + safeTargetField + " from " + safeTableName + " where " + whereClause + " limit 1", conditionValues(params, conditionFields));
|
||||
if (rows.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return rows.get(0).get(safeTargetField);
|
||||
}
|
||||
|
||||
private void appendConditionValues(List<Object> args, Map<String, Object> params, String[] conditionFields)
|
||||
{
|
||||
for (Object value : conditionValues(params, conditionFields)) {
|
||||
args.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
private Object resolveBusinessValue(Map<String, Object> params, String valueExpression)
|
||||
{
|
||||
if (valueExpression == null) {
|
||||
return null;
|
||||
}
|
||||
if ("#[[${now}]]#".equals(valueExpression)) {
|
||||
return new Date();
|
||||
}
|
||||
if (valueExpression.startsWith("#[[${param.]]#") && valueExpression.endsWith("}")) {
|
||||
String field = valueExpression.substring(8, valueExpression.length() - 1);
|
||||
requireBusinessParam(params, field);
|
||||
return params.get(field);
|
||||
}
|
||||
return valueExpression;
|
||||
}
|
||||
|
||||
private BigDecimal resolveBusinessNumber(Map<String, Object> params, String valueExpression)
|
||||
{
|
||||
return toBigDecimal(resolveBusinessValue(params, valueExpression), "Business numeric expression is invalid");
|
||||
}
|
||||
|
||||
private BigDecimal toBigDecimal(Object value, String message)
|
||||
{
|
||||
try {
|
||||
return new BigDecimal(String.valueOf(value));
|
||||
} catch (RuntimeException e) {
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private String defaultMessage(String message, String fallback)
|
||||
{
|
||||
return message == null || message.length() == 0 ? fallback : message;
|
||||
}
|
||||
|
||||
private String requireSafeIdentifier(String value, String message)
|
||||
{
|
||||
if (value == null || !value.matches("[A-Za-z][A-Za-z0-9_]*")) {
|
||||
@@ -793,7 +1037,7 @@ export default {
|
||||
submitForm() {
|
||||
const request = this.form.${pkColumn.javaField} ? ${className}Api.update${ClassName}(this.form) : ${className}Api.add${ClassName}(this.form)
|
||||
request.then(() => {
|
||||
this.$modal.msgSuccess("保存成功")
|
||||
this.#[[$modal]]#.msgSuccess("保存成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
})
|
||||
@@ -801,14 +1045,14 @@ export default {
|
||||
handleDelete(row) {
|
||||
const id = row.${pkColumn.javaField}
|
||||
${className}Api.del${ClassName}(id).then(() => {
|
||||
this.$modal.msgSuccess("删除成功")
|
||||
this.#[[$modal]]#.msgSuccess("删除成功")
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
handleBusinessAction(row, actionCode) {
|
||||
const action = this.businessActions.find(item => item.code === actionCode)
|
||||
${className}Api[actionCode]({ ...row }).then(() => {
|
||||
this.$modal.msgSuccess((action ? action.name : "业务动作") + "成功")
|
||||
this.#[[$modal]]#.msgSuccess((action ? action.name : "业务动作") + "成功")
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user