diff --git a/src/gen/ApiTypes.d.ts b/src/gen/ApiTypes.d.ts index 33c1b83..974a17d 100644 --- a/src/gen/ApiTypes.d.ts +++ b/src/gen/ApiTypes.d.ts @@ -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 }; diff --git a/src/gen/Apis.ts b/src/gen/Apis.ts index 40bd372..d10448b 100644 --- a/src/gen/Apis.ts +++ b/src/gen/Apis.ts @@ -495,6 +495,45 @@ export const Apis = { }, }, }, + HouseCharage: { + HouseChargeHasHouses: { + List(data: ApiTypes.HouseCharage.HouseChargeHasHouses.List): Promise { + return request('admin/house_charage/house_charge_has_houses/list', { data }); + }, + Store(data: ApiTypes.HouseCharage.HouseChargeHasHouses.Store): Promise { + return request('admin/house_charage/house_charge_has_houses/store', { data }); + }, + Show(data: ApiTypes.HouseCharage.HouseChargeHasHouses.Show): Promise { + return request('admin/house_charage/house_charge_has_houses/show', { data }); + }, + Delete(data: ApiTypes.HouseCharage.HouseChargeHasHouses.Delete): Promise { + return request('admin/house_charage/house_charge_has_houses/delete', { data }); + }, + }, + HouseChargeStandards: { + List(data?: ApiTypes.HouseCharage.HouseChargeStandards.List): Promise { + return request('admin/house_charage/house_charge_standards/list', { data }); + }, + Store(data: ApiTypes.HouseCharage.HouseChargeStandards.Store): Promise { + return request('admin/house_charage/house_charge_standards/store', { data }); + }, + Update(data: ApiTypes.HouseCharage.HouseChargeStandards.Update): Promise { + return request('admin/house_charage/house_charge_standards/update', { data }); + }, + Show(data: ApiTypes.HouseCharage.HouseChargeStandards.Show): Promise { + return request('admin/house_charage/house_charge_standards/show', { data }); + }, + SoftDelete(data: ApiTypes.HouseCharage.HouseChargeStandards.SoftDelete): Promise { + return request('admin/house_charage/house_charge_standards/soft_delete', { data }); + }, + Restore(data: ApiTypes.HouseCharage.HouseChargeStandards.Restore): Promise { + return request('admin/house_charage/house_charge_standards/restore', { data }); + }, + Delete(data: ApiTypes.HouseCharage.HouseChargeStandards.Delete): Promise { + return request('admin/house_charage/house_charge_standards/delete', { data }); + }, + }, + }, HouseOrder: { HouseOrderPayments: { List(data: ApiTypes.HouseOrder.HouseOrderPayments.List): Promise { @@ -539,6 +578,9 @@ export const Apis = { Show(data: ApiTypes.Msg.MsgPropertyAnnouncements.Show): Promise { return request('admin/msg/msg_property_announcements/show', { data }); }, + IsPublish(data: ApiTypes.Msg.MsgPropertyAnnouncements.IsPublish): Promise { + return request('admin/msg/msg_property_announcements/is_publish', { data }); + }, SoftDelete(data: ApiTypes.Msg.MsgPropertyAnnouncements.SoftDelete): Promise { return request('admin/msg/msg_property_announcements/soft_delete', { data }); }, diff --git a/src/gen/Enums.ts b/src/gen/Enums.ts index 33fbc82..324e482 100644 --- a/src/gen/Enums.ts +++ b/src/gen/Enums.ts @@ -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"}, diff --git a/src/pages/asset/$id.tsx b/src/pages/asset/$id.tsx index 0dcae2c..91bbae5 100644 --- a/src/pages/asset/$id.tsx +++ b/src/pages/asset/$id.tsx @@ -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: , }, + { + label: '收费标准', + key: 'charge_standard', + closable: false, + children: , + }, { label: '收款账号', key: 'asset_accounts', diff --git a/src/pages/asset/components/AssetAccounts.tsx b/src/pages/asset/components/AssetAccounts.tsx index 4d29893..3ab4e2f 100644 --- a/src/pages/asset/components/AssetAccounts.tsx +++ b/src/pages/asset/components/AssetAccounts.tsx @@ -37,7 +37,7 @@ export default function ReceiptAccounts(props: MyBetaModalFormProps) { // options={false} columns={[ { - title: '配置id', + title: 'ID', dataIndex: 'id', // width: 360, }, diff --git a/src/pages/asset/components/ChargeStandard.tsx b/src/pages/asset/components/ChargeStandard.tsx new file mode 100644 index 0000000..f6b7031 --- /dev/null +++ b/src/pages/asset/components/ChargeStandard.tsx @@ -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 ( + <> + + MyProTableProps.request( + { + ...params, + asset_projects_id: props?.item?.id, + }, + sort, + Apis.HouseCharage.HouseChargeStandards.List, + ) + } + toolBarRender={(action) => [ + , + ]} + // 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) => ( + + + + Apis.HouseCharage.HouseChargeStandards.Delete({ + id: item.id, + }).then(() => action?.reload()) + } + /> + + ), + }), + ]} + /> + + ); +} diff --git a/src/pages/asset/components/modals/ChargeStandardCreate.tsx b/src/pages/asset/components/modals/ChargeStandardCreate.tsx new file mode 100644 index 0000000..e63b3c2 --- /dev/null +++ b/src/pages/asset/components/modals/ChargeStandardCreate.tsx @@ -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(); + + return ( + + {...MyModalFormProps.props} + title={`创建收费标准`} + wrapperCol={{ span: 24 }} + width="580px" + trigger={} + 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, + }, + }, + ]} + /> + ); +} diff --git a/src/pages/asset/components/modals/ChargeStandardHasHouse.tsx b/src/pages/asset/components/modals/ChargeStandardHasHouse.tsx new file mode 100644 index 0000000..fb639bb --- /dev/null +++ b/src/pages/asset/components/modals/ChargeStandardHasHouse.tsx @@ -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([]); + const [expandedKeys, setExpandedKeys] = useState([]); + const [checkedKeys, setCheckedKeys] = useState([]); + const [selectedKeys, setSelectedKeys] = useState([]); + const [autoExpandParent, setAutoExpandParent] = useState(true); + const [loading, setLoading] = useState(false); + const [selectAll, setSelectAll] = useState(false); + const [selectedHouses, setSelectedHouses] = useState< + { id: number; name: string }[] + >([]); + const modalRef: any = useRef(null); + + // 加载楼栋数据 + const loadBuildings = async () => { + setLoading(true); + + try { + const res = await Apis.Asset.AssetBuildings.List({ + asset_projects_id: props?.item?.asset_projects_id, + }); + if (res?.data) { + const buildings = res.data.map((building: any) => ({ + id: building.id, + key: `building-${building.id}`, + title: building.name, + children: [], + isLeaf: false, + })); + setTreeData(buildings); + } + } catch (error) { + console.error('加载楼栋失败:', error); + } finally { + setLoading(false); + } + }; + + // 加载单元数据 + const loadUnits = async (buildingId: number, buildingKey: string) => { + setLoading(true); + try { + const res = await Apis.Asset.AssetUnits.List({ + asset_projects_id: props?.item?.asset_projects_id, + asset_buildings_id: buildingId, + }); + + if (res?.data) { + const units = res.data.map((unit: any) => ({ + id: unit.id, + key: `unit-${unit.id}`, + title: unit.name, + children: [], + isLeaf: false, + asset_buildings_id: buildingId, + })); + + // 更新树形数据 + const newTreeData = [...treeData]; + const buildingNode = newTreeData.find( + (node) => node.key === buildingKey, + ); + if (buildingNode) { + buildingNode.children = units; + } + + setTreeData(newTreeData); + } + } catch (error) { + console.error('加载单元失败:', error); + } finally { + setLoading(false); + } + }; + + // 加载房屋数据 + const loadHouses = async ( + buildingId: number, + unitId: number, + unitKey: string, + ) => { + setLoading(true); + try { + const res = await Apis.Asset.AssetHouses.List({ + asset_projects_id: props?.item?.asset_projects_id, + asset_buildings_id: buildingId, + asset_units_id: unitId, + }); + + if (res?.data) { + const houses = res.data.map((house: any) => ({ + id: house.id, + key: `house-${house.id}`, + title: `${house.name} (${house.floor}层)`, + isLeaf: true, + asset_buildings_id: buildingId, + asset_units_id: unitId, + })); + + // 更新树形数据 + const newTreeData = [...treeData]; + const buildingNode = newTreeData.find( + (node) => + node.asset_buildings_id === undefined && node.id === buildingId, + ); + + if (buildingNode && buildingNode.children) { + const unitNode = buildingNode.children.find( + (node) => node.key === unitKey, + ); + if (unitNode) { + unitNode.children = houses; + } + } + + setTreeData(newTreeData); + } + } catch (error) { + console.error('加载房屋失败:', error); + } finally { + setLoading(false); + } + }; + + // 初始化加载数据 + useEffect(() => { + if (props?.item?.asset_projects_id) { + loadBuildings(); + } else { + console.warn('缺少 asset_projects_id 参数'); + } + }, [props?.item?.id]); + + // 处理节点展开 + const onExpand = (expandedKeysValue: React.Key[]) => { + setExpandedKeys(expandedKeysValue); + setAutoExpandParent(false); + }; + + // 处理节点选中 + const onCheck = ( + 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(); + 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 ( + + } + node={ + + } + > +
+
+
+ + 全选 + +
+ + {loading &&
加载中...
} + + +
+ +
+
+ 已选房屋 ({selectedHouses.length}) +
+ +
+ {selectedHouses.length > 0 ? ( +
    + {selectedHouses.map((house) => ( +
  • {house.name}
  • + ))} +
+ ) : ( +
+ 暂无选中房屋{' '} +
+ )} +
+
+
+ +
+ + + + +
+
+ } + /> + ); +} diff --git a/src/pages/banner/modals/BannerCreate.tsx b/src/pages/banner/modals/BannerCreate.tsx index f606a9d..291bfa8 100644 --- a/src/pages/banner/modals/BannerCreate.tsx +++ b/src/pages/banner/modals/BannerCreate.tsx @@ -20,10 +20,14 @@ export default function Create(props: MyBetaModalFormProps) { wrapperCol={{ span: 24 }} width="600px" trigger={} + 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', diff --git a/src/pages/banner_space/components/BannerList.tsx b/src/pages/banner_space/components/BannerList.tsx index c64e740..8c7386f 100644 --- a/src/pages/banner_space/components/BannerList.tsx +++ b/src/pages/banner_space/components/BannerList.tsx @@ -32,7 +32,10 @@ export default function Index({ ...rest }) { toolBarRender={(action) => [ , diff --git a/src/pages/banner_space/modals/BannerSpaceCreate.tsx b/src/pages/banner_space/modals/BannerSpaceCreate.tsx index def0cfe..c3117de 100644 --- a/src/pages/banner_space/modals/BannerSpaceCreate.tsx +++ b/src/pages/banner_space/modals/BannerSpaceCreate.tsx @@ -18,6 +18,7 @@ export default function Create(props: MyBetaModalFormProps) { wrapperCol={{ span: 24 }} width="500px" trigger={} + key={new Date().getTime()} onFinish={async (values) => Apis.Banner.BannerSpaces.Store(values) .then(() => { diff --git a/src/pages/company/components/Employees.tsx b/src/pages/company/components/Employees.tsx index 38e825d..7c04237 100644 --- a/src/pages/company/components/Employees.tsx +++ b/src/pages/company/components/Employees.tsx @@ -25,7 +25,7 @@ export default function Index(props: MyBetaModalFormProps) { toolBarRender={(action) => [ , diff --git a/src/pages/company/components/modals/EmployeeCreate.tsx b/src/pages/company/components/modals/EmployeeCreate.tsx index 0fda94b..7949d13 100644 --- a/src/pages/company/components/modals/EmployeeCreate.tsx +++ b/src/pages/company/components/modals/EmployeeCreate.tsx @@ -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', diff --git a/src/pages/company/components/modals/EmployeeUpdate.tsx b/src/pages/company/components/modals/EmployeeUpdate.tsx index 5a32033..373774a 100644 --- a/src/pages/company/components/modals/EmployeeUpdate.tsx +++ b/src/pages/company/components/modals/EmployeeUpdate.tsx @@ -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', diff --git a/src/pages/company/modals/CompanyCreate.tsx b/src/pages/company/modals/CompanyCreate.tsx index 680b72d..8d1e024 100644 --- a/src/pages/company/modals/CompanyCreate.tsx +++ b/src/pages/company/modals/CompanyCreate.tsx @@ -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', diff --git a/src/pages/company/modals/CompanyUpdate.tsx b/src/pages/company/modals/CompanyUpdate.tsx index 7b72009..2737c9d 100644 --- a/src/pages/company/modals/CompanyUpdate.tsx +++ b/src/pages/company/modals/CompanyUpdate.tsx @@ -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', diff --git a/src/pages/employees/index.tsx b/src/pages/employees/index.tsx index dae6194..4f7b76a 100644 --- a/src/pages/employees/index.tsx +++ b/src/pages/employees/index.tsx @@ -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) => [ - // , - // ]} + toolBarRender={(action) => [ + , + ]} columns={[ MyColumns.ID(), { diff --git a/src/pages/house_charge/$id.tsx b/src/pages/house_charge/$id.tsx new file mode 100644 index 0000000..425ccca --- /dev/null +++ b/src/pages/house_charge/$id.tsx @@ -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({}); + + // 注册当前页面为标签页 + 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: ( + loadShow()} + /> + ), + }, + ]; + return ( + + + + + + + ); +} diff --git a/src/pages/house_charge/components/BannerList.tsx b/src/pages/house_charge/components/BannerList.tsx new file mode 100644 index 0000000..8c7386f --- /dev/null +++ b/src/pages/house_charge/components/BannerList.tsx @@ -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(); + useEffect(() => { + actionLooks?.current.reloadAndRest(); + }, [rest.loadmore]); + + return ( + <> + > + {...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) => [ + , + ]} + 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) => ( + + + + + ), + }), + ]} + /> + + ); +} diff --git a/src/pages/house_charge/components/BannerSpaceInfo.tsx b/src/pages/house_charge/components/BannerSpaceInfo.tsx new file mode 100644 index 0000000..2d9297e --- /dev/null +++ b/src/pages/house_charge/components/BannerSpaceInfo.tsx @@ -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 ( + + + + + {item?.name} + + + + + + + {item?.remark} + + + + + ); +} diff --git a/src/pages/house_charge/index.tsx b/src/pages/house_charge/index.tsx new file mode 100644 index 0000000..a89faf4 --- /dev/null +++ b/src/pages/house_charge/index.tsx @@ -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 ( + + + MyProTableProps.request( + params, + sort, + Apis.HouseCharage.HouseChargeStandards.List, + ) + } + toolBarRender={(action) => [ + , + ]} + 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) => ( + + { + navigate(`/house_charge/${item.id}`); + }} + /> + + + Apis.HouseCharage.HouseChargeStandards.Delete({ + id: item.id, + }).then(() => action?.reload()) + } + /> + + ), + }), + ]} + /> + + ); +} diff --git a/src/pages/house_charge/modals/HouseChargeCreate.tsx b/src/pages/house_charge/modals/HouseChargeCreate.tsx new file mode 100644 index 0000000..7689299 --- /dev/null +++ b/src/pages/house_charge/modals/HouseChargeCreate.tsx @@ -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(); + const [form] = Form.useForm(); + + return ( + + {...MyModalFormProps.props} + title={`添加收费标准`} + wrapperCol={{ span: 24 }} + width="600px" + trigger={} + 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, + }, + }, + ]} + /> + ); +} diff --git a/src/pages/house_charge/modals/HouseChargeUpdate.tsx b/src/pages/house_charge/modals/HouseChargeUpdate.tsx new file mode 100644 index 0000000..eb86cfd --- /dev/null +++ b/src/pages/house_charge/modals/HouseChargeUpdate.tsx @@ -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 ( + + {...MyModalFormProps.props} + title={`编辑广告位`} + trigger={} + wrapperCol={{ span: 24 }} + width="600px" + key={new Date().getTime()} + form={form} + onOpenChange={(open: any) => { + if (open && props.item) { + form.setFieldsValue(props.item); + } + }} + onFinish={async (values) => + Apis.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, + }, + }, + ]} + /> + ); +} \ No newline at end of file diff --git a/src/pages/work_order/modals/WorkOrderCreate.tsx b/src/pages/work_order/modals/WorkOrderCreate.tsx index e8ce280..e45d8b2 100644 --- a/src/pages/work_order/modals/WorkOrderCreate.tsx +++ b/src/pages/work_order/modals/WorkOrderCreate.tsx @@ -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: '请输入手机号码',