Ver código fonte

reactor:对接导出交办单;

zhangchong 11 meses atrás
pai
commit
b26d82fea9

+ 17 - 0
src/api/business/order.ts

@@ -221,3 +221,20 @@ export const provinceReturn = (data: object) => {
 	});
 }
 
+/**
+ * @description 导出交办单
+ * @param {object} data
+ */
+export const exportJbOrder = (data: object) => {
+	return request({
+		url: `/api/v1/ExportWord/order_submission_form`,
+		method: 'post',
+		responseType: 'blob', //注意
+		data,
+		headers: {            //注意
+			'Content-Type': 'application/json; application/octet-stream'
+		}
+	},{
+		reduce_data_format:false
+	});
+}

+ 22 - 12
src/api/todo/voiceAssistant.ts

@@ -8,20 +8,30 @@ import request from '@/utils/request';
  * @param {string} telNo
  */
 export const voiceAssistant = (telNo: string) => {
-  return request({
-    url: `users/getUserByAgentId/${telNo}`,
-    method: 'get',
-    baseURL:import.meta.env.VITE_VOICE_ASSISTANT_API_URL // 请求地址  可以在不同url中修改
-  });
-}
+	return request(
+		{
+			url: `users/getUserByAgentId/${telNo}`,
+			method: 'get',
+			baseURL: import.meta.env.VITE_VOICE_ASSISTANT_API_URL, // 请求地址  可以在不同url中修改
+		},
+		{
+			error_message_show: false,
+		}
+	);
+};
 /**
  * @description 获取识别内容
  * @param {string} callId
  */
 export const voiceAssistantContent = (callId: string) => {
-  return request({
-    url: `/monitor/remote/details/${callId}`,
-    method: 'get',
-    baseURL:import.meta.env.VITE_VOICE_ASSISTANT_API_URL
-  });
-}
+	return request(
+		{
+			url: `/monitor/remote/details/${callId}`,
+			method: 'get',
+			baseURL: import.meta.env.VITE_VOICE_ASSISTANT_API_URL,
+		},
+		{
+			error_message_show: false,
+		}
+	);
+};

+ 4 - 4
src/utils/request.ts

@@ -12,7 +12,7 @@ const LoadingInstance = {
 type customOptionsType = {
 	repeat_request_cancel?: boolean; // 是否开启取消重复请求, 默认为 true
 	loading?: boolean; // 是否开启全屏loading层效果, 默认为false
-	reduct_data_format?: boolean; // 是否开启简洁的数据结构响应 减少一层data, 默认为true
+	reduce_data_format?: boolean; // 是否开启简洁的数据结构响应 减少一层data, 默认为true
 	error_message_show?: boolean; // 是否开启接口错误信息展示,默认为true
 	code_message_show?: boolean; // 是否开启code不为0时的信息提示, 默认为false
 };
@@ -27,9 +27,9 @@ export default function myAxios(axiosConfig: any, customOptions?: customOptionsT
 	// 自定义配置
 	let custom_options = Object.assign(
 		{
-			repeat_request_cancel: false, // 是否开启取消重复请求, 默认为 true
+			repeat_request_cancel: false, // 是否开启取消重复请求, 默认为 false
 			loading: false, // 是否开启全屏loading层效果, 默认为false
-			reduct_data_format: true, // 是否开启简洁的数据结构响应 减少一层data, 默认为true
+			reduce_data_format: true, // 是否开启简洁的数据结构响应 减少一层data, 默认为true
 			error_message_show: true, // 是否开启接口错误信息展示,默认为true
 			code_message_show: false, // 是否开启code不为0时的信息提示, 默认为false
 		},
@@ -71,7 +71,7 @@ export default function myAxios(axiosConfig: any, customOptions?: customOptionsT
 				});
 				return Promise.reject(response.data); // code不等于0, 页面具体逻辑就不执行了
 			}
-			return custom_options.reduct_data_format ? response.data : response;
+			return custom_options.reduce_data_format ? response.data : response;
 		},
 		async (error: AxiosError): Promise<never> => {
 			error.config && removePending(error.config);

+ 22 - 2
src/utils/tools.ts

@@ -144,6 +144,26 @@ export function excludeSelfById(arr: Array<any>, id: string) {
 		return true;
 	});
 }
+/**
+ * @description 下载文件流zip
+ * @param res 文件流
+ */
+export function downloadZip(res: any) {
+	const blob = new Blob([res.data], { type: 'application/zip' }); //设置下载的内容以及格式
+	// 兼容webkit浏览器,处理webkit浏览器中href自动添加blob前缀,默认在浏览器打开而不是下载
+	const URL = window.URL || window.webkitURL;
+	// 这里就是创建一个a标签,等下用来模拟点击事件
+	const a = document.createElement('a');
+	const filename = res.headers['content-disposition'].split(';')[1].split('filename=')[1];
+	// 下载链接
+	a.href = URL.createObjectURL(blob);
+	//解码,返回的是文件流所以我从res.header里面拿的文件名,但是是编码后的%E4巴拉巴拉的,所以拿来用的话要在前端解码
+	a.download = decodeURIComponent(filename); //设置文件名
+	document.body.appendChild(a);
+	a.click();
+	// 收尾工作,在内存中移除URL 对象
+	document.body.removeChild(a);
+}
 /**
  * @description 下载文件流
  * @param res 文件流
@@ -153,12 +173,12 @@ export function downloadFileByStream(res: Blob, filename: string) {
 	// 创建blob对象,解析流数据
 	const blob = new Blob([res], {
 		// 设置返回的文件类型
-		// type: 'application/pdf;charset=UTF-8' 表示下载文档为pdf,如果是word则设置为msword,excel为excel
+		// type: 'application/pdf;charset=UTF-8' 表示下载文档为pdf,如果是word则设置为word,excel为excel
 		type: res.type,
 	});
 	// 这里就是创建一个a标签,等下用来模拟点击事件
 	const a = document.createElement('a');
-	// 兼容webkix浏览器,处理webkit浏览器中href自动添加blob前缀,默认在浏览器打开而不是下载
+	// 兼容webkit浏览器,处理webkit浏览器中href自动添加blob前缀,默认在浏览器打开而不是下载
 	const URL = window.URL || window.webkitURL;
 	// 根据解析后的blob对象创建URL 对象
 	// 下载链接

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

@@ -61,7 +61,7 @@ const router = useRouter(); // 路由
 const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
 const columns = ref<any[]>([
-	{ type: 'selection', fixed: 'left', width: 55 },
+	{ type: 'selection', fixed: 'left', width: 55,align: 'center' },
 	{ prop: 'expiredStatus', label: '超期状态', align: 'center',width: 80 },
 	{ prop: 'order.no', label: '工单编码', width: 150 },
 	{ prop: 'order.sourceChannel', label: '来源方式', width: 120 },

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

@@ -61,7 +61,7 @@ const router = useRouter(); // 路由
 const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
 const columns = ref<any[]>([
-	{ type: 'selection', fixed: 'left', width: 55 },
+	{ type: 'selection', fixed: 'left', width: 55,align: 'center' },
 	{ prop: 'expiredStatus', label: '超期状态', align: 'center',width: 80 },
 	{ prop: 'order.no', label: '工单编码', width: 150 },
 	{ prop: 'order.sourceChannel', label: '来源方式', width: 120 },

+ 21 - 5
src/views/business/order/index.vue

@@ -331,14 +331,18 @@
 						:loading="state.loading"
 						>省退回申请
 					</el-button>
-					<el-button type="primary" @click="onCreateRepeatEvent" :loading="state.loading">创建重复性事件 </el-button>
+					<el-button type="primary" @click="onCreateRepeatEvent" :loading="state.loading">
+						<SvgIcon name="ele-Plus" class="mr5" />创建重复性事件
+					</el-button>
 					<el-button type="primary" @click="onObserve" v-auth="'business:order:observe'" :disabled="!scope.isSelected" :loading="state.loading"
 						>设置观察件
 					</el-button>
 					<el-button type="primary" @click="onEnd" v-auth="'business:order:end'" :disabled="!scope.isSelected" :loading="state.loading"
 						>设置终结件
 					</el-button>
-					<!--					<el-button type="primary" @click="onJbExport" :disabled="!scope.isSelected" :loading="state.loading">交办单导出 </el-button>-->
+					<el-button type="primary" @click="onJbExport" :disabled="!scope.isSelected" :loading="state.loading" v-auth="'business:order:jbdExport'"
+						><SvgIcon name="iconfont icon-daochu" class="mr5" />交办单导出
+					</el-button>
 				</template>
 				<template #expiredStatus="{ row }">
 					<span :class="'overdue-status-' + row.expiredStatus" :title="row.expiredStatusText"></span>
@@ -389,11 +393,12 @@ import { shortcuts } from '@/utils/constants';
 import other from '@/utils/other';
 import { useRoute, useRouter } from 'vue-router';
 import { formatDate } from '@/utils/formatTime';
-import { listBaseData, orderList, provinceReturn } from '@/api/business/order';
+import { exportJbOrder, listBaseData, orderList, provinceReturn } from '@/api/business/order';
 import { addObserve } from '@/api/query/observe';
 import { addEnd } from '@/api/query/end';
 import { treeArea } from '@/api/auxiliary/area';
 import { orderSign } from '@/api/todo/order';
+import { downloadZip } from '@/utils/tools';
 
 // 引入组件
 const OrderDetail = defineAsyncComponent(() => import('@/components/OrderDetail/index.vue')); // 工单详情
@@ -496,7 +501,7 @@ const selectable = (row: any) => {
 };
 // 表格配置项
 const columns = ref<any[]>([
-	{ type: 'selection', fixed: 'left', width: 55, selectable: selectable },
+	{ type: 'selection', fixed: 'left', width: 55, selectable: selectable, align: 'center' },
 	{ prop: 'expiredStatus', label: '超期状态', align: 'center', width: 80 },
 	{ prop: 'no', label: '工单编码', width: 150 },
 	{ prop: 'isProvince', label: '省/市工单', width: 100 },
@@ -790,7 +795,18 @@ const onJbExport = () => {
 		cancelButtonClass: 'default-button',
 		autofocus: false,
 	})
-		.then(() => {})
+		.then(() => {
+			state.loading = true;
+			exportJbOrder(ids)
+				.then((res: any) => {
+					downloadZip(res);
+					state.loading = false;
+					ElMessage.success('导出成功');
+				})
+				.catch(() => {
+					state.loading = false;
+				});
+		})
 		.catch(() => {});
 };
 onMounted(() => {

+ 1 - 1
src/views/business/publish/todo.vue

@@ -94,7 +94,7 @@ const selectable = (row: any) => {
 };
 // 表格配置项
 const columns = ref<any[]>([
-	{ type: 'selection', selectable: selectable, fixed: 'left', width: 55 },
+	{ type: 'selection', selectable: selectable, fixed: 'left', width: 55,align: 'center' },
 	{ prop: 'no', label: '工单编码', width: 150 },
 	{ prop: 'isProvince', label: '省/市工单', width: 100 },
 	{ prop: 'statusText', label: '发布状态', width: 100 },

+ 1 - 1
src/views/business/visit/component/Smart-visit-add.vue

@@ -124,7 +124,7 @@ const state = reactive({
 	acceptTypeOptions: [],
 });
 const columns = ref<any[]>([
-	{ type: 'selection', fixed: 'left', width: 55 },
+	{ type: 'selection', fixed: 'left', width: 55,align: 'center' },
 	{ prop: 'order.no', label: '工单编码', width: 150 },
 	{
 		prop: 'title',

+ 1 - 1
src/views/business/visit/todo.vue

@@ -90,7 +90,7 @@ const router = useRouter(); // 路由
 const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
 const columns = ref<any[]>([
-	{ type: 'selection', fixed: 'left', width: 55 },
+	{ type: 'selection', fixed: 'left', width: 55,align: 'center' },
 	{ prop: 'order.no', label: '工单编码', width: 150 },
 	{ prop: 'order.title', label: '工单标题', width: 300 },
 	{ prop: 'order.sourceChannel', label: '来源方式', width: 100 },

+ 1 - 1
src/views/quality/lexicon/index.vue

@@ -65,7 +65,7 @@ const LexiconEdit = defineAsyncComponent(() => import('@/views/quality/lexicon/c
 const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
 const columns = ref<any[]>([
-	{ type: 'selection', fixed: 'left', width: 55 },
+	{ type: 'selection', fixed: 'left', width: 55,align: 'center' },
 	{ prop: 'name', label: '违禁词', width: 300 },
 	{ prop: 'classify', label: '违禁词分类', width: 130 },
 	{ prop: 'type', label: '违禁词属性' },

+ 1 - 1
src/views/quality/project/index.vue

@@ -65,7 +65,7 @@ const ProjectEdit = defineAsyncComponent(() => import('@/views/quality/project/c
 const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
 const columns = ref<any[]>([
-	{ type: 'selection', fixed: 'left', width: 55 },
+	{ type: 'selection', fixed: 'left', width: 55,align: 'center' },
 	{ prop: 'name', label: '质检项名称' },
 	{ prop: 'describe', label: '质检项描述', width: 130 },
 	{ prop: 'groupingName', label: '质检项分组' },

+ 3 - 3
src/views/quality/template/index.vue

@@ -29,10 +29,10 @@
 			>
 				<!-- 表格 header 按钮 -->
 				<template #tableHeader="scope">
-					<el-button type="primary" @click="onTemplateAdd" v-waves v-auth="'quality:template:add'">
+					<el-button type="primary" @click="onTemplateAdd" v-auth="'quality:template:add'">
 						<SvgIcon name="ele-Plus" class="mr5" />新增
 					</el-button>
-					<el-button type="primary" @click="onTemplateDelete" v-waves v-auth="'quality:template:delete'" :disabled="!scope.isSelected">
+					<el-button type="primary" @click="onTemplateDelete" v-auth="'quality:template:delete'" :disabled="!scope.isSelected">
 						<SvgIcon name="ele-Delete" class="mr5" />删除
 					</el-button>
 				</template>
@@ -66,7 +66,7 @@ const QualityTemplateEdit = defineAsyncComponent(() => import('@/views/quality/t
 const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
 const columns = ref<any[]>([
-	{ type: 'selection', fixed: 'left', width: 55 },
+	{ type: 'selection', fixed: 'left', width: 55,align: 'center' },
 	{ prop: 'name', label: '模板名称' },
 	{ prop: 'groupingText', label: '质检分类' },
 	{

+ 33 - 1
src/views/todo/center/index.vue

@@ -116,6 +116,12 @@
 				v-model:page-size="state.queryParams.PageSize"
 				:key="Math.random()"
 			>
+				<!-- 表格 header 按钮 -->
+				<template #tableHeader="scope">
+					<el-button type="primary" @click="onJbExport" :disabled="!scope.isSelected" :loading="state.loading" v-auth="'todo:center:jbdExport'"
+						><SvgIcon name="iconfont icon-daochu" class="mr5" />交办单导出
+					</el-button>
+				</template>
 				<template #expiredStatus="{ row }">
 					<span :class="'overdue-status-' + row.expiredStatus" :title="row.expiredStatusText"></span>
 				</template>
@@ -154,6 +160,8 @@ import { useRoute, useRouter } from 'vue-router';
 import { formatDate } from '@/utils/formatTime';
 import { centerTodo, centerTodoBase } from '@/api/todo/center';
 import { orderSign } from '@/api/todo/order';
+import { exportJbOrder } from '@/api/business/order';
+import { downloadZip } from '@/utils/tools';
 
 // 引入组件
 const OrderDetail = defineAsyncComponent(() => import('@/components/OrderDetail/index.vue')); // 工单详情
@@ -196,7 +204,8 @@ const router = useRouter(); // 路由
 const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
 const columns = ref<any[]>([
-	{ prop: 'expiredStatus', label: '超期状态', align: 'center', width: 80 },
+	{ type: 'selection', fixed: 'left', width: 55, align: 'center' },
+	{ prop: 'expiredStatus', label: '超期状态', width: 80 },
 	{ prop: 'no', label: '工单编码', width: 150 },
 	{ prop: 'isProvince', label: '省/市工单', width: 100 },
 	{ prop: 'actualHandleStepName', label: '办理节点', width: 150 },
@@ -345,6 +354,29 @@ const onOrderEdit = (row: any) => {
 		},
 	});
 };
+// 交办单导出
+const onJbExport = () => {
+  const ids = proTableRef.value.selectedList.map((item: any) => item.id);
+  ElMessageBox.confirm(`您确定导出选中的${proTableRef.value.selectedList.length}个工单的交办单,是否继续?`, '提示', {
+    confirmButtonText: '确认',
+    cancelButtonText: '取消',
+    type: 'warning',
+    draggable: true,
+    cancelButtonClass: 'default-button',
+    autofocus: false,
+  })
+    .then(() => {
+      state.loading = true;
+      exportJbOrder(ids)
+        .then((res: any) => {
+          downloadZip(res);
+          state.loading = false;
+          ElMessage.success('导出成功');
+        })
+        .catch(() => {state.loading = false;});
+    })
+    .catch(() => {});
+};
 onMounted(() => {
 	getBaseData();
 	queryList();

+ 33 - 2
src/views/todo/order/index.vue

@@ -46,6 +46,11 @@
 				v-model:page-size="state.queryParams.PageSize"
 				:key="Math.random()"
 			>
+        <template #tableHeader="scope">
+          <el-button type="primary" @click="onJbExport" :disabled="!scope.isSelected" :loading="state.loading" v-auth="'todo:seats:jbdExport'"
+          ><SvgIcon name="iconfont icon-daochu" class="mr5" />交办单导出
+          </el-button>
+        </template>
 				<template #expiredStatus="{ row }">
 					<span :class="'overdue-status-' + row.expiredStatus" :title="row.expiredStatusText"></span>
 				</template>
@@ -70,10 +75,12 @@
 </template>
 <script setup lang="tsx" name="todoOrder">
 import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
-import { FormInstance } from 'element-plus';
+import { ElMessage, ElMessageBox, FormInstance } from "element-plus";
 import { formatDate } from '@/utils/formatTime';
 import { useRouter } from 'vue-router';
 import { orderListTodo } from '@/api/todo/order';
+import { exportJbOrder } from "@/api/business/order";
+import { downloadZip } from "@/utils/tools";
 // 引入组件
 const OrderDetail = defineAsyncComponent(() => import('@/components/OrderDetail/index.vue')); // 工单详情
 // 定义变量内容
@@ -97,7 +104,8 @@ const router = useRouter(); // 路由
 const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
 const columns = ref<any[]>([
-	{ prop: 'expiredStatus', label: '超期状态', align: 'center',fixed: 'left' },
+  { type: 'selection', fixed: 'left', width: 55, align: 'center' },
+	{ prop: 'expiredStatus', label: '超期状态', align: 'center' },
 	{ prop: 'no', label: '工单编码', width: 150 },
 	{ prop: 'isProvince', label: '省/市工单', width: 100 },
 	{ prop: 'actualHandleStepName', label: '办理节点', width: 150 },
@@ -180,6 +188,29 @@ const resetQuery = (formEl: FormInstance | undefined) => {
 	formEl.resetFields();
 	queryList();
 };
+// 交办单导出
+const onJbExport = () => {
+  const ids = proTableRef.value.selectedList.map((item: any) => item.id);
+  ElMessageBox.confirm(`您确定导出选中的${proTableRef.value.selectedList.length}个工单的交办单,是否继续?`, '提示', {
+    confirmButtonText: '确认',
+    cancelButtonText: '取消',
+    type: 'warning',
+    draggable: true,
+    cancelButtonClass: 'default-button',
+    autofocus: false,
+  })
+    .then(() => {
+      state.loading = true;
+      exportJbOrder(ids)
+        .then((res: any) => {
+          downloadZip(res);
+          state.loading = false;
+          ElMessage.success('导出成功');
+        })
+        .catch(() => {state.loading = false;});
+    })
+    .catch(() => {});
+};
 const historyParams = history.state;
 onMounted(() => {
 	if (historyParams.IsCountersign) {

+ 1 - 0
src/views/todo/seats/accept/Call-summary.vue

@@ -86,6 +86,7 @@ const getRecognize = async () => {
 	} catch (error) {
 		console.log('获取识别内容失败', error);
 		loading.value = false;
+    ElMessage.error('获取识别内容失败');
 	}
 };
 // 一键填单

+ 2 - 1
src/views/todo/seats/accept/Voice-assistant.vue

@@ -113,7 +113,7 @@
 </template>
 <script setup lang="ts" name="orderAcceptVoiceAssistant">
 import { nextTick, onActivated, onDeactivated, onMounted, ref, watch } from 'vue';
-import { ElMessageBox } from 'element-plus';
+import { ElMessage, ElMessageBox } from "element-plus";
 import { getImageUrl } from '@/utils/tools';
 import { useRoute } from 'vue-router';
 import { formatDate } from '@/utils/formatTime';
@@ -455,6 +455,7 @@ const getRecognize = async () => {
 		recognizeList.value = result;
 	} catch (error) {
 		console.log('获取识别内容失败', error);
+    ElMessage.error('获取识别内容失败');
 	}
 };
 // 停止滚动

+ 30 - 2
src/views/todo/seats/index.vue

@@ -43,6 +43,9 @@
 				<!-- 表格 header 按钮 -->
 				<template #tableHeader="scope">
 					<el-button type="primary" @click="onAddOrder" v-auth="'todo:seats:add'"> <SvgIcon name="ele-Plus" class="mr5" />新建工单 </el-button>
+          <el-button type="primary" @click="onJbExport" :disabled="!scope.isSelected" :loading="state.loading" v-auth="'todo:order:jbdExport'"
+          ><SvgIcon name="iconfont icon-daochu" class="mr5" />交办单导出
+          </el-button>
 				</template>
 				<template #expiredStatus="{ row }">
 					<span :class="'overdue-status-' + row.expiredStatus" :title="row.expiredStatusText"></span>
@@ -74,7 +77,8 @@ import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
 import { formatDate } from '@/utils/formatTime';
 import { useRouter } from 'vue-router';
 import { seatsListTodo, orderSign } from '@/api/todo/order';
-import { guid } from '@/utils/tools';
+import { downloadZip, guid } from "@/utils/tools";
+import { exportJbOrder } from "@/api/business/order";
 // 引入组件
 const OrderDetail = defineAsyncComponent(() => import('@/components/OrderDetail/index.vue')); // 工单详情
 // 定义变量内容
@@ -97,7 +101,8 @@ const router = useRouter(); // 路由
 const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
 const columns = ref<any[]>([
-	{ prop: 'expiredStatus', label: '超期状态', align: 'center',fixed: 'left',width: 80 },
+  { type: 'selection', fixed: 'left', width: 55, align: 'center' },
+	{ prop: 'expiredStatus', label: '超期状态', align: 'center',width: 80 },
 	{ prop: 'no', label: '工单编码', width: 150 },
 	{ prop: 'isProvince', label: '省/市工单', width: 100 },
 	{ prop: 'actualHandleStepName', label: '办理节点', width: 150 },
@@ -219,6 +224,29 @@ const onSign = (row: any) => {
 		})
 		.catch(() => {});
 };
+// 交办单导出
+const onJbExport = () => {
+  const ids = proTableRef.value.selectedList.map((item: any) => item.id);
+  ElMessageBox.confirm(`您确定导出选中的${proTableRef.value.selectedList.length}个工单的交办单,是否继续?`, '提示', {
+    confirmButtonText: '确认',
+    cancelButtonText: '取消',
+    type: 'warning',
+    draggable: true,
+    cancelButtonClass: 'default-button',
+    autofocus: false,
+  })
+    .then(() => {
+      state.loading = true;
+      exportJbOrder(ids)
+        .then((res: any) => {
+          downloadZip(res);
+          state.loading = false;
+          ElMessage.success('导出成功');
+        })
+        .catch(() => {state.loading = false;});
+    })
+    .catch(() => {});
+};
 onMounted(() => {
 	queryList();
 });