Files
admin-vben5/apps/web-antd/src/views/property/costManagement/costMeterWater/costMeterWater-modal.vue
2025-07-30 14:57:42 +08:00

402 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { computed, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { useVbenForm } from '#/adapter/form';
import {
costMeterWaterAdd,
costMeterWaterInfo,
costMeterWaterUpdate,
} from '#/api/property/costMeterWater';
import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup';
import { cloneDeep, handleNode, getPopupContainer } from '@vben/utils';
import { communityTree } from '#/api/property/community';
import { costItemSettingList } from '#/api/property/costManagement/costItemSetting';
import { meterReadingTypeList } from '#/api/property/costManagement/meterReadingType';
import { getDictOptions } from '#/utils/dict';
import { ultimoWater } from '#/api/property/costMeterWater';
import { personList } from '#/api/property/resident/person';
const emit = defineEmits<{ reload: [] }>();
const costItemsOptions = ref<any>([]);
const meterTypeOptions = ref<any>([]);
const isMeterType = ref(false);
const isUpdate = ref(false);
const title = computed(() => {
return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add');
});
const schema = [
{
label: '主键ID',
fieldName: 'id',
component: 'Input',
dependencies: {
show: () => false,
triggerFields: [''],
},
},
{
label: '房间号',
fieldName: 'roomId',
component: 'TreeSelect',
rules: 'required',
},
{
label: '业主',
fieldName: 'userId',
component: 'ApiSelect',
rules: 'required',
componentProps: {
api: async () => {
const res = await personList({ pageSize: 1000000000, pageNum: 1 });
return res.rows.map((item: any) => ({
label: item.userName,
value: item.id,
}));
},
},
},
{
label: '费用类型',
fieldName: 'costType',
component: 'Select',
rules: 'required',
componentProps: {
options: getDictOptions('wy_cbfylx'),
onChange: async (value: any) => {
// 请求并更新下拉
if (!value) {
costItemsOptions.value = [];
meterTypeOptions.value = [];
isMeterType.value = false;
} else {
isMeterType.value = true;
const costItemsRes = await costItemSettingList({
pageSize: 1000000000,
pageNum: 1,
costType: value,
});
costItemsOptions.value = (costItemsRes?.rows || []).map((item) => ({
label: item.chargeItem,
value: item.id,
}));
const meterTypeRes = await meterReadingTypeList({
pageSize: 1000000000,
pageNum: 1,
costType: value == '5' ? 0 : 1,
});
meterTypeOptions.value = (meterTypeRes?.rows || []).map((item) => ({
label: item.name,
value: item.id,
}));
}
// 更新表单下拉
formApi.updateSchema([
{
fieldName: 'itemId',
componentProps: {
options: costItemsOptions.value,
disabled: !isMeterType.value,
},
},
{
fieldName: 'meterTypeId',
componentProps: {
options: meterTypeOptions.value,
disabled: !isMeterType.value,
},
},
]);
// 清空依赖字段
await formApi.setValues({
itemId: '',
meterTypeId: '',
});
console.log(await formApi.getValues());
},
},
},
{
label: '收费项目',
fieldName: 'itemId',
component: 'Select',
rules: 'required',
componentProps: {
options: costItemsOptions.value,
disabled: !isMeterType.value,
},
},
{
label: '抄表类型',
fieldName: 'meterTypeId',
component: 'Select',
rules: 'required',
componentProps: {
options: meterTypeOptions.value,
disabled: !isMeterType.value,
},
},
{
label: '上期止度',
fieldName: 'preDegrees',
component: 'Input',
disabled: true,
},
{
label: '本期度数',
fieldName: 'curDegrees',
component: 'Input',
rules: 'required',
},
{
label: '上期读表时间',
fieldName: 'preReadingTime',
component: 'DatePicker',
componentProps: {
showTime: true,
format: 'YYYY-MM-DD HH:mm:ss',
valueFormat: 'YYYY-MM-DD HH:mm:ss',
},
disabled: true,
},
{
label: '本期读表时间',
fieldName: 'curReadingTime',
component: 'DatePicker',
componentProps: {
showTime: true,
format: 'YYYY-MM-DD HH:mm:ss',
valueFormat: 'YYYY-MM-DD HH:mm:ss',
},
rules: 'required',
},
{
label: '说明',
fieldName: 'remark',
component: 'Input',
},
];
const [BasicForm, formApi] = useVbenForm({
commonConfig: {
// 默认占满两列
formItemClass: 'col-span-2',
// 默认label宽度 px
labelWidth: 140,
// 通用配置项 会影响到所有表单项
componentProps: {
class: 'w-full',
},
},
schema: schema,
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;
}
isMeterType.value = true;
setupCommunitySelect();
modalApi.modalLoading(true);
const { id } = modalApi.getData() as { id?: number | string };
isUpdate.value = !!id;
if (isUpdate.value && id) {
const record = await costMeterWaterInfo(id);
console.log(1, record);
const costItemsRes = await costItemSettingList({
pageSize: 1000000000,
pageNum: 1,
costType: record.costType,
});
costItemsOptions.value = (costItemsRes?.rows || []).map((item) => ({
label: item.chargeItem,
value: item.id,
}));
const meterTypeRes = await meterReadingTypeList({
pageSize: 1000000000,
pageNum: 1,
costType: record.costType == '5' ? 0 : 1,
});
meterTypeOptions.value = (meterTypeRes?.rows || []).map((item) => ({
label: item.name,
value: item.id,
}));
formApi.updateSchema([
{
fieldName: 'itemId',
componentProps: {
options: costItemsOptions.value,
disabled: !isMeterType.value,
},
},
{
fieldName: 'meterTypeId',
componentProps: {
options: meterTypeOptions.value,
disabled: !isMeterType.value,
},
},
]);
await formApi.setValues(record);
console.log(2, await formApi.getValues());
}
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());
console.log(data);
await (isUpdate.value
? costMeterWaterUpdate(data)
: costMeterWaterAdd(data));
resetInitialized();
//必须要手动清空不然ref会保留值
costItemsOptions.value = [];
meterTypeOptions.value = [];
isMeterType.value = false;
// 更新表单下拉
formApi.updateSchema([
{
fieldName: 'itemId',
componentProps: {
options: costItemsOptions.value,
disabled: !isMeterType.value,
},
},
{
fieldName: 'meterTypeId',
componentProps: {
options: meterTypeOptions.value,
disabled: !isMeterType.value,
},
},
]);
emit('reload');
modalApi.close();
} catch (error) {
console.error(error);
} finally {
modalApi.lock(false);
}
}
async function handleClosed() {
await formApi.resetForm();
await formApi.setValues({});
costItemsOptions.value = [];
meterTypeOptions.value = [];
isMeterType.value = false;
// 更新表单下拉
formApi.updateSchema([
{
fieldName: 'itemId',
componentProps: {
options: costItemsOptions.value,
disabled: !isMeterType.value,
},
},
{
fieldName: 'meterTypeId',
componentProps: {
options: meterTypeOptions.value,
disabled: !isMeterType.value,
},
},
]);
resetInitialized();
}
// 获取服务地址
async function setupCommunitySelect() {
const areaList = await communityTree(4);
// 选中后显示在输入框的值 即父节点 / 子节点
// addFullName(areaList, 'areaName', ' / ');
const splitStr = '/';
handleNode(areaList, 'label', splitStr, function (node: any) {
if (node.level != 4) {
node.disabled = true;
}
});
formApi.updateSchema([
{
componentProps: () => ({
class: 'w-full',
fieldNames: {
key: 'id',
label: 'label',
value: 'code',
children: 'children',
},
getPopupContainer,
placeholder: '请选择房间',
showSearch: true,
treeData: areaList,
treeDefaultExpandAll: true,
treeLine: { showLeafIcon: false },
// 筛选的字段
treeNodeFilterProp: 'label',
// 选中后显示在输入框的值
treeNodeLabelProp: 'fullName',
onChange: async (value: any) => {
if (!value) {
await formApi.setValues({ preDegrees: '' });
await formApi.setValues({ preReadingTime: '' });
} else {
const data = await ultimoWater(value);
if (data) {
await formApi.setValues({ preDegrees: data.curDegrees });
await formApi.setValues({ preReadingTime: data.curReadingTime });
}
}
},
}),
fieldName: 'roomId',
},
]);
}
</script>
<template>
<BasicModal :title="title">
<BasicForm />
</BasicModal>
</template>
<style scoped>
/* 使用 :deep() 穿透 scoped 样式,影响子组件 */
:deep(.ant-input[disabled]),
:deep(.ant-input-number-disabled .ant-input-number-input),
:deep(.ant-select-disabled .ant-select-selection-item),
:deep(.ant-picker-input input[disabled]),
:deep(.ant-picker-disabled .ant-picker-input input) {
/* 设置一个更深的颜色,可以自己调整 */
color: rgba(0, 0, 0, 0.65) !important;
/* 有些浏览器需要这个来覆盖默认颜色 */
-webkit-text-fill-color: rgba(0, 0, 0, 0.65) !important;
}
</style>