完成招聘双Sheet导入改造
This commit is contained in:
@@ -99,25 +99,6 @@
|
||||
v-hasPermi="['ccdi:staffRecruitment:import']"
|
||||
>导入</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
v-if="isPreviewMode()"
|
||||
type="info"
|
||||
plain
|
||||
icon="el-icon-upload"
|
||||
size="mini"
|
||||
@click="handleWorkImport"
|
||||
>导入工作经历</el-button>
|
||||
<el-button
|
||||
v-else
|
||||
type="info"
|
||||
plain
|
||||
icon="el-icon-upload"
|
||||
size="mini"
|
||||
@click="handleWorkImport"
|
||||
v-hasPermi="['ccdi:staffRecruitment:import']"
|
||||
>导入工作经历</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5" v-if="showFailureButton">
|
||||
<el-tooltip
|
||||
:content="getLastImportTooltip()"
|
||||
@@ -570,33 +551,22 @@
|
||||
/>
|
||||
|
||||
<el-table :data="failureList" v-loading="failureLoading">
|
||||
<el-table-column label="失败Sheet" prop="sheetName" align="center" width="140">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.sheetName || "-" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="失败行号" prop="sheetRowNum" align="center" width="120">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.sheetRowNum ? `第${scope.row.sheetRowNum}行` : "-" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="招聘记录编号" prop="recruitId" align="center" width="150" />
|
||||
<el-table-column label="招聘项目名称" prop="recruitName" align="center" :show-overflow-tooltip="true"/>
|
||||
<el-table-column label="职位名称" prop="posName" align="center" :show-overflow-tooltip="true"/>
|
||||
<el-table-column label="候选人姓名" prop="candName" align="center" width="120"/>
|
||||
<el-table-column
|
||||
v-if="currentImportType !== 'work'"
|
||||
label="证件号码"
|
||||
prop="candId"
|
||||
align="center"
|
||||
width="180"
|
||||
/>
|
||||
<el-table-column
|
||||
v-if="currentImportType === 'work'"
|
||||
label="工作单位"
|
||||
prop="companyName"
|
||||
align="center"
|
||||
min-width="180"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
<el-table-column
|
||||
v-if="currentImportType === 'work'"
|
||||
label="岗位"
|
||||
prop="positionName"
|
||||
align="center"
|
||||
min-width="140"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
<el-table-column label="工作单位" prop="companyName" align="center" min-width="180" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="岗位" prop="positionName" align="center" min-width="140" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="失败原因" prop="errorMessage" align="center" min-width="200"
|
||||
:show-overflow-tooltip="true" />
|
||||
</el-table>
|
||||
@@ -845,11 +815,9 @@ export default {
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 导入类型
|
||||
importType: "recruitment",
|
||||
title: "招聘信息数据导入",
|
||||
// 弹窗提示
|
||||
tip: "仅允许导入\"xls\"或\"xlsx\"格式文件。",
|
||||
tip: "仅允许导入\"xls\"或\"xlsx\"格式文件。模板包含“招聘信息”和“历史工作经历”两个 Sheet。",
|
||||
// 是否禁用上传
|
||||
isUploading: false,
|
||||
// 设置上传的请求头部
|
||||
@@ -866,8 +834,6 @@ export default {
|
||||
showFailureButton: false,
|
||||
// 当前导入任务ID
|
||||
currentTaskId: null,
|
||||
// 当前导入类型
|
||||
currentImportType: "recruitment",
|
||||
// 失败记录对话框
|
||||
failureDialogVisible: false,
|
||||
failureList: [],
|
||||
@@ -886,7 +852,7 @@ export default {
|
||||
lastImportInfo() {
|
||||
const savedTask = this.getImportTaskFromStorage();
|
||||
if (savedTask && savedTask.totalCount) {
|
||||
return `导入类型: ${this.getImportTypeLabel(savedTask.importType || 'recruitment')} | 导入时间: ${this.parseTime(savedTask.saveTime)} | 总数: ${savedTask.totalCount}条 | 成功: ${savedTask.successCount}条 | 失败: ${savedTask.failureCount}条`;
|
||||
return `导入时间: ${this.parseTime(savedTask.saveTime)} | 总数: ${savedTask.totalCount}条 | 成功: ${savedTask.successCount}条 | 失败: ${savedTask.failureCount}条`;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
@@ -1163,9 +1129,7 @@ export default {
|
||||
this.handleDetail({ recruitId });
|
||||
} else if (mode === "edit") {
|
||||
this.handleUpdate({ recruitId });
|
||||
} else if (mode === "workImport") {
|
||||
this.handleWorkImport();
|
||||
} else if (mode === "import") {
|
||||
} else if (mode === "workImport" || mode === "import") {
|
||||
this.handleImport();
|
||||
} else if (mode === "add") {
|
||||
this.handleAdd();
|
||||
@@ -1236,24 +1200,13 @@ export default {
|
||||
},
|
||||
/** 导入按钮操作 */
|
||||
handleImport() {
|
||||
this.openImportDialog("recruitment");
|
||||
},
|
||||
/** 导入工作经历按钮操作 */
|
||||
handleWorkImport() {
|
||||
this.openImportDialog("work");
|
||||
this.openImportDialog();
|
||||
},
|
||||
/** 打开导入弹窗 */
|
||||
openImportDialog(importType) {
|
||||
const isWorkImport = importType === "work";
|
||||
this.upload.importType = importType;
|
||||
this.currentImportType = importType;
|
||||
this.upload.title = isWorkImport ? "历史工作经历数据导入" : "招聘信息数据导入";
|
||||
this.upload.url = process.env.VUE_APP_BASE_API + (isWorkImport
|
||||
? "/ccdi/staffRecruitment/importWorkData"
|
||||
: "/ccdi/staffRecruitment/importData");
|
||||
this.upload.tip = isWorkImport
|
||||
? "仅允许导入\"xls\"或\"xlsx\"格式文件;招聘记录编号用于匹配,姓名/项目/职位用于校验。"
|
||||
: "仅允许导入\"xls\"或\"xlsx\"格式文件。";
|
||||
openImportDialog() {
|
||||
this.upload.title = "招聘信息数据导入";
|
||||
this.upload.url = process.env.VUE_APP_BASE_API + "/ccdi/staffRecruitment/importData";
|
||||
this.upload.tip = "仅允许导入\"xls\"或\"xlsx\"格式文件。模板包含“招聘信息”和“历史工作经历”两个 Sheet。";
|
||||
if (this.isPreviewMode()) {
|
||||
this.upload.open = true;
|
||||
return;
|
||||
@@ -1262,11 +1215,7 @@ export default {
|
||||
},
|
||||
/** 下载模板操作 */
|
||||
importTemplate() {
|
||||
if (this.upload.importType === "work") {
|
||||
this.download('ccdi/staffRecruitment/workImportTemplate', {}, `历史工作经历导入模板_${new Date().getTime()}.xlsx`);
|
||||
return;
|
||||
}
|
||||
this.download('ccdi/staffRecruitment/importTemplate', {}, `招聘信息导入模板_${new Date().getTime()}.xlsx`);
|
||||
this.download('ccdi/staffRecruitment/importTemplate', {}, `招聘信息管理导入模板_${new Date().getTime()}.xlsx`);
|
||||
},
|
||||
// 文件上传中处理
|
||||
handleFileUploadProgress(event, file, fileList) {
|
||||
@@ -1301,19 +1250,17 @@ export default {
|
||||
taskId: taskId,
|
||||
status: 'PROCESSING',
|
||||
timestamp: Date.now(),
|
||||
hasFailures: false,
|
||||
importType: this.upload.importType
|
||||
hasFailures: false
|
||||
});
|
||||
|
||||
// 重置状态
|
||||
this.showFailureButton = false;
|
||||
this.currentTaskId = taskId;
|
||||
this.currentImportType = this.upload.importType;
|
||||
|
||||
// 显示后台处理提示
|
||||
this.$notify({
|
||||
title: '导入任务已提交',
|
||||
message: `${this.getImportTypeLabel(this.upload.importType)}正在后台处理中,处理完成后将通知您`,
|
||||
message: '招聘信息管理导入任务正在后台处理中,处理完成后将通知您',
|
||||
type: 'info',
|
||||
duration: 3000
|
||||
});
|
||||
@@ -1361,15 +1308,14 @@ export default {
|
||||
hasFailures: statusResult.failureCount > 0,
|
||||
totalCount: statusResult.totalCount,
|
||||
successCount: statusResult.successCount,
|
||||
failureCount: statusResult.failureCount,
|
||||
importType: this.currentImportType
|
||||
failureCount: statusResult.failureCount
|
||||
});
|
||||
|
||||
if (statusResult.status === 'SUCCESS') {
|
||||
// 全部成功
|
||||
this.$notify({
|
||||
title: '导入完成',
|
||||
message: `${this.getImportTypeLabel(this.currentImportType)}全部成功!共导入${statusResult.totalCount}条数据`,
|
||||
message: `招聘信息管理全部成功!共导入${statusResult.totalCount}条数据`,
|
||||
type: 'success',
|
||||
duration: 5000
|
||||
});
|
||||
@@ -1379,7 +1325,7 @@ export default {
|
||||
// 部分失败
|
||||
this.$notify({
|
||||
title: '导入完成',
|
||||
message: `${this.getImportTypeLabel(this.currentImportType)}成功${statusResult.successCount}条,失败${statusResult.failureCount}条`,
|
||||
message: `招聘信息管理成功${statusResult.successCount}条,失败${statusResult.failureCount}条`,
|
||||
type: 'warning',
|
||||
duration: 5000
|
||||
});
|
||||
@@ -1448,7 +1394,6 @@ export default {
|
||||
// 如果有失败记录,恢复按钮显示
|
||||
if (savedTask.hasFailures && savedTask.taskId) {
|
||||
this.currentTaskId = savedTask.taskId;
|
||||
this.currentImportType = savedTask.importType || "recruitment";
|
||||
this.showFailureButton = true;
|
||||
}
|
||||
},
|
||||
@@ -1458,7 +1403,7 @@ export default {
|
||||
if (savedTask && savedTask.saveTime) {
|
||||
const date = new Date(savedTask.saveTime);
|
||||
const timeStr = this.parseTime(date, '{y}-{m}-{d} {h}:{i}');
|
||||
return `上次${this.getImportTypeLabel(savedTask.importType || 'recruitment')}: ${timeStr}`;
|
||||
return `上次导入: ${timeStr}`;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
@@ -1538,7 +1483,7 @@ export default {
|
||||
// 提交上传文件
|
||||
submitFileForm() {
|
||||
if (this.isPreviewMode()) {
|
||||
this.$modal.msgSuccess(`预览模式:已模拟提交${this.getImportTypeLabel(this.upload.importType)}`);
|
||||
this.$modal.msgSuccess("预览模式:已模拟提交招聘信息管理导入");
|
||||
this.upload.open = false;
|
||||
return;
|
||||
}
|
||||
@@ -1548,10 +1493,6 @@ export default {
|
||||
handleImportDialogClose() {
|
||||
this.upload.isUploading = false;
|
||||
this.$refs.upload.clearFiles();
|
||||
},
|
||||
/** 导入类型展示 */
|
||||
getImportTypeLabel(importType) {
|
||||
return importType === "work" ? "历史工作经历导入" : "招聘信息导入";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
const assert = require("assert");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const componentPath = path.resolve(
|
||||
__dirname,
|
||||
"../../src/views/ccdiStaffRecruitment/index.vue"
|
||||
);
|
||||
const source = fs.readFileSync(componentPath, "utf8");
|
||||
|
||||
[
|
||||
'label="失败Sheet"',
|
||||
'label="失败行号"',
|
||||
"scope.row.sheetName",
|
||||
"scope.row.sheetRowNum",
|
||||
"失败原因"
|
||||
].forEach((token) => {
|
||||
assert(source.includes(token), `招聘失败弹窗缺少双Sheet定位列: ${token}`);
|
||||
});
|
||||
|
||||
console.log("staff-recruitment-import-failure-dialog test passed");
|
||||
28
ruoyi-ui/tests/unit/staff-recruitment-import-state.test.js
Normal file
28
ruoyi-ui/tests/unit/staff-recruitment-import-state.test.js
Normal file
@@ -0,0 +1,28 @@
|
||||
const assert = require("assert");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const componentPath = path.resolve(
|
||||
__dirname,
|
||||
"../../src/views/ccdiStaffRecruitment/index.vue"
|
||||
);
|
||||
const source = fs.readFileSync(componentPath, "utf8");
|
||||
|
||||
[
|
||||
"模板包含“招聘信息”和“历史工作经历”两个 Sheet。",
|
||||
"this.currentTaskId = taskId",
|
||||
"this.showFailureButton = false",
|
||||
"this.startImportStatusPolling(taskId)"
|
||||
].forEach((token) => {
|
||||
assert(source.includes(token), `招聘导入状态未统一到单任务: ${token}`);
|
||||
});
|
||||
|
||||
[
|
||||
"currentImportType",
|
||||
"upload.importType",
|
||||
"getImportTypeLabel"
|
||||
].forEach((token) => {
|
||||
assert(!source.includes(token), `招聘导入状态不应再按类型拆分: ${token}`);
|
||||
});
|
||||
|
||||
console.log("staff-recruitment-import-state test passed");
|
||||
34
ruoyi-ui/tests/unit/staff-recruitment-import-toolbar.test.js
Normal file
34
ruoyi-ui/tests/unit/staff-recruitment-import-toolbar.test.js
Normal file
@@ -0,0 +1,34 @@
|
||||
const assert = require("assert");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const pagePath = path.resolve(
|
||||
__dirname,
|
||||
"../../src/views/ccdiStaffRecruitment/index.vue"
|
||||
);
|
||||
const apiPath = path.resolve(
|
||||
__dirname,
|
||||
"../../src/api/ccdiStaffRecruitment.js"
|
||||
);
|
||||
|
||||
const pageSource = fs.readFileSync(pagePath, "utf8");
|
||||
const apiSource = fs.readFileSync(apiPath, "utf8");
|
||||
const source = `${pageSource}\n${apiSource}`;
|
||||
|
||||
[
|
||||
"handleImport()",
|
||||
'"/ccdi/staffRecruitment/importData"',
|
||||
"招聘信息管理导入模板"
|
||||
].forEach((token) => {
|
||||
assert(source.includes(token), `招聘导入入口缺少统一双Sheet能力: ${token}`);
|
||||
});
|
||||
|
||||
[
|
||||
"handleWorkImport",
|
||||
"importWorkData",
|
||||
"workImportTemplate"
|
||||
].forEach((token) => {
|
||||
assert(!source.includes(token), `招聘页不应继续保留独立工作经历导入: ${token}`);
|
||||
});
|
||||
|
||||
console.log("staff-recruitment-import-toolbar test passed");
|
||||
Reference in New Issue
Block a user