diff --git a/src/common/components/layout/usePageTabs.ts b/src/common/components/layout/usePageTabs.ts index fc68dfa..07114c2 100644 --- a/src/common/components/layout/usePageTabs.ts +++ b/src/common/components/layout/usePageTabs.ts @@ -16,7 +16,7 @@ export interface UsePageTabsOptions { /** * 页面标签页Hook * 用于简化页面标签页的管理 - * + * * 功能特性: * - 自动添加当前页面为标签页 * - 新标签页默认在当前激活标签页的右边插入 diff --git a/src/components/Select.tsx b/src/components/Select.tsx index ad16268..86188f4 100644 --- a/src/components/Select.tsx +++ b/src/components/Select.tsx @@ -457,4 +457,75 @@ export const Selects = { }, }; }, + + //收费标准 + ChargeStandard(props?: PropsType): ReturnType { + const { + title = '选择收费标准', + key = 'house_charge_standards_id', + required = false, + hideInTable = true, + ...rest + } = props ?? {}; + + return { + title: title, + key: key, + valueType: 'select', + hideInTable: hideInTable, + formItemProps: { ...(required ? rulesHelper.number : {}) }, + request: async (params) => + ( + await Apis.HouseCharage.HouseChargeStandards.Select({ + keywords: params?.KeyWords, + asset_projects_id: params?.asset_projects_id, + ...params, + }) + ).data, + ...rest, + fieldProps: { + showSearch: true, + fieldNames: { + label: 'label', + value: 'value', + }, + ...rest?.fieldProps, + }, + }; + }, + + // 物业品牌 + PropertyBrands(props?: PropsType): ReturnType { + const { + title = '品牌', + key = 'company_property_brands_id', + required = false, + hideInTable = true, + ...rest + } = props ?? {}; + + return { + title: title, + key: key, + valueType: 'select', + hideInTable: hideInTable, + formItemProps: { ...(required ? rulesHelper.number : {}) }, + request: async (params) => + ( + await Apis.Company.CompanyPropertyBrands.Select({ + keywords: params?.KeyWords, + ...params, + }) + ).data, + ...rest, + fieldProps: { + showSearch: true, + fieldNames: { + label: 'label', + value: 'value', + }, + ...rest?.fieldProps, + }, + }; + }, }; diff --git a/src/gen/ApiTypes.d.ts b/src/gen/ApiTypes.d.ts index 2962ef0..acf9f43 100644 --- a/src/gen/ApiTypes.d.ts +++ b/src/gen/ApiTypes.d.ts @@ -34,6 +34,9 @@ declare namespace ApiTypes { "id": number; // id "is_contact": boolean; // 是否是常用联系人 }; + type Import = { + "upload_file"?: mimes:xlsx,xls; // 上传的时候必填文件 + }; } namespace HouseRegisters { type List = { @@ -123,6 +126,9 @@ declare namespace ApiTypes { "name"?: string; // 模糊搜索:名称 "full_name"?: string; // 模糊搜索:全称 "project_name"?: string; // 模糊搜索:项目名称 + "building_name"?: string; // 模糊搜索:楼栋名称 + "unit_name"?: string; // 模糊搜索:单元名称 + "usage"?: string; // 用途,[enum:AssetHousesUsageEnum] }; type Store = { "asset_projects_id": number; // 所属项目id,[ref:asset_projects] @@ -218,6 +224,7 @@ declare namespace ApiTypes { "charge"?: string; // 收费方式,[enum:AssetProjectsChargeEnum] "takeover_date"?: Date; // 接管日期 "closure_date"?: Date; // 封园日期 + "company_property_brands_id"?: string; // 物业品牌id,[ref:company_property_brands] }; type Update = { "id": number; // id @@ -242,11 +249,16 @@ declare namespace ApiTypes { "charge"?: string; // 收费方式,[enum:AssetProjectsChargeEnum] "takeover_date"?: Date; // 接管日期 "closure_date"?: Date; // 封园日期 + "company_property_brands_id"?: string; // 物业品牌id,[ref:company_property_brands] }; type BindCompany = { "projects_id": number; // 项目id "companies_id": number; // 机构id }; + type ChangePropertyBrand = { + "projects_id": number; // 项目id + "company_property_brands_id": number; // 物业品牌id,[ref:company_property_brands] + }; type Show = { "id": number; // id }; @@ -508,12 +520,14 @@ declare namespace ApiTypes { "name"?: string; // 模糊搜索:名称 }; type Store = { + "asset_projects_id": number; // 项目ID "type": string; // 类型,[enum:ConvenienceServicesTypeEnum] "name": string; // 名称 "content": string[]; // 内容 }; type Update = { "id": number; // id + "asset_projects_id": number; // 项目ID "type": string; // 类型,[enum:ConvenienceServicesTypeEnum] "name": string; // 名称 "content": string[]; // 内容 @@ -724,6 +738,35 @@ declare namespace ApiTypes { "projects_id"?: number; // 所属项目id,[ref:asset_projects] }; } + namespace CompanyPropertyBrands { + type List = { + "companies_id"?: number; // 机构id,[ref:companies + "name"?: string; // 模糊搜索:名称 + "company_name"?: string; // 模糊搜索:机构名称 + }; + type Store = { + "companies_id": number; // 机构id,[ref:companies] + "name": string; // 品牌名称 + "logo"?: string[]; // 品牌logo + }; + type Update = { + "id": number; // id + "companies_id": number; // 机构id,[ref:companies] + "name": string; // 品牌名称 + "logo"?: string[]; // 品牌logo + }; + type Show = { + "id": number; // id + }; + type Delete = { + "id": number; // id + }; + type Select = { + "companies_id"?: number; // 机构id,[ref:companies + "name"?: string; // 模糊搜索:名称 + "company_name"?: string; // 模糊搜索:机构名称 + }; + } namespace CompanyReceiptAccounts { type List = { "name"?: string; // 模糊搜索:名称 @@ -945,6 +988,56 @@ declare namespace ApiTypes { type Delete = { "id": number; // id }; + type Select = { + "name"?: string; // 模糊搜索:名称 + "project_name"?: string; // 模糊搜索:项目名称 + "company_name"?: string; // 模糊搜索:机构名称 + "charge_type"?: string; // 收费类型,[enum:HouseBillsTypeEnum] + "asset_projects_id"?: number; // 项目id,[ref:asset_projects] + "companies_id"?: number; // 机构id,[ref:companies] + }; + } + namespace HouseChargeTaskDetails { + type List = { + "house_charge_tasks_id"?: number; // 房屋收费任务id,[ref:house_charge_tasks] + "full_name"?: string; // 模糊搜索:名称 + "status"?: string; // 处理状态,[enum:HouseChargeTaskDetailsStatusEnum] + }; + type Show = { + "id": number; // id + }; + type Delete = { + "id": number; // id + }; + } + namespace HouseChargeTasks { + type List = { + "charge_standard_name"?: string; // 模糊搜索:收费标准名称 + "asset_projects_id"?: number; // 资产项目id,[ref:asset_projects] + "companies_id"?: number; // 公司id,[ref:companies] + "status"?: string; // 任务状态,[enum:HouseChargeTasksStatusEnum] + "type"?: string; // 类型,[enum:HouseChargeTasksTypeEnum] + "project_name"?: string; // 资产项目名称 + "company_name"?: string; // 公司名称 + }; + type Store = { + "house_charge_standards_id": number; // 房屋收费标准id,[ref:house_charge_standards] + "month": string; // 月份 + "start_date": Date; // 收费开始日期 + "end_date": Date; // 收费截止日期 + }; + type Show = { + "id": number; // id + }; + type SoftDelete = { + "id": number; // id + }; + type Restore = { + "id": number; // id + }; + type Delete = { + "id": number; // id + }; } } namespace HouseOrder { @@ -1122,24 +1215,27 @@ declare namespace ApiTypes { }; type Store = { "type": string; // 工单类型,[enum:HouseWorkOrdersTypeEnum] - "level": string; // 优先级,[enum:HouseWorkOrdersLevelEnum] - "title": string; // 工单标题 + "level"?: string; // 优先级,[enum:HouseWorkOrdersLevelEnum] + "complaint_type"?: string; // 投诉类型[enum:HouseWorkOrdersComplaintTypeEnum] + "location"?: string; // 报修位置[enum:HouseWorkOrdersLocationEnum] "content": string; // 工单内容 "reporter_name"?: string; // 上报人名称 "reporter_phone"?: string; // 上报人手机 "attachments"?: string[]; // 工单附件 - "asset_houses_id": number; // 资产房屋id,[ref:asset_houses] + "asset_houses_id"?: number; // 资产房屋id,[ref:asset_houses] + "asset_projects_id"?: number; // 资产项目id,[ref:asset_projects] }; type Update = { "id": number; // id "type": string; // 工单类型,[enum:HouseWorkOrdersTypeEnum] - "level": string; // 优先级,[enum:HouseWorkOrdersLevelEnum] + "level"?: string; // 优先级,[enum:HouseWorkOrdersLevelEnum] "content": string; // 工单内容 "reporter_name"?: string; // 上报人名称 "reporter_phone"?: string; // 上报人手机 "contact_phone"?: string; // 联系人电话 "attachments"?: string[]; // 工单附件 - "asset_houses_id": number; // 资产房屋id,[ref:asset_houses] + "asset_houses_id"?: number; // 资产房屋id,[ref:asset_houses] + "asset_projects_id"?: number; // 资产项目id,[ref:asset_projects] }; type Show = { "id": number; // id @@ -1149,6 +1245,7 @@ declare namespace ApiTypes { "assign_employees_id": number; // 处理人id,[ref:company_employees] "assign_remark"?: string; // 分派说明 "predict_complete_at"?: Date; // 预计完成时间 + "level"?: string; // 优先级,[enum:HouseWorkOrdersLevelEnum] }; type SoftDelete = { "id": number; // id diff --git a/src/gen/Apis.ts b/src/gen/Apis.ts index 1e64ee1..c4e0d9a 100644 --- a/src/gen/Apis.ts +++ b/src/gen/Apis.ts @@ -19,6 +19,12 @@ export const Apis = { ChangeIsContact(data: ApiTypes.Archive.HouseOccupants.ChangeIsContact): Promise { return request('admin/archive/house_occupants/change_is_contact', { data }); }, + Import(data?: ApiTypes.Archive.HouseOccupants.Import): Promise { + return request('admin/archive/house_occupants/import', { data }); + }, + DownloadTemplate(): Promise { + return request('admin/archive/house_occupants/download_template', {responseType: 'blob',}); + }, }, HouseRegisters: { List(data?: ApiTypes.Archive.HouseRegisters.List): Promise { @@ -119,6 +125,9 @@ export const Apis = { BindCompany(data: ApiTypes.Asset.AssetProjects.BindCompany): Promise { return request('admin/asset/asset_projects/bind_company', { data }); }, + ChangePropertyBrand(data: ApiTypes.Asset.AssetProjects.ChangePropertyBrand): Promise { + return request('admin/asset/asset_projects/change_property_brand', { data }); + }, Show(data: ApiTypes.Asset.AssetProjects.Show): Promise { return request('admin/asset/asset_projects/show', { data }); }, @@ -428,6 +437,26 @@ export const Apis = { return request('admin/company/company_project_receipt_accounts/select', { data }); }, }, + CompanyPropertyBrands: { + List(data?: ApiTypes.Company.CompanyPropertyBrands.List): Promise { + return request('admin/company/company_property_brands/list', { data }); + }, + Store(data: ApiTypes.Company.CompanyPropertyBrands.Store): Promise { + return request('admin/company/company_property_brands/store', { data }); + }, + Update(data: ApiTypes.Company.CompanyPropertyBrands.Update): Promise { + return request('admin/company/company_property_brands/update', { data }); + }, + Show(data: ApiTypes.Company.CompanyPropertyBrands.Show): Promise { + return request('admin/company/company_property_brands/show', { data }); + }, + Delete(data: ApiTypes.Company.CompanyPropertyBrands.Delete): Promise { + return request('admin/company/company_property_brands/delete', { data }); + }, + Select(data?: ApiTypes.Company.CompanyPropertyBrands.Select): Promise { + return request('admin/company/company_property_brands/select', { data }); + }, + }, CompanyReceiptAccounts: { List(data?: ApiTypes.Company.CompanyReceiptAccounts.List): Promise { return request('admin/company/company_receipt_accounts/list', { data }); @@ -552,6 +581,40 @@ export const Apis = { Delete(data: ApiTypes.HouseCharage.HouseChargeStandards.Delete): Promise { return request('admin/house_charage/house_charge_standards/delete', { data }); }, + Select(data?: ApiTypes.HouseCharage.HouseChargeStandards.Select): Promise { + return request('admin/house_charage/house_charge_standards/select', { data }); + }, + }, + HouseChargeTaskDetails: { + List(data?: ApiTypes.HouseCharage.HouseChargeTaskDetails.List): Promise { + return request('admin/house_charage/house_charge_task_details/list', { data }); + }, + Show(data: ApiTypes.HouseCharage.HouseChargeTaskDetails.Show): Promise { + return request('admin/house_charage/house_charge_task_details/show', { data }); + }, + Delete(data: ApiTypes.HouseCharage.HouseChargeTaskDetails.Delete): Promise { + return request('admin/house_charage/house_charge_task_details/delete', { data }); + }, + }, + HouseChargeTasks: { + List(data?: ApiTypes.HouseCharage.HouseChargeTasks.List): Promise { + return request('admin/house_charage/house_charge_tasks/list', { data }); + }, + Store(data: ApiTypes.HouseCharage.HouseChargeTasks.Store): Promise { + return request('admin/house_charage/house_charge_tasks/store', { data }); + }, + Show(data: ApiTypes.HouseCharage.HouseChargeTasks.Show): Promise { + return request('admin/house_charage/house_charge_tasks/show', { data }); + }, + SoftDelete(data: ApiTypes.HouseCharage.HouseChargeTasks.SoftDelete): Promise { + return request('admin/house_charage/house_charge_tasks/soft_delete', { data }); + }, + Restore(data: ApiTypes.HouseCharage.HouseChargeTasks.Restore): Promise { + return request('admin/house_charage/house_charge_tasks/restore', { data }); + }, + Delete(data: ApiTypes.HouseCharage.HouseChargeTasks.Delete): Promise { + return request('admin/house_charage/house_charge_tasks/delete', { data }); + }, }, }, HouseOrder: { diff --git a/src/gen/Enums.ts b/src/gen/Enums.ts index 0f7a2f4..1259f9f 100644 --- a/src/gen/Enums.ts +++ b/src/gen/Enums.ts @@ -126,7 +126,7 @@ export const BannersTypeEnum= { // 缓存类型 export const CacheTypeEnum= { - 'MobilePhoneVerificationCode': {"text":"手机验证码","color":"#a10533","value":"MobilePhoneVerificationCode"}, + 'MobilePhoneVerificationCode': {"text":"手机验证码","color":"#5b3d89","value":"MobilePhoneVerificationCode"}, }; // CompaniesMerchantTypeEnum @@ -420,6 +420,17 @@ export const HouseWorkOrdersAssignStatusEnum= { 'Assigned': {"text":"已指派","color":"#00ff00","value":"Assigned"}, }; +// HouseWorkOrdersComplaintTypeEnum +export const HouseWorkOrdersComplaintTypeEnum= { + 'Hygiene': {"text":"卫生环境","color":"#ff0000","value":"Hygiene"}, + 'Greening': {"text":"绿植绿化","color":"#00aaff","value":"Greening"}, + 'Safety': {"text":"安全问题","color":"#ffaa00","value":"Safety"}, + 'Maintenance': {"text":"维修问题","color":"#aa00ff","value":"Maintenance"}, + 'PropertyService': {"text":"物业服务","color":"#00aa55","value":"PropertyService"}, + 'Staff': {"text":"工作人员","color":"#ff00aa","value":"Staff"}, + 'Other': {"text":"其他","color":"#aaaaaa","value":"Other"}, +}; + // HouseWorkOrdersLevelEnum export const HouseWorkOrdersLevelEnum= { 'Urgent': {"text":"紧急","color":"#ff0000","value":"Urgent"}, @@ -428,6 +439,12 @@ export const HouseWorkOrdersLevelEnum= { 'Low': {"text":"低","color":"#999999","value":"Low"}, }; +// HouseWorkOrdersLocationEnum +export const HouseWorkOrdersLocationEnum= { + 'CommonArea': {"text":"公共区域","color":"#ff0000","value":"CommonArea"}, + 'MyHome': {"text":"我家","color":"#00ff00","value":"MyHome"}, +}; + // HouseWorkOrdersStatusEnum export const HouseWorkOrdersStatusEnum= { 'Pending': {"text":"待处理","color":"#FFA500","value":"Pending"}, @@ -438,11 +455,9 @@ export const HouseWorkOrdersStatusEnum= { // HouseWorkOrdersTypeEnum export const HouseWorkOrdersTypeEnum= { - 'Maintenance': {"text":"维修","color":"#ff0000","value":"Maintenance"}, - 'Installation': {"text":"安装","color":"#00aaff","value":"Installation"}, - 'Consultation': {"text":"咨询","color":"#ffaa00","value":"Consultation"}, + 'Repair': {"text":"报修","color":"#ff0000","value":"Repair"}, + 'Incident': {"text":"报事","color":"#00aaff","value":"Incident"}, 'Complaint': {"text":"投诉","color":"#aa00ff","value":"Complaint"}, - 'Other': {"text":"其它","color":"#00aa55","value":"Other"}, }; // OrganizationsTypeEnum diff --git a/src/pages/announcement/modals/AnnouncementCreate.tsx b/src/pages/announcement/modals/AnnouncementCreate.tsx index e7e869f..768e196 100644 --- a/src/pages/announcement/modals/AnnouncementCreate.tsx +++ b/src/pages/announcement/modals/AnnouncementCreate.tsx @@ -66,13 +66,6 @@ export default function Create(props: MyBetaModalFormProps) { colProps: { span: 12 }, formItemProps: { ...rulesHelper.text }, }), - - // { - // key: 'is_publish', - // title: '是否立刻发布', - // valueType: 'switch', - // colProps: { span: 8 }, - // }, { key: 'sort', title: '排序', diff --git a/src/pages/archive/index.tsx b/src/pages/archive/index.tsx index 5d98c75..0193f93 100644 --- a/src/pages/archive/index.tsx +++ b/src/pages/archive/index.tsx @@ -1,6 +1,7 @@ import { MyButtons, MyColumns, + MyImportModal, MyPageContainer, MyProTableProps, usePageTabs, @@ -29,6 +30,17 @@ export default function Index({ title = '房屋档案' }) { request={async (params, sort) => MyProTableProps.request(params, sort, Apis.Asset.AssetHouses.List) } + toolBarRender={(action) => [ + , + ]} columns={[ MyColumns.ID(), { diff --git a/src/pages/asset/$id.tsx b/src/pages/asset/$id.tsx index 939d715..76d2bdd 100644 --- a/src/pages/asset/$id.tsx +++ b/src/pages/asset/$id.tsx @@ -4,11 +4,13 @@ import { ProCard } from '@ant-design/pro-components'; import { useParams } from '@umijs/max'; import { Space, Tabs } from 'antd'; import { useEffect, useState } from 'react'; +import Announcement from './components/Announcement'; import AssetAccounts from './components/AssetAccounts'; import MyAssetBuildings from './components/AssetBuildings'; import AssetGrid from './components/AssetGrid'; import AssetInfo from './components/AssetInfo'; import ChargeStandard from './components/ChargeStandard'; +import ConvenienceServices from './components/ConvenienceServices'; import BindCompany from './components/modals/BindCompany'; import AssetUpdate from './modals/AssetUpdate'; @@ -71,12 +73,18 @@ export default function Show({ title }: { title?: string } = {}) { closable: false, children: , }, - // { - // label: '车位管理', - // key: 'carport', - // closable: false, - // children: , - // }, + { + label: '项目公告', + key: 'announcement', + closable: false, + children: , + }, + { + label: '便民服务', + key: 'convenience_services', + closable: false, + children: , + }, ]; return ( diff --git a/src/pages/asset/components/Announcement.tsx b/src/pages/asset/components/Announcement.tsx new file mode 100644 index 0000000..3310037 --- /dev/null +++ b/src/pages/asset/components/Announcement.tsx @@ -0,0 +1,129 @@ +import { MyButtons, MyColumns, MyProTableProps } from '@/common'; +import { Apis } from '@/gen/Apis'; +import { ProTable } from '@ant-design/pro-components'; +import { Space } from 'antd'; +import { useEffect, useRef } from 'react'; +import AnnouncementCreate from './modals/AnnouncementCreate'; +import AnnouncementShow from './modals/AnnouncementShow'; +import AnnouncementUpdate from './modals/AnnouncementUpdate'; + +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_projects_id: rest.item?.id }, + sort, + Apis.Msg.MsgPropertyAnnouncements.List, + ) + } + toolBarRender={(action) => [ + , + ]} + search={false} + columns={[ + MyColumns.ID(), + + { + title: '公告标题', + dataIndex: 'title', + width: 120, // 关键:固定列宽(若父容器过窄,可设 minWidth: 200 优先保证列宽) + render: (text) => ( +
+ {text} +
+ ), + }, + { + title: '公告内容', + dataIndex: 'content', + valueType: 'textarea', // 仅影响表单编辑时的输入类型,不影响表格展示 + search: false, + width: 200, // 关键:固定列宽(若父容器过窄,可设 minWidth: 200 优先保证列宽) + render: (text) => ( +
+ {text} +
+ ), + }, + { + title: '发布日期', + dataIndex: 'publish_at', + valueType: 'date', + search: false, + }, + { + title: '是否发布小程序', + dataIndex: 'is_publish', + render: (text) => (text ? '是' : '否'), + search: false, + }, + MyColumns.SoftDelete({ + title: '启/禁用', + onRestore: Apis.Msg.MsgPropertyAnnouncements.Restore, + onSoftDelete: Apis.Msg.MsgPropertyAnnouncements.SoftDelete, + search: false, + }), + { + //创建日期 + title: '创建日期', + dataIndex: 'created_at', + valueType: 'date', + search: false, + }, + MyColumns.Option({ + render: (_, item: any, index, action) => ( + + + + + Apis.Msg.MsgPropertyAnnouncements.Delete({ + id: item.id, + }).then(() => action?.reload()) + } + /> + + ), + }), + ]} + /> + + ); +} diff --git a/src/pages/asset/components/ChargeStandard.tsx b/src/pages/asset/components/ChargeStandard.tsx index 2ec8416..c4717f9 100644 --- a/src/pages/asset/components/ChargeStandard.tsx +++ b/src/pages/asset/components/ChargeStandard.tsx @@ -38,7 +38,7 @@ export default function ReceiptAccounts(props: MyBetaModalFormProps) { key="Select" reload={action?.reload} item={props?.item} - title="添加收款账号" + title="添加收费标准" />, ]} // options={false} @@ -106,13 +106,9 @@ export default function ReceiptAccounts(props: MyBetaModalFormProps) { title="编辑" /> diff --git a/src/pages/asset/components/ConvenienceServices.tsx b/src/pages/asset/components/ConvenienceServices.tsx new file mode 100644 index 0000000..3155a6b --- /dev/null +++ b/src/pages/asset/components/ConvenienceServices.tsx @@ -0,0 +1,103 @@ +import { MyButtons, MyColumns, MyProTableProps } from '@/common'; +import { Apis } from '@/gen/Apis'; +import { ConvenienceServicesTypeEnum } from '@/gen/Enums'; +import { ProTable } from '@ant-design/pro-components'; +import { Space } from 'antd'; +import { useEffect, useRef } from 'react'; +import ServiceCreate from './modals/ServiceCreate'; +import ServiceUpdate from './modals/ServiceUpdate'; + +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_projects_id: rest.item?.id }, + sort, + Apis.Common.ConvenienceServices.List, + ) + } + search={false} + toolBarRender={(action) => [ + , + ]} + columns={[ + MyColumns.ID(), + { + title: '关联项目', + dataIndex: ['asset_project', 'name'], + search: { + transform: (value) => { + return { project_name: value }; + }, + }, + }, + MyColumns.EnumTag({ + title: '类型', + dataIndex: 'type', + valueEnum: ConvenienceServicesTypeEnum, + search: false, + }), + { + title: '服务名称', + dataIndex: 'name', + }, + + { + title: '联系方式', + render(_, record) { + const content = record?.content || []; + + // 过滤有效数据 + const validItems = content.filter( + (item: any) => item?.name && item?.phone, + ); + + return ( +
+ {validItems.length > 0 ? ( + validItems.map((item: any, index: number) => ( + // 每个客户信息单独一行 +
+ {item.name}: {item.phone} +
+ )) + ) : ( + 暂无客户信息 + )} +
+ ); + }, + search: false, + }, + MyColumns.Option({ + render: (_, item: any, index, action) => ( + + + + Apis.Common.ConvenienceServices.Delete({ + id: item.id, + }).then(() => action?.reload()) + } + /> + + ), + }), + ]} + /> + + ); +} diff --git a/src/pages/asset/components/modals/AnnouncementCreate.tsx b/src/pages/asset/components/modals/AnnouncementCreate.tsx new file mode 100644 index 0000000..f261c00 --- /dev/null +++ b/src/pages/asset/components/modals/AnnouncementCreate.tsx @@ -0,0 +1,95 @@ +import { + MyBetaModalFormProps, + MyButtons, + MyModalFormProps, + rulesHelper, +} from '@/common'; +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={`添加公告`} + wrapperCol={{ span: 24 }} + width="600px" + trigger={} + key={new Date().getTime()} + form={form} + onOpenChange={(open: any) => { + if (open) { + form.resetFields(); // 清空表单数据 + } + }} + onFinish={async (values) => + Apis.Msg.MsgPropertyAnnouncements.Store({ + ...values, + asset_projects_id: props.item?.id, + }) + .then(() => { + props.reload?.(); + message.success('添加公告内容成功'); + return true; + }) + .catch(() => false) + } + columns={[ + { + key: 'title', + title: '公告标题', + colProps: { span: 24 }, + formItemProps: { ...rulesHelper.text }, + }, + { + key: 'content', + title: '公告内容', + valueType: 'textarea', + colProps: { span: 24 }, + formItemProps: { ...rulesHelper.text }, + fieldProps: { + autoSize: { minRows: 4, maxRows: 6 }, + }, + }, + { + key: 'publish_at', + title: '内容显示的发布日期', + valueType: 'date', + colProps: { span: 12 }, + fieldProps: { + style: { width: '100%' }, + }, + formItemProps: { ...rulesHelper.text }, + }, + // Selects?.AssetProjects({ + // title: '请选择项目', + // key: 'asset_projects_id', + // colProps: { span: 12 }, + // formItemProps: { ...rulesHelper.text }, + // }), + { + key: 'is_publish', + title: '是否立刻发布', + tooltip: '如果选择了,那么内容会立刻发布到小程序中', + valueType: 'switch', + colProps: { span: 8 }, + }, + { + key: 'sort', + title: '排序', + valueType: 'digit', + colProps: { span: 12 }, + tooltip: '数值越大越靠前', + fieldProps: { + placeholder: '数值越大越靠前', + min: 0, + style: { width: '100%' }, + }, + initialValue: 0, + }, + ]} + /> + ); +} diff --git a/src/pages/asset/components/modals/AnnouncementShow.tsx b/src/pages/asset/components/modals/AnnouncementShow.tsx new file mode 100644 index 0000000..cb1daf4 --- /dev/null +++ b/src/pages/asset/components/modals/AnnouncementShow.tsx @@ -0,0 +1,55 @@ +import { MyBetaModalFormProps } from '@/common'; +import { MyModal } from '@/components/MyModal'; +import { ProCard, ProDescriptions } from '@ant-design/pro-components'; +import { Typography } from 'antd'; + +const { Text } = Typography; + +export default function info(props: MyBetaModalFormProps) { + return ( + + + + {props?.item?.asset_project?.name || '-'} + + + {props?.item?.title || '-'} + + + +
+ {props?.item?.content || '-'} +
+
+ + {props?.item?.publish_at || '-'} + + + {props?.item?.created_at || '-'} + + + {props?.item?.is_publish ? '是' : '否'} + +
+ + } + /> + ); +} diff --git a/src/pages/asset/components/modals/AnnouncementUpdate.tsx b/src/pages/asset/components/modals/AnnouncementUpdate.tsx new file mode 100644 index 0000000..88ae286 --- /dev/null +++ b/src/pages/asset/components/modals/AnnouncementUpdate.tsx @@ -0,0 +1,91 @@ +import { + MyBetaModalFormProps, + MyButtons, + MyModalFormProps, + rulesHelper, +} from '@/common'; +import { Apis } from '@/gen/Apis'; +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={`编辑公告内容`} + trigger={} + wrapperCol={{ span: 24 }} + width="600px" + key={new Date().getTime()} + form={form} + onOpenChange={(open: any) => { + if (open && props.item) { + form.setFieldsValue(props.item); + } + }} + onFinish={async (values) => + Apis.Msg.MsgPropertyAnnouncements.Update({ + ...values, + id: props.item?.id ?? 0, + asset_projects_id: props.item?.asset_projects_id ?? 0, + }) + .then(() => { + props.reload?.(); + message.success('编辑公告内容成功'); + return true; + }) + .catch(() => false) + } + columns={[ + { + key: 'title', + title: '公告标题', + colProps: { span: 24 }, + formItemProps: { ...rulesHelper.text }, + }, + { + key: 'content', + title: '公告内容', + valueType: 'textarea', + colProps: { span: 24 }, + formItemProps: { ...rulesHelper.text }, + fieldProps: { + autoSize: { minRows: 4, maxRows: 6 }, + }, + }, + { + key: 'publish_at', + title: '内容显示的发布日期', + valueType: 'date', + colProps: { span: 12 }, + fieldProps: { + style: { width: '100%' }, + }, + formItemProps: { ...rulesHelper.text }, + }, + + { + key: 'is_publish', + title: '是否立刻发布', + tooltip: '如果选择了,那么内容会立刻发布到小程序中', + valueType: 'switch', + colProps: { span: 8 }, + }, + { + key: 'sort', + title: '排序', + valueType: 'digit', + colProps: { span: 12 }, + tooltip: '数值越大越靠前', + fieldProps: { + placeholder: '数值越大越靠前', + min: 0, + style: { width: '100%' }, + }, + initialValue: 0, + }, + ]} + /> + ); +} diff --git a/src/pages/asset/components/modals/ChargeStandardCreate.tsx b/src/pages/asset/components/modals/ChargeStandardCreate.tsx index a81d43e..d0e80da 100644 --- a/src/pages/asset/components/modals/ChargeStandardCreate.tsx +++ b/src/pages/asset/components/modals/ChargeStandardCreate.tsx @@ -45,8 +45,8 @@ export default function Create(props: MyBetaModalFormProps) { ...values, asset_projects_id: props?.item?.id, type: - values.charge_type === HouseBillsTypeEnum.SharedWaterFee.value || - values.charge_type === HouseBillsTypeEnum.SharedElectricityFee.value + values.charge_type === HouseBillsTypeEnum.PropertyFee.value || + values.charge_type === HouseBillsTypeEnum.MaintenanceFund.value ? HouseChargeStandardsTypeEnum.House.value : HouseChargeStandardsTypeEnum.Meter.value, is_apportionment: diff --git a/src/pages/asset/components/modals/ChargeStandardHasHouse.tsx b/src/pages/asset/components/modals/ChargeStandardHasHouse.tsx index fbd06f7..403ace8 100644 --- a/src/pages/asset/components/modals/ChargeStandardHasHouse.tsx +++ b/src/pages/asset/components/modals/ChargeStandardHasHouse.tsx @@ -1,729 +1,213 @@ -import { MyBetaModalFormProps, MyButtons, renderTextHelper } from '@/common'; +import { + MyBetaModalFormProps, + MyButtons, + MyColumns, + MyProTableProps, +} from '@/common'; import { MyModal } from '@/components/MyModal'; + import { Apis } from '@/gen/Apis'; import { - HouseBillsTypeEnum, - HouseChargeStandardsCalculationModeEnum, - HouseChargeStandardsCalculationPeriodEnum, + AssetHousesOwnershipTypeEnum, + AssetHousesUsageEnum, } from '@/gen/Enums'; -import { ProCard } from '@ant-design/pro-components'; -import { - Alert, - Button, - Checkbox, - message, - Space, - Tree, - Typography, -} from 'antd'; -import { CheckboxChangeEvent } from 'antd/es/checkbox'; -import type { DataNode } from 'antd/es/tree'; -import { useEffect, useRef, useState } from 'react'; +import { ProTable } from '@ant-design/pro-components'; +import { message, Space } from 'antd'; +import { useRef, useState } from 'react'; -const { Title } = Typography; +export default function ChargeStandardHasHouse(props: MyBetaModalFormProps) { + // 使用 useState 保存选中的房屋 ID 和行数据,确保跨页选中状态保持 + const [selectedHousesIds, setSelectedHousesIds] = useState([]); + const [selectedRows, setSelectedRows] = useState([]); -interface TreeNodeType extends DataNode { - id: number; - key: string; - title: string; - isLeaf?: boolean; - children?: TreeNodeType[]; - asset_buildings_id?: number; - asset_units_id?: number; -} + // 添加 tableRef 用于操作表格 + const tableRef = useRef(); -// 扩展 MyBetaModalFormProps 接口,添加 onCancel 属性 -interface ChargeStandardHasHouseProps extends MyBetaModalFormProps { - onCancel?: () => void; -} - -export default function ChargeStandardHasHouse( - props: ChargeStandardHasHouseProps, -) { - const [treeData, setTreeData] = useState([]); - const [expandedKeys, setExpandedKeys] = useState([]); - const [checkedKeys, setCheckedKeys] = useState([]); - const [selectedKeys, setSelectedKeys] = useState([]); - const [autoExpandParent, setAutoExpandParent] = useState(true); - const [loading, setLoading] = useState(false); - const [selectAll, setSelectAll] = useState(false); - const [selectedHouses, setSelectedHouses] = useState< - { id: number; name: string }[] - >([]); - const modalRef: any = useRef(null); - - // 加载楼栋数据 - const loadBuildings = async () => { - setLoading(true); - - try { - const res = await Apis.Asset.AssetBuildings.List({ - asset_projects_id: props?.item?.asset_projects_id, - }); - if (res?.data) { - const buildings = res.data.map((building: any) => ({ - id: building.id, - key: `building-${building.id}`, - title: building.name, - children: [], - isLeaf: false, - })); - setTreeData(buildings); - } - } catch (error) { - console.error('加载楼栋失败:', error); - } finally { - setLoading(false); - } - }; - - // 加载单元数据 - const loadUnits = async (buildingId: number, buildingKey: string) => { - setLoading(true); - try { - const res = await Apis.Asset.AssetUnits.List({ - asset_projects_id: props?.item?.asset_projects_id, - asset_buildings_id: buildingId, - }); - - if (res?.data) { - const units = res.data.map((unit: any) => ({ - id: unit.id, - key: `unit-${unit.id}`, - title: unit.name, - children: [], - isLeaf: false, - asset_buildings_id: buildingId, - })); - - // 更新树形数据 - const newTreeData = [...treeData]; - const buildingNode = newTreeData.find( - (node) => node.key === buildingKey, - ); - if (buildingNode) { - buildingNode.children = units; - } - - setTreeData(newTreeData); - } - } catch (error) { - console.error('加载单元失败:', error); - } finally { - setLoading(false); - } - }; - - // 加载房屋数据 - const loadHouses = async ( - buildingId: number, - unitId: number, - unitKey: string, - ) => { - setLoading(true); - try { - const res = await Apis.Asset.AssetHouses.List({ - asset_projects_id: props?.item?.asset_projects_id, - asset_buildings_id: buildingId, - asset_units_id: unitId, - }); - - if (res?.data) { - const houses = res.data.map((house: any) => ({ - id: house.id, - key: `house-${house.id}`, - title: `${house.name} (${house.floor}层)`, - isLeaf: true, - asset_buildings_id: buildingId, - asset_units_id: unitId, - })); - - // 更新树形数据 - const newTreeData = [...treeData]; - const buildingNode = newTreeData.find( - (node) => - node.asset_buildings_id === undefined && node.id === buildingId, - ); - - if (buildingNode && buildingNode.children) { - const unitNode = buildingNode.children.find( - (node) => node.key === unitKey, - ); - if (unitNode) { - unitNode.children = houses; - } - } - - setTreeData(newTreeData); - } - } catch (error) { - console.error('加载房屋失败:', error); - } finally { - setLoading(false); - } - }; - - // 初始化加载数据 - useEffect(() => { - if (props?.item?.asset_projects_id) { - loadBuildings(); - } else { - console.warn('缺少 asset_projects_id 参数'); - } - }, [props?.item?.id]); - - // 处理节点展开 - const onExpand = (expandedKeysValue: React.Key[]) => { - setExpandedKeys(expandedKeysValue); - setAutoExpandParent(false); - }; - - // 处理节点选中 - const onCheck = async ( - checkedKeysValue: - | React.Key[] - | { checked: React.Key[]; halfChecked: React.Key[] }, - ) => { - // 处理不同格式的返回值 - const keys = Array.isArray(checkedKeysValue) - ? checkedKeysValue - : checkedKeysValue.checked; - - // 获取之前的选中状态,用于比较变化 - const prevKeys = new Set(checkedKeys); - const newKeys = new Set(keys); - - // 找出新选中的节点 - const newlyCheckedKeys = [...newKeys].filter((key) => !prevKeys.has(key)); - - // 找出新取消选中的节点 - const uncheckedKeys = [...prevKeys].filter((key) => !newKeys.has(key)); - - // 处理新选中的节点 - for (const key of newlyCheckedKeys) { - const keyStr = key.toString(); - - // 如果选中的是楼栋 - if (keyStr.startsWith('building-')) { - const buildingNode = treeData.find((node) => node.key === key); - if (buildingNode) { - // 调用接口获取该楼栋下所有房屋 - await loadBuildingHouses(buildingNode.id); - } - } - - // 如果选中的是单元 - else if (keyStr.startsWith('unit-')) { - // 查找该单元所属的楼栋和单元ID - for (const building of treeData) { - const unitNode = building.children?.find((unit) => unit.key === key); - if (unitNode) { - // 调用接口获取该单元下所有房屋 - await loadUnitHouses(building.id, unitNode.id); - break; - } - } - } - } - - // 如果有节点被取消选中,同步取消其所有子节点 - if (uncheckedKeys.length > 0) { - const keysToRemove = new Set(); - const findChildKeys = (nodes: TreeNodeType[], parentKey: React.Key) => { - nodes.forEach((node) => { - if (node.key === parentKey) { - // 将当前节点及其所有子节点的key加入待移除集合 - const collectKeys = (n: TreeNodeType) => { - keysToRemove.add(n.key); - if (n.children) { - n.children.forEach(collectKeys); - } - }; - collectKeys(node); - } else if (node.children) { - findChildKeys(node.children, parentKey); - } - }); - }; - - uncheckedKeys.forEach((key) => { - findChildKeys(treeData, key); - }); - - // 从选中keys中移除所有需要取消的节点 - const finalKeys = keys.filter((key) => !keysToRemove.has(key)); - setCheckedKeys(finalKeys); - - // 更新selectedHouses,移除被取消选中的房屋 - const houseKeysToRemove = new Set(); - keysToRemove.forEach((key) => { - if (key.toString().startsWith('house-')) { - houseKeysToRemove.add(key.toString().replace('house-', '')); - } - }); - - const updatedHouses = selectedHouses.filter( - (house) => !houseKeysToRemove.has(house.id.toString()), - ); - - setSelectedHouses(updatedHouses); - } else { - setCheckedKeys(keys); - } - - // 收集所有选中的房屋 - const selectedHousesList: { - id: number; - name: string; - buildingName?: string; - unitName?: string; - }[] = [...selectedHouses]; - - // 遍历树形数据,收集选中节点下的所有房屋 - const collectHouses = (nodes: TreeNodeType[], checkedKeys: React.Key[]) => { - nodes.forEach((node) => { - if (checkedKeys.includes(node.key)) { - if (node.isLeaf) { - // 如果是房屋节点,检查是否已经存在 - const houseId = node.id; - const exists = selectedHousesList.some( - (house) => house.id === houseId, - ); - - if (!exists) { - // 查找楼栋和单元信息 - let buildingName = ''; - let unitName = ''; - - // 查找楼栋和单元 - for (const building of treeData) { - if (building.id === node.asset_buildings_id) { - buildingName = building.title as string; - - // 查找单元 - const unit = building.children?.find( - (u) => u.id === node.asset_units_id, - ); - if (unit) { - unitName = unit.title as string; - } - break; - } - } - - // 添加到选中列表 - selectedHousesList.push({ - id: houseId, - name: `${buildingName} ${unitName} ${node.title}(${houseId})`, - buildingName, - unitName, - }); - } - } else { - // 如果是楼栋或单元节点,递归收集其下的所有房屋 - if (node.children) { - collectHouses(node.children, checkedKeys); - } - } - } - }); - }; - - collectHouses(treeData, keys); - - setSelectedHouses(selectedHousesList); - setSelectAll( - selectedHousesList.length > 0 && - selectedHousesList.length === - treeData.reduce( - (total, building) => - total + - (building.children?.reduce( - (unitTotal, unit) => unitTotal + (unit.children?.length || 0), - 0, - ) || 0), - 0, - ), - ); - }; - - // 处理节点选择 - const onSelect = (selectedKeysValue: React.Key[]) => { - setSelectedKeys(selectedKeysValue); - }; - - // 处理动态加载数据 - const onLoadData = async (node: TreeNodeType) => { - if (node.isLeaf) { - return Promise.resolve(); - } - - // 加载楼栋下的单元 - if (node.key.toString().startsWith('building-')) { - console.log('node.key', node.key); - // 从key中提取buildingId,格式为'building-{id}' - const buildingId = parseInt( - node.key.toString().replace('building-', ''), - 10, - ); - await loadUnits(buildingId, node.key as string); - - // 如果楼栋被选中,加载并选中其下所有单元和房屋 - if (checkedKeys.includes(node.key)) { - // 直接调用loadBuildingHouses加载该楼栋下所有房屋 - await loadBuildingHouses(buildingId); - } - return Promise.resolve(); - } - - // 加载单元下的房屋 - if (node.key.toString().startsWith('unit-')) { - // 从key中提取unitId,格式为'unit-{id}' - const unitId = parseInt(node.key.toString().replace('unit-', ''), 10); - const buildingId = node.asset_buildings_id as number; - await loadHouses(buildingId, unitId, node.key as string); - - // 如果单元被选中,选中其下所有房屋 - if (checkedKeys.includes(node.key)) { - // 直接调用loadUnitHouses加载该单元下所有房屋 - await loadUnitHouses(buildingId, unitId); - } - return Promise.resolve(); - } - - return Promise.resolve(); - }; - - // 加载所有房屋数据 - const loadAllHouses = async () => { - setLoading(true); - try { - const res = await Apis.Asset.AssetHouses.List({ - asset_projects_id: props?.item?.asset_projects_id, - }); - - if (res?.data) { - const allHouseKeys: React.Key[] = []; - const allHouses: { - id: number; - name: string; - buildingName: string; - unitName: string; - }[] = []; - - // 创建映射以快速查找楼栋和单元名称 - const buildingMap = new Map(); - const unitMap = new Map(); - - // 填充楼栋映射 - treeData.forEach((building) => { - buildingMap.set(building.id, building.title); - building.children?.forEach((unit) => { - unitMap.set(unit.id, unit.title); - }); - }); - - res.data.forEach((house: any) => { - const houseKey = `house-${house.id}`; - allHouseKeys.push(houseKey); - - const buildingName = buildingMap.get(house.asset_buildings_id) || ''; - const unitName = unitMap.get(house.asset_units_id) || ''; - - allHouses.push({ - id: house.id, - name: `${buildingName} ${unitName} ${house.name}(${house.id})`, - buildingName: buildingName as string, - unitName: unitName as string, - }); - }); - - setCheckedKeys(allHouseKeys); - setSelectedHouses(allHouses); - } - } catch (error) { - console.error('加载所有房屋失败:', error); - message.error('加载所有房屋失败'); - } finally { - setLoading(false); - } - }; - - // 加载楼栋下所有房屋 - const loadBuildingHouses = async (buildingId: number) => { - setLoading(true); - try { - const res = await Apis.Asset.AssetHouses.List({ - asset_projects_id: props?.item?.asset_projects_id, - asset_buildings_id: buildingId, - }); - - if (res?.data) { - const buildingHouseKeys: React.Key[] = []; - const buildingHouses: { - id: number; - name: string; - buildingName: string; - unitName: string; - }[] = []; - - // 获取楼栋名称 - const building = treeData.find((b) => b.id === buildingId); - const buildingName = building?.title || ''; - - // 创建单元映射 - const unitMap = new Map(); - building?.children?.forEach((unit) => { - unitMap.set(unit.id, unit.title); - }); - - res.data.forEach((house: any) => { - const houseKey = `house-${house.id}`; - buildingHouseKeys.push(houseKey); - - const unitName = unitMap.get(house.asset_units_id) || ''; - - buildingHouses.push({ - id: house.id, - name: `${buildingName} ${unitName} ${house.name}(${house.id})`, - buildingName: buildingName as string, - unitName: unitName as string, - }); - }); - - // 合并当前选中的keys和新的keys - const newCheckedKeys = Array.from( - new Set([...checkedKeys, ...buildingHouseKeys]), - ); - setCheckedKeys(newCheckedKeys); - - // 合并当前选中的房屋和新的房屋 - const existingIds = new Set(selectedHouses.map((h) => h.id)); - const newHouses = buildingHouses.filter((h) => !existingIds.has(h.id)); - setSelectedHouses([...selectedHouses, ...newHouses]); - } - } catch (error) { - console.error('加载楼栋房屋失败:', error); - message.error('加载楼栋房屋失败'); - } finally { - setLoading(false); - } - }; - - // 加载单元下所有房屋 - const loadUnitHouses = async (buildingId: number, unitId: number) => { - setLoading(true); - try { - const res = await Apis.Asset.AssetHouses.List({ - asset_projects_id: props?.item?.asset_projects_id, - asset_buildings_id: buildingId, - asset_units_id: unitId, - }); - - if (res?.data) { - const unitHouseKeys: React.Key[] = []; - const unitHouses: { - id: number; - name: string; - buildingName: string; - unitName: string; - }[] = []; - - // 获取楼栋和单元名称 - const building = treeData.find((b) => b.id === buildingId); - const buildingName = building?.title || ''; - - const unit = building?.children?.find((u) => u.id === unitId); - const unitName = unit?.title || ''; - - res.data.forEach((house: any) => { - const houseKey = `house-${house.id}`; - unitHouseKeys.push(houseKey); - - unitHouses.push({ - id: house.id, - name: `${buildingName} ${unitName} ${house.name}(${house.id})`, - buildingName: buildingName as string, - unitName: unitName as string, - }); - }); - - // 合并当前选中的keys和新的keys - const newCheckedKeys = Array.from( - new Set([...checkedKeys, ...unitHouseKeys]), - ); - setCheckedKeys(newCheckedKeys); - - // 合并当前选中的房屋和新的房屋 - const existingIds = new Set(selectedHouses.map((h) => h.id)); - const newHouses = unitHouses.filter((h) => !existingIds.has(h.id)); - setSelectedHouses([...selectedHouses, ...newHouses]); - } - } catch (error) { - console.error('加载单元房屋失败:', error); - message.error('加载单元房屋失败'); - } finally { - setLoading(false); - } - }; - - // 处理全选 - const handleSelectAll = async (e: CheckboxChangeEvent) => { - setSelectAll(e.target.checked); - - if (e.target.checked) { - // 调用接口获取所有房屋 - await loadAllHouses(); - } else { - // 取消全选 - setCheckedKeys([]); - setSelectedHouses([]); - } - }; - - // 提交选中的房屋 - const handleSubmit = async () => { - if (selectedHouses.length === 0) { + const onShowContactPhone = () => { + if (selectedHousesIds.length === 0) { message.warning('请至少选择一个房屋'); return; } - try { - setLoading(true); - // 将 number[] 转换为 string[] - const houses_ids = selectedHouses.map((house) => house.id.toString()); + // 确保 houses_ids 是字符串数组 + const housesIds = selectedHousesIds.map((id) => String(id)); - await Apis.HouseCharage.HouseChargeHasHouses.Store({ - house_charge_standards_id: props?.item?.id, - houses_ids, + Apis.HouseCharage.HouseChargeHasHouses.Store({ + house_charge_standards_id: props?.item?.id ?? 0, + houses_ids: housesIds, + }) + .then(() => { + // 成功后重置选中状态 + setSelectedHousesIds([]); + setSelectedRows([]); + props.reload?.(); + message.success('添加成功!'); + }) + .catch((error) => { + console.error('添加失败:', error); + message.error('添加失败: ' + (error.message || '未知错误')); + return false; }); - - message.success('绑定房屋成功'); - props?.reload?.(); - props?.onCancel?.(); - } catch (error) { - console.error('绑定房屋失败:', error); - message.error('绑定房屋失败'); - } finally { - setLoading(false); - } }; return ( - } + type="primary" + width="920px" node={ - - - <div> - <div>收费标准名称:{props?.item?.name || '标准名称'}</div> - <Space> - <renderTextHelper.Tag - Enums={HouseBillsTypeEnum} - value={props?.item?.charge_type} - key="type" - /> - <renderTextHelper.Tag - Enums={HouseChargeStandardsCalculationModeEnum} - value={props?.item?.calculation_mode} - key="type" - /> - <renderTextHelper.Tag - Enums={HouseChargeStandardsCalculationPeriodEnum} - value={props?.item?.calculation_period} - key="type" - /> - </Space> - </div> - - - + + 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[]; - {loading &&
加载中...
} + // 更新选中状态 + setSelectedHousesIds(numericKeys); - -
+ // 合并当前页面选中的行和之前选中的行 + const newSelectedRows = [...selectedRows]; -
-
- 已选房屋 ({selectedHouses.length}) -
+ // 设置选中行数据 + setSelectedRows(newSelectedRows); + }, + }} + tableAlertOptionRender={({ selectedRowKeys, onCleanSelected }) => { + return ( + + 已选 {selectedRowKeys.length} 项 + 清空 + onShowContactPhone()} + /> + + ); + }} + options={false} + columns={[ + MyColumns.ID(), + MyColumns.EnumTag({ + title: '用途', + dataIndex: 'usage', + valueEnum: AssetHousesUsageEnum, + }), + { + 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', + }, -
- {selectedHouses.length > 0 ? ( -
    - {selectedHouses.map((house) => ( -
  • {house.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/asset/components/modals/ChargeStandardUpdate.tsx b/src/pages/asset/components/modals/ChargeStandardUpdate.tsx index 6f9d9ae..24bc14e 100644 --- a/src/pages/asset/components/modals/ChargeStandardUpdate.tsx +++ b/src/pages/asset/components/modals/ChargeStandardUpdate.tsx @@ -43,10 +43,9 @@ export default function Update(props: MyBetaModalFormProps) { Apis.HouseCharage.HouseChargeStandards.Update({ ...values, asset_projects_id: props?.item?.asset_projects_id, - type: - values.charge_type === HouseBillsTypeEnum.SharedWaterFee.value || - values.charge_type === HouseBillsTypeEnum.SharedElectricityFee.value + values.charge_type === HouseBillsTypeEnum.PropertyFee.value || + values.charge_type === HouseBillsTypeEnum.MaintenanceFund.value ? HouseChargeStandardsTypeEnum.House.value : HouseChargeStandardsTypeEnum.Meter.value, is_apportionment: diff --git a/src/pages/asset/components/modals/GridCreate.tsx b/src/pages/asset/components/modals/GridCreate.tsx index c806170..bdcfb20 100644 --- a/src/pages/asset/components/modals/GridCreate.tsx +++ b/src/pages/asset/components/modals/GridCreate.tsx @@ -15,10 +15,14 @@ export default function Create(props: MyBetaModalFormProps) { return ( {...MyModalFormProps.props} - title={`创建板块`} - wrapperCol={{ span: 24 }} + title={`划分范围`} + // 基本表单 width="700px" - trigger={} + layout="horizontal" + labelCol={{ span: 4 }} + wrapperCol={{ span: 24 }} + labelAlign="right" + trigger={} form={form} key={new Date().getTime()} onOpenChange={(open: any) => { @@ -36,7 +40,7 @@ export default function Create(props: MyBetaModalFormProps) { }) .then(() => { props.reload?.(); - message.success('网格创建成功'); + message.success('范围划分成功'); return true; }) .catch(() => false); @@ -44,7 +48,7 @@ export default function Create(props: MyBetaModalFormProps) { columns={[ Selects?.GetGridMark({ key: 'grid_mark', - title: '网格标识', + title: '范围标识', params: { asset_projects_id: props?.item?.id, }, @@ -69,8 +73,8 @@ export default function Create(props: MyBetaModalFormProps) { return ( @@ -98,27 +102,45 @@ export default function Create(props: MyBetaModalFormProps) { formItemProps: { ...rulesHelper.number }, fieldProps: { showSearch: true, - onChange: () => { + onChange: (value: any) => { + // 获取当前表单的所有值 + const formValues = form.getFieldsValue(); + const gridRanges = formValues.grid_ranges || []; + + // 清空所有行的asset_units_id,因为楼栋变化会影响所有单元选择 + const updatedGridRanges = gridRanges.map( + (item: any, index: number) => { + if (item.asset_buildings_id === value) { + return { ...item, asset_units_id: undefined }; + } + return item; + }, + ); + + // 更新表单值 form.setFieldsValue({ - asset_units_id: undefined, - asset_floors_id: undefined, + grid_ranges: updatedGridRanges, }); }, }, }), - Selects?.GridUnits({ - key: 'asset_units_id', - title: '选择单元', - params: { - asset_projects_id: props?.item?.id, - asset_buildings_id: asset_buildings_id, - }, - colProps: { span: 12 }, - formItemProps: { ...rulesHelper.text }, - fieldProps: { - showSearch: true, - }, - }), + ...(asset_buildings_id + ? [ + Selects?.GridUnits({ + key: 'asset_units_id', + title: '选择单元', + params: { + asset_projects_id: props?.item?.id, + asset_buildings_id: asset_buildings_id, + }, + colProps: { span: 12 }, + formItemProps: { ...rulesHelper.text }, + fieldProps: { + showSearch: true, + }, + }), + ] + : []), ], }, ]; diff --git a/src/pages/asset/components/modals/GridUpdate.tsx b/src/pages/asset/components/modals/GridUpdate.tsx index d6e734c..c821621 100644 --- a/src/pages/asset/components/modals/GridUpdate.tsx +++ b/src/pages/asset/components/modals/GridUpdate.tsx @@ -16,8 +16,11 @@ export default function Update(props: MyBetaModalFormProps) { {...MyModalFormProps.props} title={`网格编辑`} - wrapperCol={{ span: 24 }} width="700px" + layout="horizontal" + labelCol={{ span: 4 }} + wrapperCol={{ span: 24 }} + labelAlign="right" trigger={} form={form} key={new Date().getTime()} @@ -46,7 +49,7 @@ export default function Update(props: MyBetaModalFormProps) { columns={[ Selects?.GetGridMark({ key: 'grid_mark', - title: '网格标识', + title: '范围标识', params: { asset_projects_id: props?.item?.id, }, @@ -71,8 +74,8 @@ export default function Update(props: MyBetaModalFormProps) { return ( @@ -94,33 +97,50 @@ export default function Update(props: MyBetaModalFormProps) { key: 'asset_buildings_id', title: '选择楼栋', params: { - asset_projects_id: props?.item?.asset_projects_id, + asset_projects_id: props?.item?.id, }, colProps: { span: 12 }, formItemProps: { ...rulesHelper.number }, fieldProps: { showSearch: true, - onChange: () => { + onChange: (value: any) => { + // 获取当前表单的所有值 + const formValues = form.getFieldsValue(); + const gridRanges = formValues.grid_ranges || []; + + // 清空所有行的asset_units_id,因为楼栋变化会影响所有单元选择 + const updatedGridRanges = gridRanges.map( + (item: any, index: number) => { + if (item.asset_buildings_id === value) { + return { ...item, asset_units_id: undefined }; + } + return item; + }, + ); + // 更新表单值 form.setFieldsValue({ - asset_units_id: undefined, - asset_floors_id: undefined, + grid_ranges: updatedGridRanges, }); }, }, }), - Selects?.GridUnits({ - key: 'asset_units_id', - title: '选择单元', - params: { - asset_projects_id: props?.item?.asset_projects_id, - asset_buildings_id: asset_buildings_id, - }, - colProps: { span: 12 }, - formItemProps: { ...rulesHelper.text }, - fieldProps: { - showSearch: true, - }, - }), + ...(asset_buildings_id + ? [ + Selects?.GridUnits({ + key: 'asset_units_id', + title: '选择单元', + params: { + asset_projects_id: props?.item?.id, + asset_buildings_id: asset_buildings_id, + }, + colProps: { span: 12 }, + formItemProps: { ...rulesHelper.text }, + fieldProps: { + showSearch: true, + }, + }), + ] + : []), ], }, ]; diff --git a/src/pages/asset/components/modals/ServiceCreate.tsx b/src/pages/asset/components/modals/ServiceCreate.tsx new file mode 100644 index 0000000..82cc80c --- /dev/null +++ b/src/pages/asset/components/modals/ServiceCreate.tsx @@ -0,0 +1,170 @@ +import { + MyBetaModalFormProps, + MyButtons, + MyFormItems, + MyModalFormProps, + rulesHelper, +} from '@/common'; +import { Apis } from '@/gen/Apis'; +import { ConvenienceServicesTypeEnum } from '@/gen/Enums'; +import { BetaSchemaForm } from '@ant-design/pro-components'; +import { Form, message } from 'antd'; +import { useRef } from 'react'; + +export default function Create(props: MyBetaModalFormProps) { + const [form] = Form.useForm(); + const actionRef = useRef(); + + return ( + + {...MyModalFormProps.props} + title={`添加便民服务`} + wrapperCol={{ span: 24 }} + width="600px" + trigger={} + key={new Date().getTime()} + form={form} + onOpenChange={(open: any) => { + if (open) { + form.resetFields(); // 清空表单数据 + } + }} + onFinish={async (values: any) => { + try { + // 循环调用接口为每个服务名称创建记录 + for (const service of values.services || []) { + await Apis.Common.ConvenienceServices.Store({ + type: values.type, + name: service.name, + content: service.content, + asset_projects_id: props.item?.id, + } as any); + } + props.reload?.(); + message.success('添加便民服务成功'); + return true; + } catch (error) { + message.error('添加便民服务失败'); + return false; + } + }} + columns={[ + MyFormItems.EnumRadio({ + key: 'type', + title: '类型', + colProps: { span: 24 }, + valueEnum: ConvenienceServicesTypeEnum, + required: true, + }), + { + valueType: 'formList', + dataIndex: 'services', + colProps: { span: 24 }, + title: '服务列表(可以一次性添加同一类型下的多个服务)', + formItemProps: { ...rulesHelper.array }, + initialValue: [ + { + name: null, + content: [ + { + name: null, + phone: null, + }, + ], + }, + ], + fieldProps: { + actionRef: actionRef, + copyIconProps: false, + creatorButtonProps: { + creatorButtonText: '添加主服务', + style: { + backgroundColor: '#1890FF', + // borderColor: '#00000', + borderStyle: 'solid', + // borderWidth: '2px', + color: '#FFFFFF', + marginTop: '10px', + }, + }, + }, + columns: [ + { + valueType: 'group', + colProps: { span: 24 }, + fieldProps: { + style: { + border: '1px solid #d9d9d9', + borderRadius: '8px', + padding: '20px', + marginBottom: '10px', + }, + }, + columns: [ + { + key: 'name', + colProps: { span: 24 }, + formItemProps: { ...rulesHelper.text }, + fieldProps: { + addonBefore: '主服务名称', + }, + }, + { + valueType: 'formList', + dataIndex: 'content', + title: '主服务名称', + formItemProps: { + ...rulesHelper.array, + style: { + borderRadius: '6px', + marginBottom: 0, + }, + }, + initialValue: [ + { + name: null, + phone: null, + }, + ], + fieldProps: { + copyIconProps: false, + creatorButtonProps: { + creatorButtonText: '添加子服务', + style: { + color: '#1890FF', + }, + }, + }, + columns: [ + { + valueType: 'group', + colProps: { span: 24 }, + columns: [ + { + key: 'name', + colProps: { span: 12 }, + fieldProps: { + addonBefore: '子服务名称', + }, + formItemProps: { ...rulesHelper.text }, + }, + { + key: 'phone', + colProps: { span: 12 }, + fieldProps: { + addonBefore: '联系电话', + }, + formItemProps: { ...rulesHelper.text }, + }, + ], + }, + ], + }, + ], + }, + ], + }, + ]} + /> + ); +} diff --git a/src/pages/asset/components/modals/ServiceUpdate.tsx b/src/pages/asset/components/modals/ServiceUpdate.tsx new file mode 100644 index 0000000..3980689 --- /dev/null +++ b/src/pages/asset/components/modals/ServiceUpdate.tsx @@ -0,0 +1,115 @@ +import { + MyBetaModalFormProps, + MyButtons, + MyFormItems, + MyModalFormProps, + rulesHelper, +} from '@/common'; +import { Apis } from '@/gen/Apis'; +import { ConvenienceServicesTypeEnum } from '@/gen/Enums'; +import { BetaSchemaForm } from '@ant-design/pro-components'; +import { Form, message } from 'antd'; +import { useRef } from 'react'; + +export default function Update(props: MyBetaModalFormProps) { + const [form] = Form.useForm(); + const actionRef = useRef(); + + return ( + + {...MyModalFormProps.props} + title={`编辑便民服务`} + trigger={} + wrapperCol={{ span: 24 }} + width="600px" + key={new Date().getTime()} + form={form} + onOpenChange={(open: any) => { + if (open && props.item) { + form.setFieldsValue(props.item); + } + }} + onFinish={async (values: any) => + Apis.Common.ConvenienceServices.Update({ + ...values, + id: props.item?.id ?? 0, + asset_projects_id: props.item?.asset_projects_id ?? 0, + }) + .then(() => { + props.reload?.(); + message.success('编辑便民服务成功'); + return true; + }) + .catch(() => false) + } + columns={[ + MyFormItems.EnumRadio({ + key: 'type', + title: '类型', + colProps: { span: 24 }, + valueEnum: ConvenienceServicesTypeEnum, + required: true, + }), + { + key: 'name', + title: '主服务名称', + colProps: { span: 24 }, + fieldProps: { + addonBefore: '主服务名称', + }, + formItemProps: { ...rulesHelper.text }, + }, + { + valueType: 'formList', + dataIndex: 'content', + formItemProps: { + ...rulesHelper.array, + style: { + borderRadius: '6px', + marginBottom: 0, + }, + }, + initialValue: [ + { + name: null, + phone: null, + }, + ], + fieldProps: { + copyIconProps: false, + creatorButtonProps: { + creatorButtonText: '添加主服务', + style: { + marginTop: '8px', + }, + }, + }, + columns: [ + { + valueType: 'group', + colProps: { span: 24 }, + columns: [ + { + key: 'name', + colProps: { span: 12 }, + fieldProps: { + addonBefore: '子服务名称', + }, + formItemProps: { ...rulesHelper.text }, + }, + { + key: 'phone', + colProps: { span: 12 }, + fieldProps: { + addonBefore: '联系电话', + }, + formItemProps: { ...rulesHelper.text }, + }, + ], + }, + ], + }, + ]} + /> + ); +} diff --git a/src/pages/asset/index.tsx b/src/pages/asset/index.tsx index c36d0c1..54d8d53 100644 --- a/src/pages/asset/index.tsx +++ b/src/pages/asset/index.tsx @@ -83,6 +83,11 @@ export default function Index({ title = '项目列表' }) { onSoftDelete: Apis.Asset.AssetProjects.SoftDelete, search: false, }), + { + title: '物业品牌', + dataIndex: ['company_property_brand', 'name'], + search: false, + }, { title: '绑定机构', dataIndex: ['company', 'name'], diff --git a/src/pages/asset/modals/AssetCreate.tsx b/src/pages/asset/modals/AssetCreate.tsx index f65644a..9da77dc 100644 --- a/src/pages/asset/modals/AssetCreate.tsx +++ b/src/pages/asset/modals/AssetCreate.tsx @@ -37,7 +37,7 @@ export default function Create(props: MyBetaModalFormProps) { }); } }} - onFinish={async (values) => + onFinish={async (values: any) => Apis.Asset.AssetProjects.Store({ ...values, longitude: values?.location ? values.location.split(',')[0] : '', @@ -65,9 +65,29 @@ export default function Create(props: MyBetaModalFormProps) { Selects?.Companies({ key: 'companies_id', title: '所属机构', - colProps: { span: 24 }, + colProps: { span: 12 }, formItemProps: { ...rulesHelper.number }, }), + { + valueType: 'dependency', + name: ['companies_id'], + columns: ({ companies_id }) => { + return [ + Selects?.PropertyBrands({ + title: '选择物业品牌', + key: 'company_property_brands_id', + params: { + companies_id: companies_id, + }, + colProps: { span: 12 }, + formItemProps: { ...rulesHelper.text }, + fieldProps: { + showSearch: true, + }, + }), + ]; + }, + }, Address.Cascader({ key: 'casacader', title: '选择地址', diff --git a/src/pages/asset/modals/AssetUpdate.tsx b/src/pages/asset/modals/AssetUpdate.tsx index 002ab97..841ff17 100644 --- a/src/pages/asset/modals/AssetUpdate.tsx +++ b/src/pages/asset/modals/AssetUpdate.tsx @@ -6,6 +6,7 @@ import { rulesHelper, } from '@/common'; import { Address } from '@/components/Address'; +import { Selects } from '@/components/Select'; import { Apis } from '@/gen/Apis'; import { AssetProjectsChargeEnum, @@ -30,16 +31,20 @@ export default function Update(props: MyBetaModalFormProps) { form={form} onOpenChange={(open: any, props: any) => { if (open && props.item) { - form.setFieldsValue(props.item); - form.setFieldValue( - 'location', - `${props.item?.longitude},${props.item?.latitude}`, - ); + form.setFieldsValue({ + companies_id: props.item?.companies_id, + location: `${props.item?.longitude || ''},${ + props.item?.latitude || '' + }`, + }); } }} request={() => Promise.resolve({ ...props.item, + location: `${props.item?.longitude || ''},${ + props.item?.latitude || '' + }`, casacader: [ props.item?.province_id || '', props.item?.city_id || '', @@ -48,7 +53,7 @@ export default function Update(props: MyBetaModalFormProps) { ], }) } - onFinish={async (values) => + onFinish={async (values: any) => Apis.Asset.AssetProjects.Update({ ...values, id: props.item?.id ?? 0, @@ -80,6 +85,18 @@ export default function Update(props: MyBetaModalFormProps) { // colProps: { span: 24 }, // formItemProps: { ...rulesHelper.number }, // }), + Selects?.PropertyBrands({ + title: '选择物业品牌', + key: 'company_property_brands_id', + params: { + companies_id: props.item?.companies_id, + }, + colProps: { span: 24 }, + formItemProps: { ...rulesHelper.text }, + fieldProps: { + showSearch: true, + }, + }), Address.Cascader({ key: 'casacader', title: '选择地址', diff --git a/src/pages/bills/index.tsx b/src/pages/bills/index.tsx index c223188..f8554c1 100644 --- a/src/pages/bills/index.tsx +++ b/src/pages/bills/index.tsx @@ -13,7 +13,7 @@ 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', diff --git a/src/pages/company/$id.tsx b/src/pages/company/$id.tsx index 52d8e52..34f2b04 100644 --- a/src/pages/company/$id.tsx +++ b/src/pages/company/$id.tsx @@ -11,6 +11,7 @@ import ComponentsInfo from './components/ComponentsInfo'; import Employees from './components/Employees'; import Organizations from './components/Organizations'; import Positions from './components/Positions'; +import PropertyBrands from './components/PropertyBrands'; import ReceiptAccounts from './components/ReceiptAccounts'; import CompanyUpdate from './modals/CompanyUpdate'; @@ -42,12 +43,19 @@ export default function Show({ title }: { title?: string } = {}) { }, [id]); let items = [ + { + label: '0-品牌配置', + key: '0', + closable: false, + children: , + }, { label: '1-项目配置', key: '1', closable: false, children: , }, + { label: '2-组织配置', key: '2', diff --git a/src/pages/company/components/PropertyBrands.tsx b/src/pages/company/components/PropertyBrands.tsx new file mode 100644 index 0000000..3fd1192 --- /dev/null +++ b/src/pages/company/components/PropertyBrands.tsx @@ -0,0 +1,80 @@ +import { + MyBetaModalFormProps, + MyButtons, + MyColumns, + MyProTableProps, +} from '@/common'; +import { Apis } from '@/gen/Apis'; +import { ProTable } from '@ant-design/pro-components'; +import { Image, Space } from 'antd'; +import PropertyBrandsCreate from './modals/PropertyBrandsCreate'; +import PropertyBrandUpdate from './modals/PropertyBrandUpdate'; + +export default function PropertyBrands(props: MyBetaModalFormProps) { + return ( + <> + + MyProTableProps.request( + { ...params, companies_id: props?.item?.id }, + sort, + Apis.Company.CompanyPropertyBrands.List, + ) + } + toolBarRender={(action) => [ + , + ]} + // search={false} + // options={false} + columns={[ + MyColumns.ID(), + + { + title: '物业名称', + dataIndex: 'name', + }, + { + title: 'logo', + render: (_, item) => { + return ( + + {item?.logo?.[0] && ( + + )} + + ); + }, + }, + MyColumns.Option({ + render: (_, item: any, index, action) => ( + + + + Apis.Company.CompanyPropertyBrands.Delete({ + id: item.id, + }).then(() => action?.reload()) + } + /> + + ), + }), + ]} + /> + + ); +} diff --git a/src/pages/company/components/modals/PropertyBrandUpdate.tsx b/src/pages/company/components/modals/PropertyBrandUpdate.tsx new file mode 100644 index 0000000..22f3474 --- /dev/null +++ b/src/pages/company/components/modals/PropertyBrandUpdate.tsx @@ -0,0 +1,62 @@ +import { + MyBetaModalFormProps, + MyButtons, + MyFormItems, + MyModalFormProps, + rulesHelper, +} from '@/common'; + +import { Apis } from '@/gen/Apis'; +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={} + wrapperCol={{ span: 24 }} + width="300px" + form={form} + key={new Date().getTime()} + onOpenChange={(open: any) => { + if (open && props.item) { + form.setFieldsValue(props.item); + } + }} + onFinish={async (values) => + Apis.Company.CompanyPropertyBrands.Update({ + ...values, + companies_id: props?.item?.companies_id, + id: props.item?.id ?? 0, + }) + .then(() => { + props.reload?.(); + message.success(props.title + '成功'); + return true; + }) + .catch(() => false) + } + columns={[ + { + key: 'name', + title: '品牌名称', + colProps: { span: 24 }, + formItemProps: { ...rulesHelper.text }, + }, + MyFormItems.UploadImages({ + key: 'logo', + title: '品牌logo【尺寸:1024*1024】', + tooltip: '只能上传1张图片', + max: 1, + colProps: { span: 24 }, + formItemProps: { required: false }, + fieldProps: { + placeholder: '', + }, + }), + ]} + /> + ); +} diff --git a/src/pages/company/components/modals/PropertyBrandsCreate.tsx b/src/pages/company/components/modals/PropertyBrandsCreate.tsx new file mode 100644 index 0000000..12189c5 --- /dev/null +++ b/src/pages/company/components/modals/PropertyBrandsCreate.tsx @@ -0,0 +1,61 @@ +import { + MyBetaModalFormProps, + MyButtons, + MyFormItems, + MyModalFormProps, + rulesHelper, +} from '@/common'; +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={`添加品牌`} + wrapperCol={{ span: 24 }} + width="300px" + trigger={} + form={form} + onOpenChange={(open: any) => { + if (open) { + form.resetFields(); // 清空表单数据 + } + }} + onFinish={async (values) => + Apis.Company.CompanyPropertyBrands.Store({ + ...values, + companies_id: props?.item?.id, + }) + .then(() => { + props.reload?.(); + message.success(props.title + '成功'); + return true; + }) + .catch(() => false) + } + columns={[ + { + key: 'name', + title: '品牌名称', + colProps: { span: 24 }, + formItemProps: { ...rulesHelper.text }, + }, + MyFormItems.UploadImages({ + key: 'logo', + title: '品牌logo【尺寸:1024*1024】', + tooltip: '只能上传1张图片', + max: 1, + colProps: { span: 24 }, + formItemProps: { required: false }, + fieldProps: { + placeholder: '', + }, + }), + ]} + /> + ); +} diff --git a/src/pages/examine/house_registers_audit/index.tsx b/src/pages/examine/house_registers_audit/index.tsx index 8d3c86e..5cfd5fc 100644 --- a/src/pages/examine/house_registers_audit/index.tsx +++ b/src/pages/examine/house_registers_audit/index.tsx @@ -22,7 +22,7 @@ export default function Index({ title = '登记审核' }) { {...MyProTableProps.props} request={async (params, sort) => MyProTableProps.request( - { status: 'Pending', ...params }, + params, sort, Apis.Archive.HouseRegisters.List, ) diff --git a/src/pages/charge_standard/$id.tsx b/src/pages/house_charge_standard/$id.tsx similarity index 91% rename from src/pages/charge_standard/$id.tsx rename to src/pages/house_charge_standard/$id.tsx index ea63d30..6dc1caf 100644 --- a/src/pages/charge_standard/$id.tsx +++ b/src/pages/house_charge_standard/$id.tsx @@ -14,7 +14,7 @@ export default function Show({ title }: { title?: string } = {}) { // 注册当前页面为标签页 const { addTab } = usePageTabs({ tabKey: `charge-standard-${id}`, - tabLabel: '收费标准详情', + tabLabel: data?.name || title || '收费标准详情', }); const loadShow = () => { @@ -35,7 +35,7 @@ export default function Show({ title }: { title?: string } = {}) { closable: false, children: ( loadShow()} /> ), diff --git a/src/pages/charge_standard/components/ChargeInfo.tsx b/src/pages/house_charge_standard/components/ChargeInfo.tsx similarity index 100% rename from src/pages/charge_standard/components/ChargeInfo.tsx rename to src/pages/house_charge_standard/components/ChargeInfo.tsx diff --git a/src/pages/charge_standard/components/HasHouse.tsx b/src/pages/house_charge_standard/components/HasHouse.tsx similarity index 84% rename from src/pages/charge_standard/components/HasHouse.tsx rename to src/pages/house_charge_standard/components/HasHouse.tsx index 234c1e5..7c7c7dd 100644 --- a/src/pages/charge_standard/components/HasHouse.tsx +++ b/src/pages/house_charge_standard/components/HasHouse.tsx @@ -1,6 +1,6 @@ import { MyButtons, MyColumns, MyProTableProps } from '@/common'; import { Apis } from '@/gen/Apis'; -import BannerCreate from '@/pages/banner/modals/BannerCreate'; +import ChargeStandardHasHouse from '@/pages/asset/components/modals/ChargeStandardHasHouse'; import { ProTable } from '@ant-design/pro-components'; import { Space } from 'antd'; import { useEffect, useRef } from 'react'; @@ -20,21 +20,17 @@ export default function Index({ ...rest }) { MyProTableProps.request( { ...params, - house_charge_standards_id: rest.item?.id, + house_charge_standards_id: rest.item?.house_charge_has_houses_id, }, sort, Apis.HouseCharage.HouseChargeHasHouses.List, ) } toolBarRender={(action) => [ - , ]} search={false} @@ -69,7 +65,7 @@ export default function Index({ ...rest }) { MyColumns.Option({ render: (_, item: any, index, action) => ( - Apis.HouseCharage.HouseChargeHasHouses.Delete({ id: item.id, diff --git a/src/pages/charge_standard/index.tsx b/src/pages/house_charge_standard/index.tsx similarity index 96% rename from src/pages/charge_standard/index.tsx rename to src/pages/house_charge_standard/index.tsx index b3e5ddd..86edfa2 100644 --- a/src/pages/charge_standard/index.tsx +++ b/src/pages/house_charge_standard/index.tsx @@ -104,7 +104,6 @@ export default function Index({ title = '收费标准' }) { return `${record?.is_apportionment ? '是' : '否'} `; }, }, - // MyColumns.UpdatedAt(), // MyColumns.CreatedAt(), MyColumns.Option({ @@ -113,7 +112,7 @@ export default function Index({ title = '收费标准' }) { { - navigate(`/charge_standard/${item.id}`); + navigate(`/house_charge_standard/${item.id}`); }} /> diff --git a/src/pages/charge_standard/modals/ChargeCreate.tsx b/src/pages/house_charge_standard/modals/ChargeCreate.tsx similarity index 99% rename from src/pages/charge_standard/modals/ChargeCreate.tsx rename to src/pages/house_charge_standard/modals/ChargeCreate.tsx index 19a8699..3bccee1 100644 --- a/src/pages/charge_standard/modals/ChargeCreate.tsx +++ b/src/pages/house_charge_standard/modals/ChargeCreate.tsx @@ -44,7 +44,6 @@ export default function Create(props: MyBetaModalFormProps) { }); return Apis.HouseCharage.HouseChargeStandards.Store({ ...values, - asset_projects_id: props?.item?.id, type: values.charge_type === HouseBillsTypeEnum.SharedWaterFee.value || values.charge_type === HouseBillsTypeEnum.SharedElectricityFee.value diff --git a/src/pages/house_charge_tasks/index.tsx b/src/pages/house_charge_tasks/index.tsx new file mode 100644 index 0000000..b118dad --- /dev/null +++ b/src/pages/house_charge_tasks/index.tsx @@ -0,0 +1,115 @@ +import { + MyButtons, + MyColumns, + MyPageContainer, + MyProTableProps, + usePageTabs, +} from '@/common'; +import { Apis } from '@/gen/Apis'; +import { + HouseChargeTasksStatusEnum, + HouseChargeTasksTypeEnum, +} 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: 'charge_tasks', + tabLabel: title, + }); + + return ( + + + MyProTableProps.request( + params, + sort, + Apis.HouseCharage.HouseChargeTasks.List, + ) + } + toolBarRender={(action) => [ + , + ]} + columns={[ + MyColumns.ID(), + MyColumns.EnumTag({ + title: '任务状态', + dataIndex: 'status', + valueEnum: HouseChargeTasksStatusEnum, + }), + MyColumns.EnumTag({ + title: '创建类型', + dataIndex: 'type', + valueEnum: HouseChargeTasksTypeEnum, + }), + { + title: '收费标准名称', + dataIndex: 'charge_standard_name', + search: false, + }, + { + title: '账单月份', + render: (_, record) => { + return `${record.year}-${String(record.month).padStart(2, '0')}`; + }, + }, + { + title: '计费开始日期', + dataIndex: 'start_date', + search: false, + }, + { + title: '计费结束日期', + dataIndex: 'end_date', + search: false, + }, + { + title: '项目名称', + dataIndex: 'project_name', + search: false, + }, + { + title: '机构名称', + dataIndex: 'company_name', + search: false, + }, + MyColumns.SoftDelete({ + title: '启/禁用', + onRestore: Apis.HouseCharage.HouseChargeTasks.Restore, + onSoftDelete: Apis.HouseCharage.HouseChargeTasks.SoftDelete, + search: false, + }), + MyColumns.UpdatedAt(), + MyColumns.CreatedAt(), + MyColumns.Option({ + render: (_, item: any, index, action) => ( + + + Apis.HouseCharage.HouseChargeTasks.Delete({ + id: item.id, + }).then(() => action?.reload()) + } + /> + + ), + }), + ]} + /> + + ); +} diff --git a/src/pages/house_charge_tasks/modals/ChargeTasksCreate.tsx b/src/pages/house_charge_tasks/modals/ChargeTasksCreate.tsx new file mode 100644 index 0000000..199fa3b --- /dev/null +++ b/src/pages/house_charge_tasks/modals/ChargeTasksCreate.tsx @@ -0,0 +1,109 @@ +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 }, + }), + { + 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/work_order/modals/WorkOrderCreate.tsx b/src/pages/work_order/modals/WorkOrderCreate.tsx index e45d8b2..9ed2e72 100644 --- a/src/pages/work_order/modals/WorkOrderCreate.tsx +++ b/src/pages/work_order/modals/WorkOrderCreate.tsx @@ -7,7 +7,11 @@ import { } from '@/common'; import { Selects } from '@/components/Select'; import { Apis } from '@/gen/Apis'; -import { HouseWorkOrdersLevelEnum, HouseWorkOrdersTypeEnum } from '@/gen/Enums'; +import { + HouseWorkOrdersLevelEnum, + HouseWorkOrdersLocationEnum, + HouseWorkOrdersTypeEnum, +} from '@/gen/Enums'; import { BetaSchemaForm } from '@ant-design/pro-components'; import { Form, message } from 'antd'; @@ -40,17 +44,100 @@ export default function WorkOrderCreate(props: MyBetaModalFormProps) { MyFormItems.EnumRadio({ key: 'type', title: '工单类型', - colProps: { span: 24 }, + colProps: { span: 12 }, valueEnum: HouseWorkOrdersTypeEnum, required: true, }), - - // { - // key: 'title', - // title: '工单标题', - // colProps: { span: 18 }, - // formItemProps: { ...rulesHelper.text }, - // }, + MyFormItems.EnumRadio({ + key: 'level', + title: '优先级', + colProps: { span: 12 }, + valueEnum: HouseWorkOrdersLevelEnum, + required: true, + }), + MyFormItems.EnumRadio({ + key: 'location', + title: '报修位置', + colProps: { span: 24 }, + valueEnum: HouseWorkOrdersLocationEnum, + required: true, + }), + { + name: ['location'], + valueType: 'dependency', + columns: ({ location }: any) => { + return location === HouseWorkOrdersLocationEnum.MyHome.value + ? [ + { + valueType: 'dependency', + name: [ + 'asset_projects_id', + 'asset_buildings_id', + 'asset_units_id', + ], + columns: ({ + asset_projects_id, + asset_buildings_id, + asset_units_id, + }) => { + return [ + { + valueType: 'group', + columns: [ + Selects?.AssetProjects({ + title: '依次选择项目', + key: 'asset_projects_id', + colProps: { span: 6 }, + formItemProps: { ...rulesHelper.text }, + }), + Selects?.AssetBuildings({ + key: 'asset_buildings_id', + title: '楼栋', + params: { + asset_projects_id: asset_projects_id, + }, + colProps: { span: 6 }, + formItemProps: { ...rulesHelper.number }, + fieldProps: { + showSearch: true, + onChange: () => { + form.setFieldsValue({ + asset_units_id: undefined, + asset_floors_id: undefined, + }); + }, + }, + }), + Selects?.AssetUnits({ + key: 'asset_units_id', + title: '单元', + params: { + asset_projects_id: asset_projects_id, + asset_buildings_id: asset_buildings_id, + }, + colProps: { span: 6 }, + formItemProps: { ...rulesHelper.number }, + }), + Selects?.AssetHouses({ + title: '房屋', + key: 'asset_houses_id', + params: { + asset_projects_id: asset_projects_id, + asset_buildings_id: asset_buildings_id, + asset_units_id: asset_units_id, + }, + formItemProps: { ...rulesHelper.text }, + colProps: { span: 6 }, + }), + ], + }, + ]; + }, + }, + ] + : []; + }, + }, { key: 'content', title: '工单描述', @@ -61,99 +148,32 @@ export default function WorkOrderCreate(props: MyBetaModalFormProps) { placeholder: '请详细描述工单内容', }, }, - MyFormItems.EnumRadio({ - key: 'level', - title: '优先级', - colProps: { span: 24 }, - valueEnum: HouseWorkOrdersLevelEnum, - required: true, - }), - { - valueType: 'dependency', - name: ['asset_projects_id', 'asset_buildings_id', 'asset_units_id'], - columns: ({ - asset_projects_id, - asset_buildings_id, - asset_units_id, - }) => { - return [ - { - valueType: 'group', - columns: [ - Selects?.AssetProjects({ - title: '依次选择项目', - key: 'asset_projects_id', - colProps: { span: 6 }, - formItemProps: { ...rulesHelper.text }, - }), - Selects?.AssetBuildings({ - key: 'asset_buildings_id', - title: '楼栋', - params: { - asset_projects_id: asset_projects_id, - }, - colProps: { span: 6 }, - formItemProps: { ...rulesHelper.number }, - fieldProps: { - showSearch: true, - onChange: () => { - form.setFieldsValue({ - asset_units_id: undefined, - asset_floors_id: undefined, - }); - }, - }, - }), - Selects?.AssetUnits({ - key: 'asset_units_id', - title: '单元', - params: { - asset_projects_id: asset_projects_id, - asset_buildings_id: asset_buildings_id, - }, - colProps: { span: 6 }, - formItemProps: { ...rulesHelper.number }, - }), - Selects?.AssetHouses({ - title: '房屋', - key: 'asset_houses_id', - params: { - asset_projects_id: asset_projects_id, - asset_buildings_id: asset_buildings_id, - asset_units_id: asset_units_id, - }, - formItemProps: { ...rulesHelper.text }, - colProps: { span: 6 }, - }), - ], - }, - ]; - }, - }, + MyFormItems.UploadImages({ key: 'attachments', title: '相关图片', - uploadType: 'file', + tooltip: '最多上传5张图片', + // uploadType: 'file', max: 5, colProps: { span: 24 }, formItemProps: { required: false }, }), - { - key: 'reporter_name', - title: '上报人姓名', - colProps: { span: 12 }, - }, - { - key: 'reporter_phone', - title: '上报人手机', - // formItemProps: { ...rulesHelper.phone }, - colProps: { span: 12 }, - fieldProps: { - placeholder: '请输入手机号码', - maxLength: 11, - minLength: 11, - }, - }, + // { + // key: 'reporter_name', + // title: '上报人姓名', + // colProps: { span: 12 }, + // }, + // { + // key: 'reporter_phone', + // title: '上报人手机', + // // formItemProps: { ...rulesHelper.phone }, + // colProps: { span: 12 }, + // fieldProps: { + // placeholder: '请输入手机号码', + // maxLength: 11, + // minLength: 11, + // }, + // }, ]} /> );