Files
jinbooks/jinbooks-ui/src/views/hr/salary-voucher-rules/template.vue

314 lines
9.2 KiB
Vue
Raw Normal View History

2025-06-03 09:46:52 +08:00
<template>
<el-drawer v-model="dialogStatus" :close-on-click-modal="false" size="65%"
@close="dialogOfClosedMethods(false)">
<template #header>
<h4>{{ title }}</h4>
</template>
<template #default>
<div class="queryForm">
<el-form :model="form" ref="formRef" :inline="true" label-width="68px">
<el-form-item label="凭证类型">
2025-06-11 15:16:44 +08:00
<el-select v-model="form.voucherType" style="width: 200px" @change="handleChangeType">
2025-06-03 09:46:52 +08:00
<el-option v-for="item in voucherTypes" :label="item.label" :value="item.value"/>
</el-select>
</el-form-item>
<el-form-item label="凭证字">
<el-select v-model="form.wordHead" style="width: 200px" disabled>
<el-option v-for="item in voucherTypes" :label="item.label" :value="item.value"/>
</el-select>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="dataList" border>
<el-table-column prop="summary" label="摘要" align="left" min-width="90"
:show-overflow-tooltip="true">
<template #default="scope">
<el-input v-model="scope.row.summary" style="width: 100%"></el-input>
</template>
</el-table-column>
<el-table-column prop="direction" label="借/贷" align="center" min-width="40">
<template #default="scope">
<el-select v-model="scope.row.direction" style="width: 100%">
<el-option v-for="item in salary_directions" :label="item.label" :value="item.value"/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="subjectName" label="科目" align="left" min-width="110" :show-overflow-tooltip="true">
<template #default="scope">
<el-cascader
style="width: 100%"
filterable
2025-06-10 15:46:58 +08:00
v-model="scope.row.subjectCode"
2025-06-03 09:46:52 +08:00
:options="deptOptions"
:props="defaultProps"
/>
</template>
</el-table-column>
<el-table-column prop="selectedValue" label="取值" align="center" min-width="60"
:show-overflow-tooltip="true">
<template #default="scope">
<el-select v-model="scope.row.selectedValue" style="width: 100%">
2025-06-11 15:16:44 +08:00
<el-option v-for="item in salaryValuesList" :label="item.label" :value="item.value"/>
2025-06-03 09:46:52 +08:00
</el-select>
</template>
</el-table-column>
<el-table-column label="操作" align="center" header-align="center" width="120">
<template #default="scope">
<div >
<div>
<el-tooltip content="新增">
<el-button type="primary"
link @click="handleAdd()" icon="Plus"></el-button>
</el-tooltip>
<el-tooltip content="移除" v-if="dataList.length > 1">
<el-button type="primary"
link @click="handleDel(scope.$index)" icon="Delete"></el-button>
</el-tooltip>
</div>
</div>
</template>
</el-table-column>
</el-table>
</div>
</template>
<template #footer>
<div style="flex: auto">
<el-button @click="dialogOfClosedMethods(false)">{{ t('org.cancel') }}</el-button>
<el-button type="primary" @click="submitForm">{{ t('org.confirm') }}</el-button>
</div>
</template>
</el-drawer>
</template>
<script setup lang="ts">
import {useI18n} from "vue-i18n";
import {getCurrentInstance, reactive, ref, toRefs, watch} from "vue"
import {addRule, getById, updateRule} from "@/api/system/hr/voucher-rule";
import {ElForm} from "element-plus";
import {delConfigBalanceSheet} from "@/api/system/standard/standard-statement-balance-sheet";
import modal from "@/plugins/modal";
const {t} = useI18n()
const {proxy} = getCurrentInstance()!;
2025-06-11 15:16:44 +08:00
const {salary_values, salary_directions, labor_fee_values}
= proxy?.useDict( "salary_values", "salary_directions", "labor_fee_values");
2025-06-03 09:46:52 +08:00
const emit: any = defineEmits(['dialogOfClosedMethods'])
const formRef = ref<InstanceType<typeof ElForm> | null>(null);
2025-06-11 15:16:44 +08:00
interface SalaryValueItem {
label: string
value: string | number
}
const salaryValuesList = ref<SalaryValueItem[]>([])
2025-06-03 09:46:52 +08:00
const props: any = defineProps({
title: {
type: String,
default: ""
},
open: {
type: Boolean,
default: false
},
deptOptions: {
type: Array,
default: [],
},
voucherTypes: {
type: Array<any>,
default: [],
},
wordHeads: {
type: Array<any>,
default: []
},
formId: {
default: undefined
},
})
const defaultProps: any = ref({
expandTrigger: 'hover',
label: 'name',
2025-06-10 15:46:58 +08:00
value: 'code',
2025-06-03 09:46:52 +08:00
children: 'children',
checkStrictly: false,
emitPath: false,
defaultExpandAll: true,
showAllLevels: false,
clearable: false,
filterable: true
})
const data: any = reactive({
form: {
voucherType: 0,
wordHead: '记'
},
})
const {form} = toRefs(data);
const dialogStatus: any = ref(false);
const loading = ref(false);
// 1. 首先,为数据项定义一个明确的接口类型
interface VoucherItem {
id: null;
summary: string;
direction: string;
2025-06-10 15:46:58 +08:00
subjectCode: string | null;
2025-06-03 09:46:52 +08:00
selectedValue: string;
// 其他可能的字段...
[key: string]: any; // 这允许添加其他可能从后端返回的字段
}
// 2. 为dataList提供正确的类型
const dataList = ref<VoucherItem[]>([]);
const typeTextMap: Record<number, string> = {
0: "计提{yy}年{mm}月工资",
1: "发放{yy}年{mm}月工资",
2: "收票{yy}年{mm}月兼职人员工资",
3: "发放{yy}年{mm}月兼职人员工资"
}
watch(
() => props.open,
(val: any) => {
if (val) {
dialogStatus.value = props.open;
if (props.formId) {
getById(props.formId).then((res: any) => {
form.value = res.data;
dataList.value = res.data.employeeSalaryVoucherRules;
})
} else {
reset();
}
} else {
reset();
}
},
{immediate: true}
);
/** 重置操作表单 */
function reset(): any {
form.value = {
voucherType: 0,
wordHead: '记'
2025-06-11 15:16:44 +08:00
}
2025-06-03 09:46:52 +08:00
2025-06-11 15:16:44 +08:00
// 先根据 voucherType 给 salaryValuesList 赋值
if (form.value.voucherType === 0 || form.value.voucherType === 1) {
salaryValuesList.value = salary_values.value
} else {
salaryValuesList.value = labor_fee_values.value
}
2025-06-03 09:46:52 +08:00
2025-06-11 15:16:44 +08:00
// 取第一个值
const selectedValue = salaryValuesList.value.length > 0 ? salaryValuesList.value[0].value : null
2025-06-03 09:46:52 +08:00
2025-06-11 15:16:44 +08:00
// 设置 dataList
const summaryTemplate = typeTextMap[form.value.voucherType] || ""
dataList.value = [
{
id: null,
summary: summaryTemplate,
direction: "1",
subjectCode: props.deptOptions?.[0]?.code || null,
selectedValue: selectedValue,
}
]
formRef?.value?.resetFields()
2025-06-03 09:46:52 +08:00
}
2025-06-11 15:16:44 +08:00
function addRecord() {
2025-06-03 09:46:52 +08:00
const summaryTemplate = typeTextMap[form.value.voucherType] || "";
2025-06-11 15:16:44 +08:00
// 根据 voucherType 先切换数据源
if (form.value.voucherType === 0 || form.value.voucherType === 1) {
salaryValuesList.value = salary_values.value;
} else {
salaryValuesList.value = labor_fee_values.value;
}
// 如果 salaryValuesList 为空,安全处理(防止访问 undefined
const selectedValue = salaryValuesList.value.length > 0 ? salaryValuesList.value[0].value : null;
// 新增一条记录
2025-06-03 09:46:52 +08:00
dataList.value.push({
id: null,
summary: summaryTemplate,
direction: "1",
2025-06-10 15:46:58 +08:00
subjectCode: props.deptOptions?.[0]?.code || null,
2025-06-11 15:16:44 +08:00
selectedValue: selectedValue,
2025-06-03 09:46:52 +08:00
});
}
2025-06-11 15:16:44 +08:00
function handleChangeType() {
// 根据 voucherType 先切换数据源
if (form.value.voucherType === 0 || form.value.voucherType === 1) {
salaryValuesList.value = salary_values.value;
} else {
salaryValuesList.value = labor_fee_values.value;
}
}
2025-06-03 09:46:52 +08:00
function dialogOfClosedMethods(val: any): any {
dialogStatus.value = false;
emit('dialogOfClosedMethods', val);
}
function submitForm() {
if (dataList.value.length < 2) {
modal.msgWarning("请至少录入两条数据!");
return;
}
// 检查是否至少有一贷一借
const hasDebit = dataList.value.some((item: any) => item.direction == '1');
const hasCredit = dataList.value.some((item: any) => item.direction == '2');
if (!hasDebit || !hasCredit) {
modal.msgWarning("请至少录入一条借方和一条贷方数据!");
return;
}
const dataSave = {
...form.value,
salaryTemplateDetailDtos: dataList.value
}
if (props.formId) {
//修改
updateRule(dataSave).then((response: any) => {
if (response.code === 0) {
modal.msgSuccess("修改成功")
dialogOfClosedMethods(true);
reset();
} else {
modal.msgError(response.message)
}
})
} else {
addRule(dataSave).then((response: any) => {
if (response.code === 0) {
modal.msgSuccess("新增成功")
dialogOfClosedMethods(true);
reset();
} else {
modal.msgError(response.message)
}
})
}
}
function handleAdd() {
addRecord();
}
function handleDel(index: any) {
dataList.value.splice(index, 1)
}
</script>