diff --git a/.umirc.ts b/.umirc.ts index 4fd62ce..28f6911 100644 --- a/.umirc.ts +++ b/.umirc.ts @@ -18,6 +18,7 @@ export default defineConfig({ target: 'http://10.39.13.78:8001/', // target: 'https://test-admin.linyikj.com.cn/', // target: 'https://admin.linyikj.com.cn/', + // target: 'http://cd69cef8.natappfree.cc/', changeOrigin: true, pathRewrite: { '^': '' }, diff --git a/src/gen/ApiTypes.d.ts b/src/gen/ApiTypes.d.ts index 696d488..40edeec 100644 --- a/src/gen/ApiTypes.d.ts +++ b/src/gen/ApiTypes.d.ts @@ -15,6 +15,7 @@ declare namespace ApiTypes { "is_enroll"?: boolean; // 是否报名:1 是、0 否 "project_ids"?: string[]; // 项目ID "content": string; // 内容 + "cover_image"?: string[]; // 封面图片 }; type Update = { "id": number; // id @@ -26,6 +27,7 @@ declare namespace ApiTypes { "is_enroll"?: boolean; // 是否报名:1 是、0 否 "project_ids"?: string[]; // 项目ID "content": string; // 内容 + "cover_image"?: string[]; // 封面图片 }; type ChangePublishStatus = { "id": number; // id @@ -470,9 +472,14 @@ declare namespace ApiTypes { namespace Bill { namespace HouseBills { type List = { + "asset_houses_id"?: number; // 资产房屋id,[ref:asset_houses] "full_name"?: string; // 模糊搜索:房屋名称 "company_name"?: string; // 模糊搜索:公司名称 }; + type SummaryBillList = { + "full_name"?: string; // 模糊搜索:房屋名称 + "asset_houses_id"?: number; // 资产房屋id,[ref:asset_houses] + }; type Store = { "asset_houses_id": number; // 资产房屋id,[ref:asset_houses] "company_receipt_accounts_id": number; // 公司收款账户id,[ref:company_receipt_accounts] @@ -1278,6 +1285,131 @@ declare namespace ApiTypes { }; } } + namespace Meter { + namespace HouseMeterHasHouses { + type List = { + "house_meters_id"?: number; // 房屋仪表id,[ref:house_meters] + "name"?: string; // 模糊搜索:名称 + "full_name"?: string; // 模糊搜索:房屋全称 + }; + type StoreOrUpdate = { + "house_meters_id": number; // 房屋仪表id,[ref:house_meters] + "asset_houses_ids": string[]; // 房屋id,[ref:asset_houses] + }; + type Show = { + "id": number; // id + }; + type Delete = { + "id": number; // id + }; + } + namespace HouseMeterReadings { + type List = { + "name"?: string; // 模糊搜索:名称 + }; + type Store = { + "house_meters_id": number; // 仪表id,[ref:house_meters] + "operation_type": string; // 操作类型,[enum:HouseMeterReadingsOperationTypeEnum] + "current_reading": number; // 本次读数 + "reading_time": Date; // 抄表时间 + "company_employees_id": number; // 抄表人id,[ref:company_employees] + "remark": string; // 备注 + }; + type Update = { + "id": number; // id + "house_meters_id": number; // 仪表id,[ref:house_meters] + "operation_type": string; // 操作类型,[enum:HouseMeterReadingsOperationTypeEnum] + "previous_reading": number; // 上次读数 + "current_reading": number; // 本次读数 + "usage_amount": number; // 用量 + "loss_amount"?: number; // 损耗 + "reading_time": Date; // 抄表时间 + "company_employees_id": number; // 抄表人id,[ref:company_employees] + "remark": string; // 备注 + }; + type Show = { + "id": number; // id + }; + type Delete = { + "id": number; // id + }; + } + namespace HouseMeterTasks { + type List = { + "name"?: string; // 模糊搜索:名称 + }; + type Store = { + "asset_projects_id": number; // 资产项目id,[ref:asset_projects] + "generation_method": string; // 生成方式,[enum:HouseMeterTasksGenerationMethodEnum] + "month": string; // 月份 + "start_date": Date; // 收费开始日期 + "end_date": Date; // 收费截止日期 + "data": string[]; // 任务数据(如果是楼栋则是楼栋ID,如果是单元则是单元ID,如果是仪表则是仪表ID) + }; + type Show = { + "id": number; // id + }; + type SoftDelete = { + "id": number; // id + }; + type Restore = { + "id": number; // id + }; + type Delete = { + "id": number; // id + }; + } + namespace HouseMeters { + type List = { + "name"?: string; // 模糊搜索:名称 + "asset_projects_id"?: number; // 项目id,[ref:asset_projects] + "project_name"?: string; // 模糊搜索:项目名称 + }; + type Store = { + "asset_projects_id": number; // 项目id,[ref:asset_projects] + "charge_standards_id"?: number; // 房屋收费标准id,[ref:house_charge_standards] + "companies_id": number; // 机构id,[ref:companies] + "name": string; // 名称 + "meter_type": string; // 仪表类型,[enum:HouseMetersMeterTypeEnum] + "usage_type": string; // 使用类型,[enum:HouseMetersUsageTypeEnum] + "multiple"?: number; // 倍率 + "status"?: number; // 是否启用:0:禁用,1:启用 + "initial_value"?: number; // 初始抄表读数 + "initial_time"?: Date; // 初始抄表时间 + "latest_value"?: number; // 最新抄表读数 + "latest_time"?: Date; // 最新抄表时间 + "remark"?: string; // 备注 + }; + type Update = { + "id": number; // id + "asset_projects_id": number; // 项目id,[ref:asset_projects] + "charge_standards_id"?: number; // 房屋收费标准id,[ref:house_charge_standards] + "companies_id": number; // 机构id,[ref:companies] + "name": string; // 名称 + "meter_type": string; // 仪表类型,[enum:HouseMetersMeterTypeEnum] + "usage_type": string; // 使用类型,[enum:HouseMetersUsageTypeEnum] + "multiple"?: number; // 倍率 + "status"?: number; // 是否启用:0:禁用,1:启用 + "initial_value"?: number; // 初始抄表读数 + "initial_time"?: Date; // 初始抄表时间 + "latest_value"?: number; // 最新抄表读数 + "latest_time"?: Date; // 最新抄表时间 + "remark"?: string; // 备注 + }; + type Show = { + "id": number; // id + }; + type SoftDelete = { + "id": number; // id + }; + type Restore = { + "id": number; // id + }; + type Delete = { + "id": number; // id + }; + } + } namespace Msg { namespace MsgPropertyAnnouncements { type List = { diff --git a/src/gen/Apis.ts b/src/gen/Apis.ts index d372e32..b2b2119 100644 --- a/src/gen/Apis.ts +++ b/src/gen/Apis.ts @@ -254,6 +254,9 @@ export const Apis = { List(data?: ApiTypes.Bill.HouseBills.List): Promise { return request('admin/bill/house_bills/list', { data }); }, + SummaryBillList(data?: ApiTypes.Bill.HouseBills.SummaryBillList): Promise { + return request('admin/bill/house_bills/summary_bill_list', { data }); + }, Store(data: ApiTypes.Bill.HouseBills.Store): Promise { return request('admin/bill/house_bills/store', { data }); }, @@ -754,6 +757,82 @@ export const Apis = { }, }, }, + Meter: { + HouseMeterHasHouses: { + List(data?: ApiTypes.Meter.HouseMeterHasHouses.List): Promise { + return request('admin/meter/house_meter_has_houses/list', { data }); + }, + StoreOrUpdate(data: ApiTypes.Meter.HouseMeterHasHouses.StoreOrUpdate): Promise { + return request('admin/meter/house_meter_has_houses/store_or_update', { data }); + }, + Show(data: ApiTypes.Meter.HouseMeterHasHouses.Show): Promise { + return request('admin/meter/house_meter_has_houses/show', { data }); + }, + Delete(data: ApiTypes.Meter.HouseMeterHasHouses.Delete): Promise { + return request('admin/meter/house_meter_has_houses/delete', { data }); + }, + }, + HouseMeterReadings: { + List(data?: ApiTypes.Meter.HouseMeterReadings.List): Promise { + return request('admin/meter/house_meter_readings/list', { data }); + }, + Store(data: ApiTypes.Meter.HouseMeterReadings.Store): Promise { + return request('admin/meter/house_meter_readings/store', { data }); + }, + Update(data: ApiTypes.Meter.HouseMeterReadings.Update): Promise { + return request('admin/meter/house_meter_readings/update', { data }); + }, + Show(data: ApiTypes.Meter.HouseMeterReadings.Show): Promise { + return request('admin/meter/house_meter_readings/show', { data }); + }, + Delete(data: ApiTypes.Meter.HouseMeterReadings.Delete): Promise { + return request('admin/meter/house_meter_readings/delete', { data }); + }, + }, + HouseMeterTasks: { + List(data?: ApiTypes.Meter.HouseMeterTasks.List): Promise { + return request('admin/meter/house_meter_tasks/list', { data }); + }, + Store(data: ApiTypes.Meter.HouseMeterTasks.Store): Promise { + return request('admin/meter/house_meter_tasks/store', { data }); + }, + Show(data: ApiTypes.Meter.HouseMeterTasks.Show): Promise { + return request('admin/meter/house_meter_tasks/show', { data }); + }, + SoftDelete(data: ApiTypes.Meter.HouseMeterTasks.SoftDelete): Promise { + return request('admin/meter/house_meter_tasks/soft_delete', { data }); + }, + Restore(data: ApiTypes.Meter.HouseMeterTasks.Restore): Promise { + return request('admin/meter/house_meter_tasks/restore', { data }); + }, + Delete(data: ApiTypes.Meter.HouseMeterTasks.Delete): Promise { + return request('admin/meter/house_meter_tasks/delete', { data }); + }, + }, + HouseMeters: { + List(data?: ApiTypes.Meter.HouseMeters.List): Promise { + return request('admin/meter/house_meters/list', { data }); + }, + Store(data: ApiTypes.Meter.HouseMeters.Store): Promise { + return request('admin/meter/house_meters/store', { data }); + }, + Update(data: ApiTypes.Meter.HouseMeters.Update): Promise { + return request('admin/meter/house_meters/update', { data }); + }, + Show(data: ApiTypes.Meter.HouseMeters.Show): Promise { + return request('admin/meter/house_meters/show', { data }); + }, + SoftDelete(data: ApiTypes.Meter.HouseMeters.SoftDelete): Promise { + return request('admin/meter/house_meters/soft_delete', { data }); + }, + Restore(data: ApiTypes.Meter.HouseMeters.Restore): Promise { + return request('admin/meter/house_meters/restore', { data }); + }, + Delete(data: ApiTypes.Meter.HouseMeters.Delete): Promise { + return request('admin/meter/house_meters/delete', { data }); + }, + }, + }, Msg: { MsgPropertyAnnouncements: { List(data?: ApiTypes.Msg.MsgPropertyAnnouncements.List): Promise { diff --git a/src/gen/Enums.ts b/src/gen/Enums.ts index ed38816..eceb3cf 100644 --- a/src/gen/Enums.ts +++ b/src/gen/Enums.ts @@ -154,7 +154,7 @@ export const BannersTypeEnum= { // 缓存类型 export const CacheTypeEnum= { - 'MobilePhoneVerificationCode': {"text":"手机验证码","color":"#5acfb3","value":"MobilePhoneVerificationCode"}, + 'MobilePhoneVerificationCode': {"text":"手机验证码","color":"#0a9319","value":"MobilePhoneVerificationCode"}, }; // CompaniesMerchantTypeEnum @@ -226,7 +226,6 @@ export const CustomerMomentTasksStatusEnum= { // CustomerMomentsChannelEnum export const CustomerMomentsChannelEnum= { 'MomentCorp': {"text":"朋友圈(企业)","color":"#1E90FF","value":"MomentCorp"}, - 'MomentPersonal': {"text":"朋友圈(个人)","color":"#32CD32","value":"MomentPersonal"}, 'CustomerDirectCorp': {"text":"客户1对1消息群发(企业)","color":"#FFA500","value":"CustomerDirectCorp"}, 'CustomerGroupCorp': {"text":"客户群群发(企业)","color":"#FF69B4","value":"CustomerGroupCorp"}, }; @@ -396,6 +395,34 @@ export const HouseCollectionTasksStatusEnum= { 'Failed': {"text":"失败","color":"#ff0000","value":"Failed"}, }; +// HouseMeterReadingsOperationTypeEnum +export const HouseMeterReadingsOperationTypeEnum= { + 'NormalReading': {"text":"正常抄表","color":"#4caf50","value":"NormalReading"}, + 'ResetReading': {"text":"重置读数","color":"#f44336","value":"ResetReading"}, + 'CorrectReading': {"text":"修正读数","color":"#ff9800","value":"CorrectReading"}, +}; + +// HouseMeterTasksGenerationMethodEnum +export const HouseMeterTasksGenerationMethodEnum= { + 'Building': {"text":"按楼栋","color":"#4caf50","value":"Building"}, + 'Unit': {"text":"按单元","color":"#2196f3","value":"Unit"}, + 'Meter': {"text":"按仪表","color":"#ff9800","value":"Meter"}, +}; + +// HouseMetersMeterTypeEnum +export const HouseMetersMeterTypeEnum= { + 'HouseMeter': {"text":"房屋表","color":"#4caf50","value":"HouseMeter"}, + 'CommonMeter': {"text":"公摊表","color":"#2196f3","value":"CommonMeter"}, +}; + +// HouseMetersUsageTypeEnum +export const HouseMetersUsageTypeEnum= { + 'WaterMeter': {"text":"水表","color":"#2196f3","value":"WaterMeter"}, + 'ElectricMeter': {"text":"电表","color":"#ff9800","value":"ElectricMeter"}, + 'GasMeter': {"text":"燃气表","color":"#f44336","value":"GasMeter"}, + 'HeatingMeter': {"text":"暖气表","color":"#9c27b0","value":"HeatingMeter"}, +}; + // HouseOccupantsCardTypeEnum export const HouseOccupantsCardTypeEnum= { 'MainlandID': {"text":"中国大陆居民身份证","color":"#2db7f5","value":"MainlandID"}, diff --git a/src/pages/archive/components/HouseInfo.tsx b/src/pages/archive/components/HouseInfo.tsx index 5ef33a2..03b9061 100644 --- a/src/pages/archive/components/HouseInfo.tsx +++ b/src/pages/archive/components/HouseInfo.tsx @@ -7,7 +7,7 @@ import { } from '@/gen/Enums'; import { ProCard, ProDescriptions } from '@ant-design/pro-components'; import { Space } from 'antd'; -import ChangeStatus from './modals/ChangeStatus'; +import ChangeStatus from '../table/modals/ChangeStatus'; export default function info(props: MyBetaModalFormProps) { const { item } = props; diff --git a/src/pages/archive/components/SummaryInfo.tsx b/src/pages/archive/components/SummaryInfo.tsx new file mode 100644 index 0000000..f801d88 --- /dev/null +++ b/src/pages/archive/components/SummaryInfo.tsx @@ -0,0 +1,49 @@ +import { MyBetaModalFormProps, MyProTableProps } from '@/common'; +import { Apis } from '@/gen/Apis'; +import { ProCard, ProTable } from '@ant-design/pro-components'; + +export default function info(props: MyBetaModalFormProps) { + const { item } = props; + return ( + + + MyProTableProps.request( + { + ...params, + asset_houses_id: item?.asset_houses_id, + }, + sort, + Apis.Bill.HouseBills.SummaryBillList, + ) + } + search={false} + options={false} + pagination={false} + columns={[ + { + title: '账单金额合计', + dataIndex: 'payable_amount_sum', + search: false, + }, + { + title: '滞纳金合计', + dataIndex: 'late_fee_sum', + search: false, + }, + { + title: '优惠金额合计', + dataIndex: 'discount_amount_sum', + search: false, + }, + { + title: '应付合计', + dataIndex: 'total_payable_sum', + search: false, + }, + ]} + /> + + ); +} diff --git a/src/pages/archive/show/$id.tsx b/src/pages/archive/show/$id.tsx index 7d0c324..eb9bdcb 100644 --- a/src/pages/archive/show/$id.tsx +++ b/src/pages/archive/show/$id.tsx @@ -5,9 +5,11 @@ import { useParams } from '@umijs/max'; import { Badge, Tabs } from 'antd'; import { useEffect, useState } from 'react'; import HouseInfo from '../components/HouseInfo'; -import OccupantsHistory from '../components/OccupantsHistory'; -import OccupantsNow from '../components/OccupantsNow'; -import RegistersList from '../components/RegistersList'; +import SummaryInfo from '../components/SummaryInfo'; +import OccupantsHistory from '../table/OccupantsHistory'; +import OccupantsNow from '../table/OccupantsNow'; +import RegistersList from '../table/RegistersList'; +import UnpaidBill from '../table/UnpaidBill'; export default function Show({ title = '房屋档案' }) { const { id } = useParams<{ id: string }>(); @@ -88,11 +90,18 @@ export default function Show({ title = '房屋档案' }) { /> ), }, + { + label: '欠费账单', + key: '4', + closable: false, + children: , + }, ]; return ( + diff --git a/src/pages/archive/components/OccupantsHistory.tsx b/src/pages/archive/table/OccupantsHistory.tsx similarity index 100% rename from src/pages/archive/components/OccupantsHistory.tsx rename to src/pages/archive/table/OccupantsHistory.tsx diff --git a/src/pages/archive/components/OccupantsNow.tsx b/src/pages/archive/table/OccupantsNow.tsx similarity index 100% rename from src/pages/archive/components/OccupantsNow.tsx rename to src/pages/archive/table/OccupantsNow.tsx diff --git a/src/pages/archive/components/RegistersList.tsx b/src/pages/archive/table/RegistersList.tsx similarity index 100% rename from src/pages/archive/components/RegistersList.tsx rename to src/pages/archive/table/RegistersList.tsx diff --git a/src/pages/archive/table/UnpaidBill.tsx b/src/pages/archive/table/UnpaidBill.tsx new file mode 100644 index 0000000..7382e46 --- /dev/null +++ b/src/pages/archive/table/UnpaidBill.tsx @@ -0,0 +1,71 @@ +import { MyColumns, MyProTableProps } from '@/common'; +import { Apis } from '@/gen/Apis'; +import { HouseBillsTypeEnum } from '@/gen/Enums'; +import BillUpdate from '@/pages/bills/list/modals/BillUpdate'; +import { ProTable } from '@ant-design/pro-components'; +import { Space } from 'antd'; +import { useEffect, useRef } from 'react'; + +export default function Index({ ...rest }) { + const actionLooks = useRef(); + useEffect(() => { + actionLooks?.current.reloadAndRest(); + }, [rest.loadmore]); + + return ( + <> + > + {...MyProTableProps.props} + actionRef={actionLooks} + request={async (params, sort) => + MyProTableProps.request( + { + ...params, + asset_houses_id: rest.item?.asset_houses_id, + status: 'Normal', + }, + sort, + Apis.Bill.HouseBills.List, + ) + } + search={false} + columns={[ + MyColumns.ID(), + MyColumns.EnumTag({ + title: '类型', + dataIndex: 'type', + valueEnum: HouseBillsTypeEnum, + }), + { + title: '账单月份', + render: (_, record) => { + return `${record.year}-${String(record.month).padStart(2, '0')}`; + }, + }, + { + title: '应付金额', + dataIndex: 'total_payable_amount', + search: false, + }, + { + title: '计费开始日期', + dataIndex: 'start_date', + search: false, + }, + { + title: '计费结束日期', + dataIndex: 'end_date', + search: false, + }, + MyColumns.Option({ + render: (_, item: any, index, action) => ( + + + + ), + }), + ]} + /> + + ); +} diff --git a/src/pages/archive/components/modals/AddOccupant.tsx b/src/pages/archive/table/modals/AddOccupant.tsx similarity index 100% rename from src/pages/archive/components/modals/AddOccupant.tsx rename to src/pages/archive/table/modals/AddOccupant.tsx diff --git a/src/pages/archive/components/modals/ChangePhone.tsx b/src/pages/archive/table/modals/ChangePhone.tsx similarity index 100% rename from src/pages/archive/components/modals/ChangePhone.tsx rename to src/pages/archive/table/modals/ChangePhone.tsx diff --git a/src/pages/archive/components/modals/ChangeStatus.tsx b/src/pages/archive/table/modals/ChangeStatus.tsx similarity index 100% rename from src/pages/archive/components/modals/ChangeStatus.tsx rename to src/pages/archive/table/modals/ChangeStatus.tsx diff --git a/src/pages/archive/components/modals/MoveIn.tsx b/src/pages/archive/table/modals/MoveIn.tsx similarity index 100% rename from src/pages/archive/components/modals/MoveIn.tsx rename to src/pages/archive/table/modals/MoveIn.tsx diff --git a/src/pages/archive/components/modals/MoveOut.tsx b/src/pages/archive/table/modals/MoveOut.tsx similarity index 100% rename from src/pages/archive/components/modals/MoveOut.tsx rename to src/pages/archive/table/modals/MoveOut.tsx diff --git a/src/pages/archive/components/modals/OccupantShow.tsx b/src/pages/archive/table/modals/OccupantShow.tsx similarity index 100% rename from src/pages/archive/components/modals/OccupantShow.tsx rename to src/pages/archive/table/modals/OccupantShow.tsx diff --git a/src/pages/archive/components/modals/OccupantsUpdate.tsx b/src/pages/archive/table/modals/OccupantsUpdate.tsx similarity index 100% rename from src/pages/archive/components/modals/OccupantsUpdate.tsx rename to src/pages/archive/table/modals/OccupantsUpdate.tsx diff --git a/src/pages/archive/components/modals/OwnerUpdate.tsx b/src/pages/archive/table/modals/OwnerUpdate.tsx similarity index 100% rename from src/pages/archive/components/modals/OwnerUpdate.tsx rename to src/pages/archive/table/modals/OwnerUpdate.tsx diff --git a/src/pages/archive/components/modals/RegistersShow.tsx b/src/pages/archive/table/modals/RegistersShow.tsx similarity index 100% rename from src/pages/archive/components/modals/RegistersShow.tsx rename to src/pages/archive/table/modals/RegistersShow.tsx diff --git a/src/pages/archive/components/modals/RemoveOwner.tsx b/src/pages/archive/table/modals/RemoveOwner.tsx similarity index 100% rename from src/pages/archive/components/modals/RemoveOwner.tsx rename to src/pages/archive/table/modals/RemoveOwner.tsx diff --git a/src/pages/archive/components/modals/Transfer.tsx b/src/pages/archive/table/modals/Transfer.tsx similarity index 100% rename from src/pages/archive/components/modals/Transfer.tsx rename to src/pages/archive/table/modals/Transfer.tsx diff --git a/src/pages/asset/activities/modals/ActivityCreate.tsx b/src/pages/asset/activities/modals/ActivityCreate.tsx index 1fc7ef2..842280f 100644 --- a/src/pages/asset/activities/modals/ActivityCreate.tsx +++ b/src/pages/asset/activities/modals/ActivityCreate.tsx @@ -153,6 +153,18 @@ export default function Create(props: MyBetaModalFormProps) { }, renderFormItem: () => , }, + MyFormItems.UploadImages({ + key: 'cover_image', + title: '活动封面', + tooltip: '建议图片比例 16:9', + fieldProps: { + style: { + width: 160, + height: 90, + }, + }, + max: 1, + }), ]} /> ); diff --git a/src/pages/asset/activities/modals/ActivityShow.tsx b/src/pages/asset/activities/modals/ActivityShow.tsx index f7b2b01..86842e1 100644 --- a/src/pages/asset/activities/modals/ActivityShow.tsx +++ b/src/pages/asset/activities/modals/ActivityShow.tsx @@ -80,7 +80,21 @@ export default function Show(props: MyBetaModalFormProps) { {show?.publish_time || '-'} - + + {show?.cover_image?.[0]?.url ? ( + {show?.title + ) : ( + '-' + )} +
, initialValue: props.item?.content, }, + MyFormItems.UploadImages({ + key: 'cover_image', + title: '活动封面', + tooltip: '建议图片比例 16:9', + fieldProps: { + style: { + width: 160, + height: 90, + }, + }, + max: 1, + }), ]} /> ); diff --git a/src/pages/asset/dictionary/index.tsx b/src/pages/asset/dictionary/index.tsx new file mode 100644 index 0000000..b942d29 --- /dev/null +++ b/src/pages/asset/dictionary/index.tsx @@ -0,0 +1,539 @@ +import { + MyButtons, + MyColumns, + MyPageContainer, + MyProTableProps, + usePageTabs, +} from '@/common'; +import { Apis } from '@/gen/Apis'; +import { + AssetHousesOwnershipTypeEnum, + AssetHousesUsageEnum, +} from '@/gen/Enums'; +import { ProCard, ProTable } from '@ant-design/pro-components'; +import { useNavigate } from '@umijs/max'; +import { Alert, message, Space, Typography } from 'antd'; +import { useCallback, useMemo, useRef, useState } from 'react'; +import BuildingsCreate from './modals/BuildingsCreate'; +import AssetBuildingsUpdate from './modals/BuildingsUpdate'; +import HousesCreate from './modals/HousesCreate'; +import HousesUpdate from './modals/HousesUpdate'; +import UnitsCreate from './modals/UnitsCreate'; +import AssetUnitsUpdate from './modals/UnitsUpdate'; + +const { Title } = Typography; +interface SelectedAsset { + id: number; + name: string; +} + +interface SelectedBuilding { + id: number; + name: string; +} + +interface SelectedUnit { + id: number; + name: string; +} + +export default function Index({ title = '项目列表' }) { + usePageTabs({ + tabKey: 'asset-buildings', + tabLabel: title, + }); + + const actionAssetRef: any = useRef(); + const actionBuildingsRef: any = useRef(); + const actionUnitsRef: any = useRef(); + const actionHousesRef: any = useRef(); + const navigate = useNavigate(); + + const [selectedAsset, setSelectedAsset] = useState( + null, + ); + const [selectedBuilding, setSelectedBuilding] = + useState(null); + const [selectedUnit, setSelectedUnit] = useState(null); + const [loading, setLoading] = useState({ + buildings: false, + units: false, + houses: false, + }); + + // 选择项目的回调函数 + const handleAssetSelect = useCallback( + (asset: SelectedAsset) => { + if (selectedAsset?.id === asset.id) return; // 避免重复选择 + + setSelectedAsset(asset); + setSelectedBuilding(null); // 重置楼栋选择 + setSelectedUnit(null); // 重置单元选择 + + // 刷新楼栋和单元列表 + actionBuildingsRef?.current?.reload(); + actionUnitsRef?.current?.reload(); + actionHousesRef?.current?.reload(); + }, + [selectedAsset?.id], + ); + + // 选择楼栋的回调函数 + const handleBuildingSelect = useCallback( + (building: SelectedBuilding) => { + if (selectedBuilding?.id === building.id) return; // 避免重复选择 + + setSelectedBuilding(building); + setSelectedUnit(null); // 重置单元选择 + + // 刷新单元和房屋列表 + actionUnitsRef?.current?.reload(); + actionHousesRef?.current?.reload(); + }, + [selectedBuilding?.id], + ); + + // 选择单元的回调函数 + const handleUnitSelect = useCallback( + (unit: SelectedUnit) => { + if (selectedUnit?.id === unit.id) return; // 避免重复选择 + + setSelectedUnit(unit); + // 刷新房屋列表 + actionHousesRef?.current?.reload(); + }, + [selectedUnit?.id], + ); + + // 删除操作的通用处理 + const handleDelete = useCallback( + async (deleteApi: any, id: number, reloadAction: any, itemName: string) => { + try { + await deleteApi({ id }); + message.success(`${itemName}删除成功`); + reloadAction(); + + // 如果删除的是当前选中项,清空选择 + if (itemName === '项目' && selectedAsset?.id === id) { + setSelectedAsset(null); + setSelectedBuilding(null); + setSelectedUnit(null); + } else if (itemName === '楼栋' && selectedBuilding?.id === id) { + setSelectedBuilding(null); + setSelectedUnit(null); + } else if (itemName === '单元' && selectedUnit?.id === id) { + setSelectedUnit(null); + } + } catch (error) { + message.error(`${itemName}删除失败`); + console.error(`删除${itemName}失败:`, error); + } + }, + [selectedAsset?.id, selectedBuilding?.id, selectedUnit?.id], + ); + + // 通用表格配置 + const getTableConfig = useMemo( + () => ({ + ...MyProTableProps.props, + search: false as const, + size: 'middle' as const, + options: false as const, + pagination: { + pageSize: 10, + showSizeChanger: false, + }, + }), + [], + ); + + // 项目表格列配置 + const projectColumns = useMemo( + () => [ + { + title: '项目', + dataIndex: 'name', + ellipsis: true, + search: { + transform: (value: string) => ({ name: value }), + }, + }, + MyColumns.Option({ + width: 120, + render: (_, item: any, index, action) => ( + + { + navigate(`/asset/list/show/${item.id}`); + }} + /> + + ), + }), + ], + [handleDelete], + ); + + // 楼栋表格列配置 + const buildingColumns = useMemo( + () => [ + { + title: '楼栋', + dataIndex: 'name', + ellipsis: true, + }, + MyColumns.Option({ + width: 120, + render: (_, item: any, index, action) => ( + + + {/* + handleDelete( + Apis.Asset.AssetBuildings.Delete, + item.id, + action?.reload, + '楼栋', + ) + } + /> */} + + ), + }), + ], + [handleDelete], + ); + + // 单元表格列配置 + const unitColumns = useMemo( + () => [ + { + title: '单元', + dataIndex: 'name', + ellipsis: true, + }, + MyColumns.Option({ + width: 120, + render: (_, item: any, index, action) => ( + + + {/* + handleDelete( + Apis.Asset.AssetUnits.Delete, + item.id, + action?.reload, + '单元', + ) + } + /> */} + + ), + }), + ], + [handleDelete], + ); + + // 房屋表格列配置 + const houseColumns = useMemo( + () => [ + MyColumns.EnumTag({ + title: '用途', + dataIndex: 'usage', + valueEnum: AssetHousesUsageEnum, + }), + { + title: '房屋名称', + dataIndex: 'full_name', + }, + { + title: '楼层', + dataIndex: 'floor', + render(_, record) { + return `${record?.floor}层`; + }, + }, + { + title: '房号', + dataIndex: 'name', + }, + { + title: '计费面积', + dataIndex: 'chargeable_area', + render(_, record) { + return `${ + record?.chargeable_area ? record?.chargeable_area + ' m²' : '-' + } `; + }, + }, + + MyColumns.EnumTag({ + title: '房屋属性', + dataIndex: 'ownership_type', + valueEnum: AssetHousesOwnershipTypeEnum, + }), + MyColumns.Option({ + width: 120, + render: (_, item: any, index, action) => ( + + + {/* + handleDelete( + Apis.Asset.AssetHouses.Delete, + item.id, + action?.reload, + '房屋', + ) + } + /> */} + + ), + }), + ], + [handleDelete], + ); + + return ( + + + } + > + +
+ + <Space + style={{ display: 'flex', justifyContent: 'space-between' }} + > + 项目信息 + </Space> + + { + return selectedAsset?.id === record?.id + ? 'ant-table-row-selected' + : ''; + }} + onRow={(record: any) => { + return { + onClick: () => { + handleAssetSelect(record); + }, + style: { + cursor: 'pointer', + }, + }; + }} + request={async (params, sort) => + MyProTableProps.request( + { ...params }, + sort, + Apis.Asset.AssetProjects.List, + ) + } + columns={projectColumns} + /> +
+ + {/* 楼栋列表 */} + {selectedAsset ? ( +
+ + <Space + style={{ display: 'flex', justifyContent: 'space-between' }} + > + <span>{selectedAsset?.name}</span> + <BuildingsCreate + key="BuildingsCreate" + item={{ ...selectedAsset, size: 'small' }} + reload={() => actionBuildingsRef?.current?.reload()} + title="楼栋" + /> + </Space> + + { + return selectedBuilding?.id === record?.id + ? 'ant-table-row-selected' + : ''; + }} + onRow={(record: any) => { + return { + onClick: () => { + handleBuildingSelect(record); + }, + style: { + cursor: 'pointer', + }, + }; + }} + request={async (params, sort) => + MyProTableProps.request( + { ...params, asset_projects_id: selectedAsset?.id }, + sort, + Apis.Asset.AssetBuildings.List, + ) + } + columns={buildingColumns} + /> +
+ ) : ( +
+ 请先选择项目 +
+ )} + {/* 单元列表 */} + {selectedBuilding ? ( +
+ + <Space + style={{ display: 'flex', justifyContent: 'space-between' }} + > + <span>{selectedBuilding.name}</span> + <UnitsCreate + key="UnitsCreate" + item={{ + ...selectedBuilding, + asset_buildings_id: selectedBuilding?.id, + size: 'small', + }} + reload={() => actionUnitsRef?.current?.reload()} + title="单元" + /> + </Space> + + + MyProTableProps.request( + { + ...params, + asset_projects_id: selectedAsset?.id, + asset_buildings_id: selectedBuilding?.id, + }, + sort, + Apis.Asset.AssetUnits.List, + ) + } + rowClassName={(record: any) => { + return selectedUnit?.id === record?.id + ? 'ant-table-row-selected' + : ''; + }} + onRow={(record: any) => { + return { + onClick: () => { + handleUnitSelect(record); + }, + style: { + cursor: 'pointer', + }, + }; + }} + columns={unitColumns} + /> +
+ ) : ( +
+ 请先选择楼栋 +
+ )} + + {/* 房屋列表 */} + {selectedUnit ? ( +
+ + <Space + style={{ display: 'flex', justifyContent: 'space-between' }} + > + <span>{selectedUnit.name}</span> + <HousesCreate + key="HousesCreate" + item={{ + ...selectedUnit, + asset_projects_id: selectedAsset?.id, + asset_buildings_id: selectedBuilding?.id, + asset_units_id: selectedUnit?.id, + size: 'small', + }} + reload={() => actionHousesRef?.current?.reload()} + title="房屋" + /> + </Space> + + + MyProTableProps.request( + { + ...params, + asset_projects_id: selectedAsset?.id, + asset_buildings_id: selectedBuilding?.id, + asset_units_id: selectedUnit?.id, + }, + sort, + Apis.Asset.AssetHouses.List, + ) + } + columns={houseColumns} + /> +
+ ) : ( +
+ {selectedBuilding ? '请先选择单元' : '请先选择楼栋'} +
+ )} +
+
+
+ ); +} diff --git a/src/pages/asset/houses/modals/BuildingsCreate.tsx b/src/pages/asset/dictionary/modals/BuildingsCreate.tsx similarity index 100% rename from src/pages/asset/houses/modals/BuildingsCreate.tsx rename to src/pages/asset/dictionary/modals/BuildingsCreate.tsx diff --git a/src/pages/asset/houses/modals/BuildingsUpdate.tsx b/src/pages/asset/dictionary/modals/BuildingsUpdate.tsx similarity index 100% rename from src/pages/asset/houses/modals/BuildingsUpdate.tsx rename to src/pages/asset/dictionary/modals/BuildingsUpdate.tsx diff --git a/src/pages/asset/houses/modals/HousesCreate.tsx b/src/pages/asset/dictionary/modals/HousesCreate.tsx similarity index 100% rename from src/pages/asset/houses/modals/HousesCreate.tsx rename to src/pages/asset/dictionary/modals/HousesCreate.tsx diff --git a/src/pages/asset/houses/modals/HousesShow.tsx b/src/pages/asset/dictionary/modals/HousesShow.tsx similarity index 100% rename from src/pages/asset/houses/modals/HousesShow.tsx rename to src/pages/asset/dictionary/modals/HousesShow.tsx diff --git a/src/pages/asset/houses/modals/HousesUpdate.tsx b/src/pages/asset/dictionary/modals/HousesUpdate.tsx similarity index 100% rename from src/pages/asset/houses/modals/HousesUpdate.tsx rename to src/pages/asset/dictionary/modals/HousesUpdate.tsx diff --git a/src/pages/asset/houses/modals/UnitsCreate.tsx b/src/pages/asset/dictionary/modals/UnitsCreate.tsx similarity index 100% rename from src/pages/asset/houses/modals/UnitsCreate.tsx rename to src/pages/asset/dictionary/modals/UnitsCreate.tsx diff --git a/src/pages/asset/houses/modals/UnitsUpdate.tsx b/src/pages/asset/dictionary/modals/UnitsUpdate.tsx similarity index 100% rename from src/pages/asset/houses/modals/UnitsUpdate.tsx rename to src/pages/asset/dictionary/modals/UnitsUpdate.tsx diff --git a/src/pages/asset/houses/index.tsx b/src/pages/asset/houses/index.tsx index b942d29..4cea6fe 100644 --- a/src/pages/asset/houses/index.tsx +++ b/src/pages/asset/houses/index.tsx @@ -5,535 +5,164 @@ import { MyProTableProps, usePageTabs, } from '@/common'; +import { MyExport } from '@/components/MyExport'; import { Apis } from '@/gen/Apis'; import { AssetHousesOwnershipTypeEnum, AssetHousesUsageEnum, } from '@/gen/Enums'; -import { ProCard, ProTable } from '@ant-design/pro-components'; +import { ProTable } from '@ant-design/pro-components'; import { useNavigate } from '@umijs/max'; -import { Alert, message, Space, Typography } from 'antd'; -import { useCallback, useMemo, useRef, useState } from 'react'; -import BuildingsCreate from './modals/BuildingsCreate'; -import AssetBuildingsUpdate from './modals/BuildingsUpdate'; -import HousesCreate from './modals/HousesCreate'; -import HousesUpdate from './modals/HousesUpdate'; -import UnitsCreate from './modals/UnitsCreate'; -import AssetUnitsUpdate from './modals/UnitsUpdate'; +import { Space } from 'antd'; +import { useState } from 'react'; +import HousesShow from '../dictionary/modals/HousesShow'; +import HousesUpdate from '../dictionary/modals/HousesUpdate'; -const { Title } = Typography; -interface SelectedAsset { - id: number; - name: string; -} +export default function Index({ title = '房屋列表' }) { + const [getParams, setParams] = useState({}); -interface SelectedBuilding { - id: number; - name: string; -} - -interface SelectedUnit { - id: number; - name: string; -} - -export default function Index({ title = '项目列表' }) { + const navigate = useNavigate(); + // 注册当前页面为标签页 usePageTabs({ - tabKey: 'asset-buildings', + tabKey: 'asset-houses', tabLabel: title, }); - - const actionAssetRef: any = useRef(); - const actionBuildingsRef: any = useRef(); - const actionUnitsRef: any = useRef(); - const actionHousesRef: any = useRef(); - const navigate = useNavigate(); - - const [selectedAsset, setSelectedAsset] = useState( - null, - ); - const [selectedBuilding, setSelectedBuilding] = - useState(null); - const [selectedUnit, setSelectedUnit] = useState(null); - const [loading, setLoading] = useState({ - buildings: false, - units: false, - houses: false, - }); - - // 选择项目的回调函数 - const handleAssetSelect = useCallback( - (asset: SelectedAsset) => { - if (selectedAsset?.id === asset.id) return; // 避免重复选择 - - setSelectedAsset(asset); - setSelectedBuilding(null); // 重置楼栋选择 - setSelectedUnit(null); // 重置单元选择 - - // 刷新楼栋和单元列表 - actionBuildingsRef?.current?.reload(); - actionUnitsRef?.current?.reload(); - actionHousesRef?.current?.reload(); - }, - [selectedAsset?.id], - ); - - // 选择楼栋的回调函数 - const handleBuildingSelect = useCallback( - (building: SelectedBuilding) => { - if (selectedBuilding?.id === building.id) return; // 避免重复选择 - - setSelectedBuilding(building); - setSelectedUnit(null); // 重置单元选择 - - // 刷新单元和房屋列表 - actionUnitsRef?.current?.reload(); - actionHousesRef?.current?.reload(); - }, - [selectedBuilding?.id], - ); - - // 选择单元的回调函数 - const handleUnitSelect = useCallback( - (unit: SelectedUnit) => { - if (selectedUnit?.id === unit.id) return; // 避免重复选择 - - setSelectedUnit(unit); - // 刷新房屋列表 - actionHousesRef?.current?.reload(); - }, - [selectedUnit?.id], - ); - - // 删除操作的通用处理 - const handleDelete = useCallback( - async (deleteApi: any, id: number, reloadAction: any, itemName: string) => { - try { - await deleteApi({ id }); - message.success(`${itemName}删除成功`); - reloadAction(); - - // 如果删除的是当前选中项,清空选择 - if (itemName === '项目' && selectedAsset?.id === id) { - setSelectedAsset(null); - setSelectedBuilding(null); - setSelectedUnit(null); - } else if (itemName === '楼栋' && selectedBuilding?.id === id) { - setSelectedBuilding(null); - setSelectedUnit(null); - } else if (itemName === '单元' && selectedUnit?.id === id) { - setSelectedUnit(null); - } - } catch (error) { - message.error(`${itemName}删除失败`); - console.error(`删除${itemName}失败:`, error); - } - }, - [selectedAsset?.id, selectedBuilding?.id, selectedUnit?.id], - ); - - // 通用表格配置 - const getTableConfig = useMemo( - () => ({ - ...MyProTableProps.props, - search: false as const, - size: 'middle' as const, - options: false as const, - pagination: { - pageSize: 10, - showSizeChanger: false, - }, - }), - [], - ); - - // 项目表格列配置 - const projectColumns = useMemo( - () => [ - { - title: '项目', - dataIndex: 'name', - ellipsis: true, - search: { - transform: (value: string) => ({ name: value }), - }, - }, - MyColumns.Option({ - width: 120, - render: (_, item: any, index, action) => ( - - { - navigate(`/asset/list/show/${item.id}`); - }} - /> - - ), - }), - ], - [handleDelete], - ); - - // 楼栋表格列配置 - const buildingColumns = useMemo( - () => [ - { - title: '楼栋', - dataIndex: 'name', - ellipsis: true, - }, - MyColumns.Option({ - width: 120, - render: (_, item: any, index, action) => ( - - - {/* - handleDelete( - Apis.Asset.AssetBuildings.Delete, - item.id, - action?.reload, - '楼栋', - ) - } - /> */} - - ), - }), - ], - [handleDelete], - ); - - // 单元表格列配置 - const unitColumns = useMemo( - () => [ - { - title: '单元', - dataIndex: 'name', - ellipsis: true, - }, - MyColumns.Option({ - width: 120, - render: (_, item: any, index, action) => ( - - - {/* - handleDelete( - Apis.Asset.AssetUnits.Delete, - item.id, - action?.reload, - '单元', - ) - } - /> */} - - ), - }), - ], - [handleDelete], - ); - - // 房屋表格列配置 - const houseColumns = useMemo( - () => [ - MyColumns.EnumTag({ - title: '用途', - dataIndex: 'usage', - valueEnum: AssetHousesUsageEnum, - }), - { - title: '房屋名称', - dataIndex: 'full_name', - }, - { - title: '楼层', - dataIndex: 'floor', - render(_, record) { - return `${record?.floor}层`; - }, - }, - { - title: '房号', - dataIndex: 'name', - }, - { - title: '计费面积', - dataIndex: 'chargeable_area', - render(_, record) { - return `${ - record?.chargeable_area ? record?.chargeable_area + ' m²' : '-' - } `; - }, - }, - - MyColumns.EnumTag({ - title: '房屋属性', - dataIndex: 'ownership_type', - valueEnum: AssetHousesOwnershipTypeEnum, - }), - MyColumns.Option({ - width: 120, - render: (_, item: any, index, action) => ( - - - {/* - handleDelete( - Apis.Asset.AssetHouses.Delete, - item.id, - action?.reload, - '房屋', - ) - } - /> */} - - ), - }), - ], - [handleDelete], - ); - return ( - - } - > - -
- - <Space - style={{ display: 'flex', justifyContent: 'space-between' }} - > - 项目信息 + <ProTable + {...MyProTableProps.props} + request={async (params, sort) => { + setParams(params); + return MyProTableProps.request( + params, + sort, + Apis.Asset.AssetHouses.List, + ); + }} + toolBarRender={() => [ + <MyExport + key="export" + item={getParams} + download={Apis.Asset.AssetHouses} + />, + ]} + columns={[ + MyColumns.ID(), + { + title: '项目名称', + dataIndex: ['asset_project', 'name'], + search: { + transform: (value) => { + return { project_name: value }; + }, + }, + }, + { + title: '房屋名称', + dataIndex: 'full_name', + }, + + MyColumns.EnumTag({ + title: '用途', + dataIndex: 'usage', + valueEnum: AssetHousesUsageEnum, + }), + { + title: '楼层', + dataIndex: 'floor', + render(_, record) { + return `${record?.floor}层`; + }, + search: false, + }, + + { + title: '建筑面积', + dataIndex: 'built_area', + render(_, record) { + return `${ + record?.built_area ? record?.built_area + ' m²' : '-' + } `; + }, + search: false, + }, + { + title: '套内面积', + dataIndex: 'inside_area', + render(_, record) { + return `${ + record?.inside_area ? record?.inside_area + ' m²' : '-' + } `; + }, + search: false, + }, + { + title: '计费面积', + dataIndex: 'chargeable_area', + render(_, record) { + return `${ + record?.chargeable_area ? record?.chargeable_area + ' m²' : '-' + } `; + }, + search: false, + }, + { + title: '户型', + render(_, record) { + return `${record?.room || 'x'}室${record?.hall || 'x'}厅${ + record?.bathroom || 'x' + }卫${record?.kitchen || 'x'}厨${record?.balcony || 'x'}阳台`; + }, + search: false, + }, + // MyColumns.EnumTag({ + // title: '朝向', + // dataIndex: 'orientation', + // valueEnum: AssetHousesOrientationEnum, + // search: false, + // }), + // MyColumns.EnumTag({ + // title: '房屋状态', + // dataIndex: 'status', + // valueEnum: AssetHousesStatusEnum, + // search: false, + // }), + MyColumns.EnumTag({ + title: '房屋属性', + dataIndex: 'ownership_type', + valueEnum: AssetHousesOwnershipTypeEnum, + search: false, + }), + + // { + // title: '产权年限', + // dataIndex: 'ownership_term', + // render(_, record) { + // return `${record?.ownership_term || '-'} 年`; + // }, + // search: false, + // }, + MyColumns.Option({ + render: (_, item: any, index, action) => ( + <Space key={index}> + <HousesShow item={item} reload={action?.reload} /> + <HousesUpdate + item={item} + reload={action?.reload} + title="编辑" + /> + <MyButtons.Delete + onConfirm={() => + Apis.Asset.AssetHouses.Delete({ + id: item.id, + }).then(() => action?.reload()) + } + /> </Space> - - { - return selectedAsset?.id === record?.id - ? 'ant-table-row-selected' - : ''; - }} - onRow={(record: any) => { - return { - onClick: () => { - handleAssetSelect(record); - }, - style: { - cursor: 'pointer', - }, - }; - }} - request={async (params, sort) => - MyProTableProps.request( - { ...params }, - sort, - Apis.Asset.AssetProjects.List, - ) - } - columns={projectColumns} - /> -
- - {/* 楼栋列表 */} - {selectedAsset ? ( -
- - <Space - style={{ display: 'flex', justifyContent: 'space-between' }} - > - <span>{selectedAsset?.name}</span> - <BuildingsCreate - key="BuildingsCreate" - item={{ ...selectedAsset, size: 'small' }} - reload={() => actionBuildingsRef?.current?.reload()} - title="楼栋" - /> - </Space> - - { - return selectedBuilding?.id === record?.id - ? 'ant-table-row-selected' - : ''; - }} - onRow={(record: any) => { - return { - onClick: () => { - handleBuildingSelect(record); - }, - style: { - cursor: 'pointer', - }, - }; - }} - request={async (params, sort) => - MyProTableProps.request( - { ...params, asset_projects_id: selectedAsset?.id }, - sort, - Apis.Asset.AssetBuildings.List, - ) - } - columns={buildingColumns} - /> -
- ) : ( -
- 请先选择项目 -
- )} - {/* 单元列表 */} - {selectedBuilding ? ( -
- - <Space - style={{ display: 'flex', justifyContent: 'space-between' }} - > - <span>{selectedBuilding.name}</span> - <UnitsCreate - key="UnitsCreate" - item={{ - ...selectedBuilding, - asset_buildings_id: selectedBuilding?.id, - size: 'small', - }} - reload={() => actionUnitsRef?.current?.reload()} - title="单元" - /> - </Space> - - - MyProTableProps.request( - { - ...params, - asset_projects_id: selectedAsset?.id, - asset_buildings_id: selectedBuilding?.id, - }, - sort, - Apis.Asset.AssetUnits.List, - ) - } - rowClassName={(record: any) => { - return selectedUnit?.id === record?.id - ? 'ant-table-row-selected' - : ''; - }} - onRow={(record: any) => { - return { - onClick: () => { - handleUnitSelect(record); - }, - style: { - cursor: 'pointer', - }, - }; - }} - columns={unitColumns} - /> -
- ) : ( -
- 请先选择楼栋 -
- )} - - {/* 房屋列表 */} - {selectedUnit ? ( -
- - <Space - style={{ display: 'flex', justifyContent: 'space-between' }} - > - <span>{selectedUnit.name}</span> - <HousesCreate - key="HousesCreate" - item={{ - ...selectedUnit, - asset_projects_id: selectedAsset?.id, - asset_buildings_id: selectedBuilding?.id, - asset_units_id: selectedUnit?.id, - size: 'small', - }} - reload={() => actionHousesRef?.current?.reload()} - title="房屋" - /> - </Space> - - - MyProTableProps.request( - { - ...params, - asset_projects_id: selectedAsset?.id, - asset_buildings_id: selectedBuilding?.id, - asset_units_id: selectedUnit?.id, - }, - sort, - Apis.Asset.AssetHouses.List, - ) - } - columns={houseColumns} - /> -
- ) : ( -
- {selectedBuilding ? '请先选择单元' : '请先选择楼栋'} -
- )} -
-
+ ), + }), + ]} + />
); } diff --git a/src/pages/asset/list/table/AssetBuildings.tsx b/src/pages/asset/list/table/AssetBuildings.tsx index 8e17e08..b0e31c2 100644 --- a/src/pages/asset/list/table/AssetBuildings.tsx +++ b/src/pages/asset/list/table/AssetBuildings.tsx @@ -13,12 +13,12 @@ import { import { ProCard, ProTable } from '@ant-design/pro-components'; import { Alert, message, Space, Typography } from 'antd'; import { useCallback, useRef, useState } from 'react'; -import BuildingsCreate from '../../houses/modals/BuildingsCreate'; -import AssetBuildingsUpdate from '../../houses/modals/BuildingsUpdate'; -import HousesCreate from '../../houses/modals/HousesCreate'; -import HousesUpdate from '../../houses/modals/HousesUpdate'; -import AssetUnitsCreate from '../../houses/modals/UnitsCreate'; -import AssetUnitsUpdate from '../../houses/modals/UnitsUpdate'; +import BuildingsCreate from '../../dictionary/modals/BuildingsCreate'; +import AssetBuildingsUpdate from '../../dictionary/modals/BuildingsUpdate'; +import HousesCreate from '../../dictionary/modals/HousesCreate'; +import HousesUpdate from '../../dictionary/modals/HousesUpdate'; +import AssetUnitsCreate from '../../dictionary/modals/UnitsCreate'; +import AssetUnitsUpdate from '../../dictionary/modals/UnitsUpdate'; const { Title } = Typography; diff --git a/src/pages/asset_houses/index.tsx b/src/pages/asset_houses/index.tsx deleted file mode 100644 index 0d4422d..0000000 --- a/src/pages/asset_houses/index.tsx +++ /dev/null @@ -1,168 +0,0 @@ -import { - MyButtons, - MyColumns, - MyPageContainer, - MyProTableProps, - usePageTabs, -} from '@/common'; -import { MyExport } from '@/components/MyExport'; -import { Apis } from '@/gen/Apis'; -import { - AssetHousesOwnershipTypeEnum, - AssetHousesUsageEnum, -} from '@/gen/Enums'; -import { ProTable } from '@ant-design/pro-components'; -import { useNavigate } from '@umijs/max'; -import { Space } from 'antd'; -import { useState } from 'react'; -import HousesShow from '../asset/houses/modals/HousesShow'; -import HousesUpdate from '../asset/houses/modals/HousesUpdate'; - -export default function Index({ title = '房屋列表' }) { - const [getParams, setParams] = useState({}); - - const navigate = useNavigate(); - // 注册当前页面为标签页 - usePageTabs({ - tabKey: 'asset-houses', - tabLabel: title, - }); - return ( - - { - setParams(params); - return MyProTableProps.request( - params, - sort, - Apis.Asset.AssetHouses.List, - ); - }} - toolBarRender={() => [ - , - ]} - columns={[ - MyColumns.ID(), - { - title: '项目名称', - dataIndex: ['asset_project', 'name'], - search: { - transform: (value) => { - return { project_name: value }; - }, - }, - }, - { - title: '房屋名称', - dataIndex: 'full_name', - }, - - MyColumns.EnumTag({ - title: '用途', - dataIndex: 'usage', - valueEnum: AssetHousesUsageEnum, - }), - { - title: '楼层', - dataIndex: 'floor', - render(_, record) { - return `${record?.floor}层`; - }, - search: false, - }, - - { - title: '建筑面积', - dataIndex: 'built_area', - render(_, record) { - return `${ - record?.built_area ? record?.built_area + ' m²' : '-' - } `; - }, - search: false, - }, - { - title: '套内面积', - dataIndex: 'inside_area', - render(_, record) { - return `${ - record?.inside_area ? record?.inside_area + ' m²' : '-' - } `; - }, - search: false, - }, - { - title: '计费面积', - dataIndex: 'chargeable_area', - render(_, record) { - return `${ - record?.chargeable_area ? record?.chargeable_area + ' m²' : '-' - } `; - }, - search: false, - }, - { - title: '户型', - render(_, record) { - return `${record?.room || 'x'}室${record?.hall || 'x'}厅${ - record?.bathroom || 'x' - }卫${record?.kitchen || 'x'}厨${record?.balcony || 'x'}阳台`; - }, - search: false, - }, - // MyColumns.EnumTag({ - // title: '朝向', - // dataIndex: 'orientation', - // valueEnum: AssetHousesOrientationEnum, - // search: false, - // }), - // MyColumns.EnumTag({ - // title: '房屋状态', - // dataIndex: 'status', - // valueEnum: AssetHousesStatusEnum, - // search: false, - // }), - MyColumns.EnumTag({ - title: '房屋属性', - dataIndex: 'ownership_type', - valueEnum: AssetHousesOwnershipTypeEnum, - search: false, - }), - - // { - // title: '产权年限', - // dataIndex: 'ownership_term', - // render(_, record) { - // return `${record?.ownership_term || '-'} 年`; - // }, - // search: false, - // }, - MyColumns.Option({ - render: (_, item: any, index, action) => ( - - - - - Apis.Asset.AssetHouses.Delete({ - id: item.id, - }).then(() => action?.reload()) - } - /> - - ), - }), - ]} - /> - - ); -} diff --git a/src/pages/asset_houses_bill/index.tsx b/src/pages/asset_houses_bill/index.tsx index 87572f8..9b4c9d3 100644 --- a/src/pages/asset_houses_bill/index.tsx +++ b/src/pages/asset_houses_bill/index.tsx @@ -12,8 +12,8 @@ import { ProTable } from '@ant-design/pro-components'; import { useNavigate } from '@umijs/max'; import { Space } from 'antd'; import { useState } from 'react'; -import HousesShow from '../asset/houses/modals/HousesShow'; -import HousesUpdate from '../asset/houses/modals/HousesUpdate'; +import HousesShow from '../asset/dictionary/modals/HousesShow'; +import HousesUpdate from '../asset/dictionary/modals/HousesUpdate'; export default function Index({ title = '房屋列表' }) { const [getParams, setParams] = useState({}); diff --git a/src/pages/bills/index.tsx b/src/pages/bills/list/index.tsx similarity index 96% rename from src/pages/bills/index.tsx rename to src/pages/bills/list/index.tsx index f8554c1..06f5bce 100644 --- a/src/pages/bills/index.tsx +++ b/src/pages/bills/list/index.tsx @@ -13,10 +13,10 @@ import { Space } from 'antd'; import BillCreate from './modals/BillCreate'; import BillUpdate from './modals/BillUpdate'; -export default function Index({ title = '房屋账单' }) { +export default function Index({ title = '账单明细' }) { // 注册当前页面为标签页 usePageTabs({ - tabKey: 'bills', + tabKey: 'housebills', tabLabel: title, }); @@ -24,7 +24,7 @@ export default function Index({ title = '房屋账单' }) { + + MyProTableProps.request( + params, + sort, + Apis.Bill.HouseBills.SummaryBillList, + ) + } + // toolBarRender={(action) => [ + // , + // , + // ]} + columns={[ + { + title: '房屋ID', + dataIndex: 'asset_houses_id', + }, + { + title: '房屋', + dataIndex: ['asset_house', 'full_name'], + search: { + transform: (value) => { + return { full_name: value }; + }, + }, + }, + { + title: '账单金额合计', + dataIndex: 'payable_amount_sum', + search: false, + }, + { + title: '滞纳金合计', + dataIndex: 'late_fee_sum', + search: false, + }, + { + title: '优惠金额合计', + dataIndex: 'discount_amount_sum', + search: false, + }, + { + title: '应付合计', + dataIndex: 'total_payable_sum', + search: false, + }, + MyColumns.Option({ + render: (_, item: any, index, action) => ( + + + + ), + }), + ]} + /> + + ); +} diff --git a/src/pages/bills/summary/modals/SummaryShow.tsx b/src/pages/bills/summary/modals/SummaryShow.tsx new file mode 100644 index 0000000..7d00e9f --- /dev/null +++ b/src/pages/bills/summary/modals/SummaryShow.tsx @@ -0,0 +1,100 @@ +import { MyBetaModalFormProps, MyColumns, MyProTableProps } from '@/common'; +import { MyModal } from '@/components/MyModal'; +import { Apis } from '@/gen/Apis'; +import { HouseBillsTypeEnum } from '@/gen/Enums'; +import { ProTable } from '@ant-design/pro-components'; +import { Space } from 'antd'; +import BillUpdate from '../../list/modals/BillUpdate'; + +export default function SummaryShow(props: MyBetaModalFormProps) { + return ( + + MyProTableProps.request( + { ...params, asset_houses_id: props?.item?.asset_houses_id }, + sort, + Apis.Bill.HouseBills.List, + ) + } + columns={[ + MyColumns.ID(), + MyColumns.EnumTag({ + title: '类型', + dataIndex: 'type', + valueEnum: HouseBillsTypeEnum, + }), + { + title: '房屋', + dataIndex: ['asset_house', 'full_name'], + search: { + transform: (value) => { + return { full_name: value }; + }, + }, + }, + { + title: '账单月份', + render: (_, record) => { + return `${record.year}-${String(record.month).padStart( + 2, + '0', + )}`; + }, + }, + { + title: '账单金额', + dataIndex: 'amount', + search: false, + }, + { + title: '优惠金额', + dataIndex: 'discount_amount', + search: false, + }, + { + title: '滞纳金', + dataIndex: 'late_fee', + search: false, + }, + + { + title: '计费开始日期', + dataIndex: 'start_date', + search: false, + }, + { + title: '计费结束日期', + dataIndex: 'end_date', + search: false, + }, + MyColumns.CreatedAt(), + MyColumns.Option({ + render: (_, item: any, index, action) => ( + + + {/* + Apis.Bill.HouseBills.Delete({ id: item.id }).then(() => + action?.reload(), + ) + } + /> */} + + ), + }), + ]} + /> + } + /> + ); +} diff --git a/src/pages/company/accounts/modals/ReceiptAccountUpdate.tsx b/src/pages/company/accounts/modals/ReceiptAccountUpdate.tsx index 6b5569e..8ea1609 100644 --- a/src/pages/company/accounts/modals/ReceiptAccountUpdate.tsx +++ b/src/pages/company/accounts/modals/ReceiptAccountUpdate.tsx @@ -5,7 +5,6 @@ import { MyModalFormProps, rulesHelper, } from '@/common'; - import { Apis } from '@/gen/Apis'; import { CompanyReceiptAccountsPayChannelEnum } from '@/gen/Enums'; import { BetaSchemaForm } from '@ant-design/pro-components'; diff --git a/src/pages/house_charge_tasks copy/index.tsx b/src/pages/house_charge_tasks copy/index.tsx deleted file mode 100644 index 8e481db..0000000 --- a/src/pages/house_charge_tasks copy/index.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import { - MyButtons, - MyColumns, - MyPageContainer, - MyProTableProps, - usePageTabs, -} from '@/common'; -import { Apis } from '@/gen/Apis'; -import { HouseChargeTaskDetailsStatusEnum } from '@/gen/Enums'; -import { ProTable } from '@ant-design/pro-components'; -import { Space } from 'antd'; -import ChargeTasksCreate from './modals/ChargeTasksCreate'; - -export default function Index({ title = '账单任务' }) { - // 注册当前页面为标签页 - usePageTabs({ - tabKey: 'house_charge_tasks', - tabLabel: title, - }); - - return ( - - - MyProTableProps.request( - params, - sort, - Apis.HouseCharage.HouseChargeTasks.List, - ) - } - toolBarRender={(action) => [ - , - ]} - columns={[ - { - title: '任务ID', - dataIndex: 'house_charge_tasks_id', - search: false, - }, - MyColumns.EnumTag({ - title: '任务状态', - dataIndex: 'status', - valueEnum: HouseChargeTaskDetailsStatusEnum, - }), - { - title: '账单ID', - dataIndex: 'id', - search: false, - }, - { - title: '关联对象', - dataIndex: 'full_name', - search: false, - }, - { - title: '账单月份', - render: (_, record) => { - return `${record.year}-${String(record.month).padStart(2, '0')}`; - }, - }, - { - title: '计费开始日期', - dataIndex: ['house_charge_task', 'start_date'], - search: false, - }, - { - title: '计费结束日期', - dataIndex: ['house_charge_task', 'end_date'], - search: false, - }, - // MyColumns.UpdatedAt(), - MyColumns.CreatedAt(), - MyColumns.Option({ - render: (_, item: any, index, action) => ( - - - Apis.HouseCharage.HouseChargeTaskDetails.Delete({ - id: item.id, - }).then(() => action?.reload()) - } - /> - - ), - }), - ]} - /> - - ); -} diff --git a/src/pages/house_charge_tasks copy/modals/ChargeTasksCreate.tsx b/src/pages/house_charge_tasks copy/modals/ChargeTasksCreate.tsx deleted file mode 100644 index 7f45601..0000000 --- a/src/pages/house_charge_tasks copy/modals/ChargeTasksCreate.tsx +++ /dev/null @@ -1,116 +0,0 @@ -import { - MyBetaModalFormProps, - MyButtons, - MyModalFormProps, - rulesHelper, -} from '@/common'; -import { Selects } from '@/components/Select'; -import { Apis } from '@/gen/Apis'; -import { BetaSchemaForm } from '@ant-design/pro-components'; -import { Form, message } from 'antd'; - -export default function Create(props: MyBetaModalFormProps) { - const [form] = Form.useForm(); - return ( - - {...MyModalFormProps.props} - title={`创建${props.title}`} - width="480px" - layout="horizontal" - labelCol={{ span: 8 }} - wrapperCol={{ span: 16 }} - labelAlign="left" - trigger={} - key={new Date().getTime()} - form={form} - onOpenChange={(open: any) => { - if (open) { - form.resetFields(); // 清空表单数据 - } - }} - onFinish={async (values) => - Apis.HouseCharage.HouseChargeTasks.Store(values) - .then(() => { - props.reload?.(); - message.success(props.title + '账单任务创建成功'); - return true; - }) - .catch(() => false) - } - columns={[ - Selects?.AssetProjects({ - title: '选择项目', - key: 'asset_projects_id', - colProps: { span: 24 }, - formItemProps: { ...rulesHelper.text }, - fieldProps: { - onChange: (val: any) => { - form.setFieldsValue({ - house_charge_standards_id: undefined, - }); - }, - }, - }), - { - valueType: 'dependency', - name: ['asset_projects_id'], - columns: ({ asset_projects_id }) => { - return [ - Selects?.ChargeStandard({ - title: '选择收费标准', - key: 'house_charge_standards_id', - params: { - asset_projects_id: asset_projects_id, - }, - colProps: { span: 24 }, - formItemProps: { ...rulesHelper.text }, - fieldProps: { - showSearch: true, - }, - }), - ]; - }, - }, - { - key: 'month', - title: '选择生成月份', - valueType: 'date', - colProps: { span: 24 }, - fieldProps: { - picker: 'month', - format: 'YYYY-MM', - valueFormat: 'YYYY-MM', - style: { - width: '100%', - }, - }, - formItemProps: { ...rulesHelper.text }, - }, - { - key: 'start_date', - title: '计费开始日期', - valueType: 'date', - colProps: { span: 24 }, - fieldProps: { - style: { - width: '100%', - }, - }, - formItemProps: { ...rulesHelper.text }, - }, - { - key: 'end_date', - title: '计费结束日期', - valueType: 'date', - colProps: { span: 24 }, - fieldProps: { - style: { - width: '100%', - }, - }, - formItemProps: { ...rulesHelper.text }, - }, - ]} - /> - ); -} diff --git a/src/pages/mete/list/index.tsx b/src/pages/mete/list/index.tsx new file mode 100644 index 0000000..d55c764 --- /dev/null +++ b/src/pages/mete/list/index.tsx @@ -0,0 +1,140 @@ +import { + MyButtons, + MyColumns, + MyPageContainer, + MyProTableProps, + usePageTabs, +} from '@/common'; +import { Apis } from '@/gen/Apis'; +import { ProTable } from '@ant-design/pro-components'; +import { useNavigate } from '@umijs/max'; +import { Space } from 'antd'; + +import { + HouseMetersMeterTypeEnum, + HouseMetersUsageTypeEnum, +} from '@/gen/Enums'; +import CompanyCreate from './modals/MeterCreate'; +import MeterHasHouse from './modals/MeterHasHouse'; +import MeterHasOne from './modals/MeterHasOne'; +import CompanyUpdate from './modals/MeterUpdate'; + +export default function Index({ title = '仪表管理' }) { + const navigate = useNavigate(); + + // 注册当前页面为标签页 + usePageTabs({ + tabKey: 'house_meters', + tabLabel: title, + }); + + return ( + + + MyProTableProps.request(params, sort, Apis.Meter.HouseMeters.List) + } + toolBarRender={(action) => [ + , + ]} + columns={[ + MyColumns.ID(), + MyColumns.EnumTag({ + title: '类型', + dataIndex: 'meter_type', + valueEnum: HouseMetersMeterTypeEnum, + search: false, + }), + MyColumns.EnumTag({ + title: '使用类型', + dataIndex: 'usage_type', + valueEnum: HouseMetersUsageTypeEnum, + search: false, + }), + { + title: '仪表名称', + dataIndex: 'name', + }, + { + title: '收费标准', + dataIndex: ['charge_standard', 'name'], + search: false, + }, + { + title: '初始抄表读数', + dataIndex: 'initial_value', + search: false, + }, + { + title: '最新抄表读数', + dataIndex: 'latest_value', + search: false, + }, + { + title: '初始抄表时间', + dataIndex: 'initial_time', + search: false, + }, + { + title: '最新抄表时间', + dataIndex: 'latest_time', + search: false, + }, + { + title: '备注', + dataIndex: 'remark', + search: false, + }, + + MyColumns.SoftDelete({ + onRestore: Apis.Company.Companies.Restore, + onSoftDelete: Apis.Company.Companies.SoftDelete, + search: false, + }), + MyColumns.CreatedAt(), + MyColumns.Option({ + render: (_, item: any, index, action) => ( + + {/* */} + + {item.meter_type === + HouseMetersMeterTypeEnum.HouseMeter.value && ( + + )} + {item.meter_type === + HouseMetersMeterTypeEnum.CommonMeter.value && ( + + )} + + Apis.Company.Companies.Delete({ id: item.id }).then(() => + action?.reload(), + ) + } + /> + + ), + }), + ]} + /> + + ); +} diff --git a/src/pages/mete/list/modals/MeterCreate.tsx b/src/pages/mete/list/modals/MeterCreate.tsx new file mode 100644 index 0000000..edf4ef3 --- /dev/null +++ b/src/pages/mete/list/modals/MeterCreate.tsx @@ -0,0 +1,127 @@ +import { + MyBetaModalFormProps, + MyButtons, + MyFormItems, + MyModalFormProps, + rulesHelper, +} from '@/common'; +import { Selects } from '@/components/Select'; +import { Apis } from '@/gen/Apis'; +import { + HouseMetersMeterTypeEnum, + HouseMetersUsageTypeEnum, +} from '@/gen/Enums'; +import { BetaSchemaForm } from '@ant-design/pro-components'; +import { Form, message } from 'antd'; + +export default function Create(props: MyBetaModalFormProps) { + const [form] = Form.useForm(); + + return ( + + {...MyModalFormProps.props} + title={`添加仪表`} + layout="horizontal" + labelCol={{ span: 6 }} + wrapperCol={{ span: 18 }} + labelAlign="left" + width="600px" + key={new Date().getTime()} + trigger={} + form={form} + onOpenChange={(open: any) => { + if (open) { + form.resetFields(); // 清空表单数据 + } + }} + onFinish={async (values) => + Apis.Meter.HouseMeters.Store({ + ...values, + }) + .then(() => { + props.reload?.(); + message.success(props.title + '成功'); + return true; + }) + .catch(() => false) + } + columns={[ + ...(props?.item?.id + ? [] + : [ + Selects?.AssetProjects({ + key: 'asset_projects_id', + title: '选择项目', + colProps: { span: 24 }, + required: true, + }), + ]), + + MyFormItems.EnumRadio({ + key: 'meter_type', + title: '仪表类型', + colProps: { span: 24 }, + valueEnum: HouseMetersMeterTypeEnum, + required: true, + }), + MyFormItems.EnumRadio({ + key: 'usage_type', + title: '使用类型', + colProps: { span: 24 }, + valueEnum: HouseMetersUsageTypeEnum, + required: true, + }), + { + key: 'name', + title: '仪表名称', + colProps: { span: 24 }, + formItemProps: { ...rulesHelper.text }, + }, + { + key: 'multiple', + title: '倍率', + colProps: { span: 24 }, + formItemProps: { ...rulesHelper.text }, + }, + { + key: 'initial_value', + title: '初始抄表读数', + valueType: 'number', + colProps: { span: 24 }, + formItemProps: { ...rulesHelper.number }, + }, + { + key: 'initial_time', + title: '初始抄表时间', + valueType: 'date', + colProps: { span: 24 }, + formItemProps: { ...rulesHelper.text }, + }, + + { + valueType: 'dependency', + name: ['asset_projects_id'], + columns: ({ asset_projects_id }) => { + return [ + Selects?.ChargeStandard({ + title: '选择收费标准', + key: 'charge_standards_id', + params: { + asset_projects_id: asset_projects_id || props?.item?.id || 0, + }, + colProps: { span: 24 }, + formItemProps: { ...rulesHelper.text }, + }), + ]; + }, + }, + { + key: 'remark', + title: '备注', + valueType: 'textarea', + colProps: { span: 24 }, + }, + ]} + /> + ); +} diff --git a/src/pages/mete/list/modals/MeterHasHouse.tsx b/src/pages/mete/list/modals/MeterHasHouse.tsx new file mode 100644 index 0000000..e7d52ca --- /dev/null +++ b/src/pages/mete/list/modals/MeterHasHouse.tsx @@ -0,0 +1,215 @@ +import { + MyBetaModalFormProps, + MyButtons, + MyColumns, + MyProTableProps, +} from '@/common'; +import { MyModal } from '@/components/MyModal'; + +import { Apis } from '@/gen/Apis'; +import { + AssetHousesOwnershipTypeEnum, + AssetHousesUsageEnum, +} from '@/gen/Enums'; +import { ProTable } from '@ant-design/pro-components'; +import { message, Space } from 'antd'; +import { useRef, useState } from 'react'; + +export default function ChargeStandardHasHouse(props: MyBetaModalFormProps) { + // 使用 useState 保存选中的房屋 ID 和行数据,确保跨页选中状态保持 + const [selectedHousesIds, setSelectedHousesIds] = useState([]); + const [selectedRows, setSelectedRows] = useState([]); + + // 添加 tableRef 用于操作表格 + const tableRef = useRef(); + + const onShowContactPhone = () => { + if (selectedHousesIds.length === 0) { + message.warning('请至少选择一个房屋'); + return; + } + + // 确保 houses_ids 是字符串数组 + const housesIds = selectedHousesIds.map((id) => String(id)); + + Apis.Meter.HouseMeterHasHouses.StoreOrUpdate({ + house_meters_id: props?.item?.id ?? 0, + asset_houses_ids: housesIds, + }) + .then(() => { + // 成功后重置选中状态 + setSelectedHousesIds([]); + setSelectedRows([]); + props.reload?.(); + message.success('添加成功!'); + }) + .catch((error) => { + console.error('添加失败:', error); + message.error('添加失败: ' + (error.message || '未知错误')); + return false; + }); + }; + + return ( + + MyProTableProps.request( + { + ...params, + asset_projects_id: props?.item?.asset_projects_id, + }, + sort, + Apis.Asset.AssetHouses.List, + undefined, + (res) => { + // 确保响应数据正确处理 + console.log('加载房屋数据:', res); + return res; + }, + ) + } + style={{ height: '800px', overflowY: 'auto', overflowX: 'hidden' }} + pagination={{ + showQuickJumper: true, + pageSizeOptions: [10, 20, 50, 100, 200, 500, 1000, 2000], + }} + rowSelection={{ + type: 'checkbox', + preserveSelectedRowKeys: true, // 启用跨页选择 + selectedRowKeys: selectedHousesIds, + onChange: (selectedRowKeys, selectedRows) => { + // 确保 selectedRowKeys 是数字类型 + const numericKeys = selectedRowKeys.map((key) => + typeof key === 'string' ? parseInt(key, 10) : key, + ) as number[]; + + // 更新选中状态 + setSelectedHousesIds(numericKeys); + + // 合并当前页面选中的行和之前选中的行 + const newSelectedRows = [...selectedRows]; + + // 设置选中行数据 + setSelectedRows(newSelectedRows); + }, + }} + tableAlertOptionRender={({ selectedRowKeys, onCleanSelected }) => { + return ( + + 已选 {selectedRowKeys.length} 项 + 清空 + onShowContactPhone()} + /> + + ); + }} + options={false} + columns={[ + MyColumns.ID(), + MyColumns.EnumTag({ + title: '用途', + dataIndex: 'usage', + valueEnum: AssetHousesUsageEnum, + search: false, + }), + { + title: '项目名称', + dataIndex: ['asset_project', 'name'], + search: false, + }, + { + title: '楼栋名称', + dataIndex: ['asset_building', 'name'], + search: { + transform: (value) => { + return { building_name: value }; + }, + }, + }, + { + title: '单元名称', + dataIndex: ['asset_unit', 'name'], + search: { + transform: (value) => { + return { unit_name: value }; + }, + }, + }, + { + title: '房号', + dataIndex: 'name', + }, + + { + title: '楼层', + dataIndex: 'floor', + render(_, record) { + return `${record?.floor}层`; + }, + search: false, + }, + + { + title: '建筑面积', + dataIndex: 'built_area', + render(_, record) { + return `${ + record?.built_area ? record?.built_area + ' m²' : '-' + } `; + }, + search: false, + }, + { + title: '套内面积', + dataIndex: 'inside_area', + render(_, record) { + return `${ + record?.inside_area ? record?.inside_area + ' m²' : '-' + } `; + }, + search: false, + }, + { + title: '计费面积', + dataIndex: 'chargeable_area', + render(_, record) { + return `${ + record?.chargeable_area + ? record?.chargeable_area + ' m²' + : '-' + } `; + }, + search: false, + }, + // { + // title: '户型', + // render(_, record) { + // return `${record?.room || 'x'}室${record?.hall || 'x'}厅${ + // record?.bathroom || 'x' + // }卫${record?.kitchen || 'x'}厨${record?.balcony || 'x'}阳台`; + // }, + // search: false, + // }, + MyColumns.EnumTag({ + title: '产权性质', + dataIndex: 'ownership_type', + valueEnum: AssetHousesOwnershipTypeEnum, + search: false, + }), + ]} + /> + } + /> + ); +} diff --git a/src/pages/mete/list/modals/MeterHasOne.tsx b/src/pages/mete/list/modals/MeterHasOne.tsx new file mode 100644 index 0000000..0528a9c --- /dev/null +++ b/src/pages/mete/list/modals/MeterHasOne.tsx @@ -0,0 +1,213 @@ +import { + MyBetaModalFormProps, + MyButtons, + MyColumns, + MyProTableProps, +} from '@/common'; +import { MyModal } from '@/components/MyModal'; + +import { Apis } from '@/gen/Apis'; +import { + AssetHousesOwnershipTypeEnum, + AssetHousesUsageEnum, +} from '@/gen/Enums'; +import { ProTable } from '@ant-design/pro-components'; +import { message, Space } from 'antd'; +import { useRef, useState } from 'react'; + +export default function ChargeStandardHasHouse(props: MyBetaModalFormProps) { + // 使用 useState 保存选中的房屋 ID 和行数据,只选择一行 + const [selectedHouseId, setSelectedHouseId] = useState(null); + const [selectedRow, setSelectedRow] = useState(null); + + // 添加 tableRef 用于操作表格 + const tableRef = useRef(); + + const onShowContactPhone = () => { + if (!selectedHouseId) { + message.warning('请选择一个房屋'); + return; + } + + // 确保 houses_ids 是字符串数组 + const housesIds = [String(selectedHouseId)]; + + Apis.Meter.HouseMeterHasHouses.StoreOrUpdate({ + house_meters_id: props?.item?.id ?? 0, + asset_houses_ids: housesIds, + }) + .then(() => { + // 成功后重置选中状态 + setSelectedHouseId(null); + setSelectedRow(null); + props.reload?.(); + message.success('添加成功!'); + }) + .catch((error) => { + console.error('添加失败:', error); + message.error('添加失败: ' + (error.message || '未知错误')); + return false; + }); + }; + + return ( + + MyProTableProps.request( + { + ...params, + asset_projects_id: props?.item?.asset_projects_id, + }, + sort, + Apis.Asset.AssetHouses.List, + undefined, + (res) => { + // 确保响应数据正确处理 + console.log('加载房屋数据:', res); + return res; + }, + ) + } + style={{ height: '800px', overflowY: 'auto', overflowX: 'hidden' }} + pagination={{ + showQuickJumper: true, + pageSizeOptions: [10, 20, 50, 100, 200, 500, 1000, 2000], + }} + rowSelection={{ + type: 'radio', // 改为单选 + selectedRowKeys: selectedHouseId ? [selectedHouseId] : [], + onChange: (selectedRowKeys, selectedRows) => { + // 单选模式下,只取第一个选中的项 + if (selectedRowKeys.length > 0) { + const selectedKey = + typeof selectedRowKeys[0] === 'string' + ? parseInt(selectedRowKeys[0], 10) + : (selectedRowKeys[0] as number); + + setSelectedHouseId(selectedKey); + setSelectedRow(selectedRows[0]); + } else { + setSelectedHouseId(null); + setSelectedRow(null); + } + }, + }} + tableAlertOptionRender={({ selectedRowKeys, onCleanSelected }) => { + return ( + + 已选 {selectedRowKeys.length} 项 + { + onCleanSelected(); + setSelectedHouseId(null); + setSelectedRow(null); + }} + > + 清空 + + onShowContactPhone()} + /> + + ); + }} + options={false} + columns={[ + MyColumns.ID(), + MyColumns.EnumTag({ + title: '用途', + dataIndex: 'usage', + valueEnum: AssetHousesUsageEnum, + search: false, + }), + { + title: '项目名称', + dataIndex: ['asset_project', 'name'], + search: false, + }, + { + title: '楼栋名称', + dataIndex: ['asset_building', 'name'], + search: { + transform: (value) => { + return { building_name: value }; + }, + }, + }, + { + title: '单元名称', + dataIndex: ['asset_unit', 'name'], + search: { + transform: (value) => { + return { unit_name: value }; + }, + }, + }, + { + title: '房号', + dataIndex: 'name', + }, + + { + title: '楼层', + dataIndex: 'floor', + render(_, record) { + return `${record?.floor}层`; + }, + search: false, + }, + + { + title: '建筑面积', + dataIndex: 'built_area', + render(_, record) { + return `${ + record?.built_area ? record?.built_area + ' m²' : '-' + } `; + }, + search: false, + }, + { + title: '套内面积', + dataIndex: 'inside_area', + render(_, record) { + return `${ + record?.inside_area ? record?.inside_area + ' m²' : '-' + } `; + }, + search: false, + }, + { + title: '计费面积', + dataIndex: 'chargeable_area', + render(_, record) { + return `${ + record?.chargeable_area + ? record?.chargeable_area + ' m²' + : '-' + } `; + }, + search: false, + }, + MyColumns.EnumTag({ + title: '产权性质', + dataIndex: 'ownership_type', + valueEnum: AssetHousesOwnershipTypeEnum, + search: false, + }), + ]} + /> + } + /> + ); +} diff --git a/src/pages/mete/list/modals/MeterUpdate.tsx b/src/pages/mete/list/modals/MeterUpdate.tsx new file mode 100644 index 0000000..01df5b3 --- /dev/null +++ b/src/pages/mete/list/modals/MeterUpdate.tsx @@ -0,0 +1,111 @@ +import { + MyBetaModalFormProps, + MyButtons, + MyFormItems, + MyModalFormProps, + rulesHelper, +} from '@/common'; +import { Selects } from '@/components/Select'; +import { Apis } from '@/gen/Apis'; +import { + HouseMetersMeterTypeEnum, + HouseMetersUsageTypeEnum, +} from '@/gen/Enums'; +import { BetaSchemaForm } from '@ant-design/pro-components'; +import { Form, message } from 'antd'; + +export default function Update(props: MyBetaModalFormProps) { + const [form] = Form.useForm(); + return ( + + {...MyModalFormProps.props} + title={`编辑${props.title}`} + trigger={} + layout="horizontal" + labelCol={{ span: 6 }} + wrapperCol={{ span: 18 }} + labelAlign="left" + width="600px" + key={new Date().getTime()} + form={form} + onOpenChange={(open: any) => { + if (open && props.item) { + form.setFieldsValue({ + ...props.item, + asset_projects_id: props.item?.asset_projects_id, + house_charge_standards_id: props.item?.house_charge_standards_id, + }); + } + }} + onFinish={async (values) => + Apis.Meter.HouseMeters.Update({ + ...values, + id: props.item?.id ?? 0, + asset_projects_id: props.item?.asset_projects_id, + }) + .then(() => { + props.reload?.(); + message.success(props.title + '成功'); + return true; + }) + .catch(() => false) + } + columns={[ + MyFormItems.EnumRadio({ + key: 'meter_type', + title: '仪表类型', + colProps: { span: 24 }, + valueEnum: HouseMetersMeterTypeEnum, + required: true, + }), + MyFormItems.EnumRadio({ + key: 'usage_type', + title: '使用类型', + colProps: { span: 24 }, + valueEnum: HouseMetersUsageTypeEnum, + required: true, + }), + { + key: 'name', + title: '仪表名称', + colProps: { span: 24 }, + formItemProps: { ...rulesHelper.text }, + }, + { + key: 'multiple', + title: '倍率', + colProps: { span: 24 }, + formItemProps: { ...rulesHelper.text }, + }, + // { + // key: 'initial_value', + // title: '初始抄表读数', + // colProps: { span: 24 }, + // formItemProps: { ...rulesHelper.text }, + // }, + // { + // key: 'initial_time', + // title: '初始抄表时间', + // valueType: 'date', + // colProps: { span: 24 }, + // formItemProps: { ...rulesHelper.text }, + // }, + Selects?.ChargeStandard({ + title: '选择收费标准', + key: 'charge_standards_id', + params: { + asset_projects_id: props?.item?.asset_projects_id, + }, + colProps: { span: 24 }, + formItemProps: { ...rulesHelper.text }, + }), + { + key: 'remark', + title: '备注', + valueType: 'textarea', + colProps: { span: 24 }, + }, + ]} + /> + ); +} diff --git a/src/pages/mete/readings/index.tsx b/src/pages/mete/readings/index.tsx new file mode 100644 index 0000000..885176e --- /dev/null +++ b/src/pages/mete/readings/index.tsx @@ -0,0 +1,122 @@ +import { + MyButtons, + MyColumns, + MyPageContainer, + MyProTableProps, + usePageTabs, +} from '@/common'; +import { Apis } from '@/gen/Apis'; +import { ProTable } from '@ant-design/pro-components'; +import { useNavigate } from '@umijs/max'; +import { Space } from 'antd'; + +import { + HouseMetersMeterTypeEnum, + HouseMetersUsageTypeEnum, +} from '@/gen/Enums'; +import NormalReading from './modals/NormalReading'; + +export default function Index({ title = '抄表数据' }) { + const navigate = useNavigate(); + + // 注册当前页面为标签页 + usePageTabs({ + tabKey: 'house_meter_readings', + tabLabel: title, + }); + + return ( + + + MyProTableProps.request(params, sort, Apis.Meter.HouseMeters.List) + } + toolBarRender={(action) => [ + // , + ]} + columns={[ + MyColumns.ID(), + MyColumns.EnumTag({ + title: '类型', + dataIndex: 'meter_type', + valueEnum: HouseMetersMeterTypeEnum, + search: false, + }), + MyColumns.EnumTag({ + title: '使用类型', + dataIndex: 'usage_type', + valueEnum: HouseMetersUsageTypeEnum, + search: false, + }), + { + title: '仪表名称', + dataIndex: 'name', + }, + { + title: '收费标准', + dataIndex: ['charge_standard', 'name'], + search: false, + }, + { + title: '初始抄表读数', + dataIndex: 'initial_value', + search: false, + }, + { + title: '最新抄表读数', + dataIndex: 'latest_value', + search: false, + }, + { + title: '初始抄表时间', + dataIndex: 'initial_time', + search: false, + }, + { + title: '最新抄表时间', + dataIndex: 'latest_time', + search: false, + }, + { + title: '备注', + dataIndex: 'remark', + search: false, + }, + + MyColumns.SoftDelete({ + onRestore: Apis.Company.Companies.Restore, + onSoftDelete: Apis.Company.Companies.SoftDelete, + search: false, + }), + MyColumns.CreatedAt(), + MyColumns.Option({ + render: (_, item: any, index, action) => ( + + {/* */} + + + + Apis.Company.Companies.Delete({ id: item.id }).then(() => + action?.reload(), + ) + } + /> + + ), + }), + ]} + /> + + ); +} diff --git a/src/pages/mete/readings/modals/NormalReading.tsx b/src/pages/mete/readings/modals/NormalReading.tsx new file mode 100644 index 0000000..bbdae65 --- /dev/null +++ b/src/pages/mete/readings/modals/NormalReading.tsx @@ -0,0 +1,149 @@ +import { + MyBetaModalFormProps, + MyButtons, + MyModalFormProps, + rulesHelper, +} from '@/common'; +import { Selects } from '@/components/Select'; +import { Apis } from '@/gen/Apis'; +import { HouseMeterReadingsOperationTypeEnum } from '@/gen/Enums'; +import { BetaSchemaForm } from '@ant-design/pro-components'; +import { Form, message } from 'antd'; + +export default function Create(props: MyBetaModalFormProps) { + const [form] = Form.useForm(); + + return ( + + {...MyModalFormProps.props} + title={`添加抄表数据`} + layout="horizontal" + labelCol={{ span: 6 }} + wrapperCol={{ span: 18 }} + labelAlign="left" + width="600px" + key={new Date().getTime()} + trigger={} + form={form} + onOpenChange={(open: any) => { + if (open && props.item) { + form.resetFields(); // 清空表单数据 + form.setFieldsValue({ + ...props.item, + latest_value: + props.item?.latest_value === '0.00' + ? props.item?.initial_value + : props.item?.latest_value, + latest_time: props.item?.latest_time || props.item?.initial_time, + }); + } + }} + onFinish={async (values) => + Apis.Meter.HouseMeterReadings.Store({ + ...values, + operation_type: + HouseMeterReadingsOperationTypeEnum.NormalReading.value, + }) + .then(() => { + props.reload?.(); + message.success(props.title + '成功'); + return true; + }) + .catch(() => false) + } + columns={[ + { + key: 'latest_value', + title: '上次抄表读数', + colProps: { span: 24 }, + fieldProps: { disabled: true }, + }, + { + key: 'latest_time', + title: '上次抄表时间', + valueType: 'date', + colProps: { span: 24 }, + fieldProps: { disabled: true }, + }, + + { + key: 'current_reading', + title: '本次抄表读数', + valueType: 'number', + colProps: { span: 24 }, + formItemProps: { + ...rulesHelper.number, + rules: [ + ...rulesHelper.number.rules, + { + validator: (_, value) => { + const latestValue = form.getFieldValue('latest_value'); + if ( + value && + latestValue && + Number(value) <= Number(latestValue) + ) { + return Promise.reject( + new Error('本次读数必须大于上次抄表读数'), + ); + } + return Promise.resolve(); + }, + }, + ], + }, + }, + { + key: 'reading_time', + title: '本次抄表时间', + valueType: 'date', + colProps: { span: 24 }, + formItemProps: { + ...rulesHelper.text, + rules: [ + ...rulesHelper.text.rules, + { + validator: (_, value) => { + const latestTime = form.getFieldValue('latest_time'); + if (value && latestTime) { + const currentTime = new Date(value); + const lastTime = new Date(latestTime); + if (currentTime <= lastTime) { + return Promise.reject( + new Error('本次抄表时间必须大于上次抄表时间'), + ); + } + } + return Promise.resolve(); + }, + }, + ], + }, + }, + Selects?.Employees({ + key: 'company_employees_id', + title: '抄表人', + params: { + companies_id: props.item?.companies_id, + }, + colProps: { span: 24 }, + required: true, + fieldProps: { + showSearch: true, + fieldNames: { + label: 'label', + value: 'value', + }, + }, + }), + + { + key: 'remark', + title: '备注', + valueType: 'textarea', + colProps: { span: 24 }, + }, + ]} + /> + ); +} diff --git a/src/pages/house_order/index.tsx b/src/pages/order/index.tsx similarity index 75% rename from src/pages/house_order/index.tsx rename to src/pages/order/index.tsx index 480c90f..51cca7e 100644 --- a/src/pages/house_order/index.tsx +++ b/src/pages/order/index.tsx @@ -47,32 +47,31 @@ export default function Index({ title = '支付明细' }) { // , // ]} columns={[ - MyColumns.ID(), + // MyColumns.ID(), + { + title: '订单号', + dataIndex: 'order_code', + search: false, + }, + MyColumns.EnumTag({ + title: '支付方式', + dataIndex: 'payment_method', + valueEnum: HouseOrdersPaymentMethodEnum, + }), MyColumns.EnumTag({ title: '支付状态', dataIndex: 'order_status', valueEnum: HouseOrdersOrderStatusEnum, }), - MyColumns.EnumTag({ - title: '支付渠道', - dataIndex: 'payment_method', - valueEnum: HouseOrdersPaymentMethodEnum, - }), + // { + // title: '支付单号', + // dataIndex: 'payment_no', + // search: false, + // }, { - title: '收款单号', - dataIndex: 'order_code', - search: false, - }, - - { - title: '账单金额', - dataIndex: 'amount', - search: false, - }, - { - title: '优惠金额', - dataIndex: 'discount_amount', + title: '应收金额', + dataIndex: 'actual_paid_amount', search: false, }, { @@ -81,13 +80,26 @@ export default function Index({ title = '支付明细' }) { search: false, }, { - title: '应付金额', - dataIndex: 'total_payable_amount', + title: '退款总金额', + dataIndex: 'refund_amount', search: false, }, { - title: '关联项目', - dataIndex: ['asset_project', 'name'], + title: '实缴金额', + dataIndex: 'actual_paid_amount', + search: false, + }, + { + title: '收款账号', + dataIndex: ['house_order_items', 'receipt_account'], + render: (text, item) => + `${ + item?.receipt_account?.company_bank + } ${item?.receipt_account?.company_account?.slice(-4)}`, + }, + { + title: '支付时间', + dataIndex: 'paid_time', search: false, }, { @@ -95,7 +107,13 @@ export default function Index({ title = '支付明细' }) { dataIndex: ['company', 'name'], search: false, }, - MyColumns.CreatedAt(), + { + title: '关联项目', + dataIndex: ['asset_project', 'name'], + search: false, + }, + + // MyColumns.CreatedAt(), // MyColumns.Option({ // render: (_, item: any, index, action) => ( // diff --git a/src/pages/house_order_payments/index.tsx b/src/pages/order/payments/index.tsx similarity index 100% rename from src/pages/house_order_payments/index.tsx rename to src/pages/order/payments/index.tsx