<script lang="ts" setup>
|
import type { HrmSalaryPaymentApi } from '#/api/hrm/salary/payment';
|
|
import { ref, computed } from 'vue';
|
|
import { useVbenModal } from '#/packages/effects/common-ui/src';
|
|
import { message, Table, Tag, InputNumber, Alert } from 'ant-design-vue';
|
|
import { ACTION_ICON, TableAction } from '#/adapter/vxe-table';
|
import { getSalaryPaymentDetailList, paySalaryDetail } from '#/api/hrm/salary/payment';
|
import { $t } from '#/locales';
|
|
const emit = defineEmits(['success']);
|
|
const paymentId = ref<number>();
|
const period = ref<string>();
|
const status = ref<number>();
|
const detailList = ref<HrmSalaryPaymentApi.SalaryPaymentDetail[]>([]);
|
const loading = ref(false);
|
const selectedIds = ref<number[]>([]);
|
const payLoading = ref(false);
|
|
const isPaid = computed(() => status.value === 10);
|
|
const columns = [
|
{ title: '员工姓名', dataIndex: 'userName', width: 100, fixed: 'left' },
|
{ title: '部门', dataIndex: 'deptName', width: 120 },
|
{ title: '基本工资', dataIndex: 'baseSalary', width: 100 },
|
{ title: '绩效工资', dataIndex: 'performanceSalary', width: 100 },
|
{ title: '社保扣款', dataIndex: 'socialSecurityDeduction', width: 100 },
|
{ title: '公积金扣款', dataIndex: 'housingFundDeduction', width: 100 },
|
{ title: '个税扣款', dataIndex: 'taxDeduction', width: 100 },
|
{ title: '请假扣款', dataIndex: 'leaveDeduction', width: 100 },
|
{ title: '发放时间', dataIndex: 'paymentTime', width: 160 },
|
{ title: '实发工资', dataIndex: 'actualSalary', width: 100, fixed: 'right' },
|
{
|
title: '状态',
|
dataIndex: 'status',
|
width: 80,
|
fixed: 'right',
|
key: 'status',
|
},
|
];
|
|
/** 批量发放 */
|
async function handleBatchPay() {
|
if (selectedIds.value.length === 0) {
|
message.warning('请选择要发放的明细');
|
return;
|
}
|
payLoading.value = true;
|
try {
|
await paySalaryDetail(selectedIds.value);
|
message.success('发放成功');
|
emit('success');
|
// 刷新明细列表
|
detailList.value = await getSalaryPaymentDetailList(paymentId.value!);
|
selectedIds.value = [];
|
} finally {
|
payLoading.value = false;
|
}
|
}
|
|
/** 单条发放 */
|
async function handlePayDetail(row: HrmSalaryPaymentApi.SalaryPaymentDetail) {
|
await paySalaryDetail([row.id!]);
|
message.success('发放成功');
|
emit('success');
|
// 刷新明细列表
|
detailList.value = await getSalaryPaymentDetailList(paymentId.value!);
|
}
|
|
/** 选择行 */
|
function onSelectChange(selectedRowKeys: number[]) {
|
selectedIds.value = selectedRowKeys;
|
}
|
|
const [Modal, modalApi] = useVbenModal({
|
async onOpenChange(isOpen: boolean) {
|
if (!isOpen) {
|
detailList.value = [];
|
selectedIds.value = [];
|
return;
|
}
|
const data = modalApi.getData<{ paymentId: number; period: string; status: number }>();
|
paymentId.value = data.paymentId;
|
period.value = data.period;
|
status.value = data.status;
|
loading.value = true;
|
try {
|
detailList.value = await getSalaryPaymentDetailList(data.paymentId);
|
} finally {
|
loading.value = false;
|
}
|
},
|
});
|
</script>
|
|
<template>
|
<Modal :title="`${period} - 薪资发放明细`" class="w-[1100px]" :footer="null">
|
<Alert
|
v-if="!isPaid"
|
message="勾选需要发放的员工明细,点击批量发放按钮进行发放"
|
type="info"
|
show-icon
|
style="margin-bottom: 16px"
|
/>
|
|
<div v-if="!isPaid" class="mb-3">
|
<a-button type="primary" :loading="payLoading" :disabled="selectedIds.length === 0" @click="handleBatchPay">
|
批量发放 (已选 {{ selectedIds.length }} 条)
|
</a-button>
|
</div>
|
|
<Table
|
:columns="columns"
|
:data-source="detailList"
|
:loading="loading"
|
:pagination="false"
|
:scroll="{ x: 1200, y: 400 }"
|
:row-selection="!isPaid ? { selectedRowKeys: selectedIds, onChange: onSelectChange } : undefined"
|
size="small"
|
row-key="id"
|
bordered
|
>
|
<template #bodyCell="{ column, record }">
|
<template v-if="column.key === 'status'">
|
<Tag :color="record.status === 0 ? 'warning' : 'success'">
|
{{ record.status === 0 ? '待发放' : '已发放' }}
|
</Tag>
|
</template>
|
<template v-else-if="column.dataIndex === 'actualSalary'">
|
<span class="font-bold text-green-600">{{ record.actualSalary?.toFixed(2) }}</span>
|
</template>
|
<template v-else-if="column.dataIndex && ['baseSalary', 'performanceSalary', 'socialSecurityDeduction', 'housingFundDeduction', 'taxDeduction', 'leaveDeduction'].includes(column.dataIndex)">
|
{{ (record[column.dataIndex] || 0).toFixed(2) }}
|
</template>
|
</template>
|
</Table>
|
</Modal>
|
</template>
|