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

Reviewed-on: https://code.juyouwu.cn/pay/pay-admin/pulls/1
This commit is contained in:
yangting 2025-09-05 09:13:56 +08:00
commit e8c99b44d0
82 changed files with 4847 additions and 1331 deletions

View File

@ -64,7 +64,7 @@ jobs:
with:
host: ${{ vars.DEV_HOST_IP }}
port: 22
username: 'ubuntu'
username: 'root'
password: ${{ secrets.DEV_HOST_PASSWORD }}
script: |
docker login -u ${{ vars.REGISTRY_USERNAME }} -p ${{ secrets.REGISTRY_PASSWORD }} ${{ vars.REGISTRY_URL}}

View File

@ -12,10 +12,6 @@ env:
jobs:
build:
runs-on: ubuntu-latest
container:
image: zuogeus/act-ubuntu:node18
options: --add-host nexus.zzwb.cc:192.168.2.7
steps:
- name: Setup Environments
shell: bash
@ -25,54 +21,54 @@ jobs:
echo "IMAGE_NAME=${{ vars.REGISTRY_URL }}/${{ vars.REGISTRY_NAMESPACE }}/$REPO:$GITHUB_REF_NAME" >> $GITHUB_ENV
- name: Checkout
uses: https://gitee.com/zuowenbo/checkout@v4.1.1
uses: https://gitee.com/zuowenbo/checkout@v4.2.2
- name: Get npm cache directory
id: npm-cache-dir
shell: bash
run: echo "dir=$(npm config get cache)" >> ${GITHUB_OUTPUT}
- name: Set node_modules cache
uses: https://gitee.com/zuowenbo/cache@v4.0.0
id: npm-cache
- name: Cache Docker layers
uses: https://gitee.com/zuowenbo/cache@v4.2.1
with:
path: ${{ steps.npm-cache-dir.outputs.dir }}
key: ${{ runner.os }}-node-umi4-${{ hashFiles('**/package-lock.json') }}
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ env.REPO_NAME }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-node-umi4-
- run: npm install --registry=https://registry.npmmirror.com
- run: npm run build
${{ runner.os }}-buildx-${{ env.REPO_NAME }}-
- name: Set up Docker Buildx
uses: https://gitee.com/zuowenbo/setup-buildx-action@v3.0.0
uses: https://gitee.com/zuowenbo/setup-buildx-action@v3.9.0
with:
driver-opts: network=host
driver-opts: image=registry.cn-shenzhen.aliyuncs.com/zuoge-proxy/buildkit:buildx-stable-1
- name: Login to Docker Hub
uses: https://gitee.com/zuowenbo/login-action@v3.0.0
uses: https://gitee.com/zuowenbo/login-action@v3.3.0
with:
registry: ${{ vars.REGISTRY_URL }}
username: ${{ vars.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Build and push final image
uses: https://gitee.com/zuowenbo/build-push-action@v5.1.0
uses: https://gitee.com/zuowenbo/build-push-action@v6.14.0
with:
context: .
tags: ${{ env.IMAGE_NAME }}
push: true
platforms: linux/amd64
build-args: BRANCH=${{ env.GITHUB_REF_NAME }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
- name: Move cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
- name: Deploy to remote
uses: https://gitee.com/zuowenbo/ssh-action@v1.0.3
with:
host: ${{ vars.LOAN_MAIN_HOST_IP_PHP }}
host: ${{ vars.MAIN_HOST_IP }}
port: 22
username: 'ubuntu'
password: ${{ secrets.LOAN_MAIN_HOST_PASSWORD }}
username: 'root'
password: ${{ secrets.MAIN_HOST_PASSWORD }}
script: |
docker login -u ${{ vars.REGISTRY_USERNAME }} -p ${{ secrets.REGISTRY_PASSWORD }} ${{ vars.REGISTRY_URL}}
docker volume create ${{ env.REPO_NAME }} || true
docker pull ${{ env.IMAGE_NAME }}
docker stop ${{ env.REPO_NAME }} || true
docker rm ${{ env.REPO_NAME }} || true

View File

@ -14,8 +14,9 @@ export default defineConfig({
},
proxy: {
'/api/': {
target: 'http://yt:8001',
// target: 'http://10.39.13.80:8001',
// target: 'http://yt:8003',
target: 'http://10.39.13.80:8001',
// target: 'https://test-admin.linyikj.com.cn/',
// target: 'http://we6f9c65.natappfree.cc',
// target: 'https://loanos-test.nchl.net/',
changeOrigin: true,

View File

@ -0,0 +1,14 @@
import { SlateDescendant } from '@wangeditor/editor';
declare module '@wangeditor/editor' {
// 扩展 Text
interface SlateText {
text: string;
}
// 扩展 Element
interface SlateElement {
type: string;
children: SlateDescendant[];
}
}

View File

@ -0,0 +1,113 @@
import { Apis } from '@/gen/Apis';
import { IDomEditor, IToolbarConfig } from '@wangeditor/editor';
import { Editor, Toolbar } from '@wangeditor/editor-for-react';
import '@wangeditor/editor/dist/css/style.css'; // 引入 css
import axios from 'axios';
import { useEffect, useState } from 'react';
type InsertFnType = (url: string) => void;
function MyEditor(props: any) {
// editor 实例
const [editor, setEditor] = useState<IDomEditor | null>(null); // TS 语法
// 编辑器内容
const [html, setHtml] = useState('');
useEffect(() => {
setTimeout(() => {
setHtml(props.value || '');
}, 500);
}, []);
// 工具栏配置
const toolbarConfig: Partial<IToolbarConfig> = {}; // TS 语法
// const toolbarConfig = { } // JS 语法
const customRequest = (
file: any,
onSuccess: (url: string, file: any) => void,
) => {
Apis.Auth.PreUpload({
filename: file.name,
alc: 'public-read',
}).then(async (res) => {
axios
.put(res.data.url, file, {
headers: res.data.headers,
onUploadProgress: ({ total, loaded }) => {
console.log('loaded', total, loaded);
},
})
.then(({ data: response }) => {
console.log('response', response);
if (response.errorMessage) {
console.log(response, file);
} else {
onSuccess(res.data.url.split('?')[0], file);
}
});
});
return {
abort() {
console.log('upload progress is aborted.');
},
};
};
// 编辑器配置
const editorConfig: Partial<any> = {
// TS 语法
// const editorConfig = { // JS 语法
placeholder: '请输入内容...',
MENU_CONF: {
uploadVideo: {
async customUpload(file: File, insertFn: InsertFnType) {
// TS 语法
customRequest(file, (url) => {
console.log(url, '视频');
insertFn(url);
});
},
},
uploadImage: {
async customUpload(file: File, insertFn: InsertFnType) {
// TS 语法
customRequest(file, (url) => {
console.log(url, '图片');
insertFn(url);
});
},
},
},
};
// 及时销毁 editor ,重要!
useEffect(() => {
return () => {
if (editor === null) return;
editor.destroy();
setEditor(null);
};
}, [editor]);
return (
<div style={{ border: '1px solid #ccc', zIndex: 100 }} key="Editor">
<Toolbar
editor={editor}
defaultConfig={toolbarConfig}
mode="default"
key="Toolbar"
style={{ borderBottom: '1px solid #ccc' }}
/>
<Editor
defaultConfig={editorConfig}
value={html}
key="Editor2"
onCreated={setEditor}
onChange={(editor) => props?.onChange?.(editor.getHtml())}
mode="default"
style={{ height: '500px', overflowY: 'hidden' }}
/>
</div>
);
}
export default MyEditor;

View File

@ -49,14 +49,14 @@ export const MyButtons = {
},
View({ title, ...rest }: MyButtonsType): JSX.Element {
return (
<Button type="link" size="small" {...rest}>
<Button type="primary" size="small" {...rest}>
{title ?? '查看'}
</Button>
);
},
Edit({ title = '编辑', ...rest }: MyButtonsType): JSX.Element {
return (
<Button type="link" size="small" icon={<EditOutlined />} {...rest}>
<Button type="primary" size="small" icon={<EditOutlined />} {...rest}>
{title}
</Button>
);

View File

@ -83,27 +83,44 @@ export function MyUploadImages({
Apis.Common.Auth.PreUpload({
filename: file.name,
alc: 'public-read',
}).then(async (res) => {
axios
.put(res.data.url, file, {
headers: res.data.headers,
onUploadProgress: ({ total, loaded }) => {
if (total)
onProgress(
{ percent: Math.round((loaded / total) * 100).toFixed(2) },
file,
);
},
})
.then(({ data: response }) => {
console.log('response', response);
if (response.errorMessage) {
onError(response, file);
} else {
onSuccess(res.data.url.split('?')[0], file);
}
});
});
})
.then(async (res) => {
try {
axios
.put(res.data.url, file, {
headers: res.data.headers,
onUploadProgress: ({ total, loaded }) => {
if (total)
onProgress(
{ percent: Math.round((loaded / total) * 100).toFixed(2) },
file,
);
},
})
.then(({ data: response }) => {
console.log('response', response);
if (response && response.errorMessage) {
onError(response, file);
} else {
// 确保URL正确处理
const fileUrl = res.data.url.split('?')[0];
console.log('文件上传成功URL:', fileUrl);
onSuccess(fileUrl, file);
}
})
.catch((error) => {
console.error('上传文件时出错:', error);
onError(error, file);
});
} catch (error) {
console.error('处理上传请求时出错:', error);
onError(error, file);
}
})
.catch((error) => {
console.error('获取预上传URL时出错:', error);
onError(error, file);
});
return {
abort() {

View File

@ -7,6 +7,7 @@ type MyImportModalType = {
title?: string;
type?: any;
params?: Record<string, any>;
size?: 'small' | 'middle' | 'large';
templateApi?: () => Promise<MyResponseType>;
importApi: (data: any) => Promise<MyResponseType>;
reload?: () => void;
@ -17,17 +18,22 @@ export function MyImportModal(props: MyImportModalType) {
const [loading, setLoading] = useState(false);
const [formData, setFormData] = useState<FormData | undefined>(undefined);
const { title = '批量导入', params = {}, type = 'primary' } = props;
const {
title = '批量导入',
params = {},
type = 'primary',
size = 'middle',
} = props;
return (
<>
{type === 'danger' ? (
<Button onClick={() => setOpen(true)} type="primary" danger>
<Button onClick={() => setOpen(true)} type="primary" danger size={size}>
<ImportOutlined />
{title}
</Button>
) : (
<Button onClick={() => setOpen(true)} type="primary">
<Button onClick={() => setOpen(true)} type="primary" size={size}>
<ImportOutlined />
{title}
</Button>
@ -54,7 +60,10 @@ export function MyImportModal(props: MyImportModalType) {
});
}}
confirmLoading={loading}
destroyOnClose={true}
// 使用 destroyOnClose 已弃用,建议使用 afterClose 处理清理逻辑
afterClose={() => {
setFormData(undefined);
}}
maskClosable={false}
footer={(dom) => {
return (

View File

@ -364,7 +364,8 @@ export function MyPageContainer({
onChange={handleTabChange}
onEdit={handleTabEdit}
hideAdd
size="small"
size="middle"
// 标签size
renderTabBar={renderTabBar}
items={tabs.map((tab) => ({
key: tab.key,
@ -372,6 +373,7 @@ export function MyPageContainer({
closable: tab.closable,
}))}
style={{
marginTop: 6,
marginBottom: 0,
}}
className="tabs-header-only"

View File

@ -1,191 +0,0 @@
import { PlusOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons';
import { history } from '@umijs/max';
import { Button, Card, Divider, Space } from 'antd';
import { MyPageContainer } from './MyPageContainer';
import { usePageTabs } from './usePageTabs';
/**
* 使
* 使MyPageContainer的多标签页功能
*/
export function TabsExample() {
const tabsApi = usePageTabs({
tabKey: 'tabs-example',
tabLabel: '标签页示例',
});
const handleAddTab = (key: string, label: string, path: string) => {
tabsApi.addTab({
key,
label,
path,
closable: true,
});
history.push(path);
};
const handleAddTabNext = (key: string, label: string, path: string) => {
tabsApi.addTabNext({
key,
label,
path,
closable: true,
});
history.push(path);
};
return (
<MyPageContainer
enableTabs
tabKey="tabs-example"
tabLabel="标签页示例"
title="多标签页功能演示"
>
<Card title="标签页操作示例" style={{ marginBottom: 16 }}>
<Space wrap>
<Button
type="primary"
icon={<PlusOutlined />}
onClick={() => handleAddTab('user-list', '用户列表', '/users')}
>
</Button>
<Button
icon={<UserOutlined />}
onClick={() =>
handleAddTab('user-profile', '用户详情', '/users/profile')
}
>
</Button>
<Button
icon={<SettingOutlined />}
onClick={() => handleAddTab('settings', '系统设置', '/settings')}
>
</Button>
</Space>
<Divider orientation="left"></Divider>
<Space wrap>
<Button
type="dashed"
icon={<PlusOutlined />}
onClick={() =>
handleAddTabNext('company-1', '机构详情-1', '/company/1')
}
>
-1
</Button>
<Button
type="dashed"
icon={<UserOutlined />}
onClick={() =>
handleAddTabNext('employee-1', '员工详情-1', '/employee/1')
}
>
-1
</Button>
<Button
type="dashed"
icon={<SettingOutlined />}
onClick={() =>
handleAddTabNext('project-1', '项目详情-1', '/project/1')
}
>
-1
</Button>
</Space>
<Divider />
<Space wrap>
<Button onClick={() => tabsApi.closeOtherTabs()}></Button>
<Button onClick={() => tabsApi.closeLeftTabs()}></Button>
<Button onClick={() => tabsApi.closeRightTabs()}></Button>
<Button onClick={() => tabsApi.refreshTab()}></Button>
</Space>
</Card>
<Card title="功能说明">
<div style={{ lineHeight: '1.8' }}>
<h4>🎯 </h4>
<ul>
<li>
<strong></strong>
</li>
<li>
<strong></strong>
</li>
<li>
<strong></strong>
</li>
<li>
<strong></strong>
</li>
<li>
<strong></strong>
</li>
</ul>
<h4>🖱 </h4>
<ul>
<li>
<strong></strong>
</li>
<li>
<strong></strong>
</li>
<li>
<strong></strong>
</li>
<li>
<strong></strong>
</li>
<li>
<strong></strong>
</li>
</ul>
<h4>💻 使</h4>
<pre
style={{
background: '#f5f5f5',
padding: '12px',
borderRadius: '4px',
}}
>
{`// 1. 在页面组件中使用
import { MyPageContainer, usePageTabs } from '@/common';
function YourPage() {
usePageTabs({
tabKey: 'your-page',
tabLabel: '页面标题'
});
return (
<MyPageContainer
enableTabs
tabKey="your-page"
tabLabel="页面标题"
>
{/* 页面内容 */}
</MyPageContainer>
);
}`}
</pre>
</div>
</Card>
</MyPageContainer>
);
}

View File

@ -46,15 +46,7 @@ export const MyFormItems = {
...props,
};
},
// RichText(props: PropsType): ReturnType {
// return {
// renderFormItem: () => <MyRichText />,
// formItemProps: {
// ...(props?.required ? rulesHelper.richtext : {}),
// },
// ...props,
// };
// },
UploadImages({
max = 1,
help,

View File

@ -10,7 +10,7 @@ export * from './components/layout/MyCommonModal';
export * from './components/layout/MyImportModal';
export * from './components/layout/MyPageContainer';
export * from './components/layout/MyRootContainer';
export * from './components/layout/TabsExample';
export * from './components/layout/usePageTabs';
export * from './components/props/MyDrawerProps';

View File

@ -5,6 +5,7 @@ import {
ProFormText,
} from '@ant-design/pro-components';
import { rulesHelper } from '@/common';
import { DefaultOptionType } from 'antd/es/cascader';
import data from './city.json';
const request = async () => Promise.resolve(data as Record<string, any>[]);
@ -45,9 +46,9 @@ export const Address = {
return accumulator;
}, {} as Record<string, string>);
},
// formItemProps: {
// ...(required ? rulesHelper.array : {}),
// },
formItemProps: {
...(required ? rulesHelper.array : {}),
},
fieldProps: {
showSearch: true,
changeOnSelect: true,

View File

@ -0,0 +1,45 @@
import { Button, Dropdown, MenuProps } from 'antd';
export const MyExport = (props: any) => {
const items: MenuProps['items'] = [
{
key: '1',
label: '当前页(含查询条件)',
onClick: () =>
props?.keyParams
? props?.download?.({ download_type: 'page', ...props?.item })
: props?.download?.Export?.({
download_type: 'page',
...props?.item,
}),
},
{
key: '2',
label: '所有页(含查询条件)',
onClick: () =>
props?.keyParams
? props?.download?.({ download_type: 'query', ...props?.item })
: props?.download?.Export?.({
download_type: 'query',
...props?.item,
}),
},
{
key: '3',
label: '所有记录',
onClick: () =>
props?.keyParams
? props?.download?.({ download_type: 'all', ...props?.item })
: props?.download?.Export?.({
download_type: 'all',
...props?.item,
}),
},
];
return (
<Dropdown menu={{ items }} placement="bottomLeft">
<Button type="primary">{props?.title || '导出'}</Button>
</Dropdown>
);
};

View File

@ -1,15 +1,15 @@
import { MyButtons } from '@/common';
import { Modal } from 'antd';
import { useImperativeHandle, useState } from 'react';
import { useImperativeHandle, useState } from 'react';
export function MyModal(props?: any) {
const [open, setOpen] = useState(false);
const close = () => {
setOpen(false)
}
setOpen(false);
};
useImperativeHandle(props.myRef, () => ({
close
}));
close,
}));
return (
<>
{props?.trigger ? (
@ -17,6 +17,7 @@ export function MyModal(props?: any) {
) : (
<MyButtons.View
title={props.title || '详情'}
type={props.type || 'primary'}
onClick={() => setOpen(true)}
/>
)}

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

@ -46,18 +46,12 @@ declare namespace ApiTypes {
"asset_houses_id": number; // 房屋ID
"type": string; // 类型,[enum:HouseRegistersTypeEnum]
"status"?: string; // 状态,[enum:HouseRegistersStatusEnum]
"house_status"?: string; // 房屋状态,[enum:HouseRegistersHouseStatusEnum]
"usage_plan"?: string; // 使用计划,[enum:HouseRegistersUsagePlanEnum]
"customer_type"?: string; // 客户类型,[enum:HouseRegistersCustomerTypeEnum]
"customer_info"?: string[]; // 客户信息
"ownership_info"?: string[]; // 产权信息
};
type Update = {
"id": number; // id
"type": string; // 类型,[enum:HouseRegistersTypeEnum]
"house_status"?: string; // 房屋状态,[enum:HouseRegistersHouseStatusEnum]
"usage_plan"?: string; // 使用计划,[enum:HouseRegistersUsagePlanEnum]
"customer_type"?: string; // 客户类型,[enum:HouseRegistersCustomerTypeEnum]
"customer_info"?: string[]; // 客户信息
"ownership_info"?: string[]; // 产权信息
};
@ -127,6 +121,8 @@ declare namespace ApiTypes {
"asset_buildings_id"?: number; // 所属楼栋id,[ref:asset_buildings]
"asset_units_id"?: number; // 所属单元id,[ref:asset_units]
"name"?: string; // 模糊搜索:名称
"full_name"?: string; // 模糊搜索:全称
"project_name"?: string; // 模糊搜索:项目名称
};
type Store = {
"asset_projects_id": number; // 所属项目id,[ref:asset_projects]
@ -181,6 +177,19 @@ declare namespace ApiTypes {
"asset_units_id"?: number; // 所属单元id,[ref:asset_units]
"keywords"?: string; // 关键词
};
type Import = {
"asset_projects_id"?: number; // 所属项目id,[ref:asset_projects]
"upload_file"?: mimes:xlsx,xls; // 上传的时候必填文件
};
type Export = {
"asset_projects_id"?: number; // 所属项目id,[ref:asset_projects]
"asset_buildings_id"?: number; // 所属楼栋id,[ref:asset_buildings]
"asset_units_id"?: number; // 所属单元id,[ref:asset_units]
"name"?: string; // 模糊搜索:名称
"full_name"?: string; // 模糊搜索:全称
"current"?: number; // 页码
"download_type": string; // 下载类型page 当前页(含查询条件)query 所有页(含查询条件)all所有记录
};
}
namespace AssetProjects {
type List = {
@ -411,6 +420,9 @@ declare namespace ApiTypes {
type Delete = {
"id": number; // id
};
type Import = {
"upload_file"?: mimes:xlsx,xls; // 上传的时候必填文件
};
}
}
namespace Collcetion {
@ -420,6 +432,7 @@ declare namespace ApiTypes {
"asset_houses_id"?: number; // 房屋id,[ref:asset_houses]
"channel"?: string; // 通知渠道,[enum:HouseCollectionTasksChannelEnum]
"status"?: string; // 通知状态,[enum:HouseCollectionRecordsStatusEnum]
"full_name"?: string; // 房屋名称
};
type Show = {
"id": number; // id
@ -490,6 +503,28 @@ declare namespace ApiTypes {
"filename": string; // 文件名称
};
}
namespace ConvenienceServices {
type List = {
"name"?: string; // 模糊搜索:名称
};
type Store = {
"type": string; // 类型,[enum:ConvenienceServicesTypeEnum]
"name": string; // 名称
"content": string[]; // 内容
};
type Update = {
"id": number; // id
"type": string; // 类型,[enum:ConvenienceServicesTypeEnum]
"name": string; // 名称
"content": string[]; // 内容
};
type Show = {
"id": number; // id
};
type Delete = {
"id": number; // id
};
}
}
namespace Company {
namespace Companies {
@ -590,6 +625,7 @@ declare namespace ApiTypes {
type List = {
"companies_id"?: number; // 机构ID
"organizations_id"?: number; // 组织机构ID
"organization_name"?: string; // 组织机构名称
"name"?: string; // 模糊搜索:名称
"phone"?: string; // 模糊搜索:手机号
};
@ -730,6 +766,12 @@ declare namespace ApiTypes {
"name"?: string; // 模糊搜索:名称
"companies_id"?: number; // 机构ID[ref:companies]
"parent_id"?: number; // 父级ID
"company_name"?: string; // 机构名称
};
type TreeList = {
"name"?: string; // 模糊搜索:名称
"companies_id"?: number; // 机构ID[ref:companies]
"parent_id"?: number; // 父级ID
};
type Store = {
"companies_id": number; // 所属机构id,[ref:companies]
@ -816,6 +858,95 @@ 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 GetChargeStandardHouseIds = {
"house_charge_standards_id": number; // 房屋收费标准id,[ref:house_charge_standards]
};
type Show = {
"id": number; // id
};
type Delete = {
"id": number; // id
};
}
namespace HouseChargeStandards {
type List = {
"name"?: string; // 模糊搜索:名称
"project_name"?: string; // 模糊搜索:项目名称
"company_name"?: string; // 模糊搜索:机构名称
"charge_type"?: string; // 收费类型,[enum:HouseBillsTypeEnum]
"asset_projects_id"?: number; // 项目id,[ref:asset_projects]
"companies_id"?: number; // 机构id,[ref:companies]
};
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 = {
@ -853,6 +984,49 @@ declare namespace ApiTypes {
};
}
}
namespace Msg {
namespace MsgPropertyAnnouncements {
type List = {
"title"?: string; // 模糊搜索:标题
"asset_projects_id"?: number; // 项目id,[ref:asset_projects]
"project_name"?: string; // 模糊搜索:项目名称
"is_publish"?: number; // 是否发布
};
type Store = {
"asset_projects_id": number; // 项目id,[ref:asset_projects]
"title": string; // 标题
"content": string; // 内容
"is_publish"?: boolean; // 是否发布
"publish_at"?: Date; // 发布时间
"sort"?: number; // 排序
};
type Update = {
"id": number; // id
"asset_projects_id": number; // 项目id,[ref:asset_projects]
"title": string; // 标题
"content": string; // 内容
"is_publish"?: boolean; // 是否发布
"publish_at"?: Date; // 发布时间
"sort"?: number; // 排序
};
type Show = {
"id": number; // id
};
type IsPublish = {
"id": number; // id
"is_publish": boolean; // 是否发布
};
type SoftDelete = {
"id": number; // id
};
type Restore = {
"id": number; // id
};
type Delete = {
"id": number; // id
};
}
}
namespace Permission {
namespace SysPermissions {
type List = {
@ -960,10 +1134,10 @@ declare namespace ApiTypes {
"id": number; // id
"type": string; // 工单类型,[enum:HouseWorkOrdersTypeEnum]
"level": string; // 优先级,[enum:HouseWorkOrdersLevelEnum]
"title": string; // 工单标题
"content": string; // 工单内容
"reporter_name"?: string; // 上报人名称
"reporter_phone"?: string; // 上报人手机
"contact_phone"?: string; // 联系人电话
"attachments"?: string[]; // 工单附件
"asset_houses_id": number; // 资产房屋id,[ref:asset_houses]
};

View File

@ -96,6 +96,15 @@ export const Apis = {
Select(data?: ApiTypes.Asset.AssetHouses.Select): Promise<MyResponseType> {
return request('admin/asset/asset_houses/select', { data });
},
Import(data?: ApiTypes.Asset.AssetHouses.Import): Promise<MyResponseType> {
return request('admin/asset/asset_houses/import', { data });
},
DownloadTemplate(): Promise<MyResponseType> {
return request('admin/asset/asset_houses/download_template', {responseType: 'blob',});
},
Export(data: ApiTypes.Asset.AssetHouses.Export): Promise<MyResponseType> {
return request('admin/asset/asset_houses/export', { responseType: 'blob',data });
},
},
AssetProjects: {
List(data?: ApiTypes.Asset.AssetProjects.List): Promise<MyResponseType> {
@ -212,6 +221,12 @@ export const Apis = {
Delete(data: ApiTypes.Bill.HouseBills.Delete): Promise<MyResponseType> {
return request('admin/bill/house_bills/delete', { data });
},
Import(data?: ApiTypes.Bill.HouseBills.Import): Promise<MyResponseType> {
return request('admin/bill/house_bills/import', { data });
},
DownloadTemplate(): Promise<MyResponseType> {
return request('admin/bill/house_bills/download_template', {responseType: 'blob',});
},
},
},
Collcetion: {
@ -285,6 +300,23 @@ export const Apis = {
return request('admin/common/auth/temporary_url', { data });
},
},
ConvenienceServices: {
List(data?: ApiTypes.Common.ConvenienceServices.List): Promise<MyResponseType> {
return request('admin/common/convenience_services/list', { data });
},
Store(data: ApiTypes.Common.ConvenienceServices.Store): Promise<MyResponseType> {
return request('admin/common/convenience_services/store', { data });
},
Update(data: ApiTypes.Common.ConvenienceServices.Update): Promise<MyResponseType> {
return request('admin/common/convenience_services/update', { data });
},
Show(data: ApiTypes.Common.ConvenienceServices.Show): Promise<MyResponseType> {
return request('admin/common/convenience_services/show', { data });
},
Delete(data: ApiTypes.Common.ConvenienceServices.Delete): Promise<MyResponseType> {
return request('admin/common/convenience_services/delete', { data });
},
},
},
Company: {
Companies: {
@ -423,6 +455,9 @@ export const Apis = {
List(data?: ApiTypes.Company.Organizations.List): Promise<MyResponseType> {
return request('admin/company/organizations/list', { data });
},
TreeList(data?: ApiTypes.Company.Organizations.TreeList): Promise<MyResponseType> {
return request('admin/company/organizations/tree_list', { data });
},
Store(data: ApiTypes.Company.Organizations.Store): Promise<MyResponseType> {
return request('admin/company/organizations/store', { data });
},
@ -477,6 +512,48 @@ 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 });
},
GetChargeStandardHouseIds(data: ApiTypes.HouseCharage.HouseChargeHasHouses.GetChargeStandardHouseIds): Promise<MyResponseType> {
return request('admin/house_charage/house_charge_has_houses/get_charge_standard_house_ids', { 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> {
@ -507,6 +584,34 @@ export const Apis = {
},
},
},
Msg: {
MsgPropertyAnnouncements: {
List(data?: ApiTypes.Msg.MsgPropertyAnnouncements.List): Promise<MyResponseType> {
return request('admin/msg/msg_property_announcements/list', { data });
},
Store(data: ApiTypes.Msg.MsgPropertyAnnouncements.Store): Promise<MyResponseType> {
return request('admin/msg/msg_property_announcements/store', { data });
},
Update(data: ApiTypes.Msg.MsgPropertyAnnouncements.Update): Promise<MyResponseType> {
return request('admin/msg/msg_property_announcements/update', { data });
},
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 });
},
Restore(data: ApiTypes.Msg.MsgPropertyAnnouncements.Restore): Promise<MyResponseType> {
return request('admin/msg/msg_property_announcements/restore', { data });
},
Delete(data: ApiTypes.Msg.MsgPropertyAnnouncements.Delete): Promise<MyResponseType> {
return request('admin/msg/msg_property_announcements/delete', { data });
},
},
},
Permission: {
SysPermissions: {
List(data: ApiTypes.Permission.SysPermissions.List): Promise<MyResponseType> {

View File

@ -126,7 +126,7 @@ export const BannersTypeEnum= {
// 缓存类型
export const CacheTypeEnum= {
'MobilePhoneVerificationCode': {"text":"手机验证码","color":"#f8c2db","value":"MobilePhoneVerificationCode"},
'MobilePhoneVerificationCode': {"text":"手机验证码","color":"#a10533","value":"MobilePhoneVerificationCode"},
};
// CompaniesMerchantTypeEnum
@ -148,6 +148,18 @@ export const CompanyAppsModuleEnum= {
'Customer': {"text":"客户端","color":"#10b981","value":"Customer"},
};
// CompanyEmployeeBacklogsStatusEnum
export const CompanyEmployeeBacklogsStatusEnum= {
'Pending': {"text":"待办","color":"#FF6600","value":"Pending"},
'Completed': {"text":"已办","color":"#2A82E4","value":"Completed"},
};
// CompanyEmployeeBacklogsTypeEnum
export const CompanyEmployeeBacklogsTypeEnum= {
'WorkOrder': {"text":"工单","color":"#FF6600","value":"WorkOrder"},
'Contract': {"text":"合同","color":"#2A82E4","value":"Contract"},
};
// CompanyReceiptAccountsPayChannelEnum
export const CompanyReceiptAccountsPayChannelEnum= {
'WeChat': {"text":"微信","color":"#07c160","value":"WeChat"},
@ -156,10 +168,18 @@ export const CompanyReceiptAccountsPayChannelEnum= {
'TongLian': {"text":"通联支付","color":"#ff9f0a","value":"TongLian"},
};
// ConvenienceServicesTypeEnum
export const ConvenienceServicesTypeEnum= {
'EmergencyRepair': {"text":"紧急抢修","color":"#ef4444","value":"EmergencyRepair"},
'LifeService': {"text":"生活服务","color":"#3b82f6","value":"LifeService"},
'GovernmentConsulting': {"text":"政务咨询","color":"#10b981","value":"GovernmentConsulting"},
'PropertyExclusive': {"text":"物业专属","color":"#8b5cf6","value":"PropertyExclusive"},
};
// CustomerBacklogsStatusEnum
export const CustomerBacklogsStatusEnum= {
'Pending': {"text":"待办","color":"#faad14","value":"Pending"},
'Done': {"text":"已办","color":"#52c41a","value":"Done"},
'Completed': {"text":"已办","color":"#2A82E4","value":"Completed"},
};
// CustomerBacklogsTypeEnum
@ -188,6 +208,77 @@ 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"},
};
// HouseChargeTaskDetailsStatusEnum
export const HouseChargeTaskDetailsStatusEnum= {
'Pending': {"text":"待处理","color":"#f59e0b","value":"Pending"},
'Success': {"text":"成功","color":"#22c55e","value":"Success"},
'Failed': {"text":"失败","color":"#ef4444","value":"Failed"},
};
// 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"},
};
// HouseChargeTasksTypeEnum
export const HouseChargeTasksTypeEnum= {
'Scheduled': {"text":"定时创建","color":"#3b82f6","value":"Scheduled"},
'Manual': {"text":"手动创建","color":"#10b981","value":"Manual"},
};
// HouseCollectionRecordsCollectionResultEnum
export const HouseCollectionRecordsCollectionResultEnum= {
'PromiseToPay': {"text":"承诺缴费","color":"#4caf50","value":"PromiseToPay"},
@ -234,18 +325,23 @@ export const HouseOccupantsCardTypeEnum= {
// HouseOccupantsHouseRelationEnum
export const HouseOccupantsHouseRelationEnum= {
'Owner': {"text":"产权人","color":"#2db7f5","value":"Owner"},
'Resident': {"text":"住户","color":"#87d068","value":"Resident"},
'Tenant': {"text":"租客","color":"#fa8c16","value":"Tenant"},
'NonOwner': {"text":"非产权人","color":"#fa8c16","value":"NonOwner"},
};
// HouseOccupantsRelationWithOwnerEnum
export const HouseOccupantsRelationWithOwnerEnum= {
'Self': {"text":"本人","color":"#52c41a","value":"Self"},
'Spouse': {"text":"夫妻","color":"#2db7f5","value":"Spouse"},
'FatherSon': {"text":"父子","color":"#faad14","value":"FatherSon"},
'MotherSon': {"text":"母子","color":"#fa8c16","value":"MotherSon"},
'Spouse': {"text":"配偶","color":"#2db7f5","value":"Spouse"},
'Children': {"text":"子女","color":"#87d068","value":"Children"},
'ContactPerson': {"text":"指定联系人","color":"#f5222d","value":"ContactPerson"},
'Parents': {"text":"父母","color":"#faad14","value":"Parents"},
'Siblings': {"text":"兄弟姐妹","color":"#fa8c16","value":"Siblings"},
'OtherRelatives': {"text":"其他亲属","color":"#f5222d","value":"OtherRelatives"},
};
// HouseOccupantsResidentialRelationEnum
export const HouseOccupantsResidentialRelationEnum= {
'Resident': {"text":"住户","color":"#2db7f5","value":"Resident"},
'PrimaryTenant': {"text":"主租人","color":"#87d068","value":"PrimaryTenant"},
'Tenant': {"text":"租客","color":"#fa8c16","value":"Tenant"},
};
// HouseOccupantsStatusEnum
@ -296,18 +392,18 @@ export const HouseRegistersIdentityTypeEnum= {
// HouseRegistersStatusEnum
export const HouseRegistersStatusEnum= {
'Pending': {"text":"待审","color":"#faad14","value":"Pending"},
'Approved': {"text":"已审","color":"#52c41a","value":"Approved"},
'Approved': {"text":"通过","color":"#52c41a","value":"Approved"},
'Rejected': {"text":"驳回","color":"#f5222d","value":"Rejected"},
};
// HouseRegistersTypeEnum
export const HouseRegistersTypeEnum= {
'Delivery': {"text":"入户登记","color":"#2db7f5","value":"Delivery"},
'Transfer': {"text":"过户登记","color":"#87d068","value":"Transfer"},
'AddOwner': {"text":"添加产权人","color":"#52c41a","value":"AddOwner"},
'RemoveOwner': {"text":"减少产权人","color":"#d9363e","value":"RemoveOwner"},
'AddOccupant': {"text":"添加住户","color":"#108ee9","value":"AddOccupant"},
'RemoveOccupant': {"text":"移除住户","color":"#fa8c16","value":"RemoveOccupant"},
'MoveOut': {"text":"搬离登记","color":"#f50","value":"MoveOut"},
'MoveIn': {"text":"搬入登记","color":"#ffc53d","value":"MoveIn"},
'RemoveOwner': {"text":"减少产权人","color":"#d9363e","value":"RemoveOwner"},
};
// HouseRegistersUsagePlanEnum

View File

@ -0,0 +1,146 @@
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';
import AnnouncementCreate from './modals/AnnouncementCreate';
import AnnouncementShow from './modals/AnnouncementShow';
import AnnouncementUpdate from './modals/AnnouncementUpdate';
export default function Index({ title = '公告管理' }) {
const navigate = useNavigate();
// 注册当前页面为标签页
usePageTabs({
tabKey: 'Msg',
tabLabel: title,
});
return (
<MyPageContainer
title={title}
enableTabs={true}
tabKey="banners"
tabLabel={title}
>
<ProTable
{...MyProTableProps.props}
request={async (params, sort) =>
MyProTableProps.request(
params,
sort,
Apis.Msg.MsgPropertyAnnouncements.List,
)
}
toolBarRender={(action) => [
<AnnouncementCreate
key="Create"
reload={action?.reload}
title={title}
/>,
]}
columns={[
MyColumns.ID(),
{
title: '标题',
dataIndex: 'title',
width: 120, // 关键:固定列宽(若父容器过窄,可设 minWidth: 200 优先保证列宽)
render: (text) => (
<div
style={{
width: '100%', // 继承列宽
// height: '60px', // 设置固定高度约显示3行文本
overflow: 'hidden', // 超出隐藏
textOverflow: 'ellipsis', // 省略号
display: '-webkit-box',
WebkitBoxOrient: 'vertical',
WebkitLineClamp: 1, // 显示3行
}}
>
{text}
</div>
),
},
{
title: '内容',
dataIndex: 'content',
valueType: 'textarea', // 仅影响表单编辑时的输入类型,不影响表格展示
search: false,
width: 200, // 关键:固定列宽(若父容器过窄,可设 minWidth: 200 优先保证列宽)
render: (text) => (
<div
style={{
width: '100%', // 继承列宽
// height: '60px', // 设置固定高度约显示3行文本
overflow: 'hidden', // 超出隐藏
textOverflow: 'ellipsis', // 省略号
display: '-webkit-box',
WebkitBoxOrient: 'vertical',
WebkitLineClamp: 2, // 显示3行
}}
>
{text}
</div>
),
},
{
title: '发布日期',
dataIndex: 'publish_at',
valueType: 'date',
search: false,
},
{
title: '项目',
dataIndex: ['asset_project', 'name'],
search: false,
render: (_, record) => {
return record?.asset_project?.name;
},
},
MyColumns.SoftDelete({
title: '启/禁用',
onRestore: Apis.Msg.MsgPropertyAnnouncements.Restore,
onSoftDelete: Apis.Msg.MsgPropertyAnnouncements.SoftDelete,
search: false,
}),
{
//创建日期
title: '创建日期',
dataIndex: 'created_at',
valueType: 'date',
search: false,
// render: (_, record) => {
// return record?.created_at?.substring(0, 10);
// },
},
MyColumns.Option({
render: (_, item: any, index, action) => (
<Space key={index}>
<AnnouncementShow item={item} />
<AnnouncementUpdate
item={item}
reload={action?.reload}
title={title}
/>
<MyButtons.Delete
onConfirm={() =>
Apis.Msg.MsgPropertyAnnouncements.Delete({
id: item.id,
}).then(() => action?.reload())
}
/>
</Space>
),
}),
]}
/>
</MyPageContainer>
);
}

View File

@ -0,0 +1,92 @@
import {
MyBetaModalFormProps,
MyButtons,
MyModalFormProps,
rulesHelper,
} from '@/common';
import { Selects } from '@/components/Select';
import { Apis } from '@/gen/Apis';
import { BetaSchemaForm } from '@ant-design/pro-components';
import { Form, message } from 'antd';
export default function Create(props: MyBetaModalFormProps) {
const [form] = Form.useForm();
return (
<BetaSchemaForm<ApiTypes.Msg.MsgPropertyAnnouncements.Store>
{...MyModalFormProps.props}
title={`添加公告`}
wrapperCol={{ span: 24 }}
width="600px"
trigger={<MyButtons.Create title={`添加公告`} />}
form={form}
onOpenChange={(open: any) => {
if (open) {
form.resetFields(); // 清空表单数据
}
}}
onFinish={async (values) =>
Apis.Msg.MsgPropertyAnnouncements.Store(values)
.then(() => {
props.reload?.();
message.success('添加公告内容成功');
return true;
})
.catch(() => false)
}
columns={[
{
key: 'title',
title: '公告标题',
colProps: { span: 24 },
formItemProps: { ...rulesHelper.text },
},
{
key: 'content',
title: '公告内容',
valueType: 'textarea',
colProps: { span: 24 },
formItemProps: { ...rulesHelper.text },
fieldProps: {
autoSize: { minRows: 4, maxRows: 6 },
},
},
{
key: 'publish_at',
title: '内容显示的发布日期',
valueType: 'date',
colProps: { span: 12 },
fieldProps: {
style: { width: '100%' },
},
formItemProps: { ...rulesHelper.text },
},
Selects?.AssetProjects({
title: '请选择项目',
key: 'asset_projects_id',
colProps: { span: 12 },
formItemProps: { ...rulesHelper.text },
}),
// {
// key: 'is_publish',
// title: '是否立刻发布',
// valueType: 'switch',
// colProps: { span: 8 },
// },
{
key: 'sort',
title: '排序',
valueType: 'digit',
colProps: { span: 12 },
tooltip: '数值越大越靠前',
fieldProps: {
placeholder: '数值越大越靠前',
min: 0,
style: { width: '100%' },
},
initialValue: 0,
},
]}
/>
);
}

View File

@ -0,0 +1,53 @@
import { MyBetaModalFormProps } from '@/common';
import { MyModal } from '@/components/MyModal';
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
import { Typography } from 'antd';
const { Text } = Typography;
export default function info(props: MyBetaModalFormProps) {
return (
<MyModal
title={props.title || '查看'}
// width="40vw"
width={600}
// style={{ maxWidth: '650px' }}
node={
<ProCard>
<ProDescriptions
// bordered
// column={{ xs: 1, sm: 2, md: 3 }}
column={1}
size="small"
>
<ProDescriptions.Item label="公告标题">
{props?.item?.title || '-'}
</ProDescriptions.Item>
<ProDescriptions.Item label="公告内容">
<div
style={{
whiteSpace: 'pre-wrap',
maxHeight: '300px',
overflow: 'auto',
}}
>
{props?.item?.content || '-'}
</div>
</ProDescriptions.Item>
<ProDescriptions.Item label="发布日期">
{props?.item?.publish_at || '-'}
</ProDescriptions.Item>
<ProDescriptions.Item label=" 关联项目">
{props?.item?.asset_project?.name || '-'}
</ProDescriptions.Item>
<ProDescriptions.Item label="创建时间">
{props?.item?.created_at || '-'}
</ProDescriptions.Item>
</ProDescriptions>
</ProCard>
}
/>
);
}

View File

@ -0,0 +1,95 @@
import {
MyBetaModalFormProps,
MyButtons,
MyModalFormProps,
rulesHelper,
} from '@/common';
import { Selects } from '@/components/Select';
import { Apis } from '@/gen/Apis';
import { BetaSchemaForm } from '@ant-design/pro-components';
import { Form, message } from 'antd';
export default function Update(props: MyBetaModalFormProps) {
const [form] = Form.useForm();
return (
<BetaSchemaForm<ApiTypes.Msg.MsgPropertyAnnouncements.Update>
{...MyModalFormProps.props}
title={`编辑公告内容`}
trigger={<MyButtons.Edit />}
wrapperCol={{ span: 24 }}
width="600px"
key={new Date().getTime()}
form={form}
onOpenChange={(open: any) => {
if (open && props.item) {
form.setFieldsValue(props.item);
}
}}
onFinish={async (values) =>
Apis.Msg.MsgPropertyAnnouncements.Update({
...values,
id: props.item?.id ?? 0,
})
.then(() => {
props.reload?.();
message.success('编辑公告内容成功');
return true;
})
.catch(() => false)
}
columns={[
{
key: 'title',
title: '公告标题',
colProps: { span: 24 },
formItemProps: { ...rulesHelper.text },
},
{
key: 'content',
title: '公告内容',
valueType: 'textarea',
colProps: { span: 24 },
formItemProps: { ...rulesHelper.text },
fieldProps: {
autoSize: { minRows: 4, maxRows: 6 },
},
},
{
key: 'publish_at',
title: '内容显示的发布日期',
valueType: 'date',
colProps: { span: 12 },
fieldProps: {
style: { width: '100%' },
},
formItemProps: { ...rulesHelper.text },
},
Selects?.AssetProjects({
title: '请选择项目',
key: 'asset_projects_id',
colProps: { span: 12 },
formItemProps: { ...rulesHelper.text },
}),
// {
// key: 'is_publish',
// title: '是否立刻发布',
// valueType: 'switch',
// colProps: { span: 8 },
// },
{
key: 'sort',
title: '排序',
valueType: 'digit',
colProps: { span: 12 },
tooltip: '数值越大越靠前',
fieldProps: {
placeholder: '数值越大越靠前',
min: 0,
style: { width: '100%' },
},
initialValue: 0,
},
]}
/>
);
}

View File

@ -8,8 +8,8 @@ import {
import { ProTable } from '@ant-design/pro-components';
import { Popconfirm, Space, Tag } from 'antd';
import { useEffect, useRef } from 'react';
import Delivery from '../modals/Delivery';
import AddOccupant from './modals/AddOccupant';
import AddRent from './modals/AddRent';
import MoveIn from './modals/MoveIn';
import MoveOut from './modals/MoveOut';
import OccupantShow from './modals/OccupantShow';
@ -45,24 +45,30 @@ export default function Index({ ...rest }) {
)
}
toolBarRender={(action) => [
<AddOccupant
key="AddOccupant"
item={rest.item}
<Delivery
key="Delivery"
item={{ ...rest.item, size: 'middle' }}
reload={action?.reload}
title="添加住户"
/>,
<AddRent
key="AddOccupant"
item={rest.item}
reload={action?.reload}
title="添加租客"
/>,
<Transfer
key="Transfer"
item={rest.item}
reload={action?.reload}
title=" 过户登记"
title="添加产权人"
/>,
!rest.item?.house_occupants?.length ? (
''
) : (
<>
<AddOccupant
key="AddOccupant"
item={rest.item}
reload={action?.reload}
title="添加客户"
/>
<Transfer
key="Transfer"
item={rest.item}
reload={action?.reload}
title=" 过户登记"
/>
</>
),
]}
search={false}
columns={[
@ -73,9 +79,9 @@ export default function Index({ ...rest }) {
search: false,
}),
MyColumns.EnumTag({
// title:
// rest?.item?.status === 'Rented' ? '与租客关系' : '与业主关系',
title: '关系说明',
title:
rest?.item?.status === 'Rented' ? '与主租人关系' : '与产权人关系',
// title: '关系说明',
dataIndex: 'relation_with_owner',
valueEnum: HouseOccupantsRelationWithOwnerEnum,
search: false,

View File

@ -10,11 +10,13 @@ import {
HouseOccupantsCardTypeEnum,
HouseOccupantsHouseRelationEnum,
HouseOccupantsRelationWithOwnerEnum,
HouseOccupantsResidentialRelationEnum,
HouseRegistersTypeEnum,
} from '@/gen/Enums';
import { BetaSchemaForm, ProCard } from '@ant-design/pro-components';
import { Form, message } from 'antd';
export default function Create(props: MyBetaModalFormProps) {
export default function AddOccupant(props: MyBetaModalFormProps) {
const [form] = Form.useForm();
return (
<BetaSchemaForm<ApiTypes.Archive.HouseRegisters.Store>
@ -36,7 +38,13 @@ export default function Create(props: MyBetaModalFormProps) {
Apis.Archive.HouseRegisters.Store({
...values,
asset_houses_id: props?.item?.id,
type: 'AddOccupant',
type: HouseRegistersTypeEnum.AddOccupant.value,
customer_info: values.customer_info?.map((res: any) => {
return {
...res,
house_relation: HouseOccupantsHouseRelationEnum.NonOwner.value,
};
}),
})
.then(() => {
props.reload?.();
@ -50,10 +58,11 @@ export default function Create(props: MyBetaModalFormProps) {
valueType: 'formList',
dataIndex: 'customer_info',
colProps: { span: 24 },
initialValue: [''],
fieldProps: {
copyIconProps: false,
creatorButtonProps: {
creatorButtonText: '添加户',
creatorButtonText: '添加户',
},
itemRender: (
{ listDom, action }: any,
@ -63,7 +72,7 @@ export default function Create(props: MyBetaModalFormProps) {
<ProCard
bordered
style={{ marginBlockEnd: 0 }}
title={`${index + 1}`}
title={`${index + 1}`}
extra={action}
bodyStyle={{ paddingBlockEnd: 0 }}
>
@ -76,34 +85,47 @@ export default function Create(props: MyBetaModalFormProps) {
{
valueType: 'group',
columns: [
MyFormItems.EnumRadio({
key: 'house_relation',
title: '房客关系',
colProps: { span: 6 },
valueEnum: () => {
let obj: any = JSON.parse(
JSON.stringify(HouseOccupantsHouseRelationEnum),
);
delete obj.Tenant;
return obj;
},
required: true,
}),
MyFormItems.EnumRadio({
key: 'relation_with_owner',
title: '关系标记',
valueEnum: HouseOccupantsRelationWithOwnerEnum,
colProps: { span: 18 },
// valueEnum: () => {
// let obj: any = JSON.parse(
// JSON.stringify(HouseOccupantsRelationWithOwnerEnum),
// );
// delete obj.Self;
// return obj;
// },
required: true,
}),
{
valueType: 'group',
columns: [
MyFormItems.EnumRadio({
key: 'residential_relation',
title: '居住关系',
colProps: { span: 8 },
valueEnum: HouseOccupantsResidentialRelationEnum,
// valueEnum: () => {
// let obj: any = JSON.parse(
// JSON.stringify(HouseOccupantsResidentialRelationEnum),
// );
// delete obj.Tenant;
// return obj;
// },
required: true,
}),
{
name: ['residential_relation'],
valueType: 'dependency',
columns: ({ residential_relation }: any) => {
return residential_relation !==
HouseOccupantsResidentialRelationEnum.PrimaryTenant
.value
? [
MyFormItems.EnumRadio({
key: 'relation_with_owner',
title:
residential_relation === 'Resident'
? '与产权人关系'
: '与主租人关系',
valueEnum: HouseOccupantsRelationWithOwnerEnum,
colProps: { span: 16 },
required: true,
}),
]
: [];
},
},
],
},
{
title: '姓名',
dataIndex: 'name',
@ -119,69 +141,130 @@ export default function Create(props: MyBetaModalFormProps) {
},
formItemProps: { ...rulesHelper.phone },
},
MyFormItems.EnumSelect({
key: 'card_type',
title: '证件类型',
colProps: { span: 6 },
valueEnum: HouseOccupantsCardTypeEnum,
required: true,
}),
{
title: '证件号码',
dataIndex: 'id_card',
colProps: { span: 6 },
fieldProps: {
maxLength: 18,
},
formItemProps: { ...rulesHelper.text },
},
{
valueType: 'group',
columns: [
MyFormItems.UploadImages({
key: 'card_front_image',
title: '证件正面',
uploadType: 'file',
max: 1,
colProps: { span: 6 },
formItemProps: { ...rulesHelper.text },
}),
MyFormItems.UploadImages({
key: 'card_back_image',
title: '证件反面',
uploadType: 'file',
max: 1,
colProps: { span: 6 },
formItemProps: { ...rulesHelper.text },
}),
{
title: '是否入住',
dataIndex: 'is_live_in',
colProps: { span: 6 },
valueType: 'switch',
},
{
name: ['is_live_in'],
valueType: 'dependency',
columns: ({ is_live_in }: any) => {
return is_live_in
? [
{
title: '入住日期',
dataIndex: 'move_in_date',
valueType: 'date',
colProps: { span: 6 },
fieldProps: {
style: { width: '100%' },
},
formItemProps: { ...rulesHelper.text },
},
]
: [];
},
},
],
name: ['residential_relation'],
valueType: 'dependency',
columns: ({ residential_relation }: any) => {
return residential_relation ===
HouseOccupantsResidentialRelationEnum.PrimaryTenant.value
? [
MyFormItems.EnumSelect({
key: 'card_type',
title: '证件类型',
colProps: { span: 6 },
valueEnum: HouseOccupantsCardTypeEnum,
required: true,
}),
{
title: '证件号码',
dataIndex: 'id_card',
colProps: { span: 6 },
required: true,
fieldProps: {
maxLength: 18,
},
},
MyFormItems.UploadImages({
key: 'card_front_image',
title: '证件正面',
// uploadType: 'file',
max: 1,
colProps: { span: 6 },
formItemProps: { ...rulesHelper.text },
}),
MyFormItems.UploadImages({
key: 'card_back_image',
title: '证件反面',
// uploadType: 'file',
max: 1,
colProps: { span: 6 },
formItemProps: { ...rulesHelper.text },
}),
{
title: '是否入住',
dataIndex: 'is_live_in',
colProps: { span: 6 },
valueType: 'switch',
},
{
name: ['is_live_in'],
valueType: 'dependency',
columns: ({ is_live_in }: any) => {
return is_live_in
? [
{
title: '入住日期',
dataIndex: 'move_in_date',
valueType: 'date',
colProps: { span: 6 },
fieldProps: {
style: { width: '100%' },
},
formItemProps: { ...rulesHelper.text },
},
]
: [];
},
},
]
: [
MyFormItems.EnumSelect({
key: 'card_type',
title: '证件类型',
colProps: { span: 6 },
valueEnum: HouseOccupantsCardTypeEnum,
}),
{
title: '证件号码',
dataIndex: 'id_card',
colProps: { span: 6 },
fieldProps: {
maxLength: 18,
},
},
MyFormItems.UploadImages({
key: 'card_front_image',
title: '证件正面',
// uploadType: 'file',
max: 1,
colProps: { span: 6 },
}),
MyFormItems.UploadImages({
key: 'card_back_image',
title: '证件反面',
// uploadType: 'file',
max: 1,
colProps: { span: 6 },
}),
{
title: '是否入住',
dataIndex: 'is_live_in',
colProps: { span: 6 },
valueType: 'switch',
},
{
name: ['is_live_in'],
valueType: 'dependency',
columns: ({ is_live_in }: any) => {
return is_live_in
? [
{
title: '入住日期',
dataIndex: 'move_in_date',
valueType: 'date',
colProps: { span: 6 },
fieldProps: {
style: { width: '100%' },
},
formItemProps: { ...rulesHelper.text },
},
]
: [];
},
},
];
},
},
],
},

View File

@ -1,188 +0,0 @@
import {
MyBetaModalFormProps,
MyButtons,
MyFormItems,
MyModalFormProps,
rulesHelper,
} from '@/common';
import { Apis } from '@/gen/Apis';
import {
HouseOccupantsCardTypeEnum,
HouseOccupantsHouseRelationEnum,
HouseOccupantsRelationWithOwnerEnum,
} from '@/gen/Enums';
import { BetaSchemaForm, ProCard } from '@ant-design/pro-components';
import { Form, message } from 'antd';
export default function Create(props: MyBetaModalFormProps) {
const [form] = Form.useForm();
return (
<BetaSchemaForm<ApiTypes.Archive.HouseRegisters.Store>
{...MyModalFormProps.props}
title={`${props.title}`}
wrapperCol={{ span: 24 }}
width="900px"
trigger={
<MyButtons.Default title={props.title} size="middle" type="primary" />
}
key={new Date().getTime()}
form={form}
onOpenChange={(open: any) => {
if (open) {
form.resetFields(); // 清空表单数据
}
}}
onFinish={async (values) =>
Apis.Archive.HouseRegisters.Store({
...values,
asset_houses_id: props?.item?.id,
house_status: 'Rented',
type: 'AddOccupant',
})
.then(() => {
props.reload?.();
message.success(props.title + '成功');
return true;
})
.catch(() => false)
}
columns={[
{
valueType: 'formList',
dataIndex: 'customer_info',
colProps: { span: 24 },
fieldProps: {
copyIconProps: false,
creatorButtonProps: {
creatorButtonText: '添加租客',
},
itemRender: (
{ listDom, action }: any,
{ index }: { index: number },
) => {
return (
<ProCard
bordered
style={{ marginBlockEnd: 0 }}
title={`租客${index + 1}`}
extra={action}
bodyStyle={{ paddingBlockEnd: 0 }}
>
{listDom}
</ProCard>
);
},
},
columns: [
{
valueType: 'group',
columns: [
MyFormItems.EnumRadio({
key: 'house_relation',
title: '房客关系',
colProps: { span: 6 },
valueEnum: () => {
let obj: any = JSON.parse(
JSON.stringify(HouseOccupantsHouseRelationEnum),
);
delete obj.Owner;
delete obj.Resident;
return obj;
},
required: true,
}),
MyFormItems.EnumRadio({
key: 'relation_with_owner',
title: '关系标记',
colProps: { span: 18 },
valueEnum: HouseOccupantsRelationWithOwnerEnum,
required: true,
}),
{
title: '姓名',
dataIndex: 'name',
colProps: { span: 6 },
formItemProps: { ...rulesHelper.text },
},
{
title: '手机号',
dataIndex: 'phone',
colProps: { span: 6 },
fieldProps: {
maxLength: 11,
},
formItemProps: { ...rulesHelper.text },
},
MyFormItems.EnumSelect({
key: 'card_type',
title: '证件类型',
colProps: { span: 6 },
valueEnum: HouseOccupantsCardTypeEnum,
required: true,
}),
{
title: '证件号码',
dataIndex: 'id_card',
colProps: { span: 6 },
fieldProps: {
maxLength: 18,
},
formItemProps: { ...rulesHelper.text },
},
{
valueType: 'group',
columns: [
MyFormItems.UploadImages({
key: 'card_front_image',
title: '证件正面',
uploadType: 'file',
max: 1,
colProps: { span: 6 },
formItemProps: { ...rulesHelper.text },
}),
MyFormItems.UploadImages({
key: 'card_back_image',
title: '证件反面',
uploadType: 'file',
max: 1,
colProps: { span: 6 },
formItemProps: { ...rulesHelper.text },
}),
{
title: '是否入住',
dataIndex: 'is_live_in',
colProps: { span: 6 },
valueType: 'switch',
},
{
name: ['is_live_in'],
valueType: 'dependency',
columns: ({ is_live_in }: any) => {
return is_live_in
? [
{
title: '入住日期',
dataIndex: 'move_in_date',
valueType: 'date',
colProps: { span: 6 },
fieldProps: {
style: { width: '100%' },
},
formItemProps: { ...rulesHelper.text },
},
]
: [];
},
},
],
},
],
},
],
},
]}
/>
);
}

View File

@ -8,7 +8,7 @@ import { MyModal } from '@/components/MyModal';
import {
HouseOccupantsCardTypeEnum,
HouseOccupantsHouseRelationEnum,
HouseOccupantsRelationWithOwnerEnum,
HouseOccupantsResidentialRelationEnum,
HouseRegistersStatusEnum,
HouseRegistersTypeEnum,
} from '@/gen/Enums';
@ -63,9 +63,9 @@ export default function RegistersShow(props: MyBetaModalFormProps) {
valueEnum: HouseOccupantsHouseRelationEnum,
}),
MyColumns.EnumTag({
title: '关系说明',
dataIndex: 'relation_with_owner',
valueEnum: HouseOccupantsRelationWithOwnerEnum,
title: '居住关系',
dataIndex: 'residential_relation',
valueEnum: HouseOccupantsResidentialRelationEnum,
}),
{
title: '姓名',

View File

@ -8,7 +8,6 @@ import {
import { Apis } from '@/gen/Apis';
import {
AssetHousesOwnershipTypeEnum,
AssetHousesStatusEnum,
AssetHousesUsageEnum,
} from '@/gen/Enums';
import { ProTable } from '@ant-design/pro-components';
@ -32,17 +31,26 @@ export default function Index({ title = '房屋档案' }) {
}
columns={[
MyColumns.ID(),
{
title: '项目名称',
dataIndex: ['asset_project', 'name'],
search: {
transform: (value) => {
return { project_name: value };
},
},
},
{
title: '房屋名称',
dataIndex: 'full_name',
ellipsis: true,
},
MyColumns.EnumTag({
title: '房屋状态',
dataIndex: 'status',
valueEnum: AssetHousesStatusEnum,
search: false,
}),
// MyColumns.EnumTag({
// title: '房屋状态',
// dataIndex: 'status',
// valueEnum: AssetHousesStatusEnum,
// search: false,
// }),
MyColumns.EnumTag({
title: '产权性质',
@ -71,7 +79,7 @@ export default function Index({ title = '房屋档案' }) {
search: false,
},
{
title: '产权人/住户',
title: '客户信息',
render(_, record) {
const owners =
record?.house_occupants?.filter(
@ -111,7 +119,7 @@ export default function Index({ title = '房屋档案' }) {
render: (_, item: any, index, action) => (
<Space key={index}>
<MyButtons.View
title="详情"
title="查看"
onClick={() => {
navigate(`/archive/${item.id}`);
}}
@ -120,17 +128,10 @@ export default function Index({ title = '房屋档案' }) {
<Delivery
item={item}
reload={action?.reload}
title="入户登记"
title="添加产权人"
/>
) : (
<MyButtons.Default
title="客户管理"
size="small"
type="link"
onClick={() => {
navigate(`/archive/asset_house/${item.id}`);
}}
/>
''
)}
</Space>
),

View File

@ -9,7 +9,7 @@ import { Apis } from '@/gen/Apis';
import {
HouseOccupantsCardTypeEnum,
HouseOccupantsHouseRelationEnum,
HouseRegistersCustomerTypeEnum,
HouseRegistersTypeEnum,
} from '@/gen/Enums';
import { BetaSchemaForm, ProCard } from '@ant-design/pro-components';
import { Form, message } from 'antd';
@ -19,12 +19,17 @@ export default function Create(props: MyBetaModalFormProps) {
return (
<BetaSchemaForm<ApiTypes.Archive.HouseRegisters.Store>
{...MyModalFormProps.props}
title={`添加${props.title}`}
title={`${props.title}`}
wrapperCol={{ span: 24 }}
width="800px"
trigger={
<MyButtons.Default title={props.title} size="small" type="link" />
<MyButtons.View
title={props.title}
size={props.item?.size || 'small'}
type="primary"
/>
}
key={new Date().getTime()}
form={form}
onOpenChange={(open: any) => {
if (open) {
@ -35,13 +40,11 @@ export default function Create(props: MyBetaModalFormProps) {
Apis.Archive.HouseRegisters.Store({
...values,
asset_houses_id: props?.item?.id,
type: 'Delivery',
type: HouseRegistersTypeEnum.AddOwner.value,
customer_info: values.customer_info?.map((res: any) => {
return {
...res,
house_relation: 'Owner',
house_status: 'SelfOccupied',
relation_with_owner: 'Self',
house_relation: HouseOccupantsHouseRelationEnum.Owner.value,
};
}),
})
@ -54,38 +57,25 @@ export default function Create(props: MyBetaModalFormProps) {
}
columns={[
// MyFormItems.EnumRadio({
// key: 'house_status',
// title: '房屋状态',
// key: 'customer_type',
// title: '产权归属类型',
// colProps: { span: 12 },
// valueEnum: HouseRegistersHouseStatusEnum,
// formItemProps: { ...rulesHelper.text },
// valueEnum: HouseRegistersCustomerTypeEnum,
// }),
// MyFormItems.EnumRadio({
// key: 'house_status',
// title: '使用计划',
// colProps: { span: 8 },
// valueEnum: HouseRegistersUsagePlanEnum,
// formItemProps: { ...rulesHelper.text },
// }),
MyFormItems.EnumSelect({
key: 'customer_type',
title: '产权归属',
colProps: { span: 6 },
valueEnum: HouseRegistersCustomerTypeEnum,
}),
MyFormItems.UploadImages({
key: 'ownership_info',
title: '产权文件',
tooltip: '上限3张',
tooltip: '上限9张',
uploadType: 'file',
max: 3,
colProps: { span: 18 },
max: 9,
colProps: { span: 24 },
formItemProps: { ...rulesHelper.array },
}),
{
valueType: 'formList',
dataIndex: 'customer_info',
colProps: { span: 24 },
initialValue: [''],
fieldProps: {
copyIconProps: false,
creatorButtonProps: {
@ -159,19 +149,21 @@ export default function Create(props: MyBetaModalFormProps) {
MyFormItems.UploadImages({
key: 'card_front_image',
title: '证件正面',
uploadType: 'file',
// uploadType: 'file',
required: true,
max: 1,
colProps: { span: 6 },
}),
MyFormItems.UploadImages({
key: 'card_back_image',
title: '证件反面',
uploadType: 'file',
// uploadType: 'file',
required: true,
max: 1,
colProps: { span: 6 },
}),
{
title: '是否办理入住',
title: '是否入住',
dataIndex: 'is_live_in',
colProps: { span: 6 },
valueType: 'switch',

View File

@ -2,13 +2,15 @@ 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 { Space, Tabs } from 'antd';
import { useEffect, useState } from 'react';
import AssetAccounts from './components/AssetAccounts';
import MyAssetBuildings from './components/AssetBuildings';
import AssetGrid from './components/AssetGrid';
import AssetInfo from './components/AssetInfo';
import Basic from './components/Basic';
import ChargeStandard from './components/ChargeStandard';
import BindCompany from './components/modals/BindCompany';
import AssetUpdate from './modals/AssetUpdate';
export default function Show({ title }: { title?: string } = {}) {
const { id } = useParams<{ id: string }>();
@ -17,7 +19,7 @@ export default function Show({ title }: { title?: string } = {}) {
// 注册当前页面为标签页
const { addTab } = usePageTabs({
tabKey: `asset-show-${id}`,
tabLabel: data?.name || title || '资产详情',
tabLabel: data?.name || title || '项目详情',
});
const loadShow = () => {
@ -39,12 +41,12 @@ export default function Show({ title }: { title?: string } = {}) {
}, [id]);
let items = [
{
label: '基本信息',
key: 'info',
closable: false,
children: <AssetInfo item={data} reload={() => loadShow()} />,
},
// {
// label: '基本信息',
// key: 'info',
// closable: false,
// children: <AssetInfo item={data} reload={() => loadShow()} />,
// },
{
label: '楼栋管理',
key: 'asset_buildings',
@ -52,11 +54,17 @@ export default function Show({ title }: { title?: string } = {}) {
children: <MyAssetBuildings item={data} />,
},
{
label: '网格管理',
label: '楼栋划分',
key: 'grid',
closable: false,
children: <AssetGrid item={data} />,
},
{
label: '收费标准',
key: 'charge_standard',
closable: false,
children: <ChargeStandard item={data} />,
},
{
label: '收款账号',
key: 'asset_accounts',
@ -71,8 +79,25 @@ export default function Show({ title }: { title?: string } = {}) {
// },
];
return (
<MyPageContainer title={data?.name || title || '资产详情'}>
<Basic item={data} reload={() => loadShow()} />
<MyPageContainer title={data?.name || title || '项目详情'}>
<ProCard
title={`${data?.name} ${
data?.alias_name ? `${data?.alias_name}` : ''
}`}
extra={
<Space>
<AssetInfo
item={{ ...data, type: 'primary' }}
title="查看"
reload={loadShow}
/>
<AssetUpdate item={data} title="项目" reload={loadShow} />
<BindCompany item={data} title="机构" reload={loadShow} />
</Space>
}
>
<div>* </div>
</ProCard>
<ProCard>
<Tabs type="card" items={data?.id ? items : []} />
</ProCard>

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

@ -2,17 +2,20 @@ import {
MyBetaModalFormProps,
MyButtons,
MyColumns,
MyImportModal,
MyProTableProps,
} from '@/common';
import { Apis } from '@/gen/Apis';
import { AssetHousesUsageEnum } from '@/gen/Enums';
import {
AssetHousesOwnershipTypeEnum,
AssetHousesUsageEnum,
} from '@/gen/Enums';
import { ProCard, ProTable } from '@ant-design/pro-components';
import { Alert, message, Space, Typography } from 'antd';
import { useCallback, useRef, useState } from 'react';
import BuildingsCreate from './modals/BuildingsCreate';
import AssetBuildingsUpdate from './modals/BuildingsUpdate';
import HousesCreate from './modals/HousesCreate';
import HousesShow from './modals/HousesShow';
import HousesUpdate from './modals/HousesUpdate';
import AssetUnitsCreate from './modals/UnitsCreate';
import AssetUnitsUpdate from './modals/UnitsUpdate';
@ -70,7 +73,7 @@ export default function AssetBuildings(props: MyBetaModalFormProps) {
<ProCard
title={
<Alert
message="操作提示:单元/房屋添加,请先选择已有楼栋/单元"
message="操作提示:在楼栋下添加单元,在单元下添加房屋!"
type="info"
showIcon
style={{ margin: 0 }}
@ -83,6 +86,16 @@ export default function AssetBuildings(props: MyBetaModalFormProps) {
<Title level={5} style={{ marginBottom: 16 }}>
<Space style={{ display: 'flex', justifyContent: 'space-between' }}>
<MyImportModal
key="ImportHouse"
params={{ asset_projects_id: props?.item?.id }}
title="批量导入"
type="danger"
size="middle"
templateApi={Apis.Asset.AssetHouses.DownloadTemplate}
importApi={Apis.Asset.AssetHouses.Import}
reload={props?.reload}
/>
<BuildingsCreate
key="BuildingsCreate"
item={props?.item}
@ -168,7 +181,8 @@ export default function AssetBuildings(props: MyBetaModalFormProps) {
asset_buildings_id: selectedBuilding?.id,
}}
reload={() => actionUnitsRef?.current?.reload()}
title={`${selectedBuilding.name}单元`}
title="单元"
// title={`添加${selectedBuilding.name}单元`}
/>
)}
</Space>
@ -256,7 +270,8 @@ export default function AssetBuildings(props: MyBetaModalFormProps) {
asset_units_id: selectedUnit?.id,
}}
reload={() => actionHousesRef?.current?.reload()}
title={`${selectedUnit.name}房屋`}
title="房屋"
// title={`${selectedUnit.name}房屋`}
/>
)}
</Space>
@ -284,11 +299,6 @@ export default function AssetBuildings(props: MyBetaModalFormProps) {
showSizeChanger: false,
}}
columns={[
{
title: '房号',
dataIndex: 'name',
width: 80,
},
{
title: '楼层',
dataIndex: 'floor',
@ -297,17 +307,28 @@ export default function AssetBuildings(props: MyBetaModalFormProps) {
return `${record?.floor}`;
},
},
{
title: '房号',
dataIndex: 'name',
width: 80,
},
MyColumns.EnumTag({
title: '用途',
dataIndex: 'usage',
valueEnum: AssetHousesUsageEnum,
width: 100,
}),
MyColumns.EnumTag({
title: '房屋属性',
dataIndex: 'ownership_type',
valueEnum: AssetHousesOwnershipTypeEnum,
width: 100,
}),
MyColumns.Option({
width: 150,
render: (_, item: any, index, action) => (
<Space key={index} size="small">
<HousesShow item={item} reload={action?.reload} />
{/* <HousesShow item={item} reload={action?.reload} /> */}
<HousesUpdate
item={item}
reload={action?.reload}

View File

@ -31,19 +31,19 @@ export default function Index({ ...rest }) {
search={false}
columns={[
{
title: '网格ID',
title: 'ID',
dataIndex: 'id',
},
{
title: '网格名称',
title: '板块名称',
dataIndex: 'name',
},
{
title: '网格标识',
title: '板块标识',
dataIndex: 'grid_mark',
},
{
title: '网格员',
title: '管理员',
dataIndex: ['company_employee', 'name'],
render: (_, item: any) =>
`${item?.company_employee?.name || ''}-${

View File

@ -1,4 +1,5 @@
import { MyBetaModalFormProps, renderTextHelper } from '@/common';
import { MyModal } from '@/components/MyModal';
import {
AssetProjectsChargeEnum,
AssetProjectsEntrustTypeEnum,
@ -8,64 +9,84 @@ import {
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
import { Space } from 'antd';
export default function info(props: MyBetaModalFormProps) {
export default function AssetInfo(props: MyBetaModalFormProps) {
return (
<Space direction="vertical" style={{ width: '100%' }}>
<ProCard extra={props.extra}>
<ProDescriptions bordered>
<ProDescriptions.Item label="项目别名">
{props?.item?.alias_name}
</ProDescriptions.Item>
<ProDescriptions.Item label="项目地址" span={2}>
{props?.item?.province || ''}
{props?.item?.city || ''}
{props?.item?.district || ''}
{props?.item?.address || ''}
</ProDescriptions.Item>
<ProDescriptions.Item label="项目类型">
<renderTextHelper.Tag
Enums={AssetProjectsPropertyTypeEnum}
value={props?.item?.property_type}
key="property_type"
/>
</ProDescriptions.Item>
<ProDescriptions.Item label="项目状态">
<renderTextHelper.Tag
Enums={AssetProjectsStatusEnum}
value={props?.item?.status}
key="status"
/>
</ProDescriptions.Item>
<ProDescriptions.Item label="委托类型">
<renderTextHelper.Tag
Enums={AssetProjectsEntrustTypeEnum}
value={props?.item?.entrust_type}
key="entrust_type"
/>
</ProDescriptions.Item>
<ProDescriptions.Item label="收费方式">
<renderTextHelper.Tag
Enums={AssetProjectsChargeEnum}
value={props?.item?.charge}
key="charge"
/>
</ProDescriptions.Item>
<MyModal
title={props.title || '查看'}
type={props.item?.type || 'primary'}
width="920px"
node={
<Space direction="vertical" style={{ width: '100%' }}>
<ProCard extra={props.extra}>
<ProDescriptions bordered>
<ProDescriptions.Item label="项目名称" span={2}>
<Space size="large">
<div>
{props?.item?.name}
{props?.item?.alias_name
? `${props?.item?.alias_name}`
: ''}
</div>
</Space>
</ProDescriptions.Item>
<ProDescriptions.Item label="绑定机构">
<Space size="large">
<div>{props?.item?.company?.name}</div>
</Space>
</ProDescriptions.Item>
<ProDescriptions.Item label="接管日期">
{props?.item?.takeover_date}
</ProDescriptions.Item>
<ProDescriptions.Item label="封园日期">
{props?.item?.closure_date}
</ProDescriptions.Item>
<ProDescriptions.Item label="项目地址" span={2}>
{props?.item?.province || ''}
{props?.item?.city || ''}
{props?.item?.district || ''}
{props?.item?.address || ''}
</ProDescriptions.Item>
<ProDescriptions.Item label="项目类型">
<renderTextHelper.Tag
Enums={AssetProjectsPropertyTypeEnum}
value={props?.item?.property_type}
key="property_type"
/>
</ProDescriptions.Item>
<ProDescriptions.Item label="项目状态">
<renderTextHelper.Tag
Enums={AssetProjectsStatusEnum}
value={props?.item?.status}
key="status"
/>
</ProDescriptions.Item>
<ProDescriptions.Item label="委托类型">
<renderTextHelper.Tag
Enums={AssetProjectsEntrustTypeEnum}
value={props?.item?.entrust_type}
key="entrust_type"
/>
</ProDescriptions.Item>
<ProDescriptions.Item label="收费方式">
<renderTextHelper.Tag
Enums={AssetProjectsChargeEnum}
value={props?.item?.charge}
key="charge"
/>
</ProDescriptions.Item>
<ProDescriptions.Item label="创建日期">
<ProDescriptions.Item label="接管日期">
{props?.item?.takeover_date}
</ProDescriptions.Item>
<ProDescriptions.Item label="封园日期">
{props?.item?.closure_date}
</ProDescriptions.Item>
{/* <ProDescriptions.Item label="">
{props?.item?.created_at}
</ProDescriptions.Item>
<ProDescriptions.Item label="最近修改">
{props?.item?.updated_at}
</ProDescriptions.Item>
</ProDescriptions>
</ProCard>
</Space>
</ProDescriptions.Item> */}
<ProDescriptions.Item label="最近修改">
{props?.item?.updated_at}
</ProDescriptions.Item>
</ProDescriptions>
</ProCard>
</Space>
}
/>
);
}

View File

@ -1,36 +0,0 @@
import { MyBetaModalFormProps } from '@/common';
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
import { Space } from 'antd';
import AssetUpdate from '../modals/AssetUpdate';
import BindCompany from './modals/BindCompany';
export default function info(props: MyBetaModalFormProps) {
return (
<Space direction="vertical" style={{ width: '100%' }}>
<ProCard extra={props.extra}>
<ProDescriptions bordered>
<ProDescriptions.Item label="项目名称" span={2}>
<Space size="large">
<div>{props?.item?.name}</div>
<AssetUpdate
item={props?.item}
title="项目"
reload={props?.reload}
/>
</Space>
</ProDescriptions.Item>
<ProDescriptions.Item label="关联机构" span={3}>
<Space size="large">
<div>{props?.item?.company?.name}</div>
<BindCompany
item={props?.item}
title="项目"
reload={props?.reload}
/>
</Space>
</ProDescriptions.Item>
</ProDescriptions>
</ProCard>
</Space>
);
}

View File

@ -0,0 +1,131 @@
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';
import ChargeStandardUpdate from './modals/ChargeStandardUpdate';
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: '收费标准名称',
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}>
<ChargeStandardUpdate
item={item}
reload={action?.reload}
title="编辑"
/>
<ChargeStandardHasHouse
item={{
...item,
asset_projects_id: props?.item?.id, // 使用项目ID
size: 'small',
}}
reload={action?.reload}
title={'绑定房屋'}
/>
<MyButtons.Delete
onConfirm={() =>
Apis.HouseCharage.HouseChargeStandards.Delete({
id: item.id,
}).then(() => action?.reload())
}
/>
</Space>
),
}),
]}
/>
</>
);
}

View File

@ -14,8 +14,8 @@ export default function Update(props: MyBetaModalFormProps) {
return (
<BetaSchemaForm<ApiTypes.Asset.AssetProjects.BindCompany>
{...MyModalFormProps.props}
title={`调整${props.title}`}
trigger={<MyButtons.Default title="调整" type="primary" size="small" />}
title={`换绑${props.title}`}
trigger={<MyButtons.Default title="换绑" type="primary" size="small" />}
wrapperCol={{ span: 24 }}
width="500px"
request={() =>

View File

@ -0,0 +1,451 @@
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="600px"
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,
tiered_rates: values.tiered_rates?.map((res: any) => {
return {
...res,
};
}),
// 避免计费模式切换导致的价格异常
price:
values?.price_algorithm ===
HouseChargeStandardsPriceAlgorithmEnum.Fixed.value
? values.price
: 0,
})
.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,
}),
{
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,
}),
]
: [];
},
},
// 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: 16 },
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: 16 },
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 &&
calculation_method !==
HouseChargeStandardsCalculationMethodEnum.PerUnit.value
? []
: [
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,
// 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: 'tiered_rates',
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: 'min_quantity',
colProps: { span: 10 },
title: '起始值',
valueType: 'number',
fieldProps: {
min: 0,
addonBefore: (
_: any,
{
field,
}: { field: { index: number[] } },
) => `${field.index[1] + 1}阶梯`,
},
width: '100%',
formItemProps: { ...rulesHelper.number },
},
{
key: 'max_quantity',
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: 'tiered_rates',
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: 'min_quantity',
colProps: { span: 10 },
title: '起始值',
valueType: 'number',
fieldProps: {
min: 0,
addonBefore: (
_: any,
{
field,
}: { field: { name: number[] } },
) => `${field.name[1] + 1}阶梯`,
},
width: '100%',
formItemProps: { ...rulesHelper.number },
},
{
key: 'max_quantity',
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: ['price', 'price_algorithm'],
valueType: 'dependency',
columns: ({ price, price_algorithm }: any) => {
return price ||
price_algorithm ===
HouseChargeStandardsPriceAlgorithmEnum.Tiered.value ||
price_algorithm ===
HouseChargeStandardsPriceAlgorithmEnum.Peak.value
? [
{
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,730 @@
import { MyBetaModalFormProps, MyButtons, renderTextHelper } from '@/common';
import { MyModal } from '@/components/MyModal';
import { Apis } from '@/gen/Apis';
import {
HouseBillsTypeEnum,
HouseChargeStandardsCalculationModeEnum,
HouseChargeStandardsCalculationPeriodEnum,
} from '@/gen/Enums';
import { ProCard } from '@ant-design/pro-components';
import {
Alert,
Button,
Checkbox,
message,
Space,
Tree,
Typography,
} from 'antd';
import { CheckboxChangeEvent } from 'antd/es/checkbox';
import type { DataNode } from 'antd/es/tree';
import { useEffect, useRef, useState } from 'react';
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 = async (
checkedKeysValue:
| React.Key[]
| { checked: React.Key[]; halfChecked: React.Key[] },
) => {
// 处理不同格式的返回值
const keys = Array.isArray(checkedKeysValue)
? checkedKeysValue
: checkedKeysValue.checked;
// 获取之前的选中状态,用于比较变化
const prevKeys = new Set(checkedKeys);
const newKeys = new Set(keys);
// 找出新选中的节点
const newlyCheckedKeys = [...newKeys].filter((key) => !prevKeys.has(key));
// 找出新取消选中的节点
const uncheckedKeys = [...prevKeys].filter((key) => !newKeys.has(key));
// 处理新选中的节点
for (const key of newlyCheckedKeys) {
const keyStr = key.toString();
// 如果选中的是楼栋
if (keyStr.startsWith('building-')) {
const buildingNode = treeData.find((node) => node.key === key);
if (buildingNode) {
// 调用接口获取该楼栋下所有房屋
await loadBuildingHouses(buildingNode.id);
}
}
// 如果选中的是单元
else if (keyStr.startsWith('unit-')) {
// 查找该单元所属的楼栋和单元ID
for (const building of treeData) {
const unitNode = building.children?.find((unit) => unit.key === key);
if (unitNode) {
// 调用接口获取该单元下所有房屋
await loadUnitHouses(building.id, unitNode.id);
break;
}
}
}
}
// 如果有节点被取消选中,同步取消其所有子节点
if (uncheckedKeys.length > 0) {
const keysToRemove = new Set<React.Key>();
const findChildKeys = (nodes: TreeNodeType[], parentKey: React.Key) => {
nodes.forEach((node) => {
if (node.key === parentKey) {
// 将当前节点及其所有子节点的key加入待移除集合
const collectKeys = (n: TreeNodeType) => {
keysToRemove.add(n.key);
if (n.children) {
n.children.forEach(collectKeys);
}
};
collectKeys(node);
} else if (node.children) {
findChildKeys(node.children, parentKey);
}
});
};
uncheckedKeys.forEach((key) => {
findChildKeys(treeData, key);
});
// 从选中keys中移除所有需要取消的节点
const finalKeys = keys.filter((key) => !keysToRemove.has(key));
setCheckedKeys(finalKeys);
// 更新selectedHouses移除被取消选中的房屋
const houseKeysToRemove = new Set<string>();
keysToRemove.forEach((key) => {
if (key.toString().startsWith('house-')) {
houseKeysToRemove.add(key.toString().replace('house-', ''));
}
});
const updatedHouses = selectedHouses.filter(
(house) => !houseKeysToRemove.has(house.id.toString()),
);
setSelectedHouses(updatedHouses);
} else {
setCheckedKeys(keys);
}
// 收集所有选中的房屋
const selectedHousesList: {
id: number;
name: string;
buildingName?: string;
unitName?: string;
}[] = [...selectedHouses];
// 遍历树形数据,收集选中节点下的所有房屋
const collectHouses = (nodes: TreeNodeType[], checkedKeys: React.Key[]) => {
nodes.forEach((node) => {
if (checkedKeys.includes(node.key)) {
if (node.isLeaf) {
// 如果是房屋节点,检查是否已经存在
const houseId = node.id;
const exists = selectedHousesList.some(
(house) => house.id === houseId,
);
if (!exists) {
// 查找楼栋和单元信息
let buildingName = '';
let unitName = '';
// 查找楼栋和单元
for (const building of treeData) {
if (building.id === node.asset_buildings_id) {
buildingName = building.title as string;
// 查找单元
const unit = building.children?.find(
(u) => u.id === node.asset_units_id,
);
if (unit) {
unitName = unit.title as string;
}
break;
}
}
// 添加到选中列表
selectedHousesList.push({
id: houseId,
name: `${buildingName} ${unitName} ${node.title}(${houseId})`,
buildingName,
unitName,
});
}
} else {
// 如果是楼栋或单元节点,递归收集其下的所有房屋
if (node.children) {
collectHouses(node.children, checkedKeys);
}
}
}
});
};
collectHouses(treeData, keys);
setSelectedHouses(selectedHousesList);
setSelectAll(
selectedHousesList.length > 0 &&
selectedHousesList.length ===
treeData.reduce(
(total, building) =>
total +
(building.children?.reduce(
(unitTotal, unit) => unitTotal + (unit.children?.length || 0),
0,
) || 0),
0,
),
);
};
// 处理节点选择
const onSelect = (selectedKeysValue: React.Key[]) => {
setSelectedKeys(selectedKeysValue);
};
// 处理动态加载数据
const onLoadData = async (node: TreeNodeType) => {
if (node.isLeaf) {
return Promise.resolve();
}
// 加载楼栋下的单元
if (node.key.toString().startsWith('building-')) {
console.log('node.key', node.key);
// 从key中提取buildingId格式为'building-{id}'
const buildingId = parseInt(
node.key.toString().replace('building-', ''),
10,
);
await loadUnits(buildingId, node.key as string);
// 如果楼栋被选中,加载并选中其下所有单元和房屋
if (checkedKeys.includes(node.key)) {
// 直接调用loadBuildingHouses加载该楼栋下所有房屋
await loadBuildingHouses(buildingId);
}
return Promise.resolve();
}
// 加载单元下的房屋
if (node.key.toString().startsWith('unit-')) {
// 从key中提取unitId格式为'unit-{id}'
const unitId = parseInt(node.key.toString().replace('unit-', ''), 10);
const buildingId = node.asset_buildings_id as number;
await loadHouses(buildingId, unitId, node.key as string);
// 如果单元被选中,选中其下所有房屋
if (checkedKeys.includes(node.key)) {
// 直接调用loadUnitHouses加载该单元下所有房屋
await loadUnitHouses(buildingId, unitId);
}
return Promise.resolve();
}
return Promise.resolve();
};
// 加载所有房屋数据
const loadAllHouses = async () => {
setLoading(true);
try {
const res = await Apis.Asset.AssetHouses.List({
asset_projects_id: props?.item?.asset_projects_id,
});
if (res?.data) {
const allHouseKeys: React.Key[] = [];
const allHouses: {
id: number;
name: string;
buildingName: string;
unitName: string;
}[] = [];
// 创建映射以快速查找楼栋和单元名称
const buildingMap = new Map();
const unitMap = new Map();
// 填充楼栋映射
treeData.forEach((building) => {
buildingMap.set(building.id, building.title);
building.children?.forEach((unit) => {
unitMap.set(unit.id, unit.title);
});
});
res.data.forEach((house: any) => {
const houseKey = `house-${house.id}`;
allHouseKeys.push(houseKey);
const buildingName = buildingMap.get(house.asset_buildings_id) || '';
const unitName = unitMap.get(house.asset_units_id) || '';
allHouses.push({
id: house.id,
name: `${buildingName} ${unitName} ${house.name}(${house.id})`,
buildingName: buildingName as string,
unitName: unitName as string,
});
});
setCheckedKeys(allHouseKeys);
setSelectedHouses(allHouses);
}
} catch (error) {
console.error('加载所有房屋失败:', error);
message.error('加载所有房屋失败');
} finally {
setLoading(false);
}
};
// 加载楼栋下所有房屋
const loadBuildingHouses = async (buildingId: number) => {
setLoading(true);
try {
const res = await Apis.Asset.AssetHouses.List({
asset_projects_id: props?.item?.asset_projects_id,
asset_buildings_id: buildingId,
});
if (res?.data) {
const buildingHouseKeys: React.Key[] = [];
const buildingHouses: {
id: number;
name: string;
buildingName: string;
unitName: string;
}[] = [];
// 获取楼栋名称
const building = treeData.find((b) => b.id === buildingId);
const buildingName = building?.title || '';
// 创建单元映射
const unitMap = new Map();
building?.children?.forEach((unit) => {
unitMap.set(unit.id, unit.title);
});
res.data.forEach((house: any) => {
const houseKey = `house-${house.id}`;
buildingHouseKeys.push(houseKey);
const unitName = unitMap.get(house.asset_units_id) || '';
buildingHouses.push({
id: house.id,
name: `${buildingName} ${unitName} ${house.name}(${house.id})`,
buildingName: buildingName as string,
unitName: unitName as string,
});
});
// 合并当前选中的keys和新的keys
const newCheckedKeys = Array.from(
new Set([...checkedKeys, ...buildingHouseKeys]),
);
setCheckedKeys(newCheckedKeys);
// 合并当前选中的房屋和新的房屋
const existingIds = new Set(selectedHouses.map((h) => h.id));
const newHouses = buildingHouses.filter((h) => !existingIds.has(h.id));
setSelectedHouses([...selectedHouses, ...newHouses]);
}
} catch (error) {
console.error('加载楼栋房屋失败:', error);
message.error('加载楼栋房屋失败');
} finally {
setLoading(false);
}
};
// 加载单元下所有房屋
const loadUnitHouses = async (buildingId: number, unitId: number) => {
setLoading(true);
try {
const res = await Apis.Asset.AssetHouses.List({
asset_projects_id: props?.item?.asset_projects_id,
asset_buildings_id: buildingId,
asset_units_id: unitId,
});
if (res?.data) {
const unitHouseKeys: React.Key[] = [];
const unitHouses: {
id: number;
name: string;
buildingName: string;
unitName: string;
}[] = [];
// 获取楼栋和单元名称
const building = treeData.find((b) => b.id === buildingId);
const buildingName = building?.title || '';
const unit = building?.children?.find((u) => u.id === unitId);
const unitName = unit?.title || '';
res.data.forEach((house: any) => {
const houseKey = `house-${house.id}`;
unitHouseKeys.push(houseKey);
unitHouses.push({
id: house.id,
name: `${buildingName} ${unitName} ${house.name}(${house.id})`,
buildingName: buildingName as string,
unitName: unitName as string,
});
});
// 合并当前选中的keys和新的keys
const newCheckedKeys = Array.from(
new Set([...checkedKeys, ...unitHouseKeys]),
);
setCheckedKeys(newCheckedKeys);
// 合并当前选中的房屋和新的房屋
const existingIds = new Set(selectedHouses.map((h) => h.id));
const newHouses = unitHouses.filter((h) => !existingIds.has(h.id));
setSelectedHouses([...selectedHouses, ...newHouses]);
}
} catch (error) {
console.error('加载单元房屋失败:', error);
message.error('加载单元房屋失败');
} finally {
setLoading(false);
}
};
// 处理全选
const handleSelectAll = async (e: CheckboxChangeEvent) => {
setSelectAll(e.target.checked);
if (e.target.checked) {
// 调用接口获取所有房屋
await loadAllHouses();
} else {
// 取消全选
setCheckedKeys([]);
setSelectedHouses([]);
}
};
// 提交选中的房屋
const handleSubmit = async () => {
if (selectedHouses.length === 0) {
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="small"
title={`${props.title}`}
/>
}
node={
<ProCard
title={
<div>
<Title level={4} style={{ marginBottom: '16px' }}>
<div>
<div>{props?.item?.name || '标准名称'}</div>
<Space>
<renderTextHelper.Tag
Enums={HouseBillsTypeEnum}
value={props?.item?.charge_type}
key="type"
/>
<renderTextHelper.Tag
Enums={HouseChargeStandardsCalculationModeEnum}
value={props?.item?.calculation_mode}
key="type"
/>
<renderTextHelper.Tag
Enums={HouseChargeStandardsCalculationPeriodEnum}
value={props?.item?.calculation_period}
key="type"
/>
</Space>
</div>
</Title>
<Alert
message="请选择需要绑定的房屋"
type="info"
showIcon
style={{ margin: 0 }}
/>
</div>
}
>
<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

@ -0,0 +1,446 @@
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 Update(props: MyBetaModalFormProps) {
const [form] = Form.useForm();
const actionRef = useRef<any>();
return (
<BetaSchemaForm<ApiTypes.HouseCharage.HouseChargeStandards.Update>
{...MyModalFormProps.props}
title={props.title}
wrapperCol={{ span: 24 }}
width="600px"
trigger={
<MyButtons.Default title={props.title} size="small" type="primary" />
}
form={form}
key={new Date().getTime()}
onOpenChange={(open: any) => {
if (open) {
form.setFieldsValue(props?.item); // 编辑赋值
}
}}
onFinish={async (values) =>
Apis.HouseCharage.HouseChargeStandards.Update({
...values,
asset_projects_id: props?.item?.asset_projects_id,
type:
values.charge_type === HouseBillsTypeEnum.SharedWaterFee.value ||
values.charge_type === HouseBillsTypeEnum.SharedElectricityFee.value
? 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,
id: props?.item?.id,
tiered_rates: values.tiered_rates?.map((res: any) => {
return {
...res,
};
}),
// 避免计费模式切换导致的价格异常
price:
values?.price_algorithm ===
HouseChargeStandardsPriceAlgorithmEnum.Fixed.value
? values.price
: 0,
})
.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,
}),
{
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,
}),
]
: [];
},
},
{
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: 16 },
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: 16 },
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 &&
calculation_method !==
HouseChargeStandardsCalculationMethodEnum.PerUnit.value
? []
: [
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,
// 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: 'tiered_rates',
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: 'min_quantity',
colProps: { span: 10 },
title: '起始值',
valueType: 'number',
fieldProps: {
min: 0,
addonBefore: (
_: any,
{
field,
}: { field: { index: number[] } },
) => `${field.index[1] + 1}阶梯`,
},
width: '100%',
formItemProps: { ...rulesHelper.number },
},
{
key: 'max_quantity',
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: 'tiered_rates',
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: 'min_quantity',
colProps: { span: 10 },
title: '起始值',
valueType: 'number',
fieldProps: {
min: 0,
addonBefore: (
_: any,
{
field,
}: { field: { name: number[] } },
) => `${field.name[1] + 1}阶梯`,
},
width: '100%',
formItemProps: { ...rulesHelper.number },
},
{
key: 'max_quantity',
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: ['price', 'price_algorithm'],
valueType: 'dependency',
columns: ({ price, price_algorithm }: any) => {
return price ||
price_algorithm ===
HouseChargeStandardsPriceAlgorithmEnum.Tiered.value ||
price_algorithm ===
HouseChargeStandardsPriceAlgorithmEnum.Peak.value
? [
{
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

@ -15,10 +15,10 @@ export default function Create(props: MyBetaModalFormProps) {
return (
<BetaSchemaForm<ApiTypes.Grid.Grids.Store>
{...MyModalFormProps.props}
title={`创建网格`}
title={`创建板块`}
wrapperCol={{ span: 24 }}
width="700px"
trigger={<MyButtons.Create title={`创建网格`} />}
trigger={<MyButtons.Create title={`创建板块`} />}
form={form}
key={new Date().getTime()}
onOpenChange={(open: any) => {
@ -70,7 +70,7 @@ export default function Create(props: MyBetaModalFormProps) {
<ProCard
bordered
style={{ marginBlockEnd: 0 }}
title={`添加单元${index + 1}`}
title={`创建板块${index + 1}`}
extra={action}
bodyStyle={{ paddingBlockEnd: 0 }}
>

View File

@ -16,12 +16,12 @@ export default function Create(
return (
<BetaSchemaForm<ApiTypes.Grid.Grids.AddManager>
{...MyModalFormProps.props}
title={`设置网格`}
title={`设置管理`}
wrapperCol={{ span: 24 }}
width="500px"
form={form}
key={new Date().getTime()}
trigger={<MyButtons.Default title="网格员" type="link" />}
trigger={<MyButtons.Default title="管理员" type="link" />}
request={() => Promise.resolve(props.item)}
onOpenChange={(open: any) => {
if (open && props.item) {

View File

@ -9,7 +9,6 @@ import { Apis } from '@/gen/Apis';
import {
AssetHousesOrientationEnum,
AssetHousesOwnershipTypeEnum,
AssetHousesStatusEnum,
AssetHousesUsageEnum,
} from '@/gen/Enums';
import { BetaSchemaForm } from '@ant-design/pro-components';
@ -24,7 +23,7 @@ export default function Create(props: MyBetaModalFormProps) {
title={`添加${props.title}`}
wrapperCol={{ span: 24 }}
width="800px"
trigger={<MyButtons.Create title={`添加${props.title}`} />}
trigger={<MyButtons.Create title={`${props.title}`} />}
form={form}
key={new Date().getTime()}
onOpenChange={(open: any) => {
@ -53,14 +52,20 @@ export default function Create(props: MyBetaModalFormProps) {
colProps: { span: 6 },
formItemProps: { ...rulesHelper.text },
},
MyFormItems.EnumRadio({
key: 'ownership_type',
title: '房屋属性',
colProps: { span: 24 },
valueEnum: AssetHousesOwnershipTypeEnum,
// required: true,
}),
MyFormItems.EnumRadio({
key: 'usage',
title: '用途',
colProps: { span: 18 },
colProps: { span: 24 },
valueEnum: AssetHousesUsageEnum,
required: true,
}),
{
key: 'floor',
title: '楼层',
@ -162,35 +167,29 @@ export default function Create(props: MyBetaModalFormProps) {
valueEnum: AssetHousesOrientationEnum,
// required: true,
}),
MyFormItems.EnumRadio({
key: 'status',
title: '房屋状态',
colProps: { span: 6 },
// valueEnum: AssetHousesStatusEnum,
// required: true,
valueEnum: () => {
let obj: any = JSON.parse(JSON.stringify(AssetHousesStatusEnum));
delete obj.SelfOccupied;
delete obj.Rented;
delete obj.Vacant;
return obj;
},
}),
MyFormItems.EnumSelect({
key: 'ownership_type',
title: '产权性质',
colProps: { span: 6 },
valueEnum: AssetHousesOwnershipTypeEnum,
// required: true,
}),
{
key: 'ownership_term',
title: '产权年限',
fieldProps: {
addonAfter: '年',
},
colProps: { span: 6 },
},
// MyFormItems.EnumRadio({
// key: 'status',
// title: '房屋状态',
// colProps: { span: 6 },
// // valueEnum: AssetHousesStatusEnum,
// // required: true,
// valueEnum: () => {
// let obj: any = JSON.parse(JSON.stringify(AssetHousesStatusEnum));
// delete obj.SelfOccupied;
// delete obj.Rented;
// delete obj.Vacant;
// return obj;
// },
// }),
// {
// key: 'ownership_term',
// title: '产权年限',
// fieldProps: {
// addonAfter: '年',
// },
// colProps: { span: 6 },
// },
]}
/>
);

View File

@ -10,7 +10,6 @@ import { Apis } from '@/gen/Apis';
import {
AssetHousesOrientationEnum,
AssetHousesOwnershipTypeEnum,
AssetHousesStatusEnum,
AssetHousesUsageEnum,
} from '@/gen/Enums';
import { BetaSchemaForm } from '@ant-design/pro-components';
@ -25,7 +24,7 @@ export default function Update(props: MyBetaModalFormProps) {
wrapperCol={{ span: 24 }}
width="800px"
trigger={
<MyButtons.Default title={props.title} size="small" type="link" />
<MyButtons.Default title={props.title} size="small" type="primary" />
}
form={form}
key={new Date().getTime()}
@ -87,25 +86,31 @@ export default function Update(props: MyBetaModalFormProps) {
colProps: { span: 6 },
formItemProps: { ...rulesHelper.number },
}),
{
key: 'name',
title: '房号',
colProps: { span: 6 },
formItemProps: { ...rulesHelper.text },
},
],
},
];
},
},
{
key: 'name',
title: '房号',
colProps: { span: 6 },
formItemProps: { ...rulesHelper.text },
},
MyFormItems.EnumRadio({
key: 'ownership_type',
title: '房屋属性',
colProps: { span: 24 },
valueEnum: AssetHousesOwnershipTypeEnum,
// required: true,
}),
MyFormItems.EnumRadio({
key: 'usage',
title: '用途',
colProps: { span: 18 },
colProps: { span: 24 },
valueEnum: AssetHousesUsageEnum,
required: true,
}),
{
key: 'floor',
title: '楼层',
@ -207,35 +212,20 @@ export default function Update(props: MyBetaModalFormProps) {
valueEnum: AssetHousesOrientationEnum,
// required: true,
}),
MyFormItems.EnumRadio({
key: 'status',
title: '房屋状态',
colProps: { span: 6 },
// valueEnum: AssetHousesStatusEnum,
// required: true,
valueEnum: () => {
let obj: any = JSON.parse(JSON.stringify(AssetHousesStatusEnum));
delete obj.SelfOccupied;
delete obj.Rented;
delete obj.Vacant;
return obj;
},
}),
MyFormItems.EnumSelect({
key: 'ownership_type',
title: '产权性质',
colProps: { span: 6 },
valueEnum: AssetHousesOwnershipTypeEnum,
// required: true,
}),
{
key: 'ownership_term',
title: '产权年限',
fieldProps: {
addonAfter: '年',
},
colProps: { span: 6 },
},
// MyFormItems.EnumRadio({
// key: 'status',
// title: '房屋状态',
// colProps: { span: 6 },
// // valueEnum: AssetHousesStatusEnum,
// // required: true,
// valueEnum: () => {
// let obj: any = JSON.parse(JSON.stringify(AssetHousesStatusEnum));
// delete obj.SelfOccupied;
// delete obj.Rented;
// delete obj.Vacant;
// return obj;
// },
// }),
]}
/>
);

View File

@ -59,14 +59,14 @@ export default function Create(props: MyBetaModalFormProps) {
title: '建筑结构',
colProps: { span: 12 },
valueEnum: AssetUnitsBuildingStructureEnum,
required: true,
// required: true,
}),
MyFormItems.EnumRadio({
key: 'building_type',
title: '建筑类型',
colProps: { span: 12 },
valueEnum: AssetUnitsBuildingTypeEnum,
required: true,
// required: true,
}),
{
key: 'elevator_count',

View File

@ -69,14 +69,14 @@ export default function Update(props: MyBetaModalFormProps) {
title: '建筑结构',
colProps: { span: 12 },
valueEnum: AssetUnitsBuildingStructureEnum,
required: true,
// required: true,
}),
MyFormItems.EnumRadio({
key: 'building_type',
title: '建筑类型',
colProps: { span: 12 },
valueEnum: AssetUnitsBuildingTypeEnum,
required: true,
// required: true,
}),
{
key: 'elevator_count',

View File

@ -10,9 +10,11 @@ import { AssetProjectsPropertyTypeEnum } from '@/gen/Enums';
import { ProTable } from '@ant-design/pro-components';
import { Space } from 'antd';
import { useNavigate } from 'react-router-dom';
import Create from './modals/AssetCreate';
import AssetInfo from './components/AssetInfo';
import AssetCreate from './modals/AssetCreate';
import AssetUpdate from './modals/AssetUpdate';
export default function Index({ title = '项目管理' }) {
export default function Index({ title = '项目列表' }) {
const navigate = useNavigate();
// 注册当前页面为标签页
@ -30,12 +32,12 @@ export default function Index({ title = '项目管理' }) {
}
// headerTitle="项目列表"
toolBarRender={(action) => [
<Create key="Create" reload={action?.reload} title={'项目'} />,
<AssetCreate key="Create" reload={action?.reload} title={'项目'} />,
]}
columns={[
MyColumns.ID(),
MyColumns.EnumTag({
title: '项目类型',
title: '类型',
dataIndex: 'property_type',
valueEnum: AssetProjectsPropertyTypeEnum,
search: false,
@ -81,6 +83,15 @@ export default function Index({ title = '项目管理' }) {
onSoftDelete: Apis.Asset.AssetProjects.SoftDelete,
search: false,
}),
{
title: '绑定机构',
dataIndex: ['company', 'name'],
search: {
transform: (value) => {
return { company_name: value };
},
},
},
// {
// title: '接管日期',
// dataIndex: 'takeover_date',
@ -95,8 +106,10 @@ export default function Index({ title = '项目管理' }) {
MyColumns.Option({
render: (_, item: any, index, action) => (
<Space key={index}>
<AssetInfo item={item} title="查看" reload={action?.reload} />
<AssetUpdate item={item} title="项目" reload={action?.reload} />
<MyButtons.View
title="详情"
title="配置"
onClick={() => {
navigate(`/asset/${item.id}`);
}}

View File

@ -27,14 +27,22 @@ export default function Create(props: MyBetaModalFormProps) {
wrapperCol={{ span: 24 }}
width="600px"
trigger={<MyButtons.Create title={`添加${props.title}`} />}
key={new Date().getTime()}
form={form}
onOpenChange={(open: any) => {
if (open) {
form.resetFields(); // 清空表单数据
form.setFieldsValue({
companies_id: props?.item?.id,
});
}
}}
onFinish={async (values) =>
Apis.Asset.AssetProjects.Store(values)
Apis.Asset.AssetProjects.Store({
...values,
longitude: values?.location ? values.location.split(',')[0] : '',
latitude: values?.location ? values.location.split(',')[1] : '',
})
.then(() => {
props.reload?.();
message.success(props.title + '成功');
@ -124,6 +132,23 @@ export default function Create(props: MyBetaModalFormProps) {
},
colProps: { span: 8 },
},
{
title: '项目经纬度',
dataIndex: 'location',
colProps: { span: 24 },
fieldProps: {
addonAfter: (
<MyButtons.View
title="获取经纬度"
onClick={() => {
window.open(
'https://api.map.baidu.com/lbsapi/getpoint/index.html',
);
}}
/>
),
},
},
]}
/>
);

View File

@ -6,7 +6,6 @@ import {
rulesHelper,
} from '@/common';
import { Address } from '@/components/Address';
import { Selects } from '@/components/Select';
import { Apis } from '@/gen/Apis';
import {
AssetProjectsChargeEnum,
@ -29,9 +28,13 @@ export default function Update(props: MyBetaModalFormProps) {
width="600px"
key={new Date().getTime()}
form={form}
onOpenChange={(open: any) => {
onOpenChange={(open: any, props: any) => {
if (open && props.item) {
form.setFieldsValue(props.item);
form.setFieldValue(
'location',
`${props.item?.longitude},${props.item?.latitude}`,
);
}
}}
request={() =>
@ -46,7 +49,12 @@ export default function Update(props: MyBetaModalFormProps) {
})
}
onFinish={async (values) =>
Apis.Asset.AssetProjects.Update({ ...values, id: props.item?.id ?? 0 })
Apis.Asset.AssetProjects.Update({
...values,
id: props.item?.id ?? 0,
longitude: values?.location ? values.location.split(',')[0] : '',
latitude: values?.location ? values.location.split(',')[1] : '',
})
.then(() => {
props.reload?.();
message.success(props.title + '成功');
@ -66,12 +74,12 @@ export default function Update(props: MyBetaModalFormProps) {
title: '项目别名',
colProps: { span: 12 },
},
Selects?.Companies({
key: 'companies_id',
title: '所属机构',
colProps: { span: 24 },
formItemProps: { ...rulesHelper.number },
}),
// Selects?.Companies({
// key: 'companies_id',
// title: '所属机构',
// colProps: { span: 24 },
// formItemProps: { ...rulesHelper.number },
// }),
Address.Cascader({
key: 'casacader',
title: '选择地址',
@ -136,6 +144,23 @@ export default function Update(props: MyBetaModalFormProps) {
},
colProps: { span: 8 },
},
{
title: '项目经纬度',
dataIndex: 'location',
colProps: { span: 24 },
fieldProps: {
addonAfter: (
<MyButtons.View
title="获取经纬度"
onClick={() => {
window.open(
'https://api.map.baidu.com/lbsapi/getpoint/index.html',
);
}}
/>
),
},
},
]}
/>
);

View File

@ -1,23 +1,26 @@
import {
MyButtons,
MyColumns,
MyPageContainer,
MyProTableProps,
usePageTabs,
} from '@/common';
import { MyExport } from '@/components/MyExport';
import { Apis } from '@/gen/Apis';
import {
AssetHousesOrientationEnum,
AssetHousesOwnershipTypeEnum,
AssetHousesStatusEnum,
AssetHousesUsageEnum,
} from '@/gen/Enums';
import { ProTable } from '@ant-design/pro-components';
import { useNavigate } from '@umijs/max';
import { Space } from 'antd';
import { useState } from 'react';
import HousesShow from '../asset/components/modals/HousesShow';
import HousesUpdate from '../asset/components/modals/HousesUpdate';
export default function Index({ title = '房屋列表' }) {
const [getParams, setParams] = useState({});
const navigate = useNavigate();
// 注册当前页面为标签页
usePageTabs({
@ -28,15 +31,35 @@ export default function Index({ title = '房屋列表' }) {
<MyPageContainer title={title}>
<ProTable
{...MyProTableProps.props}
request={async (params, sort) =>
MyProTableProps.request(params, sort, Apis.Asset.AssetHouses.List)
}
request={async (params, sort) => {
setParams(params);
return MyProTableProps.request(
params,
sort,
Apis.Asset.AssetHouses.List,
);
}}
toolBarRender={() => [
<MyExport
key="export"
item={getParams}
download={Apis.Asset.AssetHouses}
/>,
]}
columns={[
MyColumns.ID(),
{
title: '项目名称',
dataIndex: ['asset_project', 'name'],
search: {
transform: (value) => {
return { project_name: value };
},
},
},
{
title: '房屋名称',
dataIndex: 'full_name',
ellipsis: true,
},
MyColumns.EnumTag({
@ -57,7 +80,9 @@ export default function Index({ title = '房屋列表' }) {
title: '建筑面积',
dataIndex: 'built_area',
render(_, record) {
return `${record?.built_area || ''}`;
return `${
record?.built_area ? record?.built_area + ' m²' : '-'
} `;
},
search: false,
},
@ -65,7 +90,9 @@ export default function Index({ title = '房屋列表' }) {
title: '套内面积',
dataIndex: 'inside_area',
render(_, record) {
return `${record?.inside_area || ''}`;
return `${
record?.inside_area ? record?.inside_area + ' m²' : '-'
} `;
},
search: false,
},
@ -73,31 +100,33 @@ export default function Index({ title = '房屋列表' }) {
title: '计费面积',
dataIndex: 'chargeable_area',
render(_, record) {
return `${record?.chargeable_area || ''}`;
return `${
record?.chargeable_area ? record?.chargeable_area + ' m²' : '-'
} `;
},
search: false,
},
{
title: '户型',
render(_, record) {
return `${record?.room || ''}${record?.hall || ''}${
record?.bathroom || ''
}${record?.kitchen || ''}${record?.balcony || ''}`;
return `${record?.room || 'x'}${record?.hall || 'x'}${
record?.bathroom || 'x'
}${record?.kitchen || 'x'}${record?.balcony || 'x'}`;
},
search: false,
},
MyColumns.EnumTag({
title: '朝向',
dataIndex: 'orientation',
valueEnum: AssetHousesOrientationEnum,
search: false,
}),
MyColumns.EnumTag({
title: '房屋状态',
dataIndex: 'status',
valueEnum: AssetHousesStatusEnum,
search: false,
}),
// MyColumns.EnumTag({
// title: '朝向',
// dataIndex: 'orientation',
// valueEnum: AssetHousesOrientationEnum,
// search: false,
// }),
// MyColumns.EnumTag({
// title: '房屋状态',
// dataIndex: 'status',
// valueEnum: AssetHousesStatusEnum,
// search: false,
// }),
MyColumns.EnumTag({
title: '产权性质',
dataIndex: 'ownership_type',
@ -105,14 +134,14 @@ export default function Index({ title = '房屋列表' }) {
search: false,
}),
{
title: '产权年限',
dataIndex: 'ownership_term',
render(_, record) {
return `${record?.ownership_term || '-'}`;
},
search: false,
},
// {
// title: '产权年限',
// dataIndex: 'ownership_term',
// render(_, record) {
// return `${record?.ownership_term || '-'} 年`;
// },
// search: false,
// },
MyColumns.Option({
render: (_, item: any, index, action) => (
<Space key={index}>
@ -122,6 +151,13 @@ export default function Index({ title = '房屋列表' }) {
reload={action?.reload}
title="编辑"
/>
<MyButtons.Delete
onConfirm={() =>
Apis.Asset.AssetHouses.Delete({
id: item.id,
}).then(() => action?.reload())
}
/>
</Space>
),
}),

View File

@ -14,7 +14,7 @@ import BannerCreate from './modals/BannerCreate';
import BannerShow from './modals/BannerShow';
import BannerUpdate from './modals/BannerUpdate';
export default function Index({ title = '投放内容' }) {
export default function Index({ title = '内容管理' }) {
const navigate = useNavigate();
// 注册当前页面为标签页

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

@ -13,7 +13,7 @@ import { Space } from 'antd';
import BannerSpaceCreate from './modals/BannerSpaceCreate';
import BannerSpaceUpdate from './modals/BannerSpaceUpdate';
export default function Index({ title = '投放位置' }) {
export default function Index({ title = '点位管理' }) {
const navigate = useNavigate();
// 注册当前页面为标签页

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

@ -1,6 +1,7 @@
import {
MyButtons,
MyColumns,
MyImportModal,
MyPageContainer,
MyProTableProps,
usePageTabs,
@ -32,6 +33,15 @@ export default function Index({ title = '账单' }) {
MyProTableProps.request(params, sort, Apis.Bill.HouseBills.List)
}
toolBarRender={(action) => [
<MyImportModal
key="ImportHouse"
title="批量导入"
type="danger"
size="middle"
templateApi={Apis.Bill.HouseBills.DownloadTemplate}
importApi={Apis.Bill.HouseBills.Import}
reload={action?.reload}
/>,
<BillCreate key="Create" reload={action?.reload} title={title} />,
]}
columns={[

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 ChargeInfo from './components/ChargeInfo';
import HasHouse from './components/HasHouse';
export default function Show({ title }: { title?: string } = {}) {
const { id } = useParams<{ id: string }>();
const [data, setShow] = useState<any>({});
// 注册当前页面为标签页
const { addTab } = usePageTabs({
tabKey: `charge-standard-${id}`,
tabLabel: '收费标准详情',
});
const loadShow = () => {
let paramsId: any = { id: id ?? 0 };
Apis.HouseCharage.HouseChargeStandards.Show(paramsId).then((res) => {
setShow(res?.data);
});
};
useEffect(() => {
loadShow();
}, [id]);
let items = [
{
label: '关联房屋',
key: '1',
closable: false,
children: (
<HasHouse
item={{ ...data, charge_standards_id: id }}
reload={() => loadShow()}
/>
),
},
];
return (
<MyPageContainer title={title}>
<ChargeInfo item={data} reload={loadShow} />
<ProCard style={{ marginTop: 16 }}>
<Tabs type="card" items={items} defaultActiveKey="1" size="small" />
</ProCard>
</MyPageContainer>
);
}

View File

@ -0,0 +1,52 @@
import { MyBetaModalFormProps, renderTextHelper } from '@/common';
import {
HouseBillsTypeEnum,
HouseChargeStandardsCalculationModeEnum,
HouseChargeStandardsCalculationPeriodEnum,
} 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="项目名称">
{item?.asset_project?.name}
</ProDescriptions.Item>
<ProDescriptions.Item label="收费项目">
<renderTextHelper.Tag
Enums={HouseBillsTypeEnum}
value={item?.charge_type}
key="type"
/>
</ProDescriptions.Item>
<ProDescriptions.Item label="计费模式">
<renderTextHelper.Tag
Enums={HouseChargeStandardsCalculationModeEnum}
value={item?.calculation_mode}
key="type"
/>
</ProDescriptions.Item>
<ProDescriptions.Item label="账单计费周期">
<renderTextHelper.Tag
Enums={HouseChargeStandardsCalculationPeriodEnum}
value={item?.calculation_period}
key="type"
/>
</ProDescriptions.Item>
<ProDescriptions.Item label="备注">
{item?.remark}
</ProDescriptions.Item>
</ProDescriptions>
</ProCard>
</Space>
);
}

View File

@ -0,0 +1,86 @@
import { MyButtons, MyColumns, MyProTableProps } from '@/common';
import { Apis } from '@/gen/Apis';
import BannerCreate from '@/pages/banner/modals/BannerCreate';
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,
house_charge_standards_id: rest.item?.id,
},
sort,
Apis.HouseCharage.HouseChargeHasHouses.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: 'full_name',
},
{
title: '项目名称',
dataIndex: 'project_name',
},
{
title: '楼栋名称',
dataIndex: 'building_name',
},
{
title: '单元名称',
dataIndex: 'unit_name',
},
{
title: '房号',
dataIndex: 'name',
},
{
title: '绑定时间',
dataIndex: 'updated_at',
search: false,
},
MyColumns.Option({
render: (_, item: any, index, action) => (
<Space key={index}>
<MyButtons.Default
onConfirm={() =>
Apis.HouseCharage.HouseChargeHasHouses.Delete({
id: item.id,
}).then(() => action?.reload())
}
/>
</Space>
),
}),
]}
/>
</>
);
}

View File

@ -0,0 +1,145 @@
import {
MyButtons,
MyColumns,
MyPageContainer,
MyProTableProps,
usePageTabs,
} from '@/common';
import { Apis } from '@/gen/Apis';
import {
HouseBillsTypeEnum,
HouseChargeStandardsCalculationMethodEnum,
HouseChargeStandardsCalculationModeEnum,
HouseChargeStandardsCalculationPeriodEnum,
} from '@/gen/Enums';
import { ProTable } from '@ant-design/pro-components';
import { useNavigate } from '@umijs/max';
import { Space } from 'antd';
import ChargeStandardHasHouse from '../asset/components/modals/ChargeStandardHasHouse';
import ChargeStandardUpdate from '../asset/components/modals/ChargeStandardUpdate';
import ChargeCreate from './modals/ChargeCreate';
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) => [
<ChargeCreate key="Create" reload={action?.reload} title={title} />,
]}
columns={[
MyColumns.ID(),
{
title: '关联项目',
dataIndex: ['asset_project', 'name'],
search: {
transform: (value) => {
return { project_name: value };
},
},
},
{
title: '收费标准名称',
dataIndex: 'name',
search: false,
},
MyColumns.EnumTag({
title: '收费项目',
dataIndex: 'charge_type',
valueEnum: HouseBillsTypeEnum,
}),
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}>
<MyButtons.View
title="查看"
onClick={() => {
navigate(`/charge_standard/${item.id}`);
}}
/>
<ChargeStandardUpdate
item={item}
reload={action?.reload}
title="编辑"
/>
<ChargeStandardHasHouse
item={{
...item,
}}
reload={action?.reload}
title={'绑房'}
/>
<MyButtons.Delete
onConfirm={() =>
Apis.HouseCharage.HouseChargeStandards.Delete({
id: item.id,
}).then(() => action?.reload())
}
/>
</Space>
),
}),
]}
/>
</MyPageContainer>
);
}

View File

@ -0,0 +1,458 @@
import {
MyBetaModalFormProps,
MyButtons,
MyFormItems,
MyModalFormProps,
rulesHelper,
} from '@/common';
import { Selects } from '@/components/Select';
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="600px"
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,
tiered_rates: values.tiered_rates?.map((res: any) => {
return {
...res,
};
}),
// 避免计费模式切换导致的价格异常
price:
values?.price_algorithm ===
HouseChargeStandardsPriceAlgorithmEnum.Fixed.value
? values.price
: 0,
})
.then(() => {
props.reload?.();
message.success('收费标准创建成功');
return true;
})
.catch(() => false);
}}
columns={[
Selects?.AssetProjects({
key: 'asset_projects_id',
title: '项目',
colProps: { span: 12 },
formItemProps: { ...rulesHelper.text },
}),
{
key: 'name',
title: '收费标准名称',
colProps: { span: 12 },
formItemProps: { ...rulesHelper.text },
},
MyFormItems.EnumRadio({
key: 'charge_type',
title: '收费项目',
colProps: { span: 24 },
valueEnum: HouseBillsTypeEnum,
required: true,
}),
{
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,
}),
]
: [];
},
},
// 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: 16 },
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: 16 },
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 &&
calculation_method !==
HouseChargeStandardsCalculationMethodEnum.PerUnit.value
? []
: [
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,
// 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: 'tiered_rates',
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: (
_: any,
{
field,
}: { field: { index: number[] } },
) => `${field.index[1] + 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: 'tiered_rates',
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: (
_: any,
{
field,
}: { field: { name: number[] } },
) => `${field.name[1] + 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: ['price', 'price_algorithm'],
valueType: 'dependency',
columns: ({ price, price_algorithm }: any) => {
return price ||
price_algorithm ===
HouseChargeStandardsPriceAlgorithmEnum.Tiered.value ||
price_algorithm ===
HouseChargeStandardsPriceAlgorithmEnum.Peak.value
? [
{
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

@ -2,15 +2,17 @@ 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 { Space, Tabs } from 'antd';
import { useEffect, useState } from 'react';
import Assets from './components/Assets';
import CompanyApps from './components/CompanyApps';
import ComponentsInfo from './components/ComponentsInfo';
import Employees from './components/Employees';
import Organizations from './components/Organizations';
import Positions from './components/Positions';
import Projects from './components/Projects';
import ReceiptAccounts from './components/ReceiptAccounts';
import CompanyUpdate from './modals/CompanyUpdate';
export default function Show({ title }: { title?: string } = {}) {
const { id } = useParams<{ id: string }>();
@ -19,7 +21,7 @@ export default function Show({ title }: { title?: string } = {}) {
// 注册当前页面为标签页
const { addTab } = usePageTabs({
tabKey: `company-show-${id}`,
tabLabel: data?.short_name || title || '资产详情',
tabLabel: '配置:' + (data?.short_name || title || '资产详情'),
});
const loadShow = () => {
let paramsId: any = { id: id ?? 0 };
@ -41,37 +43,37 @@ export default function Show({ title }: { title?: string } = {}) {
let items = [
{
label: '项目管理',
label: '1-项目配置',
key: '1',
closable: false,
children: <Projects item={data} />,
children: <Assets item={data} />,
},
{
label: '组织管理',
label: '2-组织配置',
key: '2',
closable: false,
children: <Organizations item={data} />,
},
{
label: '岗位管理',
label: '3-岗位配置',
key: '3',
closable: false,
children: <Positions item={data} />,
},
{
label: '员工管理',
label: '4-员工配置',
key: '4',
closable: false,
children: <Employees item={data} />,
},
{
label: '收款账号',
label: '5-账号配置',
key: '5',
closable: false,
children: <ReceiptAccounts item={data} />,
},
{
label: '应用管理',
label: '6-应用配置',
key: '6',
closable: false,
children: <CompanyApps item={data} />,
@ -79,7 +81,24 @@ export default function Show({ title }: { title?: string } = {}) {
];
return (
<MyPageContainer title={title}>
<ComponentsInfo item={data} />
{/* <ComponentsInfo item={data} /> */}
<ProCard
title={`${data?.name} (${data?.short_name})`}
extra={
<Space>
<ComponentsInfo
item={{ ...data, type: 'primary' }}
title="查看"
reload={loadShow}
/>
<CompanyUpdate item={data} title="机构" reload={loadShow} />
</Space>
}
>
<div>
*
</div>
</ProCard>
<ProCard>
<Tabs type="card" items={data?.id ? items : []} />
</ProCard>

View File

@ -9,6 +9,7 @@ import {
AssetProjectsPropertyTypeEnum,
AssetProjectsStatusEnum,
} from '@/gen/Enums';
import AssetCreate from '@/pages/asset/modals/AssetCreate';
import { ProTable } from '@ant-design/pro-components';
import { Space } from 'antd';
import { useNavigate } from 'react-router-dom';
@ -27,16 +28,16 @@ export default function Index(props: MyBetaModalFormProps) {
Apis.Asset.AssetProjects.List,
)
}
// toolBarRender={(action) => [
// <OrganizationsCreate
// key="Create"
// reload={action?.reload}
// item={props?.item}
// title="组织"
// />,
// ]}
toolBarRender={(action) => [
<AssetCreate
key="Create"
reload={action?.reload}
item={props?.item}
title="项目"
/>,
]}
// search={false}
options={false}
// options={false}
columns={[
MyColumns.ID(),
{

View File

@ -1,62 +1,69 @@
import { MyBetaModalFormProps, renderTextHelper } from '@/common';
import { MyModal } from '@/components/MyModal';
import { CompaniesMerchantTypeEnum } from '@/gen/Enums';
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
import { Space } from 'antd';
import CompanyUpdate from '../modals/CompanyUpdate';
export default function info(props: MyBetaModalFormProps) {
return (
<Space direction="vertical" style={{ width: '100%' }}>
<ProCard extra={props.extra}>
<ProDescriptions bordered>
<ProDescriptions.Item label="机构简称">
{props?.item?.short_name}
</ProDescriptions.Item>
<ProDescriptions.Item label="机构名称" span={2}>
<Space>
{props?.item?.name}
<CompanyUpdate
item={props?.item}
title="机构"
reload={props?.reload}
/>
</Space>
</ProDescriptions.Item>
<ProDescriptions.Item label="商户类型">
<renderTextHelper.Tag
Enums={CompaniesMerchantTypeEnum}
value={props?.item?.merchant_type}
key="merchant_type"
/>
</ProDescriptions.Item>
<MyModal
title={props.title || '查看'}
type={props.item?.type || 'primary'}
width="1000px"
node={
<Space direction="vertical" style={{ width: '100%' }}>
<ProCard extra={props.extra}>
<ProDescriptions bordered>
<ProDescriptions.Item label="机构简称">
{props?.item?.short_name}
</ProDescriptions.Item>
<ProDescriptions.Item label="机构名称" span={2}>
<Space>
{props?.item?.name}
{/* <CompanyUpdate
item={props?.item}
title="机构"
reload={props?.reload}
/> */}
</Space>
</ProDescriptions.Item>
<ProDescriptions.Item label="商户类型">
<renderTextHelper.Tag
Enums={CompaniesMerchantTypeEnum}
value={props?.item?.merchant_type}
key="merchant_type"
/>
</ProDescriptions.Item>
<ProDescriptions.Item label="营业执照号" span={2}>
{props?.item?.business_license_number}
</ProDescriptions.Item>
<ProDescriptions.Item label="营业执照号" span={2}>
{props?.item?.business_license_number}
</ProDescriptions.Item>
<ProDescriptions.Item label="联系人姓名">
{props?.item?.contact_name}
</ProDescriptions.Item>
<ProDescriptions.Item label="联系人手机">
{props?.item?.contact_phone}
</ProDescriptions.Item>
<ProDescriptions.Item label="联系人邮箱">
{props?.item?.contact_email}
</ProDescriptions.Item>
<ProDescriptions.Item label="机构地址">
{props?.item?.province || ''}
{props?.item?.city || ''}
{props?.item?.district || ''}
{props?.item?.address || ''}
</ProDescriptions.Item>
<ProDescriptions.Item label="创建日期">
{props?.item?.created_at}
</ProDescriptions.Item>
<ProDescriptions.Item label="最近修改">
{props?.item?.updated_at}
</ProDescriptions.Item>
</ProDescriptions>
</ProCard>
</Space>
<ProDescriptions.Item label="联系人姓名">
{props?.item?.contact_name}
</ProDescriptions.Item>
<ProDescriptions.Item label="联系人手机">
{props?.item?.contact_phone}
</ProDescriptions.Item>
<ProDescriptions.Item label="联系人邮箱">
{props?.item?.contact_email}
</ProDescriptions.Item>
<ProDescriptions.Item label="机构地址">
{props?.item?.province || ''}
{props?.item?.city || ''}
{props?.item?.district || ''}
{props?.item?.address || ''}
</ProDescriptions.Item>
<ProDescriptions.Item label="创建日期">
{props?.item?.created_at}
</ProDescriptions.Item>
<ProDescriptions.Item label="最近修改">
{props?.item?.updated_at}
</ProDescriptions.Item>
</ProDescriptions>
</ProCard>
</Space>
}
/>
);
}

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="员工"
/>,
@ -36,8 +36,12 @@ export default function Index(props: MyBetaModalFormProps) {
//to-do 按层级选择
{
title: '所在组织',
dataIndex: ['organization', 'name'],
search: false,
dataIndex: 'organization_path',
search: {
transform: (value) => {
return { organization_name: value };
},
},
},
{
title: '姓名',

View File

@ -21,7 +21,7 @@ export default function Organizations(props: MyBetaModalFormProps) {
MyProTableProps.request(
{ ...params, companies_id: props?.item?.id },
sort,
Apis.Company.Organizations.List,
Apis.Company.Organizations.TreeList,
)
}
toolBarRender={(action) => [
@ -33,14 +33,8 @@ export default function Organizations(props: MyBetaModalFormProps) {
/>,
]}
// search={false}
options={false}
// options={false}
columns={[
MyColumns.EnumTag({
title: '组织类型',
dataIndex: 'type',
valueEnum: OrganizationsTypeEnum,
search: false,
}),
{
title: '组织名称',
dataIndex: 'name',
@ -50,6 +44,13 @@ export default function Organizations(props: MyBetaModalFormProps) {
dataIndex: 'id',
search: false,
},
MyColumns.EnumTag({
title: '组织类型',
dataIndex: 'type',
valueEnum: OrganizationsTypeEnum,
search: false,
}),
{
title: '上级组织',
dataIndex: ['organization_parent', 'name'],
@ -58,12 +59,12 @@ export default function Organizations(props: MyBetaModalFormProps) {
MyColumns.Option({
render: (_, item: any, index, action) => (
<Space key={index}>
<OrganizationChange
<OrganizationUpdate
item={{ ...item, companies_id: props?.item?.id }}
reload={action?.reload}
title="组织"
/>
<OrganizationUpdate
<OrganizationChange
item={{ ...item, companies_id: props?.item?.id }}
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

@ -11,7 +11,9 @@ export default function Update(props: MyBetaModalFormProps) {
{...MyModalFormProps.props}
title={`${props.title}调整`}
form={form}
trigger={<MyButtons.Edit title="组织调整" type="link" size="middle" />}
trigger={
<MyButtons.Default title="组织调整" type="primary" size="small" />
}
wrapperCol={{ span: 24 }}
width="500px"
onOpenChange={(open: any) => {

View File

@ -41,18 +41,6 @@ export default function Create(props: MyBetaModalFormProps) {
.catch(() => false)
}
columns={[
Selects?.OrganizationsTree({
title: '上级组织',
key: 'parent_id',
params: { companies_id: props?.item?.id },
colProps: { span: 24 },
}),
{
key: 'name',
title: '组织名称',
colProps: { span: 24 },
formItemProps: { ...rulesHelper.text },
},
MyFormItems.EnumRadio({
key: 'type',
title: '组织类型',
@ -60,24 +48,32 @@ export default function Create(props: MyBetaModalFormProps) {
valueEnum: OrganizationsTypeEnum,
required: true,
}),
// Selects?.Employees({
// title: '负责人',
// colProps: { span: 8 },
// }),
// {
// key: 'manager_phone',
// title: '负责人手机',
// colProps: { span: 8 },
// valueType: 'number',
// fieldProps: {
// maxLength: 11,
// },
// },
// {
// key: 'manager_email',
// title: '负责人邮箱',
// colProps: { span: 8 },
// },
{
key: 'name',
title: '组织名称',
colProps: { span: 24 },
formItemProps: { ...rulesHelper.text },
},
{
name: ['type'],
valueType: 'dependency',
columns: ({ type }: any) => {
return type !== OrganizationsTypeEnum.Group.value
? [
Selects?.OrganizationsTree({
title: '请设置上级组织',
key: 'parent_id',
params: { companies_id: props?.item?.id },
colProps: { span: 24 },
fieldProps: {
placeholder: '可搜索或手动选择上级组织',
},
formItemProps: { ...rulesHelper.text },
}),
]
: [];
},
},
]}
/>
);

View File

@ -40,12 +40,6 @@ export default function Update(props: MyBetaModalFormProps) {
.catch(() => false)
}
columns={[
{
key: 'name',
title: '组织名称',
colProps: { span: 24 },
formItemProps: { ...rulesHelper.text },
},
MyFormItems.EnumRadio({
key: 'type',
title: '类型',
@ -53,12 +47,12 @@ export default function Update(props: MyBetaModalFormProps) {
valueEnum: OrganizationsTypeEnum,
required: true,
}),
// Selects?.OrganizationsTree({
// title: '上级组织',
// key: 'parent_id',
// params: { companies_id: props?.item?.companies_id },
// colProps: { span: 24 },
// }),
{
key: 'name',
title: '组织名称',
colProps: { span: 24 },
formItemProps: { ...rulesHelper.text },
},
]}
/>
);

View File

@ -30,7 +30,7 @@ export default function Create(props: MyBetaModalFormProps) {
Apis.Company.CompanyReceiptAccounts.Store({
...values,
companies_id: props?.item?.id,
is_default: values.is_default ? 1 : 0,
is_default: 0,
})
.then(() => {
props.reload?.();
@ -65,6 +65,23 @@ export default function Create(props: MyBetaModalFormProps) {
valueEnum: CompanyReceiptAccountsPayChannelEnum,
required: true,
}),
{
name: ['pay_channel'],
valueType: 'dependency',
columns: ({ pay_channel }: any) => {
return pay_channel ===
CompanyReceiptAccountsPayChannelEnum.TongLian.value
? [
{
key: 'merchant_id',
title: '商户ID',
colProps: { span: 24 },
formItemProps: { ...rulesHelper.text },
},
]
: [];
},
},
// {
// key: 'is_default',
// title: '是否设为默认账号',

View File

@ -31,6 +31,7 @@ export default function Update(props: MyBetaModalFormProps) {
...values,
companies_id: props?.item?.companies_id,
id: props.item?.id ?? 0,
is_default: 0,
})
.then(() => {
props.reload?.();
@ -65,6 +66,23 @@ export default function Update(props: MyBetaModalFormProps) {
valueEnum: CompanyReceiptAccountsPayChannelEnum,
required: true,
}),
{
name: ['pay_channel'],
valueType: 'dependency',
columns: ({ pay_channel }: any) => {
return pay_channel ===
CompanyReceiptAccountsPayChannelEnum.TongLian.value
? [
{
key: 'merchant_id',
title: '商户ID',
colProps: { span: 24 },
formItemProps: { ...rulesHelper.text },
},
]
: [];
},
},
// {
// key: 'is_default',
// title: '是否设为默认账号',

View File

@ -6,11 +6,12 @@ import {
usePageTabs,
} from '@/common';
import { Apis } from '@/gen/Apis';
import { CompaniesMerchantTypeEnum } from '@/gen/Enums';
import { ProTable } from '@ant-design/pro-components';
import { useNavigate } from '@umijs/max';
import { Space } from 'antd';
import ComponentsInfo from './components/ComponentsInfo';
import CompanyCreate from './modals/CompanyCreate';
import CompanyUpdate from './modals/CompanyUpdate';
export default function Index({ title = '机构列表' }) {
const navigate = useNavigate();
@ -39,19 +40,20 @@ export default function Index({ title = '机构列表' }) {
columns={[
MyColumns.ID(),
{
title: '组织简称',
title: '机构简称',
dataIndex: 'short_name',
search: false,
},
{
title: '企业名称',
dataIndex: 'name',
},
MyColumns.EnumTag({
title: '类型',
dataIndex: 'merchant_type',
valueEnum: CompaniesMerchantTypeEnum,
search: false,
}),
// MyColumns.EnumTag({
// title: '类型',
// dataIndex: 'merchant_type',
// valueEnum: CompaniesMerchantTypeEnum,
// search: false,
// }),
MyColumns.SoftDelete({
onRestore: Apis.Company.Companies.Restore,
onSoftDelete: Apis.Company.Companies.SoftDelete,
@ -61,15 +63,26 @@ export default function Index({ title = '机构列表' }) {
MyColumns.Option({
render: (_, item: any, index, action) => (
<Space key={index}>
<ComponentsInfo
item={item}
title="查看"
reload={action?.reload}
/>
<CompanyUpdate
item={{ ...item, type: 'link' }}
title="机构"
reload={action?.reload}
/>
<MyButtons.View
title="详情"
title="配置"
data-tooltip-position="top"
onClick={() => {
navigate(`/company/${item.id}`);
}}
/>
<MyButtons.Delete
onConfirm={() =>
Apis.Common.Admins.Delete({ id: item.id }).then(() =>
Apis.Company.Companies.Delete({ id: item.id }).then(() =>
action?.reload(),
)
}

View File

@ -47,16 +47,18 @@ export default function Create(props: MyBetaModalFormProps) {
key: 'business_license_number',
title: '营业执照号',
colProps: { span: 24 },
tooltip: '限制20位',
formItemProps: { ...rulesHelper.text },
fieldProps: {
maxLength: 18,
},
},
{
key: 'contact_name',
title: '联系人姓名',
colProps: { span: 6 },
// formItemProps: { ...rulesHelper.text },
formItemProps: { ...rulesHelper.text },
},
{
key: 'contact_phone',
@ -66,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

@ -0,0 +1,115 @@
import {
MyButtons,
MyColumns,
MyPageContainer,
MyProTableProps,
usePageTabs,
} from '@/common';
import { Apis } from '@/gen/Apis';
import { ConvenienceServicesTypeEnum } from '@/gen/Enums';
import { ProTable } from '@ant-design/pro-components';
import { useNavigate } from '@umijs/max';
import { Space } from 'antd';
import BannerCreate from './modals/ServiceCreate';
import ServiceUpdate from './modals/ServiceUpdate';
export default function Index({ title = '便民服务' }) {
const navigate = useNavigate();
// 注册当前页面为标签页
usePageTabs({
tabKey: 'convenience_services',
tabLabel: title,
});
return (
<MyPageContainer
title={title}
enableTabs={true}
tabKey="banners"
tabLabel={title}
>
<ProTable
{...MyProTableProps.props}
request={async (params, sort) =>
MyProTableProps.request(
params,
sort,
Apis.Common.ConvenienceServices.List,
)
}
toolBarRender={(action) => [
<BannerCreate key="Create" reload={action?.reload} title={title} />,
]}
columns={[
MyColumns.ID(),
{
title: '关联项目',
dataIndex: ['asset_project', 'name'],
search: {
transform: (value) => {
return { project_name: value };
},
},
},
MyColumns.EnumTag({
title: '类型',
dataIndex: 'type',
valueEnum: ConvenienceServicesTypeEnum,
search: false,
}),
{
title: '服务名称',
dataIndex: 'name',
},
{
title: '联系方式',
render(_, record) {
const content = record?.content || [];
// 过滤有效数据
const validItems = content.filter(
(item: any) => item?.name && item?.phone,
);
return (
<div style={{ lineHeight: '1.6' }}>
{validItems.length > 0 ? (
validItems.map((item: any, index: number) => (
// 每个客户信息单独一行
<div key={index}>
{item.name}: {item.phone}
</div>
))
) : (
<span></span>
)}
</div>
);
},
search: false,
},
MyColumns.Option({
render: (_, item: any, index, action) => (
<Space key={index}>
<ServiceUpdate
item={item}
reload={action?.reload}
title={title}
/>
<MyButtons.Delete
onConfirm={() =>
Apis.Common.ConvenienceServices.Delete({
id: item.id,
}).then(() => action?.reload())
}
/>
</Space>
),
}),
]}
/>
</MyPageContainer>
);
}

View File

@ -0,0 +1,109 @@
import {
MyBetaModalFormProps,
MyButtons,
MyFormItems,
MyModalFormProps,
rulesHelper,
} from '@/common';
import { Selects } from '@/components/Select';
import { Apis } from '@/gen/Apis';
import { ConvenienceServicesTypeEnum } from '@/gen/Enums';
import { BetaSchemaForm } from '@ant-design/pro-components';
import { Form, message } from 'antd';
import { useRef } from 'react';
export default function Create(props: MyBetaModalFormProps) {
const [form] = Form.useForm();
const actionRef = useRef<any>();
return (
<BetaSchemaForm<ApiTypes.Common.ConvenienceServices.Store>
{...MyModalFormProps.props}
title={`添加便民服务`}
wrapperCol={{ span: 24 }}
width="600px"
trigger={<MyButtons.Create title={`添加便民服务`} />}
key={new Date().getTime()}
form={form}
onOpenChange={(open: any) => {
if (open) {
form.resetFields(); // 清空表单数据
}
}}
onFinish={async (values) =>
Apis.Common.ConvenienceServices.Store(values)
.then(() => {
props.reload?.();
message.success('添加便民服务成功');
return true;
})
.catch(() => false)
}
columns={[
MyFormItems.EnumRadio({
key: 'type',
title: '类型',
colProps: { span: 24 },
valueEnum: ConvenienceServicesTypeEnum,
required: true,
}),
{
key: 'name',
title: '名称',
colProps: { span: 12 },
formItemProps: { ...rulesHelper.text },
},
Selects?.AssetProjects({
key: 'asset_projects_id',
title: '项目',
colProps: { span: 12 },
formItemProps: { ...rulesHelper.text },
}),
{
valueType: 'formList',
dataIndex: 'content',
title: '服务内容',
formItemProps: { ...rulesHelper.array },
initialValue: [
{
name: null,
phone: null,
},
],
fieldProps: {
actionRef: actionRef,
copyIconProps: false,
// deleteIconProps: false,
},
columns: [
{
valueType: 'group',
colProps: { span: 24 },
columns: [
{
key: 'name',
colProps: { span: 12 },
// title: '服务名称',
fieldProps: {
addonBefore: '联系对象',
},
width: '100%',
formItemProps: { ...rulesHelper.text },
},
{
key: 'phone',
colProps: { span: 12 },
// title: '阶梯单价',
fieldProps: {
addonBefore: '联系电话',
},
formItemProps: { ...rulesHelper.text },
},
],
},
],
},
]}
/>
);
}

View File

@ -0,0 +1,112 @@
import {
MyBetaModalFormProps,
MyButtons,
MyFormItems,
MyModalFormProps,
rulesHelper,
} from '@/common';
import { Selects } from '@/components/Select';
import { Apis } from '@/gen/Apis';
import { ConvenienceServicesTypeEnum } from '@/gen/Enums';
import { BetaSchemaForm } from '@ant-design/pro-components';
import { Form, message } from 'antd';
import { useRef } from 'react';
export default function Update(props: MyBetaModalFormProps) {
const [form] = Form.useForm();
const actionRef = useRef<any>();
return (
<BetaSchemaForm<ApiTypes.Common.ConvenienceServices.Update>
{...MyModalFormProps.props}
title={`编辑便民服务`}
trigger={<MyButtons.Edit />}
wrapperCol={{ span: 24 }}
width="600px"
key={new Date().getTime()}
form={form}
onOpenChange={(open: any) => {
if (open && props.item) {
form.setFieldsValue(props.item);
}
}}
onFinish={async (values) =>
Apis.Common.ConvenienceServices.Update({
...values,
id: props.item?.id ?? 0,
})
.then(() => {
props.reload?.();
message.success('编辑便民服务成功');
return true;
})
.catch(() => false)
}
columns={[
MyFormItems.EnumRadio({
key: 'type',
title: '类型',
colProps: { span: 24 },
valueEnum: ConvenienceServicesTypeEnum,
required: true,
}),
{
key: 'name',
title: '名称',
colProps: { span: 12 },
formItemProps: { ...rulesHelper.text },
},
Selects?.AssetProjects({
key: 'asset_projects_id',
title: '项目',
colProps: { span: 12 },
formItemProps: { ...rulesHelper.text },
}),
{
valueType: 'formList',
dataIndex: 'content',
title: '服务内容',
formItemProps: { ...rulesHelper.array },
initialValue: [
{
name: null,
phone: null,
},
],
fieldProps: {
actionRef: actionRef,
copyIconProps: false,
// deleteIconProps: false,
},
columns: [
{
valueType: 'group',
colProps: { span: 24 },
columns: [
{
key: 'name',
colProps: { span: 12 },
// title: '服务名称',
fieldProps: {
addonBefore: '联系对象',
},
width: '100%',
formItemProps: { ...rulesHelper.text },
},
{
key: 'phone',
colProps: { span: 12 },
// title: '阶梯单价',
fieldProps: {
addonBefore: '联系电话',
},
formItemProps: { ...rulesHelper.text },
},
],
},
],
},
]}
/>
);
}

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(),
{
@ -50,9 +47,13 @@ export default function Index({ title = '员工管理' }) {
search: false,
},
{
title: '组织',
dataIndex: ['organization', 'name'],
search: false,
title: '所在组织',
dataIndex: 'organization_path',
search: {
transform: (value) => {
return { organization_name: value };
},
},
},
{
title: '姓名',

View File

@ -12,8 +12,7 @@ import {
import { Apis } from '@/gen/Apis';
import {
HouseOccupantsCardTypeEnum,
HouseOccupantsHouseRelationEnum,
HouseRegistersHouseStatusEnum,
HouseOccupantsResidentialRelationEnum,
HouseRegistersStatusEnum,
HouseRegistersTypeEnum,
} from '@/gen/Enums';
@ -32,7 +31,7 @@ export default function Update(props: MyBetaModalFormProps) {
title={props.title}
trigger={<MyButtons.Default title="审核" type="primary" />}
wrapperCol={{ span: 24 }}
width="1000px"
width="800px"
modalProps={{
bodyStyle: { maxHeight: '70vh', overflowY: 'auto' },
}}
@ -57,17 +56,17 @@ export default function Update(props: MyBetaModalFormProps) {
valueType: 'text',
renderFormItem: () => (
<Space direction="vertical" style={{ width: '100%' }}>
<ProCard title="基本信息" size="small">
<ProDescriptions bordered size="small" column={2}>
<ProCard size="small">
<ProDescriptions bordered size="small" column={1}>
<ProDescriptions.Item label="房屋信息">
{props?.item?.asset_house?.full_name || '-'}
</ProDescriptions.Item>
<ProDescriptions.Item label="房屋状态">
{/* <ProDescriptions.Item label="">
<renderTextHelper.Tag
Enums={HouseRegistersHouseStatusEnum}
value={props?.item?.house_status}
/>
</ProDescriptions.Item>
</ProDescriptions.Item> */}
<ProDescriptions.Item label="登记类型">
<renderTextHelper.Tag
Enums={HouseRegistersTypeEnum}
@ -82,7 +81,7 @@ export default function Update(props: MyBetaModalFormProps) {
{props?.item?.customer_info &&
props?.item?.customer_info?.length > 0 && (
<ProCard title="客户信息" size="small">
<ProCard size="small">
<ProTable
{...MyProTableProps.props}
search={false}
@ -93,35 +92,39 @@ export default function Update(props: MyBetaModalFormProps) {
size="small"
columns={[
MyColumns.EnumTag({
title: '房客关系',
dataIndex: 'house_relation',
valueEnum: HouseOccupantsHouseRelationEnum,
width: 100,
title: '居住关系',
dataIndex: 'residential_relation',
valueEnum: HouseOccupantsResidentialRelationEnum,
}),
// MyColumns.EnumTag({
// title:
// props?.item?.status === 'Rented'
// ? '与主租人关系'
// : '与产权人关系',
// // title: '关系说明',
// dataIndex: 'relation_with_owner',
// valueEnum: HouseOccupantsRelationWithOwnerEnum,
// search: false,
// }),
{
title: '姓名',
dataIndex: 'name',
width: 100,
},
{
title: '手机号',
dataIndex: 'phone',
width: 120,
},
MyColumns.EnumTag({
title: '证件类型',
dataIndex: 'card_type',
valueEnum: HouseOccupantsCardTypeEnum,
width: 120,
}),
{
title: '证件号码',
dataIndex: 'id_card',
width: 180,
},
{
title: '证件资料',
width: 120,
render: (_, item) => {
return (
<Space>
@ -148,7 +151,7 @@ export default function Update(props: MyBetaModalFormProps) {
</ProCard>
)}
{props?.item?.type === 'Delivery' &&
{props?.item?.type === 'AddOwner' &&
props?.item?.ownership_info &&
props?.item?.ownership_info?.length > 0 && (
<ProCard title="产证信息" size="small">

View File

@ -1,243 +0,0 @@
import React from 'react';
import { Button, Card, Space, Divider, Row, Col, Statistic, Alert } from 'antd';
import {
PlusOutlined,
UserOutlined,
SettingOutlined,
HomeOutlined,
FileTextOutlined,
TeamOutlined
} from '@ant-design/icons';
import { MyPageContainer, usePageTabs } from '@/common';
import { history } from '@umijs/max';
/**
*
*
*/
export default function TabsDemo() {
const tabsApi = usePageTabs({
tabKey: 'tabs-demo',
tabLabel: '标签页演示',
closable: false // 演示页面不可关闭
});
// 模拟打开不同的页面标签
const openTab = (key: string, label: string, path: string) => {
tabsApi.addTab({
key,
label,
path,
closable: true
});
// 注意:在实际项目中,这里应该使用 history.push(path)
// 由于这是演示,我们只是添加标签而不实际跳转
console.log(`模拟跳转到: ${path}`);
};
const demoTabs = [
{
key: 'employees',
label: '员工管理',
path: '/employees',
icon: <TeamOutlined />,
description: '管理公司员工信息'
},
{
key: 'companies',
label: '公司管理',
path: '/company/companies',
icon: <HomeOutlined />,
description: '管理公司基本信息'
},
{
key: 'house-bills',
label: '房屋账单',
path: '/house_bills',
icon: <FileTextOutlined />,
description: '查看和管理房屋账单'
},
{
key: 'system-admins',
label: '系统管理员',
path: '/system/admins',
icon: <UserOutlined />,
description: '管理系统管理员账户'
},
{
key: 'system-roles',
label: '角色管理',
path: '/system/sys_roles',
icon: <SettingOutlined />,
description: '管理系统角色权限'
}
];
return (
<MyPageContainer
enableTabs
tabKey="tabs-demo"
tabLabel="标签页演示"
title="多标签页功能演示"
>
<Alert
message="多标签页功能演示"
description="这个页面展示了 MyPageContainer 的多标签页功能。您可以点击下方按钮打开新的标签页,然后右键点击标签体验各种操作。"
type="info"
showIcon
style={{ marginBottom: 24 }}
/>
{/* 统计信息 */}
<Row gutter={16} style={{ marginBottom: 24 }}>
<Col span={6}>
<Card>
<Statistic
title="当前标签数量"
value={tabsApi.getTabs().length}
prefix={<FileTextOutlined />}
/>
</Card>
</Col>
<Col span={6}>
<Card>
<Statistic
title="激活标签"
value={tabsApi.getActiveKey()}
valueStyle={{ fontSize: '16px' }}
/>
</Card>
</Col>
<Col span={6}>
<Card>
<Statistic
title="可用操作"
value={6}
suffix="种"
prefix={<SettingOutlined />}
/>
</Card>
</Col>
<Col span={6}>
<Card>
<Statistic
title="演示页面"
value={demoTabs.length}
suffix="个"
prefix={<PlusOutlined />}
/>
</Card>
</Col>
</Row>
{/* 快速打开标签页 */}
<Card title="🚀 快速打开页面" style={{ marginBottom: 24 }}>
<Row gutter={[16, 16]}>
{demoTabs.map(tab => (
<Col span={8} key={tab.key}>
<Card
size="small"
hoverable
onClick={() => openTab(tab.key, tab.label, tab.path)}
style={{ cursor: 'pointer', textAlign: 'center' }}
>
<div style={{ fontSize: '24px', marginBottom: '8px' }}>
{tab.icon}
</div>
<div style={{ fontWeight: 'bold', marginBottom: '4px' }}>
{tab.label}
</div>
<div style={{ fontSize: '12px', color: '#666' }}>
{tab.description}
</div>
</Card>
</Col>
))}
</Row>
</Card>
{/* 标签页操作 */}
<Card title="🎛️ 标签页操作" style={{ marginBottom: 24 }}>
<Space wrap size="middle">
<Button
type="primary"
onClick={() => tabsApi.closeOtherTabs()}
disabled={tabsApi.getTabs().length <= 1}
>
</Button>
<Button
onClick={() => tabsApi.closeLeftTabs()}
disabled={tabsApi.getTabs().length <= 1}
>
</Button>
<Button
onClick={() => tabsApi.closeRightTabs()}
disabled={tabsApi.getTabs().length <= 1}
>
</Button>
<Button
onClick={() => tabsApi.refreshTab()}
>
</Button>
<Button
danger
onClick={() => {
const tabs = tabsApi.getTabs();
const closableTabs = tabs.filter(tab => tab.closable);
closableTabs.forEach(tab => tabsApi.removeTab(tab.key));
}}
disabled={tabsApi.getTabs().filter(tab => tab.closable).length === 0}
>
</Button>
</Space>
</Card>
{/* 功能说明 */}
<Card title="📖 功能说明">
<Row gutter={24}>
<Col span={12}>
<h4>🎯 </h4>
<ul style={{ lineHeight: '1.8' }}>
<li><strong></strong></li>
<li><strong></strong></li>
<li><strong></strong></li>
<li><strong></strong></li>
<li><strong></strong></li>
</ul>
</Col>
<Col span={12}>
<h4>🖱 </h4>
<ul style={{ lineHeight: '1.8' }}>
<li><strong></strong></li>
<li><strong></strong></li>
<li><strong></strong></li>
<li><strong></strong></li>
<li><strong></strong></li>
</ul>
</Col>
</Row>
<Divider />
<h4>💡 使</h4>
<ul style={{ lineHeight: '1.8' }}>
<li></li>
<li></li>
<li>使</li>
<li></li>
<li></li>
</ul>
</Card>
</MyPageContainer>
);
}

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: '请输入手机号码',