Эх сурвалжийг харах

Merge branch 'feature/打印表单'

lanceJiang 10 сар өмнө
parent
commit
1f726a6b7e

+ 4 - 0
package.json

@@ -20,6 +20,7 @@
     "lint:lint-staged": "lint-staged"
   },
   "dependencies": {
+    "@chenfengyuan/vue-qrcode": "2",
     "@codemirror/lang-cpp": "^6.0.2",
     "@codemirror/lang-javascript": "^6.2.2",
     "@codemirror/lang-json": "^6.0.1",
@@ -44,6 +45,7 @@
     "echarts": "^5.4.2",
     "element-plus": "2.3.4",
     "everright-filter": "^1.1.1",
+    "html2canvas": "^1.4.1",
     "js-md5": "^0.7.3",
     "json-editor-vue3": "^1.0.8",
     "json-lint": "^0.1.0",
@@ -59,6 +61,8 @@
     "path-to-regexp": "^6.2.0",
     "pinia": "^2.1.7",
     "pinia-plugin-persistedstate": "^3.1.0",
+    "print-js": "^1.6.0",
+    "qrcode": "1",
     "signature_pad": "^4.1.4",
     "sortablejs": "^1.15.0",
     "vant": "^4.0.8",

+ 2 - 1
src/components/packages/theme/formEditor/FormTypes/Signature.scss

@@ -2,7 +2,8 @@
   position: relative;
   width: 100%;
   height: 200px;
-  border: black 1px solid;
+  //border: black 1px solid;
+	border: 1px solid var(--el-border-color);
   @include e(clear) {
     color: $primary-color;
     position: absolute;

+ 7 - 0
src/router/index.ts

@@ -43,6 +43,13 @@ export const sysStaticRouter: Array<AppRouteRecordRaw> = [
 				component: () => import('@/views/dashboard/index.vue'),
 				name: 'dashboard',
 				meta: { title: 'dashboard', icon: 'icon-homepage', affix: true }
+			},
+			// 详情_模拟
+			{
+				path: '/approve_detail',
+				component: () => import('@/views/approve/detail/index.vue'),
+				name: 'testDetail',
+				meta: { title: '流程详情', icon: 'icon-homepage', hidden: true }
 			}
 		]
 	},

+ 3 - 3
src/store/modules/user.ts

@@ -51,10 +51,10 @@ const useUserStore = defineStore({
 				// 用户信息
 				ls.set('userInfo', userInfo)
 				this.userInfo = userInfo
-				const { redirect, ...query } = (this.loginQuery || {}) as any
-				// debugger
+				const { redirect/*, ...query*/ } = (this.loginQuery || {}) as any
 				const path = redirect || '/'
-				router.push({ path, query })
+				// router.push({ path/*, query*/ })
+				router.push(path)
 				return data
 			})
 		},

+ 5 - 0
src/styles/lance-element-ui.scss

@@ -44,6 +44,11 @@
 		width: 16px;
 		height: 16px;
 	}
+	&.self-position {
+		.el-dialog__body {
+			position: relative;
+		}
+	}
 
 	.el-dialog__body {
 		//height: auto;

+ 115 - 13
src/views/approve/components/approvedContent.vue

@@ -17,7 +17,11 @@
 				<div class="flow-header-box">
 					<div class="flow-no">编号:{{ currentTaskRow.instanceId }}</div>
 					<div class="action-area">
-						<div class="action-item"></div>
+						<div class="action-item" @click="openPrintModal">
+							<el-tooltip effect="dark" content="打印" placement="bottom">
+								<el-icon :style="{ color: 'var(--el-color-primary)' }" :size="16"><Printer /> </el-icon>
+							</el-tooltip>
+						</div>
 					</div>
 				</div>
 				<!-- 2、内容体 -->
@@ -214,8 +218,12 @@
 
 		<!-- 回退弹窗 -->
 		<rollback-dialog v-if="rollbackVisible" v-model="rollbackVisible" :task-id="taskId" @success-cb="closeDetailEv"></rollback-dialog>
+
 		<!-- 查看子流程表单 -->
 		<ViewProcessDialog v-if="processInfo.visible" v-model="processInfo.visible" :process-info="processInfo" />
+
+		<!-- 打印审批流 -->
+		<printer-dialog v-if="printerVisible" v-model="printerVisible" :currentTaskRow="currentTaskRow" :opts="printOpts"></printer-dialog>
 	</div>
 </template>
 
@@ -227,7 +235,7 @@ import FlowStatusStamp from '@/components/Flow/FlowStatusStamp.vue'
 import FlowStatusTag from '@/components/Flow/FlowStatusTag.vue'
 import FlowNodeAvatar from '@/components/Flow/FlowNodeAvatar.vue'
 import FlowTypeDot from '@/components/Flow/FlowTypeDot.vue'
-import { ChatLineSquare, Check, Close, Switch, DArrowLeft, Plus, Minus, More } from '@element-plus/icons-vue'
+import { ChatLineSquare, Check, Close, Switch, DArrowLeft, Plus, Minus, More, Printer } from '@element-plus/icons-vue'
 import { processTaskApprovalInfo, processClaimTaskApi } from '@/api/flow/processTask'
 import { formatTimestamp } from '@/utils/datetime'
 import ReviewDialog from './reviewDialog'
@@ -237,6 +245,7 @@ import DeliverToReviewDialog from './deliverToReviewDialog'
 import LoseSignDialog from './loseSignDialog'
 import RollbackDialog from './rollbackDialog'
 import ViewProcessDialog from './ViewProcessDialog.vue'
+import PrinterDialog from './printer.vue'
 import { storeToRefs } from 'pinia'
 import { ElMessage, ElMessageBox } from 'element-plus'
 import { erFormPreview } from '@ER/formEditor'
@@ -287,15 +296,30 @@ const consentOrRefuseVisible = ref(false)
 const deliverToReviewVisible = ref(false)
 const loseSignVisible = ref(false)
 const rollbackVisible = ref(false)
+const printerVisible = ref(false)
+const printOpts = ref({})
+
 const allowReject = ref(false)
 const allowRevocation = ref(false)
+
 // 各种操作弹窗显示隐藏 end
 const activeData = ref([])
 const currentType = ref(null)
 const currentFormData = ref({})
 // 当前form 表单数据字符串
 let cur_processForm_str = ''
+let cur_formStructure = {}
+let cur_formData = {}
+const openPrintModal = () => {
+	// innerTable.value = document.querySelector('.self-Everright-formEditor').innerHTML
+	printOpts.value = {
+		formStructure: cur_formStructure,
+		formData: cur_formData
+	}
+	printerVisible.value = true
+}
 const EReditorRef = ref()
+// window.EReditorRef = EReditorRef
 const taskId = computed(() => {
 	return currentTaskRow.value.taskId || ''
 })
@@ -469,9 +493,9 @@ const getTaskDetail = () => {
 				cur_processForm_str = formContent
 				const { formStructure, formData } = JSON.parse(cur_processForm_str)
 				const formConfig = data.formConfig || []
-				let newFormStructure = formStructure // 存储一份
-				let newFields = newFormStructure.fields
-				let newFieldsList = newFormStructure.list
+				cur_formStructure = formStructure // 存储一份
+				let newFields = cur_formStructure.fields
+				let newFieldsList = cur_formStructure.list
 				// pendingApproval, 除了[待审批]这个状态, 其余只能读取
 				if (props.currentTaskType !== 'pendingApproval') {
 					newFields.map(item1 => (item1.options.disabled = true))
@@ -498,12 +522,15 @@ const getTaskDetail = () => {
 						}
 					})
 				}
-				newFormStructure = {
-					...newFormStructure,
+				cur_formStructure = {
+					...cur_formStructure,
 					fields: newFields,
 					list: newFieldsList
 				}
-				EReditorRef.value.setData(newFormStructure, formData)
+				cur_formData = formData
+				console.log(cur_formStructure, '=/////====newFormStructure');
+				console.log(formData, '=/////====newFormStructure');
+				EReditorRef.value.setData(cur_formStructure, formData)
 				validateForm.value.rule = newFields
 				/* 这里主要是表单设计的逻辑 end */
 			} catch (e) {
@@ -599,7 +626,7 @@ watch(
 	// 通过、不通过样式
 	.flow-status-stamp {
 		position: absolute;
-		right: 10px;
+		right: 60px;
 		top: 10px;
 		z-index: 99;
 	}
@@ -620,10 +647,8 @@ watch(
 			gap: 4px;
 			.action-item {
 				cursor: pointer;
-				padding: 4px;
-				border-radius: 6px;
-				width: fit-content;
-				height: fit-content;
+				display: flex;
+				align-items: center;
 			}
 		}
 	}
@@ -729,4 +754,81 @@ watch(
 		padding: 0px 16px;
 	}
 }
+// 打印时 样式
+.form-wrap--print {
+//.form-wrap {
+	// 非编辑情况下样式 调整
+	:deep(.Everright-formEditor-InlineLayout) {
+		.el-form-item {
+			border: 1px solid #000;
+			margin-bottom: 0;
+			.el-form-item__label {
+				padding: 0 6px;
+			}
+			.el-form-item__content {
+				border-left: 1px solid #000;
+				// 富文本
+				.Everright-ckeditor-Main {
+					.Everright-ckeditor-Main__toolbar {
+						display: none;
+					}
+					.ck-content {
+						border: 0 !important;
+						height: max-content;
+					}
+				}
+				// 签名
+				.Everright-formEditor-FormTypesSignature_pc {
+					border: 0;
+				}
+				// 角色
+				.Everright-formEditor-FormTypesSelectRole_pc,
+				.Everright-formEditor-FormTypesSelectUser_pc {
+					.avatar .name {
+						max-width: unset;
+					}
+				}
+				// 部门(el-cascader)
+				//.Everright-formEditor-FormTypesSelectDepart_pc {
+				.el-cascader {
+					.el-input__wrapper {
+						background-color: transparent;
+						box-shadow: unset;
+					}
+					.el-input__suffix {
+						display: none;
+					}
+				}
+				// 选择字典(.el-select)
+				//.Everright-formEditor-FormTypesSelectDict_pc {
+				.el-select {
+					.el-input {
+						&__wrapper {
+							background-color: transparent;
+							box-shadow: unset;
+						}
+						&__suffix {
+							display: none;
+						}
+					}
+				}
+				// input
+				.el-input {
+					&__wrapper {
+						background-color: transparent;
+						box-shadow: unset;
+					}
+					&__suffix {
+						display: none;
+					}
+				}
+			}
+		}
+		& + .Everright-formEditor-InlineLayout {
+			.el-form-item {
+				border-top: 0;
+			}
+		}
+	}
+}
 </style>

+ 248 - 0
src/views/approve/components/printer.vue

@@ -0,0 +1,248 @@
+<script setup>
+// lang="ts"
+import { computed, watch, ref, nextTick } from 'vue'
+import printJS from 'print-js'
+import VueQrcode from '@chenfengyuan/vue-qrcode'
+import { erFormPreview } from '@ER/formEditor'
+// import type { PropType } from 'vue'
+// 若有需要自行编辑 QR Code ...
+const props = defineProps({
+	modelValue: {
+		type: Boolean,
+		default: false
+	},
+	taskId: {
+		type: String,
+		default: undefined
+	},
+	innerTable: {
+		type: String,
+		default: ''
+	},
+	opts: {
+		type: Object, //  as PropType<{ formStructure: { fields: any[]; list: any[] }; formData: any }>,
+		default: () => ({
+			formStructure: {
+				fields: [],
+				list: []
+			},
+			formData: {}
+		})
+	},
+	currentTaskRow: {
+		type: Object,
+		// type: Object as PropType<{ instanceId: string; createTime: string }>,
+		default: () => ({
+			// instanceId: undefined,
+			// createTime: undefined,
+		})
+	}
+})
+
+const $myEmit = defineEmits(['update:modelValue'])
+
+const visibleDialog = computed({
+	get() {
+		return props.modelValue
+	},
+	set(val) {
+		$myEmit('update:modelValue', val)
+	}
+})
+const PreviewRef = ref()
+watch(
+	() => props.modelValue,
+	bool => {
+		if (bool) {
+			nextTick(() => {
+				const { formStructure, formData } = props.opts
+				PreviewRef.value.setData(formStructure, formData)
+			})
+		}
+	},
+	{ immediate: true }
+)
+const submitForm = () => {
+	printJS({
+		printable: 'printJS-form',
+		type: 'html',
+		scanStyles: true, // 是否使用html附带的样式
+		targetStyles: ['*'], // 如果上面是true, 这里就得这么写,表示使用全部样式
+		style: `
+         @page { margin:0 10mm },     // 打印时去掉眉页眉尾
+         .print-table { margin-top: 50px; },
+         @media print { .page-break { page-break-before: always; } }   // 强制打印分页
+        `
+		// css: './print.scss'
+	})
+}
+
+const closeDialog = () => {
+	$myEmit('update:modelValue', false)
+}
+const qrUrl = computed(() => {
+	return `${location.origin}/#/approve/detail?id=${props.currentTaskRow?.instanceId}`
+})
+</script>
+
+<template>
+	<el-dialog v-model="visibleDialog" class="le-dialog self-position" title="打印预览" width="700" destroy-on-close :close-on-click-modal="false">
+		<div id="printJS-form" class="w-full text-[16px]">
+			<div class="mb-[36px] text-center text-[22px] font-medium">请假审批</div>
+
+			<div class="leading-7">
+				审批编号: <span class="pl-[6px]">{{ currentTaskRow.instanceId }}</span>
+			</div>
+			<div class="leading-7">
+				提交时间: <span class="pl-[6px]"> {{ currentTaskRow.createTime }} </span>
+			</div>
+
+			<div class="text-center flex-col-center absolute top-[20px] right-[24px]">
+				<span class="mb-[3px] text-[#909399] inline-block">扫码查看流程</span>
+
+				<div>
+					<VueQrcode
+						:value="qrUrl"
+						:options="{
+							width: 90,
+							margin: 0
+						}"
+					></VueQrcode>
+				</div>
+			</div>
+			<div class="local_print-table my-[12px]">
+				<erFormPreview v-show="opts.formStructure?.fields?.length" ref="PreviewRef" :is-show-complete-button="false" />
+			</div>
+
+			<div class="flex justify-between">
+				<div class="leading-7">打印人: <span class="pl-[6px]"> admin </span></div>
+				<div class="leading-7">打印时间: <span class="pl-[6px]"> 2024-08-24 16:43:36 </span></div>
+			</div>
+		</div>
+		<template #footer>
+			<span class="dialog-footer">
+				<el-button class="dialog-btn" @click="closeDialog">取 消</el-button>
+				<el-button type="primary" class="dialog-btn" @click="submitForm">打 印</el-button>
+			</span>
+		</template>
+	</el-dialog>
+</template>
+
+<style scoped lang="scss">
+.print-table {
+	width: 100%;
+	border-collapse: collapse;
+	border-radius: 10px; /* 设置表格的圆角半径为10px */
+}
+th,
+td {
+	border: 1px solid black;
+	padding: 12px;
+	text-align: left;
+}
+/*th {
+	//background-color: #f2f2f2;
+}
+tr:nth-child(even) {
+	background-color: #f9f9f9;
+}*/
+.submitter {
+	font-weight: bold;
+}
+/* 设置第一列的宽度为200px */
+th:first-child,
+td:first-child {
+	width: 200px; /* 设置第一列的宽度 */
+}
+.local_print-table {
+	// 相关打印样式...
+	:deep(.Everright-formEditor-InlineLayout) {
+		.Everright-formEditor-selectElement {
+			padding: 0;
+		}
+		.el-form-item {
+			border: 1px solid #000;
+			margin-bottom: 0;
+			.el-form-item__label {
+				padding: 0 6px;
+			}
+			.el-form-item__content {
+				border-left: 1px solid #000;
+				// 富文本
+				.Everright-ckeditor-Main {
+					.Everright-ckeditor-Main__toolbar {
+						display: none;
+					}
+					.ck-content {
+						border: 0 !important;
+						height: max-content;
+					}
+				}
+				// 签名
+				.Everright-formEditor-FormTypesSignature_pc {
+					border: 0;
+				}
+				// 角色
+				.Everright-formEditor-FormTypesSelectRole_pc,
+				.Everright-formEditor-FormTypesSelectUser_pc {
+					.avatar {
+						background: transparent;
+						.icon {
+							display: none;
+						}
+						.name {
+							//width: fit-content;
+							////max-width: unset;
+							//max-width: max-content;
+							overflow: visible;
+						}
+					}
+				}
+				// 部门(el-cascader)
+				//.Everright-formEditor-FormTypesSelectDepart_pc {
+				.el-cascader {
+					.el-input__wrapper {
+						background-color: transparent;
+						box-shadow: unset;
+					}
+					.el-input__suffix {
+						display: none;
+					}
+				}
+				// 选择字典(.el-select)
+				//.Everright-formEditor-FormTypesSelectDict_pc {
+				.el-select {
+					.el-input {
+						&__wrapper {
+							background-color: transparent;
+							box-shadow: unset;
+						}
+						&__suffix {
+							display: none;
+						}
+					}
+				}
+				// input
+				.el-input {
+					&__wrapper {
+						background-color: transparent;
+						box-shadow: unset;
+					}
+					&__inner {
+						color: var(--el-text-color-regular);
+						-webkit-text-fill-color: var(--el-text-color-regular);
+					}
+					&__suffix {
+						display: none;
+					}
+				}
+			}
+		}
+		& + .Everright-formEditor-InlineLayout {
+			.el-form-item {
+				border-top: 0;
+			}
+		}
+	}
+}
+</style>

+ 598 - 0
src/views/approve/detail/index.vue

@@ -0,0 +1,598 @@
+<!-- 流程详情 -->
+<template>
+	<div class="flow-detail-content">
+		<div v-loading="validateForm.loading" class="flow-detail-container">
+			<!-- 值为空 -->
+			<div v-if="!currentTaskRow.instanceId" class="flow-empty-detail-box">
+				<el-empty description="暂无数据" />
+			</div>
+
+			<!-- 值不为空 -->
+			<div class="column-page-wrap" v-show="currentTaskRow.instanceId">
+				<!-- 1、头部信息 -->
+				<div class="flow-status-stamp">
+					<div class="flow-stamp-container">
+						<FlowStatusStamp :status="currentTaskRow.instanceState" />
+					</div>
+				</div>
+				<div class="flow-header-box">
+					<div class="flow-no">编号:{{ currentTaskRow.instanceId }}</div>
+					<div class="action-area">
+						<div class="action-item" @click="openPrintModal">
+							<el-tooltip effect="dark" content="打印" placement="bottom">
+								<el-icon :style="{ color: 'var(--el-color-primary)' }" :size="16"><Printer /> </el-icon>
+							</el-tooltip>
+						</div>
+					</div>
+				</div>
+				<!-- 2、内容体 -->
+				<div class="flow-detail-box">
+					<!--头部-->
+					<div class="header-box">
+						<div class="summary-info">
+							<div class="title">{{ currentTaskRow.modelContent?.name }}</div>
+							<FlowStatusTag :status="currentTaskRow.instanceState" />
+						</div>
+						<div class="initiator-info">
+							<FlowNodeAvatar :name="currentTaskRow.createBy" />
+							<div class="begin-time">{{ formatTimestamp(currentTaskRow.createTime) }} 提交</div>
+						</div>
+					</div>
+					<el-tabs v-model="tabName">
+						<el-tab-pane v-for="v of tabList" :key="v.value" :label="v.label" :name="v.value" />
+					</el-tabs>
+					<!-- 审批信息 -->
+					<div v-show="tabName === 'ApprovalInfo'" class="scroll-wrap">
+						<!-- 系统表单-->
+						<template v-if="currentTaskRow.processType === 'business' && currentObj?.formTemplate.type === 1">
+							<component :is="dyVueComponent" ref="dyVueComponentRef" @form-valid="openComment('consentOrRefuseVisible', 'agree')"></component>
+						</template>
+
+						<!-- 表单设计 -->
+						<template v-else>
+							<div class="form-wrap self-Everright-formEditor">
+								<er-form-preview
+									v-show="validateForm.rule.length"
+									ref="EReditorRef"
+									:file-upload-u-r-i="uploadFileApi"
+									:is-show-complete-button="false"
+								/>
+								<LeNoData v-if="!validateForm.rule.length" message="表单无数据" />
+							</div>
+						</template>
+
+						<div class="area-divider"></div>
+
+						<!--审批流-->
+						<el-timeline style="margin-left: 50px">
+							<el-timeline-item v-for="active in activeData" :key="active.id" hollow :timestamp="active.local_timestamp">
+								<template #dot>
+									<FlowTypeDot :status="active.id ? 0 : 1" :type="active.type" :name="active.createBy" />
+								</template>
+								<div v-show="active.type === 0" class="timeline-box flex-1">
+									<span style="color: #86909c; display: block; margin-bottom: 3px; padding-left: 4px">评论</span>
+									<div class="flex flex-align-center">
+										<div class="timeline-box-user flex-1">
+											<span style="padding-left: 4px">{{ active.createBy }}</span>
+											<div v-if="active.local_content" class="comment">
+												<div class="comment-content">{{ active.local_content }}</div>
+											</div>
+										</div>
+										<span class="timeline-box-date">{{ formatTimestamp(active.finishTime) }}</span>
+									</div>
+								</div>
+
+								<div v-show="active.type !== 0" class="timeline-box flex-1">
+									<span style="display: block" class="pl-1.5 mb-0">{{ active.taskName }}</span>
+									<div class="flex flex-align-center">
+										<div class="timeline-box-user flex-1">
+											<span v-if="active.id" class="text-gray-500 pl-1.5">
+												{{ active.createBy }}
+											</span>
+											<span v-if="active.type === 22">
+												发起的子流程<el-tooltip content="点击查看详情">
+													<a class="el-button el-button--primary is-link" style="padding-top: 0" @click="lookSubProcess(active)">
+														({{ active.content.callProcess.split(':')[1] }})
+													</a>
+												</el-tooltip>
+											</span>
+											<div class="mt-[3px] flex flex-wrap gap-[6px]">
+												<FlowNodeAvatar v-for="nodeUser in active.local_nodeUserList" :key="nodeUser.id" :name="nodeUser.name" />
+												<FlowNodeAvatar v-for="nodeRole in active.local_nodeRoleList" :key="nodeRole.id" :name="nodeRole.name">
+													<template #avatar>
+														<svg-icon icon-class="flow-group" color="#fff" />
+													</template>
+												</FlowNodeAvatar>
+											</div>
+											<div v-if="active.local_content" class="comment">
+												<div class="comment-content">{{ active.local_content }}</div>
+											</div>
+										</div>
+										<span class="timeline-box-date">{{ formatTimestamp(active.finishTime) }}</span>
+									</div>
+								</div>
+							</el-timeline-item>
+						</el-timeline>
+					</div>
+					<!-- 流程图 -->
+					<div v-show="tabName === 'FlowChart'" class="scroll-wrap">
+						<div class="tags-desc">
+							<!--0: 已执行  1正在执行-->
+							<el-tag style="margin-left: 4px" type="success" size="small">已执行</el-tag>
+							<el-tag style="margin-left: 4px" type="warning" size="small">执行中</el-tag>
+							<el-tag style="margin-left: 4px" type="info" size="small">未执行</el-tag>
+						</div>
+						<ScWorkflow style="overflow-x: auto" :model-value="modelContentConfig" disabled />
+					</div>
+				</div>
+			</div>
+		</div>
+		<!-- 打印审批流 -->
+		<printer-dialog v-if="printerVisible" v-model="printerVisible" :currentTaskRow="currentTaskRow" :opts="printOpts"></printer-dialog>
+	</div>
+</template>
+
+<script setup>
+import path from 'path'
+import useTaskProcessStore from '@/store/modules/taskProcess'
+import { computed, ref, nextTick, watch, markRaw, defineAsyncComponent, provide, onMounted } from 'vue'
+import FlowStatusStamp from '@/components/Flow/FlowStatusStamp.vue'
+import FlowStatusTag from '@/components/Flow/FlowStatusTag.vue'
+import FlowNodeAvatar from '@/components/Flow/FlowNodeAvatar.vue'
+import FlowTypeDot from '@/components/Flow/FlowTypeDot.vue'
+import { ChatLineSquare, Check, Close, Switch, DArrowLeft, Plus, Minus, More, Printer } from '@element-plus/icons-vue'
+import { processTaskApprovalInfo, processClaimTaskApi } from '@/api/flow/processTask'
+import { formatTimestamp } from '@/utils/datetime'
+// import ReviewDialog from './reviewDialog'
+// import AddSignDialog from './addSignDialog'
+// import ConsentOrRefuseDialog from './consentOrRefuseDialog'
+// import DeliverToReviewDialog from './deliverToReviewDialog'
+// import LoseSignDialog from './loseSignDialog'
+// import RollbackDialog from './rollbackDialog'
+// import ViewProcessDialog from './ViewProcessDialog.vue'
+import PrinterDialog from '@/views/approve/components/printer.vue'
+// import PrinterDialog from './printer.vue'
+import { storeToRefs } from 'pinia'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { erFormPreview } from '@ER/formEditor'
+
+const modules = import.meta.glob('@/views/**/*.vue')
+const { VITE_APP_BASE_API } = import.meta.env
+const uploadFileApi = ref(`${VITE_APP_BASE_API}/v1/oss/upload`)
+import { package_modelContentConfig } from '../components/config.ts'
+import { useRoute } from 'vue-router'
+const route = useRoute()
+const props = defineProps({
+	/**
+	 * pendingApproval 待审批
+	 * myApplication 我的申请
+	 * myReceived 我收到的
+	 * pendingClaim 认领任务
+	 * approved 已审批
+	 */
+	currentTaskType: {
+		type: String,
+		default: ''
+	}
+})
+const tabName = ref('ApprovalInfo')
+const tabList = computed(() => {
+	const list = [
+		{
+			label: '审批信息',
+			value: 'ApprovalInfo'
+		},
+		{
+			label: '流程图',
+			value: 'FlowChart'
+		}
+	]
+	/*// 待审批 去掉流程图 todo?
+	if (props.currentTaskType === 'pendingApproval') {
+		list.splice(1, 1)
+	}*/
+	return list
+})
+const currentTaskRow = ref({})
+// store值
+// const taskProcessInfo = useTaskProcessStore()
+// const { currentTaskRow } = storeToRefs(taskProcessInfo)
+
+// 各种操作弹窗显示隐藏 start
+const reviewVisible = ref(false)
+const addSignVisible = ref(false)
+const consentOrRefuseVisible = ref(false)
+const deliverToReviewVisible = ref(false)
+const loseSignVisible = ref(false)
+const rollbackVisible = ref(false)
+const printerVisible = ref(false)
+const printOpts = ref({})
+const allowReject = ref(false)
+const allowRevocation = ref(false)
+
+// 各种操作弹窗显示隐藏 end
+const activeData = ref([])
+const currentType = ref(null)
+const currentFormData = ref({})
+// 当前form 表单数据字符串
+let cur_processForm_str = ''
+let cur_formStructure = {}
+let cur_formData = {}
+const openPrintModal = () => {
+	// innerTable.value = document.querySelector('.self-Everright-formEditor').innerHTML
+	printOpts.value = {
+		formStructure: cur_formStructure,
+		formData: cur_formData
+	}
+	printerVisible.value = true
+}
+const EReditorRef = ref()
+const taskId = computed(() => {
+	return currentTaskRow.value.taskId || ''
+})
+const validateForm = ref({
+	rule: [],
+	loading: false
+})
+// 允许转交
+const allowTransfer = ref(true)
+// 允许加减签
+const allowAppendNode = ref(true)
+// 允许回退
+const allowRollback = ref(true)
+const modelContentConfig = ref({})
+
+// 系统表单
+const dyVueComponent = ref(undefined)
+const dyVueComponentRef = ref()
+const dyVueForm = ref({})
+const currentObj = ref()
+provide('dyVueForm', dyVueForm) // 这里主要是存放动态的form的属性值
+
+
+/**
+ * 详情按钮各个操作弹窗
+ * @param visibleType 评论 拒绝 同意等
+ */
+const openComment = async (visibleType, item) => {
+	switch (visibleType) {
+		case 'reviewVisible':
+			currentType.value = item
+			reviewVisible.value = !reviewVisible.value
+			break
+		case 'addSignVisible':
+			addSignVisible.value = !addSignVisible.value
+			break
+		case 'consentOrRefuseVisible':
+			currentFormData.value = {}
+			if (item === 'agree') {
+				const { processType } = currentTaskRow.value
+				const flag = processType === 'business' && currentObj.value.formTemplate.type === 1 // 系统表单
+				if (flag) {
+					const formData = dyVueComponentRef.value.getComponentData()
+					const saveData = {
+						// 这里要调整真实的URL
+						// formStructure: currentObj.value.formTemplate.pcUrl,
+						formStructure: '@/views/flow/test/test1.vue',
+						formData
+					}
+					currentFormData.value = { processForm: JSON.stringify(saveData) }
+				} else {
+					const formData = EReditorRef.value.getData()
+					let processForm = JSON.parse(cur_processForm_str)
+					processForm = { ...processForm, formData }
+					currentFormData.value = { processForm: JSON.stringify(processForm) }
+				}
+			}
+			currentType.value = item
+			consentOrRefuseVisible.value = !consentOrRefuseVisible.value
+			break
+		case 'deliverToReviewVisible':
+			deliverToReviewVisible.value = !deliverToReviewVisible.value
+			break
+		case 'loseSignVisible':
+			loseSignVisible.value = !loseSignVisible.value
+			break
+		case 'rollbackVisible':
+			rollbackVisible.value = !rollbackVisible.value
+			break
+	}
+}
+
+/**
+ * 获取taskId对应的详情
+ * @param taskId
+ * 1、获取流程数据
+ * 2、获取表单数据
+ * 	2.1 主流程、业务流程(type=0 表单设计)、子流程 使用EverightForm表单来渲染表单值
+ * 	2.2 业务流程(type=1 使用系统表单来渲染表单值)
+ */
+const getTaskDetail = () => {
+	// const cur = currentTaskRow.value || {}
+	const { id } = route.query
+	validateForm.value.loading = true
+	processTaskApprovalInfo({
+		// taskId: cur.taskId,
+		// instanceId: cur.instanceId,
+		// instanceState: cur.instanceState
+		instanceId: id,
+	})
+		.then(data => {
+			const activeList = data.processApprovals
+			activeList.forEach(v => {
+				v.local_timestamp = v.id && formatTimestamp(v.createTime)
+				const _content = v.content
+				v.local_nodeUserList = _content?.nodeUserList || []
+				v.local_nodeRoleList = _content?.nodeRoleList || []
+				v.local_content = _content?.opinion
+			})
+			activeData.value = activeList
+			try {
+				const modelContent = JSON.parse(data.modelContent || '{}')
+				data.modelContent = modelContent
+				const modelContent_config = modelContent.nodeConfig // ?? modelContent.childNode
+				if (modelContent_config) {
+					package_modelContentConfig(modelContent_config, data.renderNodes || {})
+				}
+				modelContentConfig.value = modelContent_config || {}
+				window.modelContentConfig = modelContentConfig
+				/* 允许转交 允许加减签 允许回退 start */
+				if (props.currentTaskType === 'pendingApproval') {
+					allowTransfer.value = data?.allowTransfer
+					allowAppendNode.value = data?.allowAppendNode
+					allowRollback.value = data?.allowRollback
+				}
+				if (data?.taskType !== 0) {
+					allowReject.value = true
+				}
+				if (props.currentTaskType === 'myApplication') {
+					allowRevocation.value = data.processSetting.allowRevocation
+				}
+				/* 允许转交 允许加减签 允许回退 end */
+
+				/* 这里主要是表单设计的逻辑 start */
+				let formContent = null
+				const { processType } = currentTaskRow.value
+				if (processType === 'business') {
+					currentObj.value = data
+					if (data?.formTemplate.type === 1) {
+						dyVueForm.value = {
+							dy: {
+								name: '测试名字',
+								region: 1,
+								delivery: true,
+								type: ['1'],
+								resource: 'Sponsor',
+								desc: '啦啦啦'
+							}
+						}
+						// dyVueComponent.value = markRaw(defineAsyncComponent(() => import('@/views/flow/test/test1.vue')))
+						if (data.formTemplate.pcUrl && modules[data.formTemplate.pcUrl]) {
+							dyVueComponent.value = defineAsyncComponent(async () => await /* @vite-ignore */ modules[data.formTemplate.pcUrl]())
+						}
+						return
+					} else {
+						formContent = `{"formStructure":${data.formTemplate.content}}` || '{}'
+					}
+				} else {
+					formContent = data.formContent
+				}
+				cur_processForm_str = formContent
+				const { formStructure, formData } = JSON.parse(cur_processForm_str)
+				const formConfig = data.formConfig || []
+				cur_formStructure = formStructure // 存储一份
+				let newFields = cur_formStructure.fields
+				let newFieldsList = cur_formStructure.list
+				// pendingApproval, 除了[待审批]这个状态, 其余只能读取
+				// if (props.currentTaskType !== 'pendingApproval') {
+				newFields.map(item1 => (item1.options.disabled = true))
+				// }
+				/* else {
+					// data.formConfig
+					newFields.forEach(item => {
+						const matchingFormItem = formConfig.find(formItem => formItem.id == item.id)
+						// 如果找到匹配的对象,且opera为'2',则删除newFields中的对象
+						if (matchingFormItem && matchingFormItem.opera === '2') {
+							newFields = newFields.filter(t => t.id !== item.id)
+						} else if (matchingFormItem) {
+							// 否则,将opera属性添加到newFields中的对象
+							item.opera = matchingFormItem.opera
+							// '0': 只读 '1': 编辑 '2': 隐藏
+							item.options.disabled = ['0', '1'].indexOf(matchingFormItem.opera) > -1 ? !Number(matchingFormItem.opera) : false
+						}
+					})
+
+					newFieldsList.forEach(item => {
+						const matchingFormItem = formConfig.find(formItem => formItem.id == item.id)
+						// 如果找到匹配的对象,且opera为'2',则删除newFields中的对象
+						if (matchingFormItem && matchingFormItem.opera === '2') {
+							newFieldsList = newFieldsList.filter(t => t.id !== item.id)
+						}
+					})
+				}*/
+				cur_formStructure = {
+					...cur_formStructure,
+					fields: newFields,
+					list: newFieldsList
+				}
+				cur_formData = formData
+				console.log(cur_formStructure, '=/////====newFormStructure')
+				console.log(formData, '=/////====newFormStructure')
+				EReditorRef.value.setData(cur_formStructure, formData)
+				validateForm.value.rule = newFields
+				/* 这里主要是表单设计的逻辑 end */
+			} catch (e) {
+				console.error('解析 descItems 数据出现问题', e)
+				// descItemsData.value.list = []
+				validateForm.value.rule = []
+			}
+			currentTaskRow.value = data
+		})
+		.finally(() => {
+			validateForm.value.loading = false
+		})
+}
+onMounted(getTaskDetail)
+const processInfo = ref({ name: '', id: '', instanceId: '', visible: false })
+const lookSubProcess = item => {
+	const [id, name, instanceId] = item.content.callProcess.split(':')
+	processInfo.value = {
+		name,
+		id,
+		instanceId,
+		visible: true
+	}
+}
+
+</script>
+
+<style scoped lang="scss">
+.column-page-wrap {
+	background: transparent;
+}
+.flow-detail-content {
+	height: 100%;
+	overflow: hidden;
+	background: var(--el-bg-color);
+	border-radius: 6px;
+	flex: 1;
+	.flow-detail-container {
+		display: flex;
+		flex-direction: column;
+		position: relative;
+		height: 100%;
+		overflow: hidden;
+	}
+
+	// 通过、不通过样式
+	.flow-status-stamp {
+		position: absolute;
+		right: 60px;
+		top: 10px;
+		z-index: 99;
+	}
+
+	// 头部
+	.flow-header-box {
+		font-weight: 400;
+		font-size: 13px;
+		border-bottom: 1px solid var(--el-border-color);
+		padding: 0 20px;
+		height: 39px;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		color: var(--el-color-info);
+		.action-area {
+			display: flex;
+			gap: 4px;
+			.action-item {
+				cursor: pointer;
+				display: flex;
+				align-items: center;
+			}
+		}
+	}
+
+	// 内容体
+	.flow-detail-box {
+		//height: calc(100% - 92px);
+		//overflow: hidden;
+		//overflow-y: auto;
+		flex: 1;
+		min-height: 0;
+		padding: 0 20px;
+		display: flex;
+		flex-direction: column;
+		height: 100%;
+		.header-box {
+			display: flex;
+			flex-direction: column;
+			justify-content: center;
+			padding-bottom: 10px;
+			// padding-top: 20px;
+			.summary-info {
+				display: flex;
+				align-items: center;
+				padding-top: 10px;
+				font-size: 24px;
+				.title {
+					font-family: PingFangSC-Semibold, PingFang SC;
+					color: var(--el-text-color-primary);
+				}
+			}
+			.initiator-info {
+				display: flex;
+				align-items: center;
+				margin-top: 16px;
+				.begin-time {
+					margin-left: 16px;
+					font-weight: 350;
+					color: var(--el-text-color-placeholder);
+					font-size: 13px;
+					-webkit-user-select: none;
+					user-select: none;
+				}
+			}
+		}
+		.area-divider {
+			border-bottom: 1px solid var(--el-border-color);
+			margin: 20px 0;
+			//position: relative;
+		}
+		.scroll-wrap {
+			position: relative;
+			overflow: hidden;
+			overflow-y: auto;
+			flex: 1;
+			.tags-desc {
+				position: absolute;
+				left: 6px;
+				top: 10px;
+				z-index: 1;
+			}
+
+			:deep(.zoom-scale) {
+				position: absolute;
+				top: 16px;
+				right: 16px;
+			}
+		}
+	}
+
+	// 底部
+	.flow-actions {
+		display: flex;
+		align-items: center;
+		justify-content: flex-end;
+		height: 52px;
+		//border-top: 1px solid var(--color-neutral-3);
+		border-top: 1px solid var(--el-border-color-light);
+		background: var(--el-bg-color);
+		padding: 0 20px;
+	}
+}
+
+.comment-content {
+	user-select: none;
+	margin-top: 4px;
+	padding: 8px;
+	border-radius: 4px;
+	background-color: var(--el-bg-color-page);
+}
+
+.timeline-box {
+	margin-left: 5px;
+}
+
+:deep(.el-timeline-item__timestamp) {
+	margin-left: 6px;
+}
+
+// 修改everright 表单的样式
+.self-Everright-formEditor {
+	:deep(.Everright-formEditor-selectElement) {
+		padding: 0px 16px;
+	}
+}
+</style>