Explorar o código

reactor:附件上传对接;

zhangchong hai 1 ano
pai
achega
bf679ce96d

+ 44 - 22
src/components/AnnexList/index.vue

@@ -1,5 +1,5 @@
 <template>
-	<div class="w100">
+	<div class="w100 files">
 		<slot name="head"> </slot>
 		<el-upload
 			class="upload-demo w100"
@@ -12,30 +12,33 @@
 			name="fileData"
 			:on-change="handleChangeFile"
 			:on-success="updateData"
+			:disabled="props.readonly"
 		>
-			<el-button> <SvgIcon name="ele-Upload" /> 上传附件 </el-button>
+			<el-button> <SvgIcon name="ele-Upload" /> {{ props.name }} </el-button>
 			<slot> </slot>
 			<template #file="{ file }">
 				<div class="el-upload-list__item-info">
 					<a class="el-upload-list__item-name">
-						<SvgIcon class="mr5" :name="fileType(checkFile(file.name))" size="14px" />
-						<span class="el-upload-list__item-file-name" :title="file.name">{{ file.name }}</span>
-						<el-switch
-							class="ml20 mr10"
-							v-model="file.publicity"
-							active-text="公开"
-							inactive-text="不公开"
-							inline-prompt
-							:active-value="1"
-							:inactive-value="0"
-							@change="updateData"
-						/>
+						<SvgIcon class="mr5" :name="fileType(checkFile(file.name))" size="14px"  @click="onPreview(file)"/>
+						<span class="el-upload-list__item-file-name" :title="file.name"  @click="onPreview(file)">{{ file.name }}</span>
+						<span @click.stop="">
+              <el-switch
+                  class="ml20 mr10"
+                  v-model="file.publicity"
+                  active-text="公开"
+                  inactive-text="不公开"
+                  inline-prompt
+                  :active-value="1"
+                  :inactive-value="0"
+                  @change="updateData"
+              />
+            </span>
 					</a>
 				</div>
 				<SvgIcon name="ele-Download" size="14px" class="el-icon--close mr20" title="下载文件" @click="handleDownload(file)" />
 				<SvgIcon name="ele-Close" class="el-icon--close" size="14px" title="删除文件" @click="handleRemove(file)" />
 			</template>
-			<template #tip>
+			<template #tip v-if="!props.readonly">
 				<div class="el-upload__tip">大小限制:20M</div>
 			</template>
 		</el-upload>
@@ -43,7 +46,7 @@
 	</div>
 </template>
 <script setup lang="ts" name="annexList">
-import {computed, onMounted, ref, watch} from 'vue';
+import { computed, onMounted, ref, watch } from 'vue';
 import { checkFile, downloadFile, fileType } from '/@/utils/tools';
 import { ElButton, ElMessage, ElMessageBox } from 'element-plus';
 const emit = defineEmits(['update:modelValue', 'update:format']);
@@ -176,14 +179,33 @@ const handleDownload = (uploadFile: any) => {
 		})
 		.catch(() => {});
 };
+// 预览
+const onPreview = (file: any) => {
+  if (!file.path) {
+    ElMessage.error('附件不存在');
+    return;
+  }
+  // 图片预览
+
+  const url = import.meta.env.VITE_FILE_PREFIX + file.path;
+  window.open(url);
+};
 onMounted(() => {
-  fileList.value = props.modelValue;
+	fileList.value = props.modelValue;
 });
 </script>
 <style lang="scss" scoped>
-.upload-demo{
-  .el-upload-list__item{
-    margin-bottom: 0;
-  }
+.files {
+	.upload-demo {
+		.el-upload__tip {
+			margin-top: 0 !important;
+		}
+		:deep(.el-upload-list) {
+			margin: 0 !important;
+		}
+		:deep(.el-upload-list__item) {
+			margin-bottom: 0 !important;
+		}
+	}
 }
-</style>
+</style>

+ 20 - 1
src/components/OrderDetail/index.vue

@@ -168,7 +168,7 @@
 							</el-col>
 							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
 								<el-form-item label="附件">
-									<annex-list name="查看附件" readonly :businessId="state.ruleForm.id" classify="查看附件" />
+									<annex-list name="附件列表" readonly :businessId="state.ruleForm.id" classify="查看附件" v-model="files"/>
 								</el-form-item>
 							</el-col>
 						</el-row>
@@ -580,12 +580,31 @@ const state = reactive<any>({
 const showMaskNumber = ref<boolean>(true); // 是否展示号码
 const ruleFormRef = ref<RefType>(); // 表单ref
 const router = useRouter(); // 路由
+const files = ref<any[]>([]); // 附件列表
 // 查看工单详情
 const getOrderDetail = async (id: string) => {
 	state.loading = true;
 	try {
 		const res: any = await orderDetail(id);
 		state.ruleForm = res.result;
+    // 附件列表
+    if (state.ruleForm.files) {
+      state.ruleForm.files.forEach((item: any) => {
+        files.value.push({
+          ...item,
+          name: item.name+'.'+item.type,
+          response:{
+            result: {
+              path: item.path,
+              fileName: item.name+'.'+item.type,
+              type: item.type,
+              additions: item.additions,
+            },
+          }
+        });
+      });
+    }
+    console.log(state.ruleForm.files,files.value)
 		state.workflow = state.ruleForm?.workflow ?? {};
 		state.supplements = res.result?.workflow?.supplements ?? [];
 		state.loading = false;

+ 61 - 51
src/components/ProcessAudit/index.vue

@@ -249,7 +249,7 @@
 							{{ state.ruleForm.endTime }}
 						</el-form-item>
 					</el-col>
-<!--					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="handelArr.includes(state.processType)">
+					<!--					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="handelArr.includes(state.processType)">
 						<el-form-item label="节点期满时间" prop="expiredTime" :rules="[{ required: true, message: '请选择节点期满时间', trigger: 'change' }]">
 							<el-date-picker
 								v-model="state.ruleForm.expiredTime"
@@ -318,7 +318,14 @@
 					</el-col>
 					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
 						<el-form-item label="附件" prop="additions" :rules="[{ required: false, message: '请填写诉求内容', trigger: 'change' }]">
-							<annex-list :name="state.annexName" ref="annexListRef" :businessId="state.orderDetail.id" :classify="state.classify" />
+							<annex-list
+								:name="state.annexName"
+								:flowKey="state.workflowId"
+								:businessId="state.orderDetail.id"
+								:classify="state.classify"
+								v-model="handleFiles"
+								v-model:format="handleFilesFormat"
+							/>
 						</el-form-item>
 					</el-col>
 				</template>
@@ -381,7 +388,6 @@ import { formatDate } from '/@/utils/formatTime';
 // 引入组件
 const CommonAdvice = defineAsyncComponent(() => import('/@/components/CommonAdvice/index.vue')); // 常用意见
 const AnnexList = defineAsyncComponent(() => import('/@/components/AnnexList/index.vue')); // 附件列表
-const Editor = defineAsyncComponent(() => import('/@/components/Editor/index.vue')); // 富文本编辑器
 // 定义子组件向父组件传值/事件
 const emit = defineEmits(['orderProcessSuccess', 'orderProcessFailed']);
 // 定义变量内容
@@ -432,7 +438,7 @@ const storesUserInfo = useUserInfo();
 const { userInfos } = storeToRefs(storesUserInfo); // 用户信息
 const showStepsArr = ['延期申请', '甄别申请', '工单重办']; // 显示步骤条的流程
 const handelArr = ['工单办理']; // 处于办理状态的流程 (如果是汇总节点 需要填写办理对象等  办理流程才有期满时间)
-const returnArr = ['工单退回','甄别退回','延期退回']; // 退回流程 (退回流程不需要展示其他 只需要填写意见和附件即可)
+const returnArr = ['工单退回', '甄别退回', '延期退回']; // 退回流程 (退回流程不需要展示其他 只需要填写意见和附件即可)
 
 const timeType = ref<EmptyArrayType>([]); // 延期申请单位
 const orderRedoReasonOptions = ref<EmptyArrayType>([]); // 重办理由
@@ -482,10 +488,10 @@ const openDialog = async (val: any) => {
 				break;
 			case '工单退回': // 退回流程
 				break;
-      case '甄别退回': // 退回流程
-        break;
-      case '延期退回': // 退回流程
-        break;
+			case '甄别退回': // 退回流程
+				break;
+			case '延期退回': // 退回流程
+				break;
 			case '工单办理': // 工单办理
 				const [workflowNextStepsResponse] = await Promise.all([workflowNextSteps(state.workflowId)]); // 获取下一节点和下一节点参数
 				handleResult(workflowNextStepsResponse);
@@ -498,10 +504,10 @@ const openDialog = async (val: any) => {
 				const [KnowledgeUpdateResponse] = await Promise.all([KnowledgeUpdateStartFlowParams()]); // 知识库更新参数
 				handleResult(KnowledgeUpdateResponse);
 				break;
-      case '更新新增知识':
-        const [KnowledgeAddUpdateResponse] = await Promise.all([KnowledgeAddStartFlowParams()]); // 知识库更新参数
-        handleResult(KnowledgeAddUpdateResponse);
-        break;
+			case '更新新增知识':
+				const [KnowledgeAddUpdateResponse] = await Promise.all([KnowledgeAddStartFlowParams()]); // 知识库更新参数
+				handleResult(KnowledgeAddUpdateResponse);
+				break;
 			case '删除知识':
 				const [KnowledgeDeleteResponse] = await Promise.all([KnowledgeDeleteStartFlowParams()]); // 知识库删除参数
 				handleResult(KnowledgeDeleteResponse);
@@ -531,12 +537,11 @@ const handleResult = (res: any) => {
 	if (state.nextStepOptions.length === 1) {
 		// 下一节点是否只有一个 默认选中第一个
 		setTimeout(() => {
-      state.ruleForm.nextStepCode = state.nextStepOptions[0].key; // 下一节点code
-      state.ruleForm.nextStepName = state.nextStepOptions[0].value; // 下一节点name
-      state.ruleForm.backToCountersignEnd = state.nextStepOptions[0].backToCountersignEnd ?? false; // 是否回到会签结束节点
-    }, 0);
+			state.ruleForm.nextStepCode = state.nextStepOptions[0].key; // 下一节点code
+			state.ruleForm.nextStepName = state.nextStepOptions[0].value; // 下一节点name
+			state.ruleForm.backToCountersignEnd = state.nextStepOptions[0].backToCountersignEnd ?? false; // 是否回到会签结束节点
+		}, 0);
 		selectNextStep(state.nextStepOptions[0].key); // 查询流程下一节点参数
-
 	} else {
 		state.ruleForm.nextStepCode = '';
 		state.ruleForm.nextStepName = '';
@@ -746,6 +751,11 @@ const close = () => {
 const annexListRef = ref<RefType>(); // 流程附件
 const delayAnnexListRef = ref<RefType>(); // 延期附件
 const discernAnnexListRef = ref<RefType>(); // 甄别附件
+
+const handleFiles = ref<EmptyArrayType>([]); // 流程附件
+const handleFilesFormat = ref<EmptyArrayType>([]); // 流程附件
+const handleFilesDelay = ref<EmptyArrayType>([]); // 延期附件
+const handleFilesDiscern = ref<EmptyArrayType>([]); // 甄别附件
 const onSubmit = (formEl: FormInstance | undefined) => {
 	if (!formEl) return;
 	formEl.validate((valid: boolean) => {
@@ -783,7 +793,7 @@ const onSubmit = (formEl: FormInstance | undefined) => {
 					case '工单发起':
 						const request = {
 							data: { ...state.orderDetail },
-							workflow: { ...submitObj, files: annexListRef.value?.fileList },
+							workflow: { ...submitObj, files: handleFilesFormat.value },
 						};
 						orderStartFlow(request)
 							.then(() => {
@@ -794,7 +804,7 @@ const onSubmit = (formEl: FormInstance | undefined) => {
 							});
 						break;
 					case '工单撤回':
-						workflowRecall({...submitObj,files: annexListRef.value?.fileList})
+						workflowRecall({ ...submitObj, files: annexListRef.value?.fileList })
 							.then(() => {
 								afterSubmit('orderProcessSuccess', true);
 							})
@@ -880,24 +890,24 @@ const onSubmit = (formEl: FormInstance | undefined) => {
 								afterSubmit('orderProcessFailed');
 							});
 						break;
-          case '甄别退回':
-            workflowPrevious({ ...submitObj, files: annexListRef.value?.fileList })
-                .then(() => {
-                  afterSubmit('orderProcessSuccess', true);
-                })
-                .catch(() => {
-                  afterSubmit('orderProcessFailed');
-                });
-            break;
-          case '延期退回':
-            workflowPrevious({ ...submitObj, files: annexListRef.value?.fileList })
-                .then(() => {
-                  afterSubmit('orderProcessSuccess', true);
-                })
-                .catch(() => {
-                  afterSubmit('orderProcessFailed');
-                });
-            break;
+					case '甄别退回':
+						workflowPrevious({ ...submitObj, files: annexListRef.value?.fileList })
+							.then(() => {
+								afterSubmit('orderProcessSuccess', true);
+							})
+							.catch(() => {
+								afterSubmit('orderProcessFailed');
+							});
+						break;
+					case '延期退回':
+						workflowPrevious({ ...submitObj, files: annexListRef.value?.fileList })
+							.then(() => {
+								afterSubmit('orderProcessSuccess', true);
+							})
+							.catch(() => {
+								afterSubmit('orderProcessFailed');
+							});
+						break;
 					case '新增知识':
 						const KnowledgeAddRequest = {
 							data: { ...state.orderDetail },
@@ -911,19 +921,19 @@ const onSubmit = (formEl: FormInstance | undefined) => {
 								afterSubmit('orderProcessFailed');
 							});
 						break;
-          case '更新新增知识':
-            const KnowledgeAddUpdateRequest = {
-              data: { ...state.orderDetail },
-              workflow: { ...submitObj, files: annexListRef.value?.fileList },
-            };
-            KnowledgeUpdate(KnowledgeAddUpdateRequest)
-                .then(() => {
-                  afterSubmit('orderProcessSuccess', true);
-                })
-                .catch(() => {
-                  afterSubmit('orderProcessFailed');
-                });
-            break;
+					case '更新新增知识':
+						const KnowledgeAddUpdateRequest = {
+							data: { ...state.orderDetail },
+							workflow: { ...submitObj, files: annexListRef.value?.fileList },
+						};
+						KnowledgeUpdate(KnowledgeAddUpdateRequest)
+							.then(() => {
+								afterSubmit('orderProcessSuccess', true);
+							})
+							.catch(() => {
+								afterSubmit('orderProcessFailed');
+							});
+						break;
 					case '更新知识':
 						const KnowledgeUpdateRequest = {
 							data: { ...state.orderDetail },
@@ -951,7 +961,7 @@ const onSubmit = (formEl: FormInstance | undefined) => {
 							});
 						break;
 					default: // 默认工单办理
-						workflowNext({ ...submitObj, files: annexListRef.value?.fileList })
+						workflowNext({ ...submitObj, files: handleFilesFormat.value })
 							.then(() => {
 								afterSubmit('orderProcessSuccess', true);
 							})

+ 47 - 46
src/components/ProcessTimeLine/index.vue

@@ -23,50 +23,45 @@
 				<!-- 内容 -->
 				<el-card class="card">
 					<!-- 正常流转 -->
-					<div
-						class="icon color-primary"
-						v-if="item.status === 1"
-						:style="'background-image:url(' + getImageUrl('order/processNormal.png') + ')'"
-					>
+					<div class="icon color-primary" v-if="item.status === 1" :style="'background-image:url(' + getImageUrl('order/processNormal.png') + ')'">
 						{{ item.statusText }}
 					</div>
 					<!-- 其他状态 -->
-					<div
-						class="icon color-danger"
-						:style="'background-image:url(' + getImageUrl('order/processReturn.png') + ')'"
-						v-else
-					>
+					<div class="icon color-danger" :style="'background-image:url(' + getImageUrl('order/processReturn.png') + ')'" v-else>
 						{{ item.statusText }}
 					</div>
-          <el-tag round size="large" class="tag mr10" v-for="hander in  item.handlers" :key="hander.key">
-            <span>{{ hander.value }}</span>
-          </el-tag>
-          <el-row class="infos mt20">
-            <el-col :xs="24" :sm="12" :md="12" :lg="4" :xl="4">
-                <p class="infos-title">接办人</p>
-                <p class="infos-inner">{{ item.acceptorName }}</p>
-            </el-col>
-            <el-col :xs="24" :sm="12" :md="12" :lg="4" :xl="4">
-                <p class="infos-title">接办时间</p>
-                <p class="infos-inner">{{ formatDate(item.acceptTime, 'YYYY-mm-dd HH:MM:SS') }}</p>
-            </el-col>
-            <el-col :xs="24" :sm="12" :md="12" :lg="4" :xl="4">
-              <p class="infos-title">办理人</p>
-              <p class="infos-inner">{{ item.handlerName }}</p>
-            </el-col>
-            <el-col :xs="24" :sm="12" :md="12" :lg="4" :xl="4">
-                <p class="infos-title">办理时间</p>
-                <p class="infos-inner">{{ formatDate(item.handleTime, 'YYYY-mm-dd HH:MM:SS') }}</p>
-            </el-col>
-            <el-col :xs="24" :sm="12" :md="12" :lg="4" :xl="4">
-                <p class="infos-title">办理期限</p>
-                <p class="infos-inner">{{ formatDate(item.stepExpiredTime, 'YYYY-mm-dd HH:MM:SS') }}</p>
-            </el-col>
-          </el-row>
+					<el-tag round size="large" class="tag mr10 mb10" v-for="hander in item.handlers" :key="hander.key">
+						<span>{{ hander.value }}</span>
+					</el-tag>
+					<el-row class="infos mt10">
+						<el-col :xs="24" :sm="12" :md="12" :lg="4" :xl="4">
+							<p class="infos-title">接办人</p>
+							<p class="infos-inner">{{ item.acceptorName }}</p>
+						</el-col>
+						<el-col :xs="24" :sm="12" :md="12" :lg="4" :xl="4">
+							<p class="infos-title">接办时间</p>
+							<p class="infos-inner">{{ formatDate(item.acceptTime, 'YYYY-mm-dd HH:MM:SS') }}</p>
+						</el-col>
+						<el-col :xs="24" :sm="12" :md="12" :lg="4" :xl="4">
+							<p class="infos-title">办理人</p>
+							<p class="infos-inner">{{ item.handlerName }}</p>
+						</el-col>
+						<el-col :xs="24" :sm="12" :md="12" :lg="4" :xl="4">
+							<p class="infos-title">办理时间</p>
+							<p class="infos-inner">{{ formatDate(item.handleTime, 'YYYY-mm-dd HH:MM:SS') }}</p>
+						</el-col>
+						<el-col :xs="24" :sm="12" :md="12" :lg="4" :xl="4">
+							<p class="infos-title">办理期限</p>
+							<p class="infos-inner">{{ formatDate(item.stepExpiredTime, 'YYYY-mm-dd HH:MM:SS') }}</p>
+						</el-col>
+					</el-row>
 					<div class="opinion" v-if="item.opinion">
 						<span class="opinion-title">意见</span>
-						<text-ellipsis :content="item.opinion" :rows="1">
-            </text-ellipsis>
+						<text-ellipsis :content="item.opinion" :rows="1"> </text-ellipsis>
+					</div>
+					<div class="files">
+						<span class="opinion-title">附件</span>
+            <annex-list name="附件列表" readonly businessId="" classify="查看附件" v-model="item.files"/>
 					</div>
 				</el-card>
 				<!-- 展开收起 -->
@@ -78,7 +73,7 @@
 						{{ isOpen(item.code) ? '收起' : '展开' }}会签<SvgIcon
 							name="ele-DArrowRight"
 							class="ml5 collapse-item__arrow"
-							style="transition: transform 0.3s;transform: rotate(-90deg)"
+							style="transition: transform 0.3s; transform: rotate(-90deg)"
 							:style="isOpen(item.code) ? 'transform: rotate(90deg)' : 'transform: rotate(-90deg)'"
 						/>
 					</el-button>
@@ -105,7 +100,9 @@
 import { defineAsyncComponent, computed, reactive, watch, onMounted } from 'vue';
 import { getImageUrl } from '/@/utils/tools';
 import { formatDate } from '/@/utils/formatTime';
-import {removeDuplicate} from "/@/utils/arrayOperation";
+import { removeDuplicate } from '/@/utils/arrayOperation';
+
+const AnnexList = defineAsyncComponent(() => import('/@/components/AnnexList/index.vue')); // 附件列表
 const emit = defineEmits(['node-click']);
 const props = defineProps({
 	// 数据
@@ -172,7 +169,7 @@ const getAllKeys = (val: any) => {
 const itemNodeClick = (item: any) => {
 	emit('node-click', item);
 	if (item.traces && item.traces.length) {
-    const index = state.expandedKeys.findIndex((i: any) => i === item.code);
+		const index = state.expandedKeys.findIndex((i: any) => i === item.code);
 		if (index != -1) {
 			// 如果当前节点id存在数组中,则删除
 			state.expandedKeys.splice(index, 1);
@@ -243,12 +240,12 @@ onMounted(() => {
 			line-height: 24px;
 		}
 		.infos {
-				&-title {
-					color: var(--hotline-bg-grey-color);
-				}
-				&-inner {
-					margin-top: 10px;
-				}
+			&-title {
+				color: var(--hotline-bg-grey-color);
+			}
+			&-inner {
+				margin-top: 10px;
+			}
 		}
 		.opinion {
 			display: flex;
@@ -261,6 +258,10 @@ onMounted(() => {
 				line-height: 30px;
 			}
 		}
+		.files {
+			margin-top: 5px;
+      display: flex;
+		}
 	}
 	.item-children {
 		padding: 20px;

+ 1 - 1
src/utils/ola_api.ts

@@ -324,7 +324,7 @@ export const ola: any = {
 
 	send: function (msg: any) { //发送消息
 		if(!ola.ws) {
-			ElMessage.error("请先签入")
+			ElMessage.warning("请先签入")
 			return;
 		}
 		msg.uuid = ola.next_uuid();

+ 0 - 6
src/views/todo/seats/accept/index.vue

@@ -1039,11 +1039,6 @@ const loadForm = async () => {
 		};
     // 附件列表
     if (state.ruleForm.files) {
-      // filesFormat.value = state.ruleForm.files.map((item: any) => {
-      //   return {
-      //    ...item,
-      //   };
-      // });
       state.ruleForm.files.forEach((item: any) => {
         files.value.push({
           ...item,
@@ -1058,7 +1053,6 @@ const loadForm = async () => {
           }
         });
       });
-      console.log(files.value);
     }
 		setTimeout(() => {
 			searchHistory(state.ruleForm.contact);