Parcourir la source

Merge branch 'middle-feat'

# Conflicts:
#	src/views/approve/launch/ItemDrawer.vue
luoyali il y a 1 an
Parent
commit
4fecda8212

+ 1 - 0
package.json

@@ -28,6 +28,7 @@
     "dayjs": "^1.11.7",
     "echarts": "^5.4.2",
     "element-plus": "^2.3.4",
+    "everright-formeditor": "^1.3.0-beta.2",
     "js-md5": "^0.7.3",
     "mitt": "^3.0.0",
     "nprogress": "^0.2.0",

+ 7 - 8
src/components/scWorkflow/nodes/approver.vue

@@ -120,7 +120,7 @@
 						<!-- 表单设置 -->
 						<div v-show="radio1 === '2'">
 							<el-table ref="multipleTableRef" :data="form.extendConfig.formConfig" style="width: 100%">
-								<el-table-column property="title" label="表单字段" align="center" />
+								<el-table-column property="label" label="表单字段" align="center" />
 								<el-table-column align="center">
 									<template #header>操作权限</template>
 									<template #default="scope">
@@ -216,19 +216,18 @@ export default {
 	methods: {
 		show() {
 			this.form = JSON.parse(JSON.stringify(this.nodeConfig))
-			let formConfig = []
-			if (this.form.extendConfig) {
-				formConfig = this.form.extendConfig.formConfig
-			}
-			const operateTable = JSON.parse(this.processForm).map(item => {
+			const { formStructure } = JSON.parse(this.processForm)
+			const formConfig = this.form.extendConfig?.formConfig || []
+			const operateTable = (formStructure?.fields || []).map(item => {
 				let opera = '1'
 				formConfig.map(i => {
-					if (item.field === i.field) {
+					if (item.id === i.id) {
 						opera = i.opera
 					}
 				})
-				return { title: item.title, field: item.field, opera: opera }
+				return { label: item.label, id: item.id, opera: opera }
 			})
+			console.log(operateTable, '====operateTable====')
 			this.form.extendConfig = { formConfig: operateTable }
 			this.drawer = true
 		},

+ 1 - 1
src/store/modules/flow.ts

@@ -25,7 +25,7 @@ export const useFlowStore = defineStore({
 
 			cacheSwitch: false, // 缓存开关
 			modelContent: '', // 流程模型定义JSON内容
-			processForm: '[]', // 流程定义表单
+			processForm: '{}', // 流程定义表单
 			processSetting: {
 				allowRevocation: true, // 允许撤销审批中的申请
 				allowRevocationDay: true, // 允许撤销指定天内通过的审批

+ 2 - 0
src/styles/reset.scss

@@ -102,6 +102,8 @@ ol,
 ul {
 	box-sizing: border-box;
 	list-style: none;
+	padding: 0px;
+	margin: 0px;
 }
 blockquote,
 q {

+ 49 - 34
src/views/approve/components/approvedContent.vue

@@ -38,7 +38,7 @@
 					<div class="scroll-wrap">
 						<!-- 表单 -->
 						<div v-loading="validateForm.loading" class="form-wrap">
-							<FormCreate v-show="validateForm.rule.length" v-model:api="validateForm.api" :option="validateForm.option" :rule="validateForm.rule" />
+							<er-form-preview ref="EReditorRef" v-show="validateForm.rule.length" :is-show-complete-button="false" />
 							<LeNoData v-if="!validateForm.rule.length" message="表单无数据" />
 						</div>
 
@@ -126,7 +126,7 @@
 										<el-icon><Plus /></el-icon>
 										加签
 									</el-dropdown-item>
-									<el-dropdown-item @click.native="openComment('loseSignVisible')" v-if="false">
+									<el-dropdown-item v-if="false" @click.native="openComment('loseSignVisible')">
 										<el-icon><Minus /></el-icon>
 										减签
 									</el-dropdown-item>
@@ -196,6 +196,7 @@ import RollbackDialog from './rollbackDialog'
 import viewForm from '@/utils/form'
 import { storeToRefs } from 'pinia'
 import { ElMessage, ElMessageBox } from 'element-plus'
+import { erFormPreview } from 'everright-formeditor'
 
 defineProps({
 	/**
@@ -227,17 +228,13 @@ const activeData = ref([])
 const currentType = ref(null)
 const currentFormData = ref({})
 // 当前form 表单数据字符串
-let cur_processForm_str = '[]'
+let cur_processForm_str = ''
+const EReditorRef = ref()
 const taskId = computed(() => {
 	return currentTaskRow.value.taskId || ''
 })
 
-const FormCreate = viewForm.$form()
 const validateForm = ref({
-	api: {},
-	option: {
-		submitBtn: false
-	},
 	rule: [],
 	loading: false
 })
@@ -260,21 +257,32 @@ const openComment = async (visibleType, item) => {
 			// 点击同意
 			let bool = true
 			if (item === 'agree') {
-				const api = validateForm.value.api
-				bool = await api.validate((valid, fail) => {
+				const form = EReditorRef.value.form
+				bool = await form.validate(valid => {
 					if (valid) {
-						// 表单验证通过
-						const values = api.formData()
-						const processForm = JSON.parse(cur_processForm_str)
-						processForm.forEach(v => {
-							// 填写的数据存储(local_: 本地数据处理标识)
-							v.local_value = values[v.field]
-						})
-						console.warn(processForm, 'processForm')
-						// 流程表单JSON内容 & local_value 保存
+						// 表单验证通过 进行保存
+						const formData = EReditorRef.value.getData()
+						let processForm = JSON.parse(cur_processForm_str)
+						processForm = { ...processForm, formData }
 						currentFormData.value = { processForm: JSON.stringify(processForm) }
+						console.log('验证通过')
 					}
 				})
+				// const api = validateForm.value.api
+				// bool = await api.validate((valid, fail) => {
+				// 	if (valid) {
+				// 		// 表单验证通过
+				// 		const values = api.formData()
+				// 		const processForm = JSON.parse(cur_processForm_str)
+				// 		processForm.forEach(v => {
+				// 			// 填写的数据存储(local_: 本地数据处理标识)
+				// 			v.local_value = values[v.field]
+				// 		})
+				// 		console.warn(processForm, 'processForm')
+				// 		// 流程表单JSON内容 & local_value 保存
+				// 		currentFormData.value = { processForm: JSON.stringify(processForm) }
+				// 	}
+				// })
 			}
 			if (!bool) return
 			currentType.value = item
@@ -337,22 +345,29 @@ const getTaskDetail = () => {
 						showValue
 					}
 				})*/
-				const forms = JSON.parse(data.formContent)
 				cur_processForm_str = data.formContent
-				if (Array.isArray(forms)) {
-					validateForm.value.rule = forms
-					const api = validateForm.value.api
-					api.setValue(
-						forms.reduce((obj, item) => {
-							obj[item.field] = item.local_value
-							return obj
-						}, {})
-					)
-					api.nextTick(() => {
-						// 是否有编辑权限 操作
-						api.disabled(false /*true*/)
-					})
-				}
+				const { formStructure, formData } = JSON.parse(cur_processForm_str)
+				EReditorRef.value.setData(formStructure, formData)
+				validateForm.value.rule = formStructure.fields
+				console.log(formStructure)
+				// todo 还要在这里判断哪些表单室显示 隐藏 禁用 启用
+				return
+				// 以下代码作废 todo delete
+				// if (Array.isArray(forms)) {
+				// 	validateForm.value.rule = forms
+				// 	const api = validateForm.value.api
+				// 	api.setValue(
+				// 		forms.reduce((obj, item) => {
+				// 			obj[item.field] = item.local_value
+				// 			return obj
+				// 		}, {})
+				// 	)
+				// 	api.nextTick(() => {
+				// 		// 是否有编辑权限 操作
+				// 		api.disabled(false /*true*/)
+				// 	})
+				// }
+				// 以下代码作废 todo delete
 			} catch (e) {
 				console.error('解析 descItems 数据出现问题', e)
 				// descItemsData.value.list = []

+ 42 - 35
src/views/approve/launch/ItemDrawer.vue

@@ -10,7 +10,8 @@
 		<div v-if="validateForm.loading" v-loading="true" class="local_loading"></div>
 		<div class="info-wrap">
 			<el-divider content-position="left">{{ record.processName }}表单</el-divider>
-			<FormCreate v-model:api="validateForm.api" class="form-wrap" :option="validateForm.option" :rule="validateForm.rule" />
+			<FormCreate v-if="false" v-model:api="validateForm.api" class="form-wrap" :option="validateForm.option" :rule="validateForm.rule" />
+			<er-form-preview ref="EReditorRef" :is-show-complete-button="false" />
 			<el-divider content-position="left">审批流程</el-divider>
 			<el-timeline class="timeline-wrap">
 				<el-timeline-item v-for="(v, index) in processTimelineList" :key="index">
@@ -67,11 +68,14 @@
 <script setup lang="ts">
 import model from '@/api/flow/process'
 import viewForm from '@/utils/form'
+import { erFormPreview } from 'everright-formeditor'
+import 'Everright-formEditor/dist/style.css'
 import { ref, shallowRef, computed, reactive, watchEffect } from 'vue'
 import { ElMessage } from 'element-plus'
 import UseSelect from '@/components/scWorkflow/select.vue'
 import FlowNodeAvatar from '@/components/Flow/FlowNodeAvatar.vue'
 import { approveTypeOptions_config, selectModeOptions_config, setTypeOptions_config } from '@/components/scWorkflow/nodes/config'
+const EReditorRef = ref()
 type Props = {
 	modelValue: boolean
 	record: { processId: string; processName: string; [key: string]: any }
@@ -137,43 +141,44 @@ const validateForm = ref({
 })
 
 const onSubmit = async () => {
-	const api = validateForm.value.api
-	await api.validate()
-	const values = api.formData()
-	// console.warn(values, 'values')
 	const processId = props.record.processId
-	validateForm.value.loading = true
-	const processForm: any[] = JSON.parse(cur_processForm_str)
-	processForm.forEach(v => {
-		// 填写的数据存储(local_: 本地数据处理标识)
-		v.local_value = values[v.field]
-	})
-	const _assigneeMap = assigneeMap.value
-	const assigneeMap_ = Object.keys(_assigneeMap).reduce((obj, key) => {
-		const _o = _assigneeMap[key]
-		obj[key] = {
-			assigneeList: _o.assignees,
-			type: _o.type
+	const form = EReditorRef.value.form
+	form.validate(valid => {
+		if (valid) {
+			// 表单验证通过 进行保存
+			validateForm.value.loading = true
+			const formData = EReditorRef.value.getData()
+			let processForm = JSON.parse(cur_processForm_str)
+			processForm = { ...processForm, formData }
+			console.log(processForm, '===========')
+			const _assigneeMap = assigneeMap.value
+			const assigneeMap_ = Object.keys(_assigneeMap).reduce((obj, key) => {
+				const _o = _assigneeMap[key]
+				obj[key] = {
+					assigneeList: _o.assignees,
+					type: _o.type
+				}
+				return obj
+			}, {})
+			model
+				.processLaunchApi({
+					processId, // 流程ID
+					processForm: JSON.stringify(processForm), // 流程表单JSON内容 & local_value 保存
+					assigneeMap: assigneeMap_
+				})
+				.then(res => {
+					ElMessage.success('提交成功')
+					updateModelValue(false)
+				})
+				.finally(() => {
+					validateForm.value.loading = false
+				})
 		}
-		return obj
-	}, {})
-	model
-		.processLaunchApi({
-			processId, // 流程ID
-			processForm: JSON.stringify(processForm), // 流程表单JSON内容 & local_value 保存
-			assigneeMap: assigneeMap_
-		})
-		.then(res => {
-			ElMessage.success('提交成功')
-			updateModelValue(false)
-		})
-		.finally(() => {
-			validateForm.value.loading = false
-		})
+	})
 }
 
 // 当前form 表单数据字符串
-let cur_processForm_str = '[]'
+let cur_processForm_str = '{}'
 const processChecked = reactive<{ [key: string]: any }>({
 	/*'local_条件分支_期限': '短期'*/
 })
@@ -313,13 +318,15 @@ Promise.all([
 			const modelContent = JSON.parse(res.modelContent)
 			local_workflow = modelContent.nodeConfig ?? modelContent.childNode
 		} catch (e) {}*/
-		cur_processForm_str = res.processForm || '[]'
+		cur_processForm_str = res.processForm || '{}'
 		// const x = JSON.parse(cur_processForm_str)
 		// x[0].validate = [{ required: true, message: '请输入商品简介', trigger: 'blur' }]
 
 		// processForm 动态表单
 		// validateForm.value.rule = [...JSON.parse(cur_processForm_str) /*, { ...workflowItem, value: local_workflow }*/ /*, { type: 'input', field: 'test_3' }*/]
-		validateForm.value.rule = JSON.parse(cur_processForm_str)
+		const { formStructure } = JSON.parse(cur_processForm_str)
+		EReditorRef.value.setData(formStructure)
+		// validateForm.value.rule = JSON.parse(cur_processForm_str)
 	})
 ]).finally(() => {
 	validateForm.value.loading = false

+ 39 - 27
src/views/flow/create/components/FormDesign.vue

@@ -1,45 +1,58 @@
 <script setup name="FormDesign">
-import FcDesigner from '@/components/FormCreateDesigner/FcDesigner.vue'
+import { onBeforeUnmount, onMounted, ref } from 'vue'
+import { erFormEditor } from 'everright-formeditor'
+import 'Everright-formEditor/dist/style.css'
 import useFlowStore from '@/store/modules/flow'
 import { storeToRefs } from 'pinia'
-import { onMounted, ref } from 'vue'
-
+import { ElMessage } from 'element-plus'
 const flowStore = useFlowStore()
 const { processForm } = storeToRefs(flowStore)
-const designer = ref()
 
-const exportJsonEv = async json => {
-	designer.value.saveAsForm()
-}
+const EReditorRef = ref()
 
-// 保存当前的表单数据
-const exportJson = async json => {
-	processForm.value = JSON.stringify(json)
+const handleListener = obj => {}
+
+// 保存当前的表单数据 processForm.value = '{formStructure: 表单结构值, formData: {}}
+const exportJsonEv = () => {
+	const formStructure = EReditorRef.value.getData()
+	const finallyForm = { formStructure, formData: {} }
+	processForm.value = JSON.stringify(finallyForm)
 }
 
-/**
- * 1、拿到store中的值,然后循环判表单字段的Id是否唯一
- * 2、如果不唯一,提示用户需要重新填写表单字段Id
- */
 const validate = () => {
 	// 根据后续的业务需求 调整 validate 的功能
 	exportJsonEv()
 	return new Promise((resolve, reject) => {
-		const finallyFormData = JSON.parse(processForm.value)
-		const fields = finallyFormData.map(item => item.field)
-		const bool = fields.length === [...new Set(fields)].length
-		if (bool) {
-			resolve(true)
-		} else {
-			reject(false)
-		}
+		// const finallyFormData = JSON.parse(processForm.value)
+		// const fields = finallyFormData.map(item => item.field)
+		// const bool = fields.length === [...new Set(fields)].length
+		// if (bool) {
+		resolve(true)
+		// } else {
+		//   reject(false)
+		// }
 	})
 }
+
+// onBeforeUnmount(() => {
+// 	const formData = EReditorRef.value.getData()
+// 	if (formData.hasOwnProperty('fields')) {
+// 		// 离开前 做处理
+// 		// const { fields } = formData
+// 		// console.log(fields.length, '=======')
+// 	} else {
+// 		ElMessage.error(`表单设计有误,请重新配置`)
+// 	}
+// })
+
 const updateCompInfo = () => {
 	if (processForm.value) {
-		designer.value.initForm(processForm.value || [])
+		// {formStructure: 表单结构值, formData: {}}
+		const { formStructure } = JSON.parse(processForm.value)
+		EReditorRef.value.setData(formStructure || {})
 	}
 }
+
 // 初始化的时候,渲染当前组件的值
 onMounted(() => {
 	updateCompInfo()
@@ -51,9 +64,8 @@ defineExpose({
 	updateCompInfo
 })
 </script>
-
 <template>
-	<fc-designer ref="designer" @export-json="exportJson" />
+	<div class="form-design-wrap">
+		<er-form-editor ref="EReditorRef" :is-show-i18n="false" @listener="handleListener" />
+	</div>
 </template>
-
-<style scoped lang="scss"></style>

+ 59 - 0
src/views/flow/create/components/test.vue

@@ -0,0 +1,59 @@
+<script setup name="FormDesign">
+import FcDesigner from '@/components/FormCreateDesigner/FcDesigner.vue'
+import useFlowStore from '@/store/modules/flow'
+import { storeToRefs } from 'pinia'
+import { onMounted, ref } from 'vue'
+
+const flowStore = useFlowStore()
+const { processForm } = storeToRefs(flowStore)
+const designer = ref()
+
+const exportJsonEv = async json => {
+	designer.value.saveAsForm()
+}
+
+// 保存当前的表单数据
+const exportJson = async json => {
+	processForm.value = JSON.stringify(json)
+}
+
+/**
+ * 1、拿到store中的值,然后循环判表单字段的Id是否唯一
+ * 2、如果不唯一,提示用户需要重新填写表单字段Id
+ */
+const validate = () => {
+	// 根据后续的业务需求 调整 validate 的功能
+	exportJsonEv()
+	return new Promise((resolve, reject) => {
+		const finallyFormData = JSON.parse(processForm.value)
+		const fields = finallyFormData.map(item => item.field)
+		const bool = fields.length === [...new Set(fields)].length
+		if (bool) {
+			resolve(true)
+		} else {
+			reject(false)
+		}
+	})
+}
+const updateCompInfo = () => {
+	if (processForm.value) {
+		designer.value.initForm(processForm.value || [])
+	}
+}
+// 初始化的时候,渲染当前组件的值
+onMounted(() => {
+	updateCompInfo()
+})
+
+defineExpose({
+	exportJsonEv,
+	validate,
+	updateCompInfo
+})
+</script>
+
+<template>
+	<fc-designer ref="designer" @export-json="exportJson" />
+</template>
+
+<style scoped lang="scss"></style>

+ 7 - 5
src/views/flow/create/index.vue

@@ -117,6 +117,7 @@ const submitHandler = async () => {
 	}
 	const res = await process.progressCreateApi(params)
 	console.log('---r-e-s----', res)
+	ElMessage.success('操作成功')
 	// 创建完成 删除 当前tab页
 	removeCurTab()
 }
@@ -138,10 +139,10 @@ const validateTabs = async () => {
 			}
 		await _validate().catch(e => {
 			activeTab.value = componentsArr[i].label
-			// 表单设计 额外 弹窗
+			/*// 表单设计 额外 弹窗
 			if (activeTab.value === '表单设计') {
 				ElMessage.error(`表单设计中字段ID不能重复,请确认唯一值`)
-			}
+			}*/
 			bool = false
 		})
 		if (!bool) return false
@@ -152,12 +153,14 @@ const validateTabs = async () => {
 const activeComponent = index => {
 	const cur = componentsArr[index]
 	if (activeTab.value !== cur.value) {
+		if (activeTab.value === '表单设计') {
+			compRefs.value[1]?.exportJsonEv()
+		}
 		// 当前缓存
 		if (!cache_components.value[index]) {
-			cache_components.value[index] = true
 			// 更新数据
 			const updateCompInfo = compRefs.value[index]?.updateCompInfo
-      // console.error('刷新数据')
+			// console.error('刷新数据')
 			// console.error(updateCompInfo, 'updateCompInfo')
 			if (updateCompInfo) {
 				updateCompInfo()
@@ -170,7 +173,6 @@ const activeComponent = index => {
 const queryObj = computed(() => route.query)
 
 const getCurrentProcessDetailEv = () => {
-	// console.error('api 请求')
 	let _id = queryObj.value.id
 	if (_id) {
 		cache_components.value = {}

+ 4 - 4
src/views/flow/group/components/listGroup.vue

@@ -25,7 +25,7 @@
 					<el-space>
 						<el-icon :size="16" class="edit_icon" @click="editFlowGroup('edit', item, idx)"><EditPen /></el-icon>
 					</el-space>
-					<el-space>
+					<el-space style="margin-left: 10px">
 						<el-tooltip effect="dark" content="删除" placement="top">
 							<el-icon :size="16" @click="deleteFlowGroup(item)"><Delete /></el-icon>
 						</el-tooltip>
@@ -61,12 +61,12 @@
 												<el-icon :size="16" @click="updateEv(element.processId)"><EditPen /></el-icon>
 											</el-tooltip>
 										</el-space>
-										<el-space wrap>
+										<el-space wrap style="margin-left: 10px">
 											<el-tooltip effect="dark" content="复制" placement="top">
 												<el-icon :size="16" @click="copyEv(element.processId)"><CopyDocument /></el-icon>
 											</el-tooltip>
 										</el-space>
-										<el-space wrap>
+										<el-space wrap style="margin-left: 10px">
 											<el-tooltip v-if="element.processState === 1" effect="dark" content="禁用" placement="top">
 												<el-icon :size="16" @click="enabledEv(element.processId, 0)"><CircleClose /></el-icon>
 											</el-tooltip>
@@ -74,7 +74,7 @@
 												<el-icon :size="16" @click="enabledEv(element.processId, 1)"><Check /></el-icon>
 											</el-tooltip>
 										</el-space>
-										<el-space wrap>
+										<el-space wrap style="margin-left: 10px">
 											<el-popconfirm title="确定删除?" @confirm="stopEv(element.processId)">
 												<template #reference>
 													<el-icon :size="16"><Delete /></el-icon>

+ 4 - 4
src/views/flow/group/index.vue

@@ -5,12 +5,12 @@
 				<el-input v-model="keyword" style="width: 200px" placeholder="搜索" clearable @blur="searchProcess" />
 				<div style="margin-left: auto; flex-shrink: 0">
 					<template v-if="!sortFlag">
-						<el-space wrap><el-button @click="addNewGroupEv">新建分组</el-button></el-space>
-						<el-space wrap><el-button @click="changeComponent">分组排序</el-button></el-space>
+						<el-button @click="addNewGroupEv">新建分组</el-button>
+						<el-button @click="changeComponent">分组排序</el-button>
 					</template>
 					<template v-else>
-						<el-space wrap><el-button type="primary" plain :icon="CircleCheck" @click="changeComponent('sort')">完 成</el-button></el-space>
-						<el-space wrap><el-button type="info" plain @click="changeComponent">取 消</el-button></el-space>
+						<el-button type="primary" plain :icon="CircleCheck" @click="changeComponent('sort')">完 成</el-button>
+						<el-button type="info" plain @click="changeComponent">取 消</el-button>
 					</template>
 					<el-button :type="sortFlag ? 'info' : 'primary'" :icon="Plus" :disabled="sortFlag" @click="createProcessEv">创建审批</el-button>
 				</div>