逻辑调整
This commit is contained in:
@@ -179,104 +179,6 @@
|
||||
</el-table>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 2. 适用范围配置 -->
|
||||
<el-tab-pane label="适用范围 (公司与岗位)" name="scopes">
|
||||
<div class="tab-pane-content">
|
||||
<el-card shadow="never" class="scope-add-card">
|
||||
<template #header>
|
||||
<span class="font-bold">为公司/岗位分配此合同模板</span>
|
||||
</template>
|
||||
<el-form :model="scopeForm" inline class="scope-inline-form">
|
||||
<el-form-item label="所属公司" required>
|
||||
<el-select
|
||||
v-model="scopeForm.companyId"
|
||||
placeholder="请选择公司"
|
||||
filterable
|
||||
style="width: 200px"
|
||||
@change="onScopeCompanyChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="company in companies"
|
||||
:key="company.id"
|
||||
:label="company.companyName"
|
||||
:value="company.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="适用岗位">
|
||||
<el-select
|
||||
v-model="scopeForm.positionId"
|
||||
placeholder="全公司所有岗位"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
>
|
||||
<el-option
|
||||
v-for="position in scopePositions"
|
||||
:key="position.id"
|
||||
:label="position.positionName"
|
||||
:value="position.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="绑定版本" required>
|
||||
<el-select
|
||||
v-model="scopeForm.templateVersionId"
|
||||
placeholder="请选择合同版本"
|
||||
style="width: 180px"
|
||||
>
|
||||
<el-option
|
||||
v-for="ver in enabledVersions"
|
||||
:key="ver.id"
|
||||
:label="`版本 ${ver.versionNo}`"
|
||||
:value="ver.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Plus" @click="saveScope">
|
||||
添加适用范围
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-table :data="scopes" border stripe class="mt-4">
|
||||
<el-table-column label="所属公司" min-width="180">
|
||||
<template #default="scope">
|
||||
<el-tag effect="plain" type="primary">
|
||||
{{ companyName(scope.row.companyId) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="适用岗位" min-width="180">
|
||||
<template #default="scope">
|
||||
{{ positionName(scope.row.positionId) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="生效版本" width="140" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag size="small" type="success">
|
||||
版本 {{ versionName(scope.row.templateVersionId) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" width="110" align="center">
|
||||
<template #default="scope">
|
||||
<el-button link type="danger" icon="Delete" @click="removeScope(scope.row)">
|
||||
移除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
|
||||
@@ -294,7 +196,7 @@
|
||||
append-to-body
|
||||
>
|
||||
<el-alert
|
||||
title="仅支持 .docx 文件。请在 Word 文档中使用 {{变量编码}}(如 {{EmployeeName}}、{{Salary}})作为占位符。"
|
||||
title="仅支持 .docx。占位符按来源编写:{{employee.EmployeeName}}、{{company.CompanyName}}、{{hr.MonthlySalary}}、{{system.SignDate}};保存版本时系统会自动识别。"
|
||||
type="info"
|
||||
:closable="false"
|
||||
style="margin-bottom: 16px"
|
||||
@@ -350,18 +252,12 @@
|
||||
destroy-on-close
|
||||
append-to-body
|
||||
>
|
||||
<div class="toolbar-flex">
|
||||
<el-button type="primary" icon="Plus" @click="openVariableCreate">
|
||||
新增变量定义
|
||||
</el-button>
|
||||
<el-alert
|
||||
title="在 DOCX 模板中使用 {{变量编码}} 作为占位符。点击变量编码旁复制按钮可直接复制占位符。"
|
||||
type="info"
|
||||
show-icon
|
||||
:closable="false"
|
||||
style="flex: 1; margin: 0 0 0 16px;"
|
||||
/>
|
||||
</div>
|
||||
<el-alert
|
||||
title="变量已从 DOCX 自动识别。请逐项检查来源、显示名称、数据类型和取值字段;未识别变量调整完成后才能启用版本。"
|
||||
type="info"
|
||||
show-icon
|
||||
:closable="false"
|
||||
/>
|
||||
|
||||
<el-table :data="variables" border stripe class="mt-3">
|
||||
<el-table-column prop="variableCode" label="变量编码 (DOCX占位符)" min-width="220">
|
||||
@@ -410,11 +306,7 @@
|
||||
<el-table-column label="操作" width="150" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" icon="Edit" @click="openVariableEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
|
||||
<el-button link type="danger" icon="Delete" @click="removeVariable(scope.row)">
|
||||
删除
|
||||
检查调整
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -424,14 +316,14 @@
|
||||
<!-- 新增 / 编辑单个变量 -->
|
||||
<el-dialog
|
||||
v-model="variableVisible"
|
||||
:title="variableEditing ? '编辑变量' : '新增变量'"
|
||||
title="检查并调整变量"
|
||||
width="640px"
|
||||
destroy-on-close
|
||||
append-to-body
|
||||
>
|
||||
<el-form :model="variableForm" label-width="130px">
|
||||
<el-form-item label="变量编码" required>
|
||||
<el-input v-model="variableForm.variableCode" placeholder="如:EMPLOYEE_NAME" />
|
||||
<el-input v-model="variableForm.variableCode" disabled />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="变量名称" required>
|
||||
@@ -456,7 +348,7 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="variableForm.variableType === 'employee'" label="员工字段">
|
||||
<el-form-item v-if="['employee', 'company'].includes(variableForm.variableType || '')" label="取值字段">
|
||||
<el-input v-model="variableForm.employeeField" placeholder="如:EmployeeName、IdCardNumber、Phone" />
|
||||
</el-form-item>
|
||||
|
||||
@@ -490,44 +382,30 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="onboardingContract">
|
||||
import { ref, reactive, computed, onMounted } from "vue";
|
||||
import { reactive, ref } from "vue";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { Plus, Edit, Delete, Files, Upload, Setting, Download, Check, CopyDocument } from "@element-plus/icons-vue";
|
||||
import { Check } from "@element-plus/icons-vue";
|
||||
import {
|
||||
onboardingTaskApi,
|
||||
type OnboardingCompanyOption,
|
||||
type OnboardingContractScope,
|
||||
type OnboardingContractTemplate,
|
||||
type OnboardingContractVersion,
|
||||
type OnboardingPositionOption,
|
||||
type OnboardingTemplateVariable
|
||||
} from "@/api/modules/biz/onboarding";
|
||||
import type { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
|
||||
|
||||
const templateTable = ref<ProTableInstance>();
|
||||
|
||||
const companies = ref<OnboardingCompanyOption[]>([]);
|
||||
const scopePositions = ref<OnboardingPositionOption[]>([]);
|
||||
|
||||
const selectedTemplate = ref<OnboardingContractTemplate>();
|
||||
const selectedVersion = ref<OnboardingContractVersion>();
|
||||
|
||||
const drawerVisible = ref(false);
|
||||
const drawerActiveTab = ref("versions");
|
||||
|
||||
const templateVisible = ref(false);
|
||||
const templateEditing = ref(false);
|
||||
|
||||
const versions = ref<OnboardingContractVersion[]>([]);
|
||||
const versionVisible = ref(false);
|
||||
|
||||
const variablesVisible = ref(false);
|
||||
const variableEditing = ref(false);
|
||||
const variables = ref<OnboardingTemplateVariable[]>([]);
|
||||
const variableVisible = ref(false);
|
||||
|
||||
const scopes = ref<OnboardingContractScope[]>([]);
|
||||
|
||||
const emptyTemplate = (): Partial<OnboardingContractTemplate> => ({
|
||||
templateCode: "",
|
||||
templateName: "",
|
||||
@@ -547,50 +425,24 @@ const emptyVersion = (): Partial<OnboardingContractVersion> => ({
|
||||
const emptyVariable = (): Partial<OnboardingTemplateVariable> => ({
|
||||
variableCode: "",
|
||||
variableName: "",
|
||||
variableType: "employee",
|
||||
variableType: "unresolved",
|
||||
dataType: "string",
|
||||
employeeField: "",
|
||||
defaultValue: "",
|
||||
sortCode: 10,
|
||||
required: true,
|
||||
hrEditable: true,
|
||||
hrEditable: false,
|
||||
remark: ""
|
||||
});
|
||||
|
||||
const emptyScope = (): Partial<OnboardingContractScope> => ({
|
||||
companyId: undefined,
|
||||
positionId: undefined,
|
||||
templateVersionId: undefined
|
||||
});
|
||||
|
||||
const templateForm = reactive<Partial<OnboardingContractTemplate>>(emptyTemplate());
|
||||
const versionForm = reactive<Partial<OnboardingContractVersion>>(emptyVersion());
|
||||
const variableForm = reactive<Partial<OnboardingTemplateVariable>>(emptyVariable());
|
||||
const scopeForm = reactive<Partial<OnboardingContractScope>>(emptyScope());
|
||||
|
||||
const enabledVersions = computed(() =>
|
||||
versions.value.filter(item => item.versionStatus === "enabled")
|
||||
);
|
||||
|
||||
const templateColumns: ColumnProps<OnboardingContractTemplate>[] = [
|
||||
{
|
||||
prop: "templateCode",
|
||||
label: "模板编码",
|
||||
minWidth: 160,
|
||||
search: { el: "input" }
|
||||
},
|
||||
{
|
||||
prop: "templateName",
|
||||
label: "模板名称",
|
||||
minWidth: 200,
|
||||
search: { el: "input" }
|
||||
},
|
||||
{
|
||||
prop: "contractType",
|
||||
label: "合同类型",
|
||||
width: 140,
|
||||
search: { el: "input" }
|
||||
},
|
||||
{ prop: "templateCode", label: "模板编码", minWidth: 160, search: { el: "input" } },
|
||||
{ prop: "templateName", label: "模板名称", minWidth: 200, search: { el: "input" } },
|
||||
{ prop: "contractType", label: "合同类型", width: 140, search: { el: "input" } },
|
||||
{
|
||||
prop: "status",
|
||||
label: "状态",
|
||||
@@ -602,24 +454,10 @@ const templateColumns: ColumnProps<OnboardingContractTemplate>[] = [
|
||||
],
|
||||
search: { el: "select" }
|
||||
},
|
||||
{
|
||||
prop: "description",
|
||||
label: "模板说明",
|
||||
minWidth: 200
|
||||
},
|
||||
{
|
||||
prop: "operation",
|
||||
label: "操作",
|
||||
fixed: "right",
|
||||
width: 260
|
||||
}
|
||||
{ prop: "description", label: "模板说明", minWidth: 200 },
|
||||
{ prop: "operation", label: "操作", fixed: "right", width: 260 }
|
||||
];
|
||||
|
||||
function formatTime(timeStr?: string) {
|
||||
if (!timeStr) return "-";
|
||||
return timeStr.replace("T", " ").substring(0, 19);
|
||||
}
|
||||
|
||||
function resetTemplate() {
|
||||
Object.assign(templateForm, emptyTemplate());
|
||||
}
|
||||
@@ -628,19 +466,6 @@ function resetVersion() {
|
||||
Object.assign(versionForm, emptyVersion());
|
||||
}
|
||||
|
||||
function resetVariable() {
|
||||
Object.assign(variableForm, emptyVariable());
|
||||
}
|
||||
|
||||
function resetScope() {
|
||||
Object.assign(scopeForm, emptyScope());
|
||||
}
|
||||
|
||||
async function loadCompanies() {
|
||||
const { data } = await onboardingTaskApi.listCompanies();
|
||||
companies.value = data;
|
||||
}
|
||||
|
||||
async function loadVersions() {
|
||||
if (!selectedTemplate.value) return;
|
||||
const { data } = await onboardingTaskApi.versionPage({
|
||||
@@ -648,7 +473,7 @@ async function loadVersions() {
|
||||
pageNum: 1,
|
||||
pageSize: 100
|
||||
});
|
||||
versions.value = data.list;
|
||||
versions.value = data?.list || [];
|
||||
}
|
||||
|
||||
async function loadVariables() {
|
||||
@@ -658,23 +483,13 @@ async function loadVariables() {
|
||||
pageNum: 1,
|
||||
pageSize: 100
|
||||
});
|
||||
variables.value = data.list;
|
||||
}
|
||||
|
||||
async function loadScopes() {
|
||||
if (!selectedTemplate.value) return;
|
||||
const { data } = await onboardingTaskApi.scopePage({
|
||||
templateId: selectedTemplate.value.id,
|
||||
pageNum: 1,
|
||||
pageSize: 100
|
||||
});
|
||||
scopes.value = data.list;
|
||||
variables.value = data?.list || [];
|
||||
}
|
||||
|
||||
async function openManagementDrawer(row: OnboardingContractTemplate) {
|
||||
selectedTemplate.value = row;
|
||||
drawerActiveTab.value = "versions";
|
||||
await Promise.all([loadVersions(), loadScopes()]);
|
||||
await loadVersions();
|
||||
drawerVisible.value = true;
|
||||
}
|
||||
|
||||
@@ -695,7 +510,6 @@ async function saveTemplate() {
|
||||
if (!templateForm.templateCode || !templateForm.templateName || !templateForm.contractType) {
|
||||
return ElMessage.warning("请填写模板编码、名称和合同类型");
|
||||
}
|
||||
|
||||
await onboardingTaskApi.saveTemplate(templateForm, templateEditing.value);
|
||||
templateVisible.value = false;
|
||||
templateTable.value?.refresh();
|
||||
@@ -723,10 +537,10 @@ function beforeDocxUpload(file: File) {
|
||||
}
|
||||
|
||||
async function uploadDocx(options: any) {
|
||||
const form = new FormData();
|
||||
form.append("file", options.file);
|
||||
const formData = new FormData();
|
||||
formData.append("file", options.file);
|
||||
try {
|
||||
const { data } = await onboardingTaskApi.uploadDocx(form);
|
||||
const { data } = await onboardingTaskApi.uploadDocx(formData);
|
||||
versionForm.sourceDocxFileId = data;
|
||||
options.onSuccess?.(data);
|
||||
ElMessage.success("DOCX 文件上传成功");
|
||||
@@ -737,17 +551,12 @@ async function uploadDocx(options: any) {
|
||||
|
||||
async function saveVersion() {
|
||||
if (!selectedTemplate.value || !versionForm.versionNo || !versionForm.sourceDocxFileId) {
|
||||
return ElMessage.warning("请填写版本号并上传DOCX文件");
|
||||
return ElMessage.warning("请填写版本号并上传 DOCX 文件");
|
||||
}
|
||||
|
||||
await onboardingTaskApi.addVersion({
|
||||
...versionForm,
|
||||
templateId: selectedTemplate.value.id
|
||||
});
|
||||
|
||||
await onboardingTaskApi.addVersion({ ...versionForm, templateId: selectedTemplate.value.id });
|
||||
versionVisible.value = false;
|
||||
await loadVersions();
|
||||
ElMessage.success("版本已保存");
|
||||
ElMessage.success("版本已保存,DOCX 变量已自动识别,请进入变量列表检查后再启用");
|
||||
}
|
||||
|
||||
async function changeVersionStatus(row: OnboardingContractVersion, status: string) {
|
||||
@@ -757,7 +566,7 @@ async function changeVersionStatus(row: OnboardingContractVersion, status: strin
|
||||
}
|
||||
|
||||
function downloadDocx(fileId?: number) {
|
||||
if (!fileId) return ElMessage.warning("暂无DOCX源文件");
|
||||
if (!fileId) return ElMessage.warning("暂无 DOCX 源文件");
|
||||
window.open(`/api/sys/dev/file/download?id=${fileId}`, "_blank");
|
||||
}
|
||||
|
||||
@@ -776,7 +585,8 @@ function variableTypeTag(type: string): EpTagType {
|
||||
employee: "primary",
|
||||
company: "success",
|
||||
contract: "warning",
|
||||
system: "info"
|
||||
system: "info",
|
||||
unresolved: "danger"
|
||||
};
|
||||
return map[type] || "info";
|
||||
}
|
||||
@@ -786,7 +596,8 @@ function variableTypeText(type: string) {
|
||||
employee: "员工填写",
|
||||
company: "公司信息",
|
||||
contract: "人事合同参数",
|
||||
system: "系统自动"
|
||||
system: "系统自动",
|
||||
unresolved: "待确认"
|
||||
};
|
||||
return map[type] || type;
|
||||
}
|
||||
@@ -806,87 +617,22 @@ async function openVariables(row: OnboardingContractVersion) {
|
||||
variablesVisible.value = true;
|
||||
}
|
||||
|
||||
function openVariableCreate() {
|
||||
variableEditing.value = false;
|
||||
resetVariable();
|
||||
variableVisible.value = true;
|
||||
}
|
||||
|
||||
function openVariableEdit(row: OnboardingTemplateVariable) {
|
||||
variableEditing.value = true;
|
||||
Object.assign(variableForm, row);
|
||||
Object.assign(variableForm, emptyVariable(), row);
|
||||
variableVisible.value = true;
|
||||
}
|
||||
|
||||
async function saveVariable() {
|
||||
if (
|
||||
!selectedVersion.value ||
|
||||
!variableForm.variableCode ||
|
||||
!variableForm.variableName ||
|
||||
!variableForm.variableType ||
|
||||
!variableForm.dataType
|
||||
) {
|
||||
return ElMessage.warning("请填写变量编码、名称、类型和数据类型");
|
||||
if (!selectedVersion.value || !variableForm.id || !variableForm.variableCode || !variableForm.variableName || !variableForm.variableType || !variableForm.dataType) {
|
||||
return ElMessage.warning("请完整确认变量名称、来源类型和数据类型");
|
||||
}
|
||||
|
||||
await onboardingTaskApi.saveVariable(
|
||||
{
|
||||
...variableForm,
|
||||
templateVersionId: selectedVersion.value.id
|
||||
},
|
||||
variableEditing.value
|
||||
await onboardingTaskApi.editVariable(
|
||||
{ ...variableForm, templateVersionId: selectedVersion.value.id }
|
||||
);
|
||||
|
||||
variableVisible.value = false;
|
||||
await loadVariables();
|
||||
ElMessage.success("变量已保存");
|
||||
ElMessage.success("变量已确认并保存");
|
||||
}
|
||||
|
||||
async function removeVariable(row: OnboardingTemplateVariable) {
|
||||
await ElMessageBox.confirm(`确认删除变量“${row.variableName}”?`, "删除确认", { type: "warning" });
|
||||
await onboardingTaskApi.deleteVariable([row.id]);
|
||||
await loadVariables();
|
||||
ElMessage.success("删除成功");
|
||||
}
|
||||
|
||||
async function onScopeCompanyChange(companyId: number) {
|
||||
scopeForm.positionId = undefined;
|
||||
const { data } = await onboardingTaskApi.listPositions(companyId);
|
||||
scopePositions.value = data;
|
||||
}
|
||||
|
||||
async function saveScope() {
|
||||
if (!selectedTemplate.value || !scopeForm.companyId || !scopeForm.templateVersionId) {
|
||||
return ElMessage.warning("请选择公司和已启用的合同版本");
|
||||
}
|
||||
|
||||
await onboardingTaskApi.addScope({
|
||||
...scopeForm,
|
||||
templateId: selectedTemplate.value.id
|
||||
});
|
||||
|
||||
await loadScopes();
|
||||
resetScope();
|
||||
ElMessage.success("适用范围已添加");
|
||||
}
|
||||
|
||||
async function removeScope(row: OnboardingContractScope) {
|
||||
await ElMessageBox.confirm("确认删除该适用范围?", "删除确认", { type: "warning" });
|
||||
await onboardingTaskApi.deleteScope([row.id]);
|
||||
await loadScopes();
|
||||
ElMessage.success("删除成功");
|
||||
}
|
||||
|
||||
const companyName = (id: number) => companies.value.find(c => c.id === id)?.companyName || id;
|
||||
|
||||
const positionName = (id?: number) => {
|
||||
if (!id) return "全公司 (所有岗位)";
|
||||
return scopePositions.value.find(p => p.id === id)?.positionName || id;
|
||||
};
|
||||
|
||||
const versionName = (id: number) => versions.value.find(v => v.id === id)?.versionNo || id;
|
||||
|
||||
onMounted(loadCompanies);
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user