feat:费用管理

This commit is contained in:
2025-09-13 00:11:58 +08:00
parent b0cf0a821c
commit 2a75473397
14 changed files with 301 additions and 154 deletions

View File

@@ -70,6 +70,7 @@ export interface CostItemSettingVO {
* 搜索值 * 搜索值
*/ */
searchValue: string; searchValue: string;
chargeNo: string;
} }

View File

@@ -54,6 +54,14 @@ export function houseChargeRefund(data: HouseChargeForm) {
export function houseChargeUpdate(data: HouseChargeForm) { export function houseChargeUpdate(data: HouseChargeForm) {
return requestClient.putWithMsg<void>('/property/houseCharge', data); return requestClient.putWithMsg<void>('/property/houseCharge', data);
} }
/**
* 更正房屋收费
* @param data
* @returns void
*/
export function houseChargeAddFee(data: HouseChargeForm) {
return requestClient.postWithMsg<void>('/property/houseCharge/addFee', data);
}
/** /**
* 删除房屋收费 * 删除房屋收费

View File

@@ -43,7 +43,7 @@ export interface HouseChargeVO {
*/ */
remark: string; remark: string;
chargeTime: any[]; chargeTime: string;
/** /**
* 缴费周期 * 缴费周期
*/ */

View File

@@ -7,6 +7,14 @@ import { h } from 'vue';
import { resident_unitList } from '#/api/property/resident/unit'; import { resident_unitList } from '#/api/property/resident/unit';
export const querySchema: FormSchemaGetter = () => [ export const querySchema: FormSchemaGetter = () => [
{
component: 'Select',
componentProps: {
options: getDictOptions('pro_expense_type'),
},
fieldName: 'costType',
label: '费用类型',
},
{ {
component: 'ApiSelect', component: 'ApiSelect',
componentProps: { componentProps: {
@@ -57,10 +65,24 @@ export const columns: VxeGridProps['columns'] = [
field: 'residentUnitText', field: 'residentUnitText',
minWidth: 150, minWidth: 150,
}, },
{
title: '费用类型',
field: 'costType',
slots: {
default: ({ row }) => {
return renderDict(row.costType||row.type, 'pro_expense_type');
},
},
},
{ {
title: '收费项目', title: '收费项目',
field: 'chargeItemText', field: 'chargeItemText',
width: 150, width: 150,
slots: {
default: ({ row }) => {
return row.chargeItemText||'-';
},
},
}, },
{ {
title: '应收金额', title: '应收金额',
@@ -71,13 +93,11 @@ export const columns: VxeGridProps['columns'] = [
title: '计费开始时间', title: '计费开始时间',
field: 'startTime', field: 'startTime',
width: 150, width: 150,
slots: { default: 'startTime' },
}, },
{ {
title: '计费结束时间', title: '计费结束时间',
field: 'endTime', field: 'endTime',
width: 150, width: 150,
slots: { default: 'endTime' },
}, },
{ {
title: '缴费状态', title: '缴费状态',
@@ -89,20 +109,15 @@ export const columns: VxeGridProps['columns'] = [
}, },
}, },
}, },
// {
// title: '状态',
// field: 'state',
// width: 150,
// slots: {
// default: ({row}) => {
// return renderDict(row.state, 'wy_fysfzt')
// }
// }
// },
{ {
title: '说明', title: '说明',
field: 'remark', field: 'remark',
width: 150, width: 180,
slots: {
default: ({ row }) => {
return row.remark||'-';
},
},
}, },
{ {
field: 'action', field: 'action',
@@ -184,10 +199,11 @@ export const modalSchema: FormSchemaGetter = () => [
{ {
label: '计费时间', label: '计费时间',
fieldName: 'chargeTime', fieldName: 'chargeTime',
component: 'RangePicker', component: 'DatePicker',
componentProps: { componentProps: {
format: 'YYYY-MM-DD', format: 'YYYY-MM',
valueFormat: 'YYYY-MM-DD', valueFormat: 'YYYY-MM',
picker:'month'
}, },
rules: 'selectRequired', rules: 'selectRequired',
}, },
@@ -254,3 +270,21 @@ export const modalSchemaRefund: FormSchemaGetter = () => [
rules: 'required', rules: 'required',
}, },
]; ];
export const modalSchemaCorrection: FormSchemaGetter = () => [
{
label: '主键',
fieldName: 'id',
component: 'Input',
dependencies: {
show: () => false,
triggerFields: [''],
},
},
{
label: '收费项目',
fieldName: 'costItemsId',
component: 'ApiSelect',
componentProps: {},
rules: 'selectRequired',
},
];

View File

@@ -0,0 +1,149 @@
<script setup lang="ts">
import {ref} from 'vue';
import {useVbenModal} from '@vben/common-ui';
import {cloneDeep} from '@vben/utils';
import {useVbenForm} from '#/adapter/form';
import {
houseChargeAddFee,
houseChargeInfo,
} from '#/api/property/costManagement/houseCharge';
import {defaultFormValueGetter, useBeforeCloseDiff} from '#/utils/popup';
import {modalSchemaCorrection} from './data';
import {renderDict} from "#/utils/render";
import {Descriptions, DescriptionsItem, Divider} from "ant-design-vue";
import type {HouseChargeVO} from "#/api/property/costManagement/houseCharge/model";
import {costItemSettingList} from "#/api/property/costManagement/costItemSetting";
import type {CostItemSettingVO} from "#/api/property/costManagement/costItemSetting/model";
const emit = defineEmits<{ reload: [] }>();
const isUpdate = ref(false);
const record = ref<HouseChargeVO>();
const [BasicForm, formApi] = useVbenForm({
commonConfig: {
// 默认占满两列
formItemClass: 'col-span-2',
// 默认label宽度 px
labelWidth: 80,
// 通用配置项 会影响到所有表单项
componentProps: {
class: 'w-full',
}
},
schema: modalSchemaCorrection(),
showDefaultActions: false,
wrapperClass: 'grid-cols-2',
});
const {onBeforeClose, markInitialized, resetInitialized} = useBeforeCloseDiff(
{
initializedGetter: defaultFormValueGetter(formApi),
currentGetter: defaultFormValueGetter(formApi),
},
);
const [BasicModal, modalApi] = useVbenModal({
// 在这里更改宽度
class: 'w-[550px]',
fullscreenButton: false,
onBeforeClose,
onClosed: handleClosed,
onConfirm: handleConfirm,
onOpenChange: async (isOpen) => {
if (!isOpen) {
return null;
}
modalApi.modalLoading(true);
const {id} = modalApi.getData() as { id?: number | string };
isUpdate.value = !!id;
record.value = await houseChargeInfo(id);
queryCostItemOptions(record.value.type);
await formApi.setValues(record.value);
await markInitialized();
modalApi.modalLoading(false);
},
});
async function handleConfirm() {
try {
modalApi.lock(true);
const {valid} = await formApi.validate();
if (!valid) {
return;
}
// getValues获取为一个readonly的对象 需要修改必须先深拷贝一次
const data = cloneDeep(await formApi.getValues());
record.value.costItemsId = data.costItemsId
await houseChargeAddFee(record.value);
resetInitialized();
emit('reload');
modalApi.close();
} catch (error) {
console.error(error);
} finally {
modalApi.lock(false);
}
}
async function handleClosed() {
await formApi.resetForm();
resetInitialized();
}
const costItemOptions = ref<CostItemSettingVO>([]);
async function queryCostItemOptions(costType: string) {
let params = {
pageSize: 1000,
pageNum: 1,
costType,
};
const res = await costItemSettingList(params);
costItemOptions.value = res.rows;
formApi.updateSchema([
{
componentProps: {
options: costItemOptions.value,
fieldNames: { label: 'chargeItem', value: 'id' },
showSearch: true,
optionFilterProp: 'chargeItem',
},
fieldName: 'costItemsId',
},
]);
}
</script>
<template>
<BasicModal title="更正">
<Descriptions v-if="record" size="small" :column="2"
:labelStyle="{width:'80px'}">
<DescriptionsItem label="单位" :span="2">
{{ record.residentUnitText }}
</DescriptionsItem>
<DescriptionsItem label="单位面积">
{{ `${record.area} (㎡)` }}
</DescriptionsItem>
<DescriptionsItem label="费用类型">
<component
:is="renderDict(record?.type,'pro_expense_type')"
/>
</DescriptionsItem>
<DescriptionsItem label="计费时间" :span="2">
{{ record.startTime + ' 至 ' + record.endTime }}
</DescriptionsItem>
<DescriptionsItem label="应收金额" :span="2">
<span style="font-size: 16px;font-weight: 600;color: red" v-if="record.amountReceivable">
{{ record.amountReceivable }}
</span>
</DescriptionsItem>
</Descriptions>
<Divider/>
<BasicForm/>
</BasicModal>
</template>

View File

@@ -11,7 +11,6 @@ dayjs.extend(duration);
dayjs.extend(relativeTime); dayjs.extend(relativeTime);
import {houseChargeInfo} from "#/api/property/costManagement/houseCharge"; import {houseChargeInfo} from "#/api/property/costManagement/houseCharge";
import type {HouseChargeVO} from "#/api/property/costManagement/houseCharge/model"; import type {HouseChargeVO} from "#/api/property/costManagement/houseCharge/model";
import type {RoomVO} from "#/api/property/room/model";
import type {CostItemSettingVO} from "#/api/property/costManagement/costItemSetting/model"; import type {CostItemSettingVO} from "#/api/property/costManagement/costItemSetting/model";
@@ -23,7 +22,6 @@ const [BasicModal, modalApi] = useVbenModal({
}); });
const houseChargeDetail = shallowRef<null | HouseChargeVO>(null); const houseChargeDetail = shallowRef<null | HouseChargeVO>(null);
const room = ref<RoomVO>();
const costItem = ref<CostItemSettingVO>(); const costItem = ref<CostItemSettingVO>();
async function handleOpenChange(open: boolean) { async function handleOpenChange(open: boolean) {
@@ -34,46 +32,40 @@ async function handleOpenChange(open: boolean) {
const {id} = modalApi.getData() as { id: number | string }; const {id} = modalApi.getData() as { id: number | string };
houseChargeDetail.value = await houseChargeInfo(id); houseChargeDetail.value = await houseChargeInfo(id);
if (houseChargeDetail.value) { if (houseChargeDetail.value) {
room.value = houseChargeDetail.value.roomVo
costItem.value = houseChargeDetail.value.costItemsVo costItem.value = houseChargeDetail.value.costItemsVo
} }
modalApi.modalLoading(false); modalApi.modalLoading(false);
} }
function formatDate(dateString: string) {
if (!dateString) return '';
const date = new Date(dateString);
return date.toISOString().split('T')[0];
}
</script> </script>
<template> <template>
<BasicModal :footer="false" :fullscreen-button="false" title="房屋收费详情" class="w-[70%]"> <BasicModal :footer="false" :fullscreen-button="false" title="收费详情" class="w-[70%]">
<Descriptions v-if="houseChargeDetail" size="small" :column="2" bordered <Descriptions v-if="houseChargeDetail" size="small" :column="2" bordered
:labelStyle="{width:'100px'}"> :labelStyle="{width:'100px'}">
<DescriptionsItem label="费用编号"> <DescriptionsItem label="单位" :span="2">
{{ costItem?.id }}
</DescriptionsItem>
<DescriptionsItem label="费用项目">
{{ costItem?.chargeItem }}
</DescriptionsItem>
<DescriptionsItem label="费用类型">
<component v-if="costItem"
:is="renderDict(costItem.costType,'pro_expense_type')"
/>
</DescriptionsItem>
<DescriptionsItem label="计费时间">
{{ formatDate(houseChargeDetail.startTime) + ' 至 ' + formatDate(houseChargeDetail.endTime) }}
</DescriptionsItem>
<DescriptionsItem label="单位">
{{ houseChargeDetail?.residentUnitText }} {{ houseChargeDetail?.residentUnitText }}
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="单位面积"> <DescriptionsItem label="单位面积">
{{ `${houseChargeDetail?.area} (㎡)` }} {{ `${houseChargeDetail?.area} (㎡)` }}
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="单价"> <DescriptionsItem label="费用类型" v-if="costItem?.costType">
<component v-if="costItem"
:is="renderDict(costItem.costType,'pro_expense_type')"
/>
</DescriptionsItem>
<DescriptionsItem label="费用项目" v-if="costItem?.chargeItem">
{{ costItem?.chargeItem }}
</DescriptionsItem>
<DescriptionsItem label="费用编号" v-if="costItem?.chargeNo">
{{ costItem?.chargeNo }}
</DescriptionsItem>
<DescriptionsItem label="计费时间" :span="2">
{{ houseChargeDetail.startTime + ' 至 ' + houseChargeDetail.endTime }}
</DescriptionsItem>
<DescriptionsItem label="单价" v-if="costItem?.unitPrice&&!houseChargeDetail.orderId">
{{ costItem?.unitPrice }} {{ costItem?.unitPrice }}
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="附加费"> <DescriptionsItem label="附加费" v-if="costItem?.surcharge&&!houseChargeDetail.orderId">
{{ costItem?.surcharge }} {{ costItem?.surcharge }}
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="应收金额"> <DescriptionsItem label="应收金额">

View File

@@ -14,14 +14,12 @@ import {modalSchemaRefund} from './data';
import {renderDict} from "#/utils/render"; import {renderDict} from "#/utils/render";
import {Descriptions, DescriptionsItem, Divider} from "ant-design-vue"; import {Descriptions, DescriptionsItem, Divider} from "ant-design-vue";
import type {HouseChargeVO} from "#/api/property/costManagement/houseCharge/model"; import type {HouseChargeVO} from "#/api/property/costManagement/houseCharge/model";
import type {RoomVO} from "#/api/property/room/model";
import type {CostItemSettingVO} from "#/api/property/costManagement/costItemSetting/model"; import type {CostItemSettingVO} from "#/api/property/costManagement/costItemSetting/model";
const emit = defineEmits<{ reload: [] }>(); const emit = defineEmits<{ reload: [] }>();
const isUpdate = ref(false); const isUpdate = ref(false);
const record = ref<HouseChargeVO>(); const record = ref<HouseChargeVO>();
const room = ref<RoomVO>();
const costItem = ref<CostItemSettingVO>(); const costItem = ref<CostItemSettingVO>();
const [BasicForm, formApi] = useVbenForm({ const [BasicForm, formApi] = useVbenForm({
commonConfig: { commonConfig: {
@@ -63,7 +61,6 @@ const [BasicModal, modalApi] = useVbenModal({
if(id){ if(id){
record.value = await houseChargeInfo(id); record.value = await houseChargeInfo(id);
if (record.value) { if (record.value) {
room.value = record.value.roomVo
costItem.value = record.value.costItemsVo costItem.value = record.value.costItemsVo
} }
await formApi.setValues(record.value); await formApi.setValues(record.value);
@@ -103,34 +100,34 @@ async function handleClosed() {
</script> </script>
<template> <template>
<BasicModal title="费"> <BasicModal title="退费">
<Descriptions v-if="record" size="small" :column="2" <Descriptions v-if="record" size="small" :column="2"
:labelStyle="{width:'80px'}"> :labelStyle="{width:'80px'}">
<DescriptionsItem label="费用编号"> <DescriptionsItem label="单位" :span="2">
{{ costItem?.id }}
</DescriptionsItem>
<DescriptionsItem label="费用项目">
{{ costItem?.chargeItem }}
</DescriptionsItem>
<DescriptionsItem label="费用类型">
<component
v-if="costItem"
:is="renderDict(costItem?.costType,'pro_expense_type')"
/>
</DescriptionsItem>
<DescriptionsItem label="计费起始">
{{ record.startTime }}
</DescriptionsItem>
<DescriptionsItem label="单位">
{{ record.residentUnitText }} {{ record.residentUnitText }}
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="单位面积"> <DescriptionsItem label="单位面积">
{{ `${record.area} (㎡)` }} {{ `${record.area} (㎡)` }}
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="单价"> <DescriptionsItem label="费用类型" v-if="costItem?.costType">
<component
v-if="costItem"
:is="renderDict(costItem?.costType,'pro_expense_type')"
/>
</DescriptionsItem>
<DescriptionsItem label="费用项目" v-if="costItem?.chargeItem">
{{ costItem?.chargeItem }}
</DescriptionsItem>
<DescriptionsItem label="费用编号" v-if="costItem?.chargeNo">
{{ costItem?.chargeNo }}
</DescriptionsItem>
<DescriptionsItem label="计费时间" :span="2">
{{ record.startTime + ' 至 ' + record.endTime }}
</DescriptionsItem>
<DescriptionsItem label="单价" v-if="costItem?.unitPrice&&!record.orderId">
{{ costItem?.unitPrice }} {{ costItem?.unitPrice }}
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="附加费"> <DescriptionsItem label="附加费" v-if="costItem?.surcharge&&!record.orderId">
{{ costItem?.surcharge }} {{ costItem?.surcharge }}
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="退费金额" :span="2"> <DescriptionsItem label="退费金额" :span="2">

View File

@@ -74,7 +74,7 @@ const [BasicModal, modalApi] = useVbenModal({
if (isUpdate.value && id) { if (isUpdate.value && id) {
const record = await houseChargeInfo(id); const record = await houseChargeInfo(id);
record.chargeTime = [record.startTime, record.endTime]; record.chargeTime =record.startTime?.substring(0,7);
await formApi.setValues(record); await formApi.setValues(record);
} }
await markInitialized(); await markInitialized();
@@ -92,9 +92,9 @@ async function handleConfirm() {
} }
// getValues获取为一个readonly的对象 需要修改必须先深拷贝一次 // getValues获取为一个readonly的对象 需要修改必须先深拷贝一次
const data = cloneDeep(await formApi.getValues()); const data = cloneDeep(await formApi.getValues());
if (data.chargeTime && data.chargeTime.length) { if (data.chargeTime) {
data.startTime = data.chargeTime[0]; data.startTime = data.chargeTime+'-01 00:00:00';
data.endTime = data.chargeTime[1]; data.endTime = data.chargeTime+'-31 23:59:59';
} }
await (isUpdate.value ? houseChargeUpdate(data) : houseChargeAdd(data)); await (isUpdate.value ? houseChargeUpdate(data) : houseChargeAdd(data));
resetInitialized(); resetInitialized();
@@ -156,7 +156,8 @@ async function initCostTypeOptions() {
formApi.updateSchema([ formApi.updateSchema([
{ {
componentProps: { componentProps: {
options: getDictOptions('pro_expense_type'), // 费用类型不要保洁、会议、绿植
options: getDictOptions('pro_expense_type').filter(item=>!(['1','3','4'].includes(item.value))),
onChange: async (value: string) => { onChange: async (value: string) => {
if (value) { if (value) {
await queryCostItemOptions(value); await queryCostItemOptions(value);

View File

@@ -15,14 +15,12 @@ import {modalSchemaUpdate} from './data';
import {renderDict} from "#/utils/render"; import {renderDict} from "#/utils/render";
import {Descriptions, DescriptionsItem, Divider} from "ant-design-vue"; import {Descriptions, DescriptionsItem, Divider} from "ant-design-vue";
import type {HouseChargeVO} from "#/api/property/costManagement/houseCharge/model"; import type {HouseChargeVO} from "#/api/property/costManagement/houseCharge/model";
import type {RoomVO} from "#/api/property/room/model";
import type {CostItemSettingVO} from "#/api/property/costManagement/costItemSetting/model"; import type {CostItemSettingVO} from "#/api/property/costManagement/costItemSetting/model";
const emit = defineEmits<{ reload: [] }>(); const emit = defineEmits<{ reload: [] }>();
const isUpdate = ref(false); const isUpdate = ref(false);
const record = ref<HouseChargeVO>(); const record = ref<HouseChargeVO>();
const room = ref<RoomVO>();
const costItem = ref<CostItemSettingVO>(); const costItem = ref<CostItemSettingVO>();
const [BasicForm, formApi] = useVbenForm({ const [BasicForm, formApi] = useVbenForm({
commonConfig: { commonConfig: {
@@ -63,7 +61,6 @@ const [BasicModal, modalApi] = useVbenModal({
isUpdate.value = !!id; isUpdate.value = !!id;
record.value = await houseChargeInfo(id); record.value = await houseChargeInfo(id);
if (record.value) { if (record.value) {
room.value = record.value.roomVo
costItem.value = record.value.costItemsVo costItem.value = record.value.costItemsVo
} }
await formApi.setValues(record.value); await formApi.setValues(record.value);
@@ -107,31 +104,31 @@ async function handleClosed() {
<BasicModal title="缴费"> <BasicModal title="缴费">
<Descriptions v-if="record" size="small" :column="2" <Descriptions v-if="record" size="small" :column="2"
:labelStyle="{width:'80px'}"> :labelStyle="{width:'80px'}">
<DescriptionsItem label="费用编号"> <DescriptionsItem label="单位" :span="2">
{{ costItem?.id }}
</DescriptionsItem>
<DescriptionsItem label="费用项目">
{{ costItem?.chargeItem }}
</DescriptionsItem>
<DescriptionsItem label="费用类型">
<component
v-if="costItem"
:is="renderDict(costItem?.costType,'pro_expense_type')"
/>
</DescriptionsItem>
<DescriptionsItem label="计费起始">
{{ record.startTime }}
</DescriptionsItem>
<DescriptionsItem label="单位">
{{ record.residentUnitText }} {{ record.residentUnitText }}
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="单位面积"> <DescriptionsItem label="单位面积">
{{ `${record.area} (㎡)` }} {{ `${record.area} (㎡)` }}
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="单价"> <DescriptionsItem label="费用类型" v-if="costItem?.costType">
<component
v-if="costItem"
:is="renderDict(costItem?.costType,'pro_expense_type')"
/>
</DescriptionsItem>
<DescriptionsItem label="费用项目" v-if="costItem?.chargeItem">
{{ costItem?.chargeItem }}
</DescriptionsItem>
<DescriptionsItem label="费用编号" v-if="costItem?.chargeNo">
{{ costItem?.chargeNo }}
</DescriptionsItem>
<DescriptionsItem label="计费时间" :span="2">
{{ record.startTime + ' 至 ' + record.endTime }}
</DescriptionsItem>
<DescriptionsItem label="单价" v-if="costItem?.unitPrice&&!record.orderId">
{{ costItem?.unitPrice }} {{ costItem?.unitPrice }}
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="附加费"> <DescriptionsItem label="附加费" v-if="costItem?.surcharge&&!record.orderId">
{{ costItem?.surcharge }} {{ costItem?.surcharge }}
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="缴费金额" :span="2"> <DescriptionsItem label="缴费金额" :span="2">

View File

@@ -23,6 +23,7 @@ import houseChargeAdd from './houseCharge-add.vue';
import houseChargeUpdate from './houseCharge-update.vue'; import houseChargeUpdate from './houseCharge-update.vue';
import houseChargeDetail from './house-charge-detail.vue'; import houseChargeDetail from './house-charge-detail.vue';
import houseChargeRefund from './house-charge-refund.vue'; import houseChargeRefund from './house-charge-refund.vue';
import houseChargeCorrection from './house-charge-correction.vue';
import {columns, querySchema} from './data'; import {columns, querySchema} from './data';
const formOptions: VbenFormProps = { const formOptions: VbenFormProps = {
@@ -86,6 +87,9 @@ const [HouseChargeDetail, detailApi] = useVbenModal({
const [HouseChargeRefund, refundApi] = useVbenModal({ const [HouseChargeRefund, refundApi] = useVbenModal({
connectedComponent: houseChargeRefund, connectedComponent: houseChargeRefund,
}); });
const [HouseChargeCorrection, correctionApi] = useVbenModal({
connectedComponent: houseChargeCorrection,
});
function handleAdd() { function handleAdd() {
modalApi.setData({}); modalApi.setData({});
@@ -111,6 +115,10 @@ async function handleRefund(row: Required<HouseChargeForm>) {
refundApi.setData({id: row.id}); refundApi.setData({id: row.id});
refundApi.open(); refundApi.open();
} }
async function handleCorrection(row: Required<HouseChargeForm>) {
correctionApi.setData({id: row.id});
correctionApi.open();
}
function handleMultiDelete() { function handleMultiDelete() {
const rows = tableApi.grid.getCheckboxRecords(); const rows = tableApi.grid.getCheckboxRecords();
@@ -125,11 +133,7 @@ function handleMultiDelete() {
}, },
}); });
} }
function formatDate(dateString: string) {
if (!dateString) return '';
const date = new Date(dateString);
return date.toISOString().split('T')[0];
}
function handleDownloadExcel() { function handleDownloadExcel() {
commonDownloadExcel(houseChargeExport, '房屋收费数据', tableApi.formApi.form.values, { commonDownloadExcel(houseChargeExport, '房屋收费数据', tableApi.formApi.form.values, {
fieldMappingTime: formOptions.fieldMappingTime, fieldMappingTime: formOptions.fieldMappingTime,
@@ -139,7 +143,7 @@ function handleDownloadExcel() {
<template> <template>
<Page :auto-content-height="true"> <Page :auto-content-height="true">
<BasicTable table-title="房屋收费列表"> <BasicTable table-title="收费列表">
<template #toolbar-tools> <template #toolbar-tools>
<Space> <Space>
<a-button <a-button
@@ -165,14 +169,6 @@ function handleDownloadExcel() {
</a-button> </a-button>
</Space> </Space>
</template> </template>
<template #startTime="{row}">
{{ formatDate(row.startTime) }}
</template>
<template #endTime="{row}">
{{ formatDate(row.endTime) }}
</template>
<template #action="{ row }"> <template #action="{ row }">
<Space> <Space>
<ghost-button <ghost-button
@@ -196,6 +192,13 @@ function handleDownloadExcel() {
> >
退费 退费
</ghost-button> </ghost-button>
<ghost-button
v-else-if="row.orderId!==null&&row.costItemsId==null"
v-access:code="['property:houseCharge:edit']"
@click.stop="handleCorrection(row)"
>
更正
</ghost-button>
<Popconfirm <Popconfirm
v-else v-else
:get-popup-container="getVxePopupContainer" :get-popup-container="getVxePopupContainer"
@@ -218,6 +221,7 @@ function handleDownloadExcel() {
<HouseChargeAdd @reload="tableApi.query()"/> <HouseChargeAdd @reload="tableApi.query()"/>
<HouseChargeUpdate @reload="tableApi.query()"/> <HouseChargeUpdate @reload="tableApi.query()"/>
<HouseChargeRefund @reload="tableApi.query()"/> <HouseChargeRefund @reload="tableApi.query()"/>
<HouseChargeCorrection @reload="tableApi.query()"/>
<HouseChargeDetail/> <HouseChargeDetail/>
</Page> </Page>
</template> </template>

View File

@@ -63,26 +63,11 @@ export const querySchema: FormSchemaGetter = () => [
export const columns: VxeGridProps['columns'] = [ export const columns: VxeGridProps['columns'] = [
{ type: 'checkbox', width: 60 }, { type: 'checkbox', width: 60 },
{
title: '序号',
field: 'id',
slots: {
default: ({ rowIndex }) => {
return (rowIndex + 1).toString();
},
},
minWidth: '120',
},
{ {
title: '订单号', title: '订单号',
field: 'orderId', field: 'orderId',
minWidth: '120', minWidth: '120',
}, },
{
title: '租赁合同编号',
field: 'userId',
minWidth: '120',
},
{ {
title: '租赁人', title: '租赁人',
field: 'userName', field: 'userName',

View File

@@ -49,15 +49,15 @@ async function handleOpenChange(open: boolean) {
<DescriptionsItem label="订单号"> <DescriptionsItem label="订单号">
{{ orderChargeDetail.orderId }} {{ orderChargeDetail.orderId }}
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="租赁合同编号"> <!-- <DescriptionsItem label="租赁合同编号">-->
{{ orderChargeDetail.rentalOrder.contractCode }} <!-- {{ orderChargeDetail.rentalOrder.contractCode }}-->
<!-- </DescriptionsItem>-->
<DescriptionsItem label="租赁单位">
{{ orderChargeDetail.residentUnitText }}
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="租赁人"> <DescriptionsItem label="租赁人">
{{ orderChargeDetail.userName }} {{ orderChargeDetail.userName }}
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="租赁单位">
{{ orderChargeDetail.residentUnitText }}
</DescriptionsItem>
<DescriptionsItem label="租金"> <DescriptionsItem label="租金">
{{ orderChargeDetail.rent }} {{ orderChargeDetail.rent }}
</DescriptionsItem> </DescriptionsItem>

View File

@@ -10,10 +10,7 @@ import {
orderChargeUpdate, orderChargeUpdate,
} from '#/api/property/chargeManagement'; } from '#/api/property/chargeManagement';
import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup'; import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup';
// import { modalSchema } from './data';
import QueryUserList from '#/views/property/greenPlantRentalManagement/chargeManagement/query-user-list.vue';
import { resident_unitList } from '#/api/property/resident/unit'; import { resident_unitList } from '#/api/property/resident/unit';
import type { FormSchemaGetter } from '#/adapter/form';
import { rentalNotSelectList } from '#/api/property/rentalOrder'; import { rentalNotSelectList } from '#/api/property/rentalOrder';
import { getDictOptions } from '#/utils/dict'; import { getDictOptions } from '#/utils/dict';
@@ -53,11 +50,10 @@ const modalSchema = [
labelField: 'orderNo', labelField: 'orderNo',
valueField: 'id', valueField: 'id',
onChange: async (value: any, option: any) => { onChange: async (value: any, option: any) => {
console.log(option);
await formApi.setValues({ await formApi.setValues({
residentUnitId: option.residentUnitId, // 假设订单数据中有 residentUnitId 字段 residentUnitId: option.residentUnitId, // 假设订单数据中有 residentUnitId 字段
// 其他需要自动填充的字段 userName:option.customerName,
rent:option.totalAmount
}); });
}, },
}, },
@@ -89,18 +85,18 @@ const modalSchema = [
{ {
label: '租赁人', label: '租赁人',
fieldName: 'userName', fieldName: 'userName',
component: 'Select', component: 'Input',
rules: 'selectRequired', disabled: true,
}, },
{ {
label: '租金', label: '租金',
fieldName: 'rent', fieldName: 'rent',
component: 'InputNumber', component: 'InputNumber',
rules: 'required',
componentProps: { componentProps: {
precision: 2, precision: 2,
}, },
disabled: true,
}, },
{ {
label: '押金', label: '押金',
@@ -246,10 +242,6 @@ async function handleConfirm() {
return; return;
} }
const data = cloneDeep(await formApi.getValues()); const data = cloneDeep(await formApi.getValues());
if (userInfo) {
data.userId = userInfo.userId;
data.userName = userInfo.userName;
}
await (isUpdate.value ? orderChargeUpdate(data) : orderChargeAdd(data)); await (isUpdate.value ? orderChargeUpdate(data) : orderChargeAdd(data));
resetInitialized(); resetInitialized();
emit('reload'); emit('reload');
@@ -260,14 +252,6 @@ async function handleConfirm() {
modalApi.lock(false); modalApi.lock(false);
} }
} }
let userInfo = reactive({
userId: '',
userName: '',
});
const userName = ref<number | string>('');
function getUserInfo(user: any) {
userInfo = user;
}
async function handleClosed() { async function handleClosed() {
await formApi.resetForm(); await formApi.resetForm();
resetInitialized(); resetInitialized();
@@ -277,14 +261,6 @@ async function handleClosed() {
<template> <template>
<BasicModal :title="title"> <BasicModal :title="title">
<BasicForm> <BasicForm>
<template #userName="slotProps">
<QueryUserList
@update:userInfo="getUserInfo"
v-bind="slotProps"
:isUpdate="isUpdate"
:userName="userName"
/>
</template>
</BasicForm> </BasicForm>
</BasicModal> </BasicModal>
</template> </template>

View File

@@ -83,6 +83,9 @@ async function handleConfirm() {
data.scheduledEndtime = data.timeSpan[1]?.format("HH:mm"); data.scheduledEndtime = data.timeSpan[1]?.format("HH:mm");
} }
data.price=totalAmount.value data.price=totalAmount.value
if(conferenceSettingDetail.value?.expenseType == '2'){
data.price=Number(totalAmount.value)+Number(conferenceSettingDetail.value?.basePrice||0)
}
if(data.attach=='0'){ if(data.attach=='0'){
data.meetAttachOrderBoList=addServiceList.value.filter(item=>item.quantity>0); data.meetAttachOrderBoList=addServiceList.value.filter(item=>item.quantity>0);
} }