浏览代码

Merge branch 'master' into dev

# Conflicts:
#	src/utils/constants.ts
zhangchong 10 月之前
父节点
当前提交
8cc4b94931

二进制
src/assets/images/phoneControls/mute_blue.png


二进制
src/assets/images/phoneControls/mute_grey.png


二进制
src/assets/images/phoneControls/mute_white.png


+ 13 - 12
src/layout/navBars/breadcrumb/breadcrumb.vue

@@ -1,8 +1,10 @@
 <template>
 	<div v-if="isShowBreadcrumb" class="layout-navbars-breadcrumb">
-		<SvgIcon class="layout-navbars-breadcrumb-icon" :name="themeConfig.isCollapse ? 'ele-Expand' : 'ele-Fold'"
-			size="24" @click="onThemeConfigChange" color="var(--el-color-primary)" />
-<!--		<el-breadcrumb class="layout-navbars-breadcrumb-hide" v-if="!userInfosConfig.showTelControl">
+		<el-icon class="layout-navbars-breadcrumb-icon" @click="onThemeConfigChange" size="20">
+			<Expand v-if="themeConfig.isCollapse" color="var(--el-color-primary)" />
+			<Fold v-else color="var(--el-color-primary)" />
+		</el-icon>
+		<!--		<el-breadcrumb class="layout-navbars-breadcrumb-hide" v-if="!userInfosConfig.showTelControl">
 			<transition-group name="breadcrumb">
 				<el-breadcrumb-item v-for="(v, k) in state.breadcrumbList" :key="!v.meta.tagsViewName ? v.meta.title : v.meta.tagsViewName">
 					<span v-if="k === state.breadcrumbList.length - 1" class="layout-navbars-breadcrumb-span">
@@ -18,16 +20,17 @@
 		</el-breadcrumb>-->
 	</div>
 </template>
-
 <script setup lang="ts" name="layoutBreadcrumb">
 import { reactive, computed, onMounted } from 'vue';
-import { onBeforeRouteUpdate, useRoute,useRouter } from 'vue-router';
+import { onBeforeRouteUpdate, useRoute, useRouter } from 'vue-router';
 import { Local } from '@/utils/storage';
 import other from '@/utils/other';
 import { storeToRefs } from 'pinia';
 import { useThemeConfig } from '@/stores/themeConfig';
 import { useRoutesList } from '@/stores/routesList';
-import {useUserInfo} from "@/stores/userInfo"
+import { useUserInfo } from '@/stores/userInfo';
+import { Expand, Fold } from '@element-plus/icons-vue';
+
 const storesUserInfo = useUserInfo();
 const { userInfos } = storeToRefs(storesUserInfo);
 
@@ -41,7 +44,7 @@ const route = useRoute();
 const router = useRouter();
 // 获取用户信息配置
 const userInfosConfig = computed(() => {
-  return userInfos.value;
+	return userInfos.value;
 });
 const state = reactive<BreadcrumbState>({
 	breadcrumbList: [],
@@ -69,6 +72,7 @@ const onThemeConfigChange = () => {
 };
 // 存储布局配置
 const setLocalThemeConfig = () => {
+	Local.remove('themeConfig');
 	Local.set('themeConfig', themeConfig.value);
 };
 // 处理面包屑数据
@@ -108,20 +112,17 @@ onBeforeRouteUpdate((to) => {
 
 <style scoped lang="scss">
 .layout-navbars-breadcrumb {
-	margin-right: 20px;
 	height: inherit;
 	display: flex;
 	align-items: center;
-	margin-left: 10px;
+	margin: 0 10px;
 
 	.layout-navbars-breadcrumb-icon {
 		cursor: pointer;
 		font-size: 18px;
 		color: var(--hotline-bg-topBarColor);
 		height: 100%;
-		width: 40px;
-		opacity: 0.8;
-
+		width: 30px;
 		&:hover {
 			opacity: 1;
 		}

+ 169 - 75
src/layout/navBars/breadcrumb/telControl.vue

@@ -149,6 +149,27 @@
 				</div>
 			</template>
 
+			<!-- 静音和取消静音 可用 -->
+			<template v-if="telStatusInfo.isDutyOn && activeArr.includes('mute')">
+				<div
+					class="item active"
+					:title="telStatusInfo.isMute ? '取消静音' : '静音'"
+					@click="onControlClick(telStatusInfo.isMute ? 'unMute' : 'mute')"
+					@mouseenter="onHover('muteSrc', 'phoneControls/mute_white.png')"
+					@mouseleave="onHover('muteSrc', 'phoneControls/mute_blue.png')"
+				>
+					<img :src="state.muteSrc" alt="" />
+					<span>{{ telStatusInfo.isMute ? '取消静音' : '静音' }}</span>
+				</div>
+			</template>
+			<!-- 灰色静音不可用 -->
+			<template v-else>
+				<div class="item disabled" title="静音">
+					<img :src="getImageUrl('phoneControls/mute_grey.png')" alt="" />
+					<span>静音</span>
+				</div>
+			</template>
+
 			<!-- 话后整理和取消话后整理中 可用-->
 			<template v-if="telStatusInfo.isDutyOn && activeArr.includes('TalkingDeal')">
 				<div
@@ -261,6 +282,7 @@
 			<el-text class="duty-on-time-time" tag="b" type="danger" v-if="onDutyTime">{{ formatDuration(onDutyTime) }}</el-text>
 		</div>
 	</div>
+
 	<!-- 占位标签 -->
 	<div class="seizeSeat-box"></div>
 	<!-- 功能 -->
@@ -577,6 +599,7 @@ const state = reactive<any>({
 	hangupSrc: getImageUrl('phoneControls/hangup_blue.png'), //挂断图片
 	restSrc: getImageUrl('phoneControls/rest_blue.png'), //小休图片
 	holdSrc: getImageUrl('phoneControls/hold_blue.png'), //保持图片
+	muteSrc: getImageUrl('phoneControls/mute_blue.png'), // 静音图片
 	talkingDealSrc: getImageUrl('phoneControls/talkingDeal_blue.png'), //话后整理图片
 	transferSrc: getImageUrl('phoneControls/transfer_blue.png'), //转接图片
 	conferenceSrc: getImageUrl('phoneControls/conference_blue.png'), //三方会议图片
@@ -664,10 +687,11 @@ const activeArr = computed(() => {
 	const switchCases: any = {
 		dutyOff: ['dutyOn'], // 签出状态
 		dutyOn: ['dutyOff', 'callOut', 'rest', 'outbound'], // 已签入无通话状态
-		onCallOut: ['callOut', 'outbound'], // 外呼模式中
+		onCallOut: ['dutyOff', 'callOut', 'outbound'], // 外呼模式中
 		rest: ['rest'], // 小休中状态
 		ring: ['hangup'], //振铃中
-		onCall: ['hangup', 'hold', 'transfer', 'conference'], // 单个通话中
+		onCall: ['hangup', 'hold', 'transfer', 'conference', 'mute'], // 单个通话中
+		onMute: ['hangup', 'transfer', 'mute'], // 静音中
 		onHold: ['hangup', 'hold', 'transfer'], // 保持中
 		onTalkingDeal: ['dutyOff', 'rest', 'TalkingDeal'], // 话后整理中
 		onConference: ['hangup'], // 三方会议中 只能挂断
@@ -688,6 +712,7 @@ const currentStatusText = computed(() => {
 		rest: '小休中',
 		ring: '振铃中',
 		onHold: '保持中',
+		onMute: '静音中',
 		onCall: '通话中',
 		onTalkingDeal: '整理中',
 		onConference: '会议中',
@@ -753,8 +778,11 @@ const onControlClick = (val: string) => {
 		case 'unHold': //取消保持
 			onUnHold();
 			break;
-		case 'TalkingDeal': //话后整理
-			onTalkingDeal();
+		case 'mute': //保持
+			onMute();
+			break;
+		case 'unMute': //取消保持
+			onUnMute();
 			break;
 		case 'unTalkingDeal': // 取消话后整理
 			unTalkingDeal();
@@ -926,6 +954,7 @@ const onMessage = async (event: any) => {
 					await onEndAcw(); // 挂机后整理结束
 				}
 				console.log('呼叫中心:示闲中');
+        isReconnect.value = true; // 签入重置需要是否重连
 				sendMsg('ready');
 			}
 		} else if (data.state == 'unready') {
@@ -1027,10 +1056,43 @@ const onMessage = async (event: any) => {
 		if (data.state == 'busy') {
 			call_direction.value = data.call_direction; // 保存呼叫方向
 			if (['held', 'unheld'].includes(data.private_data)) {
-				// 保持
-				holdStatus(data.private_data); //处理保持
-				if (data.private_data == 'held') await holdStart(); // 保持开始 业务系统统计需要
-				else await holdEnd();
+				console.log(muteModel.value, '21321');
+				if (muteModel.value || isTelMute.value) {
+					// 如果是静音状态
+					// 静音
+					if (data.private_data == 'held') {
+						// 设置电话状态
+						useTelStatusStore.setMute(true);
+						// 设置电话状态 静音中
+						useTelStatusStore.setPhoneControlState(TelStates.onMute);
+						sendMsg('mute');
+						await muteStart();
+					} else {
+						// 设置电话状态  取消单个静音为通话中
+						useTelStatusStore.setMute(false);
+						// 设置电话状态
+						useTelStatusStore.setPhoneControlState(TelStates.onCall);
+						sendMsg('busy');
+						await muteEnd();
+					}
+				} else {
+					// 保持
+					if (data.private_data == 'held') {
+						// 设置电话状态
+						useTelStatusStore.setHold(true);
+						// 设置电话状态 保持中
+						useTelStatusStore.setPhoneControlState(TelStates.onHold);
+						sendMsg('held');
+						await holdStart(); // 保持开始 业务系统统计需要
+					} else {
+						// 设置电话状态  取消单个保持为通话中
+						useTelStatusStore.setHold(false);
+						// 设置电话状态
+						useTelStatusStore.setPhoneControlState(TelStates.onCall);
+						sendMsg('busy');
+						await holdEnd();
+					}
+				}
 			} else {
 				// 非保持状态
 				if (data.private_data == 'monitoring') {
@@ -1219,72 +1281,8 @@ const reConnect = async () => {
 const stopReconnect = () => {
 	isReconnect.value = false;
 	clearTimeout(reconnectTimeout.value);
-	setTimeout(() => {
-		isReconnect.value = true;
-	}, 3000);
 	console.log('停止重连');
 };
-// 小休原因
-const restReason = ref(''); // 小休原因
-const break_reason = (reason: string) => {
-	switch (reason) {
-		case 'away':
-			restReason.value = '外出中';
-			break;
-		case 'rest':
-			restReason.value = '休息中';
-			break;
-		case 'conference':
-			restReason.value = '会议中';
-			break;
-		case 'train':
-			restReason.value = '培训中';
-			break;
-		case 'eat':
-			restReason.value = '用餐中';
-			break;
-		default:
-			restReason.value = '休息中';
-			break;
-	}
-	if (telStatusInfo.value.isRest !== 'resting' && !isRest.value) {
-		// 如果不在在小休中
-		const restReasons = state.restReasonOptions.find((item: any) => item.dicDataValue === reason);
-		busyOn({ reason: restReasons?.dicDataName ?? '' }) // 开始小休 设置示忙 业务系统统计需要
-			.then(() => {
-				console.log('业务系统调用示忙成功');
-				state.loading = false;
-			})
-			.catch((err) => {
-				console.log('业务系统调用示忙失败', err);
-				state.loading = false;
-			});
-	} else {
-		state.loading = false;
-	}
-};
-// 保持状态处理
-const holdStatus = (status: string) => {
-	switch (status) {
-		case 'held':
-			// 设置电话状态
-			useTelStatusStore.setHold(true);
-			// 设置电话状态 保持中
-			useTelStatusStore.setPhoneControlState(TelStates.onHold);
-			sendMsg('held');
-			break;
-		case 'unheld':
-			// 设置电话状态 通话中
-			// 设置电话状态  取消单个保持为通话中
-			useTelStatusStore.setHold(false);
-			// 设置电话状态
-			useTelStatusStore.setPhoneControlState(TelStates.onCall);
-			sendMsg('busy');
-			break;
-		default:
-			break;
-	}
-};
 const dutyFormRef = ref<RefType>();
 const currentTel = ref<any>({}); // 当前分机
 const isRest = ref<boolean>(false); // 是否小休
@@ -1341,17 +1339,20 @@ const clickOnDuty = (formEl: FormInstance | undefined) => {
 			request = {
 				telNo: state.dutyForm.telNo,
 				telPwd: state.dutyForm.password,
+				telModelState: 2, // 默认呼出模式
 			};
 		} else if (AppConfigInfo.value.isNeedTelNo) {
 			//需要分机号
 			request = {
 				telNo: state.dutyForm.telNo,
+				telModelState: 2, // 默认呼出模式
 			};
 		} else if (AppConfigInfo.value.isTelNeedVerify) {
 			// 需要密码
 			request = {
 				telNo: state.dutyForm.telNo,
 				telPwd: userInfos.value.defaultTelNo,
+				telModelState: 2, // 默认呼出模式
 			};
 		}
 		dutyOn(request)
@@ -1503,6 +1504,45 @@ const onHangup = () => {
 		})
 		.catch(() => {});
 };
+// 小休原因
+const restReason = ref(''); // 小休原因
+const break_reason = (reason: string) => {
+	switch (reason) {
+		case 'away':
+			restReason.value = '外出中';
+			break;
+		case 'rest':
+			restReason.value = '休息中';
+			break;
+		case 'conference':
+			restReason.value = '会议中';
+			break;
+		case 'train':
+			restReason.value = '培训中';
+			break;
+		case 'eat':
+			restReason.value = '用餐中';
+			break;
+		default:
+			restReason.value = '休息中';
+			break;
+	}
+	if (telStatusInfo.value.isRest !== 'resting' && !isRest.value) {
+		// 如果不在在小休中
+		const restReasons = state.restReasonOptions.find((item: any) => item.dicDataValue === reason);
+		busyOn({ reason: restReasons?.dicDataName ?? '' }) // 开始小休 设置示忙 业务系统统计需要
+			.then(() => {
+				console.log('业务系统调用示忙成功');
+				state.loading = false;
+			})
+			.catch((err) => {
+				console.log('业务系统调用示忙失败', err);
+				state.loading = false;
+			});
+	} else {
+		state.loading = false;
+	}
+};
 // 小休
 const restFormRef = ref<RefType>(); //小休表单
 const onRest = async () => {
@@ -1648,6 +1688,7 @@ const onHold = () => {
 		autofocus: false,
 	})
 		.then(() => {
+			muteModel.value = false;
 			ola.hold(); //保持
 		})
 		.catch(() => {});
@@ -1663,12 +1704,62 @@ const onUnHold = () => {
 		autofocus: false,
 	})
 		.then(() => {
+			muteModel.value = false;
+			ola.unhold(); //取消保持
+		})
+		.catch(() => {});
+};
+// 业务系统静音开始
+const muteStart = async () => {
+	try {
+		const res: any = await startAfterCall({ actionType: 4 });
+		console.log(res, '业务系统记录静音开始');
+	} catch (err) {
+		console.log(err);
+	}
+};
+// 业务系统静音结束
+const muteEnd = async () => {
+	try {
+		const res: any = await endAfterCall({ actionType: 4 });
+		console.log(res, '业务系统记录静音结束');
+	} catch (err) {
+		console.log(err);
+	}
+};
+// 静音
+const muteModel = ref(false);
+const onMute = () => {
+	ElMessageBox.confirm(`确定要静音,是否继续?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+		autofocus: false,
+	})
+		.then(() => {
+			muteModel.value = true;
+			ola.hold(); //保持
+		})
+		.catch(() => {});
+};
+// 静音取消
+const onUnMute = () => {
+	ElMessageBox.confirm(`确定要取消静音,是否继续?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+		autofocus: false,
+	})
+		.then(() => {
+			muteModel.value = true;
 			ola.unhold(); //取消保持
 		})
 		.catch(() => {});
 };
-// 话后整理(系统默认进入)
-const onTalkingDeal = () => {};
 // 取消话后整理
 const unTalkingDeal = () => {
 	ElMessageBox.confirm(`确定要取消话后整理,是否继续?`, '提示', {
@@ -1836,6 +1927,7 @@ const resetState = () => {
 // 获取当前分机状态
 const isCallHold = ref(false); // 是否是保持中
 const isAcw = ref(false); // 是否是话后整理中
+const isTelMute = ref(false); // 是否是静音中
 const getTelStatusFn = async () => {
 	try {
 		const { result } = await getTelStatus();
@@ -1848,6 +1940,7 @@ const getTelStatusFn = async () => {
 		isRest.value = result.isRest;
 		isCallHold.value = result.isCallHold;
 		isAcw.value = result.isCallEndArrange; // 是否话后整理中
+		isTelMute.value = result.isTelMute; // 是否静音中
 	} catch (e) {
 		console.log(e);
 	}
@@ -1871,6 +1964,7 @@ const callCenterConnect = async () => {
 			isCallHold.value = result.isCallHold;
 			isRest.value = result.isRest;
 			isAcw.value = result.isCallEndArrange; // 是否话后整理中
+			isTelMute.value = result.isTelMute; // 是否静音中
 			state.loading = false;
 		} else {
 			// 没有查询到当前用户上班状态  直接重置
@@ -1945,7 +2039,7 @@ onBeforeUnmount(() => {
 	}
 	.infos {
 		text-align: left;
-		width: 140px;
+		width: 150px;
 
 		.dutyOn_status {
 			color: var(--el-color-primary);

+ 1 - 1
src/layout/navBars/breadcrumb/user.vue

@@ -1,6 +1,6 @@
 <template>
 	<!--  :style="{ flex: layoutUserFlexNum }" -->
-	<div class="layout-navBars-breadcrumb-user pr15">
+	<div class="layout-navBars-breadcrumb-user pr5">
 		<!--		 <el-dropdown :show-timeout="70" :hide-timeout="50" trigger="click" @command="onComponentSizeChange">
 			<div class="layout-navBars-breadcrumb-user-icon mr10"  title="组件大小">
 				<i class="iconfont icon-ziti"></i>

+ 1 - 1
src/layout/navBars/tagsView/tagsView.vue

@@ -763,7 +763,7 @@ watch(
 
 .isShowControls {
 	background: none;
-	margin-top: 20px;
+	margin-top: 15px;
 
 	.tags-style-five {
 		.layout-navbars-tagsview-ul-li {

+ 27 - 1
src/stores/telStatus.ts

@@ -19,6 +19,7 @@ export enum TelStates {
 	rest = 'rest',  // 小休
 	ring = 'ring', // 来电响铃
 	onHold = 'onHold', // 保持中
+	onMute = 'onMute', // 静音中
 	onCall = 'onCall', // 一通电话通话中
 	onTalkingDeal = 'onTalkingDeal', 		// 事后处理中
 	onConference = 'onConference', // 三方会议中
@@ -30,13 +31,33 @@ export enum RestStates {
 	unRest = 'unRest' // 未小休
 }
 export const useTelStatus = defineStore('telStatus', {
-	state: (): TelsStateInfos => ({
+	state: (): {
+		telStatusInfo: {
+			isCallOut: boolean;
+			fromTel: string;
+			telGuid: string;
+			isMute: boolean;
+			isMeeting: boolean;
+			isDutyOn: boolean;
+			isHold: boolean;
+			isTalkingDeal: boolean;
+			telsNo: string;
+			groupName: string;
+			telGongHao: string;
+			telType: string;
+			telArea: string;
+			isRest: RestStates;
+			phoneControlState: TelStates;
+			telIVR: string
+		}
+	} => ({
 		telStatusInfo: {
 			isDutyOn: false, // 是否签入
 			isRest: RestStates.unRest, // 是否休息  'resting'|'InReview'|'unRest'; 休息中  审核中 其他状态
 			isTalkingDeal: false, //是否事后处理
 			isMeeting: false, //是否三方会议中
 			isHold: false, // 是否保持中
+			isMute: false,
 			isCallOut: false, // 是否是外呼模式
 			phoneControlState: TelStates.dutyOff, //当前状态 默认签出
 			telsNo: "", // 分机号
@@ -66,6 +87,10 @@ export const useTelStatus = defineStore('telStatus', {
 		setHold(data: boolean): void {
 			this.telStatusInfo.isHold = data;
 		},
+		// 设置静音状态
+		setMute(data: boolean): void {
+			this.telStatusInfo.isMute = data;
+		},
 		// 设置外呼模式
 		setCallOut(data: boolean): void {
 			this.telStatusInfo.isCallOut = data;
@@ -93,6 +118,7 @@ export const useTelStatus = defineStore('telStatus', {
 				isTalkingDeal: false, //是否事后处理
 				isMeeting: false, //是否三方会议中
 				isHold:false, // 是否保持中
+				isMute: false, // 是否静音
 				isCallOut:false, // 是否是外呼模式
 				phoneControlState: TelStates.dutyOff, //当前状态 默认签出
 				telsNo: "", // 分机号

+ 1 - 3
src/utils/constants.ts

@@ -147,7 +147,5 @@ export const disabledDate = (time: Date) => {
 	return time.getTime() < new Date().getTime();
 };
 
-// 默认选择日期
+// 默认选择日期(当天)
 export const defaultDate = [dayjs().startOf('day').format('YYYY-MM-DD'), dayjs().endOf('day').format('YYYY-MM-DD')];
-// 默认选择日期时间
-export const defaultDateTime = [dayjs().startOf('day').format('YYYY-MM-DD HH:mm:ss'), dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss')];

+ 21 - 36
src/views/todo/center/index.vue

@@ -14,32 +14,32 @@
 						</el-form-item>
 					</el-col>
 					<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6">
-						<el-form-item label="生成时间" prop="exTime">
+						<el-form-item label="生成时间" prop="scTime">
 							<el-date-picker
-								v-model="state.queryParams.exTime"
+								v-model="state.queryParams.scTime"
 								type="datetimerange"
 								unlink-panels
 								range-separator="至"
 								start-placeholder="开始时间"
 								end-placeholder="结束时间"
 								:shortcuts="shortcuts"
-								@change="timeStartChangeSc"
+								@change="handleQuery"
 								value-format="YYYY-MM-DD[T]HH:mm:ss"
 							/>
 						</el-form-item>
 					</el-col>
 					<transition name="el-zoom-in-top">
 						<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6" v-show="!searchCol">
-							<el-form-item label="受理时间" prop="crTime">
+							<el-form-item label="受理时间" prop="slTime">
 								<el-date-picker
-									v-model="state.queryParams.crTime"
+									v-model="state.queryParams.slTime"
 									type="datetimerange"
 									unlink-panels
 									range-separator="至"
 									start-placeholder="开始时间"
 									end-placeholder="结束时间"
 									:shortcuts="shortcuts"
-									@change="timeStartChangeCr"
+									@change="handleQuery"
 									value-format="YYYY-MM-DD[T]HH:mm:ss"
 								/>
 							</el-form-item>
@@ -87,7 +87,7 @@
 						</el-col>
 					</transition>
 					<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6">
-						<el-form-item label=" ">
+						<el-form-item label="">
 							<div class="flex-end w100">
 								<el-button type="primary" @click="handleQuery" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
 								<el-button @click="resetQuery(ruleFormRef)" class="default-button" :loading="state.loading">
@@ -150,7 +150,7 @@
 import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
 import type { FormInstance } from 'element-plus';
 import { ElMessage, ElMessageBox } from 'element-plus';
-import { shortcuts } from '@/utils/constants';
+import { defaultDateThree, shortcuts } from "@/utils/constants";
 import other from '@/utils/other';
 import { useRoute, useRouter } from 'vue-router';
 import { formatDate } from '@/utils/formatTime';
@@ -170,12 +170,12 @@ const state = reactive<any>({
 		PageSize: 10, // 每页条数
 		// 查询条件
 		No: null, // 工单编号
-		exTime: [], // 生成时间
+    scTime: defaultDateThree, // 生成时间
 		StCreationTime: null, // 生成开始时间
 		EnCreationTime: null, // 生成结束时间
-		crTime: [], // 受理时间
-		StartTimeEnd: null, // 受理开始时间
-		EndTimeEnd: null, // 受理结束时间
+    slTime: [], // 受理时间
+    StartTimeSt: null, // 受理开始时间
+		StartTimeEnd: null, // 受理结束时间
 		AcceptorName: null, // 受理人
 		ActualHandleOrgName: null, // 接办部门
 		Status: null, // 工单状态
@@ -249,24 +249,6 @@ const columns = ref<any[]>([
 	},
 	{ prop: 'operation', label: '操作', fixed: 'right', width: 160, align: 'center' },
 ]);
-const handleTimeChange = (val: string[], startKey: string, endKey: string) => {
-	if (val) {
-		state.queryParams[startKey] = val[0];
-		state.queryParams[endKey] = val[1];
-	} else {
-		state.queryParams[startKey] = '';
-		state.queryParams[endKey] = '';
-	}
-	handleQuery();
-};
-// 受理时间
-const timeStartChangeCr = (val: string[]) => {
-	handleTimeChange(val, 'StartTimeEnd', 'StartTimeSt');
-};
-// 生成时间
-const timeStartChangeSc = (val: string[]) => {
-	handleTimeChange(val, 'StCreationTime', 'EndCreationTime');
-};
 // 获取查询条件基础信息
 const getBaseData = async () => {
 	try {
@@ -291,8 +273,15 @@ const handleQuery = () => {
 /** 获取列表 */
 const queryList = () => {
 	let request = other.deepClone(state.queryParams);
-	Reflect.deleteProperty(request, 'crTime'); // 删除无用的参数
-	Reflect.deleteProperty(request, 'exTime'); // 删除无用的参数
+  request.StCreationTime = state.queryParams.scTime === null ? null : state.queryParams.scTime[0];
+  request.EndCreationTime = state.queryParams.scTime === null ? null : state.queryParams.scTime[1];
+  Reflect.deleteProperty(request, 'scTime');
+
+  request.StartTimeSt = state.queryParams.slTime === null ? null : state.queryParams.slTime[0];
+  request.StartTimeEnd = state.queryParams.slTime === null ? null : state.queryParams.slTime[1];
+  Reflect.deleteProperty(request, 'slTime');
+
+
 	state.loading = true;
 	centerTodo(request)
 		.then((response: any) => {
@@ -309,10 +298,6 @@ const queryList = () => {
 const resetQuery = (formEl: FormInstance | undefined) => {
 	if (!formEl) return;
 	formEl.resetFields();
-	state.queryParams.StCreationTime = null;
-	state.queryParams.EndCreationTime = null;
-	state.queryParams.StartTimeEnd = null;
-	state.queryParams.StartTimeSt = null;
 	queryList();
 };
 // 签收工单

+ 116 - 54
src/views/todo/order/index.vue

@@ -5,37 +5,74 @@
 				<el-tab-pane name="false" label="工单待办"></el-tab-pane>
 				<el-tab-pane name="true" label="工单已办"></el-tab-pane>
 			</el-tabs>
-			<el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent inline>
-				<el-form-item label="关键字" prop="Keyword">
-					<el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="handleQuery" class="keyword-input" />
-				</el-form-item>
-				<el-form-item label="是否省工单" prop="IsProvince">
-					<el-select v-model="state.queryParams.IsProvince" placeholder="请选择是否省工单" @change="handleQuery">
-						<el-option label="是" value="true" />
-						<el-option label="否" value="false" />
-					</el-select>
-				</el-form-item>
-				<el-form-item label="是否会签" prop="IsCounterSign">
-					<el-select v-model="state.queryParams.IsCounterSign" placeholder="请选择是否会签" @change="handleQuery">
-						<el-option label="是" value="true" />
-						<el-option label="否" value="" />
-					</el-select>
-				</el-form-item>
-				<el-form-item label="超期状态" prop="ExpiredOrAlmostOverdue">
-					<el-select v-model="state.queryParams.ExpiredOrAlmostOverdue" placeholder="请选择超期状态" @change="handleQuery">
-						<el-option label="已超期" value="true" />
-						<el-option label="即将超期" value="false" />
-					</el-select>
-				</el-form-item>
-				<el-form-item>
-					<el-button type="primary" @click="handleQuery" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
-					<el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading">
-						<SvgIcon name="ele-Refresh" class="mr5" />重置
-					</el-button>
-				</el-form-item>
+			<el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent>
+				<el-row :gutter="20">
+					<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6">
+						<el-form-item label="关键字" prop="Keyword">
+							<el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="handleQuery" />
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6">
+						<el-form-item label="生成时间" prop="scTime">
+							<el-date-picker
+								v-model="state.queryParams.scTime"
+								type="datetimerange"
+								unlink-panels
+								range-separator="至"
+								start-placeholder="开始时间"
+								end-placeholder="结束时间"
+								:shortcuts="shortcuts"
+								@change="handleQuery"
+								value-format="YYYY-MM-DD[T]HH:mm:ss"
+							/>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6">
+						<el-form-item label="是否省工单" prop="IsProvince">
+							<el-select v-model="state.queryParams.IsProvince" placeholder="请选择是否省工单" @change="handleQuery" class="w100">
+								<el-option label="是" value="true" />
+								<el-option label="否" value="false" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<transition name="el-zoom-in-top">
+						<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6" v-show="!searchCol">
+							<el-form-item label="是否会签" prop="IsCounterSign">
+								<el-select v-model="state.queryParams.IsCounterSign" placeholder="请选择是否会签" @change="handleQuery" class="w100">
+									<el-option label="是" value="true" />
+									<el-option label="否" value="" />
+								</el-select>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<transition name="el-zoom-in-top">
+						<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6" v-show="!searchCol">
+							<el-form-item label="超期状态" prop="ExpiredOrAlmostOverdue">
+								<el-select v-model="state.queryParams.ExpiredOrAlmostOverdue" placeholder="请选择超期状态" @change="handleQuery" class="w100">
+									<el-option label="已超期" value="true" />
+									<el-option label="即将超期" value="false" />
+								</el-select>
+							</el-form-item>
+						</el-col>
+					</transition>
+					<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6">
+						<el-form-item label="">
+							<div class="flex-end w100">
+								<el-button type="primary" @click="handleQuery" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+								<el-button @click="resetQuery(ruleFormRef)" class="default-button" :loading="state.loading">
+									<SvgIcon name="ele-Refresh" class="mr5" />重置
+								</el-button>
+								<el-button link type="primary" @click="closeSearch" :loading="state.loading">
+									{{ searchCol ? '展开' : '收起' }}
+									<SvgIcon :class="{ 'is-reverse': searchCol }" name="ele-ArrowUp" class="mr5 arrow" size="18px" />
+								</el-button>
+							</div>
+						</el-form-item>
+					</el-col>
+				</el-row>
 			</el-form>
 			<!-- 表格 -->
-<!--      :toolButton="['refresh', 'setting', 'exportCurrent', 'exportAll']"-->
+			<!--      :toolButton="['refresh', 'setting', 'exportCurrent', 'exportAll']"-->
 			<ProTable
 				ref="proTableRef"
 				:columns="columns"
@@ -46,9 +83,8 @@
 				v-model:page-index="state.queryParams.PageIndex"
 				v-model:page-size="state.queryParams.PageSize"
 				:key="Math.random()"
-
-        @export-current="exportTable($event)"
-        @export-all="exportTable($event, true)"
+				@export-current="exportTable($event)"
+				@export-all="exportTable($event, true)"
 			>
 				<template #tableHeader="scope">
 					<el-button type="primary" @click="onJbExport" :disabled="!scope.isSelected" :loading="state.loading" v-auth="'todo:seats:jbdExport'"
@@ -77,10 +113,12 @@ import { useRouter } from 'vue-router';
 import { orderListTodo } from '@/api/todo/order';
 import { exportJbOrder } from '@/api/business/order';
 import { downloadZip } from '@/utils/tools';
+import { defaultDateThree, shortcuts } from '@/utils/constants';
+import Other from '@/utils/other';
 // 引入组件
 const OrderDetail = defineAsyncComponent(() => import('@/components/OrderDetail/index.vue')); // 工单详情
 // 定义变量内容
-const state = reactive({
+const state = reactive<any>({
 	queryParams: {
 		// 查询条件
 		PageIndex: 1, // 当前页
@@ -90,12 +128,20 @@ const state = reactive({
 		IsProvince: null, // 是否省工单
 		IsCounterSign: null, // 是否会签
 		ExpiredOrAlmostOverdue: null, // 超期状态
+		scTime: defaultDateThree,
+		StartTime: null,
+		EndTime: null,
 	},
 	tableData: [], //表单
 	loading: false, // 加载
 	total: 0, // 总数
 });
 const ruleFormRef = ref<RefType>(); // 表单ref
+const searchCol = ref(true); // 展开/收起
+// 展开/收起
+const closeSearch = () => {
+	searchCol.value = !searchCol.value;
+};
 const router = useRouter(); // 路由
 const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
@@ -206,7 +252,12 @@ const queryList = async () => {
 		} else {
 			columns.value = columnsTodo;
 		}
-		const res: any = await orderListTodo(state.queryParams);
+
+		let request = Other.deepClone(state.queryParams);
+		request.StartTime = state.queryParams.scTime === null ? null : state.queryParams.scTime[0];
+		request.EndTime = state.queryParams.scTime === null ? null : state.queryParams.scTime[1];
+		Reflect.deleteProperty(request, 'scTime');
+		const res: any = await orderListTodo(request);
 		state.tableData = res.result?.items ?? [];
 		state.total = res.result?.total ?? 0;
 		state.loading = false;
@@ -247,26 +298,26 @@ const onJbExport = () => {
 };
 // 表格导出
 const exportTable = (val: any, isExportAll = false) => {
-  const columnInfos = val.map((item: any) => {
-    return {
-      prop: item.prop,
-      name: item.label,
-    };
-  });
-  const req = {
-    queryDto: { ...state.queryParams },
-    columnInfos,
-    isExportAll,
-  };
-  state.loading = true;
-  exportOrder(req)
-    .then((res: any) => {
-      state.loading = false;
-      downloadFileByStream(res);
-    })
-    .catch(() => {
-      state.loading = false;
-    });
+	const columnInfos = val.map((item: any) => {
+		return {
+			prop: item.prop,
+			name: item.label,
+		};
+	});
+	const req = {
+		queryDto: { ...state.queryParams },
+		columnInfos,
+		isExportAll,
+	};
+	state.loading = true;
+	exportOrder(req)
+		.then((res: any) => {
+			state.loading = false;
+			downloadFileByStream(res);
+		})
+		.catch(() => {
+			state.loading = false;
+		});
 };
 const historyParams = history.state;
 onMounted(() => {
@@ -284,3 +335,14 @@ onMounted(() => {
 	queryList();
 });
 </script>
+<style scoped lang="scss">
+.todo-order-container {
+	.arrow {
+		transition: transform var(--el-transition-duration);
+		cursor: pointer;
+	}
+	.arrow.is-reverse {
+		transform: rotateZ(-180deg);
+	}
+}
+</style>

+ 59 - 24
src/views/todo/seats/index.vue

@@ -5,28 +5,53 @@
 				<el-tab-pane name="false" label="工单待办"></el-tab-pane>
 				<el-tab-pane name="true" label="工单已办"></el-tab-pane>
 			</el-tabs>
-			<el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent inline>
-				<el-form-item label="关键字" prop="Keyword">
-					<el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="handleQuery" class="keyword-input" />
-				</el-form-item>
-				<el-form-item label="是否省工单" prop="IsProvince">
-					<el-select v-model="state.queryParams.IsProvince" placeholder="请选择是否省工单" @change="handleQuery">
-						<el-option label="是" value="true" />
-						<el-option label="否" value="false" />
-					</el-select>
-				</el-form-item>
-				<el-form-item label="是否会签" prop="IsCounterSign">
-					<el-select v-model="state.queryParams.IsCounterSign" placeholder="请选择是否会签" @change="handleQuery">
-						<el-option label="是" value="true" />
-						<el-option label="否" value="false" />
-					</el-select>
-				</el-form-item>
-				<el-form-item>
-					<el-button type="primary" @click="handleQuery" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
-					<el-button @click="resetQuery(ruleFormRef)" class="default-button" :loading="state.loading">
-						<SvgIcon name="ele-Refresh" class="mr5" />重置
-					</el-button>
-				</el-form-item>
+			<el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent>
+				<el-row :gutter="20">
+					<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6">
+						<el-form-item label="关键字" prop="Keyword">
+							<el-input v-model="state.queryParams.Keyword" placeholder="工单编码/标题" clearable @keyup.enter="handleQuery" />
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6">
+						<el-form-item label="是否省工单" prop="IsProvince">
+							<el-select v-model="state.queryParams.IsProvince" placeholder="请选择是否省工单" @change="handleQuery" class="w100">
+								<el-option label="是" value="true" />
+								<el-option label="否" value="false" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6">
+						<el-form-item label="是否会签" prop="IsCounterSign">
+							<el-select v-model="state.queryParams.IsCounterSign" placeholder="请选择是否会签" @change="handleQuery" class="w100">
+								<el-option label="是" value="true" />
+								<el-option label="否" value="false" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6">
+						<el-form-item label="生成时间" prop="scTime">
+							<el-date-picker
+								v-model="state.queryParams.scTime"
+								type="datetimerange"
+								unlink-panels
+								range-separator="至"
+								start-placeholder="开始时间"
+								end-placeholder="结束时间"
+								:shortcuts="shortcuts"
+								@change="handleQuery"
+								value-format="YYYY-MM-DD[T]HH:mm:ss"
+							/>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6">
+						<el-form-item>
+							<el-button type="primary" @click="handleQuery" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
+							<el-button @click="resetQuery(ruleFormRef)" class="default-button" :loading="state.loading">
+								<SvgIcon name="ele-Refresh" class="mr5" />重置
+							</el-button>
+						</el-form-item>
+					</el-col>
+				</el-row>
 			</el-form>
 			<!-- 表格 -->
 			<!--      	:toolButton="['refresh', 'setting', 'exportCurrent', 'exportAll']"-->
@@ -74,10 +99,12 @@ import { useRouter } from 'vue-router';
 import { seatsListTodo, orderSign } from '@/api/todo/order';
 import { downloadFileByStream, downloadZip } from '@/utils/tools';
 import { exportJbOrder, exportOrder } from '@/api/business/order';
+import { defaultDateThree, shortcuts } from '@/utils/constants';
+import Other from '@/utils/other';
 // 引入组件
 const OrderDetail = defineAsyncComponent(() => import('@/components/OrderDetail/index.vue')); // 工单详情
 // 定义变量内容
-const state = reactive({
+const state = reactive<any>({
 	queryParams: {
 		// 查询条件
 		PageIndex: 1, // 当前页
@@ -86,6 +113,9 @@ const state = reactive({
 		Keyword: null, // 关键字
 		IsProvince: null, // 是否省工单
 		IsCounterSign: null, // 是否会签
+    scTime: defaultDateThree,
+		StartTime: null,
+		EndTime: null,
 	},
 	tableData: [], //表单
 	loading: false, // 加载
@@ -201,11 +231,16 @@ const queryList = async () => {
 		} else {
 			columns.value = columnsTodo;
 		}
-		const res: any = await seatsListTodo(state.queryParams);
+		let request = Other.deepClone(state.queryParams);
+		request.StartTime = state.queryParams.scTime === null ? null : state.queryParams.scTime[0];
+		request.EndTime = state.queryParams.scTime === null ? null : state.queryParams.scTime[1];
+		Reflect.deleteProperty(request, 'scTime');
+		const res: any = await seatsListTodo(request);
 		state.tableData = res.result?.items ?? [];
 		state.total = res.result?.total ?? 0;
 		state.loading = false;
 	} catch (e) {
+		console.log(e);
 		state.loading = false;
 	}
 };