| | |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { HrmSalaryPaymentApi } from '#/api/hrm/salary/payment'; |
| | | |
| | | import { Page } from '#/packages/effects/common-ui/src'; |
| | | import { ref } from 'vue'; |
| | | |
| | | import { Page, useVbenModal } from '#/packages/effects/common-ui/src'; |
| | | import { downloadFileFromBlobPart } from '#/packages/utils/src'; |
| | | |
| | | import { message } from 'ant-design-vue'; |
| | | import { message, Tag, DatePicker } from 'ant-design-vue'; |
| | | |
| | | import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; |
| | | import { |
| | | exportSalaryPayment, |
| | | generateSalaryPayment, |
| | | getSalaryPaymentPage, |
| | | paySalary, |
| | | revokeSalaryPayment, |
| | | } from '#/api/hrm/salary/payment'; |
| | | import { $t } from '#/locales'; |
| | | |
| | | import { useGridColumns, useGridFormSchema } from './data'; |
| | | import DetailModal from './modules/detail.vue'; |
| | | |
| | | const [DetailModalComp, detailModalApi] = useVbenModal({ |
| | | connectedComponent: DetailModal, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | // 生成台账弹窗 |
| | | const generateVisible = ref(false); |
| | | const generatePeriod = ref<string>(); |
| | | const generateLoading = ref(false); |
| | | |
| | | /** 刷新表格 */ |
| | | function handleRefresh() { |
| | | gridApi.query(); |
| | | } |
| | | |
| | | /** 执行薪资发放 */ |
| | | async function handlePay() { |
| | | const records = gridApi.grid.getCheckboxRecords() as HrmSalaryPaymentApi.SalaryPayment[]; |
| | | if (records.length === 0) { |
| | | message.warning('请选择要发放的记录'); |
| | | return; |
| | | } |
| | | const unpaidRecords = records.filter((r) => r.status === 10); |
| | | if (unpaidRecords.length === 0) { |
| | | message.warning('所选记录中没有待发放状态的记录'); |
| | | return; |
| | | } |
| | | const ids = unpaidRecords.map((r) => r.id!); |
| | | await paySalary(ids); |
| | | message.success('发放成功'); |
| | | handleRefresh(); |
| | | /** 打开生成台账弹窗 */ |
| | | function openGenerateModal() { |
| | | generatePeriod.value = undefined; |
| | | generateVisible.value = true; |
| | | } |
| | | |
| | | /** 撤销薪资发放 */ |
| | | async function handleRevoke(row: HrmSalaryPaymentApi.SalaryPayment) { |
| | | await revokeSalaryPayment(row.id!); |
| | | message.success('撤销成功'); |
| | | /** 生成发放台账 */ |
| | | async function handleGenerate() { |
| | | if (!generatePeriod.value) { |
| | | message.warning('请选择发放周期'); |
| | | return; |
| | | } |
| | | generateLoading.value = true; |
| | | try { |
| | | await generateSalaryPayment(generatePeriod.value); |
| | | message.success('生成发放台账成功'); |
| | | generateVisible.value = false; |
| | | handleRefresh(); |
| | | } finally { |
| | | generateLoading.value = false; |
| | | } |
| | | } |
| | | |
| | | /** 查看明细 */ |
| | | function handleViewDetail(row: HrmSalaryPaymentApi.SalaryPayment) { |
| | | detailModalApi.setData({ paymentId: row.id, period: row.period, status: row.status }).open(); |
| | | } |
| | | |
| | | /** 发放薪资 */ |
| | | async function handlePay(row: HrmSalaryPaymentApi.SalaryPayment) { |
| | | await paySalary(row.id!); |
| | | message.success('发放成功'); |
| | | handleRefresh(); |
| | | } |
| | | |
| | | /** 导出薪资发放 */ |
| | | async function handleExport() { |
| | | const data = await exportSalaryPayment(await gridApi.formApi.getValues()); |
| | | downloadFileFromBlobPart({ fileName: '薪资发放表.xls', source: data }); |
| | | downloadFileFromBlobPart({ fileName: '薪资发放台账.xls', source: data }); |
| | | } |
| | | |
| | | const [Grid, gridApi] = useVbenVxeGrid({ |
| | |
| | | columns: useGridColumns(), |
| | | height: 'auto', |
| | | keepSource: true, |
| | | checkboxConfig: { |
| | | highlight: true, |
| | | reserve: true, |
| | | }, |
| | | proxyConfig: { |
| | | ajax: { |
| | | query: async ({ page }, formValues) => |
| | |
| | | |
| | | <template> |
| | | <Page auto-content-height> |
| | | <Grid table-title="薪资发放列表"> |
| | | <DetailModalComp @success="handleRefresh" /> |
| | | |
| | | <!-- 生成台账弹窗 --> |
| | | <Modal |
| | | v-model:open="generateVisible" |
| | | title="生成发放台账" |
| | | width="400px" |
| | | :maskClosable="false" |
| | | > |
| | | <Form layout="vertical"> |
| | | <FormItem label="发放周期" required> |
| | | <DatePicker |
| | | v-model:value="generatePeriod" |
| | | picker="month" |
| | | format="YYYY-MM" |
| | | valueFormat="YYYY-MM" |
| | | placeholder="请选择发放周期" |
| | | style="width: 100%" |
| | | /> |
| | | </FormItem> |
| | | </Form> |
| | | <template #footer> |
| | | <a-button @click="generateVisible = false">取消</a-button> |
| | | <a-button type="primary" :loading="generateLoading" @click="handleGenerate"> |
| | | 确定 |
| | | </a-button> |
| | | </template> |
| | | </Modal> |
| | | |
| | | <Grid table-title="薪资发放台账"> |
| | | <template #toolbar-tools> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: '发放', |
| | | label: '生成台账', |
| | | type: 'primary', |
| | | icon: ACTION_ICON.EDIT, |
| | | auth: ['hrm:salary-payment:pay'], |
| | | onClick: handlePay, |
| | | icon: ACTION_ICON.ADD, |
| | | auth: ['hrm:salary-payment:generate'], |
| | | onClick: openGenerateModal, |
| | | }, |
| | | { |
| | | label: $t('ui.actionTitle.export'), |
| | |
| | | ]" |
| | | /> |
| | | </template> |
| | | <template #status="{ row }"> |
| | | <Tag :color="row.status === 0 ? 'warning' : 'success'"> |
| | | {{ row.status === 0 ? '待发放' : '已发放' }} |
| | | </Tag> |
| | | </template> |
| | | <template #actions="{ row }"> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: '撤销', |
| | | label: '查看明细', |
| | | type: 'link', |
| | | auth: ['hrm:salary-payment:revoke'], |
| | | ifShow: row.status === 20, |
| | | onClick: handleViewDetail.bind(null, row), |
| | | }, |
| | | { |
| | | label: '发放', |
| | | type: 'link', |
| | | icon: ACTION_ICON.EDIT, |
| | | auth: ['hrm:salary-payment:pay'], |
| | | ifShow: row.status === 0, |
| | | popConfirm: { |
| | | title: '确认撤销该发放记录吗?', |
| | | confirm: handleRevoke.bind(null, row), |
| | | title: '确认发放该周期的薪资吗?', |
| | | confirm: handlePay.bind(null, row), |
| | | }, |
| | | }, |
| | | ]" |