This commit is contained in:
fuenmao
2026-08-25 20:37:24 +08:00
parent aec6c1f36c
commit eab359d9fa
6 changed files with 1748 additions and 1503 deletions
+170 -97
View File
@@ -82,7 +82,7 @@
<el-drawer
v-model="drawerVisible"
:title="`合同模板管理 · ${selectedTemplate?.templateName || ''}`"
size="960px"
size="1150px"
destroy-on-close
>
<div v-if="selectedTemplate" class="drawer-content-box">
@@ -135,54 +135,56 @@
<el-table-column prop="expiryDate" label="失效日期" width="130" align="center" />
<el-table-column prop="remark" label="版本说明" min-width="150" />
<el-table-column label="操作" width="280" fixed="right">
<el-table-column label="操作" width="340" fixed="right" align="center">
<template #default="scope">
<el-button
link
type="primary"
icon="Setting"
@click="openVariables(scope.row)"
>
变量
</el-button>
<div class="table-actions">
<el-button
link
type="primary"
icon="Setting"
@click="openVariables(scope.row)"
>
变量
</el-button>
<el-button
link
type="primary"
icon="Download"
@click="downloadDocx(scope.row.sourceDocxFileId)"
>
下载源文件
</el-button>
<el-button
link
type="primary"
icon="Download"
@click="downloadDocx(scope.row.sourceDocxFileId)"
>
下载源文件
</el-button>
<el-button
v-if="scope.row.versionStatus !== 'enabled'"
link
type="success"
icon="Check"
@click="changeVersionStatus(scope.row, 'enabled')"
>
启用
</el-button>
<el-button
v-if="scope.row.versionStatus !== 'enabled'"
link
type="success"
icon="Check"
@click="changeVersionStatus(scope.row, 'enabled')"
>
启用
</el-button>
<el-button
v-else
link
type="warning"
icon="Close"
@click="changeVersionStatus(scope.row, 'disabled')"
>
停用
</el-button>
<el-button
v-else
link
type="warning"
icon="Close"
@click="changeVersionStatus(scope.row, 'disabled')"
>
停用
</el-button>
<el-button
link
type="danger"
icon="Delete"
@click="removeVersion(scope.row)"
>
删除
</el-button>
<el-button
link
type="danger"
icon="Delete"
@click="removeVersion(scope.row)"
>
删除
</el-button>
</div>
</template>
</el-table-column>
</el-table>
@@ -257,69 +259,87 @@
<el-dialog
v-model="variablesVisible"
:title="`合同变量配置 · 版本 ${selectedVersion?.versionNo || ''}`"
width="1050px"
width="1220px"
top="4vh"
destroy-on-close
append-to-body
class="variables-dialog"
>
<el-alert
title="变量已从 DOCX 自动识别。请逐项检查来源、显示名称、数据类型和取值字段;未识别变量调整完成后才能启用版本。"
title="变量已从 DOCX 自动识别与解析。请核对来源分类、显示名称及数据类型;确保全部配置正确后即可启用版本。"
type="info"
show-icon
:closable="false"
class="mb-3"
/>
<el-table :data="variables" border stripe class="mt-3">
<el-table-column prop="variableCode" label="变量编码 (DOCX占位符)" min-width="220">
<template #default="scope">
<div style="display: flex; align-items: center; justify-content: space-between;">
<code style="font-weight: 600; color: #2563eb;">{{ formatPlaceholder(scope.row.variableCode) }}</code>
<el-button
size="small"
link
type="primary"
icon="CopyDocument"
@click="copyPlaceholder(scope.row.variableCode)"
>
复制
<!-- 分组 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.employee})`" name="employee" />
<el-tab-pane :label="`人事合同参数 (${variableCounts.hr})`" name="hr" />
<el-tab-pane :label="`公司信息 (${variableCounts.company})`" name="company" />
<el-tab-pane :label="`系统预置 (${variableCounts.system})`" name="system" />
</el-tabs>
<div class="variables-table-wrapper">
<el-table :data="filteredVariables" border stripe height="500px">
<el-table-column prop="variableCode" label="变量全编码 (DOCX占位符)" min-width="260">
<template #default="scope">
<div class="variable-code-cell">
<code class="code-font">{{ formatPlaceholder(scope.row.variableCode) }}</code>
<el-button
size="small"
link
type="primary"
icon="CopyDocument"
@click="copyPlaceholder(scope.row.variableCode)"
>
复制
</el-button>
</div>
</template>
</el-table-column>
<el-table-column prop="variableName" label="变量显示名称" min-width="170" />
<el-table-column prop="variableType" label="来源板块" width="130" align="center">
<template #default="scope">
<el-tag size="small" :type="variableTypeTag(scope.row.variableType)">
{{ variableTypeText(scope.row.variableType) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="dataType" label="数据类型" width="100" align="center">
<template #default="scope">
<el-tag size="small" type="info">{{ scope.row.dataType || 'string' }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="employeeField" label="对应字段" min-width="160" show-overflow-tooltip />
<el-table-column label="必填" width="80" align="center">
<template #default="scope">
<el-tag size="small" :type="scope.row.required ? 'danger' : 'info'">
{{ scope.row.required ? "是" : "否" }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="120" align="center" fixed="right">
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="openVariableEdit(scope.row)">
检查调整
</el-button>
</div>
</template>
</el-table-column>
</template>
</el-table-column>
</el-table>
</div>
<el-table-column prop="variableName" label="变量显示名称" min-width="160" />
<el-table-column prop="variableType" label="来源类型" width="130" align="center">
<template #default="scope">
<el-tag size="small" :type="variableTypeTag(scope.row.variableType)">
{{ variableTypeText(scope.row.variableType) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="dataType" label="数据类型" width="100" align="center">
<template #default="scope">
<el-tag size="small" type="info">{{ scope.row.dataType }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="employeeField" label="对应员工字段" min-width="140" />
<el-table-column label="必填" width="80" align="center">
<template #default="scope">
<el-tag size="small" :type="scope.row.required ? 'danger' : 'info'">
{{ scope.row.required ? "是" : "否" }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="150" fixed="right">
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="openVariableEdit(scope.row)">
检查调整
</el-button>
</template>
</el-table-column>
</el-table>
<template #footer>
<el-button type="primary" @click="variablesVisible = false">关闭</el-button>
</template>
</el-dialog>
<!-- 新增 / 编辑单个变量 -->
@@ -391,7 +411,7 @@
</template>
<script setup lang="ts" name="onboardingContract">
import { reactive, ref } from "vue";
import { computed, reactive, ref } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { Check } from "@element-plus/icons-vue";
import {
@@ -414,6 +434,25 @@ const versionVisible = ref(false);
const variablesVisible = ref(false);
const variables = ref<OnboardingTemplateVariable[]>([]);
const variableVisible = ref(false);
const variableTab = ref("all");
const filteredVariables = computed(() => {
if (variableTab.value === "all") return variables.value;
if (variableTab.value === "employee") return variables.value.filter(v => v.variableType === "employee");
if (variableTab.value === "hr") return variables.value.filter(v => v.variableType === "hr" || v.variableType === "contract" || v.variableCode.startsWith("hr."));
if (variableTab.value === "company") return variables.value.filter(v => v.variableType === "company");
if (variableTab.value === "system") return variables.value.filter(v => v.variableType === "system");
return variables.value;
});
const variableCounts = computed(() => {
const all = variables.value.length;
const employee = variables.value.filter(v => v.variableType === "employee").length;
const hr = variables.value.filter(v => v.variableType === "hr" || v.variableType === "contract" || v.variableCode.startsWith("hr.")).length;
const company = variables.value.filter(v => v.variableType === "company").length;
const system = variables.value.filter(v => v.variableType === "system").length;
return { all, employee, hr, company, system };
});
const emptyTemplate = (): Partial<OnboardingContractTemplate> => ({
templateCode: "",
@@ -734,4 +773,38 @@ async function saveVariable() {
display: flex;
align-items: center;
}
.table-actions {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 4px;
white-space: nowrap;
}
.variable-filter-tabs {
margin-bottom: 12px;
}
.variables-table-wrapper {
border-radius: 6px;
overflow: hidden;
}
.variable-code-cell {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
white-space: nowrap;
}
.code-font {
font-family: Consolas, Monaco, monospace;
font-weight: 600;
color: #2563eb;
background: #eff6ff;
padding: 2px 6px;
border-radius: 4px;
}
</style>