From 55e155a169b63cea3262d95cf51705ef173a36c2 Mon Sep 17 00:00:00 2001
From: tuqin <tuqin@tuqin.cn>
Date: 星期一, 12 十月 2026 10:09:40 +0800
Subject: [PATCH] feat(hrm): 合同生成与模板下载、员工转正、导入导出字段对齐
---
src/views/hrm/employee/contract/index.vue | 156 +++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 117 insertions(+), 39 deletions(-)
diff --git a/src/views/hrm/employee/contract/index.vue b/src/views/hrm/employee/contract/index.vue
index 02aa33c..c28ef57 100644
--- a/src/views/hrm/employee/contract/index.vue
+++ b/src/views/hrm/employee/contract/index.vue
@@ -3,12 +3,17 @@
import type { HrmEmployeeContractApi } from '#/api/hrm/employee/contract';
import { Page, useVbenModal } from '#/packages/effects/common-ui/src';
+import { downloadFileFromBlobPart } from '#/packages/utils/src';
-import { message, Tag } from 'ant-design-vue';
+import { DownOutlined } from '@ant-design/icons-vue';
+import { Button, Dropdown, Menu, message, Modal, Tag } from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import {
deleteEmployeeContract,
+ downloadContractTemplate,
+ generateContractArchive,
+ generateContractDocx,
getEmployeeContractPage,
} from '#/api/hrm/employee/contract';
import { $t } from '#/locales';
@@ -17,6 +22,7 @@
import Form from './modules/form.vue';
import ImportForm from './modules/import-form.vue';
import Terminate from './modules/terminate.vue';
+import Attachment from './modules/attachment-modal.vue';
const [FormModal, formModalApi] = useVbenModal({
connectedComponent: Form,
@@ -30,6 +36,11 @@
const [TerminateModal, terminateModalApi] = useVbenModal({
connectedComponent: Terminate,
+ destroyOnClose: true,
+});
+
+const [AttachmentModal, attachmentModalApi] = useVbenModal({
+ connectedComponent: Attachment,
destroyOnClose: true,
});
@@ -48,6 +59,21 @@
importModalApi.open();
}
+/** 涓嬭浇鍚堝悓绌虹櫧妯℃澘锛歵ype 1-鍔冲姩鍚堝悓绠�鐗� 2-鍔冲姩鍚堝悓鏍囧噯 3-鍔冲姟鍚堝悓 */
+const TEMPLATE_NAMES: Record<number, string> = {
+ 1: '鍔冲姩鍚堝悓锛堢畝鐗堬級.docx',
+ 2: '鍔冲姩鍚堝悓锛堟爣鍑嗭級.docx',
+ 3: '鍔冲姟鍚堝悓.doc',
+};
+async function handleDownloadTemplate(type: number) {
+ const data = await downloadContractTemplate(type);
+ downloadFileFromBlobPart({
+ fileName: TEMPLATE_NAMES[type] || '鍚堝悓妯℃澘',
+ source: data,
+ });
+ message.success('妯℃澘宸蹭笅杞�');
+}
+
/** 缂栬緫鍚堝悓 */
function handleEdit(row: HrmEmployeeContractApi.EmployeeContract) {
formModalApi.setData({ id: row.id, formType: 'update' }).open();
@@ -61,6 +87,60 @@
/** 瑙i櫎/缁堟鍚堝悓 */
function handleTerminate(row: HrmEmployeeContractApi.EmployeeContract) {
terminateModalApi.setData({ id: row.id }).open();
+}
+
+/** 鏌ョ湅鍚堝悓闄勪欢 */
+function handleAttachments(row: HrmEmployeeContractApi.EmployeeContract) {
+ attachmentModalApi.setData({ id: row.id }).open();
+}
+
+/** 鐢熸垚鍚堝悓锛坉ocx锛夛細templateType 1-鍔冲姩鍚堝悓绠�鐗� 2-鍔冲姩鍚堝悓鏍囧噯 3-鍔冲姟鍚堝悓 */
+async function handleGenerate(
+ row: HrmEmployeeContractApi.EmployeeContract,
+ templateType: number,
+) {
+ // 1. 鐢熸垚骞跺洖瀛樹负鍚堝悓闄勪欢
+ await generateContractArchive(row.id!, templateType);
+ // 2. 鍚屾椂涓嬭浇涓�浠�
+ const data = await generateContractDocx(row.id!, templateType);
+ const genName =
+ { 1: '鍔冲姩鍚堝悓(绠�鐗�).docx', 2: '鍔冲姩鍚堝悓(鏍囧噯).docx', 3: '鍔冲姟鍚堝悓.docx' }[
+ templateType
+ ] || '鍚堝悓.docx';
+ downloadFileFromBlobPart({
+ fileName: `${row.contractNo || row.id}-${genName}`,
+ source: data,
+ });
+ message.success('鍚堝悓宸茬敓鎴愶紝骞跺綊妗e埌璇ュ悎鍚岄檮浠�');
+ handleRefresh();
+}
+
+/** 鈥滄洿澶氣�濊彍鍗曪細淇敼 / 缁 / 瑙i櫎缁堟 / 鍒犻櫎 */
+function handleMore({ key }: { key: number | string }, row: HrmEmployeeContractApi.EmployeeContract) {
+ switch (key) {
+ case 'edit': {
+ handleEdit(row);
+ break;
+ }
+ case 'renew': {
+ handleRenew(row);
+ break;
+ }
+ case 'terminate': {
+ handleTerminate(row);
+ break;
+ }
+ case 'delete': {
+ Modal.confirm({
+ title: `纭鍒犻櫎鍚堝悓銆�${row.contractNo || row.id}銆戝悧锛焋,
+ okText: '鍒犻櫎',
+ okType: 'danger',
+ cancelText: '鍙栨秷',
+ onOk: () => handleDelete(row),
+ });
+ break;
+ }
+ }
}
/** 鍒犻櫎鍚堝悓 */
@@ -110,6 +190,7 @@
<FormModal @success="handleRefresh" />
<ImportModal @success="handleRefresh" />
<TerminateModal @success="handleRefresh" />
+ <AttachmentModal />
<Grid table-title="鍛樺伐鍚堝悓鍒楄〃">
<template #parentNo="{ row }">
<span>{{ row.parentNo || '-' }}</span>
@@ -119,6 +200,18 @@
<span v-else>-</span>
</template>
<template #toolbar-tools>
+ <Dropdown>
+ <Button class="mr-2" type="primary">
+ 涓嬭浇鍚堝悓妯℃澘 <DownOutlined />
+ </Button>
+ <template #overlay>
+ <Menu @click="({ key }) => handleDownloadTemplate(Number(key))">
+ <Menu.Item key="1">鍔冲姩鍚堝悓锛堢畝鐗堬級</Menu.Item>
+ <Menu.Item key="2">鍔冲姩鍚堝悓锛堟爣鍑嗭級</Menu.Item>
+ <Menu.Item key="3">鍔冲姟鍚堝悓</Menu.Item>
+ </Menu>
+ </template>
+ </Dropdown>
<TableAction
:actions="[
{
@@ -139,44 +232,29 @@
/>
</template>
<template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: '缁',
- type: 'link',
- icon: ACTION_ICON.ADD,
- auth: ['hrm:employee-contract:create'],
- ifShow: isTerminable(row),
- onClick: handleRenew.bind(null, row),
- },
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['hrm:employee-contract:update'],
- onClick: handleEdit.bind(null, row),
- },
- {
- label: '瑙i櫎/缁堟',
- type: 'link',
- icon: ACTION_ICON.CLOSE,
- auth: ['hrm:employee-contract:update'],
- ifShow: isTerminable(row),
- onClick: handleTerminate.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['hrm:employee-contract:delete'],
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', ['鍛樺伐鍚堝悓']),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
+ <Dropdown>
+ <a class="text-primary" @click.prevent>鐢熸垚鍚堝悓 <DownOutlined /></a>
+ <template #overlay>
+ <Menu @click="({ key }) => handleGenerate(row, Number(key))">
+ <Menu.Item key="1">鍔冲姩鍚堝悓锛堢畝鐗堬級</Menu.Item>
+ <Menu.Item key="2">鍔冲姩鍚堝悓锛堟爣鍑嗭級</Menu.Item>
+ <Menu.Item key="3">鍔冲姟鍚堝悓</Menu.Item>
+ </Menu>
+ </template>
+ </Dropdown>
+ <a class="ml-3 text-primary" @click="handleAttachments(row)">闄勪欢</a>
+ <Dropdown>
+ <a class="ml-3 text-primary" @click.prevent>鏇村 <DownOutlined /></a>
+ <template #overlay>
+ <Menu @click="(e) => handleMore(e, row)">
+ <Menu.Item key="edit">淇敼</Menu.Item>
+ <Menu.Item v-if="isTerminable(row)" key="renew">缁</Menu.Item>
+ <Menu.Item v-if="isTerminable(row)" key="terminate">瑙i櫎/缁堟</Menu.Item>
+ <Menu.Divider />
+ <Menu.Item danger key="delete">鍒犻櫎</Menu.Item>
+ </Menu>
+ </template>
+ </Dropdown>
</template>
</Grid>
</Page>
--
Gitblit v1.9.3