feat: 实现员工信息异步导入功能前端
- 添加导入状态查询API (getImportStatus) - 添加导入失败记录查询API (getImportFailures) - 实现导入状态轮询机制 (每2秒轮询一次) - 添加轮询定时器生命周期管理 (beforeDestroy销毁) - 添加导入完成通知功能 - 添加查看导入失败记录按钮 (有失败时显示) - 添加失败记录对话框及分页查询功能 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -59,3 +59,20 @@ export function importData(data, updateSupport) {
|
|||||||
data: data
|
data: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 查询导入状态
|
||||||
|
export function getImportStatus(taskId) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/employee/importStatus/' + taskId,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询导入失败记录
|
||||||
|
export function getImportFailures(taskId, pageNum, pageSize) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/employee/importFailures/' + taskId,
|
||||||
|
method: 'get',
|
||||||
|
params: { pageNum, pageSize }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -67,6 +67,15 @@
|
|||||||
v-hasPermi="['ccdi:employee:import']"
|
v-hasPermi="['ccdi:employee:import']"
|
||||||
>导入</el-button>
|
>导入</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="1.5" v-if="showFailureButton">
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="el-icon-warning"
|
||||||
|
size="mini"
|
||||||
|
@click="viewImportFailures"
|
||||||
|
>查看导入失败记录</el-button>
|
||||||
|
</el-col>
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
@@ -255,11 +264,39 @@
|
|||||||
title="导入结果"
|
title="导入结果"
|
||||||
@close="handleImportResultClose"
|
@close="handleImportResultClose"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- 导入失败记录对话框 -->
|
||||||
|
<el-dialog
|
||||||
|
title="导入失败记录"
|
||||||
|
:visible.sync="failureDialogVisible"
|
||||||
|
width="1200px"
|
||||||
|
append-to-body
|
||||||
|
>
|
||||||
|
<el-table :data="failureList" v-loading="failureLoading">
|
||||||
|
<el-table-column label="姓名" prop="name" align="center" />
|
||||||
|
<el-table-column label="柜员号" prop="employeeId" align="center" />
|
||||||
|
<el-table-column label="身份证号" prop="idCard" align="center" />
|
||||||
|
<el-table-column label="电话" prop="phone" align="center" />
|
||||||
|
<el-table-column label="失败原因" prop="errorMessage" align="center" min-width="200" :show-overflow-tooltip="true" />
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<pagination
|
||||||
|
v-show="failureTotal > 0"
|
||||||
|
:total="failureTotal"
|
||||||
|
:page.sync="failureQueryParams.pageNum"
|
||||||
|
:limit.sync="failureQueryParams.pageSize"
|
||||||
|
@pagination="getFailureList"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="failureDialogVisible = false">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {addEmployee, delEmployee, getEmployee, listEmployee, updateEmployee} from "@/api/ccdiEmployee";
|
import {addEmployee, delEmployee, getEmployee, listEmployee, updateEmployee, getImportStatus, getImportFailures} from "@/api/ccdiEmployee";
|
||||||
import {deptTreeSelect} from "@/api/system/user";
|
import {deptTreeSelect} from "@/api/system/user";
|
||||||
import {getToken} from "@/utils/auth";
|
import {getToken} from "@/utils/auth";
|
||||||
import Treeselect from "@riophae/vue-treeselect";
|
import Treeselect from "@riophae/vue-treeselect";
|
||||||
@@ -358,13 +395,35 @@ export default {
|
|||||||
},
|
},
|
||||||
// 导入结果弹窗
|
// 导入结果弹窗
|
||||||
importResultVisible: false,
|
importResultVisible: false,
|
||||||
importResultContent: ""
|
importResultContent: "",
|
||||||
|
// 轮询定时器
|
||||||
|
pollingTimer: null,
|
||||||
|
// 是否显示查看失败记录按钮
|
||||||
|
showFailureButton: false,
|
||||||
|
// 当前导入任务ID
|
||||||
|
currentTaskId: null,
|
||||||
|
// 失败记录对话框
|
||||||
|
failureDialogVisible: false,
|
||||||
|
failureList: [],
|
||||||
|
failureLoading: false,
|
||||||
|
failureTotal: 0,
|
||||||
|
failureQueryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10
|
||||||
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getList();
|
this.getList();
|
||||||
this.getDeptTree();
|
this.getDeptTree();
|
||||||
},
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
// 组件销毁时清除定时器
|
||||||
|
if (this.pollingTimer) {
|
||||||
|
clearInterval(this.pollingTimer);
|
||||||
|
this.pollingTimer = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/** 查询员工列表 */
|
/** 查询员工列表 */
|
||||||
getList() {
|
getList() {
|
||||||
@@ -512,16 +571,92 @@ export default {
|
|||||||
handleFileSuccess(response, file, fileList) {
|
handleFileSuccess(response, file, fileList) {
|
||||||
this.upload.isUploading = false;
|
this.upload.isUploading = false;
|
||||||
this.upload.open = false;
|
this.upload.open = false;
|
||||||
this.getList();
|
|
||||||
// 显示导入结果弹窗
|
if (response.code === 200) {
|
||||||
this.importResultContent = response.msg;
|
const taskId = response.data.taskId;
|
||||||
this.importResultVisible = true;
|
|
||||||
|
// 显示后台处理提示
|
||||||
|
this.$notify({
|
||||||
|
title: '导入任务已提交',
|
||||||
|
message: '正在后台处理中,处理完成后将通知您',
|
||||||
|
type: 'info',
|
||||||
|
duration: 3000
|
||||||
|
});
|
||||||
|
|
||||||
|
// 开始轮询检查状态
|
||||||
|
this.startImportStatusPolling(taskId);
|
||||||
|
} else {
|
||||||
|
this.$modal.msgError(response.msg);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
// 导入结果弹窗关闭
|
// 导入结果弹窗关闭
|
||||||
handleImportResultClose() {
|
handleImportResultClose() {
|
||||||
this.importResultVisible = false;
|
this.importResultVisible = false;
|
||||||
this.importResultContent = "";
|
this.importResultContent = "";
|
||||||
},
|
},
|
||||||
|
/** 开始轮询导入状态 */
|
||||||
|
startImportStatusPolling(taskId) {
|
||||||
|
this.pollingTimer = setInterval(async () => {
|
||||||
|
try {
|
||||||
|
const response = await getImportStatus(taskId);
|
||||||
|
|
||||||
|
if (response.data && response.data.status !== 'PROCESSING') {
|
||||||
|
clearInterval(this.pollingTimer);
|
||||||
|
this.handleImportComplete(response.data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
clearInterval(this.pollingTimer);
|
||||||
|
this.$modal.msgError('查询导入状态失败: ' + error.message);
|
||||||
|
}
|
||||||
|
}, 2000); // 每2秒轮询一次
|
||||||
|
},
|
||||||
|
/** 处理导入完成 */
|
||||||
|
handleImportComplete(statusResult) {
|
||||||
|
if (statusResult.status === 'SUCCESS') {
|
||||||
|
this.$notify({
|
||||||
|
title: '导入完成',
|
||||||
|
message: `全部成功!共导入${statusResult.totalCount}条数据`,
|
||||||
|
type: 'success',
|
||||||
|
duration: 5000
|
||||||
|
});
|
||||||
|
this.getList();
|
||||||
|
} else if (statusResult.failureCount > 0) {
|
||||||
|
this.$notify({
|
||||||
|
title: '导入完成',
|
||||||
|
message: `成功${statusResult.successCount}条,失败${statusResult.failureCount}条`,
|
||||||
|
type: 'warning',
|
||||||
|
duration: 5000
|
||||||
|
});
|
||||||
|
|
||||||
|
// 显示查看失败记录按钮
|
||||||
|
this.showFailureButton = true;
|
||||||
|
this.currentTaskId = statusResult.taskId;
|
||||||
|
|
||||||
|
// 刷新列表
|
||||||
|
this.getList();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 查看导入失败记录 */
|
||||||
|
viewImportFailures() {
|
||||||
|
this.failureDialogVisible = true;
|
||||||
|
this.getFailureList();
|
||||||
|
},
|
||||||
|
/** 查询失败记录列表 */
|
||||||
|
getFailureList() {
|
||||||
|
this.failureLoading = true;
|
||||||
|
getImportFailures(
|
||||||
|
this.currentTaskId,
|
||||||
|
this.failureQueryParams.pageNum,
|
||||||
|
this.failureQueryParams.pageSize
|
||||||
|
).then(response => {
|
||||||
|
this.failureList = response.rows;
|
||||||
|
this.failureTotal = response.total;
|
||||||
|
this.failureLoading = false;
|
||||||
|
}).catch(error => {
|
||||||
|
this.failureLoading = false;
|
||||||
|
this.$modal.msgError('查询失败记录失败: ' + error.message);
|
||||||
|
});
|
||||||
|
},
|
||||||
// 提交上传文件
|
// 提交上传文件
|
||||||
submitFileForm() {
|
submitFileForm() {
|
||||||
this.$refs.upload.submit();
|
this.$refs.upload.submit();
|
||||||
|
|||||||
Reference in New Issue
Block a user