|
@@ -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>
|