初始化版本,引入智慧食堂模块,第三方模块
This commit is contained in:
commit
d22f88efd3
677 files changed
+69341
No files matched your search
@@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<div><china-area v-model="form.props.value" :disabled="form.perm === 'R'" /></div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
const ChinaArea = defineAsyncComponent(() => import('/@/components/ChinaArea/index.vue'));
|
||||
let props = defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'D',
|
||||
},
|
||||
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const getValidateRule = () => {
|
||||
var item = props.form;
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
if (item.required) {
|
||||
if (!value) {
|
||||
return callback(new Error('请填写' + item.name));
|
||||
}
|
||||
}
|
||||
if (!value) {
|
||||
return callback();
|
||||
}
|
||||
return callback();
|
||||
};
|
||||
let ruleArray = [
|
||||
{
|
||||
validator: checkConfig,
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
if (item.required) {
|
||||
ruleArray.push({ required: true, message: '请填写' + item.name, trigger: 'blur' });
|
||||
}
|
||||
return ruleArray;
|
||||
};
|
||||
defineExpose({ getValidateRule });
|
||||
</script>
|
||||
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-date-picker
|
||||
class="formDate"
|
||||
v-if="mode === 'D'"
|
||||
:disabled="true"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
:placeholder="!form ? '' : form.placeholder"
|
||||
/>
|
||||
<el-date-picker
|
||||
v-else
|
||||
class="formDate"
|
||||
value-format="YYYY-MM-DD"
|
||||
v-model="form.props.value"
|
||||
:disabled="form.perm === 'R'"
|
||||
:placeholder="form.placeholder"
|
||||
type="date"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { defineExpose } from 'vue';
|
||||
|
||||
let props = defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'D',
|
||||
},
|
||||
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const getValidateRule = () => {
|
||||
var item = props.form;
|
||||
var itemProps = item.props;
|
||||
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
if (item.required) {
|
||||
if (!value) {
|
||||
return callback(new Error('请填写' + item.name));
|
||||
}
|
||||
}
|
||||
if (!value) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (itemProps.minLength) {
|
||||
if (value.length < itemProps.minLength) {
|
||||
return callback(new Error('长度不能小于' + itemProps.minLength));
|
||||
}
|
||||
}
|
||||
|
||||
if (itemProps.maxLength) {
|
||||
if (value.length > itemProps.maxLength) {
|
||||
return callback(new Error('长度不能大于' + itemProps.maxLength));
|
||||
}
|
||||
}
|
||||
if (itemProps.regex) {
|
||||
let regExp = new RegExp(itemProps.regex);
|
||||
if (!regExp.test(value)) {
|
||||
return callback(new Error(itemProps.regexDesc));
|
||||
}
|
||||
}
|
||||
return callback();
|
||||
};
|
||||
let ruleArray = [
|
||||
{
|
||||
validator: checkConfig,
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
if (item.required) {
|
||||
ruleArray.push({ required: true, message: '请填写' + item.name, trigger: 'blur' });
|
||||
}
|
||||
return ruleArray;
|
||||
};
|
||||
defineExpose({ getValidateRule });
|
||||
</script>
|
||||
<style scoped>
|
||||
:deep(.formDate div.el-input__wrapper) {
|
||||
width: 100% !important;
|
||||
}
|
||||
:deep(.formDate) {
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-date-picker
|
||||
class="formDate"
|
||||
v-if="mode === 'D'"
|
||||
:disabled="true"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
:placeholder="!form ? '' : form.placeholder"
|
||||
/>
|
||||
<el-date-picker
|
||||
v-else
|
||||
class="formDate"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
type="datetime"
|
||||
v-model="form.props.value"
|
||||
:disabled="form.perm === 'R'"
|
||||
:placeholder="form.placeholder"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { defineExpose } from 'vue';
|
||||
|
||||
let props = defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'D',
|
||||
},
|
||||
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const getValidateRule = () => {
|
||||
var item = props.form;
|
||||
var itemProps = item.props;
|
||||
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
if (item.required) {
|
||||
if (!value) {
|
||||
return callback(new Error('请填写' + item.name));
|
||||
}
|
||||
}
|
||||
if (!value) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (itemProps.minLength) {
|
||||
if (value.length < itemProps.minLength) {
|
||||
return callback(new Error('长度不能小于' + itemProps.minLength));
|
||||
}
|
||||
}
|
||||
|
||||
if (itemProps.maxLength) {
|
||||
if (value.length > itemProps.maxLength) {
|
||||
return callback(new Error('长度不能大于' + itemProps.maxLength));
|
||||
}
|
||||
}
|
||||
if (itemProps.regex) {
|
||||
let regExp = new RegExp(itemProps.regex);
|
||||
if (!regExp.test(value)) {
|
||||
return callback(new Error(itemProps.regexDesc));
|
||||
}
|
||||
}
|
||||
return callback();
|
||||
};
|
||||
let ruleArray = [
|
||||
{
|
||||
validator: checkConfig,
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
if (item.required) {
|
||||
ruleArray.push({ required: true, message: '请填写' + item.name, trigger: 'blur' });
|
||||
}
|
||||
return ruleArray;
|
||||
};
|
||||
defineExpose({ getValidateRule });
|
||||
</script>
|
||||
<style scoped>
|
||||
:deep(.formDate div.el-input__wrapper) {
|
||||
width: 100% !important;
|
||||
}
|
||||
:deep(.formDate) {
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<div>
|
||||
<text>{{ !form ? '' : form.placeholder }}</text>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { defineExpose } from 'vue';
|
||||
|
||||
let props = defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'D',
|
||||
},
|
||||
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const getValidateRule = () => {
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
return callback();
|
||||
};
|
||||
let ruleArray = [
|
||||
{
|
||||
validator: checkConfig,
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
|
||||
return ruleArray;
|
||||
};
|
||||
defineExpose({ getValidateRule });
|
||||
</script>
|
||||
@@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<div style="text-align: center; padding-top: 15px; background-color: var(--el-fill-color-light)">
|
||||
<el-text>
|
||||
<el-icon>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
{{ $t('flow.emptyComponent') }}
|
||||
</el-text>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { Check, Plus, Refresh } from '@element-plus/icons-vue';
|
||||
|
||||
let props = defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'D',
|
||||
},
|
||||
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const getValidateRule = () => {
|
||||
var item = props.form;
|
||||
var itemProps = item.props;
|
||||
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
if (item.required) {
|
||||
if (!value) {
|
||||
return callback(new Error('请填写' + item.name));
|
||||
}
|
||||
}
|
||||
if (!value) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (itemProps.minLength) {
|
||||
if (value.length < itemProps.minLength) {
|
||||
return callback(new Error('长度不能小于' + itemProps.minLength));
|
||||
}
|
||||
}
|
||||
|
||||
if (itemProps.maxLength) {
|
||||
if (value.length > itemProps.maxLength) {
|
||||
return callback(new Error('长度不能大于' + itemProps.maxLength));
|
||||
}
|
||||
}
|
||||
if (itemProps.regex) {
|
||||
let regExp = new RegExp(itemProps.regex);
|
||||
if (!regExp.test(value)) {
|
||||
return callback(new Error(itemProps.regexDesc));
|
||||
}
|
||||
}
|
||||
return callback();
|
||||
};
|
||||
let ruleArray = [
|
||||
{
|
||||
validator: checkConfig,
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
if (item.required) {
|
||||
ruleArray.push({ required: true, message: '请填写' + item.name, trigger: 'blur' });
|
||||
}
|
||||
return ruleArray;
|
||||
};
|
||||
defineExpose({ getValidateRule });
|
||||
</script>
|
||||
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-input v-if="mode === 'D'" :disabled="true" :placeholder="!form ? '' : form.placeholder" />
|
||||
<el-input v-else v-model="form.props.value" :disabled="form.perm === 'R'" :placeholder="form.placeholder" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
let props = defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'D',
|
||||
},
|
||||
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const getValidateRule = () => {
|
||||
var item = props.form;
|
||||
var itemProps = item.props;
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
if (item.required) {
|
||||
if (!value) {
|
||||
return callback(new Error('请填写' + item.name));
|
||||
}
|
||||
}
|
||||
if (!value) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (itemProps.minLength) {
|
||||
if (value.length < itemProps.minLength) {
|
||||
return callback(new Error('长度不能小于' + itemProps.minLength));
|
||||
}
|
||||
}
|
||||
|
||||
if (itemProps.maxLength) {
|
||||
if (value.length > itemProps.maxLength) {
|
||||
return callback(new Error('长度不能大于' + itemProps.maxLength));
|
||||
}
|
||||
}
|
||||
if (itemProps.regex) {
|
||||
let regExp = new RegExp(itemProps.regex);
|
||||
if (!regExp.test(value)) {
|
||||
return callback(new Error(itemProps.regexDesc));
|
||||
}
|
||||
}
|
||||
return callback();
|
||||
};
|
||||
let ruleArray = [
|
||||
{
|
||||
validator: checkConfig,
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
if (item.required) {
|
||||
ruleArray.push({ required: true, message: '请填写' + item.name, trigger: 'blur' });
|
||||
}
|
||||
return ruleArray;
|
||||
};
|
||||
defineExpose({ getValidateRule });
|
||||
</script>
|
||||
@@ -0,0 +1,236 @@
|
||||
<template>
|
||||
<div>
|
||||
<template v-if="mode === 'D'">
|
||||
<draggable
|
||||
v-model="targetList"
|
||||
class="drag-content"
|
||||
item-key="index"
|
||||
:sort="true"
|
||||
effect="dark"
|
||||
:group="{ name: 'dragFormList', pull: false, put: true }"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<div class="border okcomponent line" effect="dark" @click.stop="showConfigPanel(element.id)">
|
||||
<el-icon v-if="element.type != 'Empty'" class="deleteIcon" @click.stop="deleteForm(element.id)">
|
||||
<Delete />
|
||||
</el-icon>
|
||||
<el-form-item :label="step2Object[element.id]?.name" :required="step2Object[element.id]?.required">
|
||||
<component style="width: 100%" :is="getFormWidget(element.type)" :id="element.id" v-model:form="step2Object[element.id]"></component>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-card v-for="(item, index) in form.props.value" :key="index" style="margin-bottom: 10px">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>编号:{{ index + 1 }}</span>
|
||||
<el-button
|
||||
v-if="form.props.value.length > 0 && form.perm != 'R'"
|
||||
@click="deleteOneItem(index)"
|
||||
class="button"
|
||||
icon="Delete"
|
||||
text
|
||||
></el-button>
|
||||
</div>
|
||||
</template>
|
||||
<form-render ref="formRenderRefLayout" :form-list="item"></form-render>
|
||||
</el-card>
|
||||
<div style="text-align: center; padding: 15px">
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="addOneItem"
|
||||
:disabled="form.perm === 'R' || (form.props.max && form.props.value.length >= form.props.max)"
|
||||
text
|
||||
>添加明细
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import draggable from 'vuedraggable';
|
||||
|
||||
import {Delete} from '@element-plus/icons-vue';
|
||||
import {computed, ref} from 'vue';
|
||||
|
||||
import getFormName from '/@/views/flow/form/tools/utils/getFormWidget';
|
||||
import FormRender from './render/FormRender.vue';
|
||||
import {useFlowStore} from '../workflow/stores/flow';
|
||||
|
||||
const emit = defineEmits(['showPanel', 'addLayoutOneItem', 'deleteLayoutOneItem']);
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
var config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
return step2.filter((res) => res.id === props.id)[0];
|
||||
});
|
||||
|
||||
const getFormWidget = (name: string) => {
|
||||
//写的时候,组件的起名一定要与dragList中的element名字一模一样,不然会映射不上
|
||||
return getFormName[name];
|
||||
};
|
||||
|
||||
let targetList = computed({
|
||||
get: () => {
|
||||
let value = config.value?.props?.value;
|
||||
if (value?.length == 0) {
|
||||
return [
|
||||
{
|
||||
type: 'Empty',
|
||||
name: '',
|
||||
},
|
||||
];
|
||||
}
|
||||
return value;
|
||||
},
|
||||
set: (v) => {
|
||||
config.value.props.value = v.filter((res) => res.type != 'Layout' && res.type != 'Empty');
|
||||
},
|
||||
});
|
||||
|
||||
const addOneItem = () => {
|
||||
emit('addLayoutOneItem', props.form.id);
|
||||
};
|
||||
|
||||
const deleteOneItem = (index) => {
|
||||
emit('deleteLayoutOneItem', props.form.id, index);
|
||||
};
|
||||
|
||||
const showConfigPanel = (id) => {
|
||||
emit('showPanel', config.value.props.value.filter((res) => res.id === id)[0]);
|
||||
};
|
||||
|
||||
const deleteForm = (id) => {
|
||||
config.value.props.value = config.value.props.value.filter((res) => res.id !== id);
|
||||
|
||||
emit('showPanel', undefined);
|
||||
};
|
||||
var step2Object = computed(() => {
|
||||
var obj = {};
|
||||
|
||||
targetList.value.forEach((res) => (obj[res.id] = res));
|
||||
|
||||
return obj;
|
||||
});
|
||||
|
||||
let props = defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'D',
|
||||
},
|
||||
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
|
||||
index: {
|
||||
type: Number,
|
||||
default: undefined,
|
||||
},
|
||||
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const getValidateRule = () => {
|
||||
var item = props.form;
|
||||
var itemProps = item.props;
|
||||
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
if (item.required) {
|
||||
if (value.length == 0) {
|
||||
return callback(new Error('明细【' + item.name + '】的数量不能为0'));
|
||||
}
|
||||
}
|
||||
if (value.length == 0) {
|
||||
return callback();
|
||||
}
|
||||
if (itemProps.min && value.length < itemProps.min) {
|
||||
return callback(new Error('明细【' + item.name + '】的数量不能小于' + itemProps.min));
|
||||
}
|
||||
if (itemProps.max && value.length > itemProps.max) {
|
||||
return callback(new Error('明细【' + item.name + '】的数量不能大于' + itemProps.max));
|
||||
}
|
||||
|
||||
var result = [];
|
||||
|
||||
for (var fr of formRenderRefLayout.value) {
|
||||
fr.validate(function (valid) {
|
||||
result.push(valid);
|
||||
});
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
if (result.indexOf(false) >= 0) {
|
||||
callback(new Error('明细【' + item.name + '】下的表单验证失败'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
let ruleArray = [
|
||||
{
|
||||
validator: checkConfig,
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
if (item.required) {
|
||||
ruleArray.push({ required: true, message: '请填写' + item.name, trigger: 'change' });
|
||||
}
|
||||
return ruleArray;
|
||||
};
|
||||
const formRenderRefLayout = ref();
|
||||
|
||||
defineExpose({ getValidateRule });
|
||||
</script>
|
||||
<style scoped>
|
||||
.okcomponent {
|
||||
padding: 5px;
|
||||
border: 1px solid;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
@center_width: 360px;
|
||||
|
||||
.drag-content {
|
||||
min-height: 100px;
|
||||
padding: 10px 10px;
|
||||
}
|
||||
|
||||
.deleteIcon {
|
||||
position: absolute;
|
||||
margin-left: calc(@center_width - 80px);
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.deleteIcon:hover {
|
||||
cursor: pointer;
|
||||
color: palevioletred;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.item {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.box-card {
|
||||
width: 480px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,185 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-input-number
|
||||
style="width: 100%"
|
||||
controls-position="right"
|
||||
v-if="mode === 'D'"
|
||||
:disabled="true"
|
||||
:placeholder="!form ? '' : form.placeholder"
|
||||
/>
|
||||
<template v-else>
|
||||
<el-input-number
|
||||
style="width: 100%"
|
||||
controls-position="right"
|
||||
v-model="form.props.value"
|
||||
:precision="form.props.radixNum"
|
||||
:disabled="form.perm === 'R'"
|
||||
:placeholder="form.placeholder"
|
||||
/>
|
||||
<el-text> 大写: </el-text>
|
||||
<el-text type="info">
|
||||
{{ convertCurrency(form.props.value) }}
|
||||
</el-text>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import other from "/@/utils/other";
|
||||
|
||||
function convertCurrency(money) {
|
||||
if (money == null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
//汉字的数字
|
||||
var cnNums = new Array('零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖');
|
||||
//基本单位
|
||||
var cnIntRadice = new Array('', '拾', '佰', '仟');
|
||||
//对应整数部分扩展单位
|
||||
var cnIntUnits = new Array('', '万', '亿', '兆');
|
||||
//对应小数部分单位
|
||||
var cnDecUnits = new Array('角', '分', '毫', '厘');
|
||||
//整数金额时后面跟的字符
|
||||
var cnInteger = '整';
|
||||
//整型完以后的单位
|
||||
var cnIntLast = '元';
|
||||
//最大处理的数字
|
||||
var maxNum = 999999999999999.9999;
|
||||
//金额整数部分
|
||||
var integerNum;
|
||||
//金额小数部分
|
||||
var decimalNum;
|
||||
//输出的中文金额字符串
|
||||
var chineseStr = '';
|
||||
//分离金额后用的数组,预定义
|
||||
var parts;
|
||||
// 传入的参数为空情况
|
||||
if (money == '') {
|
||||
return '';
|
||||
}
|
||||
money = parseFloat(money);
|
||||
if (money >= maxNum) {
|
||||
return '';
|
||||
}
|
||||
// 传入的参数为0情况
|
||||
if (money == 0) {
|
||||
chineseStr = cnNums[0] + cnIntLast + cnInteger;
|
||||
return chineseStr;
|
||||
}
|
||||
// 转为字符串
|
||||
money = money.toString();
|
||||
// indexOf 检测某字符在字符串中首次出现的位置 返回索引值(从0 开始) -1 代表无
|
||||
if (money.indexOf('.') == -1) {
|
||||
integerNum = money;
|
||||
decimalNum = '';
|
||||
} else {
|
||||
parts = money.split('.');
|
||||
integerNum = parts[0];
|
||||
decimalNum = parts[1].substr(0, 4);
|
||||
}
|
||||
//转换整数部分
|
||||
if (parseInt(integerNum, 10) > 0) {
|
||||
let zeroCount = 0;
|
||||
let IntLen = integerNum.length;
|
||||
for (let i = 0; i < IntLen; i++) {
|
||||
let n = integerNum.substr(i, 1);
|
||||
let p = IntLen - i - 1;
|
||||
let q = p / 4;
|
||||
let m = p % 4;
|
||||
if (n == '0') {
|
||||
zeroCount++;
|
||||
} else {
|
||||
if (zeroCount > 0) {
|
||||
chineseStr += cnNums[0];
|
||||
}
|
||||
zeroCount = 0;
|
||||
chineseStr += cnNums[parseInt(n)] + cnIntRadice[m];
|
||||
}
|
||||
if (m == 0 && zeroCount < 4) {
|
||||
chineseStr += cnIntUnits[q];
|
||||
}
|
||||
}
|
||||
// 最后+ 元
|
||||
chineseStr += cnIntLast;
|
||||
}
|
||||
// 转换小数部分
|
||||
if (decimalNum != '') {
|
||||
let decLen = decimalNum.length;
|
||||
for (let i = 0; i < decLen; i++) {
|
||||
let n = decimalNum.substr(i, 1);
|
||||
if (n != '0') {
|
||||
chineseStr += cnNums[Number(n)] + cnDecUnits[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chineseStr == '') {
|
||||
chineseStr += cnNums[0] + cnIntLast + cnInteger;
|
||||
} else if (decimalNum == '') {
|
||||
chineseStr += cnInteger;
|
||||
}
|
||||
|
||||
return chineseStr;
|
||||
}
|
||||
|
||||
let props = defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'D',
|
||||
},
|
||||
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
import { defineExpose } from 'vue';
|
||||
|
||||
const getValidateRule = () => {
|
||||
var item = props.form;
|
||||
var itemProps = item.props;
|
||||
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
if (item.required) {
|
||||
if (!value) {
|
||||
return callback(new Error('请填写' + item.name));
|
||||
}
|
||||
}
|
||||
if (!value) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (itemProps.radixNum) {
|
||||
if (other.getNumberRadixNum(value) > itemProps.radixNum) {
|
||||
return callback(new Error('小数位数不能大于' + itemProps.radixNum));
|
||||
}
|
||||
}
|
||||
|
||||
if (itemProps.min) {
|
||||
if (value < itemProps.min) {
|
||||
return callback(new Error('数值不能小于' + itemProps.min));
|
||||
}
|
||||
}
|
||||
|
||||
if (itemProps.max) {
|
||||
if (value > itemProps.max) {
|
||||
return callback(new Error('数值不能大于' + itemProps.max));
|
||||
}
|
||||
}
|
||||
|
||||
return callback();
|
||||
};
|
||||
let ruleArray = [
|
||||
{
|
||||
validator: checkConfig,
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
if (item.required) {
|
||||
ruleArray.push({ required: true, message: '请填写' + item.name, trigger: 'blur' });
|
||||
}
|
||||
return ruleArray;
|
||||
};
|
||||
defineExpose({ getValidateRule });
|
||||
</script>
|
||||
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<el-select
|
||||
v-if="mode==='D'"
|
||||
:disabled="true"
|
||||
:placeholder="!form?'':form.placeholder"
|
||||
size="large">
|
||||
|
||||
</el-select>
|
||||
<el-select v-else style="width: 100%"
|
||||
multiple
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
v-model="formValue"
|
||||
:disabled="form.perm === 'R'"
|
||||
:placeholder="form.placeholder"
|
||||
size="large"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in form.props.options"
|
||||
:key="item.key"
|
||||
:label="item.value"
|
||||
:value="item.key"
|
||||
/>
|
||||
</el-select>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {defineExpose,computed} from "vue";
|
||||
var formValue = computed({
|
||||
get() {
|
||||
let value = props.form.props.value;
|
||||
return (value&&value.length>0)?(value.map(res=>res.key)):undefined;
|
||||
|
||||
},
|
||||
set(t) {
|
||||
let filterElement = props.form.props.options.filter(res=>t.indexOf(res.key)>=0);
|
||||
props.form.props.value = filterElement
|
||||
}
|
||||
})
|
||||
let props = defineProps({
|
||||
|
||||
mode:{
|
||||
type:String,
|
||||
default:'D'
|
||||
},
|
||||
|
||||
|
||||
form: {
|
||||
type: Object, default: () => {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
const {proxy} = getCurrentInstance();
|
||||
|
||||
|
||||
const getValidateRule = () => {
|
||||
|
||||
var item = props.form;
|
||||
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
|
||||
if (item.required) {
|
||||
if (value==undefined||value.length==0) {
|
||||
return callback(new Error("请选择" + item.name))
|
||||
}
|
||||
}
|
||||
if (value==undefined) {
|
||||
return callback()
|
||||
}
|
||||
|
||||
|
||||
return callback()
|
||||
|
||||
|
||||
}
|
||||
let ruleArray = [{
|
||||
validator: checkConfig, trigger: 'change'
|
||||
}];
|
||||
if (item.required) {
|
||||
ruleArray.push(
|
||||
{required: true, message: '请选择' + item.name, trigger: 'change'}
|
||||
)
|
||||
}
|
||||
return ruleArray
|
||||
|
||||
|
||||
}
|
||||
defineExpose({getValidateRule});
|
||||
|
||||
</script>
|
||||
@@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-input-number
|
||||
style="width: 100%"
|
||||
controls-position="right"
|
||||
v-if="mode === 'D'"
|
||||
:disabled="true"
|
||||
:placeholder="!form ? '' : form.placeholder"
|
||||
/>
|
||||
<el-input-number
|
||||
v-else
|
||||
style="width: 100%"
|
||||
controls-position="right"
|
||||
:precision="form.props.radixNum"
|
||||
v-model="form.props.value"
|
||||
:disabled="form.perm === 'R'"
|
||||
:placeholder="form.placeholder"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import other from "/@/utils/other";
|
||||
|
||||
let props = defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'D',
|
||||
},
|
||||
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
import { defineExpose } from 'vue';
|
||||
|
||||
const getValidateRule = () => {
|
||||
var item = props.form;
|
||||
var itemProps = item.props;
|
||||
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
if (item.required) {
|
||||
if (!value) {
|
||||
return callback(new Error('请填写' + item.name));
|
||||
}
|
||||
}
|
||||
if (!value) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (itemProps.radixNum) {
|
||||
if (other.getNumberRadixNum(value) > itemProps.radixNum) {
|
||||
return callback(new Error('小数位数不能大于' + itemProps.radixNum));
|
||||
}
|
||||
}
|
||||
|
||||
if (itemProps.min) {
|
||||
if (value < itemProps.min) {
|
||||
return callback(new Error('数值不能小于' + itemProps.min));
|
||||
}
|
||||
}
|
||||
|
||||
if (itemProps.max) {
|
||||
if (value > itemProps.max) {
|
||||
return callback(new Error('数值不能大于' + itemProps.max));
|
||||
}
|
||||
}
|
||||
|
||||
return callback();
|
||||
};
|
||||
let ruleArray = [
|
||||
{
|
||||
validator: checkConfig,
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
if (item.required) {
|
||||
ruleArray.push({ required: true, message: '请填写' + item.name, trigger: 'blur' });
|
||||
}
|
||||
return ruleArray;
|
||||
};
|
||||
defineExpose({ getValidateRule });
|
||||
</script>
|
||||
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="form.perm === 'R'" v-html="form.props.value" />
|
||||
<editor v-else v-model:get-html="form.props.value" :placeholder="form.placeholder" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
let props = defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'D',
|
||||
},
|
||||
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const getValidateRule = () => {
|
||||
var item = props.form;
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
if (item.required) {
|
||||
if (!value) {
|
||||
return callback(new Error('请填写' + item.name));
|
||||
}
|
||||
}
|
||||
if (!value) {
|
||||
return callback();
|
||||
}
|
||||
return callback();
|
||||
};
|
||||
let ruleArray = [
|
||||
{
|
||||
validator: checkConfig,
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
if (item.required) {
|
||||
ruleArray.push({ required: true, message: '请填写' + item.name, trigger: 'blur' });
|
||||
}
|
||||
return ruleArray;
|
||||
};
|
||||
defineExpose({ getValidateRule });
|
||||
</script>
|
||||
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-button v-if="mode === 'D'" :disabled="true" circle icon="Plus"></el-button>
|
||||
|
||||
<select-show v-else :disabled="form.perm === 'R'" v-model:orgList="form.props.value" type="dept" :multiple="form.props.multi"></select-show>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import selectShow from '/@/components/OrgSelector/index.vue';
|
||||
|
||||
let props = defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'D',
|
||||
},
|
||||
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const getValidateRule = () => {
|
||||
var item = props.form;
|
||||
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
if (item.required) {
|
||||
if (value.length == 0) {
|
||||
return callback(new Error('请选择' + item.name));
|
||||
}
|
||||
}
|
||||
if (value.length == 0) {
|
||||
return callback();
|
||||
}
|
||||
return callback();
|
||||
};
|
||||
let ruleArray = [
|
||||
{
|
||||
validator: checkConfig,
|
||||
trigger: 'change',
|
||||
},
|
||||
];
|
||||
if (item.required) {
|
||||
ruleArray.push({ required: true, message: '请选择' + item.name, trigger: 'change' });
|
||||
}
|
||||
return ruleArray;
|
||||
};
|
||||
defineExpose({ getValidateRule });
|
||||
</script>
|
||||
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-button v-if="mode === 'D'" :disabled="true" circle icon="Plus"></el-button>
|
||||
|
||||
<select-show
|
||||
v-else
|
||||
:disabled="form.perm === 'R'"
|
||||
v-model:orgList="form.props.value"
|
||||
type="user"
|
||||
:multiple="form.props.multi"
|
||||
:selectSelf="form.props.self"
|
||||
></select-show>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import selectShow from '/@/components/OrgSelector/index.vue';
|
||||
const props = defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'D',
|
||||
},
|
||||
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
onMounted(() => {});
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const getValidateRule = () => {
|
||||
var item = props.form;
|
||||
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
if (item.required) {
|
||||
if (value.length == 0) {
|
||||
return callback(new Error('请选择' + item.name));
|
||||
}
|
||||
}
|
||||
if (value.length == 0) {
|
||||
return callback();
|
||||
}
|
||||
return callback();
|
||||
};
|
||||
let ruleArray = [
|
||||
{
|
||||
validator: checkConfig,
|
||||
trigger: 'change',
|
||||
},
|
||||
];
|
||||
if (item.required) {
|
||||
ruleArray.push({ required: true, message: '请选择' + item.name, trigger: 'change' });
|
||||
}
|
||||
return ruleArray;
|
||||
};
|
||||
defineExpose({ getValidateRule });
|
||||
</script>
|
||||
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div>
|
||||
<text>{{ form?.props.value || form?.placeholder }}</text>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'D',
|
||||
},
|
||||
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const getValidateRule = () => {
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
return callback();
|
||||
};
|
||||
let ruleArray = [
|
||||
{
|
||||
validator: checkConfig,
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
|
||||
return ruleArray;
|
||||
};
|
||||
defineExpose({ getValidateRule });
|
||||
</script>
|
||||
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<div v-if="form.perm === 'R'">
|
||||
<img :src="form.props.value" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<sign
|
||||
ref="esginRef"
|
||||
v-model:bg-color="bgColor"
|
||||
:width="800"
|
||||
:height="300"
|
||||
:is-crop="isCrop"
|
||||
:line-width="lineWidth"
|
||||
:line-color="lineColor"
|
||||
></sign>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<el-link type="primary" @click.stop="handleReset">清空</el-link>
|
||||
<el-link type="primary" @click.stop="handleGenerate" class="ml-4">确认</el-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
const Sign = defineAsyncComponent(() => import('/@/components/Sign/index.vue'));
|
||||
|
||||
let props = defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'D',
|
||||
},
|
||||
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const getValidateRule = () => {
|
||||
var item = props.form;
|
||||
let ruleArray = [];
|
||||
if (item.required) {
|
||||
ruleArray.push({
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
message: '请先签名并确认',
|
||||
});
|
||||
}
|
||||
return ruleArray;
|
||||
};
|
||||
|
||||
const lineWidth = ref(6);
|
||||
const lineColor = ref('#000000');
|
||||
const bgColor = ref('');
|
||||
const isCrop = ref(false);
|
||||
|
||||
const esginRef: any = ref(null);
|
||||
const handleReset = () => {
|
||||
esginRef.value.reset();
|
||||
};
|
||||
const handleGenerate = () => {
|
||||
esginRef.value
|
||||
.generate()
|
||||
.then((res: any) => {
|
||||
props.form.props.value = res;
|
||||
ElMessage.success('签名生成成功,可提交流程发起审批');
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage.warning('请先签名');
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ getValidateRule });
|
||||
</script>
|
||||
<style scoped lang="less"></style>
|
||||
@@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<el-select
|
||||
v-if="mode==='D'"
|
||||
:disabled="true"
|
||||
:placeholder="!form?'':form.placeholder"
|
||||
size="large">
|
||||
|
||||
</el-select>
|
||||
<el-select v-else style="width: 100%"
|
||||
|
||||
v-model="formValue"
|
||||
:disabled="form.perm === 'R'"
|
||||
:placeholder="form.placeholder"
|
||||
size="large"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in form.props.options"
|
||||
:key="item.key"
|
||||
:label="item.value"
|
||||
:value="item.key"
|
||||
/>
|
||||
</el-select>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {defineExpose,computed} from "vue";
|
||||
|
||||
var formValue = computed({
|
||||
get() {
|
||||
let value = props.form.props.value;
|
||||
return (value&&value.length==1)?value[0].key:undefined;
|
||||
},
|
||||
set(t) {
|
||||
let filterElement = props.form.props.options.filter(res=>res.key===t);
|
||||
props.form.props.value = filterElement
|
||||
}
|
||||
})
|
||||
|
||||
let props = defineProps({
|
||||
|
||||
mode:{
|
||||
type:String,
|
||||
default:'D'
|
||||
},
|
||||
|
||||
|
||||
form: {
|
||||
type: Object, default: () => {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
const {proxy} = getCurrentInstance();
|
||||
|
||||
|
||||
const getValidateRule = () => {
|
||||
|
||||
var item = props.form;
|
||||
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
|
||||
if (item.required) {
|
||||
if (value==undefined||value.length==0) {
|
||||
return callback(new Error("请选择" + item.name))
|
||||
}
|
||||
}
|
||||
if (value==undefined) {
|
||||
return callback()
|
||||
}
|
||||
|
||||
|
||||
return callback()
|
||||
|
||||
|
||||
}
|
||||
let ruleArray = [{
|
||||
validator: checkConfig, trigger: 'change'
|
||||
}];
|
||||
if (item.required) {
|
||||
ruleArray.push(
|
||||
{required: true, message: '请选择' + item.name, trigger: 'change'}
|
||||
)
|
||||
}
|
||||
return ruleArray
|
||||
|
||||
|
||||
}
|
||||
defineExpose({getValidateRule});
|
||||
|
||||
|
||||
</script>
|
||||
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-input v-if="mode === 'D'" :disabled="true" resize="none" type="textarea" :placeholder="!form ? '' : form.placeholder" />
|
||||
<el-input
|
||||
v-else
|
||||
type="textarea"
|
||||
:resize="form.perm === 'R' ? 'none' : 'vertical'"
|
||||
v-model="form.props.value"
|
||||
:disabled="form.perm === 'R'"
|
||||
:placeholder="form.placeholder"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
let props = defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'D',
|
||||
},
|
||||
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
import { defineExpose } from 'vue';
|
||||
|
||||
const getValidateRule = () => {
|
||||
var item = props.form;
|
||||
var itemProps = item.props;
|
||||
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
if (item.required) {
|
||||
if (!value) {
|
||||
return callback(new Error('请填写' + item.name));
|
||||
}
|
||||
}
|
||||
if (!value) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (itemProps.minLength) {
|
||||
if (value.length < itemProps.minLength) {
|
||||
return callback(new Error('长度不能小于' + itemProps.minLength));
|
||||
}
|
||||
}
|
||||
|
||||
if (itemProps.maxLength) {
|
||||
if (value.length > itemProps.maxLength) {
|
||||
return callback(new Error('长度不能大于' + itemProps.maxLength));
|
||||
}
|
||||
}
|
||||
if (itemProps.regex) {
|
||||
let regExp = new RegExp(itemProps.regex);
|
||||
if (!regExp.test(value)) {
|
||||
return callback(new Error(itemProps.regexDesc));
|
||||
}
|
||||
}
|
||||
return callback();
|
||||
};
|
||||
let ruleArray = [
|
||||
{
|
||||
validator: checkConfig,
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
if (item.required) {
|
||||
ruleArray.push({ required: true, message: '请填写' + item.name, trigger: 'blur' });
|
||||
}
|
||||
return ruleArray;
|
||||
};
|
||||
defineExpose({ getValidateRule });
|
||||
</script>
|
||||
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-time-picker
|
||||
class="formDate"
|
||||
arrow-control
|
||||
v-if="mode === 'D'"
|
||||
:disabled="true"
|
||||
value-format="HH:mm:ss"
|
||||
:placeholder="!form ? '' : form.placeholder"
|
||||
/>
|
||||
<el-time-picker
|
||||
v-else
|
||||
class="formDate"
|
||||
arrow-control
|
||||
v-model="form.props.value"
|
||||
:disabled="form.perm === 'R'"
|
||||
:placeholder="form.placeholder"
|
||||
value-format="HH:mm:ss"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { defineExpose } from 'vue';
|
||||
|
||||
let props = defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'D',
|
||||
},
|
||||
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const getValidateRule = () => {
|
||||
var item = props.form;
|
||||
var itemProps = item.props;
|
||||
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
if (item.required) {
|
||||
if (!value) {
|
||||
return callback(new Error('请填写' + item.name));
|
||||
}
|
||||
}
|
||||
if (!value) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (itemProps.minLength) {
|
||||
if (value.length < itemProps.minLength) {
|
||||
return callback(new Error('长度不能小于' + itemProps.minLength));
|
||||
}
|
||||
}
|
||||
|
||||
if (itemProps.maxLength) {
|
||||
if (value.length > itemProps.maxLength) {
|
||||
return callback(new Error('长度不能大于' + itemProps.maxLength));
|
||||
}
|
||||
}
|
||||
if (itemProps.regex) {
|
||||
let regExp = new RegExp(itemProps.regex);
|
||||
if (!regExp.test(value)) {
|
||||
return callback(new Error(itemProps.regexDesc));
|
||||
}
|
||||
}
|
||||
return callback();
|
||||
};
|
||||
let ruleArray = [
|
||||
{
|
||||
validator: checkConfig,
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
if (item.required) {
|
||||
ruleArray.push({ required: true, message: '请填写' + item.name, trigger: 'blur' });
|
||||
}
|
||||
return ruleArray;
|
||||
};
|
||||
defineExpose({ getValidateRule });
|
||||
</script>
|
||||
<style scoped>
|
||||
:deep(.formDate div.el-input__wrapper) {
|
||||
width: 100% !important;
|
||||
}
|
||||
:deep(.formDate) {
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<div>
|
||||
<upload-file
|
||||
v-model="form.props.value"
|
||||
:disabled="form.perm === 'E'"
|
||||
:fileSize="form.props.maxSize"
|
||||
:limit="form.props.max"
|
||||
:fileType="form.props.suffixArray"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
let props = defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'D',
|
||||
},
|
||||
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const getValidateRule = () => {
|
||||
const item = props.form;
|
||||
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
if (item.required) {
|
||||
if (value.length == 0) {
|
||||
return callback(new Error('请上传' + item.name));
|
||||
}
|
||||
}
|
||||
if (value.length == 0) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (item.props.min && value.length < item.props.min) {
|
||||
return callback(new Error('上传数量不能小于' + item.props.min));
|
||||
}
|
||||
if (item.props.suffixArray && item.props.suffixArray.length > 0) {
|
||||
for (const name of value.split(',')) {
|
||||
const suffix = name.substring(name.lastIndexOf('.') + 1);
|
||||
if (item.props.suffixArray.indexOf(suffix) < 0) {
|
||||
return callback(new Error('文件只支持' + item.props.suffixArray + '格式'));
|
||||
}
|
||||
}
|
||||
}
|
||||
return callback();
|
||||
};
|
||||
let ruleArray = [
|
||||
{
|
||||
validator: checkConfig,
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
if (item.required) {
|
||||
ruleArray.push({ required: true, message: '请上传' + item.name, trigger: 'blur' });
|
||||
}
|
||||
return ruleArray;
|
||||
};
|
||||
defineExpose({ getValidateRule });
|
||||
</script>
|
||||
<style scoped lang="less"></style>
|
||||
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<div>
|
||||
<upload-img
|
||||
:disabled="form.perm === 'R'"
|
||||
v-model:image-url="form.props.value"
|
||||
:fileSize="form.props.maxSize"
|
||||
:fileType="form.props.suffixArray"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
let props = defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'D',
|
||||
},
|
||||
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const getValidateRule = () => {
|
||||
var item = props.form;
|
||||
|
||||
var checkConfig = (rule: any, value: any, callback: any) => {
|
||||
if (item.required) {
|
||||
if (value.length == 0) {
|
||||
return callback(new Error('请上传' + item.name));
|
||||
}
|
||||
}
|
||||
if (value.length == 0) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (value.length < item.props.min) {
|
||||
return callback(new Error('上传数量不能小于' + item.props.min));
|
||||
}
|
||||
return callback();
|
||||
};
|
||||
let ruleArray = [
|
||||
{
|
||||
validator: checkConfig,
|
||||
trigger: 'blur',
|
||||
},
|
||||
];
|
||||
if (item.required) {
|
||||
ruleArray.push({ required: true, message: '请上传' + item.name, trigger: 'blur' });
|
||||
}
|
||||
return ruleArray;
|
||||
};
|
||||
defineExpose({ getValidateRule });
|
||||
</script>
|
||||
<style scoped lang="less"></style>
|
||||
@@ -0,0 +1,35 @@
|
||||
<script setup lang="ts">
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
import { useFlowStore } from '../../workflow/stores/flow';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
const config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
|
||||
const idObjList = step2.filter((res) => res.id === props.id);
|
||||
if (idObjList.length > 0) {
|
||||
return idObjList[0];
|
||||
}
|
||||
|
||||
let list = step2.filter((res) => res.type === 'Layout');
|
||||
for (const item of list) {
|
||||
let value = item.props.value;
|
||||
const valueList = value.filter((res: any) => res.id === props.id);
|
||||
if (valueList.length > 0) {
|
||||
return valueList[0];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
@@ -0,0 +1,45 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, defineExpose } from 'vue';
|
||||
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
import { useFlowStore } from '../../workflow/stores/flow';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
var config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
let filterElement = step2.filter((res) => res.id === props.id)[0];
|
||||
return filterElement;
|
||||
});
|
||||
const { proxy } = getCurrentInstance();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-form-item label="最小值">
|
||||
<el-date-picker size="default" class="formDate" v-model="config.props.min" value-format="YYYY-MM-DD" type="date" />
|
||||
</el-form-item>
|
||||
<el-form-item label="最大值">
|
||||
<el-date-picker size="default" class="formDate" v-model="config.props.max" value-format="YYYY-MM-DD" type="date" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="默认值">
|
||||
<el-date-picker size="default" class="formDate" value-format="YYYY-MM-DD" v-model="config.props.value" type="date" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.formDate div.el-input__wrapper) {
|
||||
width: 100% !important;
|
||||
}
|
||||
:deep(.formDate) {
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,45 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, defineExpose } from 'vue';
|
||||
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
import { useFlowStore } from '../../workflow/stores/flow';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
var config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
let filterElement = step2.filter((res) => res.id === props.id)[0];
|
||||
return filterElement;
|
||||
});
|
||||
const { proxy } = getCurrentInstance();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-form-item label="最小值">
|
||||
<el-date-picker size="default" class="formDate" v-model="config.props.min" value-format="YYYY-MM-DD HH:mm:ss" type="datetime" />
|
||||
</el-form-item>
|
||||
<el-form-item label="最大值">
|
||||
<el-date-picker size="default" class="formDate" v-model="config.props.max" value-format="YYYY-MM-DD HH:mm:ss" type="datetime" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="默认值">
|
||||
<el-date-picker size="default" class="formDate" value-format="YYYY-MM-DD HH:mm:ss" v-model="config.props.value" type="datetime" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.formDate div.el-input__wrapper) {
|
||||
width: 100% !important;
|
||||
}
|
||||
:deep(.formDate) {
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,50 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, defineExpose } from 'vue';
|
||||
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
import { useFlowStore } from '../../workflow/stores/flow';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
var config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
var idObjList = step2.filter((res) => res.id === props.id);
|
||||
if (idObjList.length > 0) {
|
||||
return idObjList[0];
|
||||
}
|
||||
|
||||
let list = step2.filter((res) => res.type === 'Layout');
|
||||
for (var item of list) {
|
||||
let value = item.props.value;
|
||||
var valueList = value.filter((res) => res.id === props.id);
|
||||
if (valueList.length > 0) {
|
||||
return valueList[0];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const placeHolder = computed(() => {
|
||||
return config.value.placeholder;
|
||||
});
|
||||
|
||||
watch(
|
||||
() => placeHolder.value,
|
||||
(f) => {
|
||||
config.value.props.value = f;
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
@@ -0,0 +1,51 @@
|
||||
<script setup lang="ts">
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
import { useFlowStore } from '../../workflow/stores/flow';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
const config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
|
||||
const idObjList = step2.filter((res) => res.id === props.id);
|
||||
if (idObjList.length > 0) {
|
||||
return idObjList[0];
|
||||
}
|
||||
|
||||
let list = step2.filter((res) => res.type === 'Layout');
|
||||
for (const item of list) {
|
||||
let value = item.props.value;
|
||||
const valueList = value.filter((res: any) => res.id === props.id);
|
||||
if (valueList.length > 0) {
|
||||
return valueList[0];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-form-item :label="$t('flow.minLength')">
|
||||
<el-input-number :step="1" step-strictly v-model="config.props.minLength" style="width: 100%" controls-position="right" :min="1" :max="100" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('flow.maxLength')">
|
||||
<el-input-number :step="1" step-strictly v-model="config.props.maxLength" style="width: 100%" controls-position="right" :min="1" :max="100" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('flow.regularExpression')">
|
||||
<el-input placeholder="^\d+$" v-model="config.props.regex" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('flow.regularExpressionTip')">
|
||||
<el-input :placeholder="$t('flow.inputErrorRegularExpressionTip')" v-model="config.props.regexDesc" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('flow.defaultTip')">
|
||||
<el-input v-model="config.props.value" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,45 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, defineExpose } from 'vue';
|
||||
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
import { useFlowStore } from '../../workflow/stores/flow';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
var config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
var idObjList = step2.filter((res) => res.id === props.id);
|
||||
if (idObjList.length > 0) {
|
||||
return idObjList[0];
|
||||
}
|
||||
|
||||
let list = step2.filter((res) => res.type === 'Layout');
|
||||
for (var item of list) {
|
||||
let value = item.props.value;
|
||||
var valueList = value.filter((res) => res.id === props.id);
|
||||
if (valueList.length > 0) {
|
||||
return valueList[0];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
const { proxy } = getCurrentInstance();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-form-item label="最小数量">
|
||||
<el-input-number v-model="config.props.min" style="width: 100%" controls-position="right" :min="1" :max="100" />
|
||||
</el-form-item>
|
||||
<el-form-item label="最大数量">
|
||||
<el-input-number v-model="config.props.max" style="width: 100%" controls-position="right" :min="1" :max="100" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,65 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, defineExpose } from 'vue';
|
||||
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
import { useFlowStore } from '../../workflow/stores/flow';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
var config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
var idObjList = step2.filter((res) => res.id === props.id);
|
||||
if (idObjList.length > 0) {
|
||||
return idObjList[0];
|
||||
}
|
||||
|
||||
let list = step2.filter((res) => res.type === 'Layout');
|
||||
for (var item of list) {
|
||||
let value = item.props.value;
|
||||
var valueList = value.filter((res) => res.id === props.id);
|
||||
if (valueList.length > 0) {
|
||||
return valueList[0];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
const { proxy } = getCurrentInstance();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-form-item label="格式">
|
||||
<el-checkbox v-model="config.props.showChinese" label="显示大写数字" />
|
||||
<!-- <el-checkbox v-model="config.props.showThousandSymbol" label="显示千位分隔符" />-->
|
||||
</el-form-item>
|
||||
<el-form-item label="最小值">
|
||||
<el-input-number v-model="config.props.min" style="width: 100%" controls-position="right" :min="1" :max="100000000000000" />
|
||||
</el-form-item>
|
||||
<el-form-item label="最大值">
|
||||
<el-input-number v-model="config.props.max" style="width: 100%" controls-position="right" :min="1" :max="100000000000000" />
|
||||
</el-form-item>
|
||||
<el-form-item label="小数位数">
|
||||
<el-input-number
|
||||
:step="1"
|
||||
step-strictly
|
||||
v-model="config.props.radixNum"
|
||||
style="width: 100%"
|
||||
controls-position="right"
|
||||
:min="0"
|
||||
value-on-clear="min"
|
||||
:max="10"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="默认值">
|
||||
<el-input-number :precision="config.props.radixNum" controls-position="right" style="width: 100%" v-model="config.props.value" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,129 @@
|
||||
<script setup lang="ts">
|
||||
import {computed, defineExpose} from "vue";
|
||||
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
});
|
||||
|
||||
import {useFlowStore} from "../../workflow/stores/flow";
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
var config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
var idObjList = step2.filter(res => res.id === props.id);
|
||||
if (idObjList.length > 0) {
|
||||
return idObjList[0];
|
||||
}
|
||||
|
||||
let list = step2.filter(res => res.type === 'Layout');
|
||||
for (var item of list) {
|
||||
let value = item.props.value;
|
||||
var valueList = value.filter(res => res.id === props.id);
|
||||
if (valueList.length > 0) {
|
||||
return valueList[0];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
var options = computed(() => {
|
||||
return config.value.props.options;
|
||||
});
|
||||
|
||||
const {proxy} = getCurrentInstance();
|
||||
|
||||
|
||||
import {Delete, Edit, Search, Share, Upload} from "@element-plus/icons-vue";
|
||||
|
||||
const addOption = () => {
|
||||
options.value.push({
|
||||
key: "",
|
||||
value: "",
|
||||
});
|
||||
};
|
||||
const deleteOption = (index) => {
|
||||
options.value.splice(index, 1);
|
||||
};
|
||||
|
||||
var formValue = computed({
|
||||
get() {
|
||||
let value = config.value.props.value;
|
||||
return (value && value.length > 0) ? (value.map(res => res.key)) : undefined;
|
||||
},
|
||||
set(t) {
|
||||
let filterElement = options.value.filter(res => t.indexOf(res.key) >= 0);
|
||||
config.value.props.value = filterElement
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="config">
|
||||
|
||||
<el-form-item label="选项" required>
|
||||
<div v-for="(item, index) in options" :key="index" class="class_option">
|
||||
<div class="f1">
|
||||
<el-input v-model="item.key" placeholder="选项值key"/>
|
||||
</div>
|
||||
<div class="f2">
|
||||
<el-input v-model="item.value" placeholder="选项标签value"/>
|
||||
</div>
|
||||
<div class="f3">
|
||||
<el-icon :size="20" @click.stop="deleteOption(index)">
|
||||
<Delete/>
|
||||
</el-icon>
|
||||
</div>
|
||||
</div>
|
||||
<el-link type="primary" @click.stop="addOption">添加选项</el-link>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="默认值">
|
||||
<el-select
|
||||
v-model="formValue"
|
||||
multiple
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
placeholder=""
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.key"
|
||||
:label="item.value"
|
||||
:value="item.key"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
$width-f1: 150px;
|
||||
$width-f3: 40px;
|
||||
|
||||
.class_option {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
|
||||
.f1 {
|
||||
width: $width-f1;
|
||||
}
|
||||
|
||||
.f2 {
|
||||
margin-left: 5px;
|
||||
width: calc(100% - #{$width-f1} - #{$width-f3} - 5px);
|
||||
}
|
||||
|
||||
.f3 {
|
||||
width: $width-f3;
|
||||
text-align: center;
|
||||
padding-top: 5px;
|
||||
height: 35.6px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,61 @@
|
||||
<script setup lang="ts">
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
import { useFlowStore } from '../../workflow/stores/flow';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
var config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
var idObjList = step2.filter((res) => res.id === props.id);
|
||||
if (idObjList.length > 0) {
|
||||
return idObjList[0];
|
||||
}
|
||||
|
||||
let list = step2.filter((res) => res.type === 'Layout');
|
||||
for (var item of list) {
|
||||
let value = item.props.value;
|
||||
var valueList = value.filter((res) => res.id === props.id);
|
||||
if (valueList.length > 0) {
|
||||
return valueList[0];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-form-item label="单位">
|
||||
<el-input v-model="config.props.unit" style="width: 100%" maxlength="10" />
|
||||
</el-form-item>
|
||||
<el-form-item label="最小值">
|
||||
<el-input-number v-model="config.props.min" style="width: 100%" controls-position="right" :min="1" :max="100000000000000" />
|
||||
</el-form-item>
|
||||
<el-form-item label="最大值">
|
||||
<el-input-number v-model="config.props.max" style="width: 100%" controls-position="right" :min="1" :max="100000000000000" />
|
||||
</el-form-item>
|
||||
<el-form-item label="小数位数">
|
||||
<el-input-number
|
||||
:step="1"
|
||||
step-strictly
|
||||
v-model="config.props.radixNum"
|
||||
style="width: 100%"
|
||||
controls-position="right"
|
||||
:min="0"
|
||||
value-on-clear="min"
|
||||
:max="10"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="默认值">
|
||||
<el-input-number :precision="config.props.radixNum" controls-position="right" style="width: 100%" v-model="config.props.value" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,35 @@
|
||||
<script setup lang="ts">
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
import { useFlowStore } from '../../workflow/stores/flow';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
const config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
|
||||
const idObjList = step2.filter((res) => res.id === props.id);
|
||||
if (idObjList.length > 0) {
|
||||
return idObjList[0];
|
||||
}
|
||||
|
||||
let list = step2.filter((res) => res.type === 'Layout');
|
||||
for (const item of list) {
|
||||
let value = item.props.value;
|
||||
const valueList = value.filter((res: any) => res.id === props.id);
|
||||
if (valueList.length > 0) {
|
||||
return valueList[0];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
@@ -0,0 +1,78 @@
|
||||
<script setup lang="ts">
|
||||
import employeesDialog from '/@/components/OrgSelector/employeesDialog.vue';
|
||||
import orgItem from '/@/components/OrgSelector/orgItem.vue';
|
||||
import { useFlowStore } from '../../workflow/stores/flow';
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
import { ref } from 'vue';
|
||||
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
var config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
var idObjList = step2.filter((res) => res.id === props.id);
|
||||
if (idObjList.length > 0) {
|
||||
return idObjList[0];
|
||||
}
|
||||
|
||||
let list = step2.filter((res) => res.type === 'Layout');
|
||||
for (var item of list) {
|
||||
let value = item.props.value;
|
||||
var valueList = value.filter((res) => res.id === props.id);
|
||||
if (valueList.length > 0) {
|
||||
return valueList[0];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
|
||||
var defaultValue = computed({
|
||||
get: () => {
|
||||
return config.value.props.value;
|
||||
},
|
||||
set: (s: any[]) => {
|
||||
config.value.props.value = s;
|
||||
},
|
||||
});
|
||||
|
||||
//校验
|
||||
const validate = () => {
|
||||
return true;
|
||||
};
|
||||
defineExpose({ validate });
|
||||
|
||||
let selectUserDialogVisible = ref(false);
|
||||
const afterSelectUser = (data) => {
|
||||
defaultValue.value = data;
|
||||
selectUserDialogVisible.value = false;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<employees-dialog
|
||||
v-model:visible="selectUserDialogVisible"
|
||||
:data="defaultValue"
|
||||
type="dept"
|
||||
:multiple="config.props.multi"
|
||||
@change="afterSelectUser"
|
||||
/>
|
||||
<el-form-item label="选择范围">
|
||||
<el-checkbox v-model="config.props.multi" :disabled="defaultValue.length > 0" label="可选多个部门" />
|
||||
</el-form-item>
|
||||
<el-form-item label="默认值">
|
||||
<el-button circle :icon="Plus" @click.stop="selectUserDialogVisible = true"></el-button>
|
||||
|
||||
<div style="width: 100%">
|
||||
<org-item v-model:data="defaultValue" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,82 @@
|
||||
<script setup lang="ts">
|
||||
import employeesDialog from '/@/components/OrgSelector/employeesDialog.vue';
|
||||
import orgItem from '/@/components/OrgSelector/orgItem.vue';
|
||||
import { useFlowStore } from '../../workflow/stores/flow';
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
import { ref } from 'vue';
|
||||
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
var config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
var idObjList = step2.filter((res) => res.id === props.id);
|
||||
if (idObjList.length > 0) {
|
||||
return idObjList[0];
|
||||
}
|
||||
|
||||
let list = step2.filter((res) => res.type === 'Layout');
|
||||
for (var item of list) {
|
||||
let value = item.props.value;
|
||||
var valueList = value.filter((res) => res.id === props.id);
|
||||
if (valueList.length > 0) {
|
||||
return valueList[0];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
|
||||
var defaultValue = computed({
|
||||
get: () => {
|
||||
return config.value.props.value;
|
||||
},
|
||||
set: (s: any[]) => {
|
||||
config.value.props.value = s;
|
||||
},
|
||||
});
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
//校验
|
||||
const validate = () => {
|
||||
return true;
|
||||
};
|
||||
defineExpose({ validate });
|
||||
|
||||
let selectUserDialogVisible = ref(false);
|
||||
const afterSelectUser = (data) => {
|
||||
defaultValue.value = data;
|
||||
selectUserDialogVisible.value = false;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<employees-dialog
|
||||
v-model:visible="selectUserDialogVisible"
|
||||
:data="defaultValue"
|
||||
type="user"
|
||||
:multiple="config.props.multi"
|
||||
@change="afterSelectUser"
|
||||
/>
|
||||
<el-form-item label="选择范围">
|
||||
<el-checkbox v-model="config.props.self" :disabled="defaultValue.length > 0" label="可选自己" />
|
||||
<el-checkbox v-model="config.props.multi" :disabled="defaultValue.length > 0" label="可选多人" />
|
||||
</el-form-item>
|
||||
<el-form-item label="默认值">
|
||||
<el-button circle :icon="Plus" @click.stop="selectUserDialogVisible = true"></el-button>
|
||||
|
||||
<div style="width: 100%">
|
||||
<org-item v-model:data="defaultValue" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,43 @@
|
||||
<script setup lang="ts">
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
import { useFlowStore } from '../../workflow/stores/flow';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
var config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
var idObjList = step2.filter((res) => res.id === props.id);
|
||||
if (idObjList.length > 0) {
|
||||
return idObjList[0];
|
||||
}
|
||||
|
||||
let list = step2.filter((res) => res.type === 'Layout');
|
||||
for (var item of list) {
|
||||
let value = item.props.value;
|
||||
var valueList = value.filter((res) => res.id === props.id);
|
||||
if (valueList.length > 0) {
|
||||
return valueList[0];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
|
||||
computed(() => {
|
||||
return config.value?.placeholder;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-form-item :label="$t('flow.servicePrefix')">
|
||||
<el-input :placeholder="$t('flow.servicePrefixTips')" v-model="config.props.prefix" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,39 @@
|
||||
<script setup lang="ts">
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
import { useFlowStore } from '../../workflow/stores/flow';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
const config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
|
||||
const idObjList = step2.filter((res) => res.id === props.id);
|
||||
if (idObjList.length > 0) {
|
||||
return idObjList[0];
|
||||
}
|
||||
|
||||
let list = step2.filter((res) => res.type === 'Layout');
|
||||
for (const item of list) {
|
||||
let value = item.props.value;
|
||||
const valueList = value.filter((res: any) => res.id === props.id);
|
||||
if (valueList.length > 0) {
|
||||
return valueList[0];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-form-item label="默认值">
|
||||
<el-input v-model="config.props.value" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,128 @@
|
||||
<script setup lang="ts">
|
||||
import {computed, defineExpose} from "vue";
|
||||
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
});
|
||||
|
||||
import {useFlowStore} from "../../workflow/stores/flow";
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
var config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
var idObjList = step2.filter(res => res.id === props.id);
|
||||
if (idObjList.length > 0) {
|
||||
return idObjList[0];
|
||||
}
|
||||
|
||||
let list = step2.filter(res => res.type === 'Layout');
|
||||
for (var item of list) {
|
||||
let value = item.props.value;
|
||||
var valueList = value.filter(res => res.id === props.id);
|
||||
if (valueList.length > 0) {
|
||||
return valueList[0];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
|
||||
var options = computed(() => {
|
||||
return config.value.props.options;
|
||||
});
|
||||
|
||||
const {proxy} = getCurrentInstance();
|
||||
|
||||
|
||||
import {Delete, Edit, Search, Share, Upload} from "@element-plus/icons-vue";
|
||||
|
||||
const addOption = () => {
|
||||
options.value.push({
|
||||
key: "",
|
||||
value: "",
|
||||
});
|
||||
};
|
||||
const deleteOption = (index) => {
|
||||
options.value.splice(index, 1);
|
||||
};
|
||||
|
||||
var formValue = computed({
|
||||
get() {
|
||||
let value = config.value.props.value;
|
||||
return (value && value.length == 1) ? value[0].key : undefined;
|
||||
},
|
||||
set(t) {
|
||||
let filterElement = options.value.filter(res => res.key === t);
|
||||
config.value.props.value = filterElement
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="config">
|
||||
|
||||
<el-form-item label="选项" required>
|
||||
<div v-for="(item, index) in options" :key="index" class="class_option">
|
||||
<div class="f1">
|
||||
<el-input v-model="item.key" placeholder="选项值key"/>
|
||||
</div>
|
||||
<div class="f2">
|
||||
<el-input v-model="item.value" placeholder="选项标签value"/>
|
||||
</div>
|
||||
<div class="f3">
|
||||
<el-icon :size="20" @click.stop="deleteOption(index)">
|
||||
<Delete/>
|
||||
</el-icon>
|
||||
</div>
|
||||
</div>
|
||||
<el-link type="primary" @click.stop="addOption">添加选项</el-link>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="默认值">
|
||||
<el-select
|
||||
v-model="formValue"
|
||||
placeholder=""
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.key"
|
||||
:label="item.value"
|
||||
:value="item.key"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
$f1_width: 150px;
|
||||
$f3_width: 40px;
|
||||
|
||||
.class_option {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
|
||||
.f1 {
|
||||
width: $f1_width;
|
||||
}
|
||||
|
||||
.f2 {
|
||||
margin-left: 5px;
|
||||
width: calc(100% - #{$f1_width} - #{$f3_width} - 5px);
|
||||
}
|
||||
|
||||
.f3 {
|
||||
width: $f3_width;
|
||||
text-align: center;
|
||||
padding-top: 5px;
|
||||
height: 35.6px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,50 @@
|
||||
<script setup lang="ts">
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
import { useFlowStore } from '../../workflow/stores/flow';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
var config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
var idObjList = step2.filter((res) => res.id === props.id);
|
||||
if (idObjList.length > 0) {
|
||||
return idObjList[0];
|
||||
}
|
||||
|
||||
let list = step2.filter((res) => res.type === 'Layout');
|
||||
for (var item of list) {
|
||||
let value = item.props.value;
|
||||
var valueList = value.filter((res) => res.id === props.id);
|
||||
if (valueList.length > 0) {
|
||||
return valueList[0];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-form-item :label="$t('flow.minLength')">
|
||||
<el-input-number :step="1" step-strictly v-model="config.props.minLength" style="width: 100%" controls-position="right" :min="1" :max="100" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('flow.maxLength')">
|
||||
<el-input-number :step="1" step-strictly v-model="config.props.maxLength" style="width: 100%" controls-position="right" :min="1" :max="100" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('flow.regularExpression')">
|
||||
<el-input placeholder="^\d+$" v-model="config.props.regex" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('flow.regularExpressionTip')">
|
||||
<el-input :placeholder="$t('flow.inputErrorRegularExpressionTip')" v-model="config.props.regexDesc" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('flow.defaultTip')">
|
||||
<el-input v-model="config.props.value" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,42 @@
|
||||
<script setup lang="ts">
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
import { useFlowStore } from '../../workflow/stores/flow';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
var config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
let filterElement = step2.filter((res) => res.id === props.id)[0];
|
||||
return filterElement;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-form-item label="最小值">
|
||||
<el-time-picker arrow-control size="default" class="formDate" v-model="config.props.min" value-format="HH:mm:ss" />
|
||||
</el-form-item>
|
||||
<el-form-item label="最大值">
|
||||
<el-time-picker arrow-control size="default" class="formDate" v-model="config.props.max" value-format="HH:mm:ss" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="默认值">
|
||||
<el-time-picker arrow-control size="default" class="formDate" value-format="HH:mm:ss" v-model="config.props.value" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.formDate div.el-input__wrapper) {
|
||||
width: 100% !important;
|
||||
}
|
||||
:deep(.formDate) {
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,60 @@
|
||||
<script setup lang="ts">
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
import { useFlowStore } from '../../workflow/stores/flow';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
var config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
var idObjList = step2.filter((res) => res.id === props.id);
|
||||
if (idObjList.length > 0) {
|
||||
return idObjList[0];
|
||||
}
|
||||
|
||||
let list = step2.filter((res) => res.type === 'Layout');
|
||||
for (var item of list) {
|
||||
let value = item.props.value;
|
||||
var valueList = value.filter((res) => res.id === props.id);
|
||||
if (valueList.length > 0) {
|
||||
return valueList[0];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-form-item label="最小数量">
|
||||
<el-input-number v-model="config.props.min" style="width: 100%" controls-position="right" :min="1" value-on-clear="min" :max="10" />
|
||||
</el-form-item>
|
||||
<el-form-item label="最大数量">
|
||||
<el-input-number v-model="config.props.max" style="width: 100%" controls-position="right" :min="1" value-on-clear="max" :max="10" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="文件大小(MB)">
|
||||
<el-input-number v-model="config.props.maxSize" style="width: 100%" controls-position="right" :min="0.01" value-on-clear="max" :max="10" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="文件后缀(jpg,jpeg,png)">
|
||||
<el-select
|
||||
v-model="config.props.suffixArray"
|
||||
style="width: 100%"
|
||||
multiple
|
||||
filterable
|
||||
allow-create
|
||||
default-first-option
|
||||
:reserve-keyword="false"
|
||||
placeholder="请输入支持的后缀,回车确定"
|
||||
>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,39 @@
|
||||
<script setup lang="ts">
|
||||
let props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
import { useFlowStore } from '../../workflow/stores/flow';
|
||||
|
||||
let flowStore = useFlowStore();
|
||||
|
||||
var config = computed(() => {
|
||||
let step2 = flowStore.step2;
|
||||
var idObjList = step2.filter((res) => res.id === props.id);
|
||||
if (idObjList.length > 0) {
|
||||
return idObjList[0];
|
||||
}
|
||||
|
||||
let list = step2.filter((res) => res.type === 'Layout');
|
||||
for (var item of list) {
|
||||
let value = item.props.value;
|
||||
var valueList = value.filter((res) => res.id === props.id);
|
||||
if (valueList.length > 0) {
|
||||
return valueList[0];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-form-item label="文件大小(MB)">
|
||||
<el-input-number v-model="config.props.maxSize" style="width: 100%" controls-position="right" :min="0.01" value-on-clear="max" :max="10" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,263 @@
|
||||
import { FormGroupVO } from './types';
|
||||
|
||||
const formGroupConfig: FormGroupVO[] = [
|
||||
{
|
||||
name: '文本',
|
||||
type: 'Text',
|
||||
formList: [
|
||||
{
|
||||
name: '流水号',
|
||||
icon: 'Timer',
|
||||
type: 'Sequence',
|
||||
typeName: '说明',
|
||||
placeholder: 'PREFIX2023072300001',
|
||||
required: false,
|
||||
props: {
|
||||
value: '',
|
||||
prefix: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '单行文本',
|
||||
type: 'Input',
|
||||
typeName: '单行文本',
|
||||
icon: 'EditPen',
|
||||
placeholder: '请填写',
|
||||
required: false,
|
||||
props: {
|
||||
value: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '多行文本',
|
||||
icon: 'More',
|
||||
type: 'Textarea',
|
||||
typeName: '多行文本',
|
||||
placeholder: '请填写',
|
||||
required: false,
|
||||
props: {
|
||||
value: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '富文本',
|
||||
type: 'RichEditor',
|
||||
typeName: '富文本',
|
||||
icon: 'Notebook',
|
||||
placeholder: '请填写',
|
||||
required: false,
|
||||
props: {
|
||||
value: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '签名',
|
||||
icon: 'EditPen',
|
||||
type: 'Sign',
|
||||
typeName: '说明',
|
||||
placeholder: '请填写',
|
||||
required: false,
|
||||
props: {
|
||||
value: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '说明',
|
||||
icon: 'ChatLineSquare',
|
||||
type: 'Description',
|
||||
typeName: '说明',
|
||||
placeholder: '请填写',
|
||||
required: false,
|
||||
props: {
|
||||
value: '',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: '数值',
|
||||
type: 'Number',
|
||||
formList: [
|
||||
{
|
||||
name: '数字',
|
||||
type: 'Number',
|
||||
icon: 'Edit',
|
||||
|
||||
typeName: '数字',
|
||||
placeholder: '请填写',
|
||||
required: false,
|
||||
props: {
|
||||
radixNum: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '金额',
|
||||
type: 'Money',
|
||||
icon: 'Money',
|
||||
|
||||
typeName: '金额',
|
||||
placeholder: '请填写',
|
||||
required: false,
|
||||
props: {
|
||||
radixNum: 0,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: '日期-时间',
|
||||
type: 'DateTime',
|
||||
formList: [
|
||||
{
|
||||
name: '日期',
|
||||
type: 'Date',
|
||||
icon: 'Calendar',
|
||||
|
||||
typeName: '日期',
|
||||
placeholder: '请选择',
|
||||
required: false,
|
||||
props: {
|
||||
radixNum: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '日期时间',
|
||||
type: 'DateTime',
|
||||
icon: 'AlarmClock',
|
||||
|
||||
typeName: '日期时间',
|
||||
placeholder: '请选择',
|
||||
required: false,
|
||||
props: {
|
||||
radixNum: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '时间',
|
||||
type: 'Time',
|
||||
icon: 'Timer',
|
||||
|
||||
typeName: '时间',
|
||||
placeholder: '请选择',
|
||||
required: false,
|
||||
props: {
|
||||
radixNum: 0,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: '选项',
|
||||
type: 'Option',
|
||||
formList: [
|
||||
{
|
||||
name: '单选',
|
||||
icon: 'Select',
|
||||
type: 'SingleSelect',
|
||||
typeName: '单选',
|
||||
placeholder: '请选择',
|
||||
required: false,
|
||||
props: {
|
||||
options: [
|
||||
{
|
||||
key: '',
|
||||
value: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '多选',
|
||||
type: 'MultiSelect',
|
||||
typeName: '多选',
|
||||
icon: 'Finished',
|
||||
placeholder: '请选择',
|
||||
required: false,
|
||||
props: {
|
||||
value: [],
|
||||
options: [
|
||||
{
|
||||
key: '',
|
||||
value: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '省市区',
|
||||
type: 'Area',
|
||||
typeName: '省市区',
|
||||
icon: 'MapLocation',
|
||||
placeholder: '请选择',
|
||||
required: false,
|
||||
props: {
|
||||
value: '',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: '其他',
|
||||
type: 'Other',
|
||||
formList: [
|
||||
{
|
||||
name: '图片',
|
||||
type: 'UploadImage',
|
||||
typeName: '图片',
|
||||
icon: 'Picture',
|
||||
placeholder: '请选择',
|
||||
required: false,
|
||||
props: {
|
||||
value: '',
|
||||
maxSize: 10,
|
||||
suffixArray: ['image/jpeg', 'image/png', 'image/gif'],
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: '文件',
|
||||
type: 'UploadFile',
|
||||
typeName: '文件',
|
||||
icon: 'Upload',
|
||||
placeholder: '请选择',
|
||||
required: false,
|
||||
props: {
|
||||
value: '',
|
||||
min: 1,
|
||||
max: 10,
|
||||
maxSize: 10,
|
||||
suffixArray: ['png', 'jpg', 'jpeg', 'doc', 'xls', 'ppt', 'txt', 'pdf', 'docx', 'xlsx', 'pptx'],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '用户',
|
||||
type: 'SelectUser',
|
||||
typeName: '用户',
|
||||
placeholder: '请选择',
|
||||
icon: 'User',
|
||||
|
||||
required: false,
|
||||
props: {
|
||||
multi: false,
|
||||
self: false,
|
||||
value: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '部门',
|
||||
icon: 'OfficeBuilding',
|
||||
type: 'SelectDept',
|
||||
typeName: '部门',
|
||||
placeholder: '请选择',
|
||||
required: false,
|
||||
props: {
|
||||
multi: false,
|
||||
self: false,
|
||||
value: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export { formGroupConfig };
|
||||
@@ -0,0 +1,47 @@
|
||||
export interface FormGroupVO {
|
||||
name: string;
|
||||
formList: FormVO[];
|
||||
}
|
||||
export interface FormVO {
|
||||
name: string | '';
|
||||
id: String | '';
|
||||
type: string | '';
|
||||
typeName: string | '';
|
||||
placeholder: string;
|
||||
required: boolean;
|
||||
icon: String;
|
||||
props: FormConfigVO;
|
||||
}
|
||||
export interface FormConfigVO {
|
||||
minLength: Number;
|
||||
maxLength: Number;
|
||||
|
||||
value: any | '';
|
||||
regex: string | '';
|
||||
regexDesc: string | '';
|
||||
min: Number;
|
||||
max: Number;
|
||||
radixNum: Number;
|
||||
showChinese: boolean;
|
||||
self: boolean;
|
||||
multi: boolean;
|
||||
showThousandSymbol: boolean;
|
||||
fileList: any[];
|
||||
unit: string;
|
||||
options: FormConfigOptionVO[];
|
||||
maxSize: Number;
|
||||
suffixArray: String[];
|
||||
prefix: string | '';
|
||||
}
|
||||
|
||||
export interface FormConfigOptionVO {
|
||||
key: String;
|
||||
value: String;
|
||||
}
|
||||
|
||||
export interface FormConfigUserVO {
|
||||
id: string;
|
||||
name: string;
|
||||
type: string;
|
||||
avatar: string;
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-aside width="400px">
|
||||
<div effect="dark">
|
||||
<h4 style="text-align: center">{{ $t('flow.componentLibrary') }}</h4>
|
||||
<div v-for="item in oriFormList" :key="item.id">
|
||||
<h5 style="padding-left: 60px">{{ $i18n.locale === 'en' ? item.type : item.name }}</h5>
|
||||
<draggable
|
||||
v-model="item.formList"
|
||||
ghost-class="ghost"
|
||||
:force-fallback="true"
|
||||
item-key="index"
|
||||
:sort="false"
|
||||
@end="dragEnd"
|
||||
@start="drag = true"
|
||||
class="leftItem"
|
||||
:animation="300"
|
||||
:group="{ name: 'dragFormList', pull: 'clone', put: false }"
|
||||
:clone="cloneFunc"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<div class="zj">
|
||||
<el-button size="large" style="width: 100%" :icon="element.icon">{{ $i18n.locale === 'en' ? element.type : element.name }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
</div>
|
||||
</el-aside>
|
||||
<el-main>
|
||||
<div style="display: flex; flex-direction: row">
|
||||
<div class="f11">
|
||||
<el-form label-position="top">
|
||||
<draggable
|
||||
v-model="targetList"
|
||||
class="drag-content"
|
||||
item-key="index"
|
||||
:sort="true"
|
||||
effect="dark"
|
||||
:group="{ name: 'dragFormList', pull: true, put: true }"
|
||||
@change="dragChanged"
|
||||
>
|
||||
<template #item="{ element, index }">
|
||||
<div class="border okcomponent line" effect="dark" @click.stop="showCurrentPageConfigPanel(element.id)">
|
||||
<el-icon v-if="element.type != 'Empty'" class="deleteIcon" @click.stop="deleteForm(element.id)">
|
||||
<Delete />
|
||||
</el-icon>
|
||||
<el-form-item :label="step2Object[element.id]?.name" :required="step2Object[element.id]?.required">
|
||||
<component
|
||||
style="width: 100%"
|
||||
@showPanel="showPanel"
|
||||
:index="index"
|
||||
:is="getFormWidget(element.type)"
|
||||
:id="element.id"
|
||||
v-model:form="step2Object[element.id]"
|
||||
></component>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<el-drawer v-model="drawer">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
{{ currentForm?.typeName }}
|
||||
</div>
|
||||
</template>
|
||||
<el-form label-width="120px" label-position="top">
|
||||
<el-form-item required label="字段ID">
|
||||
<el-input v-model="currentForm.id" maxlength="50" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item required :label="$t('flow.title')">
|
||||
<el-input v-model="currentForm.name" maxlength="10" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('flow.tips')" :required="currentForm?.type === 'Description'">
|
||||
<el-input v-model="currentForm.placeholder" maxlength="50" />
|
||||
</el-form-item>
|
||||
|
||||
<component :is="getFormConfigWidget(currentForm?.type)" :id="currentForm?.id" ref="currentFormConfigRef"></component>
|
||||
<el-form-item :label="$t('flow.other')">
|
||||
<el-checkbox v-model="currentForm.required" :label="$t('flow.required')" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</template>
|
||||
<script lang="ts" setup name="flow-form-designer">
|
||||
import getFormName from '/@/views/flow/form/tools/utils/getFormWidget';
|
||||
import getFormConfigName from '/@/views/flow/form/tools/utils/getFormConfigWidget';
|
||||
import { formValidateDict } from '/@/views/flow/form/tools/utils/formValidate';
|
||||
import { Delete } from '@element-plus/icons-vue';
|
||||
import { useFlowStore } from '../workflow/stores/flow';
|
||||
import draggable from 'vuedraggable';
|
||||
import { FormGroupVO } from '/@/views/flow/form/const/types';
|
||||
import { formGroupConfig } from '/@/views/flow/form/const/data';
|
||||
import { computed } from 'vue';
|
||||
import other from '/@/utils/other';
|
||||
|
||||
const drag = ref(false);
|
||||
const currentForm = ref();
|
||||
const drawer = ref(false);
|
||||
let oriFormList = ref<FormGroupVO[]>(formGroupConfig);
|
||||
|
||||
const flowStore = useFlowStore();
|
||||
|
||||
const currentFormConfigRef = ref();
|
||||
const step2List = computed(() => flowStore.step2);
|
||||
const step2Object = computed(() => {
|
||||
const obj = {};
|
||||
|
||||
step2List.value.forEach((res) => (obj[res.id] = res));
|
||||
|
||||
return obj;
|
||||
});
|
||||
|
||||
const cloneFunc = (el) => {
|
||||
el.id = other.getNonDuplicateID();
|
||||
return el;
|
||||
};
|
||||
const deleteForm = (id) => {
|
||||
const existForm = flowStore.step2.find((res) => res.id === id);
|
||||
if (existForm?.type === 'Layout' && currentForm.value) {
|
||||
//明细
|
||||
const value = existForm.props.value;
|
||||
const filter = value.filter((res) => res.id === currentForm.value.id);
|
||||
if (filter.length > 0) {
|
||||
currentForm.value = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
flowStore.setStep2(flowStore.step2.filter((res) => res.id !== id));
|
||||
|
||||
if (currentForm.value && currentForm.value?.id === id) {
|
||||
currentForm.value = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const showCurrentPageConfigPanel = (id) => {
|
||||
currentForm.value = flowStore.step2.find((res) => res.id === id);
|
||||
drawer.value = true;
|
||||
};
|
||||
const showPanel = (form) => {
|
||||
currentForm.value = form;
|
||||
};
|
||||
|
||||
const getFormWidget = (name) => {
|
||||
//写的时候,组件的起名一定要与dragList中的element名字一模一样,不然会映射不上
|
||||
return getFormName[name];
|
||||
};
|
||||
|
||||
const getFormConfigWidget = (name) => {
|
||||
//写的时候,组件的起名一定要与dragList中的element名字一模一样,不然会映射不上
|
||||
return getFormConfigName[name];
|
||||
};
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const dragEnd = (a) => {
|
||||
drag.value = false;
|
||||
oriFormList.value = other.deepClone(oriFormList.value);
|
||||
};
|
||||
|
||||
const dragChanged = (a) => {};
|
||||
|
||||
const targetList = computed({
|
||||
get: () => {
|
||||
const value = flowStore.step2;
|
||||
if (value?.length == 0) {
|
||||
return [
|
||||
{
|
||||
type: 'Empty',
|
||||
name: '',
|
||||
},
|
||||
];
|
||||
}
|
||||
return value;
|
||||
},
|
||||
set: (v) => {
|
||||
const value = v.filter((res) => res.type != 'Empty');
|
||||
flowStore.setStep2(value);
|
||||
},
|
||||
});
|
||||
|
||||
const validate = (f) => {
|
||||
const err = [];
|
||||
|
||||
const formList = step2List.value;
|
||||
if (formList.length == 0) {
|
||||
err.push('表单不能为空');
|
||||
}
|
||||
|
||||
console.log(formList);
|
||||
|
||||
for (let form of formList) {
|
||||
const count = formList.filter((item) => item.id === form.id).length;
|
||||
if (count > 1) {
|
||||
err.push(`发现字段ID重复: ${form.id}`);
|
||||
}
|
||||
|
||||
const formValidateDictElement = formValidateDict[form.type];
|
||||
if (formValidateDictElement) {
|
||||
const result = formValidateDictElement(form, proxy);
|
||||
|
||||
if (!result.valid) {
|
||||
err.push(result.msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const newList = Array.from(new Set(formList.map((res) => res.name)));
|
||||
|
||||
if (newList.length < formList.length) {
|
||||
err.push('表单名称不能重复');
|
||||
}
|
||||
|
||||
f(err.length == 0, err);
|
||||
};
|
||||
defineExpose({ validate });
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
$width: 140px;
|
||||
$f22_width: 400px;
|
||||
$center_width: 360px;
|
||||
|
||||
.leftItem {
|
||||
padding-left: 50px;
|
||||
}
|
||||
|
||||
.zj {
|
||||
display: inline-block;
|
||||
width: $width;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.drag-content {
|
||||
border: 1px solid;
|
||||
width: $center_width;
|
||||
border-radius: 10px;
|
||||
padding: 10px 10px;
|
||||
}
|
||||
|
||||
.f11 {
|
||||
width: calc(100% - #{$f22_width});
|
||||
}
|
||||
|
||||
.f22 {
|
||||
width: $f22_width;
|
||||
}
|
||||
|
||||
.okcomponent {
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.deleteIcon {
|
||||
margin-left: calc(#{$center_width} - 50px);
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.deleteIcon:hover {
|
||||
cursor: pointer;
|
||||
color: palevioletred;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,97 @@
|
||||
<script setup lang="ts">
|
||||
import getFormName from '/@/views/flow/form/tools/utils/getFormWidget';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import type { FormRules } from 'element-plus';
|
||||
|
||||
const getFormWidget = (name: string) => {
|
||||
//写的时候,组件的起名一定要与dragList中的element名字一模一样,不然会映射不上
|
||||
return getFormName[name];
|
||||
};
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
let props = defineProps({
|
||||
formList: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
let formList = props.formList;
|
||||
|
||||
for (var item of formList) {
|
||||
let id = item.id;
|
||||
if (proxy.$refs['form' + id]?.length > 0) {
|
||||
let validateRule = proxy.$refs['form' + id][0].getValidateRule();
|
||||
rules[id] = validateRule;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['addLayoutOneItem', 'deleteLayoutOneItem']);
|
||||
|
||||
const addLayoutOneItem = (id) => {
|
||||
emit('addLayoutOneItem', id);
|
||||
};
|
||||
const deleteLayoutOneItem = (id, index) => {
|
||||
emit('deleteLayoutOneItem', id, index);
|
||||
};
|
||||
|
||||
const ruleFormRef = ref();
|
||||
|
||||
const rules = reactive<FormRules>({});
|
||||
|
||||
const validate = (f) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
f(valid);
|
||||
});
|
||||
};
|
||||
defineExpose({ validate });
|
||||
|
||||
const formValue = computed(() => {
|
||||
var obj = {};
|
||||
|
||||
for (let item of props.formList) {
|
||||
obj[item.id] = item.props.value;
|
||||
if (item.type === 'Layout') {
|
||||
let subList = item.props.value;
|
||||
|
||||
var d = [];
|
||||
for (var array of subList) {
|
||||
var v = {};
|
||||
|
||||
for (var subItem of array) {
|
||||
let value = subItem.props.value;
|
||||
v[subItem.id] = value;
|
||||
}
|
||||
d.push(v);
|
||||
}
|
||||
obj[item.id] = d;
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-form label-position="top" :rules="rules" :model="formValue" ref="ruleFormRef">
|
||||
<template v-for="(item, index) in formList">
|
||||
<el-form-item
|
||||
v-if="item.perm != 'H'"
|
||||
:label="item.name + (item.props.unit ? '(' + item.props.unit + ')' : '')"
|
||||
:prop="!item ? '' : item.id"
|
||||
:required="!item ? false : item.required"
|
||||
>
|
||||
<component
|
||||
style="width: 100%"
|
||||
@addLayoutOneItem="addLayoutOneItem"
|
||||
@deleteLayoutOneItem="deleteLayoutOneItem"
|
||||
:is="getFormWidget(item.type)"
|
||||
mode="RUN"
|
||||
:ref="'form' + item.id"
|
||||
:form="item"
|
||||
></component>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
</template>
|
||||
@@ -0,0 +1,101 @@
|
||||
<script setup lang="ts">
|
||||
import selectShow from '/@/components/OrgSelector/index.vue';
|
||||
|
||||
let props = defineProps({
|
||||
nodeUser: {
|
||||
type: Object,
|
||||
dafault: () => {},
|
||||
},
|
||||
row: {
|
||||
type: Array,
|
||||
dafault: () => [],
|
||||
},
|
||||
disableSelect: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
import { Check, Plus, Refresh } from '@element-plus/icons-vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div style="padding: 10px">
|
||||
<el-timeline :reverse="false">
|
||||
<el-timeline-item
|
||||
v-for="(node, index) in row"
|
||||
:key="index"
|
||||
size="large"
|
||||
:color="node.status != 2 ? (node.status == 1 ? 'pink' : 'green') : 'blue'"
|
||||
:icon="node.status == 2 ? Check : node.status == 1 ? Plus : Refresh"
|
||||
>
|
||||
<template v-if="node.selectUser && (!nodeUser[node.id] || nodeUser[node.id]?.length == 0)">
|
||||
<p style="color: red">
|
||||
{{ node.name }}
|
||||
<template v-if="node.placeholder && node.placeholder.length > 0">[{{ node.placeholder }}]</template>
|
||||
</p>
|
||||
</template>
|
||||
<template v-else>
|
||||
<p>
|
||||
{{ node.name }}
|
||||
<template v-if="node.placeholder && node.placeholder.length > 0">[{{ node.placeholder }}]</template>
|
||||
</p>
|
||||
</template>
|
||||
<!-- 渲染用户头像列表-->
|
||||
<div v-if="node.userVoList && node.userVoList.length > 0" style="display: flex; flex-direction: row; flex-wrap: wrap">
|
||||
<div
|
||||
class="box-card"
|
||||
v-for="(item1, index1) in node.userVoList"
|
||||
:key="index1"
|
||||
style="margin-bottom: 10px; border: 0px solid red; width: 40px; text-align: center"
|
||||
>
|
||||
<div class="node-show">
|
||||
<div style="overflow: hidden">
|
||||
<div class="d1">
|
||||
<div>
|
||||
<upload-img v-model:image-url="item1.avatar" width="30px" height="30px"></upload-img>
|
||||
</div>
|
||||
<div style="font-size: 8px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; text-align: center">
|
||||
{{ item1.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 渲染审批评论-->
|
||||
<template v-for="(item1, index1) in node.userVoList" :key="index1">
|
||||
<template v-if="item1.approveDesc?.length > 0">
|
||||
<div style="display: flex; flex-direction: row">
|
||||
<div style="width: 40px; text-align: center">
|
||||
<upload-img v-model:image-url="item1.avatar" disabled width="30px" height="30px"></upload-img>
|
||||
</div>
|
||||
<div style="height: 40px; line-height: 40px; font-size: 10px">
|
||||
{{ item1.name }}
|
||||
</div>
|
||||
<div style="height: 40px; line-height: 40px; font-size: 10px">(添加了评论) {{ item1.showTime }}</div>
|
||||
</div>
|
||||
<div class="box-card" style="margin-bottom: 10px; padding: 5px; background-color: var(--el-fill-color-light)">
|
||||
{{ item1.approveDesc }}
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 选择用户-->
|
||||
<template v-if="node.selectUser">
|
||||
<select-show :disabled="disableSelect" v-model:orgList="nodeUser[node.id]" type="user" :multiple="node.multiple"></select-show>
|
||||
</template>
|
||||
|
||||
<el-tabs v-if="node.branch.length > 0" type="border-card">
|
||||
<el-tab-pane v-for="(node1, index1) in node.branch" :label="'分支' + (index1 + 1)" :name="index1 + ''" :key="index1">
|
||||
<template v-if="node1.placeholder && node1.placeholder.length > 0">[{{ node1.placeholder }}]</template>
|
||||
<div style="padding: 0px 5px">
|
||||
<flow-node-format :node-user="nodeUser" :disableSelect="disableSelect" :row="node1.children"></flow-node-format>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,92 @@
|
||||
<script setup lang="ts">
|
||||
import FlowNodeFormat from '/@/views/flow/form/tools/FlowNodeFormat.vue';
|
||||
import { formatStartNodeShow } from '/@/api/flow/task';
|
||||
import { defineExpose, onMounted, ref, watch } from 'vue';
|
||||
|
||||
let props = defineProps({
|
||||
flowId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
disableSelect: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
taskId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
processInstanceId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
formData: {
|
||||
type: Object,
|
||||
dafault: () => {},
|
||||
},
|
||||
selectUserNodeId: {
|
||||
type: Array,
|
||||
dafault: () => [],
|
||||
},
|
||||
});
|
||||
const row = ref([]);
|
||||
|
||||
const queryData = (p) => {
|
||||
var data = {
|
||||
flowId: props.flowId,
|
||||
processInstanceId: props.processInstanceId,
|
||||
paramMap: p,
|
||||
taskId: props.taskId,
|
||||
};
|
||||
formatStartNodeShow(data).then((res) => {
|
||||
row.value = res.data;
|
||||
});
|
||||
};
|
||||
watch(
|
||||
() => props.formData,
|
||||
(val) => {
|
||||
setTimeout(function () {
|
||||
if (new Date().getTime() - formDataChangeTime.value > 500) {
|
||||
formDataChangeTime.value = new Date().getTime();
|
||||
queryData(val);
|
||||
}
|
||||
}, 600);
|
||||
}
|
||||
);
|
||||
const formDataChangeTime = ref();
|
||||
onMounted(() => {
|
||||
formDataChangeTime.value = new Date().getTime();
|
||||
queryData({});
|
||||
});
|
||||
|
||||
const validate = () => {
|
||||
for (var k of props.selectUserNodeId) {
|
||||
var d = nodeUser.value[k];
|
||||
if (d && d.length > 0) {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
const nodeUser = ref({});
|
||||
|
||||
const formatSelectNodeUser = () => {
|
||||
var obj = {};
|
||||
|
||||
for (var k of props.selectUserNodeId) {
|
||||
var d = nodeUser.value[k];
|
||||
obj[k + '_assignee_select'] = d;
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
defineExpose({ validate, formatSelectNodeUser });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<flow-node-format :row="row" :node-user="nodeUser" :disableSelect="disableSelect" ref="flowNodeFormatRef"></flow-node-format>
|
||||
</template>
|
||||
@@ -0,0 +1,158 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog v-model="dialogTableVisible" title="发起流程" width="800px" destroy-on-close>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form label-position="top">
|
||||
<form-render
|
||||
@addLayoutOneItem="addLayoutOneItem"
|
||||
ref="formRenderRef"
|
||||
@deleteLayoutOneItem="deleteLayoutOneItem"
|
||||
:form-list="currentOpenFlowForm"
|
||||
></form-render>
|
||||
</el-form>
|
||||
|
||||
<div class="flex justify-center mt-4">
|
||||
<el-button @click="dialogTableVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitProcess"> 提交 </el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<flow-node-format
|
||||
:formData="formValue"
|
||||
:selectUserNodeId="selectUserNodeId"
|
||||
:flow-id="currentOpenFlow.flowId"
|
||||
ref="flowNodeFormatRef"
|
||||
></flow-node-format>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import FormRender from '/@/views/flow/form/render/FormRender.vue';
|
||||
import FlowNodeFormat from '/@/views/flow/form/tools/FlowNodeFormatData.vue';
|
||||
import { FormVO } from '/@/api/flow/form/types';
|
||||
import { getFlowDetail, startFlow } from '/@/api/flow/flow';
|
||||
import other from '/@/utils/other';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
const dialogTableVisible = ref<Boolean>(false);
|
||||
const currentOpenFlowForm = ref<FormVO[]>([]);
|
||||
const currentOpenFlow = ref<FormVO[]>([]);
|
||||
const formRenderRef = ref();
|
||||
const submitProcess = () => {
|
||||
let validate = flowNodeFormatRef.value.validate();
|
||||
if (!validate) {
|
||||
ElMessage.warning('请选择节点执行人');
|
||||
return;
|
||||
}
|
||||
|
||||
let param = flowNodeFormatRef.value.formatSelectNodeUser();
|
||||
|
||||
currentOpenFlowForm.value.forEach((res) => (param[res.id] = res.props.value));
|
||||
|
||||
{
|
||||
for (var item of currentOpenFlowForm.value) {
|
||||
param[item.id] = item.props.value;
|
||||
if (item.type === 'Layout') {
|
||||
let subList = item.props.value;
|
||||
|
||||
var d = [];
|
||||
for (var array of subList) {
|
||||
var v = {};
|
||||
|
||||
for (var subItem of array) {
|
||||
let value = subItem.props.value;
|
||||
v[subItem.id] = value;
|
||||
}
|
||||
d.push(v);
|
||||
}
|
||||
param[item.id] = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var data = {
|
||||
flowId: currentOpenFlow.value.flowId,
|
||||
paramMap: param,
|
||||
};
|
||||
formRenderRef.value.validate(function (valid) {
|
||||
if (valid) {
|
||||
startFlow(data).then((res) => {
|
||||
ElMessage.success('提交成功');
|
||||
dialogTableVisible.value = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handle = (row) => {
|
||||
currentOpenFlow.value = row;
|
||||
|
||||
startProcess(row);
|
||||
};
|
||||
|
||||
defineExpose({ handle });
|
||||
|
||||
const selectUserNodeId = ref<String[]>([]);
|
||||
|
||||
const startProcess = (f) => {
|
||||
getFlowDetail(f.flowId).then((res) => {
|
||||
const { data } = res;
|
||||
|
||||
const { formItems } = data;
|
||||
|
||||
let formIteamJsonArray = JSON.parse(formItems);
|
||||
|
||||
for (var fi of formIteamJsonArray) {
|
||||
if (fi.type === 'Layout') {
|
||||
var arr = [];
|
||||
let value = fi.props.value;
|
||||
arr.push(value);
|
||||
fi.props.value = arr;
|
||||
fi.props.oriForm = other.deepClone(value);
|
||||
}
|
||||
}
|
||||
|
||||
currentOpenFlowForm.value = formIteamJsonArray;
|
||||
|
||||
selectUserNodeId.value = data.selectUserNodeId;
|
||||
|
||||
dialogTableVisible.value = true;
|
||||
});
|
||||
};
|
||||
|
||||
const formValue = computed(() => {
|
||||
var obj = {};
|
||||
|
||||
for (var item of currentOpenFlowForm.value) {
|
||||
obj[item.id] = item.props.value;
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
|
||||
//明细的添加一个
|
||||
const addLayoutOneItem = (id) => {
|
||||
for (var item of currentOpenFlowForm.value) {
|
||||
if (item.id !== id) {
|
||||
continue;
|
||||
}
|
||||
let value = item.props.value;
|
||||
let oriForm = item.props.oriForm;
|
||||
value.push(other.deepClone(oriForm));
|
||||
item.props.value = value;
|
||||
}
|
||||
};
|
||||
const deleteLayoutOneItem = (id, index) => {
|
||||
for (var item of currentOpenFlowForm.value) {
|
||||
if (item.id !== id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
item.props.value.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
const flowNodeFormatRef = ref();
|
||||
</script>
|
||||
@@ -0,0 +1,244 @@
|
||||
import other from "/@/utils/other";
|
||||
|
||||
export function inputValidate(configValue: any, proxy: any) {
|
||||
let minLength = configValue.props.minLength;
|
||||
let maxLength = configValue.props.maxLength;
|
||||
let value = configValue.props.value;
|
||||
let regex = configValue.props.regex;
|
||||
let regexDesc = configValue.props.regexDesc;
|
||||
|
||||
if (minLength && maxLength && maxLength < minLength) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':长度设置错误',
|
||||
};
|
||||
}
|
||||
if (regex) {
|
||||
if (!regexDesc) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':请填写正则表达式提示语',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (value) {
|
||||
if (minLength) {
|
||||
if (value.length < minLength) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':默认值长度不能小于' + minLength,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (maxLength) {
|
||||
if (value.length > maxLength) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':默认值长度不能大于' + maxLength,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (regex) {
|
||||
var reg = new RegExp(regex, 'g');
|
||||
if (!reg.test(value)) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':默认值不符合正则表达式',
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
valid: true,
|
||||
};
|
||||
}
|
||||
|
||||
export function descriptionValidate(configValue: any, proxy: any) {
|
||||
let placeHolder = configValue.placeholder;
|
||||
if (!placeHolder) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':请设置提示',
|
||||
};
|
||||
}
|
||||
return {
|
||||
valid: true,
|
||||
};
|
||||
}
|
||||
export function numberValidate(configValue: any, proxy: any) {
|
||||
let min = configValue.props.min;
|
||||
let max = configValue.props.max;
|
||||
let defaultValue = configValue.props.value;
|
||||
let radixNum = configValue.props.radixNum;
|
||||
|
||||
if (min && max && max < min) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':值范围设置错误',
|
||||
};
|
||||
}
|
||||
|
||||
if (radixNum) {
|
||||
if (min) {
|
||||
let num = other.getNumberRadixNum(min);
|
||||
if (num > radixNum) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':最小值小数点位数不能超过' + radixNum,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (max) {
|
||||
let num = other.getNumberRadixNum(max);
|
||||
if (num > radixNum) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':最大值小数点位数不能超过' + radixNum,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultValue) {
|
||||
if (radixNum) {
|
||||
let num = other.getNumberRadixNum(defaultValue);
|
||||
if (num > radixNum) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':默认值小数点位数不能超过' + radixNum,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (min) {
|
||||
if (defaultValue < min) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':默认值不能小于' + min,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (max) {
|
||||
if (defaultValue > max) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':默认值不能大于' + max,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
valid: true,
|
||||
};
|
||||
}
|
||||
export function layoutValidate(configValue: any, proxy: any) {
|
||||
let min = configValue.props.min;
|
||||
let max = configValue.props.max;
|
||||
|
||||
if (min && max && max < min) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':数量范围设置错误',
|
||||
};
|
||||
}
|
||||
let value = configValue.props.value;
|
||||
if (value.length == 0) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':内部表单不能为空',
|
||||
};
|
||||
}
|
||||
for (var item of value) {
|
||||
let formValidateDictElement = formValidateDict[item.type];
|
||||
if (formValidateDictElement) {
|
||||
let result = formValidateDictElement(item, proxy);
|
||||
|
||||
if (!result.valid) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':' + result.msg,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
valid: true,
|
||||
};
|
||||
}
|
||||
export function selectValidate(configValue: any, proxy: any) {
|
||||
var options = configValue.props.options;
|
||||
if (!options) {
|
||||
options = [];
|
||||
}
|
||||
|
||||
if (options.length < 1) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':请设置选项',
|
||||
};
|
||||
}
|
||||
|
||||
{
|
||||
var keyList = options.map((w) => w.key);
|
||||
let newList = Array.from(new Set(keyList));
|
||||
if (keyList.length > newList.length) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':选项值不能重复',
|
||||
};
|
||||
}
|
||||
}
|
||||
{
|
||||
let length = options.filter((res) => !res.key || !res.value).length;
|
||||
if (length > 0) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':选项不能为空',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
var keyList = options.map((w) => w.value);
|
||||
let newList = Array.from(new Set(keyList));
|
||||
if (keyList.length > newList.length) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':选项标签不能重复',
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
valid: true,
|
||||
};
|
||||
}
|
||||
export function fileValidate(configValue: any, proxy: any) {
|
||||
let min = configValue.props.min;
|
||||
let max = configValue.props.max;
|
||||
|
||||
if (min && max && max < min) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: configValue.name + ':数量设置错误',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
valid: true,
|
||||
};
|
||||
}
|
||||
|
||||
export let formValidateDict = {
|
||||
Input: inputValidate,
|
||||
Textarea: inputValidate,
|
||||
Number: numberValidate,
|
||||
Money: numberValidate,
|
||||
Description: descriptionValidate,
|
||||
SingleSelect: selectValidate,
|
||||
MultiSelect: selectValidate,
|
||||
UploadFile: fileValidate,
|
||||
Layout: layoutValidate,
|
||||
UploadImage: fileValidate,
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
const gets = {} as any;
|
||||
const modules = import.meta.glob('../../config/*.vue', { eager: true });
|
||||
|
||||
for (let each in modules) {
|
||||
const name = modules[each].default.__name;
|
||||
|
||||
gets[name] = (modules[each] as any).default;
|
||||
}
|
||||
|
||||
export default gets;
|
||||
@@ -0,0 +1,14 @@
|
||||
const gets = {} as any;
|
||||
const modules = import.meta.glob('../../*.vue', { eager: true });
|
||||
|
||||
async function processModules() {
|
||||
for (let each in modules) {
|
||||
const module = await modules[each];
|
||||
const name = module.default.__name;
|
||||
gets[name] = module.default;
|
||||
}
|
||||
}
|
||||
|
||||
processModules();
|
||||
|
||||
export default gets;
|
||||
Reference in new issue
Block a user