From 611dd8268e40caa4d97e8954b85b5adaaef99afa Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期一, 26 十月 2026 17:45:58 +0800
Subject: [PATCH] feat(hrm): 考勤规则支持地图定位打卡
---
src/views/hrm/employee/contract/index.vue | 176 +++++++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 137 insertions(+), 39 deletions(-)
diff --git a/src/views/hrm/employee/contract/index.vue b/src/views/hrm/employee/contract/index.vue
index 8f69373..53c329f 100644
--- a/src/views/hrm/employee/contract/index.vue
+++ b/src/views/hrm/employee/contract/index.vue
@@ -3,27 +3,44 @@
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 { IconifyIcon } from '@vben/icons';
+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';
import { useGridColumns, useGridFormSchema } from './data';
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,
destroyOnClose: true,
});
+const [ImportModal, importModalApi] = useVbenModal({
+ connectedComponent: ImportForm,
+ destroyOnClose: true,
+});
+
const [TerminateModal, terminateModalApi] = useVbenModal({
connectedComponent: Terminate,
+ destroyOnClose: true,
+});
+
+const [AttachmentModal, attachmentModalApi] = useVbenModal({
+ connectedComponent: Attachment,
destroyOnClose: true,
});
@@ -35,6 +52,26 @@
/** 鏂板鍚堝悓 */
function handleCreate() {
formModalApi.setData({ formType: 'create' }).open();
+}
+
+/** 瀵煎叆鍚堝悓 */
+function handleImport() {
+ 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('妯℃澘宸蹭笅杞�');
}
/** 缂栬緫鍚堝悓 */
@@ -50,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;
+ }
+ }
}
/** 鍒犻櫎鍚堝悓 */
@@ -97,7 +188,9 @@
<template>
<Page auto-content-height>
<FormModal @success="handleRefresh" />
+ <ImportModal @success="handleRefresh" />
<TerminateModal @success="handleRefresh" />
+ <AttachmentModal />
<Grid table-title="鍛樺伐鍚堝悓鍒楄〃">
<template #parentNo="{ row }">
<span>{{ row.parentNo || '-' }}</span>
@@ -107,6 +200,19 @@
<span v-else>-</span>
</template>
<template #toolbar-tools>
+ <Dropdown>
+ <Button class="mr-2" type="primary">
+ 涓嬭浇鍚堝悓妯℃澘 <IconifyIcon class="size-3" icon="lucide:chevron-down" />
+ </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.Item key="4">閫�浼戣繑鑱樺悎鍚�</Menu.Item>
+ </Menu>
+ </template>
+ </Dropdown>
<TableAction
:actions="[
{
@@ -116,48 +222,40 @@
auth: ['hrm:employee-contract:create'],
onClick: handleCreate,
},
+ {
+ label: '瀵煎叆',
+ type: 'primary',
+ icon: ACTION_ICON.UPLOAD,
+ auth: ['hrm:employee-contract:import'],
+ onClick: handleImport,
+ },
]"
/>
</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>鐢熸垚鍚堝悓 <IconifyIcon class="size-3" icon="lucide:chevron-down" /></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>鏇村 <IconifyIcon class="size-3" icon="lucide:chevron-down" /></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