feat:客户列表
All checks were successful
Build and Push Docker Image / build (push) Successful in 3m32s

This commit is contained in:
uiuJun 2025-10-01 18:01:02 +08:00
parent c9ea61ef8f
commit fcaee2806f
10 changed files with 463 additions and 31 deletions

View File

@ -570,4 +570,39 @@ export const Selects = {
}, },
}; };
}, },
//获取项目仪表
AssetMeters(props?: PropsType): ReturnType {
const {
title = '选择仪表',
key = 'id',
required = false,
hideInTable = true,
...rest
} = props ?? {};
return {
title: title,
key: key,
valueType: 'select',
hideInTable: hideInTable,
formItemProps: { ...(required ? rulesHelper.number : {}) },
request: async (params) =>
(
await Apis.Meter.HouseMeters.List({
keywords: params?.KeyWords,
...params,
asset_projects_id: params?.asset_projects_id,
})
).data,
...rest,
fieldProps: {
showSearch: true,
fieldNames: {
label: 'label',
value: 'value',
},
...rest?.fieldProps,
},
};
},
}; };

View File

@ -98,6 +98,18 @@ export default function Index({ title = '账单任务' }) {
render: (_, item: any, index, action) => ( render: (_, item: any, index, action) => (
<Space key={index}> <Space key={index}>
<TaskShow item={item} title="查看" reload={action?.reload} /> <TaskShow item={item} title="查看" reload={action?.reload} />
<MyButtons.Default
title="重新执行"
type="link"
color="primary"
isConfirm
description="是否重新执行此任务?"
onConfirm={() =>
Apis.HouseCharage.HouseChargeTasks.ExecuteTask({
id: item.id,
}).then(() => action?.reload())
}
/>
<MyButtons.Delete <MyButtons.Delete
onConfirm={() => onConfirm={() =>
Apis.HouseCharage.HouseChargeTasks.Delete({ Apis.HouseCharage.HouseChargeTasks.Delete({

View File

@ -1,8 +1,14 @@
import { MyBetaModalFormProps, MyColumns, MyProTableProps } from '@/common'; import {
MyBetaModalFormProps,
MyButtons,
MyColumns,
MyProTableProps,
} from '@/common';
import { MyModal } from '@/components/MyModal'; import { MyModal } from '@/components/MyModal';
import { Apis } from '@/gen/Apis'; import { Apis } from '@/gen/Apis';
import { HouseChargeTaskDetailsStatusEnum } from '@/gen/Enums'; import { HouseChargeTaskDetailsStatusEnum } from '@/gen/Enums';
import { ProTable } from '@ant-design/pro-components'; import { ProTable } from '@ant-design/pro-components';
import { Space } from 'antd';
export default function AssetInfo(props: MyBetaModalFormProps) { export default function AssetInfo(props: MyBetaModalFormProps) {
return ( return (
@ -61,6 +67,24 @@ export default function AssetInfo(props: MyBetaModalFormProps) {
dataIndex: 'processed_time', dataIndex: 'processed_time',
search: false, search: false,
}, },
MyColumns.Option({
render: (_, item: any, index, action) => (
<Space key={index}>
<MyButtons.Default
title="重新执行"
type="link"
color="primary"
isConfirm
description="确认执行此任务吗?"
onConfirm={() =>
Apis.HouseCharage.HouseChargeTaskDetails.CreateHouseBill({
id: item.id,
}).then(() => action?.reload())
}
/>
</Space>
),
}),
]} ]}
/> />
} }

View File

@ -0,0 +1,74 @@
import { MyBetaModalFormProps, MyColumns, MyProTableProps } from '@/common';
import { Apis } from '@/gen/Apis';
import { HouseMeterReadingsOperationTypeEnum } from '@/gen/Enums';
import { ProTable } from '@ant-design/pro-components';
export default function Index(props: MyBetaModalFormProps) {
console.log(props?.item, 'pppppppp');
return (
<>
<ProTable
{...MyProTableProps.props}
request={async (params, sort) =>
MyProTableProps.request(
{ ...params, phone: props?.item?.phone },
sort,
Apis.Archive.HouseOccupants.CustomerHouseByPhone,
)
}
// search={false}
// options={false}
columns={[
MyColumns.EnumTag({
title: '操作类型',
dataIndex: 'operation_type',
valueEnum: HouseMeterReadingsOperationTypeEnum,
}),
{
title: '抄表读数',
dataIndex: 'current_reading',
search: false,
},
{
title: '抄表用量',
dataIndex: 'usage_amount',
search: false,
},
{
title: '抄表时间',
dataIndex: 'reading_time',
search: false,
},
{
title: '抄表人',
dataIndex: ['company_employee', 'name'],
search: false,
},
{
title: '备注',
dataIndex: 'remark',
search: false,
},
{
title: '账单状态',
dataIndex: 'bill_status',
render: (value) => (value ? '已生成' : '未生成'),
search: false,
},
// MyColumns.Option({
// render: (_, item: any, index, action) => (
// <Space key={index}>
// {/* 只有未生成账单的抄表记录,且不是重置读数,才显示修正按钮 */}
// {!item?.bill_status &&
// item?.operation_type !==
// HouseMeterReadingsOperationTypeEnum.ResetReading.value && (
// <CorrectReading item={item} reload={action?.reload} />
// )}
// </Space>
// ),
// }),
]}
/>
</>
);
}

View File

@ -0,0 +1,70 @@
import { MyBetaModalFormProps, renderTextHelper } from '@/common';
import { HouseOccupantsCardTypeEnum, SexEnum } from '@/gen/Enums';
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
import { Image, 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="姓名">
<div style={{ fontWeight: 'bold' }}>{item?.name}</div>
</ProDescriptions.Item>
<ProDescriptions.Item label="电话">
{item?.phone}
</ProDescriptions.Item>
<ProDescriptions.Item label="性别">
<renderTextHelper.Tag Enums={SexEnum} value={item?.sex} key="sex" />
</ProDescriptions.Item>
<ProDescriptions.Item label="证件类型">
<renderTextHelper.Tag
Enums={HouseOccupantsCardTypeEnum}
value={props?.item?.card_type}
key="card_type"
/>
</ProDescriptions.Item>
<ProDescriptions.Item label="证件号码" span={2}>
{props?.item?.id_card}
</ProDescriptions.Item>
<ProDescriptions.Item label="证件材料" span={3}>
<Space>
<Image.PreviewGroup>
{props?.item?.card_front_image?.map(
(res: any, index: number) => {
return (
<Image
width={40}
height={30}
src={res?.url || ''}
key={`${res?.name}_${index}`}
/>
);
},
)}
</Image.PreviewGroup>
<Image.PreviewGroup>
{props?.item?.card_back_image?.map(
(res: any, index: number) => {
return (
<Image
width={40}
height={30}
src={res?.url || ''}
key={`${res?.name}_${index}`}
/>
);
},
)}
</Image.PreviewGroup>
</Space>
</ProDescriptions.Item>
</ProDescriptions>
</ProCard>
</Space>
);
}

View File

@ -0,0 +1,63 @@
import {
MyButtons,
MyColumns,
MyPageContainer,
MyProTableProps,
usePageTabs,
} from '@/common';
import { Apis } from '@/gen/Apis';
import { ProTable } from '@ant-design/pro-components';
import { useNavigate } from '@umijs/max';
import { Space } from 'antd';
export default function Index({ title = '房客关系' }) {
const navigate = useNavigate();
// 注册当前页面为标签页
usePageTabs({
tabKey: 'archive-asset-houses',
tabLabel: title,
});
return (
<MyPageContainer title={title}>
<ProTable
{...MyProTableProps.props}
request={async (params, sort) =>
MyProTableProps.request(
params,
sort,
Apis.Archive.HouseOccupants.CustomerList,
)
}
columns={[
MyColumns.ID(),
{
title: '客户名称',
dataIndex: 'name',
search: {
transform: (value) => {
return { name: value };
},
},
},
{
title: '客户电话',
dataIndex: 'phone',
},
MyColumns.UpdatedAt(),
MyColumns.Option({
render: (_, item: any, index, action) => (
<Space key={index}>
<MyButtons.View
title="查看"
onClick={() => {
navigate(`/customer/show/${item.id}`);
}}
/>
</Space>
),
}),
]}
/>
</MyPageContainer>
);
}

View File

@ -0,0 +1,63 @@
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 CustomerHouse from '../components/CustomerHouse';
import CustomerInfo from '../components/CustomerInfo';
export default function Show({ title = '客户档案' }) {
const { id } = useParams<{ id: string }>();
const [data, setShow] = useState<any>({});
// 注册标签页
const { addTab } = usePageTabs({
tabKey: `customer-detail-${id}`,
tabLabel: `${data?.name}档案` || title,
});
const loadShow = () => {
let paramsId: any = { id: id ?? 0 };
Apis.Archive.HouseOccupants.Show(paramsId).then((res) => {
setShow(res?.data);
// 更新标签页标题
if (res?.data?.name) {
addTab({
key: `customer-detail-${id}`,
label: `${res?.data?.name}档案`,
path: `/customer/show/${id}`,
});
}
});
};
useEffect(() => {
loadShow();
}, [id]);
let items = [
{
label: '关联房屋',
key: '1',
closable: false,
children: (
<CustomerHouse
item={{ ...data, phone: data?.phone }}
reload={() => {
loadShow();
}}
/>
),
},
];
return (
<MyPageContainer title={title}>
<CustomerInfo item={data} reload={loadShow} />
<ProCard style={{ marginTop: 16 }}>
<Tabs type="card" items={items} defaultActiveKey="1" size="small" />
</ProCard>
</MyPageContainer>
);
}

View File

@ -15,10 +15,10 @@ import { Space } from 'antd';
import TaskCreate from './modals/TaskCreate'; import TaskCreate from './modals/TaskCreate';
import TaskShow from './modals/TaskShow'; import TaskShow from './modals/TaskShow';
export default function Index({ title = '账单任务' }) { export default function Index({ title = '仪表账单' }) {
// 注册当前页面为标签页 // 注册当前页面为标签页
usePageTabs({ usePageTabs({
tabKey: 'house_charge_tasks', tabKey: 'house_meter_tasks',
tabLabel: title, tabLabel: title,
}); });

View File

@ -7,7 +7,10 @@ import {
} from '@/common'; } from '@/common';
import { Selects } from '@/components/Select'; import { Selects } from '@/components/Select';
import { Apis } from '@/gen/Apis'; import { Apis } from '@/gen/Apis';
import { HouseMeterTasksGenerationMethodEnum } from '@/gen/Enums'; import {
HouseMetersMeterTypeEnum,
HouseMeterTasksGenerationMethodEnum,
} from '@/gen/Enums';
import { BetaSchemaForm } from '@ant-design/pro-components'; import { BetaSchemaForm } from '@ant-design/pro-components';
import { Form, message } from 'antd'; import { Form, message } from 'antd';
@ -30,8 +33,11 @@ export default function Create(props: MyBetaModalFormProps) {
form.resetFields(); // 清空表单数据 form.resetFields(); // 清空表单数据
} }
}} }}
onFinish={async (values) => onFinish={async (values: any) =>
Apis.Meter.HouseMeterTasks.Store(values) Apis.Meter.HouseMeterTasks.Store({
...values,
data: [values?.data_id],
})
.then(() => { .then(() => {
props.reload?.(); props.reload?.();
message.success(props.title + '账单任务创建成功'); message.success(props.title + '账单任务创建成功');
@ -53,26 +59,7 @@ export default function Create(props: MyBetaModalFormProps) {
}, },
}, },
}), }),
{
valueType: 'dependency',
name: ['asset_projects_id'],
columns: ({ asset_projects_id }) => {
return [
Selects?.ChargeStandard({
title: '选择收费标准',
key: 'house_charge_standards_id',
params: {
asset_projects_id: asset_projects_id,
},
colProps: { span: 24 },
formItemProps: { ...rulesHelper.text },
fieldProps: {
showSearch: true,
},
}),
];
},
},
{ {
key: 'month', key: 'month',
title: '选择生成月份', title: '选择生成月份',
@ -118,14 +105,118 @@ export default function Create(props: MyBetaModalFormProps) {
}, },
formItemProps: { ...rulesHelper.text }, formItemProps: { ...rulesHelper.text },
}, },
MyFormItems.EnumRadio({ MyFormItems.EnumRadio({
key: 'generation_method', key: 'meter_type',
title: '收款渠道', title: '仪表类型',
colProps: { span: 24 }, colProps: { span: 24 },
valueEnum: HouseMeterTasksGenerationMethodEnum, valueEnum: HouseMetersMeterTypeEnum,
required: true, required: true,
fieldProps: {
onChange: () => {
// 切换计量单位时清空计费模式
form.setFieldValue('generation_method', undefined);
form.setFieldValue('data', undefined);
},
},
}), }),
{
name: ['meter_type'],
valueType: 'dependency',
columns: ({ meter_type }: any) => {
return meter_type === HouseMetersMeterTypeEnum.CommonMeter.value
? [
MyFormItems.EnumRadio({
key: 'generation_method',
title: '生成方式',
colProps: { span: 24 },
valueEnum: () => {
let obj: any = JSON.parse(
JSON.stringify(HouseMeterTasksGenerationMethodEnum),
);
delete obj.Unit;
delete obj.Building;
return obj;
},
required: true,
}),
Selects?.AssetMeters({
title: '选择仪表',
params: {
asset_projects_id:
form.getFieldValue('asset_projects_id'),
// 仪表类型必须为房屋仪表
meter_type: HouseMetersMeterTypeEnum.CommonMeter.value,
},
key: 'data_id',
colProps: { span: 24 },
formItemProps: { ...rulesHelper.text },
}),
]
: meter_type === HouseMetersMeterTypeEnum.HouseMeter.value
? [
MyFormItems.EnumRadio({
key: 'generation_method',
title: '生成方式',
colProps: { span: 24 },
valueEnum: HouseMeterTasksGenerationMethodEnum,
required: true,
}),
{
name: ['generation_method'],
valueType: 'dependency',
columns: ({ generation_method }: any) => {
return generation_method ===
HouseMeterTasksGenerationMethodEnum.Building.value
? [
Selects?.AssetBuildings({
title: '选择楼栋',
key: 'data_id',
params: {
asset_projects_id:
form.getFieldValue('asset_projects_id'),
},
colProps: { span: 24 },
formItemProps: { ...rulesHelper.text },
}),
]
: generation_method ===
HouseMeterTasksGenerationMethodEnum.Unit.value
? [
Selects?.AssetUnits({
title: '选择单元',
key: 'data_id',
params: {
asset_projects_id:
form.getFieldValue('asset_projects_id'),
},
colProps: { span: 24 },
formItemProps: { ...rulesHelper.text },
}),
]
: generation_method ===
HouseMeterTasksGenerationMethodEnum.Meter.value
? [
Selects?.AssetMeters({
title: '选择仪表',
params: {
asset_projects_id:
form.getFieldValue('asset_projects_id'),
// 仪表类型必须为房屋仪表
meter_type:
HouseMetersMeterTypeEnum.HouseMeter.value,
},
key: 'data_id',
colProps: { span: 24 },
formItemProps: { ...rulesHelper.text },
}),
]
: [];
},
},
]
: [];
},
},
]} ]}
/> />
); );

View File

@ -17,7 +17,7 @@ export default function AssetInfo(props: MyBetaModalFormProps) {
MyProTableProps.request( MyProTableProps.request(
{ ...params, house_charge_tasks_id: props?.item?.id }, { ...params, house_charge_tasks_id: props?.item?.id },
sort, sort,
Apis.HouseCharage.HouseChargeTaskDetails.List, Apis.Meter.HouseMeterTasks.List,
) )
} }
columns={[ columns={[