瀏覽代碼

reactor:附件上传对接;

zhangchong 1 年之前
父節點
當前提交
bd1c0d9fdc

+ 2 - 2
.env.development

@@ -16,8 +16,8 @@ VITE_API_SOCKET_URL=http://110.188.24.28:50100/hubs/hotline
 # #上传 API
 VITE_API_UPLOAD_URL=http://110.188.24.28:50120
 
-# #上传 API
-VITE_SOCKET_GROUP_NAME=ws://110.188.24.28:50100/hubs/hotline
+# # 文件上传地址前缀
+VITE_FILE_PREFIX=http://open.fs.12345lm.cn
 
 # #高德地图安全密钥
 VITE_AMAP_SECURITYJSCODE=dd12ddafb11921dbcdc5b9c4484bb4e2

+ 2 - 2
.env.production

@@ -16,8 +16,8 @@ VITE_API_SOCKET_URL=http://110.188.24.28:50100/hubs/hotline
 # #上传 API
 VITE_API_UPLOAD_URL=http://110.188.24.28:50120
 
-# #上传 API
-VITE_SOCKET_GROUP_NAME=http://110.188.24.28:50100/hubs/hotline
+# # 文件上传地址前缀
+VITE_FILE_PREFIX=http://open.fs.12345lm.cn
 
 # #高德地图安全密钥
 VITE_AMAP_SECURITYJSCODE=dd12ddafb11921dbcdc5b9c4484bb4e2

+ 2 - 2
.env.test

@@ -15,8 +15,8 @@ VITE_API_SOCKET_URL=http://110.188.24.28:50100/hubs/hotline
 # #上传 API
 VITE_API_UPLOAD_URL=http://110.188.24.28:50100/hubs/hotline
 
-# #上传 API
-VITE_SOCKET_GROUP_NAME=http://110.188.24.28:50100/hubs/hotline
+# # 文件上传地址前缀
+VITE_FILE_PREFIX=http://open.fs.12345lm.cn
 
 # #高德地图安全密钥
 VITE_AMAP_SECURITYJSCODE=dd12ddafb11921dbcdc5b9c4484bb4e2

+ 172 - 332
src/components/AnnexList/index.vue

@@ -1,349 +1,189 @@
 <template>
-  <slot>
-    <el-button @click="uploadAnnex"> <SvgIcon name="ele-Upload" /> {{props.name}} </el-button>
-    <span class="color-info ml10" v-if="state.tableData.length">当前已上传 <span class="color-primary">{{ state.tableData.length }}</span> 个附件</span>
-  </slot>
-	<el-dialog v-model="dialogVisible" draggable title="附件列表" ref="dialogRef" width="60%" append-to-body destroy-on-close>
-		<div class="mb20" v-if="!props.readonly">
-			<el-button type="primary" @click="handleAdd"><SvgIcon name="ele-Plus" class="mr3" v-auth="'file:add'"/> 添加附件</el-button>
-			<el-button type="primary" @click="handleDelete" :disabled="!multipleSelection.length" v-auth="'file:delete'"
-				><SvgIcon name="ele-Delete" class="mr3" />删除附件</el-button
-			>
-		</div>
-		<!-- 表格 -->
-		<el-table :data="state.tableData" v-loading="loading" row-key="id" ref="multipleTableRef" @selection-change="handleSelectionChange">
-			<el-table-column type="selection" width="55" :reserve-selection="true" v-if="!props.readonly"/>
-			<el-table-column prop="name" label="附件名称" show-overflow-tooltip width="240"></el-table-column>
-			<el-table-column prop="type" label="文件类型" show-overflow-tooltip width="100"></el-table-column>
-			<el-table-column prop="creationTime" label="上传时间" show-overflow-tooltip width="170">
-				<template #default="{ row }">
-					<span>{{ formatDate(row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
-				</template>
-			</el-table-column>
-			<el-table-column prop="orgName" label="上传部门" show-overflow-tooltip width="200"></el-table-column>
-			<el-table-column prop="userName" label="上传人" show-overflow-tooltip></el-table-column>
-			<el-table-column prop="publicity" label="是否公开给市民" show-overflow-tooltip width="140">
-        <template #default="{ row }">
-          {{ row.publicity == 1 ? '是' : '否'}}
-        </template>
-      </el-table-column>
-			<el-table-column prop="classify" label="附件分类" show-overflow-tooltip width="100"></el-table-column>
-			<el-table-column label="操作" width="80" fixed="right" align="center">
-				<template #default="{ row }">
-					<el-button link type="primary" @click="download(row)" title="下载附件" v-auth="'file:download'" v-if="row.url"> 下载 </el-button>
-				</template>
-			</el-table-column>
-			<template #empty>
-				<Empty />
+	<div class="w100">
+		<slot name="head"> </slot>
+		<el-upload
+			class="upload-demo w100"
+			v-model:file-list="fileList"
+			:action="action"
+			:multiple="true"
+			accept="*"
+			:on-exceed="handleExceed"
+			ref="uploadListRef"
+			name="fileData"
+			:on-change="handleChangeFile"
+			:on-success="updateData"
+		>
+			<el-button> <SvgIcon name="ele-Upload" /> 上传附件 </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"
+						/>
+					</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>
-		</el-table>
-		<!-- 分页 -->
-		<pagination :total="total" v-model:page="queryParams.PageIndex" v-model:limit="queryParams.PageSize" @pagination="queryList" v-if="props.businessId"/>
-		<!--  上传  -->
-		<el-dialog v-model="dialogVisibleUpload" draggable title="上传附件" @close="close" ref="dialogRef" width="600px" append-to-body destroy-on-close>
-			<el-form :model="ruleForm" ref="ruleFormRef" @submit.native.prevent class="mt15" label-width="120px">
-				<el-form-item label="是否公开给市民" prop="publicity" :rules="[{ required: true, message: '请选择是否公开', trigger: 'change' }]">
-					<el-radio-group v-model="ruleForm.publicity">
-						<el-radio :label="1">公开</el-radio>
-						<el-radio :label="0">不公开</el-radio>
-					</el-radio-group>
-				</el-form-item>
-        <el-form-item label="附件" prop="fileList" :rules="[{ required: true, message: '请选择附件文件', trigger: 'change' }]">
-          <el-upload
-              class="upload-demo w100"
-              v-model:file-list="ruleForm.fileList"
-              action="#"
-              :auto-upload="false"
-              :multiple="true"
-              accept="*"
-              :on-exceed="handleExceed"
-              :http-request="httpRequest"
-              :on-change="handleChange"
-              ref="uploadListRef"
-          >
-            <el-button> <SvgIcon name="ele-Upload" /> 上传附件 </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>
-                </a>
-              </div>
-              <SvgIcon name="ele-Close" class="el-icon--close" size="14px" title="删除文件" @click="handleRemove(file)" />
-            </template>
-          </el-upload>
-        </el-form-item>
-			</el-form>
-      <template #footer>
-          <el-button class="default-button" @click="dialogVisibleUpload = false"> 取 消</el-button>
-          <el-button type="primary"  @click="submit(ruleFormRef)"> 确 定 </el-button>
-      </template>
-		</el-dialog>
-    <template #footer>
-      <el-button class="default-button" @click="dialogVisible = false">取 消</el-button>
-    </template>
-	</el-dialog>
+			<template #tip>
+				<div class="el-upload__tip">大小限制:20M</div>
+			</template>
+		</el-upload>
+		<slot name="footer"> </slot>
+	</div>
 </template>
-<script setup lang="ts" name="AnnexList">
-import {reactive, ref} from 'vue';
-import { formatDate } from '/@/utils/formatTime';
-import {checkFile, fileType} from '/@/utils/tools';
-import { storeToRefs } from 'pinia';
-import { useUserInfo } from '/@/stores/userInfo';
-import { guid } from '/@/utils/tools';
-import {ElButton, ElMessage, ElMessageBox, FormInstance} from 'element-plus';
-import {fileList, fileAdd, fileDelete} from "/@/api/public/file";
-
-const dialogVisible = ref(false); // 弹窗显示隐藏
-const dialogVisibleUpload = ref(false); // 上传弹窗显示隐藏
-const loading = ref(false); // 表格加载状态
-const total = ref(0); // 表格总数
-const uploadListRef = ref<RefType>(); // 上传附件ref
-const ruleFormRef = ref<RefType>(); // 上传附件表单ref
-const queryParams = ref({
-	// 查询参数
-	PageIndex: 1, // 当前页
-	PageSize: 10, // 每页条数
-});
-const ruleForm = reactive({
-	// 上传附件表单
-  publicity: 0,
-  fileList:<EmptyArrayType>[]
-});
-const state = reactive<any>({
-  tableData: <EmptyArrayType>[], //表格数据
-})
-const emit = defineEmits(['uploadAnnex'])
+<script setup lang="ts" name="annexList">
+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']);
 const props = defineProps({
-  name: {
-    type: String,
-    default: '上传附件'
-  },
-  fileLimit:{ // 限制上传数量
-    type: Number,
-    default: 5
-  },
-  fileSize:{ // 限制上传大小(M)
-    type: Number,
-    default: 10
-  },
-  businessId:{ // 业务id
-    type: String,
-    default: ''
-  },
-  classify:{ // 附件分类
-    type: String,
-    required: true,
-    default: ''
-  },
-  readonly:{ // 只读(详情查看)
-    type: Boolean,
-    default: false
-  },
-})
-const uploadAnnex = ()=>{
-  openDialog();
-  emit('uploadAnnex')
-}
-// 查询附件列表
-const queryList = () => {
-	loading.value = true;
-  fileList({Key:props.businessId}).then((res: any) => {
-    state.tableData = res.result?.items ?? [];
-    total.value = res.result?.total ?? 0;
-    loading.value = false;
-  }).catch(() => {
-    loading.value = false;
-  });
-};
+	name: {
+		type: String,
+		default: '上传附件',
+	},
+	fileLimit: {
+		// 限制上传数量
+		type: Number,
+		default: 5,
+	},
+	fileSize: {
+		// 限制上传大小(M)
+		type: Number,
+		default: 1,
+	},
+	businessId: {
+		// 业务id
+		type: String,
+		default: '',
+	},
+	classify: {
+		// 附件分类
+		type: String,
+		required: true,
+		default: '',
+	},
+	readonly: {
+		// 只读(详情查看)
+		type: Boolean,
+		default: false,
+	},
+	fileNumber: {
+		// 附件数量
+		type: Number,
+		default: 0,
+	},
+	flowKey: {
+		// 流程key
+		type: String,
+		default: '',
+	},
+	modelValue: {
+		// 附件数据
+		type: Array,
+		default: () => [],
+	},
+});
 
-// 表格多选
-const multipleTableRef = ref<RefType>();
-const multipleSelection = ref<any>([]);
-const handleSelectionChange = (val: any[]) => {
-  multipleSelection.value = val;
-};
-// 下载附件
-const download = (row:any) => {
-  const link = document.createElement('a') // 创建一个 a 标签用来模拟点击事件
-  link.style.display = 'none'
-  link.href = row.url;
-  link.setAttribute('download', '文件名')
-  document.body.appendChild(link)
-  link.click()
-  document.body.removeChild(link)
-};
-// 打开弹窗
-const openDialog = () => {
-	loading.value = false;
-  if(props.businessId){
-    queryList();
-  }
-  multipleSelection.value = [];
-	dialogVisible.value = true;
-};
-// 关闭弹窗
-const closeDialog = () => {
-	dialogVisible.value = false;
-};
-// 上传附件
-const handleAdd = () => {
-	dialogVisibleUpload.value = true;
-};
-// 删除附件
-const handleDelete = () => {
-  const names:string = multipleSelection.value.map((item: any) => item.name).join(',');
-  ElMessageBox.confirm(`确定要删除【${names}】的附件?`, '提示', {
-    confirmButtonText: '确认',
-    cancelButtonText: '取消',
-    type: 'warning',
-    draggable: true,
-    cancelButtonClass: 'default-button',
-  })
-      .then(() => {
-        if(props.businessId){
-          fileDelete({ids:multipleSelection.value.map((v: any) => v.id)}).then(() => {
-            queryList();
-            for(let item of multipleSelection.value) {
-              state.tableData.forEach((v: any, i: any) => {
-                if (v.id == item.id) {
-                  state.tableData.splice(i, 1);
-                  multipleTableRef.value!.toggleRowSelection(v, false);
-                  ElMessage.success('操作成功');
-                }
-              });
-            }
-          });
-        }else{
-          for(let item of multipleSelection.value) {
-            state.tableData.forEach((v: any, i: any) => {
-              if (v.id == item.id) {
-                state.tableData.splice(i, 1);
-                multipleTableRef.value!.toggleRowSelection(v, false);
-                ElMessage.success('操作成功');
-              }
-            });
-          }
-        }
-      })
-      .catch(() => {});
+const action = computed(() => {
+	return import.meta.env.VITE_API_UPLOAD_URL + '/file/upload?source=hotline';
+});
+// 上传成功
+const fileList = ref<EmptyArrayType>([]);
+const uploadListRef = ref<RefType>(); // 上传组件ref
+// 更新数据
+const updateData = () => {
+	emit('update:modelValue', [fileList.value]);
+	const data = formatData(fileList.value);
+	emit('update:format', [...data]);
 };
-// 上传
-const httpRequest = async (params: any) => {
-  const file = params.file;
-  // 文件名(8位随机数):
-  const fileName = Math.random().toString(36).substring(-8) + file.name.substring(file.name.lastIndexOf('.'));
-
-  // 目录加文件名【上线前修改目录名】
-  const fileSrc = `test20220824/${fileName}`;
-  console.log(fileSrc);
-  try {
-    params.onProgress({ percent: 0 });
-    //上传的自定义逻辑都在这里
-
-    ruleForm.fileList = [
-      ...ruleForm.fileList
-
-    ];
-    // console.log(`上传成功 ${res.key}`)
-    console.log(ruleForm.fileList)
-    params.onSuccess();
-  } catch (err) {
-    console.log(err, 'err');
-
-    ElMessage.error('网络错误,请稍后重试');
-    params.onError();
-  }
+// 格式化数据
+const formatData = (data: any) => {
+	let newData: any = [];
+	for (let v of data) {
+		newData.push({
+			additions: v.response?.result.id,
+			name: v.response?.result?.fileName?.substring(0, v.response.result?.fileName?.lastIndexOf('.')),
+			type: v.response?.result?.fileName?.split('.').pop(),
+			path: v.response?.result?.path,
+			publicity: v.publicity ? 1 : 0,
+			classify: props.classify,
+			key: props.businessId,
+			flowKey: props.flowKey,
+		});
+	}
+	return newData;
 };
 //文件限制
 const handleExceed = (files: any, fileList: any) => {
-  ElMessage.warning(`当前限制选择 ${props.fileLimit} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
+	ElMessage.warning(`当前限制选择 ${props.fileLimit} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
 };
-//上传前的校验
-const handleChange = (rawFile: any) => {
-  const isLt = rawFile.size / 1024 / 1024 < props.fileSize;
-  if (!isLt) {
-    ElMessage.warning(`文件超过了最大限度 ${props.fileSize} MB!`);
-    ruleForm.fileList = ruleForm.fileList.slice(0, ruleForm.fileList.length - 1);
-    return;
-  }
+//限制文件大小
+const handleChangeFile = (file: any, fileList: any) => {
+	//限制上传文件大小
+	if (!file) return;
+	const isLt2M = file.size / 1024 / 1024 < props.fileSize;
+	if (!isLt2M) {
+		const currIdx = fileList.indexOf(file);
+		fileList.splice(currIdx, 1);
+		ElMessage.warning(`文件超过了最大限度 ${props.fileSize} MB!`);
+		return false;
+	}
 };
 // 删除
 const handleRemove = (uploadFile: any) => {
-  ElMessageBox.confirm(`确定要删除?`, '提示', {
-    confirmButtonText: '确认',
-    cancelButtonText: '取消',
-    type: 'warning',
-    draggable: true,
-    cancelButtonClass: 'default-button',
-  })
-      .then(() => {
-        // infoList.value.forEach((v: any, i: any) => {
-        // 	if (v.uid == uploadFile.uid) {
-        // 		infoList.value.splice(i, 1);
-        // 	}
-        // });
-        uploadListRef.value.handleRemove(uploadFile);
-      })
-      .catch(() => {});
+	ElMessageBox.confirm(`确定要删除?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+	})
+		.then(() => {
+			uploadListRef.value.handleRemove(uploadFile);
+			updateData();
+		})
+		.catch(() => {});
 };
-const storesUserInfo = useUserInfo();
-const { userInfos } = storeToRefs(storesUserInfo); // 用户信息
-// 提交
-const submit = (formEl: FormInstance | undefined) => {
-  if (!formEl) return
-  formEl.validate((valid: boolean) => {
-    if(!valid) return;
-    if(props.businessId){// 业务id存在,上传附件
-      const uploadTable =  ruleForm.fileList.map((v: any) => {
-        return {
-          ...v,
-          name: v.name.substring(0, v.name.lastIndexOf(".")),
-          type: v.name.split(".").pop(),
-          publicity: ruleForm.publicity,
-          classify: props.classify,
-          key: props.businessId,
-          additions:'测试附件上传内容',
-        };
-      })
-      fileAdd(uploadTable).then(() => {
-        ElMessage.success('操作成功');
-        queryList();
-      });
-    }else{
-      const uploadTable =  ruleForm.fileList.map((v: any) => {
-        return {
-          id: guid(),
-          name: v.name.substring(0, v.name.lastIndexOf(".")),
-          type: v.name.split(".").pop(),
-          orgName: userInfos.value.orgName,
-          userName:userInfos.value.name,
-          creationTime: new Date(),
-          publicity: ruleForm.publicity,
-          classify: props.classify,
-          key: props.businessId,
-          additions:'测试附件上传内容',
-        };
-      })
-      state.tableData.push(...uploadTable)
-      ElMessage.success('操作成功');
-    }
-    ruleForm.fileList = [];
-    formEl.clearValidate();
-    formEl.resetFields();
-    dialogVisibleUpload.value = false;
-  });
+// 下载
+const handleDownload = (uploadFile: any) => {
+	if (!uploadFile.path) {
+		ElMessage.error('附件不存在');
+		return;
+	}
+	// 确定是否下载
+	ElMessageBox.confirm('确定要下载附件?', '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+	})
+		.then(() => {
+			const fileName = uploadFile.name;
+			const url = import.meta.env.VITE_FILE_PREFIX + uploadFile.path;
+			downloadFile(url, fileName);
+		})
+		.catch(() => {});
 };
-const close = ()=>{
-  ruleForm.fileList = [];
-  ruleFormRef.value!.clearValidate();
-  ruleFormRef.value!.resetFields();
-}
-defineExpose({
-	openDialog,
-	closeDialog,
-  fileList:state.tableData
+onMounted(() => {
+  fileList.value = props.modelValue;
 });
 </script>
-
+<style lang="scss" scoped>
+.upload-demo{
+  .el-upload-list__item{
+    margin-bottom: 0;
+  }
+}
+</style>

+ 1 - 1
src/components/CommonAdvice/index.vue

@@ -152,7 +152,7 @@ const props = defineProps({
 	},
 	maxlength: {
 		type: [Number, String, undefined],
-		default: 2000,
+		default: 5000,
 	},
 	drawerWidth: {
 		type: [Number, String],

+ 11 - 34
src/components/Editor/index.vue

@@ -18,6 +18,7 @@ import { IDomEditor, Boot } from '@wangeditor/editor';
 import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
 import { Cookie } from '/@/utils/storage';
 import { uploadFile } from '/@/api/public/upload';
+import {ElMessage} from "element-plus";
 //  全局配置
 // 定义父组件传过来的值
 const props = defineProps({
@@ -69,43 +70,19 @@ type InsertFnType = (url: string, alt: string, href: string) => void;
 state.editorConfig.MENU_CONF['uploadImage'] = {
 	// 自定义上传
 	async customUpload(file: File, insertFn: InsertFnType) {
+    // 限制文件不能大于100M
+    if (file.size > 10 * 1024 * 1024) {
+      ElMessage.error('上传图片不能大于10M');
+      return;
+    }
     const formData = new FormData();
     formData.append('fileData', file);
 		uploadFile(formData).then((res) => {
-      console.log(res)
-			// insertFn(res.data.url,'','')
-		});
-		// file 即选中的文件
-		// 自己实现上传,并得到图片 url alt href
-		// 最后插入图片
-		// insertFn(url, alt, href)
-	},
-
-	/*server: import.meta.env.VITE_API_UPLOAD_URL,
-	// form-data fieldName ,默认值 'wangeditor-uploaded-image'
-	fieldName: 'fileData',
-	// 单个文件的最大体积限制,默认为 2M
-	maxFileSize: 5 * 1024 * 1024, // 1M
-	// 最多可上传几个文件,默认为 100
-	maxNumberOfFiles: 10,
-	// 选择文件时的类型限制,默认为 ['image/!*'] 。如不想限制,则设置为 []
-	allowedFileTypes: ['image/!*'],
-	// 将 meta 拼接到 url 参数中,默认 false
-	metaWithUrl: false,
-	// 自定义增加 http  header
-	headers: {
-		Authorization: 'Bearer ' + Cookie.get('token'),
-		userid: '',
-	},
-	// 跨域是否传递 cookie ,默认为 false
-	withCredentials: true,
-	// 超时时间,默认为 10 秒
-	timeout: 5 * 1000, // 5 秒
-	// 自定义插入图片
-	customInsert(res: any, insertFn: any) {
-		// 从 res 中找到 url alt href ,然后插图图片
-		insertFn(res.data.url);
-	},*/
+			insertFn( import.meta.env.VITE_FILE_PREFIX+res.result.path,'加载失败','')
+		}).catch((err) => {
+      ElMessage.error(err);
+    });
+	}
 };
 
 // //上传视频

+ 9 - 2
src/components/Pagination/index.vue

@@ -7,7 +7,7 @@
 </template>
 
 <script lang="ts" name="pagination" setup>
-import { computed, onMounted, ref } from 'vue';
+import {computed, onMounted, ref, watch} from 'vue';
 import mittBus from '/@/utils/mitt';
 // 定义父组件传过来的值
 const props = defineProps({
@@ -74,7 +74,14 @@ const pageSize = computed({
   },
 })
 const handleSizeChange = (val: any) => {
-  emit('pagination', { page: currentPage.value, limit: val });
+  /**
+   * 场景:API返回总数为25条,按照10条每页,一共有3页。选了2的页数之后,然后把size选择成30条,
+   * 这个时候,分页就会同时触发size选择函数以及current选择函数。{page: 2, size: 30},{page: 1, size: 30}请求两次,会导致列表会有暂无数据的情况
+   * 解决办法:用setTimeout(函数,0),用延迟,虽然还是两次请求,但是每次都是{page: 1, size: 30}
+   */
+  setTimeout(() => {
+    emit('pagination', { page: currentPage.value, limit: val })
+  }, 0)
   mittBus.emit('scrollTopEmit', { top: 0 });// 分页发送监听事件 滚动到页面顶部
 }
 const handleCurrentChange = (val: any) => {

+ 1 - 1
src/views/business/order/index.vue

@@ -218,7 +218,7 @@
 						<el-button link type="success" @click="onOrderEdit(row)" title="编辑工单" v-if="row.canEdit" v-auth="'business:order:edit'">
 							修改
 						</el-button>
-						<order-detail :order="row" @updateList="queryList" />
+						<order-detail :order="row" @updateList="queryList" v-if="row.workflowId"/>
 					</template>
 				</el-table-column>
 				<template #empty>

+ 8 - 2
src/views/business/publish/component/Order-publish.vue

@@ -90,7 +90,7 @@
 					</el-col>
 					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
 						<el-form-item label="实际办理部门">
-              {{ state.publishDetail.actualHandleOrgName?.value }}
+							{{ state.publishDetail.actualHandleOrgName?.value }}
 						</el-form-item>
 					</el-col>
 					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" v-if="idNamesArray.length">
@@ -195,9 +195,15 @@ const onPublish = (formEl: FormInstance | undefined) => {
 	formEl.validate((valid: boolean) => {
 		if (!valid) return;
 		state.loading = true;
+		let idNames = [];
+		if (state.ruleForm.idNames.length > 0) { // 如果选择了部门
+			idNames = [...state.ruleForm.idNames];
+		} else {
+			idNames = [{ key: state.publishDetail.actualHandleOrgName?.key, value: state.publishDetail.actualHandleOrgName?.value }];
+		}
 		const request = {
 			...state.ruleForm,
-			idNames: [...state.ruleForm.idNames, { key: state.publishDetail.actualHandleOrgName?.key, value: state.publishDetail.actualHandleOrgName?.value}],
+			idNames,
 			id: state.orderDetail.id,
 		};
 		publishOrder(request)

+ 159 - 127
src/views/todo/seats/accept/index.vue

@@ -435,12 +435,12 @@
 								</el-col>
 								<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
 									<el-form-item label="附件" prop="remark" :rules="[{ required: false, message: '请填写诉求内容', trigger: 'change' }]">
-										<annex-list ref="annexListRef" :businessId="state.orderId" classify="受理上传" />
+										<annex-list :businessId="state.orderId" classify="受理上传" v-model="files" v-model:format="filesFormat"/>
 									</el-form-item>
 								</el-col>
 								<el-col :xs="24" :sm="12" :md="24" :lg="24" :xl="24">
 									<el-form-item>
-                    <el-button class="default-button" @click="onCancel"> 取消 </el-button>
+										<el-button class="default-button" @click="onCancel"> 取消 </el-button>
 										<el-button class="default-button" @click="save(ruleFormRef)" :loading="buttonLoading"> 保存 </el-button>
 										<el-button type="primary" @click="submit(ruleFormRef)" :loading="buttonLoading" v-if="canHandle"> 办理 </el-button>
 									</el-form-item>
@@ -810,37 +810,44 @@ const saveExpandForm = (val: any) => {
 const deleteUnnecessaryProperties = (obj: any) => {
 	const propertiesToDelete = ['ageRangeObj', 'pushTypeObj', 'licenceTypeObj', 'channel', 'acceptTypeObj'];
 	propertiesToDelete.forEach((prop) => Reflect.deleteProperty(obj, prop));
-	if (state.orderId) Reflect.deleteProperty(obj, 'files');
 };
+const files = ref<EmptyArrayType>([]); // 附件列表
+const filesFormat = ref<EmptyArrayType>([]); // 附件列表格式化
+
 // 是否打开拓展表单
 const shouldOpenDialog = (obj: any) =>
-	!ExpandFormRef.value.state.validated && obj.orderExtension && obj.orderExtension.orderTypeCode && ['scjgjts,scjgjjb'].includes(obj.orderExtension.orderTypeCode);
-const annexListRef = ref<RefType>(); // 附件列表
+	!ExpandFormRef.value.state.validated &&
+	obj.orderExtension &&
+	obj.orderExtension.orderTypeCode &&
+	['scjgjts,scjgjjb'].includes(obj.orderExtension.orderTypeCode);
+
 const buttonLoading = ref<boolean>(false);
 // 保存
 const save = throttle((formEl: FormInstance | undefined) => {
 	if (!formEl) return;
 	formEl.validate((valid: boolean) => {
 		if (!valid) return;
-    buttonLoading.value  = true;
+		buttonLoading.value = true;
 		let orderDetail = {
 			...state.ruleForm,
 			hotspotExternal: state.hotspotExternal.join(','),
 			repeatableEventDetails: repeatableEventDetails.value,
-			files: annexListRef.value?.fileList,
+			files: filesFormat.value,
 		};
 		deleteUnnecessaryProperties(orderDetail);
 		const operation = state.orderId ? orderEdit : orderAdd;
 		const addOrderAndNavigate = () => {
-			operation(orderDetail).then(() => {
-        buttonLoading.value  = false;
-				ElMessage.success('操作成功');
-				mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
-				mittBus.emit('clearCache', 'order');
-        router.go(-1);
-			}).catch(() => {
-        buttonLoading.value  = false;
-      });
+			operation(orderDetail)
+				.then(() => {
+					buttonLoading.value = false;
+					ElMessage.success('操作成功');
+					mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
+					mittBus.emit('clearCache', 'order');
+					router.go(-1);
+				})
+				.catch(() => {
+					buttonLoading.value = false;
+				});
 		};
 		if (shouldOpenDialog(orderDetail)) {
 			ExpandFormRef.value.openDialog(true);
@@ -859,47 +866,48 @@ const selectIdentity = (val: number) => {
 };
 // 是否可以办理(如果有流程id 并且当前账号可以办理 则可以办理 没有流程ID都可以办理)
 const canHandle = computed(() => {
-  if(state.ruleForm?.workflowId) return state.ruleForm?.workflow?.canHandle;
-  else return true;
+	if (state.ruleForm?.workflowId) return state.ruleForm?.workflow?.canHandle;
+	else return true;
 });
 // 流程审批
 const processAuditRef = ref<RefType>();
 const processOrder = (orderDetail: any) => {
-  buttonLoading.value = false;
-  if(orderDetail.workflowId){// 如果已经有流程id 说明已经发起过流程  直接调用工单办理
-    const params = {
-      id: orderDetail.workflowId,
-      processType: '工单办理',
-      orderDetail,
-      extra: {
-        dialogTitle: '工单办理',
-        inputPlaceholder: '办理意见',
-        annexName:'办理附件',
-      },
-    };
-    processAuditRef.value.openDialog(params);
-  }else{
-    // 如果没有流程id 说明没有发起过流程  调用工单发起
-    const params = {
-      id: state.orderId,
-      processType: '工单发起',
-      extra: {
-        dialogTitle: '提交流程',
-        inputPlaceholder: '办理意见',
-        annexName: '办理附件',
-      },
-      orderDetail,
-    };
-    processAuditRef.value.openDialog(params);
-  }
-  console.log(orderDetail)
+	buttonLoading.value = false;
+	if (orderDetail.workflowId) {
+		// 如果已经有流程id 说明已经发起过流程  直接调用工单办理
+		const params = {
+			id: orderDetail.workflowId,
+			processType: '工单办理',
+			orderDetail,
+			extra: {
+				dialogTitle: '工单办理',
+				inputPlaceholder: '办理意见',
+				annexName: '办理附件',
+			},
+		};
+		processAuditRef.value.openDialog(params);
+	} else {
+		// 如果没有流程id 说明没有发起过流程  调用工单发起
+		const params = {
+			id: state.orderId,
+			processType: '工单发起',
+			extra: {
+				dialogTitle: '提交流程',
+				inputPlaceholder: '办理意见',
+				annexName: '办理附件',
+			},
+			orderDetail,
+		};
+		processAuditRef.value.openDialog(params);
+	}
+	console.log(orderDetail);
 };
 const handleForm = (orderDetail: any) => {
 	if (orderDetail.orderExtension?.orderTypeCode) {
 		if (ExpandFormRef.value.state.validated) {
 			processOrder(orderDetail);
 		} else {
-			ExpandFormRef.value.openDialog( true);
+			ExpandFormRef.value.openDialog(true);
 		}
 	} else {
 		processOrder(orderDetail);
@@ -910,11 +918,12 @@ const submit = throttle((formEl: FormInstance | undefined) => {
 	if (!formEl) return;
 	formEl.validate((valid: boolean) => {
 		if (!valid) return;
-    buttonLoading.value = true;
+		buttonLoading.value = true;
 		let orderDetail = {
 			...state.ruleForm,
 			hotspotExternal: state.hotspotExternal.join(','),
 			repeatableEventDetails: repeatableEventDetails.value,
+      files: filesFormat.value,
 		};
 		deleteUnnecessaryProperties(orderDetail);
 		handleForm(orderDetail);
@@ -929,11 +938,11 @@ const orderProcessSuccess = () => {
 	// 关闭当前 tagsView
 	mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
 	mittBus.emit('clearCache', 'order');
-  router.go(-1);
+	router.go(-1);
 };
 // 取消
 const onCancel = () => {
-  orderProcessSuccess();
+	orderProcessSuccess();
 };
 // 加载基础数据
 const loadBaseData = async () => {
@@ -961,77 +970,100 @@ const loadBaseData = async () => {
 const historyParams = history.state;
 
 const loadForm = async () => {
-  //  historyParams.createBy  createBy 代表来源  tel:来电弹单  letter:互联网来信 默认表示手动创建
-  if (historyParams.createBy) {
-    state.createBy = historyParams.createBy;
-    if (historyParams.createBy === 'tel') {
-      //通话
-      state.ruleForm.sourceChannel = '电话'; //电话
-      state.ruleForm.sourceChannelCode = 'RGDH'; //电话
-      state.ruleForm.fromPhone = historyParams.fromTel;
-      state.ruleForm.callId = historyParams.telGuid;
-      state.ruleForm.transferPhone = historyParams.transfer;
-      state.ruleForm.callAddress = historyParams.telArea; // 来电归属地
-      state.ruleForm.channel = {
-        // 来源渠道
-        dicDataValue: state.ruleForm.sourceChannelCode,
-        dicDataName: state.ruleForm.sourceChannel,
-      };
-    }
-  }
-  if (route.params.id) {
-    // 如果 有id
-    state.orderId = route.params.id;
-    const response = await orderDetail(route.params.id);
-    // 如果获取到id 调用查询详情
-    state.ruleForm = response.result;
-    if (response.result.duplicateIds && response.result.duplicateIds.length) {
-      // 是否重复
-      state.ruleForm.isRepeat = 'true';
-      state.ruleForm.duplicateTitle = '已选择';
-    } else {
-      state.ruleForm.isRepeat = 'false';
-    }
-    state.ruleForm.channel = {
-      // 来源渠道
-      dicDataValue: state.ruleForm.sourceChannelCode,
-      dicDataName: state.ruleForm.sourceChannel,
-    };
+	//  historyParams.createBy  createBy 代表来源  tel:来电弹单  letter:互联网来信 默认表示手动创建
+	if (historyParams.createBy) {
+		state.createBy = historyParams.createBy;
+		if (historyParams.createBy === 'tel') {
+			//通话
+			state.ruleForm.sourceChannel = '电话'; //电话
+			state.ruleForm.sourceChannelCode = 'RGDH'; //电话
+			state.ruleForm.fromPhone = historyParams.fromTel;
+			state.ruleForm.callId = historyParams.telGuid;
+			state.ruleForm.transferPhone = historyParams.transfer;
+			state.ruleForm.callAddress = historyParams.telArea; // 来电归属地
+			state.ruleForm.channel = {
+				// 来源渠道
+				dicDataValue: state.ruleForm.sourceChannelCode,
+				dicDataName: state.ruleForm.sourceChannel,
+			};
+		}
+	}
+	if (route.params.id) {
+		// 如果 有id
+		state.orderId = route.params.id;
+		const response = await orderDetail(route.params.id);
+		// 如果获取到id 调用查询详情
+		state.ruleForm = response.result;
+		if (response.result.duplicateIds && response.result.duplicateIds.length) {
+			// 是否重复
+			state.ruleForm.isRepeat = 'true';
+			state.ruleForm.duplicateTitle = '已选择';
+		} else {
+			state.ruleForm.isRepeat = 'false';
+		}
+		state.ruleForm.channel = {
+			// 来源渠道
+			dicDataValue: state.ruleForm.sourceChannelCode,
+			dicDataName: state.ruleForm.sourceChannel,
+		};
 
-    if (state.ruleForm.duplicateIds && state.ruleForm.duplicateIds.length) {
-      // 是否重复
-      state.ruleForm.isRepeat = 'true';
-    } else {
-      state.ruleForm.isRepeat = 'false';
-    }
-    if (state.ruleForm.hotspotExternal) {
-      //热点分类默认展开
-      state.hotspotExternal = state.ruleForm.hotspotExternal.split(',');
+		if (state.ruleForm.duplicateIds && state.ruleForm.duplicateIds.length) {
+			// 是否重复
+			state.ruleForm.isRepeat = 'true';
+		} else {
+			state.ruleForm.isRepeat = 'false';
+		}
+		if (state.ruleForm.hotspotExternal) {
+			//热点分类默认展开
+			state.hotspotExternal = state.ruleForm.hotspotExternal.split(',');
+		}
+		state.ruleForm.ageRangeObj = {
+			// 年龄段
+			dicDataValue: state.ruleForm.ageRangeCode,
+			dicDataName: state.ruleForm.ageRange,
+		};
+		state.ruleForm.licenceTypeObj = {
+			// 证件类型
+			dicDataValue: state.ruleForm.licenceTypeCode,
+			dicDataName: state.ruleForm.licenceType,
+		};
+		state.ruleForm.acceptTypeObj = {
+			// 受理类型
+			dicDataValue: state.ruleForm.acceptTypeCode,
+			dicDataName: state.ruleForm.acceptType,
+		};
+		state.ruleForm.pushTypeObj = {
+			// 推送分类
+			dicDataValue: state.ruleForm.pushTypeCode,
+			dicDataName: state.ruleForm.pushType,
+		};
+    // 附件列表
+    if (state.ruleForm.files) {
+      // filesFormat.value = state.ruleForm.files.map((item: any) => {
+      //   return {
+      //    ...item,
+      //   };
+      // });
+      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(files.value);
     }
-    state.ruleForm.ageRangeObj = {
-      // 年龄段
-      dicDataValue: state.ruleForm.ageRangeCode,
-      dicDataName: state.ruleForm.ageRange,
-    };
-    state.ruleForm.licenceTypeObj = {
-      // 证件类型
-      dicDataValue: state.ruleForm.licenceTypeCode,
-      dicDataName: state.ruleForm.licenceType,
-    };
-    state.ruleForm.acceptTypeObj = {
-      // 受理类型
-      dicDataValue: state.ruleForm.acceptTypeCode,
-      dicDataName: state.ruleForm.acceptType,
-    };
-    state.ruleForm.pushTypeObj = {
-      // 推送分类
-      dicDataValue: state.ruleForm.pushTypeCode,
-      dicDataName: state.ruleForm.pushType,
-    };
-    setTimeout(() => {
-      searchHistory(state.ruleForm.contact);
-    }, 2000);
-  }
+		setTimeout(() => {
+			searchHistory(state.ruleForm.contact);
+		}, 2000);
+	}
 };
 // 加载省市区
 const addressLoading = ref<boolean>(false);
@@ -1067,14 +1099,14 @@ const loadExtra = async () => {
 		extraLoading.value = false;
 	}
 };
-onBeforeMount(()=>{
-  loadBaseData();
-})
+onBeforeMount(() => {
+	loadBaseData();
+});
 onMounted(() => {
-  loadForm();
+	loadForm();
+});
+nextTick(() => {
+	loadAddress();
+	loadExtra();
 });
-nextTick(()=>{
-  loadAddress();
-  loadExtra();
-})
 </script>

+ 1 - 1
src/views/todo/seats/index.vue

@@ -139,7 +139,7 @@
 					<template #default="{ row }">
 						<el-button link type="success" @click="onOrderEdit(row)" title="编辑工单" v-if="row.canEdit" v-auth="'todo:seats:edit'"> 修改 </el-button>
 						<el-button link type="primary" @click="onSign(row)" title="签收工单" v-if="row.canSign" v-auth="'todo:seats:sign'"> 签收 </el-button>
-						<order-detail :order="row" @updateList="queryList" />
+						<order-detail :order="row" @updateList="queryList" v-if="row.workflowId"/>
 					</template>
 				</el-table-column>
 				<template #empty>