1111
This commit is contained in:
+2
-2
@@ -25,10 +25,10 @@ VITE_PWA = true
|
|||||||
VITE_HTTP_PROXY = true
|
VITE_HTTP_PROXY = true
|
||||||
|
|
||||||
# 线上环境接口地址
|
# 线上环境接口地址
|
||||||
VITE_API_URL = http://medical.23544.com:7106/
|
VITE_API_URL = https://onboardx-api.cnzhyx.cn/
|
||||||
|
|
||||||
# 开发环境跨域代理,支持配置多个
|
# 开发环境跨域代理,支持配置多个
|
||||||
VITE_PROXY = [["/api","http://medical.23544.com:7106/"]]
|
VITE_PROXY = [["/api","https://onboardx-api.cnzhyx.cn/"]]
|
||||||
|
|
||||||
#是否启用mqtt
|
#是否启用mqtt
|
||||||
VITE_MQTT = false
|
VITE_MQTT = false
|
||||||
|
|||||||
@@ -145,13 +145,15 @@ export interface OnboardingEmployee {
|
|||||||
employeeNo?: string;
|
employeeNo?: string;
|
||||||
employeeName: string;
|
employeeName: string;
|
||||||
companyId: number;
|
companyId: number;
|
||||||
|
companyName?: string;
|
||||||
departmentId?: number;
|
departmentId?: number;
|
||||||
departmentName?: string;
|
departmentName?: string;
|
||||||
positionId: number;
|
positionId: number;
|
||||||
|
positionName?: string;
|
||||||
phone: string;
|
phone: string;
|
||||||
idCardNumber: string;
|
idCardNumber: string;
|
||||||
entryDate?: string;
|
entryDate?: string;
|
||||||
createTime: string;
|
createTime?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OnboardingFormField {
|
export interface OnboardingFormField {
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
<div class="table-box">
|
<div class="table-box">
|
||||||
<ProTable
|
<ProTable
|
||||||
ref="templateTable"
|
ref="templateTable"
|
||||||
title="合同模板列表"
|
title="签署材料模板列表"
|
||||||
:columns="templateColumns"
|
:columns="templateColumns"
|
||||||
:request-api="onboardingTaskApi.templatePage"
|
:request-api="onboardingTaskApi.templatePage"
|
||||||
>
|
>
|
||||||
<template #tableHeader>
|
<template #tableHeader>
|
||||||
<el-button type="primary" icon="Plus" @click="openTemplateCreate">
|
<el-button type="primary" icon="Plus" @click="openTemplateCreate">
|
||||||
新增合同模板
|
新增签署材料模板
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -60,10 +60,10 @@
|
|||||||
</template>
|
</template>
|
||||||
</ProTable>
|
</ProTable>
|
||||||
|
|
||||||
<!-- 新增 / 编辑合同模板基础信息弹窗 -->
|
<!-- 新增 / 编辑签署材料模板基础信息弹窗 -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="templateVisible"
|
v-model="templateVisible"
|
||||||
:title="templateEditing ? '编辑合同模板' : '新增合同模板'"
|
:title="templateEditing ? '编辑签署材料模板' : '新增签署材料模板'"
|
||||||
width="720px"
|
width="720px"
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
append-to-body
|
append-to-body
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
collapse-tags
|
collapse-tags
|
||||||
collapse-tags-tooltip
|
collapse-tags-tooltip
|
||||||
class="w-full"
|
class="w-full"
|
||||||
placeholder="请选择该合同可适用的岗位"
|
placeholder="请选择该签署材料可适用的岗位"
|
||||||
:disabled="!templateForm.departmentId"
|
:disabled="!templateForm.departmentId"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
@@ -132,7 +132,7 @@
|
|||||||
<el-input v-model="templateForm.templateName" placeholder="如:标准全职劳动合同" />
|
<el-input v-model="templateForm.templateName" placeholder="如:标准全职劳动合同" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="合同类型" required>
|
<el-form-item label="材料类型" required>
|
||||||
<el-input v-model="templateForm.contractType" placeholder="如:劳动合同、保密协议、竞业协议" />
|
<el-input v-model="templateForm.contractType" placeholder="如:劳动合同、保密协议、竞业协议" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="模板说明">
|
<el-form-item label="模板说明">
|
||||||
<el-input v-model="templateForm.description" type="textarea" :rows="3" placeholder="合同模板适用说明或签署注意事项" />
|
<el-input v-model="templateForm.description" type="textarea" :rows="3" placeholder="签署材料模板适用说明或签署注意事项" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
@@ -154,10 +154,10 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 一站式合同版本与配置大抽屉 -->
|
<!-- 一站式签署材料版本与配置大抽屉 -->
|
||||||
<el-drawer
|
<el-drawer
|
||||||
v-model="drawerVisible"
|
v-model="drawerVisible"
|
||||||
:title="`合同模板管理 · ${selectedTemplate?.templateName || ''}`"
|
:title="`签署材料模板管理 · ${selectedTemplate?.templateName || ''}`"
|
||||||
size="1150px"
|
size="1150px"
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
>
|
>
|
||||||
@@ -188,7 +188,7 @@
|
|||||||
上传新版本 DOCX
|
上传新版本 DOCX
|
||||||
</el-button>
|
</el-button>
|
||||||
<span class="pane-tip-text">
|
<span class="pane-tip-text">
|
||||||
支持多版本迭代。启用某个版本后,该版本的 DOCX 将用于生成新入职员工的合同。
|
支持多版本迭代。启用某个版本后,该版本的 DOCX 将用于生成新入职员工的签署材料。
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -274,7 +274,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
|
|
||||||
<!-- 上传合同 DOCX 版本弹窗 -->
|
<!-- 上传签署材料 DOCX 版本弹窗 -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="versionVisible"
|
v-model="versionVisible"
|
||||||
title="上传新版本 DOCX"
|
title="上传新版本 DOCX"
|
||||||
@@ -334,7 +334,7 @@
|
|||||||
<!-- 变量配置弹窗 -->
|
<!-- 变量配置弹窗 -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="variablesVisible"
|
v-model="variablesVisible"
|
||||||
:title="`合同变量配置 · 版本 ${selectedVersion?.versionNo || ''}`"
|
:title="`签署材料变量配置 · 版本 ${selectedVersion?.versionNo || ''}`"
|
||||||
width="1220px"
|
width="1220px"
|
||||||
top="4vh"
|
top="4vh"
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
@@ -353,7 +353,7 @@
|
|||||||
<el-tabs v-model="variableTab" type="card" class="variable-filter-tabs">
|
<el-tabs v-model="variableTab" type="card" class="variable-filter-tabs">
|
||||||
<el-tab-pane :label="`全部变量 (${variableCounts.all})`" name="all" />
|
<el-tab-pane :label="`全部变量 (${variableCounts.all})`" name="all" />
|
||||||
<el-tab-pane :label="`员工填写 (${variableCounts.employee})`" name="employee" />
|
<el-tab-pane :label="`员工填写 (${variableCounts.employee})`" name="employee" />
|
||||||
<el-tab-pane :label="`人事合同参数 (${variableCounts.hr})`" name="hr" />
|
<el-tab-pane :label="`人事预设参数 (${variableCounts.hr})`" name="hr" />
|
||||||
<el-tab-pane :label="`公司信息 (${variableCounts.company})`" name="company" />
|
<el-tab-pane :label="`公司信息 (${variableCounts.company})`" name="company" />
|
||||||
<el-tab-pane :label="`系统预置 (${variableCounts.system})`" name="system" />
|
<el-tab-pane :label="`系统预置 (${variableCounts.system})`" name="system" />
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
@@ -439,7 +439,7 @@
|
|||||||
<el-select v-model="variableForm.variableType" class="w-full">
|
<el-select v-model="variableForm.variableType" class="w-full">
|
||||||
<el-option label="员工填写(从新员工基本信息/动态字段读取)" value="employee" />
|
<el-option label="员工填写(从新员工基本信息/动态字段读取)" value="employee" />
|
||||||
<el-option label="公司信息(从公司档案自动读取)" value="company" />
|
<el-option label="公司信息(从公司档案自动读取)" value="company" />
|
||||||
<el-option label="合同/人事填写(人事发起时录入)" value="contract" />
|
<el-option label="人事预设填写(人事发起时录入)" value="contract" />
|
||||||
<el-option label="系统生成(签署日期等)" value="system" />
|
<el-option label="系统生成(签署日期等)" value="system" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -630,7 +630,7 @@ const templateColumns: ColumnProps<OnboardingContractTemplate>[] = [
|
|||||||
},
|
},
|
||||||
{ prop: "templateCode", label: "模板编码", minWidth: 160, search: { el: "input" } },
|
{ prop: "templateCode", label: "模板编码", minWidth: 160, search: { el: "input" } },
|
||||||
{ prop: "templateName", label: "模板名称", minWidth: 200, search: { el: "input" } },
|
{ prop: "templateName", label: "模板名称", minWidth: 200, search: { el: "input" } },
|
||||||
{ prop: "contractType", label: "合同类型", width: 140, search: { el: "input" } },
|
{ prop: "contractType", label: "材料类型", width: 140, search: { el: "input" } },
|
||||||
{
|
{
|
||||||
prop: "status",
|
prop: "status",
|
||||||
label: "状态",
|
label: "状态",
|
||||||
@@ -738,7 +738,7 @@ async function saveTemplate() {
|
|||||||
|| !templateForm.templateName
|
|| !templateForm.templateName
|
||||||
|| !templateForm.contractType
|
|| !templateForm.contractType
|
||||||
) {
|
) {
|
||||||
return ElMessage.warning("请完整填写公司、部门、适用岗位及合同模板基本信息");
|
return ElMessage.warning("请完整填写公司、部门、适用岗位及签署材料模板基本信息");
|
||||||
}
|
}
|
||||||
await onboardingTaskApi.saveTemplate(templateForm, templateEditing.value);
|
await onboardingTaskApi.saveTemplate(templateForm, templateEditing.value);
|
||||||
templateVisible.value = false;
|
templateVisible.value = false;
|
||||||
@@ -747,7 +747,7 @@ async function saveTemplate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function removeTemplate(row: OnboardingContractTemplate) {
|
async function removeTemplate(row: OnboardingContractTemplate) {
|
||||||
await ElMessageBox.confirm(`确认删除合同模板“${row.templateName}”?`, "删除确认", { type: "warning" });
|
await ElMessageBox.confirm(`确认删除签署材料模板“${row.templateName}”?`, "删除确认", { type: "warning" });
|
||||||
await onboardingTaskApi.deleteTemplate([row.id]);
|
await onboardingTaskApi.deleteTemplate([row.id]);
|
||||||
templateTable.value?.refresh();
|
templateTable.value?.refresh();
|
||||||
ElMessage.success("删除成功");
|
ElMessage.success("删除成功");
|
||||||
@@ -760,7 +760,7 @@ function openVersionCreate() {
|
|||||||
|
|
||||||
function beforeDocxUpload(file: File) {
|
function beforeDocxUpload(file: File) {
|
||||||
if (!file.name.toLowerCase().endsWith(".docx")) {
|
if (!file.name.toLowerCase().endsWith(".docx")) {
|
||||||
ElMessage.error("合同模板仅支持 DOCX 文件");
|
ElMessage.error("签署材料模板仅支持 DOCX 文件");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -796,7 +796,7 @@ async function changeVersionStatus(row: OnboardingContractVersion, status: strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function removeVersion(row: OnboardingContractVersion) {
|
async function removeVersion(row: OnboardingContractVersion) {
|
||||||
await ElMessageBox.confirm(`确认删除合同版本“${row.versionNo}”?此操作不可撤销。`, "删除确认", { type: "warning" });
|
await ElMessageBox.confirm(`确认删除签署材料版本“${row.versionNo}”?此操作不可撤销。`, "删除确认", { type: "warning" });
|
||||||
await onboardingTaskApi.deleteVersion(row.id);
|
await onboardingTaskApi.deleteVersion(row.id);
|
||||||
await loadVersions();
|
await loadVersions();
|
||||||
ElMessage.success("版本删除成功");
|
ElMessage.success("版本删除成功");
|
||||||
@@ -819,7 +819,7 @@ async function downloadDocx(fileId?: number) {
|
|||||||
const encodedName =
|
const encodedName =
|
||||||
disposition.match(/filename\*=UTF-8\'\'([^;]+)/i)?.[1] ||
|
disposition.match(/filename\*=UTF-8\'\'([^;]+)/i)?.[1] ||
|
||||||
disposition.match(/filename="?([^";]+)"?/i)?.[1];
|
disposition.match(/filename="?([^";]+)"?/i)?.[1];
|
||||||
let fileName = "合同模板.docx";
|
let fileName = "签署材料模板.docx";
|
||||||
if (encodedName) {
|
if (encodedName) {
|
||||||
try {
|
try {
|
||||||
fileName = decodeURIComponent(encodedName.replace(/\+/g, "%20"));
|
fileName = decodeURIComponent(encodedName.replace(/\+/g, "%20"));
|
||||||
@@ -870,7 +870,7 @@ function variableTypeText(type: string) {
|
|||||||
const map: Record<string, string> = {
|
const map: Record<string, string> = {
|
||||||
employee: "员工填写",
|
employee: "员工填写",
|
||||||
company: "公司信息",
|
company: "公司信息",
|
||||||
contract: "人事合同参数",
|
contract: "人事预设参数",
|
||||||
system: "系统自动",
|
system: "系统自动",
|
||||||
unresolved: "待确认"
|
unresolved: "待确认"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,43 +1,32 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="table-box">
|
<div class="table-box">
|
||||||
<ProTable
|
<ProTable ref="proTable" title="正式员工档案" :columns="columns" :request-api="onboardingTaskApi.employeePage">
|
||||||
ref="proTable"
|
|
||||||
title="正式员工档案"
|
|
||||||
:columns="columns"
|
|
||||||
:request-api="onboardingTaskApi.employeePage"
|
|
||||||
>
|
|
||||||
<template #operation="scope">
|
<template #operation="scope">
|
||||||
<el-button link type="primary" icon="UserFilled" @click="showDetail(scope.row)">
|
<el-button link type="primary" icon="UserFilled" @click="showDetail(scope.row)"> 查看完整档案 </el-button>
|
||||||
查看完整档案
|
|
||||||
</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</ProTable>
|
</ProTable>
|
||||||
|
|
||||||
<!-- 员工完整档案抽屉 -->
|
<!-- 员工完整档案抽屉 -->
|
||||||
<el-drawer
|
<el-drawer v-model="detailVisible" :title="`员工档案详情 · ${detail?.employee?.employeeName || ''}`" size="820px" destroy-on-close>
|
||||||
v-model="detailVisible"
|
|
||||||
:title="`员工档案详情 · ${detail?.employee?.employeeName || ''}`"
|
|
||||||
size="820px"
|
|
||||||
destroy-on-close
|
|
||||||
>
|
|
||||||
<div v-if="detail?.employee" class="employee-drawer-content">
|
<div v-if="detail?.employee" class="employee-drawer-content">
|
||||||
<!-- 头部个人简要信息 -->
|
<!-- 头部个人简要信息 -->
|
||||||
<div class="employee-header-card">
|
<div class="employee-header-card">
|
||||||
<el-avatar :size="64" class="employee-avatar">
|
<el-avatar :size="64" class="employee-avatar">
|
||||||
{{ detail.employee.employeeName ? detail.employee.employeeName.substring(0, 1) : '员' }}
|
{{ detail.employee.employeeName ? detail.employee.employeeName.substring(0, 1) : "员" }}
|
||||||
</el-avatar>
|
</el-avatar>
|
||||||
<div class="employee-header-info">
|
<div class="employee-header-info">
|
||||||
<div class="employee-name-row">
|
<div class="employee-name-row">
|
||||||
<span class="employee-name">{{ detail.employee.employeeName }}</span>
|
<span class="employee-name">{{ detail.employee.employeeName }}</span>
|
||||||
<el-tag size="small" :type="detail.employee.gender === '女' ? 'danger' : 'primary'" effect="plain">
|
<el-tag size="small" :type="detail.employee.gender === '女' ? 'danger' : 'primary'" effect="plain">
|
||||||
{{ detail.employee.gender || '未知' }}
|
{{ detail.employee.gender || "未知" }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<el-tag size="small" type="success">正式员工</el-tag>
|
<el-tag size="small" type="success">正式员工</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div class="employee-meta-row">
|
<div class="employee-meta-row">
|
||||||
<span>员工编号:{{ detail.employee.employeeNo || '-' }}</span>
|
<span>所属公司:{{ detail.employee.companyName || "-" }}</span>
|
||||||
<span>联系电话:{{ detail.employee.phone }}</span>
|
<span>所属部门:{{ detail.employee.departmentName || "-" }}</span>
|
||||||
<span>入职日期:{{ detail.employee.entryDate || '-' }}</span>
|
<span>所属岗位:{{ detail.employee.positionName || "-" }}</span>
|
||||||
|
<span>入职日期:{{ formatDate(detail.employee.entryDate) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -46,38 +35,64 @@
|
|||||||
<!-- 1. 基本人事档案 -->
|
<!-- 1. 基本人事档案 -->
|
||||||
<el-tab-pane label="基本人事档案" name="basic">
|
<el-tab-pane label="基本人事档案" name="basic">
|
||||||
<el-card shadow="never" class="section-card">
|
<el-card shadow="never" class="section-card">
|
||||||
<template #header>
|
<template #header><div class="card-header-title">个人基本信息</div></template>
|
||||||
<div class="card-header-title">身份与联系信息</div>
|
|
||||||
</template>
|
|
||||||
<el-descriptions :column="2" border>
|
<el-descriptions :column="2" border>
|
||||||
<el-descriptions-item label="姓名">{{ detail.employee.employeeName }}</el-descriptions-item>
|
<el-descriptions-item label="姓名">{{ employeeInfo.employeeName || detail.employee.employeeName }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="性别">{{ detail.employee.gender || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="性别">{{ employeeInfo.gender || detail.employee.gender || "-" }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="联系电话">{{ detail.employee.phone }}</el-descriptions-item>
|
<el-descriptions-item label="民族">{{ employeeInfo.nation || detail.employee.nation || "-" }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="身份证号码">{{ detail.employee.idCardNumber }}</el-descriptions-item>
|
<el-descriptions-item label="出生日期">{{ employeeInfo.birthday || formatDate(detail.employee.birthDate) }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="出生日期">{{ detail.employee.birthDate || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="身高">{{ employeeInfo.height ? `${employeeInfo.height} cm` : "-" }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="民族">{{ detail.employee.nation || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="体重">{{ employeeInfo.weight ? `${employeeInfo.weight} kg` : "-" }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="户口所在地" :span="2">
|
<el-descriptions-item label="健康状况">{{ employeeInfo.healthCondition || "-" }}</el-descriptions-item>
|
||||||
{{ detail.employee.registeredResidence || '-' }}
|
<el-descriptions-item label="婚育情况">{{ employeeInfo.maritalStatus || "-" }}</el-descriptions-item>
|
||||||
</el-descriptions-item>
|
<el-descriptions-item label="联系电话">{{ employeeInfo.phone || detail.employee.phone || "-" }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="现居通讯地址" :span="2">
|
<el-descriptions-item label="电子邮箱">{{ employeeInfo.email || "-" }}</el-descriptions-item>
|
||||||
{{ detail.employee.contactAddress || '-' }}
|
<el-descriptions-item label="身份证号码" :span="2">{{
|
||||||
</el-descriptions-item>
|
employeeInfo.idCardNumber || detail.employee.idCardNumber || "-"
|
||||||
|
}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="户口所在地" :span="2">{{
|
||||||
|
employeeInfo.registeredResidence || detail.employee.registeredResidence || "-"
|
||||||
|
}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="现居通讯地址" :span="2">{{
|
||||||
|
employeeInfo.currentAddress || detail.employee.contactAddress || "-"
|
||||||
|
}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="房东联系方式" :span="2">{{ employeeInfo.landlordContact || "-" }}</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card shadow="never" class="section-card mt-4">
|
<el-card shadow="never" class="section-card mt-4">
|
||||||
<template #header>
|
<template #header><div class="card-header-title">学历、资质与特长</div></template>
|
||||||
<div class="card-header-title">学历与就职信息</div>
|
|
||||||
</template>
|
|
||||||
<el-descriptions :column="2" border>
|
<el-descriptions :column="2" border>
|
||||||
<el-descriptions-item label="毕业院校">{{ detail.employee.college || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="最高学历">{{ employeeInfo.education || detail.employee.education || "-" }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="最高学历">{{ detail.employee.education || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="所学专业">{{ employeeInfo.major || detail.employee.major || "-" }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="所学专业">{{ detail.employee.major || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="毕业院校" :span="2">{{
|
||||||
<el-descriptions-item label="部门名称">{{ detail.employee.departmentName || '-' }}</el-descriptions-item>
|
employeeInfo.graduatedSchool || detail.employee.college || "-"
|
||||||
<el-descriptions-item label="合同社保单位">{{ detail.employee.socialInsuranceCompany || '-' }}</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="合同性质">{{ detail.employee.contractNature || '全职劳动合同' }}</el-descriptions-item>
|
<el-descriptions-item label="职业资格">{{ employeeInfo.vocationalQualification || "-" }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="合同开始日期">{{ detail.employee.contractStartDate || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="资格等级">{{ employeeInfo.qualificationLevel || "-" }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="合同终止日期">{{ detail.employee.contractEndDate || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="技术特长" :span="2">{{ employeeInfo.technicalSpecialty || "-" }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<el-card shadow="never" class="section-card mt-4">
|
||||||
|
<template #header><div class="card-header-title">任职与签署材料信息</div></template>
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="所属公司">{{ detail.employee.companyName || "-" }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="所属部门">{{
|
||||||
|
detail.employee.departmentName || employeeInfo.onboardingDepartment || "-"
|
||||||
|
}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="所属岗位">{{
|
||||||
|
detail.employee.positionName || employeeInfo.onboardingPosition || "-"
|
||||||
|
}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="员工编号">{{ detail.employee.employeeNo || employeeInfo.employeeNo || "-" }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="入职日期">{{ formatDate(detail.employee.entryDate) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="社保缴纳单位">{{ detail.employee.socialInsuranceCompany || "-" }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="聘用/材料性质">{{ detail.employee.contractNature || "全职劳动合同" }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="签署材料开始日期">{{ formatDate(detail.employee.contractStartDate) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="签署材料终止日期">{{ formatDate(detail.employee.contractEndDate) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="其他说明" :span="2">{{
|
||||||
|
employeeInfo.otherRemarks || detail.employee.remark || "-"
|
||||||
|
}}</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
@@ -86,16 +101,60 @@
|
|||||||
<div class="card-header-title">工资卡账户信息</div>
|
<div class="card-header-title">工资卡账户信息</div>
|
||||||
</template>
|
</template>
|
||||||
<el-descriptions :column="2" border>
|
<el-descriptions :column="2" border>
|
||||||
<el-descriptions-item label="银行卡号">{{ detail.employee.bankCardNumber || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="银行卡号">{{ detail.employee.bankCardNumber || "-" }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="开户人姓名">{{ detail.employee.bankAccountName || detail.employee.employeeName }}</el-descriptions-item>
|
<el-descriptions-item label="开户人姓名">{{ detail.employee.bankAccountName || detail.employee.employeeName }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="工资卡开户行" :span="2">{{ detail.employee.bankName || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="工资卡开户行" :span="2">{{ detail.employee.bankName || "-" }}</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
|
<el-card shadow="never" class="section-card mt-4">
|
||||||
|
<template #header><div class="card-header-title">紧急联系人</div></template>
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="联系人姓名">{{ employeeInfo.emergencyContact || "-" }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="联系电话">{{ employeeInfo.emergencyPhone || "-" }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="联系地址" :span="2">{{ employeeInfo.emergencyAddress || "-" }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<el-card shadow="never" class="section-card mt-4">
|
||||||
|
<template #header><div class="card-header-title">教育学习经历</div></template>
|
||||||
|
<el-empty v-if="!educationHistory.length" description="暂无教育学习经历" :image-size="70" />
|
||||||
|
<el-table v-else :data="educationHistory" border size="small">
|
||||||
|
<el-table-column prop="timeRange" label="时间" min-width="140" />
|
||||||
|
<el-table-column prop="location" label="学校/地点" min-width="150" />
|
||||||
|
<el-table-column prop="content" label="学习内容" min-width="180" />
|
||||||
|
<el-table-column prop="result" label="学历/结果" min-width="120" />
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<el-card shadow="never" class="section-card mt-4">
|
||||||
|
<template #header><div class="card-header-title">主要工作经历</div></template>
|
||||||
|
<el-empty v-if="!workHistory.length" description="暂无工作经历" :image-size="70" />
|
||||||
|
<el-table v-else :data="workHistory" border size="small">
|
||||||
|
<el-table-column prop="timeRange" label="时间" min-width="140" />
|
||||||
|
<el-table-column prop="companyName" label="工作单位" min-width="160" />
|
||||||
|
<el-table-column prop="position" label="岗位" min-width="120" />
|
||||||
|
<el-table-column prop="salary" label="薪资" min-width="100" />
|
||||||
|
<el-table-column prop="leaveReason" label="离职原因" min-width="160" />
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<el-card shadow="never" class="section-card mt-4">
|
||||||
|
<template #header><div class="card-header-title">家庭成员</div></template>
|
||||||
|
<el-empty v-if="!familyMembers.length" description="暂无家庭成员信息" :image-size="70" />
|
||||||
|
<el-table v-else :data="familyMembers" border size="small">
|
||||||
|
<el-table-column prop="name" label="姓名" min-width="100" />
|
||||||
|
<el-table-column prop="relationship" label="关系" min-width="100" />
|
||||||
|
<el-table-column prop="age" label="年龄" min-width="80" />
|
||||||
|
<el-table-column prop="company" label="工作单位" min-width="160" />
|
||||||
|
<el-table-column prop="phone" label="联系电话" min-width="140" />
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<!-- 2. 归档合同与协议 -->
|
<!-- 2. 归档合同与协议 -->
|
||||||
<el-tab-pane label="归档合同协议" name="contracts">
|
<el-tab-pane label="归档签署材料" name="contracts">
|
||||||
<el-empty v-if="!detail.contracts?.length" description="暂无已归档的劳动合同" />
|
<el-empty v-if="!detail.contracts?.length" description="暂无已归档的签署材料" />
|
||||||
<div v-else class="contracts-list">
|
<div v-else class="contracts-list">
|
||||||
<div v-for="contract in detail.contracts" :key="contract.id" class="contract-box">
|
<div v-for="contract in detail.contracts" :key="contract.id" class="contract-box">
|
||||||
<div class="contract-info-left">
|
<div class="contract-info-left">
|
||||||
@@ -112,9 +171,14 @@
|
|||||||
plain
|
plain
|
||||||
size="small"
|
size="small"
|
||||||
icon="Download"
|
icon="Download"
|
||||||
@click="download(contract.generatedDocxFileId, `${detail?.employee?.employeeName || '员工'}_${contract.contractName || '入职合同'}.docx`)"
|
@click="
|
||||||
|
download(
|
||||||
|
contract.generatedDocxFileId,
|
||||||
|
`${detail?.employee?.employeeName || '员工'}_${contract.contractName || '入职合同'}.docx`
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
下载合同 DOCX
|
下载签署材料 DOCX
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-tag v-else type="info">尚未生成电子文件</el-tag>
|
<el-tag v-else type="info">尚未生成电子文件</el-tag>
|
||||||
</div>
|
</div>
|
||||||
@@ -127,21 +191,13 @@
|
|||||||
<el-empty v-if="!detail.audits?.length" description="暂无流转记录" />
|
<el-empty v-if="!detail.audits?.length" description="暂无流转记录" />
|
||||||
<div v-else class="timeline-box">
|
<div v-else class="timeline-box">
|
||||||
<el-timeline>
|
<el-timeline>
|
||||||
<el-timeline-item
|
<el-timeline-item v-for="item in detail.audits" :key="item.id" type="primary" :timestamp="formatTime(item.auditedAt)" placement="top">
|
||||||
v-for="item in detail.audits"
|
|
||||||
:key="item.id"
|
|
||||||
type="primary"
|
|
||||||
:timestamp="formatTime(item.auditedAt)"
|
|
||||||
placement="top"
|
|
||||||
>
|
|
||||||
<div class="audit-card">
|
<div class="audit-card">
|
||||||
<div class="audit-action-name font-bold">
|
<div class="audit-action-name font-bold">
|
||||||
{{ auditActionText(item.auditAction) }}
|
{{ auditActionText(item.auditAction) }}
|
||||||
<span v-if="item.createUser" class="audit-operator">(操作人:{{ item.createUser }})</span>
|
<span v-if="item.createUser" class="audit-operator">(操作人:{{ item.createUser }})</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="item.auditOpinion" class="audit-opinion">
|
<div v-if="item.auditOpinion" class="audit-opinion">审核意见:{{ item.auditOpinion }}</div>
|
||||||
审核意见:{{ item.auditOpinion }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</el-timeline-item>
|
</el-timeline-item>
|
||||||
</el-timeline>
|
</el-timeline>
|
||||||
@@ -157,25 +213,33 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="onboardingEmployee">
|
<script setup lang="ts" name="onboardingEmployee">
|
||||||
import { ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import { UserFilled, Download } from "@element-plus/icons-vue";
|
import { UserFilled, Download } from "@element-plus/icons-vue";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import {
|
import { onboardingTaskApi, type OnboardingEmployee } from "@/api/modules/biz/onboarding";
|
||||||
onboardingTaskApi,
|
|
||||||
type OnboardingEmployee
|
|
||||||
} from "@/api/modules/biz/onboarding";
|
|
||||||
import type { ColumnProps } from "@/components/ProTable/interface";
|
import type { ColumnProps } from "@/components/ProTable/interface";
|
||||||
|
|
||||||
const detailVisible = ref(false);
|
const detailVisible = ref(false);
|
||||||
const activeTab = ref("basic");
|
const activeTab = ref("basic");
|
||||||
const detail = ref<any>();
|
const detail = ref<any>();
|
||||||
|
const employeeInfo = computed<Record<string, any>>(() => detail.value?.employeeInfo || {});
|
||||||
|
|
||||||
|
function parseJsonList(value?: string) {
|
||||||
|
if (!value) return [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = JSON.parse(value);
|
||||||
|
return Array.isArray(result) ? result : [];
|
||||||
|
} catch {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const educationHistory = computed(() => parseJsonList(employeeInfo.value.educationHistoryJson));
|
||||||
|
const workHistory = computed(() => parseJsonList(employeeInfo.value.workHistoryJson));
|
||||||
|
const familyMembers = computed(() => parseJsonList(employeeInfo.value.familyMembersJson));
|
||||||
|
|
||||||
const columns: ColumnProps<OnboardingEmployee>[] = [
|
const columns: ColumnProps<OnboardingEmployee>[] = [
|
||||||
{
|
|
||||||
prop: "employeeNo",
|
|
||||||
label: "员工编号",
|
|
||||||
minWidth: 160
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
prop: "employeeName",
|
prop: "employeeName",
|
||||||
label: "姓名",
|
label: "姓名",
|
||||||
@@ -189,10 +253,9 @@ const columns: ColumnProps<OnboardingEmployee>[] = [
|
|||||||
align: "center"
|
align: "center"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: "phone",
|
prop: "companyName",
|
||||||
label: "手机号码",
|
label: "所属公司",
|
||||||
minWidth: 160,
|
minWidth: 180
|
||||||
search: { el: "input" }
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: "departmentName",
|
prop: "departmentName",
|
||||||
@@ -200,15 +263,21 @@ const columns: ColumnProps<OnboardingEmployee>[] = [
|
|||||||
minWidth: 140
|
minWidth: 140
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: "entryDate",
|
prop: "positionName",
|
||||||
label: "入职日期",
|
label: "所属岗位",
|
||||||
minWidth: 140
|
minWidth: 140
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: "createTime",
|
prop: "phone",
|
||||||
label: "建档时间",
|
label: "手机号码",
|
||||||
minWidth: 180,
|
minWidth: 160,
|
||||||
render: scope => formatTime(scope.row.createTime)
|
search: { el: "input" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "entryDate",
|
||||||
|
label: "入职日期",
|
||||||
|
minWidth: 140,
|
||||||
|
render: scope => formatDate(scope.row.entryDate)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: "operation",
|
prop: "operation",
|
||||||
@@ -234,6 +303,11 @@ const formatTime = (timeStr?: string) => {
|
|||||||
return timeStr.replace("T", " ").substring(0, 19);
|
return timeStr.replace("T", " ").substring(0, 19);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const formatDate = (timeStr?: string) => {
|
||||||
|
if (!timeStr) return "-";
|
||||||
|
return timeStr.replace("T", " ").substring(0, 10);
|
||||||
|
};
|
||||||
|
|
||||||
async function showDetail(row: OnboardingEmployee) {
|
async function showDetail(row: OnboardingEmployee) {
|
||||||
const { data } = await onboardingTaskApi.employeeDetail({
|
const { data } = await onboardingTaskApi.employeeDetail({
|
||||||
id: row.id
|
id: row.id
|
||||||
@@ -246,9 +320,7 @@ async function showDetail(row: OnboardingEmployee) {
|
|||||||
|
|
||||||
function resolveDownloadFileName(response: any, fallbackFileName?: string) {
|
function resolveDownloadFileName(response: any, fallbackFileName?: string) {
|
||||||
const disposition = String(response?.headers?.["content-disposition"] || "");
|
const disposition = String(response?.headers?.["content-disposition"] || "");
|
||||||
const encodedName =
|
const encodedName = disposition.match(/filename\*=UTF-8\'\'([^;]+)/i)?.[1] || disposition.match(/filename="?([^";]+)"?/i)?.[1];
|
||||||
disposition.match(/filename\*=UTF-8\'\'([^;]+)/i)?.[1] ||
|
|
||||||
disposition.match(/filename="?([^";]+)"?/i)?.[1];
|
|
||||||
|
|
||||||
if (encodedName) {
|
if (encodedName) {
|
||||||
try {
|
try {
|
||||||
@@ -258,7 +330,7 @@ function resolveDownloadFileName(response: any, fallbackFileName?: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fallbackFileName || "入职合同.docx";
|
return fallbackFileName || "入职签署材料.docx";
|
||||||
}
|
}
|
||||||
|
|
||||||
async function download(fileId: number, fallbackFileName?: string) {
|
async function download(fileId: number, fallbackFileName?: string) {
|
||||||
@@ -278,7 +350,7 @@ async function download(fileId: number, fallbackFileName?: string) {
|
|||||||
link.remove();
|
link.remove();
|
||||||
window.setTimeout(() => URL.revokeObjectURL(objectUrl), 0);
|
window.setTimeout(() => URL.revokeObjectURL(objectUrl), 0);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
ElMessage.error(error?.msg || error?.message || "合同文件下载失败");
|
ElMessage.error(error?.msg || error?.message || "签署材料文件下载失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -341,6 +413,7 @@ async function download(fileId: number, fallbackFileName?: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.section-card {
|
.section-card {
|
||||||
|
flex-wrap: wrap;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
border: 1px solid #e2e8f0;
|
border: 1px solid #e2e8f0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
<el-button type="primary" icon="Plus" @click="openCreate">新增入职模板</el-button>
|
<el-button type="primary" icon="Plus" @click="openCreate">新增入职模板</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-alert title="入职模板统一管理公司、岗位、合同文件与员工上传材料;员工入职档案自动采用标准《入职登记表》。" type="info" :closable="false" show-icon
|
<el-alert title="入职模板统一管理公司、岗位、签署材料文件与员工上传材料;员工入职档案自动采用标准《入职登记表》。" type="info" :closable="false" show-icon
|
||||||
class="tip" />
|
class="tip" />
|
||||||
|
|
||||||
<div class="table-container">
|
<div class="table-container">
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="配置内容" min-width="200">
|
<el-table-column label="配置内容" min-width="200">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
合同 {{ scope.row.contractCount || 0 }} 份 / 材料 {{ scope.row.materialCount || 0 }} 项
|
签署材料 {{ scope.row.contractCount || 0 }} 份 / 材料 {{ scope.row.materialCount || 0 }} 项
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="status" label="状态" width="90" align="center">
|
<el-table-column prop="status" label="状态" width="90" align="center">
|
||||||
@@ -186,7 +186,7 @@
|
|||||||
<el-table :data="form.contracts" border empty-text="暂无关联合同,请点击右上角添加" class="mt-2">
|
<el-table :data="form.contracts" border empty-text="暂无关联合同,请点击右上角添加" class="mt-2">
|
||||||
<el-table-column label="合同模板" min-width="220">
|
<el-table-column label="合同模板" min-width="220">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-select v-model="scope.row.contractTemplateId" filterable class="full-width" placeholder="选择合同模板"
|
<el-select v-model="scope.row.contractTemplateId" filterable class="full-width" placeholder="选择签署材料模板"
|
||||||
@change="onContractTemplateChange(scope.row)">
|
@change="onContractTemplateChange(scope.row)">
|
||||||
<el-option v-for="item in contractTemplates" :key="item.id" :label="item.templateName"
|
<el-option v-for="item in contractTemplates" :key="item.id" :label="item.templateName"
|
||||||
:value="item.id" />
|
:value="item.id" />
|
||||||
@@ -494,7 +494,7 @@ function addContract() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!contractTemplates.value.length) {
|
if (!contractTemplates.value.length) {
|
||||||
ElMessage.warning("当前公司、部门和岗位没有可用的合同模板");
|
ElMessage.warning("当前公司、部门和岗位没有可用的签署材料模板");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,7 +602,7 @@ async function save() {
|
|||||||
return ElMessage.warning("请完整填写模板编码、名称、公司、部门及适用岗位");
|
return ElMessage.warning("请完整填写模板编码、名称、公司、部门及适用岗位");
|
||||||
}
|
}
|
||||||
if (!form.contracts.length || form.contracts.some(item => !item.contractTemplateId || !item.contractTemplateVersionId)) {
|
if (!form.contracts.length || form.contracts.some(item => !item.contractTemplateId || !item.contractTemplateVersionId)) {
|
||||||
return ElMessage.warning("请完整选择至少一份合同模板及版本");
|
return ElMessage.warning("请完整选择至少一份签署材料模板及版本");
|
||||||
}
|
}
|
||||||
|
|
||||||
saving.value = true;
|
saving.value = true;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
>
|
>
|
||||||
<el-option label="全部变量分类" value="" />
|
<el-option label="全部变量分类" value="" />
|
||||||
<el-option label="员工登记表变量 (employee)" value="employee" />
|
<el-option label="员工登记表变量 (employee)" value="employee" />
|
||||||
<el-option label="人事合同参数 (hr)" value="hr" />
|
<el-option label="人事预设参数 (hr)" value="hr" />
|
||||||
<el-option label="公司信息变量 (company)" value="company" />
|
<el-option label="公司信息变量 (company)" value="company" />
|
||||||
<el-option label="系统预置变量 (system)" value="system" />
|
<el-option label="系统预置变量 (system)" value="system" />
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-alert
|
<el-alert
|
||||||
title="变量字典库定义了合同 DOCX 中所有合法的占位符(如 {{employee.EmployeeName}})。上传 Word 时系统会自动校验占位符是否在此字典中,防止拼写错误。"
|
title="变量字典库定义了签署材料 DOCX 中所有合法的占位符(如 {{employee.EmployeeName}})。上传 Word 时系统会自动校验占位符是否在此字典中,防止拼写错误。"
|
||||||
type="info"
|
type="info"
|
||||||
show-icon
|
show-icon
|
||||||
:closable="false"
|
:closable="false"
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
<el-form-item label="变量分类" prop="variableCategory" required>
|
<el-form-item label="变量分类" prop="variableCategory" required>
|
||||||
<el-select v-model="form.variableCategory" :disabled="form.isBuiltIn" style="width: 100%">
|
<el-select v-model="form.variableCategory" :disabled="form.isBuiltIn" style="width: 100%">
|
||||||
<el-option label="员工变量 (employee.)" value="employee" />
|
<el-option label="员工变量 (employee.)" value="employee" />
|
||||||
<el-option label="人事合同参数 (hr.)" value="hr" />
|
<el-option label="人事预设参数 (hr.)" value="hr" />
|
||||||
<el-option label="公司信息 (company.)" value="company" />
|
<el-option label="公司信息 (company.)" value="company" />
|
||||||
<el-option label="系统变量 (system.)" value="system" />
|
<el-option label="系统变量 (system.)" value="system" />
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|||||||
@@ -149,8 +149,8 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-form-item label="合同甲方全称" required>
|
<el-form-item label="签署材料甲方全称" required>
|
||||||
<el-input v-model="companyForm.legalName" placeholder="用于合同填写的法定主体全称" />
|
<el-input v-model="companyForm.legalName" placeholder="用于签署材料填写的法定主体全称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
@@ -290,7 +290,7 @@
|
|||||||
|
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="默认合同年限">
|
<el-form-item label="默认签署材料年限">
|
||||||
<el-input-number v-model="positionForm.defaultContractYears" :min="1" :max="20" class="w-full" />
|
<el-input-number v-model="positionForm.defaultContractYears" :min="1" :max="20" class="w-full" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -419,7 +419,7 @@ const companyColumns: ColumnProps<OnboardingCompany>[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: "legalName",
|
prop: "legalName",
|
||||||
label: "合同甲方全称",
|
label: "签署材料甲方全称",
|
||||||
minWidth: 220
|
minWidth: 220
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -534,7 +534,7 @@ const positionColumns: ColumnProps<OnboardingPosition>[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: "defaultContractYears",
|
prop: "defaultContractYears",
|
||||||
label: "默认合同年限",
|
label: "默认签署材料年限",
|
||||||
width: 130,
|
width: 130,
|
||||||
align: "center",
|
align: "center",
|
||||||
render: scope => `${scope.row.defaultContractYears || 3} 年`
|
render: scope => `${scope.row.defaultContractYears || 3} 年`
|
||||||
@@ -648,7 +648,7 @@ async function openPositionEdit(row: OnboardingPosition) {
|
|||||||
async function save() {
|
async function save() {
|
||||||
if (dialogKind.value === "company") {
|
if (dialogKind.value === "company") {
|
||||||
if (!companyForm.companyCode || !companyForm.companyName || !companyForm.legalName) {
|
if (!companyForm.companyCode || !companyForm.companyName || !companyForm.legalName) {
|
||||||
return ElMessage.warning("请填写公司编码、公司名称和合同甲方全称");
|
return ElMessage.warning("请填写公司编码、公司名称和签署材料甲方全称");
|
||||||
}
|
}
|
||||||
await onboardingTaskApi.saveCompany(companyForm, editing.value);
|
await onboardingTaskApi.saveCompany(companyForm, editing.value);
|
||||||
companyTable.value?.refresh();
|
companyTable.value?.refresh();
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
icon="Setting"
|
icon="Setting"
|
||||||
@click="openContractVariables(scope.row)"
|
@click="openContractVariables(scope.row)"
|
||||||
>
|
>
|
||||||
合同参数
|
签署材料参数
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
<el-button
|
<el-button
|
||||||
@@ -214,12 +214,12 @@
|
|||||||
<!-- 2. 合同人事参数卡片 -->
|
<!-- 2. 合同人事参数卡片 -->
|
||||||
<div v-if="form.contractVariables.length" class="form-card-section">
|
<div v-if="form.contractVariables.length" class="form-card-section">
|
||||||
<div class="section-title">
|
<div class="section-title">
|
||||||
<span class="title-text">合同人事参数预设</span>
|
<span class="title-text">签署材料人事参数预设</span>
|
||||||
<span class="title-tip">以下参数将自动替换进 DOCX 合同中,请在向员工发送链接前核对填写</span>
|
<span class="title-tip">以下参数将自动替换进 DOCX 签署材料中,请在向员工发送链接前核对填写</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-alert
|
<el-alert
|
||||||
title="提示:此处填写的内容将作为合同正式条款,如薪资、合同起止日期、试用期等,请谨慎填写。"
|
title="提示:此处填写的内容将作为签署材料正式条款,如薪资、协议起止日期、试用期等,请谨慎填写。"
|
||||||
type="warning"
|
type="warning"
|
||||||
:closable="false"
|
:closable="false"
|
||||||
show-icon
|
show-icon
|
||||||
@@ -292,7 +292,7 @@
|
|||||||
|
|
||||||
<!-- 任务创建成功与分享弹窗 -->
|
<!-- 任务创建成功与分享弹窗 -->
|
||||||
<el-dialog v-model="shareVisible" title="入职任务已创建" width="560px" destroy-on-close>
|
<el-dialog v-model="shareVisible" title="入职任务已创建" width="560px" destroy-on-close>
|
||||||
<el-result icon="success" title="任务创建成功!" sub-title="请先确认合同人事参数,再将专属链接发送给候选人">
|
<el-result icon="success" title="任务创建成功!" sub-title="请先确认签署材料人事参数,再将专属链接发送给候选人">
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<div class="share-box">
|
<div class="share-box">
|
||||||
<div class="share-item">
|
<div class="share-item">
|
||||||
@@ -510,8 +510,8 @@
|
|||||||
<el-card v-if="detailCustomVars.length" shadow="never" class="mb-3 border-card">
|
<el-card v-if="detailCustomVars.length" shadow="never" class="mb-3 border-card">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="card-header-flex">
|
<div class="card-header-flex">
|
||||||
<span class="font-bold card-title-text">合同专属补充信息</span>
|
<span class="font-bold card-title-text">签署材料专属补充信息</span>
|
||||||
<el-tag size="small" type="warning">合同专有项</el-tag>
|
<el-tag size="small" type="warning">签署材料专有项</el-tag>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-descriptions :column="2" border size="default">
|
<el-descriptions :column="2" border size="default">
|
||||||
@@ -611,8 +611,8 @@
|
|||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<!-- 3. 合同管理与归档 -->
|
<!-- 3. 合同管理与归档 -->
|
||||||
<el-tab-pane label="入职合同列表" name="contracts">
|
<el-tab-pane label="入职签署材料列表" name="contracts">
|
||||||
<el-empty v-if="!detail.contracts || !detail.contracts.length" description="暂无关联合同" />
|
<el-empty v-if="!detail.contracts || !detail.contracts.length" description="暂无关联签署材料" />
|
||||||
<div v-else class="contracts-panel">
|
<div v-else class="contracts-panel">
|
||||||
<div v-for="item in detail.contracts" :key="item.id" class="contract-card-item">
|
<div v-for="item in detail.contracts" :key="item.id" class="contract-card-item">
|
||||||
<div class="contract-left">
|
<div class="contract-left">
|
||||||
@@ -634,7 +634,7 @@
|
|||||||
icon="DocumentChecked"
|
icon="DocumentChecked"
|
||||||
@click="generate(item.id)"
|
@click="generate(item.id)"
|
||||||
>
|
>
|
||||||
生成DOCX合同
|
生成DOCX签署材料
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-else
|
v-else
|
||||||
@@ -728,24 +728,24 @@
|
|||||||
@close="closeImageViewer"
|
@close="closeImageViewer"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 合同参数录入弹窗 -->
|
<!-- 签署材料参数录入弹窗 -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="contractVariablesVisible"
|
v-model="contractVariablesVisible"
|
||||||
:title="`${contractVariableTask?.taskNo || ''} · 合同参数录入`"
|
:title="`${contractVariableTask?.taskNo || ''} · 签署材料参数录入`"
|
||||||
width="1180px"
|
width="1180px"
|
||||||
top="4vh"
|
top="4vh"
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
>
|
>
|
||||||
<div class="contract-vars-dialog-body">
|
<div class="contract-vars-dialog-body">
|
||||||
<el-alert
|
<el-alert
|
||||||
title="说明:此处展示本次入职任务关联的所有合同变量。带有【人事变量】标签的项为本次需要 HR 填写的核心条款(如薪资、试用期、合同起止日等);员工变量与公司变量将在流程中自动带入。"
|
title="说明:此处展示本次入职任务关联的所有签署材料变量。带有【人事变量】标签的项为本次需要 HR 填写的核心条款(如薪资、试用期、协议起止日等);员工变量与公司变量将在流程中自动带入。"
|
||||||
type="info"
|
type="info"
|
||||||
show-icon
|
show-icon
|
||||||
:closable="false"
|
:closable="false"
|
||||||
style="margin-bottom: 16px;"
|
style="margin-bottom: 16px;"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<el-empty v-if="!contractVariableGroups.length" description="当前任务合同无需配置人事变量" />
|
<el-empty v-if="!contractVariableGroups.length" description="当前任务签署材料无需配置人事变量" />
|
||||||
|
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<!-- 顶部合同分组切换 Tab -->
|
<!-- 顶部合同分组切换 Tab -->
|
||||||
@@ -862,7 +862,7 @@
|
|||||||
<div class="dialog-footer-flex">
|
<div class="dialog-footer-flex">
|
||||||
<el-button @click="contractVariablesVisible = false">关闭</el-button>
|
<el-button @click="contractVariablesVisible = false">关闭</el-button>
|
||||||
<el-button type="primary" icon="Check" :loading="savingAllVars" @click="saveAllContractVariables">
|
<el-button type="primary" icon="Check" :loading="savingAllVars" @click="saveAllContractVariables">
|
||||||
一键保存全部合同参数
|
一键保存全部签署材料参数
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -1112,7 +1112,7 @@ const variableTypeText = (type: string) => {
|
|||||||
const map: Record<string, string> = {
|
const map: Record<string, string> = {
|
||||||
employee: "员工变量",
|
employee: "员工变量",
|
||||||
company: "公司变量",
|
company: "公司变量",
|
||||||
contract: "合同人事参数",
|
contract: "人事预设参数",
|
||||||
system: "系统变量"
|
system: "系统变量"
|
||||||
};
|
};
|
||||||
return map[type] || type;
|
return map[type] || type;
|
||||||
@@ -1359,7 +1359,7 @@ async function createTask() {
|
|||||||
item => item.required && isBlankContractVariableValue(item.variableValue)
|
item => item.required && isBlankContractVariableValue(item.variableValue)
|
||||||
);
|
);
|
||||||
if (missingVariable) {
|
if (missingVariable) {
|
||||||
return ElMessage.warning(`请填写合同人事参数“${missingVariable.variableName}”`);
|
return ElMessage.warning(`请填写签署材料人事参数“${missingVariable.variableName}”`);
|
||||||
}
|
}
|
||||||
|
|
||||||
creating.value = true;
|
creating.value = true;
|
||||||
@@ -1403,7 +1403,7 @@ function copyText(text?: string, successMsg = "复制成功") {
|
|||||||
|
|
||||||
function copyInviteMessage() {
|
function copyInviteMessage() {
|
||||||
if (!createdTaskInfo.value) return;
|
if (!createdTaskInfo.value) return;
|
||||||
const msg = `【入职邀请】您好!欢迎加入${createdTaskInfo.value.companyName},担任${createdTaskInfo.value.positionName}一职。请点击以下链接完成您的入职登记与合同确认:${createdTaskInfo.value.linkUrl} (链接有效期至:${createdTaskInfo.value.expiresAt})`;
|
const msg = `【入职邀请】您好!欢迎加入${createdTaskInfo.value.companyName},担任${createdTaskInfo.value.positionName}一职。请点击以下链接完成您的入职登记与签署材料确认:${createdTaskInfo.value.linkUrl} (链接有效期至:${createdTaskInfo.value.expiresAt})`;
|
||||||
copyText(msg, "邀请文案已复制至剪贴板");
|
copyText(msg, "邀请文案已复制至剪贴板");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1457,7 +1457,7 @@ async function saveContractVariables(group: OnboardingTaskContractVariableGroup)
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (requiredBlank) {
|
if (requiredBlank) {
|
||||||
return ElMessage.warning("请填写所有必填合同人事参数");
|
return ElMessage.warning("请填写所有必填签署材料人事参数");
|
||||||
}
|
}
|
||||||
|
|
||||||
await onboardingTaskApi.saveTaskContractVariables({
|
await onboardingTaskApi.saveTaskContractVariables({
|
||||||
@@ -1489,7 +1489,7 @@ async function saveAllContractVariables() {
|
|||||||
values: buildContractVariableSaveValues(group)
|
values: buildContractVariableSaveValues(group)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ElMessage.success("全部合同参数已保存成功!");
|
ElMessage.success("全部签署材料参数已保存成功!");
|
||||||
contractVariablesVisible.value = false;
|
contractVariablesVisible.value = false;
|
||||||
} finally {
|
} finally {
|
||||||
savingAllVars.value = false;
|
savingAllVars.value = false;
|
||||||
@@ -1520,7 +1520,7 @@ function buildContractVariableSaveValues(group: OnboardingTaskContractVariableGr
|
|||||||
|
|
||||||
async function approve(row: OnboardingTask) {
|
async function approve(row: OnboardingTask) {
|
||||||
await ElMessageBox.confirm(
|
await ElMessageBox.confirm(
|
||||||
"确认审核通过?系统将自动创建正式员工档案并锁定合同快照。",
|
"确认审核通过?系统将自动创建正式员工档案并锁定签署材料快照。",
|
||||||
"审核通过确认",
|
"审核通过确认",
|
||||||
{ type: "success", confirmButtonText: "审核通过", cancelButtonText: "取消" }
|
{ type: "success", confirmButtonText: "审核通过", cancelButtonText: "取消" }
|
||||||
);
|
);
|
||||||
@@ -1546,7 +1546,7 @@ async function reject(row: OnboardingTask) {
|
|||||||
|
|
||||||
async function generate(taskContractId: number) {
|
async function generate(taskContractId: number) {
|
||||||
await onboardingTaskApi.generateContract(taskContractId);
|
await onboardingTaskApi.generateContract(taskContractId);
|
||||||
ElMessage.success("DOCX合同文件已生成");
|
ElMessage.success("DOCX签署材料文件已生成");
|
||||||
if (detail.value?.task?.id) {
|
if (detail.value?.task?.id) {
|
||||||
await showDetail(detail.value.task, true);
|
await showDetail(detail.value.task, true);
|
||||||
}
|
}
|
||||||
@@ -2163,7 +2163,7 @@ onMounted(loadCompanies);
|
|||||||
color: #2563eb;
|
color: #2563eb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 合同参数录入弹窗优化 */
|
/* 签署材料参数录入弹窗优化 */
|
||||||
.contract-vars-dialog-body {
|
.contract-vars-dialog-body {
|
||||||
max-height: 68vh;
|
max-height: 68vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<span>OnboardX 智能入职服务</span>
|
<span>OnboardX 智能入职服务</span>
|
||||||
</div>
|
</div>
|
||||||
<h1 class="brand-title">欢迎加入新团队</h1>
|
<h1 class="brand-title">欢迎加入新团队</h1>
|
||||||
<p class="brand-subtitle">请按照 4 步指引完成入职登记表、证件上传与合同查阅确认</p>
|
<p class="brand-subtitle">请按照 4 步指引完成入职登记表、证件上传与签署材料查阅确认</p>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@@ -60,16 +60,16 @@
|
|||||||
<div class="steps-wrapper desktop-only">
|
<div class="steps-wrapper desktop-only">
|
||||||
<el-steps :active="currentStep" finish-status="success" align-center>
|
<el-steps :active="currentStep" finish-status="success" align-center>
|
||||||
<el-step title="入职登记表" icon="User" />
|
<el-step title="入职登记表" icon="User" />
|
||||||
<el-step title="合同补充项" icon="Document" />
|
<el-step title="材料补充项" icon="Document" />
|
||||||
<el-step title="证件材料" icon="FolderChecked" />
|
<el-step title="证件材料" icon="FolderChecked" />
|
||||||
<el-step title="合同确认" icon="Tickets" />
|
<el-step title="材料确认" icon="Tickets" />
|
||||||
</el-steps>
|
</el-steps>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mobile-steps-wrapper mobile-only">
|
<div class="mobile-steps-wrapper mobile-only">
|
||||||
<div class="mobile-steps-track">
|
<div class="mobile-steps-track">
|
||||||
<div
|
<div
|
||||||
v-for="(stepName, index) in ['1. 登记表', '2. 补充项', '3. 证件材料', '4. 合同确认']"
|
v-for="(stepName, index) in ['1. 登记表', '2. 补充项', '3. 证件材料', '4. 材料确认']"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="mobile-step-item"
|
class="mobile-step-item"
|
||||||
:class="{
|
:class="{
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mobile-current-indicator">
|
<div class="mobile-current-indicator">
|
||||||
当前进行:<span class="highlight-step">第 {{ currentStep + 1 }}/4 步 · {{ ['入职登记表填写', '合同专有补充项', '证件材料上传', '合同查阅与确认'][currentStep] }}</span>
|
当前进行:<span class="highlight-step">第 {{ currentStep + 1 }}/4 步 · {{ ['入职登记表填写', '签署材料补充项', '证件材料上传', '签署材料查阅与确认'][currentStep] }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -419,21 +419,21 @@
|
|||||||
<!-- 步骤 2: 合同专属增量补充项 (自适应差集) -->
|
<!-- 步骤 2: 合同专属增量补充项 (自适应差集) -->
|
||||||
<div v-show="currentStep === 1" class="step-content">
|
<div v-show="currentStep === 1" class="step-content">
|
||||||
<div class="section-header">
|
<div class="section-header">
|
||||||
<h3 class="section-title">合同专属补充信息</h3>
|
<h3 class="section-title">签署材料专属补充信息</h3>
|
||||||
<p class="section-desc">以下是本次签署合同中特殊约定的增量字段,登记表未涵盖的项需在此补充确认</p>
|
<p class="section-desc">以下是本次签署材料中特殊约定的增量字段,登记表未涵盖的项需在此补充确认</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="!extraVariables.length" class="all-covered-card">
|
<div v-if="!extraVariables.length" class="all-covered-card">
|
||||||
<el-result
|
<el-result
|
||||||
icon="success"
|
icon="success"
|
||||||
title="个人信息已完整覆盖"
|
title="个人信息已完整覆盖"
|
||||||
sub-title="您在《入职登记表》中填写的姓名、身份证、电话、银行卡等信息已完整满足本次合同签署所需,无需额外补充!"
|
sub-title="您在《入职登记表》中填写的姓名、身份证、电话、银行卡等信息已完整满足本次签署材料所需,无需额外补充!"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-form v-else label-position="top" class="extra-form">
|
<el-form v-else label-position="top" class="extra-form">
|
||||||
<el-alert
|
<el-alert
|
||||||
title="请补充填写以下合同专有信息:"
|
title="请补充填写以下签署材料专有信息:"
|
||||||
type="info"
|
type="info"
|
||||||
show-icon
|
show-icon
|
||||||
:closable="false"
|
:closable="false"
|
||||||
@@ -568,21 +568,21 @@
|
|||||||
<!-- 步骤 4: 合同查阅与签署 -->
|
<!-- 步骤 4: 合同查阅与签署 -->
|
||||||
<div v-show="currentStep === 3" class="step-content">
|
<div v-show="currentStep === 3" class="step-content">
|
||||||
<div class="section-header">
|
<div class="section-header">
|
||||||
<h3 class="section-title">入职合同查阅与确认</h3>
|
<h3 class="section-title">入职签署材料查阅与确认</h3>
|
||||||
<p class="section-desc">系统已为您代入真实登记信息生成专属合同,请认真查阅条款并勾选确认</p>
|
<p class="section-desc">系统已为您代入真实登记信息生成专属签署材料,请认真查阅条款并勾选确认</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-alert
|
<el-alert
|
||||||
v-if="preparingContract"
|
v-if="preparingContract"
|
||||||
class="contract-preparing-alert"
|
class="contract-preparing-alert"
|
||||||
title="正在生成您的专属合同"
|
title="正在生成您的专属签署材料"
|
||||||
:description="contractPreparingDescription"
|
:description="contractPreparingDescription"
|
||||||
type="info"
|
type="info"
|
||||||
show-icon
|
show-icon
|
||||||
:closable="false"
|
:closable="false"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<el-empty v-if="!contracts.length" description="暂无待签署入职合同" />
|
<el-empty v-if="!contracts.length" description="暂无待确认签署材料" />
|
||||||
|
|
||||||
<div v-else class="contracts-list">
|
<div v-else class="contracts-list">
|
||||||
<div
|
<div
|
||||||
@@ -599,7 +599,7 @@
|
|||||||
</el-tag>
|
</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div class="contract-desc">
|
<div class="contract-desc">
|
||||||
请点击下方按钮下载/查阅带您专属信息的合同全文,仔细核对您的基本信息与薪资条款。
|
请点击下方按钮下载/查阅带您专属信息的签署材料全文,仔细核对您的基本信息与条款内容。
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -638,7 +638,7 @@
|
|||||||
v-if="canEdit && isContractPrepared(c.id) && !c.hasViewed"
|
v-if="canEdit && isContractPrepared(c.id) && !c.hasViewed"
|
||||||
class="contract-view-hint"
|
class="contract-view-hint"
|
||||||
>
|
>
|
||||||
请先点击“下载并查看合同”,查看后才能勾选确认。
|
请先点击“下载并查看签署材料”,查看后才能勾选确认。
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -772,7 +772,7 @@ const contractPreparingDescription = computed(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const index = contracts.value.findIndex(item => item.id === contract.id);
|
const index = contracts.value.findIndex(item => item.id === contract.id);
|
||||||
return `正在校验合同信息并生成第 ${index + 1}/${contracts.value.length} 份《${contract.contractName}》,请稍候,不要关闭页面。`;
|
return `正在校验材料信息并生成第 ${index + 1}/${contracts.value.length} 份《${contract.contractName}》,请稍候,不要关闭页面。`;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 计算差集增量变量 (合同需要的 employee. 变量中,登记表没有的字段)
|
// 计算差集增量变量 (合同需要的 employee. 变量中,登记表没有的字段)
|
||||||
@@ -1091,15 +1091,15 @@ function isContractPrepareFailed(taskContractId: number) {
|
|||||||
function getContractActionText(taskContractId: number) {
|
function getContractActionText(taskContractId: number) {
|
||||||
const status = getContractPrepareStatus(taskContractId);
|
const status = getContractPrepareStatus(taskContractId);
|
||||||
if (status === "preparing") {
|
if (status === "preparing") {
|
||||||
return "正在准备合同";
|
return "正在准备签署材料";
|
||||||
}
|
}
|
||||||
if (status === "error") {
|
if (status === "error") {
|
||||||
return "重新准备合同";
|
return "重新准备签署材料";
|
||||||
}
|
}
|
||||||
if (status === "ready") {
|
if (status === "ready") {
|
||||||
return "下载并查看合同";
|
return "下载并查看签署材料";
|
||||||
}
|
}
|
||||||
return "等待准备合同";
|
return "等待准备签署材料";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1126,7 +1126,7 @@ async function prepareContract(contract: any) {
|
|||||||
contractPrepareStatus[key] = "ready";
|
contractPrepareStatus[key] = "ready";
|
||||||
return true;
|
return true;
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
const message = err?.msg || err?.message || "合同准备失败,请稍后重试";
|
const message = err?.msg || err?.message || "签署材料准备失败,请稍后重试";
|
||||||
contractPrepareStatus[key] = "error";
|
contractPrepareStatus[key] = "error";
|
||||||
contractPrepareErrors[key] = message;
|
contractPrepareErrors[key] = message;
|
||||||
// 业务异常已由统一请求拦截器提示;仅为网络等非标准异常补充提示,避免重复弹窗。
|
// 业务异常已由统一请求拦截器提示;仅为网络等非标准异常补充提示,避免重复弹窗。
|
||||||
@@ -1150,7 +1150,7 @@ async function handleContractAction(contract: any) {
|
|||||||
if (isContractPrepareFailed(contract.id)) {
|
if (isContractPrepareFailed(contract.id)) {
|
||||||
const prepared = await prepareContract(contract);
|
const prepared = await prepareContract(contract);
|
||||||
if (prepared) {
|
if (prepared) {
|
||||||
ElMessage.success("合同已重新准备完成,请再次点击下载查看");
|
ElMessage.success("签署材料已重新准备完成,请再次点击下载查看");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1179,21 +1179,21 @@ function previewAndDownloadContract(c: any) {
|
|||||||
async function submitAll() {
|
async function submitAll() {
|
||||||
const unprepared = contracts.value.filter(c => !isContractPrepared(c.id));
|
const unprepared = contracts.value.filter(c => !isContractPrepared(c.id));
|
||||||
if (unprepared.length) {
|
if (unprepared.length) {
|
||||||
return ElMessage.warning(`请先等待合同准备完成:${unprepared.map(c => c.contractName).join("、")}`);
|
return ElMessage.warning(`请先等待签署材料准备完成:${unprepared.map(c => c.contractName).join("、")}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const unviewed = contracts.value.filter(c => !c.hasViewed);
|
const unviewed = contracts.value.filter(c => !c.hasViewed);
|
||||||
if (unviewed.length) {
|
if (unviewed.length) {
|
||||||
return ElMessage.warning(`请先下载并查看合同:${unviewed.map(c => c.contractName).join("、")}`);
|
return ElMessage.warning(`请先下载并查看签署材料:${unviewed.map(c => c.contractName).join("、")}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const unconfirmed = contracts.value.filter(c => !c.isAgreed);
|
const unconfirmed = contracts.value.filter(c => !c.isAgreed);
|
||||||
if (unconfirmed.length) {
|
if (unconfirmed.length) {
|
||||||
return ElMessage.warning(`请先勾选同意全部合同(未勾选:${unconfirmed.map(c => c.contractName).join("、")})`);
|
return ElMessage.warning(`请先勾选同意全部签署材料(未勾选:${unconfirmed.map(c => c.contractName).join("、")})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const confirmed = await isMessageBoxConfirmed(
|
const confirmed = await isMessageBoxConfirmed(
|
||||||
ElMessageBox.confirm("确认提交全部入职资料与合同确认?提交后将进入人事复核建档流程。", "最终提交确认", {
|
ElMessageBox.confirm("确认提交全部入职资料与签署材料确认?提交后将进入人事复核建档流程。", "最终提交确认", {
|
||||||
type: "success",
|
type: "success",
|
||||||
confirmButtonText: "确认提交",
|
confirmButtonText: "确认提交",
|
||||||
cancelButtonText: "再检查一下"
|
cancelButtonText: "再检查一下"
|
||||||
|
|||||||
Reference in New Issue
Block a user