Files
school-developer/src/flow/designer/components/flow-clazz.vue
吴红兵 1f645dad3e init
2025-12-02 10:37:49 +08:00

412 lines
19 KiB
Vue

<template>
<div>
<el-form label-position="left" class="flow-config-attr" label-width="160px">
<el-form-item label="监听类">
<el-input class="input-attr" :placeholder="props.clazzPlaceholder" v-model="data.clazz.clazz" clearable></el-input>
</el-form-item>
<el-form-item label="Http请求地址">
<el-input class="input-attr" placeholder="可输入全路径或相对路径" v-model="data.clazz.httpUrl"
@blur="methods.handleHttpUrlBlur" clearable>
<template #prepend>
<el-select v-model="data.clazz.httpMethod">
<el-option v-for="(item, index) in DIC_PROP.HTTP_METHODS" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</template>
</el-input>
<el-tooltip content="点击可设置Http请求的参数信息" placement="bottom">
<el-button type="primary" size="small" round style="margin-left: 10px"
@click="methods.openHttpUrlParams(true)">
参数
</el-button>
</el-tooltip>
</el-form-item>
<el-form-item label="触发时机">
<el-select class="input-attr"
v-model="data.clazz.methods" multiple
clearable placeholder="多个方法名称, 英文逗号分隔, 顺序从左到右">
<el-option
v-for="(item, index) in props.addType === '0' && props.currSelect.attributes.attrs.cdata.attrs.isAutoAudit === '1' ?
props.flowMethods.slice(3) : props.flowMethods"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-divider v-if="!data.moreInter">
<el-button type="primary" link @click="methods.showMoreSetting()"
style="margin-left: 10px; font-size: 14px">
{{ data.moreInter ? '隐藏更多' : '更多配置' }}
</el-button>
</el-divider>
<template v-if="data.moreInter">
<div style="margin: 10px 13px">
<span style="color: red;font-size: 14px">注: 监听事件允许设置生效条件,用于控制在某种条件下才会执行</span>
</div>
<el-form-item label="条件模式">
<el-radio-group style="width: 313px" @change="methods.handleClazzValType" :disabled="data.existData"
v-model="data.clazz.valType">
<el-radio v-for="(item, index) in DIC_PROP.VAL_TYPE.slice(2, 5)" :key="index" :label="item.value" style="width: 75px">
{{ item.label }}
</el-radio>
</el-radio-group>
<el-tooltip placement="top">
<template #content>若无法切换模式,请先清空监听事件列表</template>
<el-icon><QuestionFilled /></el-icon>
</el-tooltip>
</el-form-item>
<el-table :data="data.tableFieldData" v-if="data.clazz.valType === '0'"
border style="width: 100%; margin-bottom: 10px" max-height="500">
<el-table-column prop="varKeyVal" :label="t('flowClazz.varKeyVal')" show-overflow-tooltip>
<template #default="scope">
<el-select v-model="data.clazz.varKeyVal" @change="methods.handleVarKeyVal"
clearable
filterable>
<el-option-group
v-for="(group, index) in data.allFieldPerms"
:key="index"
:label="group.label">
<el-option
v-for="(item, index) in group.options"
:disabled="item.prop.indexOf('_define_') !== -1"
:key="index"
:label="item.label"
:value="item.prop">
</el-option>
</el-option-group>
</el-select>
</template>
</el-table-column>
<el-table-column prop="operator" :label="t('flowClazz.operator')" show-overflow-tooltip>
<template #default="scope">
<el-select v-model="data.clazz.operator"
clearable>
<el-option
v-for="(item, index) in data.varValOperator"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="varVal" :label="t('flowClazz.varVal')" show-overflow-tooltip>
<template #default="scope">
<el-input v-model="data.clazz.varVal" clearable/>
</template>
</el-table-column>
</el-table>
<el-form-item label="SpEL表达式" v-if="data.clazz.valType === '1'">
<el-input class="input-attr" v-model="data.clazz.varKeyVal" clearable @blur="methods.handleClazzVarKeyVal"/>
<el-tooltip placement="top">
<template #content>{{ PROP_CONST.TEXT_DESC.condSpELExplain }}</template>
<el-icon style="margin-left: 10px"><QuestionFilled /></el-icon>
</el-tooltip>
</el-form-item>
<el-form-item label="函数表达式" v-if="data.clazz.valType === '2'">
<el-input class="input-attr" v-model="data.clazz.varKeyVal" placeholder="请输入函数表达式" clearable @blur="methods.handleClazzVarKeyVal"/>
<el-tooltip placement="top">
<template #content>{{ PROP_CONST.TEXT_DESC.condMethodExplain1 }}
<br />{{ PROP_CONST.TEXT_DESC.condMethodExplain2 }}
<br />{{ PROP_CONST.TEXT_DESC.condMethodExplain3 }}
<br />{{ PROP_CONST.TEXT_DESC.condMethodExplain4 }}
</template>
<el-icon style="margin-left: 10px"><QuestionFilled /></el-icon>
</el-tooltip>
</el-form-item>
<el-form-item label="监听备注">
<el-input class="input-attr" type="textarea" v-model="data.clazz.remark"></el-input>
</el-form-item>
<el-form-item label="监听排序">
<el-input-number class="input-attr" v-model="data.clazz.sort" :min="1"></el-input-number>
</el-form-item>
</template>
<el-button type="primary" round style="margin-left: 185px; margin-top: 30px; margin-bottom: 30px; width: 200px" @click="methods.addFlowNodeClazz(props.addType)">
{{ data.clazz.isSelectedRow ? '修改完成': '添加事件' }}
</el-button>
<el-divider>已添加监听事件列表(点击行可再次修改)</el-divider>
<el-empty description="监听事件列表为空" style="margin: 10px 230px" v-if="!data.existData">
</el-empty>
<el-table :data="data.tableData" border style="width: 100%" max-height="500" v-else
highlight-current-row @current-change="methods.handleCurrentChange" ref="tableDataRef">
<el-table-column type="index" label="操作" width="55">
<template #default="scope">
<el-button icon="Minus" size="small" type="danger" circle @click="methods.handleClazzDelete(scope.$index, scope.row, props.addType)"></el-button>
</template>
</el-table-column>
<el-table-column prop="clazz" :label="t('flowClazz.clazz')" width="130" show-overflow-tooltip/>
<el-table-column prop="httpUrl" :label="t('flowClazz.httpUrl')" width="130" show-overflow-tooltip>
</el-table-column>
<el-table-column prop="methods" label="触发时机" width="130" show-overflow-tooltip>
<template #default="scope">
<dict-tag :options="props.flowMethods" :value="scope.row.methods"></dict-tag>
</template>
</el-table-column>
<el-table-column prop="varKeyVal" label="函数表达式" width="130" show-overflow-tooltip v-if="data.clazz.valType === '2'"/>
<el-table-column prop="varKeyVal" label="SpEL表达式" width="130" show-overflow-tooltip v-if="data.clazz.valType === '1'"/>
<el-table-column prop="varKeyVal" :label="t('flowClazz.varKeyVal')" width="130" show-overflow-tooltip v-if="data.clazz.valType === '0'">
<template #default="scope">
<convert-group-name :options="data.allFieldPerms" :value="scope.row.varKeyVal"
:valueKey="'prop'" :showKey="'label'"></convert-group-name>
</template>
</el-table-column>
<el-table-column prop="operator" :label="t('flowClazz.operator')" width="100" show-overflow-tooltip v-if="data.clazz.valType === '0'">
<template #default="scope">
<dict-tag :options="DIC_PROP.OPERATOR" :value="scope.row.operator"></dict-tag>
</template>
</el-table-column>
<el-table-column prop="varVal" :label="t('flowClazz.varVal')" width="100" show-overflow-tooltip v-if="data.clazz.valType === '0'"/>
<el-table-column prop="remark" :label="t('flowClazz.remark')" width="70" show-overflow-tooltip/>
<el-table-column prop="sort" :label="t('flowClazz.sort')" width="70" show-overflow-tooltip/>
</el-table>
</el-form>
<el-drawer
class="flow-attr-drawer"
title="Http请求的参数信息"
direction="rtl"
append-to-body
:size="630" v-if="data.httpUrlParamsVisible"
v-model="data.httpUrlParamsVisible">
<el-form label-position="left" class="flow-attr flow-param-attr" label-width="150px">
<flow-http-param ref="flowHttpParam" :currFlowForm="props.currFlowForm" :httpParam="data.clazz"
:flowData="props.flowData"></flow-http-param>
</el-form>
</el-drawer>
</div>
</template>
<script setup lang="ts" name="FlowClazz">
import {useI18n} from "vue-i18n";
import {useMessage} from "/@/hooks/message";
import {rule, validateNull} from "/@/utils/validate";
import {deepClone} from "/@/utils/other";
import {DIC_PROP} from "/@/flow/support/dict-prop";
import {buildSysFieldsFormOption} from "../../utils/form-perm";
const { proxy } = getCurrentInstance();
const FlowHttpParam = defineAsyncComponent(() => import('./flow-http-param.vue'));
const {t} = useI18n();
const $message = useMessage();
const props = defineProps({
currFlowForm: {
type: Object,
default: null,
},
currSelect: {
type: Object,
default: null,
},
flowData: {
type: Object,
default: null,
},
clazzPlaceholder: {
type: String,
default: '',
},
flowMethods: {
type: Array,
default: [],
},
addType: {
type: String,
default: '',
}
});
const clazzData = {
clazz: null,
httpUrl: null,
httpMethod: 'GET',
httpParams: null,
methods: null,
valType: null,
varKeyVal: null,
operator: null,
varVal: null,
remark: null,
sort: 1,
}
const data = reactive({
tableFieldData: [],
allFieldPerms: [],
formFieldPerms: [],
clazz: deepClone(clazzData),
httpUrlParamsVisible: false,
moreInter: false,
existData: false,
tableData: []
})
onMounted(() => {
methods.changeTabPane(props.currSelect)
})
const methods = {
openHttpUrlParams(bool) {
if (!data.clazz.httpUrl) {
$message.warning("请先输入【Http请求地址】")
return
}
data.httpUrlParamsVisible = bool
},
handleHttpUrlBlur() {
if (!data.clazz.httpUrl) {
data.clazz.httpParams = []
return;
}
},
handleCurrentChange(row) {
if (!row) return
data.clazz = row
data.clazz.isSelectedRow = true
},
handleVarKeyVal(varKeyVal) {
let dots = varKeyVal.split('.').length - 1;
if (dots === 2) {
data.varValOperator = DIC_PROP.OPERATOR.slice(6)
} else {
data.varValOperator = DIC_PROP.OPERATOR
}
},
onAddItem(){
if (validateNull(data.formFieldPerms)) {
buildSysFieldsFormOption(data, props, $message)
}
if (data.tableFieldData.length > 0) return
let obj = {varKeyVal: '', operator: '', varVal: ''};
data.tableFieldData.push(obj);
},
addFlowNodeClazz(type) {
let clazzes = type === '0' ? props.currSelect.attributes.attrs.cdata.attrs.clazzes : props.flowData.attrs.clazzes;
if (!data.clazz.clazz && !data.clazz.httpUrl) {
$message.warning("请填写 监听类 或者 Http请求地址")
return
}
if (validateNull(data.clazz.methods)) {
$message.warning("触发时机不能为空")
return
}
if (!validateNull(clazzes) && !data.clazz.isSelectedRow) {
if (data.clazz.clazz) {
let b = methods.validateClazzHttpUrl(clazzes, 'clazz', '监听类');
if (b) return;
} else {
let b = methods.validateClazzHttpUrl(clazzes, 'httpUrl', 'Http请求地址');
if (b) return;
}
}
if (data.clazz.clazz && data.clazz.httpUrl) {
$message.error("监听类 与 Http请求地址不能同时存在")
return;
}
if (data.clazz.isSelectedRow) {
data.clazz.isSelectedRow = false
proxy.$refs.tableDataRef.setCurrentRow(null)
data.clazz = deepClone(clazzData);
} else {
let clazz = deepClone(data.clazz);
if (type === '0') props.currSelect.attributes.attrs.cdata.attrs.clazzes.unshift(clazz)
else props.flowData.attrs.clazzes.unshift(clazz)
methods.validateClazzData()
}
},
validateClazzHttpUrl(clazzes, key, errMsg){
let find = clazzes.find(f => f[key] === data.clazz[key]);
if (find) {
$message.warning("请勿重复添加 " + errMsg)
return true
}
return false
},
handleClazzDelete(index: number, row: any, type: string){
if (type === '0') props.currSelect.attributes.attrs.cdata.attrs.clazzes.splice(index, 1)
else props.flowData.attrs.clazzes.splice(index, 1)
methods.validateClazzData()
},
handleClazzValType(type?) {
if (!type) {
type = methods.initCurrVarKeyVal()
}
if (type === DIC_PROP.VAL_TYPE[2].value) {
data.varValOperator = DIC_PROP.OPERATOR
methods.onAddItem()
} else {
data.varValOperator = []
}
data.clazz.varKeyVal = null
data.clazz.operator = null
data.clazz.varVal = null
},
handleClazzVarKeyVal() {
let val = data.clazz.varKeyVal
if (!val) return
let valType = data.clazz.valType;
if (valType === DIC_PROP.VAL_TYPE[3].value && val.indexOf("#") === -1) {
data.clazz.varKeyVal = null
$message.warning("当选择SpEL模式时, SpEL表达式必须符合SpEL格式")
} else if (valType === DIC_PROP.VAL_TYPE[4].value && val.indexOf("#") === -1) {
data.clazz.varKeyVal = null
$message.warning("当选择专业模式时, 函数表达式必须符合规定的格式")
}
},
showMoreSetting() {
data.moreInter = !data.moreInter
},
validateClazzData() {
let clazzes = props.addType === '0' ? props.currSelect.attributes.attrs.cdata.attrs.clazzes : props.flowData.attrs.clazzes;
if (!clazzes) {
if (props.addType === '0') props.currSelect.attributes.attrs.cdata.attrs.clazzes = []
else props.flowData.attrs.clazzes = []
}
data.tableData.splice(0, data.tableData.length);
if (props.addType === '0') {
props.currSelect.attributes.attrs.cdata.attrs.clazzes.forEach(each => data.tableData.push(each))
} else {
props.flowData.attrs.clazzes.forEach(each => data.tableData.push(each))
}
data.existData = !validateNull(data.tableData)
},
initCurrVarKeyVal() {
if (data.tableData.length > 0) {
data.clazz.valType = data.tableData[0].valType
}
data.clazz.methods = []
return data.clazz.valType
},
changeTabPane(val) {
methods.validateClazzData()
methods.handleClazzValType()
}
}
// 监听双向绑定
watch(
() => props.currSelect,
(val) => {
if (Object.keys(val).length === 0) {
return
}
methods.changeTabPane(val)
}
);
</script>
<style lang="scss">
@import '../assets/style/flow-attr.scss';
</style>