This commit is contained in:
吴红兵
2025-12-02 10:37:49 +08:00
commit 1f645dad3e
1183 changed files with 147673 additions and 0 deletions

View File

@@ -0,0 +1,453 @@
<template>
<div :style="props.currFlowForm ? 'width: 70%; margin-left: 15%' : ''">
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="120px" v-loading="loading"
:disabled="operType === 'view'">
<el-row :gutter="24">
<el-col :span="12" class="mb20">
<el-form-item :label="t('formoption.type')" prop="type">
<el-select v-model="form.type" :placeholder="t('formoption.inputTypeTip')" clearable filterable
@change="typeChange" :disabled="true">
<el-option v-for="(item, index) in DIC_PROP.FORM_DATA_TYPE" :key="index" :label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('formoption.formType')" prop="formType">
<el-select v-model="form.formType" :placeholder="t('formoption.inputFormTypeTip')" clearable
filterable
@change="formTypeChange" :disabled="disabledFields.formType">
<el-option v-for="(item, index) in DIC_PROP.FORM_TYPE" :key="index" :label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20" v-if="!props.currFlowForm">
<el-form-item :label="t('formoption.formId')" prop="formId">
<el-select v-model="form.formId" :placeholder="t('formoption.inputFormIdTip')" clearable
filterable
@change="formIdChange">
<el-option v-for="(item, index) in dicData.formIdByType" :key="index"
:label="item.formName" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20" v-if="!hiddenFields.defFlowId">
<el-form-item :label="t('formoption.defFlowId')" prop="defFlowId">
<el-select v-model="form.defFlowId" :placeholder="t('formoption.inputDefFlowIdTip')" clearable
filterable
@change="cascadeChange('defFlowId', ['flowNodeId'])">
<el-option v-for="(item, index) in dicData.defFlowId" :key="index" :label="item.flowName"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20" v-if="!hiddenFields.flowNodeId">
<el-form-item :label="t('formoption.flowNodeId')" prop="flowNodeId">
<el-select v-model="form.flowNodeId" :placeholder="t('formoption.inputFlowNodeIdTip')" clearable
filterable
@change="changeFlowNodeId">
<el-option v-for="(item, index) in cascadeDic.flowNodeId" :key="index"
:label="item.nodeName" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20" v-if="!hiddenFields.flowNodeId">
<el-form-item :label="t('formoption.resetBtn')" prop="resetBtn">
<el-button icon="RefreshLeft" size="small" type="primary" circle
@click="resetFormPerm"></el-button>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20" v-if="!hiddenFields.printInfo">
<el-form-item :label="t('formoption.printInfo')" prop="printInfo">
<el-input v-model="form.printInfo" :placeholder="t('formoption.inputPrintInfoTip')"/>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item :label="t('createTable.columnInfo')" prop="columns">
<el-table :data="form.columns" border style="width: 100%" max-height="500">
<el-table-column type="index" :label="t('createTable.index')" width="80">
<template #header>
<el-button icon="Plus" size="small" type="primary" circle @click="onAddItem"
:disabled="disabledFields.label"></el-button>
</template>
<template #default="scope">
<el-button icon="Minus" size="small" type="danger" circle
@click="handleDelete(scope.$index, scope.row)"></el-button>
</template>
</el-table-column>
<el-table-column prop="propId" :label="t('formoption.propId')" show-overflow-tooltip
v-if="!hiddenFields.propId && !props.currFlowForm">
<template #default="scope">
<el-input v-model="scope.row.propId" :placeholder="t('formoption.inputPropIdTip')"/>
</template>
</el-table-column>
<el-table-column prop="label" :label="t('formoption.label')" show-overflow-tooltip
v-if="!hiddenFields.label">
<template #default="scope">
<el-input v-model="scope.row.label" :placeholder="t('formoption.inputLabelTip')"
:disabled="disabledFields.label"/>
</template>
</el-table-column>
<el-table-column prop="prop" :label="t('formoption.prop')" show-overflow-tooltip
v-if="!hiddenFields.prop">
<template #default="scope">
<el-input v-model="scope.row.prop" :placeholder="t('formoption.inputPropTip')"/>
</template>
</el-table-column>
<el-table-column prop="subForm" :label="t('formoption.subForm')" show-overflow-tooltip
v-if="!hiddenFields.subForm">
<template #default="scope">
<el-input v-model="scope.row.subForm"
:placeholder="t('formoption.inputSubFormTip')"/>
</template>
</el-table-column>
<el-table-column prop="propType" :label="t('formoption.propType')" show-overflow-tooltip
v-if="!hiddenFields.propType">
<template #default="scope">
<el-input v-model="scope.row.propType"
:placeholder="t('formoption.inputPropTypeTip')"/>
</template>
</el-table-column>
<el-table-column prop="permType" :label="t('formoption.permType')" show-overflow-tooltip
v-if="!hiddenFields.permType">
<template #default="scope">
<el-radio-group v-model="scope.row.permType">
<el-radio v-for="(item, index) in DIC_PROP.FORM_PERM_TYPE" :key="index"
:label="item.value">
{{ item.label }}
</el-radio>
</el-radio-group>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-col>
</el-row>
</el-form>
<footer class="el-dialog__footer" style="text-align: center;" v-if="!props.currFlowForm">
<span class="dialog-footer">
<el-button type="primary" @click="handleSubmit()" :disabled="loading">{{
$t('common.confirmButtonText')
}}</el-button>
<el-button type="primary" @click="onClearSubmit" :disabled="loading" v-if="!validateNull(form.columns)">
清空
</el-button>
</span>
</footer>
</div>
</template>
<script setup lang="ts" name="FormDefPerm">
import {useMessage} from "/@/hooks/message";
import {getObj, addObj, putObj, listFormOption} from '/@/api/jsonflow/form-option'
import {useI18n} from "vue-i18n"
import {setPropsNull, setPropsValue} from "/@/flow/support/common";
import {onCascadeChange, onLoadDicUrl} from "/@/flow/components/convert-name/convert";
import {validateNull} from "/@/utils/validate";
import {initFromSomeAttrs, validateRunFlowId, parseWithFunctions, notifyLeft} from "/@/flow";
import {buildFieldPerms} from "/@/flow/utils/form-perm";
import {DIC_PROP} from "/@/flow/support/dict-prop";
const emit = defineEmits(['refresh']);
const {t} = useI18n();
const $message = useMessage();
// 定义变量内容
const dataFormRef = ref();
const loading = ref(false)
const operType = ref(false);
// 提交表单数据
const form = reactive({
id: '',
flowKey: '',
defFlowId: '',
flowNodeId: '',
columns: [],
formType: '',
formId: '',
formName: '',
path: '',
printInfo: '',
type: '',
});
// 定义校验规则
const dataRules = ref({
formType: [{required: true, message: '表单来源不能为空', trigger: 'blur'}],
formId: [{required: true, message: '表单名称不能为空', trigger: 'blur'}],
type: [{required: true, message: '数据类型不能为空', trigger: 'blur'}],
})
// 定义查询字典
const dicData = reactive({});
const cascadeDic = reactive({});
const onLoad = onLoadDicUrl({key: "defFlowId"}, {key: "formId"});
const onCascade = onCascadeChange(cascadeDic, {key: "defFlowId", cascades: ["flowNodeId"]});
onMounted(async () => {
await onLoad(dicData);
// 判断是否设计器中
if (props.currFlowForm) {
await openDialog('add', null, '0')
} else {
let {type, id, dataType} = props.formDefPerm
await openDialog(type, id, dataType)
}
});
const props = defineProps({
currFlowForm: {
type: Object,
default: null,
},
formDefPerm: {
type: Object,
default: null,
},
});
function cascadeChange(key, cascades) {
onCascade(form, {key: key, cascades: cascades});
if (key === 'defFlowId') {
let find = dicData.defFlowId.find(f => f.id === form.defFlowId);
if (find) form.flowKey = find.flowKey
else form.flowKey = null
}
}
// 打开弹窗
const openDialog = async (type, id, dataType) => {
operType.value = type;
form.id = ''
// 重置表单数据
nextTick(async () => {
dataFormRef.value.resetFields()
// 获取FormOption信息
if (id) {
form.id = id
await getFormOptionData(id)
await onCascade(form);
}
if (type === 'add') form.type = dataType
typeChange(form.type);
if (!props.currFlowForm) return
validateRunFlowId(props, form)
formIdChange(form.formId)
})
};
const onClearSubmit = async () => {
form.columns = []
await handleSubmit()
}
const syncCurrFormInfo = (isClear) => {
if (!isClear) props.currFlowForm.formFieldPerms = form.columns
else props.currFlowForm.formFieldPerms = []
}
// 提交
const handleSubmit = async (callback?) => {
const valid = await dataFormRef.value.validate().catch(() => {
});
if (!valid) return false;
if (!form.formId) {
$message.warning("请先选择表单名称")
return
}
if (form.type === DIC_PROP.FORM_DATA_TYPE[1].value && !form.flowNodeId) {
$message.warning("请先选择节点名称")
return
}
if (validateColumns()) return;
initFromSomeAttrs(props, form)
try {
loading.value = true;
await addObj(form);
notifyLeft('当前表单设计保存成功')
emit('refresh');
if (callback) callback()
} catch (err: any) {
useMessage().error(err);
} finally {
loading.value = false;
}
}
// 初始化表单数据
const getFormOptionData = async (id: string) => {
// 获取数据
loading.value = true
let res = await getObj(id);
Object.assign(form, res.data)
loading.value = false
};
// 定义字段显隐
const hiddenFields = reactive({
defFlowId: true,
flowNodeId: true,
label: true,
prop: true,
propId: true,
subForm: true,
propType: true,
permType: true,
printInfo: true,
});
// 定义字段是否可编辑
const disabledFields = reactive({
formType: false,
label: false,
});
const formTypeChange = (value) => {
if (value) dicData.formIdByType = dicData.formId.filter(f => f.type === value)
else dicData.formIdByType = []
form.columns = [];
form.formId = null
}
const formIdChange = (value) => {
form.columns = [];
setPropsNull(form, 'flowKey', 'defFlowId', 'flowNodeId')
if (!value) return
if (form.type === DIC_PROP.FORM_DATA_TYPE[0].value) {
handleCustomFormDef(value, form.type)
}
if (props.currFlowForm) return;
let find = dicData.formIdByType.find(f => f.id === value);
form.formName = find.formName
form.path = find.path
}
// 查询字段信息
function handleCustomFormDef(formId, type) {
listFormOption({
flowInstId: form.flowInstId,
type: type, formType: form.formType, formId: formId
}).then(resp => {
let res = resp.data;
if (!validateNull(res)) form.columns = res
else form.columns = [];
})
.catch(() => {
$message.error("获取表单字段定义失败");
})
}
const changeFlowNodeId = (value) => {
if (!value) {
form.columns = [];
return
}
handleCustomFormPerm(form.defFlowId, value, form.type)
}
function handleCustomFormPerm(defFlowId, flowNodeId, type) {
listFormOption({
type: type, formType: form.formType, formId: form.formId,
defFlowId: defFlowId, flowInstId: form.flowInstId, flowNodeId: flowNodeId
}).then(resp => {
let res = resp.data;
if (!validateNull(res)) form.columns = res
else changeNodeFormId(form.formId)
}).catch(() => {
$message.error("获取表单字段权限失败");
})
}
function changeNodeFormId(formId) {
// 判断审批表单
let find;
if (form.formType === DIC_PROP.FORM_TYPE[0].value) {
find = dicData.formIdByType.find(f => f.id === formId);
} else {
form.columns = [];
$message.warning("当前选择的系统表单无字段信息,请点击《字段定义》按钮录入")
return;
}
if (validateNull(find.formInfo)) {
form.columns = [];
$message.warning("当前选择的设计表单无字段信息,请先在《表单设计器》中设计")
return;
}
let formInfo = parseWithFunctions(find.formInfo, true)
buildFormFieldPerms(formInfo)
}
function buildFormFieldPerms(formInfo) {
form.columns = []
buildFieldPerms(form.columns, formInfo.widgetList);
}
const typeChange = (value) => {
setPropsValue(disabledFields, false, 'formType', 'label')
setPropsValue(hiddenFields, true, 'defFlowId', 'flowNodeId', 'propId', 'label', 'prop', 'subForm', 'propType', 'permType', 'printInfo')
if (value === DIC_PROP.FORM_DATA_TYPE[0].value) {
disabledFields.formType = true
setPropsValue(hiddenFields, false, 'propId', 'label', 'prop', 'subForm', 'propType')
form.formType = DIC_PROP.FORM_TYPE[1].value
} else if (value === DIC_PROP.FORM_DATA_TYPE[1].value) {
disabledFields.label = true
setPropsValue(hiddenFields, false, 'defFlowId', 'flowNodeId', 'label', 'permType')
} else {
hiddenFields.printInfo = true
}
formTypeChange(form.formType)
}
const resetFormPerm = () => {
if (!form.formId) {
$message.warning("请先选择表单名称")
return
}
handleCustomFormPerm(null, null, DIC_PROP.FORM_DATA_TYPE[0].value)
}
const onAddItem = () => {
if (!form.formId) {
$message.warning("请先选择表单名称")
return
}
if (form.type === DIC_PROP.FORM_DATA_TYPE[1].value && !form.flowNodeId) {
$message.warning("请先选择节点名称")
return
}
if (validateColumns()) return;
let obj = {propId: null, label: '', prop: '', subForm: null, propType: null, permType: null};
form.columns.push(obj);
}
const validateColumns = () => {
if (!validateNull(form.columns)) {
let find = form.columns.find(s => !s.label || !s.prop);
if (find) {
$message.warning("请先填写 属性名称 或 属性名")
return true
}
}
return false
}
const handleDelete = (index: number, row: any) => {
form.columns.splice(index, 1)
}
// 暴露变量
defineExpose({
openDialog, handleSubmit, syncCurrFormInfo
});
</script>

View File

@@ -0,0 +1,265 @@
<template>
<el-dialog :title="title" v-model="visible" width="60%"
:close-on-click-modal="false" draggable>
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="120px" v-loading="loading" :disabled="operType === 'view'">
<el-row :gutter="24">
<el-col :span="12" class="mb20">
<el-form-item :label="t('formoption.type')" prop="type">
<el-select v-model="form.type" :placeholder="t('formoption.inputTypeTip')" clearable filterable
@change="typeChange" :disabled="true">
<el-option v-for="(item, index) in DIC_PROP.FORM_DATA_TYPE" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('formoption.formType')" prop="formType">
<el-select v-model="form.formType" :placeholder="t('formoption.inputFormTypeTip')" clearable filterable
@change="formTypeChange" :disabled="disabledFields.formType">
<el-option v-for="(item, index) in DIC_PROP.FORM_TYPE" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('formoption.formId')" prop="formId">
<el-select v-model="form.formId" :placeholder="t('formoption.inputFormIdTip')" clearable filterable
@change="formIdChange">
<el-option v-for="(item, index) in dicData.formIdByType" :key="index"
:label="item.formName" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20" v-if="!hiddenFields.defFlowId">
<el-form-item :label="t('formoption.defFlowId')" prop="defFlowId">
<el-select v-model="form.defFlowId" :placeholder="t('formoption.inputDefFlowIdTip')" clearable filterable
@change="cascadeChange('defFlowId', ['flowNodeId'])">
<el-option v-for="(item, index) in dicData.defFlowId" :key="index" :label="item.flowName" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20" v-if="!hiddenFields.flowNodeId">
<el-form-item :label="t('formoption.flowNodeId')" prop="flowNodeId">
<el-select v-model="form.flowNodeId" :placeholder="t('formoption.inputFlowNodeIdTip')" clearable filterable>
<el-option v-for="(item, index) in cascadeDic.flowNodeId" :key="index" :label="item.nodeName" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20" v-if="!hiddenFields.propId">
<el-form-item :label="t('formoption.propId')" prop="propId">
<el-input v-model="form.propId" :placeholder="t('formoption.inputPropIdTip')"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20" v-if="!hiddenFields.label">
<el-form-item :label="t('formoption.label')" prop="label">
<el-input v-model="form.label" :placeholder="t('formoption.inputLabelTip')"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20" v-if="!hiddenFields.prop">
<el-form-item :label="t('formoption.prop')" prop="prop">
<el-input v-model="form.prop" :placeholder="t('formoption.inputPropTip')"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20" v-if="!hiddenFields.subForm">
<el-form-item :label="t('formoption.subForm')" prop="subForm">
<el-input v-model="form.subForm" :placeholder="t('formoption.inputSubFormTip')"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20" v-if="!hiddenFields.propType">
<el-form-item :label="t('formoption.propType')" prop="propType">
<el-input v-model="form.propType" :placeholder="t('formoption.inputPropTypeTip')"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20" v-if="!hiddenFields.permType">
<el-form-item :label="t('formoption.permType')" prop="type">
<el-radio-group v-model="form.permType">
<el-radio v-for="(item, index) in DIC_PROP.FORM_PERM_TYPE" :key="index" :label="item.value">
{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20" v-if="!hiddenFields.printInfo">
<el-form-item :label="t('formoption.printInfo')" prop="printInfo">
<el-input v-model="form.printInfo" :placeholder="t('formoption.inputPrintInfoTip')"/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer v-if="operType !== 'view'">
<span class="dialog-footer">
<el-button @click="visible = false">{{ $t('common.cancelButtonText') }}</el-button>
<el-button type="primary" @click="onSubmit" :disabled="loading">{{ $t('common.confirmButtonText') }}</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts" name="FormOptionDialog">
import { useMessage } from "/@/hooks/message";
import { getObj, putObj } from '/@/api/jsonflow/form-option'
import { useI18n } from "vue-i18n"
import {setPropsValue} from "/@/flow/support/common";
import {onCascadeChange, onLoadDicUrl} from "/@/flow/components/convert-name/convert";
import {DIC_PROP} from "/@/flow/support/dict-prop";
const emit = defineEmits(['refresh']);
const { t } = useI18n();
// 定义变量内容
const dataFormRef = ref();
const visible = ref(false)
const loading = ref(false)
const operType = ref(false);
const title = ref('');
// 提交表单数据
const form = reactive({
id: '',
flowKey: '',
defFlowId: '',
flowNodeId: '',
propId: '',
label: '',
prop: '',
subForm: '',
propType: '',
permType: '',
formType: '',
formId: '',
formName: '',
path: '',
printInfo: '',
type: '',
});
// 定义校验规则
const dataRules = ref({
formType: [{required: true, message: '表单来源不能为空', trigger: 'blur'}],
formId: [{required: true, message: '表单名称不能为空', trigger: 'blur'}],
type: [{required: true, message: '数据类型不能为空', trigger: 'blur'}],
})
// 定义查询字典
const dicData = reactive({});
const cascadeDic = reactive({});
const onLoad = onLoadDicUrl({key: "defFlowId"}, {key: "formId"});
const onCascade = onCascadeChange(cascadeDic, {key: "defFlowId", cascades: ["flowNodeId"]});
onMounted(() => {
onLoad(dicData);
});
function cascadeChange(key, cascades){
onCascade(form, {key: key, cascades: cascades});
if (key === 'defFlowId') {
let find = dicData.defFlowId.find(f => f.id === form.defFlowId);
if (find) form.flowKey = find.flowKey
else form.flowKey = null
}
}
// 打开弹窗
const openDialog = async (type: string, id: string, dataType: string) => {
visible.value = true
operType.value = type;
form.id = ''
if (type === 'add') {
title.value = t('common.addBtn');
} else if (type === 'edit') {
title.value = t('common.editBtn');
} else if (type === 'view') {
title.value = t('common.viewBtn');
}
// 重置表单数据
nextTick(async () => {
dataFormRef.value.resetFields()
// 获取FormOption信息
if (id) {
form.id = id
await getFormOptionData(id)
await onCascade(form);
}
if (type === 'add') form.type = dataType
typeChange(form.type);
})
};
// 提交
const onSubmit = async () => {
const valid = await dataFormRef.value.validate().catch(() => {});
if (!valid) return false;
try {
loading.value = true;
await putObj(form);
useMessage().success(t(form.id ? 'common.editSuccessText' : 'common.addSuccessText'));
visible.value = false;
emit('refresh');
} catch (err: any) {
useMessage().error(err);
} finally {
loading.value = false;
}
}
// 初始化表单数据
const getFormOptionData = async (id: string) => {
// 获取数据
loading.value = true
let res = await getObj(id);
Object.assign(form, res.data)
loading.value = false
};
// 定义字段显隐
const hiddenFields = reactive({
defFlowId: true,
flowNodeId: true,
label: true,
prop: true,
propId: true,
subForm: true,
propType: true,
permType: true,
printInfo: true,
});
// 定义字段是否可编辑
const disabledFields = reactive({
formType: false,
});
const formTypeChange = (value) => {
if (value) dicData.formIdByType = dicData.formId.filter(f => f.type === value)
else dicData.formIdByType = []
}
const formIdChange = (value) => {
if (!value) return
let find = dicData.formIdByType.find(f => f.id === value);
form.formName = find.formName
form.path = find.path
}
const typeChange = (value) => {
disabledFields.formType = false
setPropsValue(hiddenFields, true, 'defFlowId', 'flowNodeId', 'propId', 'label', 'prop', 'subForm', 'propType', 'permType', 'printInfo')
if (value === DIC_PROP.FORM_DATA_TYPE[0].value) {
disabledFields.formType = true
setPropsValue(hiddenFields, false, 'propId', 'label', 'prop', 'subForm', 'propType')
form.formType = DIC_PROP.FORM_TYPE[1].value
} else if (value === DIC_PROP.FORM_DATA_TYPE[1].value) {
setPropsValue(hiddenFields, false, 'defFlowId', 'flowNodeId', 'propId', 'label', 'prop', 'subForm', 'propType', 'permType')
} else {
hiddenFields.printInfo = true
}
formTypeChange(form.formType)
}
// 暴露变量
defineExpose({
openDialog
});
</script>

View File

@@ -0,0 +1,39 @@
export default {
formoption: {
index: '#',
importFormOptionTip: ' import FormOption',
id: 'id',
defFlowId: 'defFlowId',
flowNodeId: 'flowNodeId',
flowKey: 'flowKey',
propId: 'propId',
label: 'label',
prop: 'prop',
subForm: 'subForm',
propType: 'propType',
printInfo: 'printInfo',
permType: 'permType',
formType: 'formType',
formId: 'formId',
formName: 'formName',
path: 'path',
type: 'type',
resetBtn: 'resetPerm',
inputIdTip: 'input id',
inputDefFlowIdTip: 'input defFlowId',
inputFlowNodeIdTip: 'input flowNodeId',
inputFlowKeyTip: 'input flowKey',
inputPropIdTip: 'input propId',
inputLabelTip: 'input label',
inputPropTip: 'input prop',
inputSubFormTip: 'input subForm',
inputPropTypeTip: 'input propType',
inputPermTypeTip: 'input permType',
inputFormTypeTip: 'input formType',
inputFormIdTip: 'input formId',
inputFormNameTip: 'input formName',
inputPathTip: 'input path',
inputPrintInfoTip: 'input printInfo',
inputTypeTip: 'input type',
}
}

View File

@@ -0,0 +1,39 @@
export default {
formoption: {
index: '#',
importFormOptionTip: '导入表单操作表',
id: '',
flowKey: '流程KEY',
defFlowId: '流程名称',
flowNodeId: '节点名称',
propId: '属性唯一ID',
label: '属性名称',
prop: '属性名',
subForm: '子表单属性名',
propType: '属性类型',
printInfo: '打印信息',
permType: '权限类型',
formType: '表单来源',
formId: '表单名称',
formName: '表单名称',
path: '表单路径',
type: '数据类型',
resetBtn: '重置权限',
inputIdTip: '请输入',
inputFlowKeyTip: '请选择流程KEY',
inputDefFlowIdTip: '请选择流程名称',
inputFlowNodeIdTip: '请先选择流程名称',
inputPropIdTip: '表单设计器的属性唯一ID',
inputLabelTip: '例如:用户名',
inputPropTip: '例如userName',
inputSubFormTip: '若是子表数据则需填写',
inputPropTypeTip: '打印设计的属性类型参考PRINT_FORMAT常量',
inputPermTypeTip: '请选择权限类型',
inputFormTypeTip: '请选择表单来源',
inputFormIdTip: '请先选择表单名称',
inputFormNameTip: '请输入表单名称',
inputPathTip: '请输入表单路径',
inputPrintInfoTip: '请输入打印信息',
inputTypeTip: '请选择数据类型',
}
}

View File

@@ -0,0 +1,280 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<el-row v-show="showSearch">
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
<el-form-item :label="t('formoption.type')" prop="type">
<el-select v-model="state.queryForm.type" :placeholder="t('formoption.inputTypeTip')" clearable filterable>
<el-option v-for="(item, index) in DIC_PROP.FORM_DATA_TYPE" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="t('formoption.formType')" prop="formType">
<el-select v-model="state.queryForm.formType" :placeholder="t('formoption.inputFormTypeTip')" clearable
filterable
@change="formTypeChange">
<el-option v-for="(item, index) in DIC_PROP.FORM_TYPE" :key="index" :label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="t('formoption.formId')" prop="formId">
<el-select v-model="state.queryForm.formId" :placeholder="t('formoption.inputFormIdTip')" clearable filterable>
<el-option v-for="(item, index) in dicData.formIdByType" :key="index"
:label="item.formName" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('formoption.defFlowId')" prop="defFlowId">
<el-select v-model="state.queryForm.defFlowId" :placeholder="t('formoption.inputDefFlowIdTip')"
clearable filterable @change="cascadeChange('defFlowId', ['flowNodeId'])">
<el-option v-for="(item, index) in dicData.defFlowId" :key="index" :label="item.flowName"
:value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="t('formoption.flowNodeId')" prop="flowNodeId">
<el-select v-model="state.queryForm.flowNodeId" :placeholder="t('formoption.inputFlowNodeIdTip')" clearable filterable>
<el-option v-for="(item, index) in cascadeDic.flowNodeId" :key="index" :label="item.nodeName" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button icon="search" type="primary" @click="getDataList">
{{ $t('common.queryBtn') }}
</el-button>
<el-button icon="Refresh" @click="resetQuery">{{ $t('common.resetBtn') }}</el-button>
</el-form-item>
</el-form>
</el-row>
<el-row>
<div class="mb8" style="width: 100%">
<el-button icon="CirclePlus" type="primary" class="ml10" @click="openFormDefPerm('add', null, '0')"
v-auth="'jsonflow_formoption_add'">字段定义
</el-button>
<el-button icon="Setting" type="primary" class="ml10" @click="openFormDefPerm('add', null, '1')"
v-auth="'jsonflow_formoption_add'">权限配置
</el-button>
<el-button icon="Pointer" type="primary" class="ml10" @click="handlePrintTemplate"
v-auth="'jsonflow_formoption_add'">打印设计
</el-button>
<el-button plain :disabled="multiple" icon="Delete" type="primary" class="ml10"
v-auth="'jsonflow_formoption_del'" @click="handleDelete(selectObjs)">
{{ $t('common.delBtn') }}
</el-button>
<right-toolbar v-model:showSearch="showSearch" class="ml10" style="float: right;margin-right: 20px"
:export="'jsonflow_formoption_export'" @exportExcel="exportExcel"
@queryTable="getDataList"></right-toolbar>
</div>
</el-row>
<el-table :data="state.dataList" v-loading="state.loading" style="width: 100%"
@selection-change="handleSelectionChange" @sort-change="sortChangeHandle">
<el-table-column type="selection" width="40" align="center" />
<el-table-column fixed="left" type="index" :label="t('formoption.index')" width="40" />
<el-table-column prop="type" :label="t('formoption.type')" show-overflow-tooltip>
<template #default="scope">
<dict-tag :options="DIC_PROP.FORM_DATA_TYPE" :value="scope.row.type"></dict-tag>
</template>
</el-table-column>
<el-table-column prop="formType" :label="t('formoption.formType')" show-overflow-tooltip>
<template #default="scope">
<dict-tag :options="DIC_PROP.FORM_TYPE" :value="scope.row.formType"></dict-tag>
</template>
</el-table-column>
<el-table-column prop="formName" :label="t('formoption.formName')" show-overflow-tooltip/>
<el-table-column prop="path" :label="t('formoption.path')" show-overflow-tooltip/>
<el-table-column prop="defFlowId" :label="t('formoption.defFlowId')" show-overflow-tooltip>
<template #default="scope">
<convert-name :options="dicData.defFlowId" :value="scope.row.defFlowId"
:valueKey="'id'" :showKey="'flowName'"></convert-name>
</template>
</el-table-column>
<el-table-column prop="flowNodeId" :label="t('formoption.flowNodeId')" show-overflow-tooltip>
<template #default="scope">
<convert-name :options="dicData.flowNodeId" :value="scope.row.flowNodeId"
:valueKey="'id'" :showKey="'nodeName'"></convert-name>
</template>
</el-table-column>
<el-table-column prop="propId" :label="t('formoption.propId')" show-overflow-tooltip/>
<el-table-column prop="label" :label="t('formoption.label')" show-overflow-tooltip/>
<el-table-column prop="prop" :label="t('formoption.prop')" show-overflow-tooltip/>
<el-table-column prop="subForm" :label="t('formoption.subForm')" show-overflow-tooltip/>
<el-table-column prop="propType" :label="t('formoption.propType')" show-overflow-tooltip/>
<el-table-column prop="permType" :label="t('formoption.permType')" show-overflow-tooltip>
<template #default="scope">
<dict-tag :options="DIC_PROP.FORM_PERM_TYPE" :value="scope.row.permType"></dict-tag>
</template>
</el-table-column>
<el-table-column prop="printInfo" :label="t('formoption.printInfo')" show-overflow-tooltip/>
<el-table-column :label="$t('common.action')" fixed="right" width="100">
<template #default="scope">
<el-tooltip placement="top">
<template #content>
{{ $t('common.viewBtn') }}
</template>
<el-button text type="primary" icon="view" @click="formDialogRef.openDialog('view', scope.row.id)">
</el-button>
</el-tooltip>
<el-tooltip placement="top">
<template #content>
{{ $t('common.editBtn') }}
</template>
<el-button icon="edit-pen" text type="primary" @click="handleRowEdit(scope.row)">
</el-button>
</el-tooltip>
<el-tooltip placement="top">
<template #content>
{{ $t('common.delBtn') }}
</template>
<el-button icon="delete" text type="primary" @click="handleDelete([scope.row.id])">
</el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" v-bind="state.pagination" />
</div>
<!-- 编辑新增 -->
<form-dialog ref="formDialogRef" @refresh="getDataList(false)" />
<!-- 打印模板设计器 -->
<el-drawer class="tinymce-print-drawer" append-to-body direction="rtl"
v-model="data.showTinymceEditor" size="100%"
:title="data.tinymceTitle" @close="getDataList">
<tinymce-editor v-if="data.showTinymceEditor" :currFlowForm="data.currFlowForm"></tinymce-editor>
</el-drawer>
<el-dialog title="新增或修改" v-model="data.formDefPermVisible" width="80%"
v-if="data.formDefPermVisible"
:close-on-click-modal="false" draggable>
<form-def-perm :formDefPerm="data.formDefPerm" ref="formDefPermRef" @refresh="getDataList(false)" />
</el-dialog>
</div>
</template>
<script setup lang="ts" name="FormOption">
import { BasicTableProps, useTable } from "/@/hooks/table";
import { fetchList, delObjs } from "/@/api/jsonflow/form-option";
import { useMessage, useMessageBox } from "/@/hooks/message";
import { useI18n } from "vue-i18n";
import {onCascadeChange, onLoadDicUrl} from "/@/flow/components/convert-name/convert";
import {DIC_PROP} from "/@/flow/support/dict-prop";
import {deepClone} from "/@/utils/other";
// 引入组件
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
const FormDefPerm = defineAsyncComponent(() => import('./form-def-perm.vue'));
const TinymceEditor = defineAsyncComponent(() => import('/@/flow/components/tinymce/TinymceEditor.vue'));
const { t } = useI18n()
// 定义查询字典
const dicData = reactive({});
const cascadeDic = reactive({});
const onLoad = onLoadDicUrl({key: "defFlowId"}, {key: "flowNodeId"}, {key: "formId"});
const onCascade = onCascadeChange(cascadeDic, {key: "defFlowId", cascades: ["flowNodeId"]});
onMounted(() => {
onLoad(dicData);
});
function cascadeChange(key, cascades){
onCascade(state.queryForm, {key: key, cascades: cascades});
}
// 定义变量内容
const formDialogRef = ref()
const formDefPermRef = ref()
// 搜索变量
const queryRef = ref()
const showSearch = ref(true)
// 多选变量
const selectObjs = ref([]) as any
const multiple = ref(true)
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: {},
pageList: fetchList,
descs: ["create_time"]
})
// table hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
sortChangeHandle,
downBlobFile
} = useTable(state)
// 清空搜索条件
const resetQuery = () => {
queryRef.value.resetFields()
// 清空多选
selectObjs.value = []
getDataList()
}
// 多选事件
const handleSelectionChange = (objs: any) => {
selectObjs.value = objs.map(({ id }) => id);
multiple.value = !objs.length
}
// 导出excel
const exportExcel = () => {
downBlobFile('/jsonflow/form-option/export', state.queryForm, 'formoption.xlsx')
}
// 删除操作
const handleDelete = async (ids: string[]) => {
try {
await useMessageBox().confirm(t('common.delConfirmText'));
} catch {
return;
}
try {
await delObjs(ids);
getDataList();
useMessage().success(t('common.delSuccessText'));
} catch (err: any) {
useMessage().error(err);
}
};
const formTypeChange = (value) => {
if (value) dicData.formIdByType = dicData.formId.filter(f => f.type === value)
else dicData.formIdByType = []
state.queryForm.formId = null
}
function handleRowEdit(row){
if (row.type === DIC_PROP.FORM_DATA_TYPE[2].value) {
handlePrintTemplate(row, true)
} else {
formDialogRef.value.openDialog('edit', row.id)
}
}
const data = reactive({
currFlowForm: {},
showTinymceEditor: false,
formDefPermVisible: false,
formDefPerm: {},
tinymceTitle: '',
})
const openFormDefPerm = async (type: string, id: string, dataType: string) => {
data.formDefPermVisible = true
data.formDefPerm = {type, id, dataType}
}
function handlePrintTemplate(row, isExist) {
data.currFlowForm = {}
if (isExist) {
data.currFlowForm = deepClone(row)
data.currFlowForm.isForm = true
}
data.tinymceTitle = "打印模板设计器(自定义打印格式)"
data.showTinymceEditor = true
}
</script>
<style lang="scss">
@import "../../../flow/components/style/flow-drawer.scss";
</style>