Ver Fonte

reactor:辅助功能表格重构完成;

zhangchong há 5 meses atrás
pai
commit
f4a1fae0c5

+ 1 - 1
.env.development

@@ -3,7 +3,7 @@ VITE_MODE_NAME=development
 # 防止部署多套系统到同一域名不同目录时,变量共用的问题 设置不同的前缀
 VITE_STORAGE_NAME=dev
 # 业务系统基础请求地址
-VITE_API_URL=http://110.188.24.28:50100
+VITE_API_URL=http://110.188.24.28:50300
 # 业务系统socket请求地址
 VITE_API_SOCKET_URL=http://110.188.24.28:50100/hubs/hotline
 # 业务系统文件上传上传请求地址

+ 28 - 25
src/views/auxiliary/citizen/components/Tags-record.vue

@@ -12,42 +12,45 @@
 				<el-button @click="resetQuery(ruleFormRef)" class="default-button"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
 			</el-form-item>
 		</el-form>
-		<ProTable
-			ref="proTableRef"
-			:columns="columns"
-			:data="state.tableData"
-			@updateTable="queryList"
+		<vxe-table
+			border
 			:loading="state.loading"
-			:total="state.total"
-			v-model:page-index="state.queryParams.PageIndex"
-			v-model:page-size="state.queryParams.PageSize"
+			:data="state.tableData"
+			:column-config="{ resizable: true }"
+			:row-config="{ isCurrent: true, isHover: true, height: 30 }"
+			ref="tableRef"
+			:scrollY="{ enabled: true, gt: 0 }"
+			show-overflow
 			max-height="500px"
 		>
-		</ProTable>
+			<vxe-column field="label" title="市民标签"></vxe-column>
+			<vxe-column field="phone" title="电话"></vxe-column>
+			<vxe-column field="creatorName" title="记录人"></vxe-column>
+			<vxe-column field="creationTime" title="创建时间" width="160">
+				<template #default="{ row }">
+					{{ formatDate(row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}
+				</template>
+			</vxe-column>
+		</vxe-table>
+		<pagination
+			@pagination="queryList"
+			:total="state.total"
+			v-model:current-page="state.queryParams.PageIndex"
+			v-model:page-size="state.queryParams.PageSize"
+			:disabled="state.loading"
+		/>
 	</el-dialog>
 </template>
 
 <script setup lang="tsx" name="businessCitizenTagsRecord">
-import { reactive, ref } from 'vue';
+import { defineAsyncComponent, reactive, ref } from 'vue';
 import type { FormInstance } from 'element-plus';
 import { citizenLabelList } from '@/api/auxiliary/citizen';
 import { formatDate } from '@/utils/formatTime';
 
-const proTableRef = ref<RefType>(); // 表格ref
-// 表格配置项
-const columns = ref<any[]>([
-	{ prop: 'label', label: '市民标签' },
-	{ prop: 'phone', label: '市民' },
-	{ prop: 'creatorName', label: '记录人' },
-	{
-		prop: 'creationTime',
-		label: '创建时间',
-		width: 170,
-		render: (scope: any) => {
-			return <span>{formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
-		},
-	},
-]);
+
+const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
+
 // 定义变量内容
 const state = reactive({
 	dialogVisible: false, // 弹窗显示隐藏

+ 74 - 58
src/views/auxiliary/citizen/index.vue

@@ -1,42 +1,77 @@
 <template>
 	<div class="auxiliary-citizen-container layout-padding">
 		<div class="layout-padding-auto layout-padding-view pd20">
-			<ProTable
-				ref="proTableRef"
-				:columns="columns"
-				:data="state.tableData"
-				@updateTable="queryList"
+			<el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent>
+				<el-form-item label="市民联系方式" prop="PhoneNumber">
+					<el-input
+						v-model="state.queryParams.PhoneNumber"
+						placeholder="请填写市民联系方式"
+						clearable
+						@keyup.enter="handleQuery"
+						class="keyword-input"
+					/>
+				</el-form-item>
+				<el-form-item label="市民标签" prop="Label">
+					<el-input v-model="state.queryParams.Label" placeholder="请填写市民标签" clearable @keyup.enter="handleQuery" class="keyword-input" />
+				</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"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
+				</el-form-item>
+			</el-form>
+			<vxe-toolbar
+				ref="toolbarRef"
 				:loading="state.loading"
+				custom
+				:refresh="{
+					queryMethod: handleQuery,
+				}"
+			>
+			</vxe-toolbar>
+			<div style="overflow: hidden; width: 100%; height: 100%; flex: 1">
+				<vxe-table
+					border
+					:loading="state.loading"
+					:data="state.tableData"
+					:column-config="{ resizable: true }"
+					:row-config="{ isCurrent: true, isHover: true, height: 30 }"
+					ref="tableRef"
+					height="auto"
+					auto-resize
+					id="auxiliaryCitizen"
+					:custom-config="{ storage: true }"
+					:scrollY="{ enabled: true, gt: 0 }"
+					show-overflow
+				>
+					<vxe-column field="phoneNumber" title="市民联系方式" width="200"></vxe-column>
+					<vxe-column field="label" title="市民标签" min-width="300"></vxe-column>
+					<vxe-column field="creatorName" title="创建人" width="120"></vxe-column>
+					<vxe-column field="creationTime" title="创建时间" width="160">
+						<template #default="{ row }">
+							{{ formatDate(row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}
+						</template>
+					</vxe-column>
+					<vxe-column field="lastModificationName" title="更新人" width="120"></vxe-column>
+					<vxe-column field="lastModificationTime" title="更新时间" width="160">
+						<template #default="{ row }">
+							{{ formatDate(row.lastModificationTime, 'YYYY-mm-dd HH:MM:SS') }}
+						</template>
+					</vxe-column>
+					<vxe-column title="操作" fixed="right" width="140" align="center" :show-overflow="false">
+						<template #default="{ row }">
+							<el-button link type="primary" @click="onTagsRecord(row)" v-auth="'auxiliary:citizen:tag'" title="查看市民标签记录"> 标签记录 </el-button>
+							<el-button link type="primary" @click="onTagsEdit(row)" v-auth="'auxiliary:citizen:edit'" title="编辑市民画像"> 编辑 </el-button>
+						</template>
+					</vxe-column>
+				</vxe-table>
+			</div>
+			<pagination
+				@pagination="queryList"
 				:total="state.total"
-				v-model:page-index="state.queryParams.PageIndex"
+				v-model:current-page="state.queryParams.PageIndex"
 				v-model:page-size="state.queryParams.PageSize"
-			>
-        <template #table-search>
-          <el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent>
-            <el-form-item label="市民联系方式" prop="PhoneNumber">
-              <el-input
-                  v-model="state.queryParams.PhoneNumber"
-                  placeholder="请填写市民联系方式"
-                  clearable
-                  @keyup.enter="handleQuery"
-                  class="keyword-input"
-              />
-            </el-form-item>
-            <el-form-item label="市民标签" prop="Label">
-              <el-input v-model="state.queryParams.Label" placeholder="请填写市民标签" clearable @keyup.enter="handleQuery" class="keyword-input" />
-            </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"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
-            </el-form-item>
-          </el-form>
-        </template>
-				<!-- 表格操作 -->
-				<template #operation="{ row }">
-					<el-button link type="primary" @click="onTagsRecord(row)" v-auth="'auxiliary:citizen:tag'" title="查看市民标签记录"> 标签记录 </el-button>
-					<el-button link type="primary" @click="onTagsEdit(row)" v-auth="'auxiliary:citizen:edit'" title="编辑市民画像"> 编辑 </el-button>
-				</template>
-			</ProTable>
+				:disabled="state.loading"
+			/>
 		</div>
 		<!-- 标签记录   -->
 		<tags-record ref="tagsRecordRef" />
@@ -54,32 +89,8 @@ import { citizenList } from '@/api/auxiliary/citizen';
 // 引入组件
 const TagsRecord = defineAsyncComponent(() => import('@/views/auxiliary/citizen/components/Tags-record.vue')); // 标签记录
 const TagsEdit = defineAsyncComponent(() => import('@/views/auxiliary/citizen/components/Tags-edit.vue')); // 标签编辑
+const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
 
-const proTableRef = ref<RefType>(); // 表格ref
-// 表格配置项
-const columns = ref<any[]>([
-	{ prop: 'phoneNumber', label: '市民联系方式', minWidth: 200 },
-	{ prop: 'label', label: '市民标签', minWidth: 300 },
-	{ prop: 'creatorName', label: '创建人', minWidth: 120 },
-	{
-		prop: 'creationTime',
-		label: '创建时间',
-    minWidth: 160,
-		render: (scope) => {
-			return <span>{formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
-		},
-	},
-	{ prop: 'lastModificationName', label: '更新人', minWidth: 120 },
-	{
-		prop: 'lastModificationTime',
-		label: '更新时间',
-    minWidth: 160,
-		render: (scope) => {
-			return <span>{formatDate(scope.row.lastModificationTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
-		},
-	},
-	{ prop: 'operation', label: '操作', fixed: 'right', width: 140, align: 'center' },
-]);
 // 定义变量内容
 const state = reactive({
 	loading: false, // 加载状态
@@ -128,8 +139,13 @@ const TagsEditRef = ref<RefType>();
 const onTagsEdit = (row: any) => {
 	TagsEditRef.value.openDialog(row);
 };
+const toolbarRef = ref<RefType>();
+const tableRef = ref<RefType>();
 // 页面加载时
 onMounted(() => {
 	queryList();
+	if (tableRef.value && toolbarRef.value) {
+		tableRef.value.connect(toolbarRef.value);
+	}
 });
 </script>

+ 101 - 56
src/views/auxiliary/externalCitizen/index.vue

@@ -1,38 +1,33 @@
 <template>
 	<div class="auxiliary-external-citizen-container layout-padding">
 		<div class="layout-padding-auto layout-padding-view pd20">
-			<!-- 表格 -->
-			<ProTable
-				ref="proTableRef"
-				:columns="columns"
-				:data="state.tableData"
-				@updateTable="queryList"
+			<el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent>
+				<el-form-item label="市民姓名" prop="Name">
+					<el-input v-model="state.queryParams.Name" placeholder="请填写市民姓名" clearable @keyup.enter="handleQuery" class="keyword-input" />
+				</el-form-item>
+				<el-form-item label="联系电话" prop="PhoneNum">
+					<el-input
+						v-model="state.queryParams.PhoneNum"
+						placeholder="请填写市民联系电话"
+						clearable
+						@keyup.enter="handleQuery"
+						class="keyword-input"
+					/>
+				</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>
+			<vxe-toolbar
+				ref="toolbarRef"
 				:loading="state.loading"
-				:total="state.total"
-				v-model:page-index="state.queryParams.PageIndex"
-				v-model:page-size="state.queryParams.PageSize"
+				custom
+				:refresh="{
+					queryMethod: handleQuery
+				}"
 			>
-				<template #table-search>
-					<el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent>
-						<el-form-item label="市民姓名" prop="Name">
-							<el-input v-model="state.queryParams.Name" placeholder="请填写市民姓名" clearable @keyup.enter="handleQuery" class="keyword-input" />
-						</el-form-item>
-						<el-form-item label="联系电话" prop="PhoneNum">
-							<el-input
-								v-model="state.queryParams.PhoneNum"
-								placeholder="请填写市民联系电话"
-								clearable
-								@keyup.enter="handleQuery"
-								class="keyword-input"
-							/>
-						</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>
-				</template>
-				<template #tableHeader="scope">
+				<template #buttons>
 					<el-upload
 						v-model:file-list="fileList"
 						action="#"
@@ -49,14 +44,51 @@
 					<el-button type="primary" @click="onDownload" v-auth="'auxiliary:externalCitizen:download'" :loading="state.loading">
 						<SvgIcon name="ele-Download" class="mr5" /> 模板下载
 					</el-button>
-					<el-button type="danger" @click="onDelete" :disabled="!scope.isSelected" :loading="state.loading" v-auth="'auxiliary:externalCitizen:delete'"
-					><SvgIcon name="ele-Delete" class="mr5" />删除<span v-if="proTableRef?.selectedList?.length">({{proTableRef?.selectedList?.length}})</span>
+					<el-button type="danger" @click="onDelete" :disabled="isChecked" :loading="state.loading" v-auth="'auxiliary:externalCitizen:delete'"
+					><SvgIcon name="ele-Delete" class="mr5" />删除
 					</el-button>
 				</template>
-				<template #operation="{ row }">
-					<el-button link type="primary" @click="onEdit(row)" title="编辑市民信息" v-auth="'auxiliary:externalCitizen:edit'"> 修改 </el-button>
-				</template>
-			</ProTable>
+			</vxe-toolbar>
+			<div style="overflow: hidden; width: 100%; height: 100%; flex: 1">
+				<vxe-table
+					border
+					:loading="state.loading"
+					:data="state.tableData"
+					:column-config="{ resizable: true }"
+					:row-config="{ isCurrent: true, isHover: true, height: 30 }"
+					ref="tableRef"
+					@checkbox-all="selectAllChangeEvent"
+					@checkbox-change="selectChangeEvent"
+					height="auto"
+					auto-resize
+					show-overflow
+					:scrollY="{ enabled: true, gt: 0 }"
+					id="auxiliaryExternalCitizen"
+					:custom-config="{ storage: true }"
+					showHeaderOverflow
+				>
+					<vxe-column type="checkbox" width="50" align="center"></vxe-column>
+					<vxe-column field="name" title="市民姓名" ></vxe-column>
+					<vxe-column field="phoneNum" title="联系电话"></vxe-column>
+					<vxe-column field="creationTime" title="创建时间" width="160">
+						<template #default="{ row }">
+							{{ formatDate(row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}
+						</template>
+					</vxe-column>
+					<vxe-column title="操作" fixed="right" width="90" align="center">
+						<template #default="{ row }">
+							<el-button link type="primary" @click="onEdit(row)" title="编辑市民信息" v-auth="'auxiliary:externalCitizen:edit'"> 修改 </el-button>
+						</template>
+					</vxe-column>
+				</vxe-table>
+			</div>
+			<pagination
+				@pagination="queryList"
+				:total="state.total"
+				v-model:current-page="state.queryParams.PageIndex"
+				v-model:page-size="state.queryParams.PageSize"
+				:disabled="state.loading"
+			/>
 		</div>
 		<!-- 编辑   -->
 		<edit-info ref="editInfoRef" @updateList="queryList" />
@@ -64,7 +96,7 @@
 </template>
 
 <script lang="tsx" setup name="auxiliaryExternalCitizen">
-import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
+import { computed, defineAsyncComponent, onMounted, reactive, ref } from 'vue';
 import { ElMessage, ElMessageBox, ElNotification, FormInstance } from 'element-plus';
 import { externalCitizenDelete, externalCitizenImport, externalCitizenList, externalCitizenTemplate } from '@/api/auxiliary/externalCitizen';
 import { downloadFileByStream } from '@/utils/tools';
@@ -72,30 +104,15 @@ import { formatDate } from '@/utils/formatTime';
 
 // 引入组件
 const EditInfo = defineAsyncComponent(() => import('@/views/auxiliary/externalCitizen/components/Edit.vue')); // 标签编辑
+const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
 
-const proTableRef = ref<RefType>(); // 表格ref
-// 表格配置项
-const columns = ref<any[]>([
-	{ type: 'selection', width: 40, align: 'center' },
-	{ prop: 'name', label: '市民姓名' },
-	{ prop: 'phoneNum', label: '联系电话' },
-	{
-		prop: 'creationTime',
-		label: '创建时间',
-		minWidth: 160,
-		render: (scope: any) => {
-			return formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS');
-		},
-	},
-	{ prop: 'operation', label: '操作', fixed: 'right', minWidth: 90, align: 'center' },
-]);
 // 定义变量内容
 const state = reactive({
 	loading: false, // 加载状态
 	queryParams: {
 		// 查询参数
 		PageIndex: 1,
-		PageSize: 20,
+		PageSize: 2,
 		PhoneNum: null,
 		Name: null,
 	},
@@ -116,9 +133,13 @@ const queryList = () => {
 			state.loading = false;
 			state.tableData = res.result.items ?? [];
 			state.total = res.result.total ?? 0;
+			tableRef.value.clearCheckboxRow();
+			checkTable.value = [];
 		})
 		.finally(() => {
 			state.loading = false;
+			tableRef.value.clearCheckboxRow();
+			checkTable.value = [];
 		});
 };
 // 重置表单
@@ -174,8 +195,8 @@ const onDownload = () => {
 };
 // 删除
 const onDelete = () => {
-	const ids = proTableRef.value.selectedList.map((item: any) => item.id);
-	ElMessageBox.confirm(`您确定删除选中的${ids.length}条数据,是否继续?`, '提示', {
+	const ids = checkTable.value.map((item: any) => item.id);
+	ElMessageBox.confirm(`您确定删除选中的外部市民,是否继续?`, '提示', {
 		confirmButtonText: '确认',
 		cancelButtonText: '取消',
 		type: 'warning',
@@ -200,9 +221,33 @@ const editInfoRef = ref<RefType>();
 const onEdit = (row: any) => {
 	editInfoRef.value.openDialog(row);
 };
+const tableRef = ref<RefType>();
+const checkTable = ref<EmptyArrayType>([]);
+const selectAllChangeEvent = ({ checked }) => {
+	if (tableRef.value) {
+		const records = tableRef.value.getCheckboxRecords();
+		checkTable.value = records;
+		console.log(checked ? '所有勾选事件' : '所有取消事件', records);
+	}
+};
+
+const selectChangeEvent = ({ checked }) => {
+	if (tableRef.value) {
+		const records = tableRef.value.getCheckboxRecords();
+		checkTable.value = records;
+		console.log(checked ? '勾选事件' : '取消事件', records);
+	}
+};
+const isChecked = computed(() => {
+	return !Boolean(checkTable.value.length);
+});
+const toolbarRef = ref<RefType>();
 // 页面加载时
 onMounted(() => {
 	queryList();
+	if (tableRef.value && toolbarRef.value) {
+		tableRef.value.connect(toolbarRef.value);
+	}
 });
 </script>
 <style scoped lang="scss">

+ 74 - 54
src/views/auxiliary/smartCallOut/components/Create-task.vue

@@ -48,45 +48,53 @@
 				</el-col>
 			</el-row>
 			<el-divider />
-			<ProTable
-				ref="proTableRef"
-				:columns="columns"
-				:data="state.tableData"
+			<div class="mb10">
+				<el-button type="primary" @click="addCitizen"> <SvgIcon name="ele-Plus" class="mr5" />添加市民 </el-button>
+				<el-upload
+					v-model:file-list="fileList"
+					action="#"
+					:multiple="false"
+					ref="uploadListRef"
+					name="file"
+					:http-request="importCitizen"
+					:show-file-list="false"
+					v-loading="state.loading"
+					class="upload-demo"
+				>
+					<el-button type="primary"> <SvgIcon name="ele-Upload" class="mr5" /> 导入市民 </el-button>
+				</el-upload>
+				<el-button type="primary" @click="temDownload"> <SvgIcon name="ele-Download" class="mr5" />模板下载 </el-button>
+				<el-button type="danger" @click="onDelete" :disabled="isChecked"> <SvgIcon name="ele-Delete" class="mr5" />批量删除 </el-button>
+				<el-button type="danger" @click="onClear"> <SvgIcon name="ele-CircleClose" class="mr5" /> 清空 </el-button>
+			</div>
+			<vxe-table
+				border
 				:loading="state.loading"
-				:pagination="false"
-				:tool-button="false"
-				max-height="400px"
-				row-key="id"
+				:data="state.tableData"
+				:column-config="{ resizable: true }"
+				:row-config="{ isCurrent: true, isHover: true, height: 30 }"
+				ref="tableRef"
+				show-overflow
+				:scrollY="{ enabled: true, gt: 0 }"
+				showHeaderOverflow
+				@checkbox-all="selectAllChangeEvent"
+				@checkbox-change="selectChangeEvent"
+				max-height="500"
 			>
-				<template #tableHeader="scope">
-					<el-button type="primary" @click="addCitizen"> <SvgIcon name="ele-Plus" class="mr5" />添加市民 </el-button>
-					<el-upload
-						v-model:file-list="fileList"
-						action="#"
-						:multiple="false"
-						ref="uploadListRef"
-						name="file"
-						:http-request="importCitizen"
-						:show-file-list="false"
-						v-loading="state.loading"
-						class="upload-demo"
-					>
-						<el-button type="primary"> <SvgIcon name="ele-Upload" class="mr5" /> 导入市民 </el-button>
-					</el-upload>
-					<el-button type="primary" @click="temDownload"> <SvgIcon name="ele-Download" class="mr5" />模板下载 </el-button>
-					<el-button type="primary" @click="onDelete" :disabled="!scope.isSelected"> <SvgIcon name="ele-Delete" class="mr5" />批量删除 </el-button>
-					<el-button type="primary" @click="onClear"> <SvgIcon name="ele-CircleClose" class="mr5" /> 清空 </el-button>
-				</template>
-				<!-- 表格操作 -->
-				<template #operation="{ row }">
-					<el-button link type="primary" @click="onDel(row)" title="删除"> 删除 </el-button>
-				</template>
-			</ProTable>
+				<vxe-column type="checkbox" width="60" align="center"></vxe-column>
+				<vxe-column field="name" title="市民姓名"></vxe-column>
+				<vxe-column field="phoneNum" title="联系电话"></vxe-column>
+				<vxe-column title="操作" fixed="right" width="90" align="center">
+					<template #default="{ row }">
+						<el-button link type="danger" @click="onDel(row)" title="删除"> 删除 </el-button>
+					</template>
+				</vxe-column>
+			</vxe-table>
 		</el-form>
 		<template #footer>
 			<span class="dialog-footer">
 				<el-button @click="closeDialog" class="default-button">取 消</el-button>
-				<el-button type="primary" @click="onSubmit(ruleFormRef)" :loading="loading" :disabled="!canChoose">确 定</el-button>
+				<el-button type="primary" @click="onSubmit(ruleFormRef)" :loading="loading" :disabled="isChecked">确 定</el-button>
 			</span>
 		</template>
 	</el-dialog>
@@ -149,18 +157,8 @@ const close = () => {
 	ruleFormRef.value?.resetFields();
 	ruleFormRef.value?.resetFields();
 	state.tableData = [];
+	checkTable.value = [];
 };
-// 表格配置项
-const proTableRef = ref<RefType>(); // 表格ref
-const canChoose = computed(() => {
-	return proTableRef.value?.selectedList.length;
-});
-const columns = ref<any[]>([
-	{ type: 'selection', fixed: 'left', width: 55, align: 'center' },
-	{ prop: 'name', label: '市民姓名' },
-	{ prop: 'phoneNum', label: '联系电话' },
-	{ prop: 'operation', label: '操作', fixed: 'right', width: 80, align: 'center' },
-]);
 // 添加市民
 const addCitizenRef = ref<RefType>();
 const addCitizen = () => {
@@ -223,12 +221,14 @@ const onDel = (row: any) => {
 			} else {
 				state.tableData = state.tableData.filter((item: any) => item.phoneNum !== row.phoneNum);
 			}
+			tableRef.value.clearCheckboxRow();
+			checkTable.value = [];
 		})
 		.catch(() => {});
 };
 // 批量删除市民
 const onDelete = () => {
-	ElMessageBox.confirm(`您确定要删除选择的【${proTableRef.value.selectedList.length}】个市民?`, '提示', {
+	ElMessageBox.confirm(`您确定要删除选中的市民?`, '提示', {
 		confirmButtonText: '确定',
 		cancelButtonText: '取消',
 		type: 'warning',
@@ -236,7 +236,9 @@ const onDelete = () => {
 		autofocus: false,
 	})
 		.then(() => {
-			state.tableData = state.tableData.filter((item: any) => !proTableRef.value.selectedList.includes(item));
+			state.tableData = state.tableData.filter((item: any) => !checkTable.value.includes(item));
+			tableRef.value.clearCheckboxRow();
+			checkTable.value = [];
 		})
 		.catch(() => {});
 };
@@ -250,23 +252,41 @@ const onClear = () => {
 		autofocus: false,
 	})
 		.then(() => {
-			proTableRef.value.clearSelection();
+			tableRef.value.clearCheckboxRow();
+			checkTable.value = [];
 			state.tableData = [];
 		})
 		.catch(() => {});
 };
+const tableRef = ref<RefType>();
+const checkTable = ref<EmptyArrayType>([]);
+const selectAllChangeEvent = ({ checked }) => {
+	if (tableRef.value) {
+		const records = tableRef.value.getCheckboxRecords();
+		checkTable.value = records;
+		console.log(checked ? '所有勾选事件' : '所有取消事件', records);
+	}
+};
+
+const selectChangeEvent = ({ checked }) => {
+	if (tableRef.value) {
+		const records = tableRef.value.getCheckboxRecords();
+		checkTable.value = records;
+		console.log(checked ? '勾选事件' : '取消事件', records);
+	}
+};
+const isChecked = computed(() => {
+	return !Boolean(checkTable.value.length);
+});
 // 添加市民后
 const selectCitizen = (data: any) => {
 	state.tableData = removeDuplicate([...state.tableData, ...data], 'phoneNum'); // 添加时去重
 	// 新添加的数据默认选中
 	nextTick(() => {
-		proTableRef.value.clearSelection();
-		const ids = data.map((item: any) => item.id);
-		state.tableData.forEach((row) => {
-			if (ids.includes(row.id)) {
-				proTableRef.value.element.toggleRowSelection(row, true);
-			}
-		});
+		if (tableRef.value) {
+			tableRef.value.setCheckboxRow(data, true);
+			checkTable.value = tableRef.value.getCheckboxRecords();
+		}
 	});
 };
 // 保存

+ 89 - 96
src/views/auxiliary/smartCallOut/components/Task-detail.vue

@@ -1,134 +1,127 @@
 <template>
-  <el-dialog v-model="state.dialogVisible" draggable title="外呼明细" destroy-on-close append-to-body @close="close">
-    <el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent>
-      <el-row :gutter="20">
-        <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
-          <el-form-item label="市民姓名" prop="Name">
-            <el-input v-model="state.queryParams.Name" placeholder="请填写市民姓名" clearable @keyup.enter="handleQuery" />
-          </el-form-item>
-        </el-col>
-        <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
-          <el-form-item label="联系电话" prop="OuterNo">
-            <el-input v-model="state.queryParams.OuterNo" placeholder="请填写市民联系电话" clearable @keyup.enter="handleQuery" />
-          </el-form-item>
-        </el-col>
-        <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
-          <el-form-item label="外呼状态" prop="AiCallOutState">
-            <el-select v-model="state.queryParams.AiCallOutState" placeholder="请选择外呼状态" @change="handleQuery" class="w100">
-              <el-option v-for="item in aiCallOutStateArr" :value="item.key" :key="item.key" :label="item.value" />
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
-          <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"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
-          </el-form-item>
-        </el-col>
-      </el-row>
-    </el-form>
-    <ProTable
-        ref="proTableRef"
-        :columns="columns"
-        :data="state.tableData"
-        :loading="state.loading"
-        :total="state.total"
-        v-model:page-index="state.queryParams.PageIndex"
-        v-model:page-size="state.queryParams.PageSize"
-        :tool-button="false"
-    >
-    </ProTable>
-    <template #footer>
+	<el-dialog v-model="state.dialogVisible" draggable title="外呼明细" destroy-on-close append-to-body @close="close">
+		<el-form :model="state.queryParams" ref="ruleFormRef" @submit.native.prevent inline>
+			<el-form-item label="市民姓名" prop="Name">
+				<el-input v-model="state.queryParams.Name" placeholder="请填写市民姓名" clearable @keyup.enter="handleQuery" class="keyword-input"/>
+			</el-form-item>
+			<el-form-item label="联系电话" prop="OuterNo">
+				<el-input v-model="state.queryParams.OuterNo" placeholder="请填写市民联系电话" clearable @keyup.enter="handleQuery"  class="keyword-input"/>
+			</el-form-item>
+			<el-form-item label="外呼状态" prop="AiCallOutState">
+				<el-select v-model="state.queryParams.AiCallOutState" placeholder="请选择外呼状态" @change="handleQuery" class="w100">
+					<el-option v-for="item in aiCallOutStateArr" :value="item.key" :key="item.key" :label="item.value" />
+				</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"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
+			</el-form-item>
+		</el-form>
+		<vxe-table
+			border
+			:loading="state.loading"
+			:data="state.tableData"
+			:column-config="{ resizable: true }"
+			:row-config="{ isCurrent: true, isHover: true, height: 30 }"
+			ref="tableRef"
+			show-overflow
+			:scrollY="{ enabled: true, gt: 0 }"
+			max-height="500px"
+		>
+			<vxe-column field="name" title="市民姓名"></vxe-column>
+			<vxe-column field="outerNo" title="联系电话"></vxe-column>
+			<vxe-column field="aiCallOutStateText" title="外呼状态"></vxe-column>
+		</vxe-table>
+		<pagination
+			@pagination="queryList"
+			:total="state.total"
+			v-model:current-page="state.queryParams.PageIndex"
+			v-model:page-size="state.queryParams.PageSize"
+			:disabled="state.loading"
+		/>
+		<template #footer>
 			<span class="dialog-footer">
 				<el-button @click="closeDialog" class="default-button">关 闭</el-button>
 			</span>
-    </template>
-  </el-dialog>
+		</template>
+	</el-dialog>
 </template>
 
 <script setup lang="tsx">
-import { reactive, ref } from 'vue';
+import { defineAsyncComponent, reactive, ref } from 'vue';
 import { FormInstance } from 'element-plus';
 import { smartCallOutTaskBaseData, smartCallOutTaskDetailList } from '@/api/auxiliary/smartCallOut';
-import { exportOrder } from '@/api/business/order';
-import { downloadFileByStream } from '@/utils/tools';
+
+const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
 
 // 定义变量内容
 const state = reactive<any>({
-  dialogVisible: false,
-  queryParams: {
-    // 查询参数
-    PageIndex: 1,
-    PageSize: 10,
-    OuterNo: null,
-    Name: null,
-    id: null,
-    AiCallOutState: null,
-  },
-  tableData: [],
+	dialogVisible: false,
+	queryParams: {
+		// 查询参数
+		PageIndex: 1,
+		PageSize: 10,
+		OuterNo: null,
+		Name: null,
+		id: null,
+		AiCallOutState: null,
+	},
+	total:0,
+	tableData: [],
 });
 const close = () => {
-  ruleFormRef.value?.clearValidate();
-  ruleFormRef.value?.resetFields();
+	ruleFormRef.value?.clearValidate();
+	ruleFormRef.value?.resetFields();
 };
 const ruleFormRef = ref<RefType>(null); // 表单ref
 /** 搜索按钮操作 */
 const handleQuery = () => {
-  state.queryParams.PageIndex = 1;
-  queryList();
+	state.queryParams.PageIndex = 1;
+	queryList();
 };
 // 获取列表
 const queryList = () => {
-  state.loading = true;
-  smartCallOutTaskDetailList(state.queryParams)
-      .then((res) => {
-        state.loading = false;
-        state.tableData = res.result.items ?? [];
-        state.total = res.result.total ?? 0;
-      })
-      .finally(() => {
-        state.loading = false;
-      });
+	state.loading = true;
+	smartCallOutTaskDetailList(state.queryParams)
+		.then((res) => {
+			state.loading = false;
+			state.tableData = res.result.items ?? [];
+			state.total = res.result.total ?? 0;
+		})
+		.finally(() => {
+			state.loading = false;
+		});
 };
 // 重置表单
 const resetQuery = (formEl: FormInstance | undefined) => {
-  if (!formEl) return;
-  formEl.resetFields();
-  queryList();
+	if (!formEl) return;
+	formEl.resetFields();
+	queryList();
 };
-const proTableRef = ref<RefType>(); // 表格ref
-// 表格配置项
-const columns = ref<any[]>([
-  { prop: 'name', label: '市民姓名' },
-  { prop: 'outerNo', label: '联系电话' },
-  { prop: 'aiCallOutStateText', label: '外呼状态' },
-]);
-
-let loading = ref<boolean>(false); // 加载状态
 // 获取基础数据
-const aiCallOutStateArr = ref([]);
+const aiCallOutStateArr = ref<EmptyArrayType>([]);
 const getBaseData = async () => {
-  try {
-    const { result } = await smartCallOutTaskBaseData();
-    aiCallOutStateArr.value = result.aiCallOutState;
-  } catch (e) {
-    console.log(e);
-  }
+	try {
+		const { result } = await smartCallOutTaskBaseData();
+		aiCallOutStateArr.value = result.aiCallOutState;
+	} catch (e) {
+		console.log(e);
+	}
 };
 // 打开弹窗
 const openDialog = async (row: any) => {
-  state.queryParams.id = row.id;
-  state.dialogVisible = true;
-  queryList();
-  await getBaseData();
+	state.queryParams.id = row.id;
+	state.dialogVisible = true;
+	queryList();
+	await getBaseData();
 };
 // 关闭弹窗
 const closeDialog = () => {
-  state.dialogVisible = false;
+	state.dialogVisible = false;
 };
 // 暴露变量
 defineExpose({
-  openDialog,
-  closeDialog,
+	openDialog,
+	closeDialog,
 });
 </script>

+ 124 - 83
src/views/auxiliary/smartCallOut/task.vue

@@ -1,93 +1,129 @@
 <template>
 	<div class="auxiliary-Smart-call-out-task-container layout-padding">
 		<div class="layout-padding-auto layout-padding-view pd20">
-			<ProTable
-				ref="proTableRef"
-				:columns="columns"
-				:data="state.tableData"
-				@updateTable="queryList"
+			<el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent>
+				<el-form-item label="任务名称" prop="TaskName">
+					<el-input v-model="state.queryParams.TaskName" placeholder="请填写任务名称" clearable @keyup.enter="handleQuery" class="keyword-input" />
+				</el-form-item>
+				<el-form-item label="任务状态" prop="AiCallOutTaskState">
+					<el-select v-model="state.queryParams.AiCallOutTaskState" placeholder="请选择任务状态" @change="handleQuery" clearable>
+						<el-option v-for="item in aiCallOutTaskState" :value="item.key" :key="item.key" :label="item.value" />
+					</el-select>
+				</el-form-item>
+				<el-form-item label="创建时间" prop="crTime">
+					<el-date-picker
+						v-model="state.queryParams.crTime"
+						type="datetimerange"
+						unlink-panels
+						range-separator="至"
+						start-placeholder="开始时间"
+						end-placeholder="结束时间"
+						:shortcuts="shortcuts"
+						@change="handleQuery"
+						value-format="YYYY-MM-DD[T]HH:mm:ss"
+						:default-time="defaultTimeStartEnd"
+					/>
+				</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"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
+				</el-form-item>
+			</el-form>
+			<vxe-toolbar
+				ref="toolbarRef"
 				:loading="state.loading"
-				:total="state.total"
-				v-model:page-index="state.queryParams.PageIndex"
-				v-model:page-size="state.queryParams.PageSize"
+				custom
+				:refresh="{
+					queryMethod: handleQuery,
+				}"
 			>
-				<template #table-search>
-					<el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent>
-						<el-form-item label="任务名称" prop="TaskName">
-							<el-input
-								v-model="state.queryParams.TaskName"
-								placeholder="请填写任务名称"
-								clearable
-								@keyup.enter="handleQuery"
-								class="keyword-input"
-							/>
-						</el-form-item>
-						<el-form-item label="任务状态" prop="AiCallOutTaskState">
-							<el-select v-model="state.queryParams.AiCallOutTaskState" placeholder="请选择任务状态" @change="handleQuery" clearable>
-								<el-option v-for="item in aiCallOutTaskState" :value="item.key" :key="item.key" :label="item.value" />
-							</el-select>
-						</el-form-item>
-						<el-form-item label="创建时间" prop="crTime">
-							<el-date-picker
-								v-model="state.queryParams.crTime"
-								type="datetimerange"
-								unlink-panels
-								range-separator="至"
-								start-placeholder="开始时间"
-								end-placeholder="结束时间"
-								:shortcuts="shortcuts"
-								@change="handleQuery"
-								value-format="YYYY-MM-DD[T]HH:mm:ss"
-								:default-time="defaultTimeStartEnd"
-							/>
-						</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"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
-						</el-form-item>
-					</el-form>
-				</template>
-				<template #tableHeader="scope">
+				<template #buttons>
 					<el-button type="primary" @click="addTask" v-auth="'auxiliary:smartCallOut:add'">
 						<SvgIcon name="ele-Plus" class="mr5" />创建任务
 					</el-button>
 				</template>
-				<!-- 表格操作 -->
-				<template #operation="{ row }">
-					<el-button link type="primary" @click="onDetail(row)" title="外呼明细"> 外呼明细 </el-button>
-					<!-- 已结束,已终止不能终止任务 其他状态都可以中止任务 -->
-					<el-button
-						link
-						type="primary"
-						@click="onEnd(row)"
-						v-auth="'auxiliary:smartCallOut:end'"
-						title="终止任务"
-						v-if="[5].includes(row.aiCallOutTaskState)"
-					>
-						终止任务
-					</el-button>
-					<el-button
-						link
-						type="primary"
-						v-if="[5].includes(row.aiCallOutTaskState)"
-						@click="onStart(row)"
-						title="启动任务"
-						v-auth="'auxiliary:smartCallOut:start'"
-					>
-						启动
-					</el-button>
-					<el-button
-						link
-						type="primary"
-						v-if="[1, 2].includes(row.aiCallOutTaskState)"
-						@click="onPause(row)"
-						title="暂停任务"
-						v-auth="'auxiliary:smartCallOut:pause'"
-					>
-						暂停
-					</el-button>
-				</template>
-			</ProTable>
+			</vxe-toolbar>
+			<div style="overflow: hidden; width: 100%; height: 100%; flex: 1">
+				<vxe-table
+					border
+					:loading="state.loading"
+					:data="state.tableData"
+					:column-config="{ resizable: true }"
+					:row-config="{ isCurrent: true, isHover: true, height: 30 }"
+					ref="tableRef"
+					height="auto"
+					auto-resize
+					show-overflow
+					:scrollY="{ enabled: true, gt: 0 }"
+					id="auxiliarySmartCallOutTask"
+					:custom-config="{ storage: true }"
+					showHeaderOverflow
+				>
+					<vxe-column field="taskName" title="市民姓名" min-width="200"></vxe-column>
+					<vxe-column field="aiCallOutTaskStateText" title="任务状态" width="110"></vxe-column>
+					<vxe-column field="hasVisitCount" title="外呼总量" width="120"></vxe-column>
+					<vxe-column field="beginTime" title="任务开始时间" width="160">
+						<template #default="{ row }">
+							{{ formatDate(row.beginTime, 'YYYY-mm-dd HH:MM:SS') }}
+						</template>
+					</vxe-column>
+					<vxe-column field="endTime" title="任务结束时间" width="160">
+						<template #default="{ row }">
+							{{ formatDate(row.endTime, 'YYYY-mm-dd HH:MM:SS') }}
+						</template>
+					</vxe-column>
+					<vxe-column field="creatorName" title="创建人" width="120"></vxe-column>
+					<vxe-column field="creatorOrgName" title="创建部门" width="140"></vxe-column>
+					<vxe-column field="creationTime" title="创建时间" width="160">
+						<template #default="{ row }">
+							{{ formatDate(row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}
+						</template>
+					</vxe-column>
+					<vxe-column title="操作" fixed="right" width="210" align="center">
+						<template #default="{ row }">
+							<el-button link type="primary" @click="onDetail(row)" title="外呼明细"> 外呼明细 </el-button>
+							<!-- 已结束,已终止不能终止任务 其他状态都可以中止任务 -->
+							<el-button
+								link
+								type="primary"
+								@click="onEnd(row)"
+								v-auth="'auxiliary:smartCallOut:end'"
+								title="终止任务"
+								v-if="[5].includes(row.aiCallOutTaskState)"
+							>
+								终止任务
+							</el-button>
+							<el-button
+								link
+								type="primary"
+								v-if="[5].includes(row.aiCallOutTaskState)"
+								@click="onStart(row)"
+								title="启动任务"
+								v-auth="'auxiliary:smartCallOut:start'"
+							>
+								启动
+							</el-button>
+							<el-button
+								link
+								type="primary"
+								v-if="[1, 2].includes(row.aiCallOutTaskState)"
+								@click="onPause(row)"
+								title="暂停任务"
+								v-auth="'auxiliary:smartCallOut:pause'"
+							>
+								暂停
+							</el-button>
+						</template>
+					</vxe-column>
+				</vxe-table>
+			</div>
+			<pagination
+				@pagination="queryList"
+				:total="state.total"
+				v-model:current-page="state.queryParams.PageIndex"
+				v-model:page-size="state.queryParams.PageSize"
+				:disabled="state.loading"
+			/>
 		</div>
 		<!-- 创建任务   -->
 		<create-task ref="createTaskRef" @updateList="queryList" />
@@ -112,6 +148,7 @@ import Other from '@/utils/other';
 // 引入组件
 const CreateTask = defineAsyncComponent(() => import('@/views/auxiliary/smartCallOut/components/Create-task.vue')); // 创建任务
 const TaskDetail = defineAsyncComponent(() => import('@/views/auxiliary/smartCallOut/components/Task-detail.vue')); // 任务详情
+const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
 
 const proTableRef = ref<RefType>(); // 表格ref
 // 表格配置项
@@ -292,10 +329,14 @@ const getBaseData = async () => {
 	} catch (e) {
 		console.log(e);
 	}
-};
+};const toolbarRef = ref<RefType>();
+const tableRef = ref<RefType>();
 // 页面加载时
 onMounted(() => {
-	getBaseData();
 	queryList();
+	if (tableRef.value && toolbarRef.value) {
+		tableRef.value.connect(toolbarRef.value);
+	}
+	getBaseData();
 });
 </script>

+ 95 - 89
src/views/auxiliary/smartCallOut/template.vue

@@ -1,58 +1,96 @@
 <template>
 	<div class="auxiliary-Smart-call-out-template-container layout-padding">
 		<div class="layout-padding-auto layout-padding-view pd20">
-			<ProTable
-				ref="proTableRef"
-				:columns="columns"
-				:data="state.tableData"
-				@updateTable="queryList"
+			<el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent>
+				<el-form-item label="模板标题" prop="TemplateName">
+					<el-input
+						v-model="state.queryParams.TemplateName"
+						placeholder="请填写模板标题"
+						clearable
+						@keyup.enter="handleQuery"
+						class="keyword-input"
+					/>
+				</el-form-item>
+				<el-form-item label="创建时间" prop="crTime">
+					<el-date-picker
+						v-model="state.queryParams.crTime"
+						type="datetimerange"
+						unlink-panels
+						range-separator="至"
+						start-placeholder="开始时间"
+						end-placeholder="结束时间"
+						:shortcuts="shortcuts"
+						@change="timeStartChangeCr"
+						value-format="YYYY-MM-DD[T]HH:mm:ss"
+						:default-time="defaultTimeStartEnd"
+					/>
+				</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"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
+				</el-form-item>
+			</el-form>
+			<vxe-toolbar
+				ref="toolbarRef"
 				:loading="state.loading"
-				:total="state.total"
-				v-model:page-index="state.queryParams.PageIndex"
-				v-model:page-size="state.queryParams.PageSize"
+				custom
+				:refresh="{
+					queryMethod: handleQuery,
+				}"
 			>
-        <template #table-search>
-          <el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent>
-            <el-form-item label="模板标题" prop="TemplateName">
-              <el-input
-                  v-model="state.queryParams.TemplateName"
-                  placeholder="请填写模板标题"
-                  clearable
-                  @keyup.enter="handleQuery"
-                  class="keyword-input"
-              />
-            </el-form-item>
-            <el-form-item label="创建时间" prop="crTime">
-              <el-date-picker
-                  v-model="state.queryParams.crTime"
-                  type="datetimerange"
-                  unlink-panels
-                  range-separator="至"
-                  start-placeholder="开始时间"
-                  end-placeholder="结束时间"
-                  :shortcuts="shortcuts"
-                  @change="timeStartChangeCr"
-                  value-format="YYYY-MM-DD[T]HH:mm:ss"
-                  :default-time="defaultTimeStartEnd"
-              />
-            </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"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
-            </el-form-item>
-          </el-form>
-        </template>
-				<template #tableHeader="scope">
+				<template #buttons>
 					<el-button type="primary" @click="onAdd" v-auth="'auxiliary:smartCallOut:tem:add'">
 						<SvgIcon name="ele-Plus" class="mr5" /> 新增模板
 					</el-button>
 				</template>
-				<!-- 表格操作 -->
-				<template #operation="{ row }">
-					<el-button link type="primary" @click="onEdit(row)" v-auth="'auxiliary:smartCallOut:tem:edit'" title="编辑模板"> 编辑 </el-button>
-					<el-button link type="primary" @click="onDelete(row)" v-auth="'auxiliary:smartCallOut:tem:delete'" title="删除模板"> 删除 </el-button>
-				</template>
-			</ProTable>
+			</vxe-toolbar>
+			<div style="overflow: hidden; width: 100%; height: 100%; flex: 1">
+				<vxe-table
+					border
+					:loading="state.loading"
+					:data="state.tableData"
+					:column-config="{ resizable: true, useKey: true }"
+					:row-config="{ isCurrent: true, isHover: true, useKey: true, height: 30 }"
+					ref="tableRef"
+					height="auto"
+					auto-resize
+					show-overflow
+					:scrollY="{ enabled: true, gt: 0 }"
+					id="auxiliarySmartCallOutTemplate"
+					:custom-config="{ storage: true }"
+				>
+					<vxe-column field="templateName" title="模板名称" min-width="150"></vxe-column>
+					<vxe-column field="callOutTaskCount" title="关联外呼任务" width="150"></vxe-column>
+					<vxe-column field="isEnable" title="是否启用" width="100">
+						<template #default="{ row }">
+							<template v-if="auth('quality:template:edit')">
+								<el-switch v-model="row.isEnable" active-text="启用" inactive-text="禁用" @change="changeIsEnable(row)" inline-prompt size="small" />
+							</template>
+							<span v-else>{{ row.isEnable ? '已启用' : '已禁用' }}</span>
+						</template>
+					</vxe-column>
+					<vxe-column field="creatorName" title="创建人" width="120"></vxe-column>
+					<vxe-column field="creatorOrgName" title="创建部门" width="140"></vxe-column>
+					<vxe-column field="creationTime" title="创建时间" width="160">
+						<template #default="{ row }">
+							{{ formatDate(row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}
+						</template>
+					</vxe-column>
+					<vxe-column title="操作" fixed="right" width="140" align="center">
+						<template #default="{ row }">
+							<el-button link type="primary" @click="onEdit(row)" v-auth="'auxiliary:smartCallOut:tem:edit'" title="编辑模板"> 编辑 </el-button>
+							<el-button link type="danger" @click="onDelete(row)" v-auth="'auxiliary:smartCallOut:tem:delete'" title="删除模板"> 删除 </el-button>
+						</template>
+					</vxe-column>
+				</vxe-table>
+			</div>
+			<pagination
+				@pagination="queryList"
+				:total="state.total"
+				v-model:current-page="state.queryParams.PageIndex"
+				v-model:page-size="state.queryParams.PageSize"
+				:disabled="state.loading"
+			/>
 		</div>
 		<!-- 新增模板   -->
 		<tem-add ref="temAddRef" @updateList="queryList" />
@@ -65,54 +103,16 @@
 import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
 import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
 import { formatDate } from '@/utils/formatTime';
-import { defaultTimeStartEnd, shortcuts } from "@/utils/constants";
+import { defaultTimeStartEnd, shortcuts } from '@/utils/constants';
 import { auth } from '@/utils/authFunction';
-import {  smartCallOutTemDelete, smartCallOutTemEnable, smartCallOutTemList } from '@/api/auxiliary/smartCallOut';
+import { smartCallOutTemDelete, smartCallOutTemEnable, smartCallOutTemList } from '@/api/auxiliary/smartCallOut';
 import other from '@/utils/other';
 
 // 引入组件
 const TemAdd = defineAsyncComponent(() => import('@/views/auxiliary/smartCallOut/components/Tem-add.vue')); // 新建模板
 const TemEdit = defineAsyncComponent(() => import('@/views/auxiliary/smartCallOut/components/Tem-edit.vue')); // 编辑标签
+const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
 
-const proTableRef = ref<RefType>(); // 表格ref
-// 表格配置项
-const columns = ref<any[]>([
-	{ prop: 'templateName', label: '模板名称',minWidth:150 },
-	{ prop: 'callOutTaskCount', label: '关联外呼任务' },
-	{
-		prop: 'isEnable',
-		label: '是否启用',
-		render: (scope) => {
-			return (
-				<>
-					{auth('quality:template:edit') ? (
-						<el-switch
-							model-value={scope.row.isEnable}
-							active-text="启用"
-							inactive-text="禁用"
-							onClick={() => changeIsEnable(scope.row)}
-							inline-prompt
-              size="small"
-						/>
-					) : (
-						<span>{scope.row.isEnable ? '启用' : '禁用'}</span>
-					)}
-				</>
-			);
-		},
-	},
-	{ prop: 'creatorName', label: '创建人',minWidth:120 },
-	{ prop: 'creatorOrgName', label: '创建部门',minWidth:150 },
-	{
-		prop: 'creationTime',
-		label: '创建时间',
-    minWidth: 170,
-		render: (scope) => {
-			return <span>{formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
-		},
-	},
-	{ prop: 'operation', label: '操作', fixed: 'right', width: 120, align: 'center' },
-]);
 // 定义变量内容
 const state = reactive({
 	loading: false, // 加载状态
@@ -189,13 +189,13 @@ const onDelete = (row: any) => {
 		type: 'warning',
 	})
 		.then(() => {
-			smartCallOutTemDelete( row.id)
+			smartCallOutTemDelete(row.id)
 				.then(() => {
 					ElMessage({
 						message: '操作成功',
 						type: 'success',
 					});
-          queryList();
+					queryList();
 					state.loading = false;
 				})
 				.catch(() => {})
@@ -207,6 +207,7 @@ const onDelete = (row: any) => {
 };
 // 启用和禁用
 const changeIsEnable = (row: any) => {
+	row.isEnable = !row.isEnable; //保持switch点击前的状态
 	ElMessageBox.confirm(`您确定要${row.isEnable ? '禁用' : '启用'}:【${row.templateName}】模板,是否继续?`, '提示', {
 		confirmButtonText: '确认',
 		cancelButtonText: '取消',
@@ -228,7 +229,12 @@ const changeIsEnable = (row: any) => {
 		.catch(() => {});
 };
 // 页面加载时
+const toolbarRef = ref<RefType>();
+const tableRef = ref<RefType>();
 onMounted(() => {
 	queryList();
+	if (tableRef.value && toolbarRef.value) {
+		tableRef.value.connect(toolbarRef.value);
+	}
 });
 </script>

+ 48 - 34
src/views/auxiliary/smsTask/components/Add-citizen.vue

@@ -12,22 +12,33 @@
 				<el-button @click="resetQuery(ruleFormRef)" class="default-button"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
 			</el-form-item>
 		</el-form>
-		<ProTable
-			ref="proTableRef"
-			:columns="columns"
-			:data="state.tableData"
+		<vxe-table
+			border
 			:loading="state.loading"
-			:total="state.total"
-			v-model:page-index="state.queryParams.PageIndex"
-			v-model:page-size="state.queryParams.PageSize"
-			:tool-button="false"
-			@updateTable="queryList"
+			:data="state.tableData"
+			:column-config="{ resizable: true }"
+			:row-config="{ isCurrent: true, isHover: true, height: 30 }"
+			ref="tableRef"
+			show-overflow
+			:scrollY="{ enabled: true, gt: 0 }"
+			showHeaderOverflow
+			@checkbox-all="selectAllChangeEvent"
+			@checkbox-change="selectChangeEvent"
+			max-height="500"
 		>
-		</ProTable>
+			<vxe-column type="checkbox" width="60" align="center"></vxe-column>
+			<vxe-column field="name" title="市民姓名"></vxe-column>
+			<vxe-column field="phoneNum" title="联系电话"></vxe-column>
+			<vxe-column field="creationTime" title="创建时间" width="160">
+				<template #default="{ row }">
+					{{ formatDate(row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}
+				</template>
+			</vxe-column>
+		</vxe-table>
 		<template #footer>
 			<span class="dialog-footer">
 				<el-button @click="closeDialog" class="default-button">取 消</el-button>
-				<el-button type="primary" @click="onSubmit" :loading="loading" :disabled="!canChoose">确 定</el-button>
+				<el-button type="primary" @click="onSubmit" :loading="loading" :disabled="isChecked">确 定</el-button>
 			</span>
 		</template>
 	</el-dialog>
@@ -37,7 +48,8 @@
 import { computed, onMounted, reactive, ref } from 'vue';
 import { FormInstance } from 'element-plus';
 import { externalCitizenList } from '@/api/auxiliary/externalCitizen';
-import { formatDate } from "@/utils/formatTime";
+import { formatDate } from '@/utils/formatTime';
+import { auth } from '@/utils/authFunction';
 
 // 定义子组件向父组件传值/事件
 const emit = defineEmits(['selectCitizen']);
@@ -49,8 +61,8 @@ const state = reactive<any>({
 		// 查询参数
 		PageIndex: 1,
 		PageSize: 10,
-    Name: null,
-    PhoneNum: null,
+		Name: null,
+		PhoneNum: null,
 	},
 	tableData: [],
 });
@@ -80,30 +92,12 @@ const resetQuery = (formEl: FormInstance | undefined) => {
 	formEl.resetFields();
 	queryList();
 };
-const proTableRef = ref<RefType>(); // 表格ref
-const canChoose = computed(() => {
-	return proTableRef.value?.selectedList.length;
-});
-// 表格配置项
-const columns = ref<any[]>([
-	{ type: 'selection', fixed: 'left', width: 55, align: 'center' },
-  { prop: 'name', label: '市民姓名' },
-  { prop: 'phoneNum', label: '联系电话' },
-  {
-    prop: 'creationTime',
-    label: '创建时间',
-    width: 170,
-    render: (scope: any) => {
-      return formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS');
-    },
-  },
-]);
 
 let loading = ref<Boolean>(false); // 加载状态
 // 打开弹窗
 const openDialog = async () => {
 	try {
-    queryList();
+		queryList();
 		state.dialogVisible = true;
 	} catch (error) {
 		console.log(error);
@@ -117,9 +111,29 @@ const close = () => {
 	ruleFormRef.value?.resetFields();
 	ruleFormRef.value?.resetFields();
 };
+const tableRef = ref<RefType>();
+const checkTable = ref<EmptyArrayType>([]);
+const selectAllChangeEvent = ({ checked }) => {
+	if (tableRef.value) {
+		const records = tableRef.value.getCheckboxRecords();
+		checkTable.value = records;
+		console.log(checked ? '所有勾选事件' : '所有取消事件', records);
+	}
+};
+
+const selectChangeEvent = ({ checked }) => {
+	if (tableRef.value) {
+		const records = tableRef.value.getCheckboxRecords();
+		checkTable.value = records;
+		console.log(checked ? '勾选事件' : '取消事件', records);
+	}
+};
+const isChecked = computed(() => {
+	return !Boolean(checkTable.value.length);
+});
 // 新增
 const onSubmit = () => {
-	emit('selectCitizen', proTableRef.value?.selectedList);
+	emit('selectCitizen', checkTable.value);
 	closeDialog();
 };
 // 暴露变量

+ 126 - 104
src/views/auxiliary/smsTask/components/Create-task.vue

@@ -15,7 +15,7 @@
 							placeholder="请选择计划发送时间"
 							class="w100"
 							value-format="YYYY-MM-DD[T]HH:mm:ss"
-              :disabled-date="disabledDate"
+							:disabled-date="disabledDate"
 						/>
 					</el-form-item>
 				</el-col>
@@ -26,45 +26,53 @@
 				</el-col>
 			</el-row>
 			<el-divider />
-			<ProTable
-				ref="proTableRef"
-				:columns="columns"
-				:data="state.tableData"
+			<div class="mb10">
+				<el-button type="primary" @click="addCitizen"> <SvgIcon name="ele-Plus" class="mr5" />添加市民 </el-button>
+				<el-upload
+					v-model:file-list="fileList"
+					action="#"
+					:multiple="false"
+					ref="uploadListRef"
+					name="file"
+					:http-request="importCitizen"
+					:show-file-list="false"
+					v-loading="state.loading"
+					class="upload-demo"
+				>
+					<el-button type="primary"> <SvgIcon name="ele-Upload" class="mr5" /> 导入市民 </el-button>
+				</el-upload>
+				<el-button type="primary" @click="temDownload"> <SvgIcon name="ele-Download" class="mr5" />模板下载 </el-button>
+				<el-button type="danger" @click="onDelete" :disabled="isChecked"> <SvgIcon name="ele-Delete" class="mr5" />批量删除 </el-button>
+				<el-button type="danger" @click="onClear"> <SvgIcon name="ele-CircleClose" class="mr5" /> 清空 </el-button>
+			</div>
+			<vxe-table
+				border
 				:loading="state.loading"
-				:pagination="false"
-				:tool-button="false"
-				max-height="400px"
-				row-key="id"
+				:data="state.tableData"
+				:column-config="{ resizable: true }"
+				:row-config="{ isCurrent: true, isHover: true, height: 30 }"
+				ref="tableRef"
+				show-overflow
+				:scrollY="{ enabled: true, gt: 0 }"
+				showHeaderOverflow
+				@checkbox-all="selectAllChangeEvent"
+				@checkbox-change="selectChangeEvent"
+				max-height="500"
 			>
-				<template #tableHeader="scope">
-					<el-button type="primary" @click="addCitizen"> <SvgIcon name="ele-Plus" class="mr5" />添加市民 </el-button>
-          <el-upload
-            v-model:file-list="fileList"
-            action="#"
-            :multiple="false"
-            ref="uploadListRef"
-            name="file"
-            :http-request="importCitizen"
-            :show-file-list="false"
-            v-loading="state.loading"
-            class="upload-demo"
-          >
-            <el-button type="primary"> <SvgIcon name="ele-Upload" class="mr5" /> 导入市民 </el-button>
-          </el-upload>
-					<el-button type="primary" @click="temDownload"> <SvgIcon name="ele-Download" class="mr5" />模板下载 </el-button>
-					<el-button type="primary" @click="onDelete" :disabled="!scope.isSelected"> <SvgIcon name="ele-Delete" class="mr5" />批量删除 </el-button>
-					<el-button type="primary" @click="onClear"> <SvgIcon name="ele-CircleClose" class="mr5" /> 清空 </el-button>
-				</template>
-				<!-- 表格操作 -->
-				<template #operation="{ row }">
-					<el-button link type="primary" @click="onDel(row)" title="删除"> 删除 </el-button>
-				</template>
-			</ProTable>
+				<vxe-column type="checkbox" width="60" align="center"></vxe-column>
+				<vxe-column field="name" title="市民姓名"></vxe-column>
+				<vxe-column field="phoneNum" title="联系电话"></vxe-column>
+				<vxe-column title="操作" fixed="right" width="90" align="center">
+					<template #default="{ row }">
+						<el-button link type="danger" @click="onDel(row)" title="删除"> 删除 </el-button>
+					</template>
+				</vxe-column>
+			</vxe-table>
 		</el-form>
 		<template #footer>
 			<span class="dialog-footer">
 				<el-button @click="closeDialog" class="default-button">取 消</el-button>
-				<el-button type="primary" @click="onSubmit(ruleFormRef)" :loading="loading" :disabled="!canChoose">确 定</el-button>
+				<el-button type="primary" @click="onSubmit(ruleFormRef)" :loading="loading" :disabled="isChecked">确 定</el-button>
 			</span>
 		</template>
 	</el-dialog>
@@ -72,11 +80,11 @@
 </template>
 
 <script setup lang="ts">
-import { computed, defineAsyncComponent, nextTick, reactive, ref } from 'vue';
+import { computed, defineAsyncComponent, nextTick, reactive, ref, watch } from 'vue';
 import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
-import { downloadFileByStream, throttle } from "@/utils/tools";
+import { downloadFileByStream, throttle } from '@/utils/tools';
 import { removeDuplicate } from '@/utils/arrayOperation';
-import { externalCitizenImport, externalCitizenTemplate } from "@/api/auxiliary/externalCitizen";
+import { externalCitizenImport, externalCitizenTemplate } from '@/api/auxiliary/externalCitizen';
 import { smartCallOutSmsAdd } from '@/api/auxiliary/smartCallOut';
 
 const CitizenAdd = defineAsyncComponent(() => import('@/views/auxiliary/smsTask/components/Add-citizen.vue')); // 创建任务
@@ -87,16 +95,16 @@ const emit = defineEmits(['updateList']);
 const state = reactive<any>({
 	dialogVisible: false,
 	ruleForm: {
-		taskName:null,
-		planSendTime:null,
-		content:null,
-		batchSmsTaskDetail:[]
+		taskName: null,
+		planSendTime: null,
+		content: null,
+		batchSmsTaskDetail: [],
 	},
 	tableData: [], // 表格内容
 });
 const disabledDate = (time: Date) => {
-  return time.getTime() < Date.now() - 8.64e7// - 8.64e7是今天可以选
-}
+	return time.getTime() < Date.now() - 8.64e7; // - 8.64e7是今天可以选
+};
 let loading = ref<boolean>(false); // 加载状态
 // 打开弹窗
 const ruleFormRef = ref<RefType>();
@@ -115,18 +123,9 @@ const closeDialog = () => {
 const close = () => {
 	ruleFormRef.value?.resetFields();
 	ruleFormRef.value?.resetFields();
+	state.tableData = [];
+	checkTable.value = [];
 };
-// 表格配置项
-const proTableRef = ref<RefType>(); // 表格ref
-const canChoose = computed(() => {
-	return proTableRef.value?.selectedList.length;
-});
-const columns = ref<any[]>([
-	{ type: 'selection', fixed: 'left', width: 55, align: 'center' },
-	{ prop: 'name', label: '市民姓名' },
-	{ prop: 'phoneNum', label: '联系电话' },
-	{ prop: 'operation', label: '操作', fixed: 'right', width: 80, align: 'center' },
-]);
 // 添加市民
 const addCitizenRef = ref<RefType>();
 const addCitizen = () => {
@@ -135,44 +134,44 @@ const addCitizen = () => {
 // 导入市民
 const fileList = ref<EmptyArrayType>([]);
 const uploadListRef = ref<RefType>(); // 上传组件ref
-const importCitizen = async (file:any) => {
-  state.loading = true;
-  let fileObj = file.file; // 相当于input里取得的files
-  let fd = new FormData(); // FormData 对象
-  fd.append('file', fileObj); // 文件对象
-  fd.append('needresult','true');
-  try {
-    const { result } = await externalCitizenImport(fd);
-    ElMessage.success('导入完成');
-    state.tableData = removeDuplicate([...state.tableData, ...result.resultList], 'phoneNum'); // 添加时去重
-    state.loading = false;
-  } catch (e) {
-    console.log(e);
-    state.loading = false;
-  }
+const importCitizen = async (file: any) => {
+	state.loading = true;
+	let fileObj = file.file; // 相当于input里取得的files
+	let fd = new FormData(); // FormData 对象
+	fd.append('file', fileObj); // 文件对象
+	fd.append('needresult', 'true');
+	try {
+		const { result } = await externalCitizenImport(fd);
+		ElMessage.success('导入完成');
+		state.tableData = removeDuplicate([...state.tableData, ...result.resultList], 'phoneNum'); // 添加时去重
+		state.loading = false;
+	} catch (e) {
+		console.log(e);
+		state.loading = false;
+	}
 };
 // 模板下载
 const temDownload = () => {
-  ElMessageBox.confirm(`您确定下载外部市民导入模板,是否继续?`, '提示', {
-    confirmButtonText: '确认',
-    cancelButtonText: '取消',
-    type: 'warning',
-    draggable: true,
-    cancelButtonClass: 'default-button',
-    autofocus: false,
-  })
-    .then(() => {
-      state.loading = true;
-      externalCitizenTemplate()
-        .then((res: any) => {
-          state.loading = false;
-          downloadFileByStream(res);
-        })
-        .catch(() => {
-          state.loading = false;
-        });
-    })
-    .catch(() => {});
+	ElMessageBox.confirm(`您确定下载外部市民导入模板,是否继续?`, '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+		draggable: true,
+		cancelButtonClass: 'default-button',
+		autofocus: false,
+	})
+		.then(() => {
+			state.loading = true;
+			externalCitizenTemplate()
+				.then((res: any) => {
+					state.loading = false;
+					downloadFileByStream(res);
+				})
+				.catch(() => {
+					state.loading = false;
+				});
+		})
+		.catch(() => {});
 };
 // 单个删除
 const onDel = (row: any) => {
@@ -189,12 +188,14 @@ const onDel = (row: any) => {
 			} else {
 				state.tableData = state.tableData.filter((item: any) => item.phoneNum !== row.phoneNum);
 			}
+			tableRef.value.clearCheckboxRow();
+			checkTable.value = [];
 		})
 		.catch(() => {});
 };
 // 批量删除市民
 const onDelete = () => {
-	ElMessageBox.confirm(`您确定要删除选择的【${proTableRef.value.selectedList.length}】个市民?`, '提示', {
+	ElMessageBox.confirm(`您确定要删除选中的市民?`, '提示', {
 		confirmButtonText: '确定',
 		cancelButtonText: '取消',
 		type: 'warning',
@@ -202,7 +203,9 @@ const onDelete = () => {
 		autofocus: false,
 	})
 		.then(() => {
-			state.tableData = state.tableData.filter((item: any) => !proTableRef.value.selectedList.includes(item));
+			state.tableData = state.tableData.filter((item: any) => !checkTable.value.includes(item));
+			tableRef.value.clearCheckboxRow();
+			checkTable.value = [];
 		})
 		.catch(() => {});
 };
@@ -216,23 +219,42 @@ const onClear = () => {
 		autofocus: false,
 	})
 		.then(() => {
-			proTableRef.value.clearSelection();
+			tableRef.value.clearCheckboxRow();
+			checkTable.value = [];
+
 			state.tableData = [];
 		})
 		.catch(() => {});
 };
+const tableRef = ref<RefType>();
+const checkTable = ref<EmptyArrayType>([]);
+const selectAllChangeEvent = ({ checked }) => {
+	if (tableRef.value) {
+		const records = tableRef.value.getCheckboxRecords();
+		checkTable.value = records;
+		console.log(checked ? '所有勾选事件' : '所有取消事件', records);
+	}
+};
+
+const selectChangeEvent = ({ checked }) => {
+	if (tableRef.value) {
+		const records = tableRef.value.getCheckboxRecords();
+		checkTable.value = records;
+		console.log(checked ? '勾选事件' : '取消事件', records);
+	}
+};
+const isChecked = computed(() => {
+	return !Boolean(checkTable.value.length);
+});
 // 添加市民后
 const selectCitizen = (data: any) => {
 	state.tableData = removeDuplicate([...state.tableData, ...data], 'phoneNum'); // 添加时去重
 	// 新添加的数据默认选中
 	nextTick(() => {
-		proTableRef.value.clearSelection();
-    const ids = data.map((item: any) => item.id);
-		state.tableData.forEach((row) => {
-			if (ids.includes(row.id)) {
-				proTableRef.value.element.toggleRowSelection(row, true);
-			}
-		});
+		if (tableRef.value) {
+			tableRef.value.setCheckboxRow(data, true);
+			checkTable.value = tableRef.value.getCheckboxRecords();
+		}
 	});
 };
 // 保存
@@ -243,7 +265,7 @@ const onSubmit = throttle(async (formEl: FormInstance | undefined) => {
 		loading.value = true;
 		const request = {
 			...state.ruleForm,
-			batchSmsTaskDetail:state.tableData
+			batchSmsTaskDetail: state.tableData,
 		};
 		smartCallOutSmsAdd(request)
 			.then(() => {
@@ -268,9 +290,9 @@ defineExpose({
 </script>
 <style scoped lang="scss">
 .upload-demo {
-  display: inline-flex;
-  vertical-align: middle;
-  margin-right: 12px;
-  margin-left: 12px;
+	display: inline-flex;
+	vertical-align: middle;
+	margin-right: 12px;
+	margin-left: 12px;
 }
 </style>

+ 23 - 16
src/views/auxiliary/smsTask/components/Task-detail.vue

@@ -12,25 +12,37 @@
 				<el-button @click="resetQuery(ruleFormRef)" class="default-button"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
 			</el-form-item>
 		</el-form>
-		<ProTable
-			ref="proTableRef"
-			:columns="columns"
-			:data="state.tableData"
+		<vxe-table
+			border
 			:loading="state.loading"
+			:data="state.tableData"
+			:column-config="{ resizable: true }"
+			:row-config="{ isCurrent: true, isHover: true, height: 30 }"
+			ref="tableRef"
+			show-overflow
+			:scrollY="{ enabled: true, gt: 0 }"
+			max-height="500px"
+		>
+			<vxe-column field="name" title="市民姓名"></vxe-column>
+			<vxe-column field="phoneNum" title="联系电话"></vxe-column>
+		</vxe-table>
+		<pagination
+			@pagination="queryList"
 			:total="state.total"
-			v-model:page-index="state.queryParams.PageIndex"
+			v-model:current-page="state.queryParams.PageIndex"
 			v-model:page-size="state.queryParams.PageSize"
-			:tool-button="false"
-		>
-		</ProTable>
+			:disabled="state.loading"
+		/>
 	</el-dialog>
 </template>
 
 <script setup lang="tsx">
-import { computed, reactive, ref } from 'vue';
+import { defineAsyncComponent, reactive, ref } from 'vue';
 import { FormInstance } from 'element-plus';
 import { smartCallOutSmsDetailQuery } from '@/api/auxiliary/smartCallOut';
 
+const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
+
 // 定义变量内容
 const state = reactive<any>({
 	dialogVisible: false,
@@ -41,6 +53,7 @@ const state = reactive<any>({
 		PhoneNumber: null,
 		Name: null,
 	},
+	total:0,
 	tableData: [],
 });
 
@@ -69,14 +82,8 @@ const resetQuery = (formEl: FormInstance | undefined) => {
 	formEl.resetFields();
 	queryList();
 };
-const proTableRef = ref<RefType>(); // 表格ref
-// 表格配置项
-const columns = ref<any[]>([
-	{ prop: 'phoneNum', label: '市民姓名' },
-	{ prop: 'name', label: '联系电话' },
-]);
 // 打开弹窗
-const openDialog = async (row:any) => {
+const openDialog = async (row: any) => {
 	try {
 		state.dialogVisible = true;
 		state.queryParams.id = row.id;

+ 93 - 75
src/views/auxiliary/smsTask/index.vue

@@ -1,54 +1,93 @@
 <template>
 	<div class="auxiliary-SMS-task-container layout-padding">
 		<div class="layout-padding-auto layout-padding-view pd20">
-			<ProTable
-				ref="proTableRef"
-				:columns="columns"
-				:data="state.tableData"
-				@updateTable="queryList"
+			<el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent>
+				<el-form-item label="任务名称" prop="TaskName">
+					<el-input v-model="state.queryParams.TaskName" placeholder="请填写任务名称" clearable @keyup.enter="handleQuery" class="keyword-input" />
+				</el-form-item>
+				<el-form-item label="任务状态" prop="State">
+					<el-select v-model="state.queryParams.State" placeholder="请选择任务状态" @change="handleQuery">
+						<el-option v-for="item in smsTaskState" :value="item.key" :key="item.key" :label="item.value" />
+					</el-select>
+				</el-form-item>
+				<el-form-item label="创建时间" prop="crTime">
+					<el-date-picker
+						v-model="state.queryParams.crTime"
+						type="datetimerange"
+						unlink-panels
+						range-separator="至"
+						start-placeholder="开始时间"
+						end-placeholder="结束时间"
+						:shortcuts="shortcuts"
+						@change="handleQuery"
+						value-format="YYYY-MM-DD[T]HH:mm:ss"
+						:default-time="defaultTimeStartEnd"
+					/>
+				</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"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
+				</el-form-item>
+			</el-form>
+			<vxe-toolbar
+				ref="toolbarRef"
 				:loading="state.loading"
-				:total="state.total"
-				v-model:page-index="state.queryParams.PageIndex"
-				v-model:page-size="state.queryParams.PageSize"
+				custom
+				:refresh="{
+					queryMethod: handleQuery
+				}"
 			>
-        <template #table-search>
-          <el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent>
-            <el-form-item label="任务名称" prop="TaskName">
-              <el-input v-model="state.queryParams.TaskName" placeholder="请填写任务名称" clearable @keyup.enter="handleQuery" class="keyword-input" />
-            </el-form-item>
-            <el-form-item label="任务状态" prop="State">
-              <el-select v-model="state.queryParams.State" placeholder="请选择任务状态" @change="handleQuery">
-                <el-option v-for="item in smsTaskState" :value="item.key" :key="item.key" :label="item.value" />
-              </el-select>
-            </el-form-item>
-            <el-form-item label="创建时间" prop="crTime">
-              <el-date-picker
-                  v-model="state.queryParams.crTime"
-                  type="datetimerange"
-                  unlink-panels
-                  range-separator="至"
-                  start-placeholder="开始时间"
-                  end-placeholder="结束时间"
-                  :shortcuts="shortcuts"
-                  @change="handleQuery"
-                  value-format="YYYY-MM-DD[T]HH:mm:ss"
-                  :default-time="defaultTimeStartEnd"
-              />
-            </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"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
-            </el-form-item>
-          </el-form>
-        </template>
-				<template #tableHeader="scope">
+				<template #buttons>
 					<el-button type="primary" @click="addTask" v-auth="'auxiliary:smsTask:add'"> <SvgIcon name="ele-Plus" class="mr5" />创建任务 </el-button>
 				</template>
-				<template #operation="{ row }">
-					<el-button link type="primary" @click="onDetail(row)" title="短信明细"> 短信明细 </el-button>
-					<el-button link type="primary" @click="onEnd(row)" v-auth="'auxiliary:smsTask:end'" title="终止任务" v-if="[0].includes(row.smsTaskState)"> 终止任务 </el-button>
-				</template>
-			</ProTable>
+			</vxe-toolbar>
+			<div style="overflow: hidden; width: 100%; height: 100%; flex: 1">
+				<vxe-table
+					border
+					:loading="state.loading"
+					:data="state.tableData"
+					:column-config="{ resizable: true }"
+					:row-config="{ isCurrent: true, isHover: true, height: 30 }"
+					ref="tableRef"
+					height="auto"
+					auto-resize
+					show-overflow
+					:scrollY="{ enabled: true, gt: 0 }"
+					id="auxiliarySmsTask"
+					:custom-config="{ storage: true }"
+					showHeaderOverflow
+				>
+					<vxe-column field="taskName" title="市民姓名" min-width="200"></vxe-column>
+					<vxe-column field="smsTaskStateText" title="任务状态" width="110"></vxe-column>
+					<vxe-column field="content" title="短信内容" min-width="200"></vxe-column>
+					<vxe-column field="smsCount" title="短信总量" width="110"></vxe-column>
+					<vxe-column field="planSendTime" title="计划发送时间" width="160">
+						<template #default="{ row }">
+							{{ formatDate(row.planSendTime, 'YYYY-mm-dd HH:MM:SS') }}
+						</template>
+					</vxe-column>
+					<vxe-column field="creatorName" title="创建人" width="120"></vxe-column>
+					<vxe-column field="creatorOrgName" title="创建部门" width="140"></vxe-column>
+					<vxe-column field="creationTime" title="创建时间" width="160">
+						<template #default="{ row }">
+							{{ formatDate(row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}
+						</template>
+					</vxe-column>
+					<vxe-column title="操作" fixed="right" width="160" align="center">
+						<template #default="{ row }">
+							<el-button link type="primary" @click="onDetail(row)" title="短信明细"> 短信明细 </el-button>
+							<el-button link type="primary" @click="onEnd(row)" v-auth="'auxiliary:smsTask:end'" title="终止任务" v-if="[0].includes(row.smsTaskState)"> 终止任务 </el-button>
+						</template>
+					</vxe-column>
+				</vxe-table>
+			</div>
+			<pagination
+				@pagination="queryList"
+				:total="state.total"
+				v-model:current-page="state.queryParams.PageIndex"
+				v-model:page-size="state.queryParams.PageSize"
+				:disabled="state.loading"
+			/>
 		</div>
 		<!-- 创建任务   -->
 		<create-task ref="createTaskRef" @updateList="queryList"/>
@@ -61,47 +100,21 @@ import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
 import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
 import { formatDate } from '@/utils/formatTime';
 import { defaultTimeStartEnd, shortcuts } from "@/utils/constants";
-import { smartCallOutSmsBaseData, smartCallOutSmsList, smartCallOutSmsStop, smartCallOutTaskStop } from '@/api/auxiliary/smartCallOut';
+import { smartCallOutSmsBaseData, smartCallOutSmsList, smartCallOutSmsStop } from '@/api/auxiliary/smartCallOut';
 import Other from '@/utils/other';
 
 // 引入组件
 const CreateTask = defineAsyncComponent(() => import('@/views/auxiliary/smsTask/components/Create-task.vue')); // 创建任务
 const TaskDetail = defineAsyncComponent(() => import('@/views/auxiliary/smsTask/components/Task-detail.vue')); // 任务详情
+const pagination = defineAsyncComponent(() => import('@/components/ProTable/components/Pagination.vue')); // 分页
 
-const proTableRef = ref<RefType>(); // 表格ref
-// 表格配置项
-const columns = ref<any[]>([
-	{ prop: 'taskName', label: '任务名称', minWidth: 200 },
-	{ prop: 'smsTaskStateText', label: '任务状态', width: 100 },
-	{ prop: 'content', label: '短信内容', minWidth: 200 },
-	{ prop: 'smsCount', label: '短信总量' },
-	{
-		prop: 'planSendTime',
-		label: '计划发送时间',
-		width: 170,
-		render: (scope) => {
-			return <span>{formatDate(scope.row.planSendTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
-		},
-	},
-	{ prop: 'creatorName', label: '创建人' },
-	{ prop: 'creatorOrgName', label: '创建部门' },
-	{
-		prop: 'creationTime',
-		label: '创建时间',
-		width: 170,
-		render: (scope) => {
-			return <span>{formatDate(scope.row.creationTime, 'YYYY-mm-dd HH:MM:SS')}</span>;
-		},
-	},
-	{ prop: 'operation', label: '操作', fixed: 'right', width: 160, align: 'center' },
-]);
 // 定义变量内容
 const state = reactive<any>({
 	loading: false, // 加载状态
 	queryParams: {
 		// 查询参数
 		PageIndex: 1,
-		PageSize: 20,
+		PageSize: 2,
 		State: null,
 		TaskName: null,
 		crTime: [],
@@ -172,16 +185,21 @@ const onEnd = (row: any) => {
 		})
 		.catch(() => {});
 };
-const smsTaskState = ref([]);
+const smsTaskState = ref<EmptyArrayType>([]);
 // 获取基础数据
 const getBaseData  = () => {
 	smartCallOutSmsBaseData().then((res) => {
 		smsTaskState.value = res.result?.smsTaskState ?? [];
 	});
 };
+const toolbarRef = ref<RefType>();
+const tableRef = ref<RefType>();
 // 页面加载时
 onMounted(() => {
-	getBaseData();
 	queryList();
+	if (tableRef.value && toolbarRef.value) {
+		tableRef.value.connect(toolbarRef.value);
+	}
+	getBaseData();
 });
 </script>