代码优化

This commit is contained in:
fuenmao
2026-08-27 11:09:33 +08:00
parent c091fc92b6
commit 6d4ad7236f
7 changed files with 629 additions and 87 deletions
+256 -16
View File
@@ -1,4 +1,4 @@
<template>
<template>
<div class="main-box setup-container">
<el-tabs v-model="activeTab" class="setup-tabs">
<!-- 1. 入职公司管理 -->
@@ -36,7 +36,48 @@
</div>
</el-tab-pane>
<!-- 2. 入职岗位管理 -->
<!-- 2. 入职部门管理 -->
<el-tab-pane label="入职部门" name="department">
<div class="table-wrapper">
<ProTable
ref="departmentTable"
title="入职部门列表"
:columns="departmentColumns"
:request-api="onboardingTaskApi.departmentPage"
:search-col="5"
>
<template #tableHeader>
<el-button type="primary" icon="Plus" @click="openDepartmentCreate">
新增入职部门
</el-button>
</template>
<template #companyId="scope">
<el-tag effect="plain" type="primary">
{{ scope.row.companyName || getCompanyName(scope.row.companyId) }}
</el-tag>
</template>
<template #status="scope">
<el-tag size="small" :type="scope.row.status === 'enable' ? 'success' : 'info'">
{{ scope.row.status === "enable" ? "启用" : "停用" }}
</el-tag>
</template>
<template #operation="scope">
<el-button link type="primary" icon="Edit" @click="openDepartmentEdit(scope.row)">
编辑
</el-button>
<el-button link type="danger" icon="Delete" @click="removeDepartment(scope.row)">
删除
</el-button>
</template>
</ProTable>
</div>
</el-tab-pane>
<!-- 3. 入职岗位管理 -->
<el-tab-pane label="入职岗位" name="position">
<div class="table-wrapper">
<ProTable
@@ -54,10 +95,17 @@
<template #companyId="scope">
<el-tag effect="plain" type="primary">
{{ getCompanyName(scope.row.companyId) }}
{{ scope.row.companyName || getCompanyName(scope.row.companyId) }}
</el-tag>
</template>
<template #departmentName="scope">
<el-tag v-if="scope.row.departmentName" effect="light" type="warning">
{{ scope.row.departmentName }}
</el-tag>
<span v-else class="text-gray-400">-</span>
</template>
<template #status="scope">
<el-tag size="small" :type="scope.row.status === 'enable' ? 'success' : 'info'">
{{ scope.row.status === "enable" ? "启用" : "停用" }}
@@ -86,6 +134,7 @@
destroy-on-close
append-to-body
>
<!-- 1. 公司表单 -->
<el-form v-if="dialogKind === 'company'" :model="companyForm" label-width="140px">
<el-row :gutter="20">
<el-col :span="12">
@@ -142,9 +191,10 @@
</el-form-item>
</el-form>
<el-form v-else :model="positionForm" label-width="140px">
<!-- 2. 部门表单 -->
<el-form v-else-if="dialogKind === 'department'" :model="departmentForm" label-width="140px">
<el-form-item label="所属公司" required>
<el-select v-model="positionForm.companyId" placeholder="请选择所属公司" filterable class="w-full">
<el-select v-model="departmentForm.companyId" placeholder="请选择所属公司" filterable class="w-full">
<el-option
v-for="company in companies"
:key="company.id"
@@ -154,6 +204,77 @@
</el-select>
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="部门编码" required>
<el-input v-model="departmentForm.departmentCode" placeholder="如:DEPT_TECH" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="部门名称" required>
<el-input v-model="departmentForm.departmentName" placeholder="如:技术研发部" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="显示排序">
<el-input-number v-model="departmentForm.sortCode" :min="1" :max="999" class="w-full" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="状态" required>
<el-select v-model="departmentForm.status" class="w-full">
<el-option label="启用" value="enable" />
<el-option label="停用" value="disable" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="备注">
<el-input v-model="departmentForm.remark" type="textarea" :rows="2" placeholder="备注信息" />
</el-form-item>
</el-form>
<!-- 3. 岗位表单 -->
<el-form v-else :model="positionForm" label-width="140px">
<el-form-item label="所属公司" required>
<el-select
v-model="positionForm.companyId"
placeholder="请选择所属公司"
filterable
class="w-full"
@change="onPositionCompanyChange"
>
<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="所属部门" required>
<el-select
v-model="positionForm.departmentId"
placeholder="请先选择所属公司"
filterable
clearable
class="w-full"
:disabled="!positionForm.companyId"
>
<el-option
v-for="dept in formDepartments"
:key="dept.id"
:label="dept.departmentName"
:value="dept.id"
/>
</el-select>
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="岗位编码" required>
@@ -208,6 +329,8 @@ import {
onboardingTaskApi,
type OnboardingCompany,
type OnboardingCompanyOption,
type OnboardingDepartment,
type OnboardingDepartmentOption,
type OnboardingPosition
} from "@/api/modules/biz/onboarding";
import type { ColumnProps, ProTableInstance, EnumProps } from "@/components/ProTable/interface";
@@ -215,9 +338,12 @@ import type { ColumnProps, ProTableInstance, EnumProps } from "@/components/ProT
const activeTab = ref("company");
const companyTable = ref<ProTableInstance>();
const departmentTable = ref<ProTableInstance>();
const positionTable = ref<ProTableInstance>();
const companies = ref<OnboardingCompanyOption[]>([]);
const formDepartments = ref<OnboardingDepartmentOption[]>([]);
const companyOptions = computed<EnumProps[]>(() =>
companies.value.map(c => ({
label: c.companyName,
@@ -232,7 +358,7 @@ const getCompanyName = (companyId?: number) => {
};
const dialogVisible = ref(false);
const dialogKind = ref<"company" | "position">("company");
const dialogKind = ref<"company" | "department" | "position">("company");
const editing = ref(false);
const emptyCompany = (): Partial<OnboardingCompany> => ({
@@ -247,8 +373,18 @@ const emptyCompany = (): Partial<OnboardingCompany> => ({
remark: ""
});
const emptyDepartment = (): Partial<OnboardingDepartment> => ({
companyId: undefined,
departmentCode: "",
departmentName: "",
sortCode: 99,
status: "enable",
remark: ""
});
const emptyPosition = (): Partial<OnboardingPosition> => ({
companyId: undefined,
departmentId: undefined,
positionCode: "",
positionName: "",
defaultContractYears: 3,
@@ -258,11 +394,15 @@ const emptyPosition = (): Partial<OnboardingPosition> => ({
});
const companyForm = reactive<Partial<OnboardingCompany>>(emptyCompany());
const departmentForm = reactive<Partial<OnboardingDepartment>>(emptyDepartment());
const positionForm = reactive<Partial<OnboardingPosition>>(emptyPosition());
const dialogTitle = computed(
() => `${editing.value ? "编辑" : "新增"}${dialogKind.value === "company" ? "入职公司" : "入职岗位"}`
);
const dialogTitle = computed(() => {
const prefix = editing.value ? "编辑" : "新增";
if (dialogKind.value === "company") return `${prefix}入职公司`;
if (dialogKind.value === "department") return `${prefix}入职部门`;
return `${prefix}入职岗位`;
});
const companyColumns: ColumnProps<OnboardingCompany>[] = [
{
@@ -316,7 +456,7 @@ const companyColumns: ColumnProps<OnboardingCompany>[] = [
}
];
const positionColumns: ColumnProps<OnboardingPosition>[] = [
const departmentColumns: ColumnProps<OnboardingDepartment>[] = [
{
prop: "companyId",
label: "所属公司",
@@ -327,6 +467,59 @@ const positionColumns: ColumnProps<OnboardingPosition>[] = [
props: { filterable: true, placeholder: "请选择所属公司" }
}
},
{
prop: "departmentCode",
label: "部门编码",
width: 160,
search: { el: "input" }
},
{
prop: "departmentName",
label: "部门名称",
minWidth: 180,
search: { el: "input" }
},
{
prop: "sortCode",
label: "显示排序",
width: 110,
align: "center"
},
{
prop: "status",
label: "状态",
width: 100,
align: "center",
enum: [
{ label: "启用", value: "enable" },
{ label: "停用", value: "disable" }
],
search: { el: "select" }
},
{
prop: "operation",
label: "操作",
fixed: "right",
width: 160
}
];
const positionColumns: ColumnProps<OnboardingPosition>[] = [
{
prop: "companyId",
label: "所属公司",
minWidth: 180,
enum: companyOptions,
search: {
el: "select",
props: { filterable: true, placeholder: "请选择所属公司" }
}
},
{
prop: "departmentName",
label: "所属部门",
minWidth: 180
},
{
prop: "positionCode",
label: "岗位编码",
@@ -374,13 +567,31 @@ const positionColumns: ColumnProps<OnboardingPosition>[] = [
async function loadCompanies() {
const { data } = await onboardingTaskApi.listCompanies();
companies.value = data;
companies.value = data || [];
}
async function loadDepartmentsForCompany(companyId?: number) {
if (!companyId) {
formDepartments.value = [];
return;
}
const { data } = await onboardingTaskApi.listDepartments(companyId);
formDepartments.value = data || [];
}
async function onPositionCompanyChange(companyId?: number) {
positionForm.departmentId = undefined;
await loadDepartmentsForCompany(companyId);
}
function resetCompany() {
Object.assign(companyForm, emptyCompany());
}
function resetDepartment() {
Object.assign(departmentForm, emptyDepartment());
}
function resetPosition() {
Object.assign(positionForm, emptyPosition());
}
@@ -392,10 +603,18 @@ function openCompanyCreate() {
dialogVisible.value = true;
}
function openDepartmentCreate() {
dialogKind.value = "department";
editing.value = false;
resetDepartment();
dialogVisible.value = true;
}
function openPositionCreate() {
dialogKind.value = "position";
editing.value = false;
resetPosition();
formDepartments.value = [];
dialogVisible.value = true;
}
@@ -407,11 +626,22 @@ async function openCompanyEdit(row: OnboardingCompany) {
dialogVisible.value = true;
}
async function openDepartmentEdit(row: OnboardingDepartment) {
const { data } = await onboardingTaskApi.departmentDetail({ id: row.id });
dialogKind.value = "department";
editing.value = true;
Object.assign(departmentForm, data);
dialogVisible.value = true;
}
async function openPositionEdit(row: OnboardingPosition) {
const { data } = await onboardingTaskApi.positionDetail({ id: row.id });
dialogKind.value = "position";
editing.value = true;
Object.assign(positionForm, data);
if (data?.companyId) {
await loadDepartmentsForCompany(data.companyId);
}
dialogVisible.value = true;
}
@@ -420,15 +650,19 @@ async function save() {
if (!companyForm.companyCode || !companyForm.companyName || !companyForm.legalName) {
return ElMessage.warning("请填写公司编码、公司名称和合同甲方全称");
}
await onboardingTaskApi.saveCompany(companyForm, editing.value);
companyTable.value?.refresh();
await loadCompanies();
} else if (dialogKind.value === "department") {
if (!departmentForm.companyId || !departmentForm.departmentCode || !departmentForm.departmentName) {
return ElMessage.warning("请填写所属公司、部门编码和部门名称");
}
await onboardingTaskApi.saveDepartment(departmentForm, editing.value);
departmentTable.value?.refresh();
} else {
if (!positionForm.companyId || !positionForm.positionCode || !positionForm.positionName) {
return ElMessage.warning("请填写所属公司、岗位编码和岗位名称");
if (!positionForm.companyId || !positionForm.departmentId || !positionForm.positionCode || !positionForm.positionName) {
return ElMessage.warning("请填写所属公司、所属部门、岗位编码和岗位名称");
}
await onboardingTaskApi.savePosition(positionForm, editing.value);
positionTable.value?.refresh();
}
@@ -444,6 +678,12 @@ async function removeCompany(row: OnboardingCompany) {
await loadCompanies();
}
async function removeDepartment(row: OnboardingDepartment) {
await ElMessageBox.confirm(`确认删除部门“${row.departmentName}”?`, "删除确认", { type: "warning" });
await onboardingTaskApi.deleteDepartment([row.id]);
departmentTable.value?.refresh();
}
async function removePosition(row: OnboardingPosition) {
await ElMessageBox.confirm(`确认删除岗位“${row.positionName}”?`, "删除确认", { type: "warning" });
await onboardingTaskApi.deletePosition([row.id]);
@@ -522,4 +762,4 @@ onMounted(loadCompanies);
.w-full {
width: 100%;
}
</style>
</style>