feat:收费标准0.5 + 房屋绑定0.5
All checks were successful
Build and Push Docker Image / build (push) Successful in 3m11s

This commit is contained in:
uiuJun 2025-09-01 21:32:29 +08:00
parent 0e49b5cf60
commit 6edacd4926
24 changed files with 1839 additions and 50 deletions

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

@ -835,6 +835,87 @@ declare namespace ApiTypes {
};
}
}
namespace HouseCharage {
namespace HouseChargeHasHouses {
type List = {
"house_charge_standards_id": number; // 房屋收费标准id,[ref:house_charge_standards]
};
type Store = {
"house_charge_standards_id": number; // 房屋收费标准id,[ref:house_charge_standards]
"houses_ids": string[]; // 房屋id,[ref:houses]
};
type Show = {
"id": number; // id
};
type Delete = {
"id": number; // id
};
}
namespace HouseChargeStandards {
type List = {
"name"?: string; // 模糊搜索:名称
};
type Store = {
"asset_projects_id": number; // 项目id,[ref:asset_projects]
"name": string; // 收费标准名称
"type": string; // 收费类型,[enum:HouseChargeStandardsTypeEnum]
"charge_type": string; // 收费类型,[enum:HouseBillsTypeEnum]
"calculation_mode": string; // 计费模式,[enum:HouseChargeStandardsCalculationModeEnum]
"calculation_method": string; // 计量方式,[enum:HouseChargeStandardsCalculationMethodEnum]
"price_algorithm": string; // 单价算法,[enum:HouseChargeStandardsPriceAlgorithmEnum]
"price"?: number; // 单价
"calculation_period"?: string; // 计费周期,[enum:HouseChargeStandardsCalculationPeriodEnum]
"auto_date"?: Date; // 自动生成日期
"is_tiered"?: number; // 是否阶梯收费
"tiered_rates"?: string[]; // 阶梯收费标准
"is_apportionment"?: number; // 是否分摊
"apportionment_method"?: string; // 分摊方式,[enum:HouseChargeStandardsApportionmentMethodEnum]
"has_late_fee"?: number; // 是否滞纳金
"late_fee_start_days"?: number; // 生成几天后开始收取滞纳金
"late_fee_rate"?: number; // 滞纳金费率(百分比)
"late_fee_cap_days"?: number; // 滞纳金封顶天数
"has_minimum_charge"?: number; // 是否保底价
"minimum_charge_amount"?: number; // 保底价金额
"remark"?: string; // 备注
};
type Update = {
"id": number; // id
"asset_projects_id": number; // 项目id,[ref:asset_projects]
"name": string; // 收费标准名称
"type": string; // 收费类型,[enum:HouseChargeStandardsTypeEnum]
"charge_type": string; // 收费类型,[enum:HouseBillsTypeEnum]
"calculation_mode": string; // 计费模式,[enum:HouseChargeStandardsCalculationModeEnum]
"calculation_method": string; // 计量方式,[enum:HouseChargeStandardsCalculationMethodEnum]
"price_algorithm": string; // 单价算法,[enum:HouseChargeStandardsPriceAlgorithmEnum]
"price"?: number; // 单价
"calculation_period"?: string; // 计费周期,[enum:HouseChargeStandardsCalculationPeriodEnum]
"auto_date"?: Date; // 自动生成日期
"is_tiered"?: number; // 是否阶梯收费
"tiered_rates"?: string[]; // 阶梯收费标准
"is_apportionment"?: number; // 是否分摊
"apportionment_method"?: string; // 分摊方式,[enum:HouseChargeStandardsApportionmentMethodEnum]
"has_late_fee"?: number; // 是否滞纳金
"late_fee_start_days"?: number; // 生成几天后开始收取滞纳金
"late_fee_rate"?: number; // 滞纳金费率(百分比)
"late_fee_cap_days"?: number; // 滞纳金封顶天数
"has_minimum_charge"?: number; // 是否保底价
"minimum_charge_amount"?: number; // 保底价金额
"remark"?: string; // 备注
};
type Show = {
"id": number; // id
};
type SoftDelete = {
"id": number; // id
};
type Restore = {
"id": number; // id
};
type Delete = {
"id": number; // id
};
}
}
namespace HouseOrder {
namespace HouseOrderPayments {
type List = {
@ -884,27 +965,26 @@ declare namespace ApiTypes {
"asset_projects_id": number; // 项目id,[ref:asset_projects]
"title": string; // 标题
"content": string; // 内容
"is_publish"?: number; // 是否发布
"is_publish"?: boolean; // 是否发布
"publish_at"?: Date; // 发布时间
"sort"?: number; // 排序
};
type Update = {
"id": number; // id
"asset_projects_id": number; // 项目id,[ref:asset_projects]
"companies_id": number; // 公司id,[ref:companies]
"title": string; // 标题
"content": string; // 内容
"is_publish"?: number; // 是否发布
"publish_at"?: mixed; // 发布时间
"is_publish"?: boolean; // 是否发布
"publish_at"?: Date; // 发布时间
"sort"?: number; // 排序
"admins_id"?: number; // 创建人id,[ref:admins]
"company_employees_id"?: number; // 创建员工id,[ref:company_employees]
"last_update_admins_id"?: number; // 最后修改人id,[ref:admins]
"last_update_company_employees"?: number; // 最后修改员工id,[ref:company_employees]
};
type Show = {
"id": number; // id
};
type IsPublish = {
"id": number; // id
"is_publish": boolean; // 是否发布
};
type SoftDelete = {
"id": number; // id
};

View File

@ -495,6 +495,45 @@ export const Apis = {
},
},
},
HouseCharage: {
HouseChargeHasHouses: {
List(data: ApiTypes.HouseCharage.HouseChargeHasHouses.List): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_has_houses/list', { data });
},
Store(data: ApiTypes.HouseCharage.HouseChargeHasHouses.Store): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_has_houses/store', { data });
},
Show(data: ApiTypes.HouseCharage.HouseChargeHasHouses.Show): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_has_houses/show', { data });
},
Delete(data: ApiTypes.HouseCharage.HouseChargeHasHouses.Delete): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_has_houses/delete', { data });
},
},
HouseChargeStandards: {
List(data?: ApiTypes.HouseCharage.HouseChargeStandards.List): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_standards/list', { data });
},
Store(data: ApiTypes.HouseCharage.HouseChargeStandards.Store): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_standards/store', { data });
},
Update(data: ApiTypes.HouseCharage.HouseChargeStandards.Update): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_standards/update', { data });
},
Show(data: ApiTypes.HouseCharage.HouseChargeStandards.Show): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_standards/show', { data });
},
SoftDelete(data: ApiTypes.HouseCharage.HouseChargeStandards.SoftDelete): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_standards/soft_delete', { data });
},
Restore(data: ApiTypes.HouseCharage.HouseChargeStandards.Restore): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_standards/restore', { data });
},
Delete(data: ApiTypes.HouseCharage.HouseChargeStandards.Delete): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_standards/delete', { data });
},
},
},
HouseOrder: {
HouseOrderPayments: {
List(data: ApiTypes.HouseOrder.HouseOrderPayments.List): Promise<MyResponseType> {
@ -539,6 +578,9 @@ export const Apis = {
Show(data: ApiTypes.Msg.MsgPropertyAnnouncements.Show): Promise<MyResponseType> {
return request('admin/msg/msg_property_announcements/show', { data });
},
IsPublish(data: ApiTypes.Msg.MsgPropertyAnnouncements.IsPublish): Promise<MyResponseType> {
return request('admin/msg/msg_property_announcements/is_publish', { data });
},
SoftDelete(data: ApiTypes.Msg.MsgPropertyAnnouncements.SoftDelete): Promise<MyResponseType> {
return request('admin/msg/msg_property_announcements/soft_delete', { data });
},

View File

@ -126,7 +126,7 @@ export const BannersTypeEnum= {
// 缓存类型
export const CacheTypeEnum= {
'MobilePhoneVerificationCode': {"text":"手机验证码","color":"#f002cf","value":"MobilePhoneVerificationCode"},
'MobilePhoneVerificationCode': {"text":"手机验证码","color":"#649200","value":"MobilePhoneVerificationCode"},
};
// CompaniesMerchantTypeEnum
@ -200,6 +200,64 @@ export const HouseBillsTypeEnum= {
'SharedElectricityFee': {"text":"公摊电费","color":"#ec4899","value":"SharedElectricityFee"},
};
// HouseChargeStandardsApportionmentMethodEnum
export const HouseChargeStandardsApportionmentMethodEnum= {
'HouseCount': {"text":"房屋数分摊","color":"#3b82f6","value":"HouseCount"},
'AreaProportion': {"text":"房屋计费面积分摊","color":"#10b981","value":"AreaProportion"},
'FixedRatio': {"text":"按固定比例分摊","color":"#f59e0b","value":"FixedRatio"},
};
// HouseChargeStandardsCalculationMethodEnum
export const HouseChargeStandardsCalculationMethodEnum= {
'ChargeableArea': {"text":"计费面积","color":"#3b82f6","value":"ChargeableArea"},
'BuiltArea': {"text":"建筑面积","color":"#10b981","value":"BuiltArea"},
'InsideArea': {"text":"套内面积","color":"#f59e0b","value":"InsideArea"},
'PerUnit': {"text":"按套","color":"#06b6d4","value":"PerUnit"},
'ElectricityUsage': {"text":"用电量","color":"#8b5cf6","value":"ElectricityUsage"},
'WaterUsage': {"text":"用水量","color":"#ec4899","value":"WaterUsage"},
};
// HouseChargeStandardsCalculationModeEnum
export const HouseChargeStandardsCalculationModeEnum= {
'FixedAmount': {"text":"固定金额","color":"#3b82f6","value":"FixedAmount"},
'QuantityPrice': {"text":"数量*单价","color":"#10b981","value":"QuantityPrice"},
};
// HouseChargeStandardsCalculationPeriodEnum
export const HouseChargeStandardsCalculationPeriodEnum= {
'PerTime': {"text":"按次","color":"#3b82f6","value":"PerTime"},
'PerDay': {"text":"按日","color":"#10b981","value":"PerDay"},
'PerMonth': {"text":"按月","color":"#f59e0b","value":"PerMonth"},
'PerYear': {"text":"按年","color":"#8b5cf6","value":"PerYear"},
};
// HouseChargeStandardsPriceAlgorithmEnum
export const HouseChargeStandardsPriceAlgorithmEnum= {
'Fixed': {"text":"固定","color":"#4caf50","value":"Fixed"},
'Tiered': {"text":"分级价阶梯","color":"#2196f3","value":"Tiered"},
'Peak': {"text":"最高价阶梯","color":"#ff9800","value":"Peak"},
};
// HouseChargeStandardsStatusEnum
export const HouseChargeStandardsStatusEnum= {
'Active': {"text":"启用","color":"#3b82f6","value":"Active"},
'Inactive': {"text":"禁用","color":"#ef4444","value":"Inactive"},
};
// HouseChargeStandardsTypeEnum
export const HouseChargeStandardsTypeEnum= {
'House': {"text":"房屋","color":"#3b82f6","value":"House"},
'Meter': {"text":"仪表","color":"#10b981","value":"Meter"},
};
// HouseChargeTasksStatusEnum
export const HouseChargeTasksStatusEnum= {
'Pending': {"text":"待执行","color":"#f59e0b","value":"Pending"},
'InProgress': {"text":"执行中","color":"#3b82f6","value":"InProgress"},
'Completed': {"text":"已完成","color":"#10b981","value":"Completed"},
'Failed': {"text":"失败","color":"#ef4444","value":"Failed"},
};
// HouseCollectionRecordsCollectionResultEnum
export const HouseCollectionRecordsCollectionResultEnum= {
'PromiseToPay': {"text":"承诺缴费","color":"#4caf50","value":"PromiseToPay"},

View File

@ -8,6 +8,7 @@ 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 BindCompany from './components/modals/BindCompany';
import AssetUpdate from './modals/AssetUpdate';
@ -58,6 +59,12 @@ export default function Show({ title }: { title?: string } = {}) {
closable: false,
children: <AssetGrid item={data} />,
},
{
label: '收费标准',
key: 'charge_standard',
closable: false,
children: <ChargeStandard item={data} />,
},
{
label: '收款账号',
key: 'asset_accounts',

View File

@ -37,7 +37,7 @@ export default function ReceiptAccounts(props: MyBetaModalFormProps) {
// options={false}
columns={[
{
title: '配置id',
title: 'ID',
dataIndex: 'id',
// width: 360,
},

View File

@ -0,0 +1,124 @@
import {
MyBetaModalFormProps,
MyButtons,
MyColumns,
MyProTableProps,
} from '@/common';
import { Apis } from '@/gen/Apis';
import {
HouseBillsTypeEnum,
HouseChargeStandardsCalculationMethodEnum,
HouseChargeStandardsCalculationModeEnum,
HouseChargeStandardsCalculationPeriodEnum,
} from '@/gen/Enums';
import { ProTable } from '@ant-design/pro-components';
import { Space } from 'antd';
import ChargeStandardCreate from './modals/ChargeStandardCreate';
import ChargeStandardHasHouse from './modals/ChargeStandardHasHouse';
export default function ReceiptAccounts(props: MyBetaModalFormProps) {
return (
<>
<ProTable
{...MyProTableProps.props}
search={false}
request={async (params, sort) =>
MyProTableProps.request(
{
...params,
asset_projects_id: props?.item?.id,
},
sort,
Apis.HouseCharage.HouseChargeStandards.List,
)
}
toolBarRender={(action) => [
<ChargeStandardCreate
key="Select"
reload={action?.reload}
item={props?.item}
title="添加收款账号"
/>,
]}
// options={false}
columns={[
{
title: 'ID',
dataIndex: 'id',
},
{
title: 'name',
dataIndex: 'name',
search: false,
},
MyColumns.EnumTag({
title: '收费项目',
dataIndex: 'charge_type',
valueEnum: HouseBillsTypeEnum,
search: false,
}),
MyColumns.EnumTag({
title: '计量单位',
dataIndex: 'calculation_method',
valueEnum: HouseChargeStandardsCalculationMethodEnum,
search: false,
}),
MyColumns.EnumTag({
title: '计费模式',
dataIndex: 'calculation_mode',
valueEnum: HouseChargeStandardsCalculationModeEnum,
search: false,
}),
{
title: '单价',
dataIndex: 'price',
search: false,
},
MyColumns.EnumTag({
title: '账单计费周期',
dataIndex: 'calculation_period',
valueEnum: HouseChargeStandardsCalculationPeriodEnum,
search: false,
}),
{
title: '账单自动生成日期',
dataIndex: 'auto_date',
search: false,
},
{
title: '是否分摊',
dataIndex: 'is_apportionment',
search: false,
render(_, record) {
return `${record?.is_apportionment ? '是' : '否'} `;
},
},
// MyColumns.UpdatedAt(),
// MyColumns.CreatedAt(),
MyColumns.Option({
render: (_, item: any, index, action) => (
<Space key={index}>
<ChargeStandardHasHouse
item={{
...item,
asset_projects_id: props?.item?.id, // 使用项目ID
}}
reload={action?.reload}
title={'绑定房屋'}
/>
<MyButtons.Delete
onConfirm={() =>
Apis.HouseCharage.HouseChargeStandards.Delete({
id: item.id,
}).then(() => action?.reload())
}
/>
</Space>
),
}),
]}
/>
</>
);
}

View File

@ -0,0 +1,423 @@
import {
MyBetaModalFormProps,
MyButtons,
MyFormItems,
MyModalFormProps,
rulesHelper,
} from '@/common';
import { Apis } from '@/gen/Apis';
import {
HouseBillsTypeEnum,
HouseChargeStandardsApportionmentMethodEnum,
HouseChargeStandardsCalculationMethodEnum,
HouseChargeStandardsCalculationModeEnum,
HouseChargeStandardsCalculationPeriodEnum,
HouseChargeStandardsPriceAlgorithmEnum,
HouseChargeStandardsTypeEnum,
} 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.HouseCharage.HouseChargeStandards.Store>
{...MyModalFormProps.props}
title={`创建收费标准`}
wrapperCol={{ span: 24 }}
width="580px"
trigger={<MyButtons.Create title={`创建收费标准`} />}
form={form}
key={new Date().getTime()}
onOpenChange={(open: any) => {
if (open) {
form.resetFields(); // 清空表单数据
}
}}
onFinish={async (values: any) => {
values?.grid_ranges?.forEach((res: { asset_projects_id: string }) => {
res.asset_projects_id = props?.item?.id;
});
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
? HouseChargeStandardsTypeEnum.House.value
: HouseChargeStandardsTypeEnum.Meter.value,
is_apportionment:
values.charge_type === HouseBillsTypeEnum.SharedWaterFee.value ||
values.charge_type === HouseBillsTypeEnum.SharedElectricityFee.value
? 1
: 0,
// 按套
calculation_mode:
values?.calculation_method ===
HouseChargeStandardsCalculationMethodEnum.PerUnit.value
? HouseChargeStandardsCalculationModeEnum.FixedAmount.value
: values?.calculation_mode,
// 按固定金额
price_algorithm:
values?.calculation_mode ===
HouseChargeStandardsCalculationModeEnum.FixedAmount.value ||
values?.calculation_method ===
HouseChargeStandardsCalculationMethodEnum.PerUnit.value
? HouseChargeStandardsPriceAlgorithmEnum.Fixed.value
: values?.price_algorithm,
})
.then(() => {
props.reload?.();
message.success('收费标准创建成功');
return true;
})
.catch(() => false);
}}
columns={[
{
key: 'name',
title: '收费标准名称',
colProps: { span: 24 },
formItemProps: { ...rulesHelper.text },
},
MyFormItems.EnumRadio({
key: 'charge_type',
title: '收费项目',
colProps: { span: 24 },
valueEnum: HouseBillsTypeEnum,
required: true,
}),
// Selects?.AssetProjects({
// key: 'asset_projects_id',
// title: '项目',
// colProps: { span: 12 },
// formItemProps: { ...rulesHelper.text },
// }),
{
name: ['charge_type'],
valueType: 'dependency',
columns: ({ charge_type }: any) => {
return charge_type === HouseBillsTypeEnum.PropertyFee.value ||
charge_type === HouseBillsTypeEnum.MaintenanceFund.value
? [
MyFormItems.EnumRadio({
key: 'calculation_method',
title: '计量单位',
colProps: { span: 24 },
valueEnum: () => {
let obj: any = JSON.parse(
JSON.stringify(
HouseChargeStandardsCalculationMethodEnum,
),
);
delete obj.ElectricityUsage;
delete obj.WaterUsage;
return obj;
},
required: true,
}),
]
: charge_type === HouseBillsTypeEnum.WaterFee.value ||
charge_type === HouseBillsTypeEnum.ElectricityFee.value ||
charge_type === HouseBillsTypeEnum.SharedWaterFee.value ||
charge_type === HouseBillsTypeEnum.SharedElectricityFee.value
? [
MyFormItems.EnumRadio({
key: 'calculation_method',
title: '计量单位',
colProps: { span: 24 },
valueEnum: () => {
let obj: any = JSON.parse(
JSON.stringify(
HouseChargeStandardsCalculationMethodEnum,
),
);
delete obj.ChargeableArea;
delete obj.BuiltArea;
delete obj.InsideArea;
delete obj.PerUnit;
return obj;
},
required: true,
}),
]
: [];
},
},
{
name: ['calculation_method'],
valueType: 'dependency',
columns: ({ calculation_method }: any) => {
return calculation_method ===
HouseChargeStandardsCalculationMethodEnum.PerUnit.value
? [
{
key: 'price',
title: '固定单价',
colProps: { span: 10 },
fieldProps: {
addonAfter: '元',
},
formItemProps: { ...rulesHelper.number },
},
]
: !calculation_method
? []
: [
MyFormItems.EnumRadio({
key: 'calculation_mode',
title: '计费模式',
colProps: { span: 12 },
valueEnum: HouseChargeStandardsCalculationModeEnum,
required: true,
}),
];
},
},
{
name: ['calculation_mode'],
valueType: 'dependency',
columns: ({ calculation_mode }: any) => {
return calculation_mode ===
HouseChargeStandardsCalculationModeEnum.FixedAmount.value
? [
{
key: 'price',
title: '固定单价',
colProps: { span: 10 },
fieldProps: {
addonAfter: '元',
},
formItemProps: { ...rulesHelper.number },
},
]
: calculation_mode ===
HouseChargeStandardsCalculationModeEnum.QuantityPrice.value
? [
MyFormItems.EnumRadio({
key: 'price_algorithm',
title: '计费算法',
colProps: { span: 14 },
valueEnum: HouseChargeStandardsPriceAlgorithmEnum,
required: true,
// valueEnum: () => {
// let obj: any = JSON.parse(
// JSON.stringify(HouseChargeStandardsPriceAlgorithmEnum),
// );
// delete obj.Fixed;
// return obj;
// },
// fieldProps: {
// onChange: () => {
// // 切换计费算法时清空阶梯配置
// form.setFieldValue('scheme', undefined);
// },
// },
}),
{
name: ['price_algorithm'],
valueType: 'dependency',
columns: ({ price_algorithm }: any) => {
return price_algorithm ===
HouseChargeStandardsPriceAlgorithmEnum.Fixed.value
? [
{
key: 'price',
title: '固定单价',
colProps: { span: 10 },
fieldProps: {
addonAfter: '元',
},
formItemProps: { ...rulesHelper.number },
},
]
: price_algorithm ===
HouseChargeStandardsPriceAlgorithmEnum.Tiered.value
? [
{
valueType: 'formList',
dataIndex: 'scheme',
title: '阶梯标准',
formItemProps: { ...rulesHelper.array },
initialValue: [
{
start: 0,
end: null,
price: null,
},
],
fieldProps: {
actionRef: actionRef,
copyIconProps: false,
// deleteIconProps: false,
},
columns: [
{
valueType: 'group',
colProps: { span: 24 },
columns: [
{
key: 'start',
colProps: { span: 10 },
title: '起始值',
valueType: 'number',
fieldProps: {
min: 0,
// addonBefore: `第${index + 1}阶梯`,
addonBefore: `第1阶梯`,
},
width: '100%',
formItemProps: { ...rulesHelper.number },
},
{
key: 'end',
colProps: { span: 6 },
title: '结束值',
valueType: 'number',
width: '100%',
formItemProps: { ...rulesHelper.number },
fieldProps: { maxLength: 12 },
},
{
key: 'price',
colProps: { span: 8 },
title: '阶梯单价',
valueType: 'number',
fieldProps: {
addonAfter: '元',
min: 0,
},
formItemProps: { ...rulesHelper.number },
},
],
},
],
},
]
: price_algorithm ===
HouseChargeStandardsPriceAlgorithmEnum.Peak.value
? [
{
valueType: 'formList',
dataIndex: 'scheme',
title: '阶梯标准',
formItemProps: { ...rulesHelper.array },
initialValue: [
{
start: 0,
end: null,
price: null,
},
],
fieldProps: {
actionRef: actionRef,
copyIconProps: false,
// deleteIconProps: false,
},
columns: [
{
valueType: 'group',
colProps: { span: 24 },
columns: [
{
key: 'start',
colProps: { span: 10 },
title: '起始值',
valueType: 'number',
fieldProps: {
min: 0,
// addonBefore: `第${index + 1}阶梯`,
addonBefore: `第1阶梯`,
},
width: '100%',
formItemProps: { ...rulesHelper.number },
},
{
key: 'end',
colProps: { span: 6 },
title: '结束值',
valueType: 'number',
width: '100%',
formItemProps: { ...rulesHelper.number },
fieldProps: { maxLength: 12 },
},
{
key: 'price',
colProps: { span: 8 },
title: '阶梯单价',
valueType: 'number',
fieldProps: {
addonAfter: '元',
min: 0,
},
formItemProps: { ...rulesHelper.number },
},
],
},
],
},
]
: [];
},
},
]
: [];
},
},
{
name: ['charge_type'],
valueType: 'dependency',
columns: ({ charge_type }: any) => {
return charge_type === HouseBillsTypeEnum.SharedWaterFee.value ||
charge_type === HouseBillsTypeEnum.SharedElectricityFee.value
? [
MyFormItems.EnumRadio({
key: 'calculation_method',
title: '分摊方式',
colProps: { span: 18 },
valueEnum: HouseChargeStandardsApportionmentMethodEnum,
required: true,
}),
]
: [];
},
},
{
valueType: 'group',
columns: [
MyFormItems.EnumRadio({
key: 'calculation_period',
title: '账单计费周期',
colProps: { span: 14 },
valueEnum: HouseChargeStandardsCalculationPeriodEnum,
required: true,
}),
{
key: 'auto_date',
title: '账单自动生成日期',
colProps: { span: 10 },
valueType: 'date',
width: '100%',
},
],
},
{
key: 'remark',
title: '备注',
colProps: { span: 24 },
valueType: 'textarea',
fieldProps: {
rows: 4,
maxLength: 500,
showCount: true,
},
},
]}
/>
);
}

View File

@ -0,0 +1,491 @@
import { MyBetaModalFormProps, MyButtons } from '@/common';
import { MyModal } from '@/components/MyModal';
import { Apis } from '@/gen/Apis';
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';
const { Title } = Typography;
interface TreeNodeType extends DataNode {
id: number;
key: string;
title: string;
isLeaf?: boolean;
children?: TreeNodeType[];
asset_buildings_id?: number;
asset_units_id?: number;
}
// 扩展 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 = (
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 uncheckedKeys = [...prevKeys].filter((key) => !newKeys.has(key));
// 如果有节点被取消选中,同步取消其所有子节点
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);
} else {
setCheckedKeys(keys);
}
// 收集所有选中的房屋
const selectedHousesList: { id: number; name: string }[] = [];
// 遍历树形数据,收集选中节点下的所有房屋
const collectHouses = (nodes: TreeNodeType[], checkedKeys: React.Key[]) => {
nodes.forEach((node) => {
if (checkedKeys.includes(node.key)) {
if (node.isLeaf) {
// 如果是房屋节点,直接添加
selectedHousesList.push({
id: node.id,
name: node.title as string,
});
} 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-')) {
const buildingId = node.id;
await loadUnits(buildingId, node.key as string);
// 如果楼栋被选中,加载并选中其下所有单元和房屋
if (checkedKeys.includes(node.key)) {
const newTreeData = [...treeData];
const buildingNode = newTreeData.find((n) => n.key === node.key);
if (buildingNode?.children) {
// 加载每个单元下的房屋
for (const unit of buildingNode.children) {
await loadHouses(buildingId, unit.id, unit.key as string);
}
// 更新树形数据
setTreeData(newTreeData);
// 收集所有房屋的key
const allKeys: React.Key[] = [];
const collectKeys = (nodes: TreeNodeType[]) => {
nodes.forEach((node) => {
allKeys.push(node.key);
if (node.children) {
collectKeys(node.children);
}
});
};
collectKeys([buildingNode]);
// 更新选中状态
setCheckedKeys(Array.from(new Set([...checkedKeys, ...allKeys])));
}
}
return Promise.resolve();
}
// 加载单元下的房屋
if (node.key.toString().startsWith('unit-')) {
const unitId = node.id;
const buildingId = node.asset_buildings_id as number;
await loadHouses(buildingId, unitId, node.key as string);
// 如果单元被选中,选中其下所有房屋
if (checkedKeys.includes(node.key)) {
const newTreeData = [...treeData];
const buildingNode = newTreeData.find((n) =>
n.children?.some((unit) => unit.key === node.key),
);
const unitNode = buildingNode?.children?.find(
(n) => n.key === node.key,
);
if (unitNode?.children) {
const houseKeys = unitNode.children.map((house) => house.key);
setCheckedKeys(Array.from(new Set([...checkedKeys, ...houseKeys])));
}
}
return Promise.resolve();
}
return Promise.resolve();
};
// 处理全选
const handleSelectAll = (e: CheckboxChangeEvent) => {
setSelectAll(e.target.checked);
if (e.target.checked) {
// 收集所有房屋节点的key
const allHouseKeys: React.Key[] = [];
const allHouses: { id: number; name: string }[] = [];
treeData.forEach((building) => {
building.children?.forEach((unit) => {
unit.children?.forEach((house) => {
if (house.isLeaf) {
allHouseKeys.push(house.key);
allHouses.push({
id: house.id,
name: house.title as string,
});
}
});
});
});
setCheckedKeys(allHouseKeys);
setSelectedHouses(allHouses);
} else {
// 取消全选
setCheckedKeys([]);
setSelectedHouses([]);
}
};
// 提交选中的房屋
const handleSubmit = async () => {
if (selectedHouses.length === 0) {
message.warning('请至少选择一个房屋');
return;
}
try {
setLoading(true);
// 将 number[] 转换为 string[]
const houses_ids = selectedHouses.map((house) => house.id.toString());
await Apis.HouseCharage.HouseChargeHasHouses.Store({
house_charge_standards_id: props?.item?.id,
houses_ids,
});
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="middle"
title={`${props.title}`}
/>
}
node={
<ProCard
title={
<Alert
message="请选择需要绑定的房屋"
type="info"
showIcon
style={{ margin: 0 }}
/>
}
>
<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>
{loading && <div>...</div>}
<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>
<div style={{ width: '50%', padding: '0 16px' }}>
<div style={{ marginBottom: 16 }}>
<Title level={5}> ({selectedHouses.length})</Title>
</div>
<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>
<div style={{ marginTop: 16, textAlign: 'right' }}>
<Space>
<Button onClick={props?.onCancel}></Button>
<Button type="primary" loading={loading} onClick={handleSubmit}>
</Button>
</Space>
</div>
</ProCard>
}
/>
);
}

View File

@ -20,10 +20,14 @@ export default function Create(props: MyBetaModalFormProps) {
wrapperCol={{ span: 24 }}
width="600px"
trigger={<MyButtons.Create title={`添加广告`} />}
key={new Date().getTime()}
form={form}
onOpenChange={(open: any) => {
if (open) {
form.resetFields(); // 清空表单数据
form.setFieldsValue({
banner_spaces_id: props.item?.banner_spaces_id,
});
}
}}
onFinish={async (values) =>
@ -41,6 +45,10 @@ export default function Create(props: MyBetaModalFormProps) {
title: '选择广告位',
colProps: { span: 12 },
formItemProps: { ...rulesHelper.text },
fieldProps: {
showSearch: true,
optionFilterProp: 'label',
},
}),
{
key: 'name',

View File

@ -32,7 +32,10 @@ export default function Index({ ...rest }) {
toolBarRender={(action) => [
<BannerCreate
key="AddOccupant"
item={rest.item}
item={{
...rest.item,
banner_spaces_id: rest.item?.banner_spaces_id,
}}
reload={action?.reload}
title="添加住户"
/>,

View File

@ -18,6 +18,7 @@ export default function Create(props: MyBetaModalFormProps) {
wrapperCol={{ span: 24 }}
width="500px"
trigger={<MyButtons.Create title={`添加广告位`} />}
key={new Date().getTime()}
onFinish={async (values) =>
Apis.Banner.BannerSpaces.Store(values)
.then(() => {

View File

@ -25,7 +25,7 @@ export default function Index(props: MyBetaModalFormProps) {
toolBarRender={(action) => [
<EmployeeCreate
key="Create"
item={{ companies_id: props?.item?.id }}
item={props?.item}
reload={action?.reload}
title="员工"
/>,

View File

@ -24,6 +24,9 @@ export default function Create(props: MyBetaModalFormProps) {
onOpenChange={(open: any) => {
if (open) {
form.resetFields(); // 清空表单数据
form.setFieldsValue({
companies_id: props?.item?.id,
});
}
}}
onFinish={async (values: any) =>
@ -40,17 +43,18 @@ export default function Create(props: MyBetaModalFormProps) {
.catch(() => false)
}
columns={[
// Selects?.Organizations({
// title: '设置所属组织',
// params: { companies_id: props?.item?.companies_id },
// key: 'organizations_id',
// formItemProps: { ...rulesHelper.text },
// }),
Selects?.Companies({
key: 'companies_id',
title: '所属机构',
colProps: { span: 24 },
formItemProps: { ...rulesHelper.number },
}),
Selects?.OrganizationsTree({
title: '选择组织',
key: 'organizations_id',
params: { companies_id: props?.item?.companies_id },
colProps: { span: 24 },
formItemProps: { ...rulesHelper.text },
}),
{
key: 'name',

View File

@ -46,12 +46,6 @@ export default function Update(props: MyBetaModalFormProps) {
.catch(() => false)
}
columns={[
// Selects?.Organizations({
// title: '所属组织',
// params: { companies_id: props?.item?.companies_id },
// key: 'organizations_id',
// formItemProps: { ...rulesHelper.text },
// }),
Selects?.OrganizationsTree({
title: '选择组织',
key: 'organizations_id',
@ -60,6 +54,7 @@ export default function Update(props: MyBetaModalFormProps) {
fieldProps: {
showSearch: true,
},
formItemProps: { ...rulesHelper.text },
}),
{
key: 'name',

View File

@ -58,7 +58,7 @@ export default function Create(props: MyBetaModalFormProps) {
key: 'contact_name',
title: '联系人姓名',
colProps: { span: 6 },
// formItemProps: { ...rulesHelper.text },
formItemProps: { ...rulesHelper.text },
},
{
key: 'contact_phone',
@ -68,7 +68,7 @@ export default function Create(props: MyBetaModalFormProps) {
fieldProps: {
maxLength: 11,
},
// formItemProps: { ...rulesHelper.phone },
formItemProps: { ...rulesHelper.phone },
},
{
key: 'contact_email',

View File

@ -69,7 +69,7 @@ export default function Update(props: MyBetaModalFormProps) {
key: 'contact_name',
title: '联系人姓名',
colProps: { span: 6 },
// formItemProps: { ...rulesHelper.text },
formItemProps: { ...rulesHelper.text },
},
{
key: 'contact_phone',
@ -79,7 +79,7 @@ export default function Update(props: MyBetaModalFormProps) {
fieldProps: {
maxLength: 11,
},
// formItemProps: { ...rulesHelper.phone },
formItemProps: { ...rulesHelper.phone },
},
{
key: 'contact_email',

View File

@ -8,6 +8,7 @@ import {
import { Apis } from '@/gen/Apis';
import { ProTable } from '@ant-design/pro-components';
import { Space } from 'antd';
import EmployeeCreate from '../company/components/modals/EmployeeCreate';
import EmployeeUpdate from '../company/components/modals/EmployeeUpdate';
export default function Index({ title = '员工管理' }) {
@ -35,13 +36,9 @@ export default function Index({ title = '员工管理' }) {
Apis.Company.CompanyEmployees.List,
)
}
// toolBarRender={(action) => [
// <EmployeesCreate
// key="Create"
// reload={action?.reload}
// title={title}
// />,
// ]}
toolBarRender={(action) => [
<EmployeeCreate key="Create" reload={action?.reload} title="员工" />,
]}
columns={[
MyColumns.ID(),
{

View File

@ -0,0 +1,52 @@
import { MyPageContainer, usePageTabs } from '@/common';
import { Apis } from '@/gen/Apis';
import { ProCard } from '@ant-design/pro-components';
import { useParams } from '@umijs/max';
import { Tabs } from 'antd';
import { useEffect, useState } from 'react';
import BannerList from './components/BannerList';
import BannerSpaceInfo from './components/BannerSpaceInfo';
export default function Show({ title }: { title?: string } = {}) {
const { id } = useParams<{ id: string }>();
const [data, setShow] = useState<any>({});
// 注册当前页面为标签页
const { addTab } = usePageTabs({
tabKey: `banner-space-${id}`,
tabLabel: data?.name || title || '广告位详情',
});
const loadShow = () => {
let paramsId: any = { id: id ?? 0 };
Apis.Banner.BannerSpaces.Show(paramsId).then((res) => {
setShow(res?.data);
});
};
useEffect(() => {
loadShow();
}, [id]);
let items = [
{
label: '关联房屋',
key: '1',
closable: false,
children: (
<BannerList
item={{ ...data, banner_spaces_id: id }}
reload={() => loadShow()}
/>
),
},
];
return (
<MyPageContainer title={title}>
<BannerSpaceInfo item={data} reload={loadShow} />
<ProCard style={{ marginTop: 16 }}>
<Tabs type="card" items={items} defaultActiveKey="1" size="small" />
</ProCard>
</MyPageContainer>
);
}

View File

@ -0,0 +1,86 @@
import { MyColumns, MyProTableProps } from '@/common';
import { Apis } from '@/gen/Apis';
import { BannersRedirectTypeEnum, BannersTypeEnum } from '@/gen/Enums';
import BannerCreate from '@/pages/banner/modals/BannerCreate';
import BannerShow from '@/pages/banner/modals/BannerShow';
import BannerUpdate from '@/pages/banner/modals/BannerUpdate';
import { ProTable } from '@ant-design/pro-components';
import { Space } from 'antd';
import { useEffect, useRef } from 'react';
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,
banner_spaces_id: rest.item?.banner_spaces_id,
},
sort,
Apis.Banner.Banners.List,
)
}
toolBarRender={(action) => [
<BannerCreate
key="AddOccupant"
item={{
...rest.item,
banner_spaces_id: rest.item?.banner_spaces_id,
}}
reload={action?.reload}
title="添加住户"
/>,
]}
search={false}
columns={[
MyColumns.ID(),
{
title: '广告名称',
dataIndex: 'name',
},
MyColumns.EnumTag({
title: '类型',
dataIndex: 'type',
valueEnum: BannersTypeEnum,
search: false,
}),
MyColumns.EnumTag({
title: '跳转类型',
dataIndex: 'redirect_type',
valueEnum: BannersRedirectTypeEnum,
search: false,
}),
{
title: '开始时间',
dataIndex: 'start_time',
valueType: 'dateTime',
search: false,
},
{
title: '结束时间',
dataIndex: 'end_time',
valueType: 'dateTime',
search: false,
},
MyColumns.Option({
render: (_, item: any, index, action) => (
<Space key={index}>
<BannerShow item={item} reload={action?.reload} />
<BannerUpdate item={item} reload={action?.reload} />
</Space>
),
}),
]}
/>
</>
);
}

View File

@ -0,0 +1,31 @@
import { MyBetaModalFormProps, renderTextHelper } from '@/common';
import { BannerSpacesTypeEnum } from '@/gen/Enums';
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
import { Space } from 'antd';
export default function info(props: MyBetaModalFormProps) {
const { item } = props;
return (
<Space direction="vertical" style={{ width: '100%' }}>
<ProCard title="基本信息">
<ProDescriptions bordered>
<ProDescriptions.Item label="名称" span={2}>
{item?.name}
</ProDescriptions.Item>
<ProDescriptions.Item label="类型">
<renderTextHelper.Tag
Enums={BannerSpacesTypeEnum}
value={item?.type}
key="type"
/>
</ProDescriptions.Item>
<ProDescriptions.Item label="备注">
{item?.remark}
</ProDescriptions.Item>
</ProDescriptions>
</ProCard>
</Space>
);
}

View File

@ -0,0 +1,95 @@
import {
MyButtons,
MyColumns,
MyPageContainer,
MyProTableProps,
usePageTabs,
} from '@/common';
import { Apis } from '@/gen/Apis';
import { BannerSpacesTypeEnum } from '@/gen/Enums';
import { ProTable } from '@ant-design/pro-components';
import { useNavigate } from '@umijs/max';
import { Space } from 'antd';
import HouseChargeCreate from './modals/HouseChargeCreate';
import HouseChargeUpdate from './modals/HouseChargeUpdate';
export default function Index({ title = '收费标准' }) {
const navigate = useNavigate();
// 注册当前页面为标签页
usePageTabs({
tabKey: 'house-charge',
tabLabel: title,
});
return (
<MyPageContainer
title={title}
enableTabs={true}
tabKey="banner-spaces"
tabLabel={title}
>
<ProTable
{...MyProTableProps.props}
request={async (params, sort) =>
MyProTableProps.request(
params,
sort,
Apis.HouseCharage.HouseChargeStandards.List,
)
}
toolBarRender={(action) => [
<HouseChargeCreate
key="Create"
reload={action?.reload}
title={title}
/>,
]}
columns={[
MyColumns.ID(),
{
title: '广告位名称',
dataIndex: 'name',
},
MyColumns.EnumTag({
title: '类型',
dataIndex: 'type',
valueEnum: BannerSpacesTypeEnum,
search: false,
}),
{
title: '备注',
dataIndex: 'remark',
search: false,
ellipsis: true,
},
MyColumns.CreatedAt(),
MyColumns.Option({
render: (_, item: any, index, action) => (
<Space key={index}>
<MyButtons.View
title="查看"
onClick={() => {
navigate(`/house_charge/${item.id}`);
}}
/>
<HouseChargeUpdate
item={item}
reload={action?.reload}
title={title}
/>
<MyButtons.Delete
onConfirm={() =>
Apis.HouseCharage.HouseChargeStandards.Delete({
id: item.id,
}).then(() => action?.reload())
}
/>
</Space>
),
}),
]}
/>
</MyPageContainer>
);
}

View File

@ -0,0 +1,227 @@
import {
MyBetaModalFormProps,
MyButtons,
MyFormItems,
MyModalFormProps,
rulesHelper,
} from '@/common';
import { Selects } from '@/components/Select';
import { Apis } from '@/gen/Apis';
import {
HouseChargeStandardsApportionmentMethodEnum,
HouseChargeStandardsCalculationMethodEnum,
HouseChargeStandardsCalculationModeEnum,
HouseChargeStandardsCalculationPeriodEnum,
HouseChargeStandardsPriceAlgorithmEnum,
HouseChargeStandardsTypeEnum,
} 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 actionRef = useRef<any>();
const [form] = Form.useForm();
return (
<BetaSchemaForm<ApiTypes.HouseCharage.HouseChargeStandards.Store>
{...MyModalFormProps.props}
title={`添加收费标准`}
wrapperCol={{ span: 24 }}
width="600px"
trigger={<MyButtons.Create title={`添加收费标准`} />}
key={new Date().getTime()}
form={form}
onFinish={async (values) =>
Apis.HouseCharage.HouseChargeStandards.Store(values)
.then(() => {
props.reload?.();
message.success('添加收费标准成功');
return true;
})
.catch(() => false)
}
columns={[
{
key: 'name',
title: '收费标准名称',
colProps: { span: 12 },
formItemProps: { ...rulesHelper.text },
},
MyFormItems.EnumRadio({
key: 'type',
title: '适用对象',
colProps: { span: 12 },
valueEnum: HouseChargeStandardsTypeEnum,
required: true,
}),
Selects?.AssetProjects({
key: 'asset_projects_id',
title: '项目',
colProps: { span: 12 },
formItemProps: { ...rulesHelper.text },
}),
MyFormItems.EnumRadio({
key: 'calculation_mode',
title: '计费模式',
colProps: { span: 12 },
valueEnum: HouseChargeStandardsCalculationModeEnum,
required: true,
}),
MyFormItems.EnumRadio({
key: 'calculation_method',
title: '计量单位',
colProps: { span: 24 },
valueEnum: HouseChargeStandardsCalculationMethodEnum,
required: true,
}),
MyFormItems.EnumRadio({
key: 'price_algorithm',
title: '计费算法',
colProps: { span: 14 },
valueEnum: HouseChargeStandardsPriceAlgorithmEnum,
required: true,
fieldProps: {
onChange: () => {
// 切换计费算法时清空阶梯配置
form.setFieldValue('scheme', undefined);
},
},
}),
{
valueType: '',
},
{
name: ['price_algorithm'],
valueType: 'dependency',
columns: ({ price_algorithm }: any) => {
return price_algorithm ===
HouseChargeStandardsPriceAlgorithmEnum.Fixed.value
? [
{
key: 'price',
title: '固定单价',
colProps: { span: 10 },
fieldProps: {
addonAfter: '元',
},
},
]
: price_algorithm ===
HouseChargeStandardsPriceAlgorithmEnum.Tiered.value
? [
{
valueType: 'formList',
dataIndex: 'scheme',
title: '阶梯标准',
formItemProps: { ...rulesHelper.array },
initialValue: [
{
start: 0,
end: null,
price: null,
},
],
fieldProps: {
actionRef: actionRef,
copyIconProps: false,
// deleteIconProps: false,
},
columns: [
{
valueType: 'group',
colProps: { span: 24 },
columns: [
{
key: 'start',
colProps: { span: 7 },
title: '起始值',
valueType: 'number',
fieldProps: { min: 0 },
width: '100%',
formItemProps: { ...rulesHelper.number },
},
{
key: 'end',
colProps: { span: 7 },
title: '结束值',
valueType: 'number',
width: '100%',
formItemProps: { ...rulesHelper.number },
fieldProps: { maxLength: 12 },
},
{
key: 'price',
colProps: { span: 8 },
title: '阶梯单价',
valueType: 'number',
fieldProps: {
addonAfter: '元',
min: 0,
},
formItemProps: { ...rulesHelper.number },
},
],
},
],
},
]
: price_algorithm ===
HouseChargeStandardsPriceAlgorithmEnum.Peak.value
? []
: [];
},
},
{
valueType: 'group',
columns: [
{
title: '是否分摊',
dataIndex: 'is_apportionment',
colProps: { span: 6 },
valueType: 'switch',
formItemProps: { ...rulesHelper.text },
},
{
name: ['is_apportionment'],
valueType: 'dependency',
columns: ({ is_apportionment }: any) => {
return is_apportionment
? [
MyFormItems.EnumRadio({
key: 'calculation_method',
title: '计量单位',
colProps: { span: 18 },
valueEnum: HouseChargeStandardsApportionmentMethodEnum,
required: true,
}),
]
: [];
},
},
],
},
MyFormItems.EnumRadio({
key: 'calculation_period',
title: '计费周期',
colProps: { span: 18 },
valueEnum: HouseChargeStandardsCalculationPeriodEnum,
required: true,
}),
{
key: 'remark',
title: '备注',
valueType: 'textarea',
colProps: { span: 24 },
fieldProps: {
rows: 4,
maxLength: 500,
showCount: true,
},
},
]}
/>
);
}

View File

@ -0,0 +1,66 @@
import {
MyBetaModalFormProps,
MyButtons,
MyFormItems,
MyModalFormProps,
rulesHelper,
} from '@/common';
import { Apis } from '@/gen/Apis';
import { BannerSpacesTypeEnum } from '@/gen/Enums';
import { BetaSchemaForm } from '@ant-design/pro-components';
import { Form, message } from 'antd';
export default function Update(props: MyBetaModalFormProps) {
const [form] = Form.useForm();
return (
<BetaSchemaForm<ApiTypes.Banner.BannerSpaces.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.Banner.BannerSpaces.Update({ ...values, id: props.item?.id ?? 0 })
.then(() => {
props.reload?.();
message.success('编辑广告位成功');
return true;
})
.catch(() => false)
}
columns={[
{
key: 'name',
title: '广告位名称',
colProps: { span: 24 },
formItemProps: { ...rulesHelper.text },
},
MyFormItems.EnumRadio({
key: 'type',
title: '类型',
colProps: { span: 24 },
valueEnum: BannerSpacesTypeEnum,
required: true,
}),
{
key: 'remark',
title: '备注',
valueType: 'textarea',
colProps: { span: 24 },
fieldProps: {
rows: 4,
maxLength: 500,
showCount: true,
},
},
]}
/>
);
}

View File

@ -45,19 +45,12 @@ export default function WorkOrderCreate(props: MyBetaModalFormProps) {
required: true,
}),
{
key: 'title',
title: '工单标题',
colProps: { span: 18 },
formItemProps: { ...rulesHelper.text },
},
MyFormItems.EnumSelect({
key: 'level',
title: '优先级',
colProps: { span: 6 },
valueEnum: HouseWorkOrdersLevelEnum,
required: true,
}),
// {
// key: 'title',
// title: '工单标题',
// colProps: { span: 18 },
// formItemProps: { ...rulesHelper.text },
// },
{
key: 'content',
title: '工单描述',
@ -68,7 +61,13 @@ 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'],
@ -147,7 +146,7 @@ export default function WorkOrderCreate(props: MyBetaModalFormProps) {
{
key: 'reporter_phone',
title: '上报人手机',
formItemProps: { ...rulesHelper.phone },
// formItemProps: { ...rulesHelper.phone },
colProps: { span: 12 },
fieldProps: {
placeholder: '请输入手机号码',