This commit is contained in:
2025-09-14 21:46:45 +08:00
9 changed files with 130 additions and 72 deletions

View File

@@ -71,6 +71,7 @@ export interface CostItemSettingVO {
*/ */
searchValue: string; searchValue: string;
chargeNo: string; chargeNo: string;
unit: string;
} }

View File

@@ -222,7 +222,7 @@ const [BasicModal, modalApi] = useVbenModal({
data.roomId = data.roomId data.roomId = data.roomId
.split(',') .split(',')
.filter((id: string) => id.trim() !== ''); .filter((id: string) => id.trim() !== '');
data.area = data.sumPeices / data.peices; // data.area = data.sumPeices / data.peices;
} else { } else {
isAdd.value = true; isAdd.value = true;
} }

View File

@@ -332,7 +332,7 @@ const [BasicModal, modalApi] = useVbenModal({
for (const item of record.relationList) { for (const item of record.relationList) {
for (let i = 0; i < detailTable.value.length; i++) { for (let i = 0; i < detailTable.value.length; i++) {
if (item.cleanId === detailTable.value[i].id) { if (item.cleanId === detailTable.value[i].id) {
detailTable.value[i].area = item.areas; // detailTable.value[i].area = item.areas;
detailTable.value[i].sumPeices = item.sumPrice; detailTable.value[i].sumPeices = item.sumPrice;
} }
} }
@@ -446,7 +446,7 @@ const detailColumns = [
customRender: ({ value }: { value: number }) => customRender: ({ value }: { value: number }) =>
value === 1 ? '启用' : '禁用', value === 1 ? '启用' : '禁用',
}, },
// { title: '保洁面积', dataIndex: 'area', key: 'area' }, { title: '保洁面积', dataIndex: 'area', key: 'area' },
{ {
title: '合计费用', title: '合计费用',
dataIndex: 'sumPeices', dataIndex: 'sumPeices',
@@ -490,7 +490,6 @@ function handleViewDetail(record: any) {
...record, ...record,
readonly: true, readonly: true,
unitId: currentUnitId.value, unitId: currentUnitId.value,
area: record.su,
}); });
detailModalApi.open(); detailModalApi.open();
} }
@@ -542,6 +541,7 @@ async function handleConfirm() {
: await clean_orderAdd(data); : await clean_orderAdd(data);
resetInitialized(); resetInitialized();
emit('reload'); emit('reload');
currentUnitId.value = ''; //清空当前单位id
modalApi.close(); modalApi.close();
} catch (error) { } catch (error) {
console.error(error); console.error(error);
@@ -553,6 +553,7 @@ async function handleConfirm() {
async function handleClosed() { async function handleClosed() {
await formApi.resetForm(); await formApi.resetForm();
detailTable.value = []; //清空详情表格 detailTable.value = []; //清空详情表格
currentUnitId.value = ''; //清空当前单位id
resetInitialized(); resetInitialized();
} }
// 获取服务地址 // 获取服务地址

View File

@@ -57,9 +57,9 @@ async function handleOpenChange(open: boolean) {
:is="renderDict(costItemSettingDetail.paymentType,'pro_payment_type')" :is="renderDict(costItemSettingDetail.paymentType,'pro_payment_type')"
/> />
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="费用周期(月)"> <!-- <DescriptionsItem label="费用周期(月)">-->
{{ costItemSettingDetail.chargeCycle }} <!-- {{ costItemSettingDetail.chargeCycle }}-->
</DescriptionsItem> <!-- </DescriptionsItem>-->
<DescriptionsItem label="单位"> <DescriptionsItem label="单位">
{{ costItemSettingDetail.unit }} {{ costItemSettingDetail.unit }}
</DescriptionsItem> </DescriptionsItem>
@@ -83,15 +83,15 @@ async function handleOpenChange(open: boolean) {
:is="renderDict(costItemSettingDetail.state,'wy_state')" :is="renderDict(costItemSettingDetail.state,'wy_state')"
/> />
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="计算公式" v-if="costItemSettingDetail.formula!=null"> <DescriptionsItem label="计算公式" v-if="costItemSettingDetail.formula!=null" :span="2">
<component <component
:is="renderDict(costItemSettingDetail.formula,'pro_calculation_formula')" :is="renderDict(costItemSettingDetail.formula,'pro_calculation_formula')"
/> />
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="计费单价"> <DescriptionsItem :label="costItemSettingDetail.formula=='1'?'费用':'计费单价'" v-if="costItemSettingDetail.unitPrice!=null">
{{ costItemSettingDetail.unitPrice }} {{ costItemSettingDetail.unitPrice }}
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="附加费用"> <DescriptionsItem label="附加费用" v-if="costItemSettingDetail.surcharge!=null">
{{ costItemSettingDetail.surcharge }} {{ costItemSettingDetail.surcharge }}
</DescriptionsItem> </DescriptionsItem>
</Descriptions> </Descriptions>

View File

@@ -10,6 +10,7 @@ import { costItemSettingAdd, costItemSettingInfo, costItemSettingUpdate } from '
import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup'; import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup';
import { modalSchema } from './data'; import { modalSchema } from './data';
import {getDictOptions} from "#/utils/dict";
const emit = defineEmits<{ reload: [] }>(); const emit = defineEmits<{ reload: [] }>();
@@ -53,7 +54,7 @@ const [BasicModal, modalApi] = useVbenModal({
return null; return null;
} }
modalApi.modalLoading(true); modalApi.modalLoading(true);
initCostTypeOptions()
const { id } = modalApi.getData() as { id?: number | string }; const { id } = modalApi.getData() as { id?: number | string };
isUpdate.value = !!id; isUpdate.value = !!id;
@@ -67,6 +68,39 @@ const [BasicModal, modalApi] = useVbenModal({
}, },
}); });
/**
* 初始化费用类型
*/
async function initCostTypeOptions() {
formApi.updateSchema([
{
componentProps: {
// 费用类型不要保洁、会议、绿植
options: getDictOptions('pro_expense_type'),
onChange: async (value: string) => {
if (value) {
//水费、电费、气费
if(['5','6','8'].includes(value)){
await formApi.setFieldValue('formula', '5');//(本层本次读数-上次读数)*单价/本层实际使用面积*本单位面积
//停车费、租金、押金
}else if(['2','7','9'].includes(value)){
await formApi.setFieldValue('formula', '1');//固定费用
//会议室使用费、绿植租赁费、保洁服务费
}else if(['1','3','4'].includes(value)){
await formApi.setFieldValue('formula', null);
//物业管理费
}else{
await formApi.setFieldValue('formula', '0');//建筑面积*单价
}
}
},
},
fieldName: 'costType',
},
]);
}
async function handleConfirm() { async function handleConfirm() {
try { try {
modalApi.lock(true); modalApi.lock(true);
@@ -76,6 +110,18 @@ async function handleConfirm() {
} }
// getValues获取为一个readonly的对象 需要修改必须先深拷贝一次 // getValues获取为一个readonly的对象 需要修改必须先深拷贝一次
const data = cloneDeep(await formApi.getValues()); const data = cloneDeep(await formApi.getValues());
//会议室使用费、绿植租赁费、保洁服务费
if(['1','3','4'].includes(data.costType)){
data.roundingMode=null;
data.currencyDecimals=null;
data.formula=null;
data.unitPrice=null;
data.surcharge=null;
}
//固定费用
if(data.formula=='1'){
data.surcharge=null;
}
await (isUpdate.value ? costItemSettingUpdate(data) : costItemSettingAdd(data)); await (isUpdate.value ? costItemSettingUpdate(data) : costItemSettingAdd(data));
resetInitialized(); resetInitialized();
emit('reload'); emit('reload');

View File

@@ -32,6 +32,7 @@ export const columns: VxeGridProps['columns'] = [
{ {
title: '费用编号', title: '费用编号',
field: 'chargeNo', field: 'chargeNo',
width: 180,
}, },
{ {
title: '费用类型', title: '费用类型',
@@ -41,10 +42,12 @@ export const columns: VxeGridProps['columns'] = [
return renderDict(row.costType, 'pro_expense_type'); return renderDict(row.costType, 'pro_expense_type');
}, },
}, },
width: 150,
}, },
{ {
title: '收费项目', title: '收费项目',
field: 'chargeItem', field: 'chargeItem',
minWidth: 180,
}, },
{ {
title: '费用标识', title: '费用标识',
@@ -54,6 +57,7 @@ export const columns: VxeGridProps['columns'] = [
return renderDict(row.costMark, 'pro_cost_identification'); return renderDict(row.costMark, 'pro_cost_identification');
}, },
}, },
width: 180,
}, },
{ {
title: '付费类型', title: '付费类型',
@@ -63,33 +67,18 @@ export const columns: VxeGridProps['columns'] = [
return renderDict(row.paymentType, 'pro_payment_type'); return renderDict(row.paymentType, 'pro_payment_type');
}, },
}, },
width: 180,
}, },
{ {
title: '费用周期(月)', title: '单位',
field: 'chargeCycle', field: 'unit',
}, minWidth: 120,
{
title: '计算公式',
field: 'formula',
slots: {
default: ({ row }) => {
return renderDict(row.formula, 'pro_calculation_formula');
},
},
},
{
title: '计费单价',
field: 'unitPrice',
},
{
title: '附加费用',
field: 'surcharge',
}, },
{ {
title: '状态', title: '状态',
field: 'state', field: 'state',
slots: { default: 'state' }, slots: { default: 'state' },
width: 100, width: 120,
}, },
{ {
field: 'action', field: 'action',
@@ -114,9 +103,6 @@ export const modalSchema: FormSchemaGetter = () => [
label: '费用类型', label: '费用类型',
fieldName: 'costType', fieldName: 'costType',
component: 'Select', component: 'Select',
componentProps: {
options: getDictOptions('pro_expense_type'),
},
rules: 'selectRequired', rules: 'selectRequired',
}, },
{ {
@@ -143,12 +129,6 @@ export const modalSchema: FormSchemaGetter = () => [
}, },
rules: 'selectRequired', rules: 'selectRequired',
}, },
{
label: '费用周期(月)',
fieldName: 'chargeCycle',
component: 'Input',
rules: 'required',
},
{ {
label: '单位', label: '单位',
fieldName: 'unit', fieldName: 'unit',
@@ -158,15 +138,6 @@ export const modalSchema: FormSchemaGetter = () => [
placeholder: '请输入(如:元)', placeholder: '请输入(如:元)',
}, },
}, },
// {
// label: '付费方式',
// fieldName: 'paymentMode',
// component: 'Select',
// componentProps: {
// options: getDictOptions('wy_fffs'),
// },
// rules: 'selectRequired',
// },
{ {
label: '进位方式', label: '进位方式',
fieldName: 'roundingMode', fieldName: 'roundingMode',
@@ -175,6 +146,10 @@ export const modalSchema: FormSchemaGetter = () => [
}, },
component: 'Select', component: 'Select',
rules: 'selectRequired', rules: 'selectRequired',
dependencies: {
show: (fromValue) => !(['1','3','4'].includes(fromValue.costType)),
triggerFields: ['costType'],
},
}, },
{ {
label: '保留小数', label: '保留小数',
@@ -184,6 +159,10 @@ export const modalSchema: FormSchemaGetter = () => [
options: getDictOptions('pro_keep_decimals'), options: getDictOptions('pro_keep_decimals'),
}, },
rules: 'selectRequired', rules: 'selectRequired',
dependencies: {
show: (fromValue) => !(['1','3','4'].includes(fromValue.costType)),
triggerFields: ['costType'],
},
}, },
{ {
component: 'Select', component: 'Select',
@@ -201,18 +180,42 @@ export const modalSchema: FormSchemaGetter = () => [
componentProps: { componentProps: {
options: getDictOptions('pro_calculation_formula'), options: getDictOptions('pro_calculation_formula'),
}, },
rules: 'selectRequired', disabled:true,
defaultValue:'1',
dependencies: {
show: (fromValue) => !(['1','3','4'].includes(fromValue.costType)),
triggerFields: ['costType'],
},
formItemClass:'col-span-2'
}, },
{ {
label: '计费单价', label: '计费单价',
fieldName: 'unitPrice', fieldName: 'unitPrice',
component: 'InputNumber', component: 'InputNumber',
rules: 'required', rules: 'required',
dependencies: {
show: (fromValue) => ['0','5','6','8'].includes(fromValue.costType),
triggerFields: ['costType'],
},
},
{
label: '费用',
fieldName: 'unitPrice',
component: 'InputNumber',
rules: 'required',
dependencies: {
show: (fromValue) => ['2','7','9'].includes(fromValue.costType),
triggerFields: ['costType'],
},
}, },
{ {
label: '附加费', label: '附加费',
fieldName: 'surcharge', fieldName: 'surcharge',
component: 'InputNumber', component: 'InputNumber',
rules: 'required', rules: 'required',
dependencies: {
show: (fromValue) => ['0','5','6','8'].includes(fromValue.costType),
triggerFields: ['costType'],
},
}, },
]; ];

View File

@@ -63,10 +63,11 @@ export const columns: VxeGridProps['columns'] = [
{ {
title: '单位', title: '单位',
field: 'residentUnitText', field: 'residentUnitText',
minWidth: 150, minWidth: 180,
}, },
{ {
title: '费用类型', title: '费用类型',
width: 150,
field: 'costType', field: 'costType',
slots: { slots: {
default: ({ row }) => { default: ({ row }) => {

View File

@@ -20,8 +20,11 @@ import type { CostItemSettingVO } from '#/api/property/costManagement/costItemSe
import { getDictOptions } from '#/utils/dict'; import { getDictOptions } from '#/utils/dict';
import { personList } from '#/api/property/resident/person'; import { personList } from '#/api/property/resident/person';
import { renderDictValue } from '#/utils/render'; import { renderDictValue } from '#/utils/render';
import {resident_unitInfo, resident_unitList} from "#/api/property/resident/unit"; import {
resident_unitInfo,
resident_unitList,
} from '#/api/property/resident/unit';
import dayjs from 'dayjs';
const emit = defineEmits<{ reload: [] }>(); const emit = defineEmits<{ reload: [] }>();
const isUpdate = ref(false); const isUpdate = ref(false);
@@ -74,7 +77,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?.substring(0,7); record.chargeTime = record.startTime?.substring(0, 7);
await formApi.setValues(record); await formApi.setValues(record);
} }
await markInitialized(); await markInitialized();
@@ -93,8 +96,12 @@ async function handleConfirm() {
// getValues获取为一个readonly的对象 需要修改必须先深拷贝一次 // getValues获取为一个readonly的对象 需要修改必须先深拷贝一次
const data = cloneDeep(await formApi.getValues()); const data = cloneDeep(await formApi.getValues());
if (data.chargeTime) { if (data.chargeTime) {
data.startTime = data.chargeTime+'-01 00:00:00'; data.startTime = dayjs(data.chargeTime)
data.endTime = data.chargeTime+'-31 23:59:59'; .startOf('month')
.format('YYYY-MM-DD HH:mm:ss');
data.endTime = dayjs(data.chargeTime)
.endOf('month')
.format('YYYY-MM-DD HH:mm:ss');
} }
await (isUpdate.value ? houseChargeUpdate(data) : houseChargeAdd(data)); await (isUpdate.value ? houseChargeUpdate(data) : houseChargeAdd(data));
resetInitialized(); resetInitialized();
@@ -115,7 +122,7 @@ async function handleClosed() {
/** /**
* 查询费用项设置 * 查询费用项设置
*/ */
async function queryCostItemOptions(costType: string|null) { async function queryCostItemOptions(costType: string | null) {
let params = { let params = {
pageSize: 1000, pageSize: 1000,
pageNum: 1, pageNum: 1,
@@ -157,7 +164,9 @@ async function initCostTypeOptions() {
{ {
componentProps: { componentProps: {
// 费用类型不要保洁、会议、绿植 // 费用类型不要保洁、会议、绿植
options: getDictOptions('pro_expense_type').filter(item=>!(['1','3','4'].includes(item.value))), 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);
@@ -207,7 +216,7 @@ async function queryUnitData() {
}; };
const res = await resident_unitList(params); const res = await resident_unitList(params);
const options = res.rows.map((unit) => ({ const options = res.rows.map((unit) => ({
label:unit.name, label: unit.name,
value: unit.id, value: unit.id,
})); }));
formApi.updateSchema([ formApi.updateSchema([
@@ -229,8 +238,8 @@ async function queryUnitData() {
} }
async function queryRoomByUnit(unitId: string) { async function queryRoomByUnit(unitId: string) {
let unitInfo = await resident_unitInfo(unitId); let unitInfo = await resident_unitInfo(unitId);
if(unitInfo&&unitInfo.locationDetail){ if (unitInfo && unitInfo.locationDetail) {
await formApi.setFieldValue('roomInfo', unitInfo.locationDetail); await formApi.setFieldValue('roomInfo', unitInfo.locationDetail);
await formApi.setFieldValue('area', unitInfo.area); await formApi.setFieldValue('area', unitInfo.area);
} }
@@ -241,14 +250,12 @@ async function queryRoomByUnit(unitId: string) {
<BasicModal :title="title"> <BasicModal :title="title">
<BasicForm> <BasicForm>
<template #roomInfo="slotProps"> <template #roomInfo="slotProps">
<div> <div>
{{slotProps.field.value}} {{ slotProps.field.value }}
</div> </div>
</template> </template>
<template #area="slotProps"> <template #area="slotProps">
<div> <div>{{ slotProps.field.value }}</div>
{{slotProps.field.value}}
</div>
</template> </template>
</BasicForm> </BasicForm>
</BasicModal> </BasicModal>

View File

@@ -718,17 +718,16 @@ onBeforeUnmount(() => {
.left { .left {
display: flex; display: flex;
width: 18.3125rem; width: 18.3125rem;
font-size: 1.875rem;
font-family: ShiShangZhongHeiJianTi;
font-weight: 400;
.left-first { .left-first {
padding-left: 2.3125rem; padding-left: 2.3125rem;
font-size: 1.875rem;
width: 10.5rem; width: 10.5rem;
color: #ffffff; color: #ffffff;
} }
.left-second { .left-second {
width: 6.5rem; width: 6.5rem;
font-family: ShiShangZhongHeiJianTi;
font-weight: 400;
font-size: 1.25rem;
color: #ffffff; color: #ffffff;
} }
} }
@@ -759,7 +758,7 @@ onBeforeUnmount(() => {
} }
} }
.header { .header {
margin-top: 1.125rem; margin-top: 2.125rem;
margin-left: 4.625rem; margin-left: 4.625rem;
margin-right: 4.25rem; margin-right: 4.25rem;
height: 6rem; height: 6rem;