Merge pull request 'develop' (#2) from develop into main
All checks were successful
Build and Push Docker Image / build (push) Successful in 3m10s

Reviewed-on: https://code.juyouwu.cn/pay/pay-admin/pulls/2
This commit is contained in:
uiujun 2025-09-08 17:38:34 +08:00
commit 6dfd361fc5
38 changed files with 1931 additions and 904 deletions

View File

@ -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,
},
};
},
};

107
src/gen/ApiTypes.d.ts vendored
View File

@ -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

View File

@ -19,6 +19,12 @@ export const Apis = {
ChangeIsContact(data: ApiTypes.Archive.HouseOccupants.ChangeIsContact): Promise<MyResponseType> {
return request('admin/archive/house_occupants/change_is_contact', { data });
},
Import(data?: ApiTypes.Archive.HouseOccupants.Import): Promise<MyResponseType> {
return request('admin/archive/house_occupants/import', { data });
},
DownloadTemplate(): Promise<MyResponseType> {
return request('admin/archive/house_occupants/download_template', {responseType: 'blob',});
},
},
HouseRegisters: {
List(data?: ApiTypes.Archive.HouseRegisters.List): Promise<MyResponseType> {
@ -119,6 +125,9 @@ export const Apis = {
BindCompany(data: ApiTypes.Asset.AssetProjects.BindCompany): Promise<MyResponseType> {
return request('admin/asset/asset_projects/bind_company', { data });
},
ChangePropertyBrand(data: ApiTypes.Asset.AssetProjects.ChangePropertyBrand): Promise<MyResponseType> {
return request('admin/asset/asset_projects/change_property_brand', { data });
},
Show(data: ApiTypes.Asset.AssetProjects.Show): Promise<MyResponseType> {
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<MyResponseType> {
return request('admin/company/company_property_brands/list', { data });
},
Store(data: ApiTypes.Company.CompanyPropertyBrands.Store): Promise<MyResponseType> {
return request('admin/company/company_property_brands/store', { data });
},
Update(data: ApiTypes.Company.CompanyPropertyBrands.Update): Promise<MyResponseType> {
return request('admin/company/company_property_brands/update', { data });
},
Show(data: ApiTypes.Company.CompanyPropertyBrands.Show): Promise<MyResponseType> {
return request('admin/company/company_property_brands/show', { data });
},
Delete(data: ApiTypes.Company.CompanyPropertyBrands.Delete): Promise<MyResponseType> {
return request('admin/company/company_property_brands/delete', { data });
},
Select(data?: ApiTypes.Company.CompanyPropertyBrands.Select): Promise<MyResponseType> {
return request('admin/company/company_property_brands/select', { data });
},
},
CompanyReceiptAccounts: {
List(data?: ApiTypes.Company.CompanyReceiptAccounts.List): Promise<MyResponseType> {
return request('admin/company/company_receipt_accounts/list', { data });
@ -552,6 +581,40 @@ export const Apis = {
Delete(data: ApiTypes.HouseCharage.HouseChargeStandards.Delete): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_standards/delete', { data });
},
Select(data?: ApiTypes.HouseCharage.HouseChargeStandards.Select): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_standards/select', { data });
},
},
HouseChargeTaskDetails: {
List(data?: ApiTypes.HouseCharage.HouseChargeTaskDetails.List): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_task_details/list', { data });
},
Show(data: ApiTypes.HouseCharage.HouseChargeTaskDetails.Show): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_task_details/show', { data });
},
Delete(data: ApiTypes.HouseCharage.HouseChargeTaskDetails.Delete): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_task_details/delete', { data });
},
},
HouseChargeTasks: {
List(data?: ApiTypes.HouseCharage.HouseChargeTasks.List): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_tasks/list', { data });
},
Store(data: ApiTypes.HouseCharage.HouseChargeTasks.Store): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_tasks/store', { data });
},
Show(data: ApiTypes.HouseCharage.HouseChargeTasks.Show): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_tasks/show', { data });
},
SoftDelete(data: ApiTypes.HouseCharage.HouseChargeTasks.SoftDelete): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_tasks/soft_delete', { data });
},
Restore(data: ApiTypes.HouseCharage.HouseChargeTasks.Restore): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_tasks/restore', { data });
},
Delete(data: ApiTypes.HouseCharage.HouseChargeTasks.Delete): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_tasks/delete', { data });
},
},
},
HouseOrder: {

View File

@ -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

View File

@ -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: '排序',

View File

@ -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) => [
<MyImportModal
key="ImportHouse"
title="批量导入"
type="danger"
size="middle"
templateApi={Apis.Archive.HouseOccupants.DownloadTemplate}
importApi={Apis.Archive.HouseOccupants.Import}
reload={action?.reload}
/>,
]}
columns={[
MyColumns.ID(),
{

View File

@ -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: <AssetAccounts item={data} />,
},
// {
// label: '车位管理',
// key: 'carport',
// closable: false,
// children: <MyAssetBuildings item={data} />,
// },
{
label: '项目公告',
key: 'announcement',
closable: false,
children: <Announcement item={data} />,
},
{
label: '便民服务',
key: 'convenience_services',
closable: false,
children: <ConvenienceServices item={data} />,
},
];
return (
<MyPageContainer title={data?.name || title || '项目详情'}>

View File

@ -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<any>();
useEffect(() => {
actionLooks?.current.reloadAndRest();
}, [rest.loadmore]);
return (
<>
<ProTable<Record<any, any>>
{...MyProTableProps.props}
actionRef={actionLooks}
request={async (params, sort) =>
MyProTableProps.request(
{ ...params, asset_projects_id: rest.item?.id },
sort,
Apis.Msg.MsgPropertyAnnouncements.List,
)
}
toolBarRender={(action) => [
<AnnouncementCreate
key="Create"
item={rest.item}
reload={action?.reload}
/>,
]}
search={false}
columns={[
MyColumns.ID(),
{
title: '公告标题',
dataIndex: 'title',
width: 120, // 关键:固定列宽(若父容器过窄,可设 minWidth: 200 优先保证列宽)
render: (text) => (
<div
style={{
width: '100%', // 继承列宽
// height: '60px', // 设置固定高度约显示3行文本
overflow: 'hidden', // 超出隐藏
textOverflow: 'ellipsis', // 省略号
display: '-webkit-box',
WebkitBoxOrient: 'vertical',
WebkitLineClamp: 1, // 显示3行
}}
>
{text}
</div>
),
},
{
title: '公告内容',
dataIndex: 'content',
valueType: 'textarea', // 仅影响表单编辑时的输入类型,不影响表格展示
search: false,
width: 200, // 关键:固定列宽(若父容器过窄,可设 minWidth: 200 优先保证列宽)
render: (text) => (
<div
style={{
width: '100%', // 继承列宽
// height: '60px', // 设置固定高度约显示3行文本
overflow: 'hidden', // 超出隐藏
textOverflow: 'ellipsis', // 省略号
display: '-webkit-box',
WebkitBoxOrient: 'vertical',
WebkitLineClamp: 2, // 显示3行
}}
>
{text}
</div>
),
},
{
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) => (
<Space key={index}>
<AnnouncementShow item={item} />
<AnnouncementUpdate
item={item}
reload={action?.reload}
// title={title}
/>
<MyButtons.Delete
onConfirm={() =>
Apis.Msg.MsgPropertyAnnouncements.Delete({
id: item.id,
}).then(() => action?.reload())
}
/>
</Space>
),
}),
]}
/>
</>
);
}

View File

@ -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="编辑"
/>
<ChargeStandardHasHouse
item={{
...item,
asset_projects_id: props?.item?.id, // 使用项目ID
size: 'small',
}}
item={item}
reload={action?.reload}
title={'绑'}
title={'绑房'}
/>
<MyButtons.Delete
onConfirm={() =>

View File

@ -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<any>();
useEffect(() => {
actionLooks?.current.reloadAndRest();
}, [rest.loadmore]);
return (
<>
<ProTable<Record<any, any>>
{...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) => [
<ServiceCreate
item={rest.item}
key="Create"
reload={action?.reload}
/>,
]}
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 (
<div style={{ lineHeight: '1.6' }}>
{validItems.length > 0 ? (
validItems.map((item: any, index: number) => (
// 每个客户信息单独一行
<div key={index}>
{item.name}: {item.phone}
</div>
))
) : (
<span></span>
)}
</div>
);
},
search: false,
},
MyColumns.Option({
render: (_, item: any, index, action) => (
<Space key={index}>
<ServiceUpdate item={item} reload={action?.reload} />
<MyButtons.Delete
onConfirm={() =>
Apis.Common.ConvenienceServices.Delete({
id: item.id,
}).then(() => action?.reload())
}
/>
</Space>
),
}),
]}
/>
</>
);
}

View File

@ -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 (
<BetaSchemaForm<ApiTypes.Msg.MsgPropertyAnnouncements.Store>
{...MyModalFormProps.props}
title={`添加公告`}
wrapperCol={{ span: 24 }}
width="600px"
trigger={<MyButtons.Create title={`添加公告`} />}
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,
},
]}
/>
);
}

View File

@ -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 (
<MyModal
title={props.title || '查看'}
// width="40vw"
width={600}
// style={{ maxWidth: '650px' }}
node={
<ProCard>
<ProDescriptions
// bordered
// column={{ xs: 1, sm: 2, md: 3 }}
column={1}
size="small"
>
<ProDescriptions.Item label=" 关联项目">
{props?.item?.asset_project?.name || '-'}
</ProDescriptions.Item>
<ProDescriptions.Item label="公告标题">
{props?.item?.title || '-'}
</ProDescriptions.Item>
<ProDescriptions.Item label="公告内容">
<div
style={{
whiteSpace: 'pre-wrap',
maxHeight: '300px',
overflow: 'auto',
}}
>
{props?.item?.content || '-'}
</div>
</ProDescriptions.Item>
<ProDescriptions.Item label="发布日期">
{props?.item?.publish_at || '-'}
</ProDescriptions.Item>
<ProDescriptions.Item label="创建时间">
{props?.item?.created_at || '-'}
</ProDescriptions.Item>
<ProDescriptions.Item label="是否发布小程序">
{props?.item?.is_publish ? '是' : '否'}
</ProDescriptions.Item>
</ProDescriptions>
</ProCard>
}
/>
);
}

View File

@ -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 (
<BetaSchemaForm<ApiTypes.Msg.MsgPropertyAnnouncements.Update>
{...MyModalFormProps.props}
title={`编辑公告内容`}
trigger={<MyButtons.Edit />}
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,
},
]}
/>
);
}

View File

@ -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:

View File

@ -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<number[]>([]);
const [selectedRows, setSelectedRows] = useState<any[]>([]);
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<any>();
// 扩展 MyBetaModalFormProps 接口,添加 onCancel 属性
interface ChargeStandardHasHouseProps extends MyBetaModalFormProps {
onCancel?: () => void;
}
export default function ChargeStandardHasHouse(
props: ChargeStandardHasHouseProps,
) {
const [treeData, setTreeData] = useState<TreeNodeType[]>([]);
const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
const [checkedKeys, setCheckedKeys] = useState<React.Key[]>([]);
const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
const [autoExpandParent, setAutoExpandParent] = useState<boolean>(true);
const [loading, setLoading] = useState<boolean>(false);
const [selectAll, setSelectAll] = useState<boolean>(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<React.Key>();
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<string>();
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 (
<MyModal
title={props.title || '查看'}
width="800px"
myRef={modalRef}
trigger={
<MyButtons.Default
type="primary"
size="small"
title={`${props.title}`}
/>
}
type="primary"
width="920px"
node={
<ProCard
title={
<div>
<Title level={4} style={{ marginBottom: '16px' }}>
<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>
</Title>
<Alert
message="请选择需要绑定的房屋"
type="info"
showIcon
style={{ margin: 0 }}
/>
</div>
<ProTable
actionRef={tableRef}
{...MyProTableProps.props}
request={async (params, sort) =>
MyProTableProps.request(
{
...params,
asset_projects_id: props?.item?.asset_projects_id,
},
sort,
Apis.Asset.AssetHouses.List,
undefined,
(res) => {
// 确保响应数据正确处理
console.log('加载房屋数据:', res);
return res;
},
)
}
>
<div style={{ display: 'flex', height: '500px' }}>
<div
style={{
width: '50%',
borderRight: '1px solid #f0f0f0',
padding: '0 16px',
}}
>
<div style={{ marginBottom: 16 }}>
<Checkbox checked={selectAll} onChange={handleSelectAll}>
</Checkbox>
</div>
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 && <div>...</div>}
// 更新选中状态
setSelectedHousesIds(numericKeys);
<Tree
checkable
checkStrictly={false}
onExpand={onExpand}
expandedKeys={expandedKeys}
autoExpandParent={autoExpandParent}
onCheck={onCheck}
checkedKeys={checkedKeys}
onSelect={onSelect}
selectedKeys={selectedKeys}
loadData={onLoadData}
treeData={treeData}
height={400}
/>
</div>
// 合并当前页面选中的行和之前选中的行
const newSelectedRows = [...selectedRows];
<div style={{ width: '50%', padding: '0 16px' }}>
<div style={{ marginBottom: 16 }}>
<Title level={5}> ({selectedHouses.length})</Title>
</div>
// 设置选中行数据
setSelectedRows(newSelectedRows);
},
}}
tableAlertOptionRender={({ selectedRowKeys, onCleanSelected }) => {
return (
<Space>
<span> {selectedRowKeys.length} </span>
<a onClick={onCleanSelected}></a>
<MyButtons.Create
title="批量添加"
type="primary"
key="create2"
onClick={() => onShowContactPhone()}
/>
</Space>
);
}}
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',
},
<div style={{ height: 400, overflow: 'auto' }}>
{selectedHouses.length > 0 ? (
<ul style={{ padding: '0 0 0 20px' }}>
{selectedHouses.map((house) => (
<li key={house.id}>{house.name}</li>
))}
</ul>
) : (
<div
style={{
color: '#999',
textAlign: 'center',
marginTop: 100,
}}
>
{' '}
</div>
)}
</div>
</div>
</div>
{
title: '楼层',
dataIndex: 'floor',
render(_, record) {
return `${record?.floor}`;
},
search: false,
},
<div style={{ marginTop: 16, textAlign: 'right' }}>
<Space>
<Button onClick={props?.onCancel}></Button>
<Button type="primary" loading={loading} onClick={handleSubmit}>
</Button>
</Space>
</div>
</ProCard>
{
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,
}),
]}
/>
}
/>
);

View File

@ -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:

View File

@ -15,10 +15,14 @@ export default function Create(props: MyBetaModalFormProps) {
return (
<BetaSchemaForm<ApiTypes.Grid.Grids.Store>
{...MyModalFormProps.props}
title={`创建板块`}
wrapperCol={{ span: 24 }}
title={`划分范围`}
// 基本表单
width="700px"
trigger={<MyButtons.Create title={`创建板块`} />}
layout="horizontal"
labelCol={{ span: 4 }}
wrapperCol={{ span: 24 }}
labelAlign="right"
trigger={<MyButtons.Create title={`划分范围`} />}
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 (
<ProCard
bordered
style={{ marginBlockEnd: 0 }}
title={`创建板块${index + 1}`}
style={{ marginBlockEnd: 5 }}
title={`选择范围${index + 1}`}
extra={action}
bodyStyle={{ paddingBlockEnd: 0 }}
>
@ -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,
},
}),
]
: []),
],
},
];

View File

@ -16,8 +16,11 @@ export default function Update(props: MyBetaModalFormProps) {
<BetaSchemaForm<ApiTypes.Grid.Grids.Update>
{...MyModalFormProps.props}
title={`网格编辑`}
wrapperCol={{ span: 24 }}
width="700px"
layout="horizontal"
labelCol={{ span: 4 }}
wrapperCol={{ span: 24 }}
labelAlign="right"
trigger={<MyButtons.Default title={`编辑`} size="small" type="link" />}
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 (
<ProCard
bordered
style={{ marginBlockEnd: 0 }}
title={`添加单元${index + 1}`}
style={{ marginBlockEnd: 5 }}
title={`选择范围${index + 1}`}
extra={action}
bodyStyle={{ paddingBlockEnd: 0 }}
>
@ -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,
},
}),
]
: []),
],
},
];

View File

@ -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<any>();
return (
<BetaSchemaForm<ApiTypes.Common.ConvenienceServices.Store>
{...MyModalFormProps.props}
title={`添加便民服务`}
wrapperCol={{ span: 24 }}
width="600px"
trigger={<MyButtons.Create title={`添加便民服务`} />}
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 },
},
],
},
],
},
],
},
],
},
]}
/>
);
}

View File

@ -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<any>();
return (
<BetaSchemaForm<ApiTypes.Common.ConvenienceServices.Update>
{...MyModalFormProps.props}
title={`编辑便民服务`}
trigger={<MyButtons.Edit />}
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 },
},
],
},
],
},
]}
/>
);
}

View File

@ -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'],

View File

@ -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: '选择地址',

View File

@ -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: '选择地址',

View File

@ -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',

View File

@ -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: <PropertyBrands item={data} />,
},
{
label: '1-项目配置',
key: '1',
closable: false,
children: <Assets item={data} />,
},
{
label: '2-组织配置',
key: '2',

View File

@ -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 (
<>
<ProTable
{...MyProTableProps.props}
request={async (params, sort) =>
MyProTableProps.request(
{ ...params, companies_id: props?.item?.id },
sort,
Apis.Company.CompanyPropertyBrands.List,
)
}
toolBarRender={(action) => [
<PropertyBrandsCreate
key="Create"
reload={action?.reload}
item={props?.item}
title="品牌"
/>,
]}
// search={false}
// options={false}
columns={[
MyColumns.ID(),
{
title: '物业名称',
dataIndex: 'name',
},
{
title: 'logo',
render: (_, item) => {
return (
<Space>
{item?.logo?.[0] && (
<Image
height={30}
src={item?.logo[0]?.url}
placeholder="正面"
/>
)}
</Space>
);
},
},
MyColumns.Option({
render: (_, item: any, index, action) => (
<Space key={index}>
<PropertyBrandUpdate
item={{ ...item, companies_id: props?.item?.id }}
reload={action?.reload}
title="品牌"
/>
<MyButtons.Delete
onConfirm={() =>
Apis.Company.CompanyPropertyBrands.Delete({
id: item.id,
}).then(() => action?.reload())
}
/>
</Space>
),
}),
]}
/>
</>
);
}

View File

@ -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 (
<BetaSchemaForm<ApiTypes.Company.CompanyPropertyBrands.Update>
{...MyModalFormProps.props}
title={`编辑${props.title}`}
trigger={<MyButtons.Edit />}
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: '',
},
}),
]}
/>
);
}

View File

@ -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 (
<BetaSchemaForm<ApiTypes.Company.CompanyPropertyBrands.Store>
{...MyModalFormProps.props}
title={`添加品牌`}
wrapperCol={{ span: 24 }}
width="300px"
trigger={<MyButtons.Create title={`添加品牌`} />}
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: '',
},
}),
]}
/>
);
}

View File

@ -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,
)

View File

@ -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: (
<HasHouse
item={{ ...data, charge_standards_id: id }}
item={{ ...data, house_charge_has_houses_id: id }}
reload={() => loadShow()}
/>
),

View File

@ -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) => [
<BannerCreate
key="AddOccupant"
item={{
...rest.item,
banner_spaces_id: rest.item?.banner_spaces_id,
}}
<ChargeStandardHasHouse
item={rest.item}
reload={action?.reload}
title="添加住户"
title={'绑房'}
/>,
]}
search={false}
@ -69,7 +65,7 @@ export default function Index({ ...rest }) {
MyColumns.Option({
render: (_, item: any, index, action) => (
<Space key={index}>
<MyButtons.Default
<MyButtons.Delete
onConfirm={() =>
Apis.HouseCharage.HouseChargeHasHouses.Delete({
id: item.id,

View File

@ -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 = '收费标准' }) {
<MyButtons.View
title="查看"
onClick={() => {
navigate(`/charge_standard/${item.id}`);
navigate(`/house_charge_standard/${item.id}`);
}}
/>
<ChargeStandardUpdate
@ -122,9 +121,7 @@ export default function Index({ title = '收费标准' }) {
title="编辑"
/>
<ChargeStandardHasHouse
item={{
...item,
}}
item={item}
reload={action?.reload}
title={'绑房'}
/>

View File

@ -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

View File

@ -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 (
<MyPageContainer
title={title}
enableTabs={true}
tabKey="bills"
tabLabel={title}
>
<ProTable
{...MyProTableProps.props}
request={async (params, sort) =>
MyProTableProps.request(
params,
sort,
Apis.HouseCharage.HouseChargeTasks.List,
)
}
toolBarRender={(action) => [
<ChargeTasksCreate
key="Create"
reload={action?.reload}
title={title}
/>,
]}
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) => (
<Space key={index}>
<MyButtons.Delete
onConfirm={() =>
Apis.HouseCharage.HouseChargeTasks.Delete({
id: item.id,
}).then(() => action?.reload())
}
/>
</Space>
),
}),
]}
/>
</MyPageContainer>
);
}

View File

@ -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 (
<BetaSchemaForm<ApiTypes.HouseCharage.HouseChargeTasks.Store>
{...MyModalFormProps.props}
title={`创建${props.title}`}
width="480px"
layout="horizontal"
labelCol={{ span: 8 }}
wrapperCol={{ span: 16 }}
labelAlign="left"
trigger={<MyButtons.Create title={`创建${props.title}`} />}
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 },
},
]}
/>
);
}

View File

@ -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,
// },
// },
]}
/>
);