@ -17,10 +17,10 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api/': {
|
'/api/': {
|
||||||
target: 'http://10.39.13.78:8002/',
|
target: 'http://10.39.13.78:8001/',
|
||||||
// target: 'https://gcadmin-test.linyikj.com.cn',
|
// target: 'https://gcadmin-test.linyikj.com.cn',
|
||||||
// target: 'http://guocaiservice.com',
|
// target: 'http://guocaiservice.com',
|
||||||
// changeOrigin: true,
|
changeOrigin: true,
|
||||||
pathRewrite: { '^': '' },
|
pathRewrite: { '^': '' },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"url": "http://10.39.13.78:8002/api/docs/openapi",
|
"url": "http://10.39.13.78:8001/api/docs/openapi",
|
||||||
"module": "Admin",
|
"module": "Company",
|
||||||
"outPath": "./src/gen/",
|
"outPath": "./src/gen/",
|
||||||
"apis": {
|
"apis": {
|
||||||
"firstLine": "import { MyResponseType } from '@/common';\nimport { request } from '@umijs/max';"
|
"firstLine": "import { MyResponseType } from '@/common';\nimport { request } from '@umijs/max';"
|
||||||
|
|||||||
28
src/common/components/MyModalPagination.tsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { MyPaginationMetaType } from '@/common';
|
||||||
|
import { Pagination } from 'antd';
|
||||||
|
|
||||||
|
export function MyModalPagination({
|
||||||
|
meta,
|
||||||
|
setParams,
|
||||||
|
}: {
|
||||||
|
meta?: MyPaginationMetaType | null;
|
||||||
|
setParams?: ({ page, perPage }: { page: number; perPage: number }) => void;
|
||||||
|
}) {
|
||||||
|
console.log(meta, 'meta2222');
|
||||||
|
if (!meta) return null;
|
||||||
|
return (
|
||||||
|
<div style={{ textAlign: 'right' }}>
|
||||||
|
<Pagination
|
||||||
|
style={{ padding: '10px 0' }}
|
||||||
|
current={meta?.current_page || 1}
|
||||||
|
total={meta?.total || 0}
|
||||||
|
pageSize={meta?.per_page || 20}
|
||||||
|
onChange={(page, perPage) => setParams?.({ page, perPage })}
|
||||||
|
size="small"
|
||||||
|
showTotal={(total) => `总共${total}条`}
|
||||||
|
showSizeChanger
|
||||||
|
showQuickJumper
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,25 +1,10 @@
|
|||||||
import { MyIcons, MyIconsType, PermissionsType, useMyState } from '@/common';
|
import { MyIcons, MyIconsType, PermissionsType, useMyState } from '@/common';
|
||||||
import AvatarProps from '@/common/components/layout/AvatarProps';
|
import AvatarProps from '@/common/components/layout/AvatarProps';
|
||||||
import {
|
import { SettingOutlined } from '@ant-design/icons';
|
||||||
BellOutlined,
|
|
||||||
SettingOutlined,
|
|
||||||
TabletOutlined,
|
|
||||||
} from '@ant-design/icons';
|
|
||||||
import { Link, RuntimeConfig, history, useNavigate } from '@umijs/max';
|
import { Link, RuntimeConfig, history, useNavigate } from '@umijs/max';
|
||||||
import {
|
import { AutoComplete, Button, Input, Menu, MenuProps, Space } from 'antd';
|
||||||
AutoComplete,
|
|
||||||
Button,
|
|
||||||
Image,
|
|
||||||
Input,
|
|
||||||
Menu,
|
|
||||||
MenuProps,
|
|
||||||
Popover,
|
|
||||||
Space,
|
|
||||||
} from 'antd';
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import './allConfig.scss';
|
import './allConfig.scss';
|
||||||
import ImgCustomerWxApp from './customer_wx_app.jpg';
|
|
||||||
import ImgEmployeeWxApp from './employee_wx_app.jpg';
|
|
||||||
// import Logo from './logo.png';
|
// import Logo from './logo.png';
|
||||||
interface LevelKeysProps {
|
interface LevelKeysProps {
|
||||||
key?: string;
|
key?: string;
|
||||||
@ -122,7 +107,7 @@ export const LayoutConfig: RuntimeConfig['layout'] = () => {
|
|||||||
<div className="headerContentRender">
|
<div className="headerContentRender">
|
||||||
<div style={{ display: 'flex', alignItems: 'center', gap: 20 }}>
|
<div style={{ display: 'flex', alignItems: 'center', gap: 20 }}>
|
||||||
<HeaderSearch permissionsList={permissionsList} />
|
<HeaderSearch permissionsList={permissionsList} />
|
||||||
<Space size={20} style={{ color: '#666' }}>
|
{/* <Space size={20} style={{ color: '#666' }}>
|
||||||
常用功能:
|
常用功能:
|
||||||
{quickLinks.map((q) => (
|
{quickLinks.map((q) => (
|
||||||
<a
|
<a
|
||||||
@ -133,10 +118,10 @@ export const LayoutConfig: RuntimeConfig['layout'] = () => {
|
|||||||
{q.label}
|
{q.label}
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
</Space>
|
</Space> */}
|
||||||
</div>
|
</div>
|
||||||
<Space size={10}>
|
<Space size={10}>
|
||||||
<Popover
|
{/* <Popover
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
title="小程序二维码"
|
title="小程序二维码"
|
||||||
content={
|
content={
|
||||||
@ -155,7 +140,7 @@ export const LayoutConfig: RuntimeConfig['layout'] = () => {
|
|||||||
>
|
>
|
||||||
<Button type="default" shape="circle" icon={<TabletOutlined />} />
|
<Button type="default" shape="circle" icon={<TabletOutlined />} />
|
||||||
</Popover>
|
</Popover>
|
||||||
<Button type="default" shape="circle" icon={<BellOutlined />} />
|
<Button type="default" shape="circle" icon={<BellOutlined />} /> */}
|
||||||
<Button
|
<Button
|
||||||
type="default"
|
type="default"
|
||||||
shape="circle"
|
shape="circle"
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import { theme } from 'antd';
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { stateActions } from '..';
|
import { stateActions } from '..';
|
||||||
import gcLogo from './gclogo.png';
|
// import gcLogo from './gclogo.png';
|
||||||
import logingBg from './loginBgImg.jpg';
|
import logingBg from './loginBgImg.jpg';
|
||||||
|
|
||||||
export function MyLoginPage() {
|
export function MyLoginPage() {
|
||||||
@ -44,7 +44,7 @@ export function MyLoginPage() {
|
|||||||
<LoginFormPage<ApiTypes.Common.Auth.Login>
|
<LoginFormPage<ApiTypes.Common.Auth.Login>
|
||||||
title={
|
title={
|
||||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
|
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
|
||||||
<img src={gcLogo} style={{ height: 30, width: 'auto' }} />
|
{/* <img src={gcLogo} style={{ height: 30, width: 'auto' }} /> */}
|
||||||
<span style={{ color: '#b1b1b1ff', fontSize: 20 }}>|</span>
|
<span style={{ color: '#b1b1b1ff', fontSize: 20 }}>|</span>
|
||||||
<span style={{ color: token.colorTextBase, fontSize: 21 }}>
|
<span style={{ color: token.colorTextBase, fontSize: 21 }}>
|
||||||
智慧物业管理系统
|
智慧物业管理系统
|
||||||
@ -71,7 +71,7 @@ export function MyLoginPage() {
|
|||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
<ProFormText
|
<ProFormText
|
||||||
name="username"
|
name="phone"
|
||||||
fieldProps={{
|
fieldProps={{
|
||||||
size: 'large',
|
size: 'large',
|
||||||
prefix: <UserOutlined className={'prefixIcon'} />,
|
prefix: <UserOutlined className={'prefixIcon'} />,
|
||||||
|
|||||||
3750
src/gen/ApiTypes.d.ts
vendored
2501
src/gen/Apis.ts
1653
src/gen/Enums.ts
38
src/pages/bills/summary/components/SearchInfo.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { Apis } from '@/gen/Apis';
|
||||||
|
import { ProFormSelect, QueryFilter } from '@ant-design/pro-components';
|
||||||
|
import { Form } from 'antd';
|
||||||
|
type Props = {
|
||||||
|
onChange?: (value: any) => void;
|
||||||
|
};
|
||||||
|
export default function Search(props: Props) {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
return (
|
||||||
|
<QueryFilter
|
||||||
|
style={{ backgroundColor: '#fff' }}
|
||||||
|
defaultCollapsed
|
||||||
|
split
|
||||||
|
form={form}
|
||||||
|
onFinish={props?.onChange}
|
||||||
|
onReset={() => {
|
||||||
|
props?.onChange?.(form?.getFieldsValue() || {});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProFormSelect
|
||||||
|
name="asset_houses_id"
|
||||||
|
label="房屋"
|
||||||
|
valueEnum={{
|
||||||
|
open: '未解决',
|
||||||
|
closed: '已解决',
|
||||||
|
}}
|
||||||
|
request={async (params) => {
|
||||||
|
let res = await Apis.Asset.AssetProjects.Select({
|
||||||
|
keywords: params?.keyWords,
|
||||||
|
...params,
|
||||||
|
});
|
||||||
|
return res?.data;
|
||||||
|
}}
|
||||||
|
placeholder="请选择房屋"
|
||||||
|
/>
|
||||||
|
</QueryFilter>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,17 +1,52 @@
|
|||||||
import {
|
import { MyPageContainer } from '@/common';
|
||||||
MyButtons,
|
import { MyModalPagination } from '@/common/components/MyModalPagination';
|
||||||
MyColumns,
|
|
||||||
MyPageContainer,
|
|
||||||
MyProTableProps,
|
|
||||||
} from '@/common';
|
|
||||||
import { Selects } from '@/components/Select';
|
|
||||||
import { Apis } from '@/gen/Apis';
|
import { Apis } from '@/gen/Apis';
|
||||||
import { ProTable } from '@ant-design/pro-components';
|
import { HomeFilled } from '@ant-design/icons';
|
||||||
|
import { ProCard } from '@ant-design/pro-components';
|
||||||
import { useNavigate } from '@umijs/max';
|
import { useNavigate } from '@umijs/max';
|
||||||
import { Space } from 'antd';
|
import { Empty, Space, Tag } from 'antd';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import SearchInfo from './components/SearchInfo';
|
||||||
|
|
||||||
export default function Index({ title = '房屋账单' }) {
|
export default function Index({ title = '房屋账单' }) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
// const [selectedBuilding, setSelectedBuilding] =
|
||||||
|
// useState<SelectedBuilding | null>(null);
|
||||||
|
const [params, setParams] = useState<any>({ page: 1 });
|
||||||
|
const [getSummaryBillListData, setGetSummaryBillListData] = useState<any>({});
|
||||||
|
|
||||||
|
const getSummaryBillList = (data: any) => {
|
||||||
|
Apis.Bill.HouseBills.SummaryBillList({ ...params, ...data }).then((res) => {
|
||||||
|
setParams({ ...params, ...data });
|
||||||
|
setGetSummaryBillListData(res);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getSummaryBillList({ page: 1 });
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// 选择楼栋的回调函数
|
||||||
|
// const handleBuildingSelect = useCallback((building: SelectedBuilding) => {
|
||||||
|
// setSelectedBuilding(building);
|
||||||
|
// // 保存到本地缓存
|
||||||
|
// localStorage.setItem('selectedBuilding', JSON.stringify(building));
|
||||||
|
// }, []);
|
||||||
|
|
||||||
|
// 从本地缓存恢复选中的楼栋信息
|
||||||
|
// useEffect(() => {
|
||||||
|
// const cachedBuilding = localStorage.getItem('selectedBuilding');
|
||||||
|
// if (cachedBuilding) {
|
||||||
|
// try {
|
||||||
|
// const building = JSON.parse(cachedBuilding) as SelectedBuilding;
|
||||||
|
// setSelectedBuilding(building);
|
||||||
|
// // 恢复后重新获取账单列表
|
||||||
|
// getSummaryBillList(building);
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error('Failed to parse cached building:', error);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MyPageContainer
|
<MyPageContainer
|
||||||
@ -20,94 +55,111 @@ export default function Index({ title = '房屋账单' }) {
|
|||||||
tabKey="summary"
|
tabKey="summary"
|
||||||
tabLabel={title}
|
tabLabel={title}
|
||||||
>
|
>
|
||||||
<ProTable
|
<div
|
||||||
{...MyProTableProps.props}
|
style={{
|
||||||
headerTitle="房屋账单"
|
display: 'flex',
|
||||||
request={async (params, sort) =>
|
alignItems: 'start',
|
||||||
MyProTableProps.request(
|
justifyContent: 'space-between',
|
||||||
params,
|
gap: 15,
|
||||||
sort,
|
}}
|
||||||
Apis.Bill.HouseBills.SummaryBillList,
|
>
|
||||||
)
|
<Space direction="vertical" style={{ flex: 1 }}>
|
||||||
}
|
<SearchInfo
|
||||||
columns={[
|
onChange={(values) => {
|
||||||
{
|
setParams({
|
||||||
title: '房屋ID',
|
asset_houses_id: values?.asset_houses_id || '',
|
||||||
dataIndex: 'asset_houses_id',
|
page: 1,
|
||||||
search: false,
|
});
|
||||||
},
|
getSummaryBillList({
|
||||||
Selects?.AssetProjects({
|
asset_houses_id: values?.asset_houses_id || '',
|
||||||
title: '选择项目',
|
page: 1,
|
||||||
key: 'asset_projects_id',
|
});
|
||||||
hidden: true,
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
title: '关联项目',
|
|
||||||
dataIndex: 'project_name',
|
|
||||||
search: false,
|
|
||||||
// search: {
|
|
||||||
// transform: (value) => {
|
|
||||||
// return { project_name: value };
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '房屋名称',
|
|
||||||
dataIndex: ['asset_house', 'full_name'],
|
|
||||||
search: {
|
|
||||||
transform: (value) => {
|
|
||||||
return { full_name: value };
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// title: '账单金额合计',
|
|
||||||
// dataIndex: 'payable_amount_sum',
|
|
||||||
// search: false,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: '滞纳金合计',
|
|
||||||
// dataIndex: 'late_fee_sum',
|
|
||||||
// search: false,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: '优惠金额合计',
|
|
||||||
// dataIndex: 'discount_amount_sum',
|
|
||||||
// search: false,
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
title: '应收合计',
|
|
||||||
dataIndex: 'total_payable_sum',
|
|
||||||
search: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '已收合计',
|
|
||||||
dataIndex: 'total_paid_sum',
|
|
||||||
search: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '未收合计',
|
|
||||||
render: (_, record) => {
|
|
||||||
return (record.total_payable_sum - record.total_paid_sum).toFixed(
|
|
||||||
2,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
search: false,
|
|
||||||
},
|
|
||||||
MyColumns.Option({
|
|
||||||
render: (_, item: any, index) => (
|
|
||||||
<Space key={index}>
|
|
||||||
<MyButtons.View
|
|
||||||
title="查看"
|
|
||||||
onClick={() => {
|
|
||||||
navigate(`/bills/summary/show/${item.asset_houses_id}`);
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Space>
|
<ProCard>
|
||||||
),
|
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 15 }}>
|
||||||
}),
|
{getSummaryBillListData?.data?.length ? null : (
|
||||||
]}
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
padding: '15px 0',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Empty />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{getSummaryBillListData?.data?.map((res: any) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={`item_${res?.id}`}
|
||||||
|
style={{
|
||||||
|
width: '240px',
|
||||||
|
height: '120px',
|
||||||
|
backgroundColor: '#f8f8f8',
|
||||||
|
borderRadius: 5,
|
||||||
|
overflow: 'hidden',
|
||||||
|
cursor: 'pointer',
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
navigate(`/bills/summary/show/${res?.asset_houses_id}`);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
borderBottom: '1px solid #eee',
|
||||||
|
padding: '10px 14px 10px 15px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<HomeFilled />
|
||||||
|
<div>
|
||||||
|
{res.total_payable_sum - res.total_paid_sum > 0 ? (
|
||||||
|
<Tag color="red">欠费</Tag>
|
||||||
|
) : (
|
||||||
|
<Tag color="green">清欠</Tag>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style={{ padding: '0 15px' }}>
|
||||||
|
<div style={{ padding: '10px 0', fontWeight: 'bold' }}>
|
||||||
|
{res?.asset_house?.full_name}
|
||||||
|
</div>
|
||||||
|
{res.total_payable_sum - res.total_paid_sum ? (
|
||||||
|
<div style={{ color: '#f00' }}>
|
||||||
|
欠: ¥
|
||||||
|
{(res.total_payable_sum - res.total_paid_sum).toFixed(
|
||||||
|
2,
|
||||||
|
)}
|
||||||
|
元
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
''
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
padding: '15px 0 0 0',
|
||||||
|
justifyContent: 'flex-end',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MyModalPagination
|
||||||
|
{...{ setParams: getSummaryBillList }}
|
||||||
|
meta={getSummaryBillListData?.meta}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
</ProCard>
|
||||||
|
</Space>
|
||||||
|
</div>
|
||||||
</MyPageContainer>
|
</MyPageContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
MyButtons,
|
MyButtons,
|
||||||
MyColumns,
|
MyColumns,
|
||||||
MyImportModal,
|
|
||||||
MyPageContainer,
|
MyPageContainer,
|
||||||
MyProTableProps,
|
MyProTableProps,
|
||||||
renderTextHelper,
|
renderTextHelper,
|
||||||
@ -21,20 +20,7 @@ export default function Index({ title = '员工管理' }) {
|
|||||||
const getCurrentPermissions = useCurrentPermissions();
|
const getCurrentPermissions = useCurrentPermissions();
|
||||||
let toolBarRender = (action: any) => {
|
let toolBarRender = (action: any) => {
|
||||||
return getCurrentPermissions({
|
return getCurrentPermissions({
|
||||||
create: (
|
add: <EmployeeCreate key="Create" reload={action?.reload} title="员工" />,
|
||||||
<EmployeeCreate key="Create" reload={action?.reload} title="员工" />
|
|
||||||
),
|
|
||||||
export: (
|
|
||||||
<MyImportModal
|
|
||||||
key="ImportHouse"
|
|
||||||
title="导入外部人员"
|
|
||||||
type="default"
|
|
||||||
size="middle"
|
|
||||||
templateApi={Apis.Company.CompanyEmployees.DownloadTemplate}
|
|
||||||
importApi={Apis.Company.CompanyEmployees.Import}
|
|
||||||
reload={action?.reload}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
let tableRender = (item: any, action: any) => {
|
let tableRender = (item: any, action: any) => {
|
||||||
@ -42,14 +28,16 @@ export default function Index({ title = '员工管理' }) {
|
|||||||
update: (
|
update: (
|
||||||
<EmployeeUpdate item={item} reload={action?.reload} title={title} />
|
<EmployeeUpdate item={item} reload={action?.reload} title={title} />
|
||||||
),
|
),
|
||||||
change: <Change item={item} reload={action?.reload} title={title} />,
|
CompanyEmployees: (
|
||||||
|
<Change item={item} reload={action?.reload} title={title} />
|
||||||
|
),
|
||||||
});
|
});
|
||||||
let permissionsSpace = getCurrentPermissions({
|
let permissionsSpace = getCurrentPermissions({
|
||||||
Role: {
|
Role: {
|
||||||
key: '1',
|
key: '1',
|
||||||
label: <Role item={item} reload={action?.reload} title={title} />,
|
label: <Role item={item} reload={action?.reload} title={title} />,
|
||||||
},
|
},
|
||||||
resetPassword: {
|
ResetPassword: {
|
||||||
key: '2',
|
key: '2',
|
||||||
label: (
|
label: (
|
||||||
<MyButtons.Default
|
<MyButtons.Default
|
||||||
@ -97,7 +85,6 @@ export default function Index({ title = '员工管理' }) {
|
|||||||
{...MyProTableProps.props}
|
{...MyProTableProps.props}
|
||||||
// search={false}
|
// search={false}
|
||||||
headerTitle="员工列表"
|
headerTitle="员工列表"
|
||||||
tooltip="通过企微同步的员工信息的修改,需在企微修改后,同步到系统,才能生效。"
|
|
||||||
request={async (params, sort) =>
|
request={async (params, sort) =>
|
||||||
MyProTableProps.request(
|
MyProTableProps.request(
|
||||||
params,
|
params,
|
||||||
@ -106,22 +93,6 @@ export default function Index({ title = '员工管理' }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
toolBarRender={(action) => [
|
toolBarRender={(action) => [
|
||||||
<MyButtons.Default
|
|
||||||
key="sync_wechat_employees"
|
|
||||||
type="primary"
|
|
||||||
size="middle"
|
|
||||||
title="企微同步"
|
|
||||||
isConfirm={true}
|
|
||||||
description="确定要执行企微同步操作吗?"
|
|
||||||
onConfirm={async () => {
|
|
||||||
try {
|
|
||||||
await Apis.Company.CompanyEmployees.SyncWechatEmployees();
|
|
||||||
action?.reload?.();
|
|
||||||
} catch (error) {
|
|
||||||
console.error('同步企微信息失败:', error);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>,
|
|
||||||
<CompletePhone
|
<CompletePhone
|
||||||
key="CompletePhone"
|
key="CompletePhone"
|
||||||
reload={action?.reload}
|
reload={action?.reload}
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import {
|
|||||||
|
|
||||||
import { Selects } from '@/components/Select';
|
import { Selects } from '@/components/Select';
|
||||||
import { Apis } from '@/gen/Apis';
|
import { Apis } from '@/gen/Apis';
|
||||||
import { CompanyEmployeesTypeEnum } from '@/gen/Enums';
|
|
||||||
import { BetaSchemaForm } from '@ant-design/pro-components';
|
import { BetaSchemaForm } from '@ant-design/pro-components';
|
||||||
import { Form, message } from 'antd';
|
import { Form, message } from 'antd';
|
||||||
export default function Update(props: MyBetaModalFormProps) {
|
export default function Update(props: MyBetaModalFormProps) {
|
||||||
@ -16,15 +15,7 @@ export default function Update(props: MyBetaModalFormProps) {
|
|||||||
<BetaSchemaForm<ApiTypes.Company.CompanyEmployees.Update>
|
<BetaSchemaForm<ApiTypes.Company.CompanyEmployees.Update>
|
||||||
{...MyModalFormProps.props}
|
{...MyModalFormProps.props}
|
||||||
title={`组织调整`}
|
title={`组织调整`}
|
||||||
trigger={
|
trigger={<MyButtons.Edit title="组织" type="primary" />}
|
||||||
<MyButtons.Edit
|
|
||||||
title="组织"
|
|
||||||
disabled={
|
|
||||||
props.item?.type !== CompanyEmployeesTypeEnum.External.value
|
|
||||||
}
|
|
||||||
type="primary"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
wrapperCol={{ span: 24 }}
|
wrapperCol={{ span: 24 }}
|
||||||
width="500px"
|
width="500px"
|
||||||
key={new Date().getTime()}
|
key={new Date().getTime()}
|
||||||
|
|||||||
@ -17,14 +17,14 @@ export default function Create(props: MyBetaModalFormProps) {
|
|||||||
return (
|
return (
|
||||||
<BetaSchemaForm<ApiTypes.Company.CompanyEmployees.Store>
|
<BetaSchemaForm<ApiTypes.Company.CompanyEmployees.Store>
|
||||||
{...MyModalFormProps.props}
|
{...MyModalFormProps.props}
|
||||||
title={`添加外部人员`}
|
title={`添加${props?.title}`}
|
||||||
layout="horizontal"
|
layout="horizontal"
|
||||||
labelCol={{ span: 5 }}
|
labelCol={{ span: 5 }}
|
||||||
wrapperCol={{ span: 19 }}
|
wrapperCol={{ span: 19 }}
|
||||||
labelAlign="left"
|
labelAlign="left"
|
||||||
width="500px"
|
width="500px"
|
||||||
key={new Date().getTime()}
|
key={new Date().getTime()}
|
||||||
trigger={<MyButtons.Create title={`外部人员`} />}
|
trigger={<MyButtons.Create title={props?.title} />}
|
||||||
form={form}
|
form={form}
|
||||||
onOpenChange={(open: any) => {
|
onOpenChange={(open: any) => {
|
||||||
if (open) {
|
if (open) {
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import {
|
|||||||
|
|
||||||
import { Selects } from '@/components/Select';
|
import { Selects } from '@/components/Select';
|
||||||
import { Apis } from '@/gen/Apis';
|
import { Apis } from '@/gen/Apis';
|
||||||
import { CompanyEmployeesTypeEnum, SexEnum } from '@/gen/Enums';
|
import { SexEnum } from '@/gen/Enums';
|
||||||
import { BetaSchemaForm } from '@ant-design/pro-components';
|
import { BetaSchemaForm } from '@ant-design/pro-components';
|
||||||
import { Form, message } from 'antd';
|
import { Form, message } from 'antd';
|
||||||
export default function Update(props: MyBetaModalFormProps) {
|
export default function Update(props: MyBetaModalFormProps) {
|
||||||
@ -17,17 +17,7 @@ export default function Update(props: MyBetaModalFormProps) {
|
|||||||
<BetaSchemaForm<ApiTypes.Company.CompanyEmployees.Update>
|
<BetaSchemaForm<ApiTypes.Company.CompanyEmployees.Update>
|
||||||
{...MyModalFormProps.props}
|
{...MyModalFormProps.props}
|
||||||
title={`编辑员工`}
|
title={`编辑员工`}
|
||||||
trigger={
|
trigger={<MyButtons.Default title="编辑" type="primary" size="small" />}
|
||||||
<MyButtons.Default
|
|
||||||
title="编辑"
|
|
||||||
type="primary"
|
|
||||||
// variant="solid"
|
|
||||||
size="small"
|
|
||||||
disabled={
|
|
||||||
props.item?.type !== CompanyEmployeesTypeEnum.External.value
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
layout="horizontal"
|
layout="horizontal"
|
||||||
labelCol={{ span: 5 }}
|
labelCol={{ span: 5 }}
|
||||||
wrapperCol={{ span: 19 }}
|
wrapperCol={{ span: 19 }}
|
||||||
|
|||||||
@ -1,121 +0,0 @@
|
|||||||
import { Scene } from '@antv/l7';
|
|
||||||
import { L7Layer } from '@antv/l7-leaflet';
|
|
||||||
import { Choropleth } from '@antv/l7plot';
|
|
||||||
import * as L from 'leaflet';
|
|
||||||
import 'leaflet/dist/leaflet.css';
|
|
||||||
import { useEffect, useRef } from 'react';
|
|
||||||
import map_bg_img from './images/map_bg_img.png';
|
|
||||||
|
|
||||||
export default function MapInfo() {
|
|
||||||
const sceneRef = useRef<Scene>();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (sceneRef.current) return;
|
|
||||||
// 初始化地图场景
|
|
||||||
const map = L.map('map', {
|
|
||||||
center: [29.909571, 119.600006],
|
|
||||||
zoom: 10,
|
|
||||||
minZoom: 9,
|
|
||||||
maxZoom: 10,
|
|
||||||
zoomControl: false,
|
|
||||||
attributionControl: false,
|
|
||||||
}).setView([29.909571, 119.600006], 9);
|
|
||||||
|
|
||||||
const l7layer = new L7Layer({
|
|
||||||
logoVisible: false,
|
|
||||||
}).addTo(map);
|
|
||||||
const scene: any = l7layer.getScene();
|
|
||||||
// const scene = new Scene({
|
|
||||||
// id: 'map', // 传递 DOM 元素
|
|
||||||
// map: new Map({
|
|
||||||
// style: 'blank',
|
|
||||||
// pitch: 0,
|
|
||||||
// rotation: 0,
|
|
||||||
// center: [120.19382669582967, 30.258134],
|
|
||||||
// zoom: 9,
|
|
||||||
// minZoom: 8.5,
|
|
||||||
// maxZoom: 9,
|
|
||||||
// }),
|
|
||||||
// });
|
|
||||||
|
|
||||||
sceneRef.current = scene;
|
|
||||||
|
|
||||||
scene.on('loaded', () => {
|
|
||||||
// const imageLayer = new ImageLayer();
|
|
||||||
// imageLayer.source(localMapImage, {
|
|
||||||
// parser: {
|
|
||||||
// type: 'image',
|
|
||||||
// extent: [110, 27, 130, 45],
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
// scene.addLayer(imageLayer);
|
|
||||||
|
|
||||||
const choropleth = new Choropleth({
|
|
||||||
chinaBorder: false,
|
|
||||||
source: {
|
|
||||||
data: [],
|
|
||||||
joinBy: {
|
|
||||||
sourceField: 'name',
|
|
||||||
geoField: 'value',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
viewLevel: {
|
|
||||||
level: 'city',
|
|
||||||
adcode: 330100,
|
|
||||||
},
|
|
||||||
autoFit: true,
|
|
||||||
style: {
|
|
||||||
opacity: 1,
|
|
||||||
stroke: '#0083FF',
|
|
||||||
lineWidth: 1,
|
|
||||||
lineOpacity: 1,
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
field: 'name',
|
|
||||||
style: {
|
|
||||||
fill: '#000',
|
|
||||||
opacity: 1,
|
|
||||||
fontSize: 15,
|
|
||||||
strokeWidth: 1.5,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
state: {
|
|
||||||
active: { stroke: '#0083FF', lineWidth: 1, fill: '#E4F2FF' },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
choropleth.addToScene(scene);
|
|
||||||
});
|
|
||||||
scene.on('resize', () => {
|
|
||||||
console.log('resize');
|
|
||||||
});
|
|
||||||
|
|
||||||
// 组件卸载时清理
|
|
||||||
return () => {
|
|
||||||
if (sceneRef.current) {
|
|
||||||
sceneRef.current.destroy();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
height: '582px',
|
|
||||||
position: 'relative',
|
|
||||||
zIndex: 1,
|
|
||||||
backgroundColor: '#fff',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
id="map"
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
height: '582px',
|
|
||||||
background: `url(${map_bg_img}) no-repeat bottom`,
|
|
||||||
backgroundSize: '100%',
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
import { MyBetaModalFormProps } from '@/common';
|
|
||||||
import { Space } from 'antd';
|
|
||||||
import MyOverviewClient from './charts/OverviewClient';
|
|
||||||
import AddressIcon from './images/addressIcon.png';
|
|
||||||
import ImgLeftIcon from './images/LeftIcon.png';
|
|
||||||
import ImgMapTitleBg from './images/map_title_bg_img.svg';
|
|
||||||
import MyMapAntL7 from './MapAntL7';
|
|
||||||
import './styleMap.scss';
|
|
||||||
export default function Map(props: MyBetaModalFormProps) {
|
|
||||||
return (
|
|
||||||
<Space direction="vertical" style={{ width: '100%' }} size="small">
|
|
||||||
<div className="map_card">
|
|
||||||
<MyMapAntL7 />
|
|
||||||
<div className="map_card_contents">
|
|
||||||
<img src={ImgMapTitleBg} className="map_card_title_bg" />
|
|
||||||
<div className="map_data_contents">
|
|
||||||
<div className="map_card_title">项目分布数据</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="map_card_data_contents">
|
|
||||||
<div className="map_card_data">
|
|
||||||
<div>
|
|
||||||
<div className="map_card_data_title">
|
|
||||||
<img src={ImgLeftIcon} />
|
|
||||||
<span>用户总数</span>
|
|
||||||
{/* <img src={ImgRightIcon} /> */}
|
|
||||||
</div>
|
|
||||||
<div className="map_card_data_number">
|
|
||||||
{props?.item?.rankingData?.total_users}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="map_card_data">
|
|
||||||
<div>
|
|
||||||
<div className="map_card_data_title">
|
|
||||||
<img src={ImgLeftIcon} />
|
|
||||||
<span>管理户数</span>
|
|
||||||
{/* <img src={ImgRightIcon} /> */}
|
|
||||||
</div>
|
|
||||||
<div className="map_card_data_number">
|
|
||||||
{props?.item?.rankingData?.total_occupants}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="others_project">
|
|
||||||
<div className="others_project_cell_list">
|
|
||||||
<img src={AddressIcon} alt="" />
|
|
||||||
<div>苏州3个项目</div>
|
|
||||||
</div>
|
|
||||||
<div className="others_project_cell_list">
|
|
||||||
<img src={AddressIcon} alt="" />
|
|
||||||
<div>南京3个项目</div>
|
|
||||||
</div>
|
|
||||||
<div className="others_project_cell_list">
|
|
||||||
<img src={AddressIcon} alt="" />
|
|
||||||
<div>上海8个项目</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<MyOverviewClient item={props?.item?.overviewData} />
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,163 +0,0 @@
|
|||||||
import { useMyState } from '@/common';
|
|
||||||
import { Apis } from '@/gen/Apis';
|
|
||||||
import { DoubleRightOutlined, RightOutlined } from '@ant-design/icons';
|
|
||||||
import { ProCard } from '@ant-design/pro-components';
|
|
||||||
import { useNavigate } from '@umijs/max';
|
|
||||||
import { Progress, Space } from 'antd';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import ContractsToTalNumberBg from './images/ContractsToTalNumberBg.jpg';
|
|
||||||
import InfoIcon from './images/info.png';
|
|
||||||
import './styleLeft.scss';
|
|
||||||
export default function OverviewContractData() {
|
|
||||||
const { snap } = useMyState();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const [pendingCount, setPendingCount] = useState(0);
|
|
||||||
const [contractCount, setContractCount] = useState(0);
|
|
||||||
const [contractCountList, setContractCountList] = useState<any>([]);
|
|
||||||
|
|
||||||
const getPendingCount = async () => {
|
|
||||||
const res = await Apis.Approval.ApprovalInstances.PendingCount();
|
|
||||||
setPendingCount(res?.data?.count || 0);
|
|
||||||
const res2 = await Apis.Statistics.IndexCount.ContractStatistics();
|
|
||||||
setContractCount(res2?.data?.total);
|
|
||||||
setContractCountList([
|
|
||||||
{
|
|
||||||
title: '未审批',
|
|
||||||
number: res2?.data?.pending_approval,
|
|
||||||
path: '/contract/contracts',
|
|
||||||
status: 'TemporaryStorage',
|
|
||||||
color: '#FF2427',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '未用印',
|
|
||||||
number: res2?.data?.pending_seal,
|
|
||||||
path: '/contract/contracts',
|
|
||||||
color: '#F9B01E',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '未归档',
|
|
||||||
number: res2?.data?.pending_archive,
|
|
||||||
path: '/contract/contracts',
|
|
||||||
color: '#FFD789',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '待关闭',
|
|
||||||
number: res2?.data?.pending_close,
|
|
||||||
path: '/contract/contracts',
|
|
||||||
color: '#2A7EFB',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '审批中',
|
|
||||||
number: res2?.data?.under_approval,
|
|
||||||
status: 'UnderApproval',
|
|
||||||
path: '/contract/contracts',
|
|
||||||
color: '#2A7EFB',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '30天内到期',
|
|
||||||
number: res2?.data?.expiring_30_days,
|
|
||||||
path: '/contract/contracts',
|
|
||||||
color: '#2A7EFB',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '60天内到期',
|
|
||||||
number: res2?.data?.expiring_60_days,
|
|
||||||
path: '/contract/contracts',
|
|
||||||
color: '#2A7EFB',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '履约中',
|
|
||||||
number: res2?.data?.in_progress,
|
|
||||||
path: '/contract/contracts',
|
|
||||||
color: '#2A7EFB',
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
console.log(res);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getPendingCount();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Space direction="vertical" style={{ width: '100%' }} size="small">
|
|
||||||
<ProCard className="border_radius_15px overview_contract_info_data_card">
|
|
||||||
<div className="review_information">
|
|
||||||
<div>
|
|
||||||
<div className="info_title">
|
|
||||||
{snap.session.user?.name || ''},欢迎回来!
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="info_content"
|
|
||||||
onClick={() => {
|
|
||||||
navigate('/approval/pending');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{pendingCount ? (
|
|
||||||
<a>
|
|
||||||
你有{pendingCount || 0}条待审核,请及时处理
|
|
||||||
<DoubleRightOutlined />
|
|
||||||
</a>
|
|
||||||
) : (
|
|
||||||
'暂无可审核信息'
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<img src={InfoIcon} alt="" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ProCard>
|
|
||||||
<ProCard
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
title={<a href="/contract/contracts_bi">合同数据概览</a>}
|
|
||||||
className="border_radius_15px overview_contract_data_card"
|
|
||||||
headerBordered
|
|
||||||
>
|
|
||||||
<Space direction="vertical" style={{ width: '100%' }}>
|
|
||||||
{/* <MyPageTitle title="合同数据概览" /> */}
|
|
||||||
<div className="contracts_total_number">
|
|
||||||
<img src={ContractsToTalNumberBg} alt="" />
|
|
||||||
<div className="contracts_total_number_text">
|
|
||||||
<div className="contracts_total_number_text_title">合同总数</div>
|
|
||||||
<div className="contracts_total_number_text_number">
|
|
||||||
{contractCount || 0}份
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Space direction="vertical" size={10} style={{ width: '100%' }}>
|
|
||||||
{contractCountList?.map((res: any, index: number) => {
|
|
||||||
return (
|
|
||||||
<div key={`items_${index}`}>
|
|
||||||
<a
|
|
||||||
className="progress_title progress_title_first"
|
|
||||||
onClick={() => {
|
|
||||||
navigate(`${res?.path}?status=${res?.status}`);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="progress_title_text">
|
|
||||||
{res?.title} <RightOutlined />
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="progress_title_number"
|
|
||||||
style={{ color: index < 3 ? res?.color : '#666' }}
|
|
||||||
>
|
|
||||||
{res?.number}份
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<Progress
|
|
||||||
percent={res?.number}
|
|
||||||
status="active"
|
|
||||||
strokeColor={res?.color}
|
|
||||||
size={['100%', 14]}
|
|
||||||
showInfo={false}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Space>
|
|
||||||
</Space>
|
|
||||||
</ProCard>
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
export default function PageTitle(props: {
|
|
||||||
title?: string;
|
|
||||||
subTitle?: string;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
borderLeft: '5px solid #1890FF',
|
|
||||||
margin: '10px 0',
|
|
||||||
fontSize: '15px',
|
|
||||||
height: '23px',
|
|
||||||
lineHeight: '23px',
|
|
||||||
paddingLeft: '10px',
|
|
||||||
display: 'flex',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<h2 style={{ display: 'inline-block' }}>{props.title || '标题'}</h2>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'inline-block',
|
|
||||||
padding: '3px 0 0 5px',
|
|
||||||
color: '#999',
|
|
||||||
fontSize: '15px',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{props?.subTitle}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
import { MyBetaModalFormProps } from '@/common';
|
|
||||||
import { ProCard } from '@ant-design/pro-components';
|
|
||||||
import { Space } from 'antd';
|
|
||||||
import MyFinanceClient from './charts/FinanceClient';
|
|
||||||
import Ranking1 from './images/Ranking1.png';
|
|
||||||
import Ranking2 from './images/Ranking2.png';
|
|
||||||
import Ranking3 from './images/Ranking3.png';
|
|
||||||
import './styleRight.scss';
|
|
||||||
export default function Ranking(props: MyBetaModalFormProps) {
|
|
||||||
return (
|
|
||||||
<Space direction="vertical" size="small" className="overview_ranking_right">
|
|
||||||
<ProCard
|
|
||||||
style={{ width: '100%', height: '582px' }}
|
|
||||||
title="项目缴费率排名"
|
|
||||||
className="border_radius_15px"
|
|
||||||
headerBordered
|
|
||||||
>
|
|
||||||
<Space direction="vertical" size="large" style={{ width: '100%' }}>
|
|
||||||
<div className="ranking_item_content">
|
|
||||||
{props?.item?.rankingData?.payment_ranking?.map(
|
|
||||||
(item: any, index: number) => {
|
|
||||||
return (
|
|
||||||
<div className="ranking_item" key={index}>
|
|
||||||
{index < 3 ? (
|
|
||||||
<img
|
|
||||||
src={
|
|
||||||
index === 0
|
|
||||||
? Ranking1
|
|
||||||
: index === 1
|
|
||||||
? Ranking2
|
|
||||||
: Ranking3
|
|
||||||
}
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<div className="ranking_number">{index + 1}</div>
|
|
||||||
)}
|
|
||||||
<div className="name">{item?.project_name}</div>
|
|
||||||
<div className="number">{item?.payment_rate}%</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Space>
|
|
||||||
</ProCard>
|
|
||||||
<MyFinanceClient item={props?.item?.overviewData} />
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,155 +0,0 @@
|
|||||||
export const workChartsData = [
|
|
||||||
{
|
|
||||||
name: '报修',
|
|
||||||
月份: '1月',
|
|
||||||
数量: 70,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '报事',
|
|
||||||
月份: '1月',
|
|
||||||
数量: 20,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '投诉',
|
|
||||||
月份: '2月',
|
|
||||||
数量: 10,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '报修',
|
|
||||||
月份: '2月',
|
|
||||||
数量: 80,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '报事',
|
|
||||||
月份: '2月',
|
|
||||||
数量: 40,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '投诉',
|
|
||||||
月份: '2月',
|
|
||||||
数量: 6,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '报修',
|
|
||||||
月份: '3月',
|
|
||||||
数量: 67,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '报事',
|
|
||||||
月份: '3月',
|
|
||||||
数量: 27,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '投诉',
|
|
||||||
月份: '3月',
|
|
||||||
数量: 7,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '报修',
|
|
||||||
月份: '4月',
|
|
||||||
数量: 55,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '报事',
|
|
||||||
月份: '4月',
|
|
||||||
数量: 17,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '投诉',
|
|
||||||
月份: '4月',
|
|
||||||
数量: 9,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '报修',
|
|
||||||
月份: '5月',
|
|
||||||
数量: 32,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '报事',
|
|
||||||
月份: '5月',
|
|
||||||
数量: 27,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '投诉',
|
|
||||||
月份: '5月',
|
|
||||||
数量: 11,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '报修',
|
|
||||||
月份: '6月',
|
|
||||||
数量: 42,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '报事',
|
|
||||||
月份: '6月',
|
|
||||||
数量: 7,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '投诉',
|
|
||||||
月份: '6月',
|
|
||||||
数量: 21,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const FinanceClientData = [
|
|
||||||
{
|
|
||||||
name: '应收',
|
|
||||||
月份: '1月',
|
|
||||||
数量: 200,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '实收',
|
|
||||||
月份: '1月',
|
|
||||||
数量: 210,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '应收',
|
|
||||||
月份: '2月',
|
|
||||||
数量: 170,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '实收',
|
|
||||||
月份: '2月',
|
|
||||||
数量: 200,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '应收',
|
|
||||||
月份: '3月',
|
|
||||||
数量: 270,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '实收',
|
|
||||||
月份: '3月',
|
|
||||||
数量: 310,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '应收',
|
|
||||||
月份: '4月',
|
|
||||||
数量: 230,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '实收',
|
|
||||||
月份: '4月',
|
|
||||||
数量: 190,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '应收',
|
|
||||||
月份: '5月',
|
|
||||||
数量: 170,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '实收',
|
|
||||||
月份: '5月',
|
|
||||||
数量: 160,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '应收',
|
|
||||||
月份: '6月',
|
|
||||||
数量: 250,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '实收',
|
|
||||||
月份: '6月',
|
|
||||||
数量: 280,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
import { MyBetaModalFormProps } from '@/common';
|
|
||||||
import { Column } from '@ant-design/plots';
|
|
||||||
import { ProCard } from '@ant-design/pro-components';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
export default function FinanceClient(props: MyBetaModalFormProps) {
|
|
||||||
const [configData, setConfigData] = useState({});
|
|
||||||
const config = {
|
|
||||||
data: [],
|
|
||||||
xField: '月份',
|
|
||||||
yField: '数量',
|
|
||||||
colorField: 'name',
|
|
||||||
group: true,
|
|
||||||
style: {
|
|
||||||
// 矩形四个方向的内边距
|
|
||||||
inset: 3,
|
|
||||||
// 矩形单个方向的内边距
|
|
||||||
// insetLeft:5,
|
|
||||||
// insetRight:20,
|
|
||||||
// insetBottom:10
|
|
||||||
// insetTop:10
|
|
||||||
},
|
|
||||||
};
|
|
||||||
useEffect(() => {
|
|
||||||
console.log(props?.item?.financial, 'financial');
|
|
||||||
setConfigData({ ...config, data: props?.item?.financial || [] });
|
|
||||||
}, [props?.item?.financial]);
|
|
||||||
return (
|
|
||||||
<ProCard
|
|
||||||
title={<a href="/work_order/work_bi">财务数据概览</a>}
|
|
||||||
//跳转链接src/pages/work_order/work_bill/index.tsx
|
|
||||||
|
|
||||||
headerBordered
|
|
||||||
className="border_radius_15px"
|
|
||||||
style={{ height: 468, width: '100%', overflow: 'hidden' }}
|
|
||||||
>
|
|
||||||
<Column {...configData} />
|
|
||||||
</ProCard>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
import { MyBetaModalFormProps } from '@/common';
|
|
||||||
import { Column } from '@ant-design/plots';
|
|
||||||
import { ProCard } from '@ant-design/pro-components';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
export default function OverviewClient(props: MyBetaModalFormProps) {
|
|
||||||
const [configData, setConfigData] = useState({});
|
|
||||||
const config = {
|
|
||||||
data: [],
|
|
||||||
xField: '月份',
|
|
||||||
yField: '数量',
|
|
||||||
colorField: 'name',
|
|
||||||
group: true,
|
|
||||||
style: {
|
|
||||||
// 矩形四个方向的内边距
|
|
||||||
inset: 5,
|
|
||||||
// 矩形单个方向的内边距
|
|
||||||
// insetLeft:5,
|
|
||||||
// insetRight:20,
|
|
||||||
// insetBottom:10
|
|
||||||
// insetTop:10
|
|
||||||
},
|
|
||||||
};
|
|
||||||
useEffect(() => {
|
|
||||||
console.log(props?.item?.work_order, 'financial');
|
|
||||||
setConfigData({ ...config, data: props?.item?.work_order || [] });
|
|
||||||
}, [props?.item?.work_order]);
|
|
||||||
return (
|
|
||||||
<ProCard
|
|
||||||
title={<a href="/charge/charge_bi">工单数据概览</a>}
|
|
||||||
headerBordered
|
|
||||||
className="border_radius_15px"
|
|
||||||
style={{ height: 468, width: '100%', overflow: 'hidden' }}
|
|
||||||
>
|
|
||||||
<Column {...configData} />
|
|
||||||
</ProCard>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 532 B |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 562 B |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 759 B |
|
Before Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 1.0 KiB |
@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="714" height="47" viewBox="0 0 714 47"><g><g><g><path d="M212,17L231.661898,39.996876C235.461674,44.441154,241.016041,47,246.863251,47L467.13675,47C472.98395,47,478.53833,44.441154,482.3381,39.996877999999995L502,17L212,17Z" fill="#2A7EFB" fill-opacity="1"/></g><g><path d="M0,17L714,17L714,12.000001C714,6.4771528,709.52283,2,704,2L10.000001,2C4.4771528,2,0,6.4771528,0,12.000001L0,17Z" fill="#2A7EFB" fill-opacity="1"/></g></g><g><g><path d="M212,15L231.661898,37.996876C235.461674,42.441154,241.016041,45,246.863251,45L467.13675,45C472.98395,45,478.53833,42.441154,482.3381,37.996877999999995L502,15L212,15Z" fill="#E2F1FF" fill-opacity="1"/></g><g><path d="M0,15L714,15L714,10.000001C714,4.4771528,709.52283,0,704,0L10.000001,0C4.4771528,0,0,4.4771528,0,10.000001L0,15Z" fill="#E2F1FF" fill-opacity="1"/></g></g></g></svg>
|
|
||||||
|
Before Width: | Height: | Size: 941 B |
@ -1,123 +0,0 @@
|
|||||||
.progress_title {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 10px 0 8px 0;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #3d3d3d;
|
|
||||||
&_number {
|
|
||||||
color: #666;
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.review_information {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
img {
|
|
||||||
width: 62px;
|
|
||||||
height: 62px;
|
|
||||||
}
|
|
||||||
.info_title {
|
|
||||||
color: #333;
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
.info_content {
|
|
||||||
color: #2a7efb;
|
|
||||||
font-size: 14px;
|
|
||||||
padding-top: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.overview_contract_info_data_card {
|
|
||||||
height: 100px;
|
|
||||||
}
|
|
||||||
.overview_contract_data_card {
|
|
||||||
height: 950px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 平板端 */
|
|
||||||
@media (min-width: 768px) and (max-width: 1024px) {
|
|
||||||
.contracts_total_number {
|
|
||||||
.contracts_total_number_text {
|
|
||||||
&_title {
|
|
||||||
font-size: 15px;
|
|
||||||
padding-top: 8px;
|
|
||||||
}
|
|
||||||
&_number {
|
|
||||||
font-size: 28px;
|
|
||||||
line-height: 35px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 笔记本端 */
|
|
||||||
@media (min-width: 1025px) and (max-width: 2000px) {
|
|
||||||
.contracts_total_number {
|
|
||||||
position: relative;
|
|
||||||
padding: 15px 0 20px 0;
|
|
||||||
width: 100%;
|
|
||||||
img {
|
|
||||||
width: 100%;
|
|
||||||
border-radius: 15px;
|
|
||||||
font-size: 0;
|
|
||||||
}
|
|
||||||
.contracts_total_number_text {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
padding: 15px;
|
|
||||||
&_title {
|
|
||||||
font-size: 15px;
|
|
||||||
padding-top: 8px;
|
|
||||||
}
|
|
||||||
&_number {
|
|
||||||
font-size: 28px;
|
|
||||||
line-height: 35px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #2a7efb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 台式机大屏幕 */
|
|
||||||
@media (min-width: 2001px) {
|
|
||||||
.contracts_total_number {
|
|
||||||
position: relative;
|
|
||||||
padding: 10px 0;
|
|
||||||
width: 100%;
|
|
||||||
img {
|
|
||||||
width: 100%;
|
|
||||||
border-radius: 15px;
|
|
||||||
font-size: 0;
|
|
||||||
}
|
|
||||||
.contracts_total_number_text {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
padding: 15px;
|
|
||||||
&_title {
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #333;
|
|
||||||
padding-top: 16px;
|
|
||||||
}
|
|
||||||
&_number {
|
|
||||||
font-size: 36px;
|
|
||||||
line-height: 50px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #2a7efb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,99 +0,0 @@
|
|||||||
.map_card {
|
|
||||||
width: 100%;
|
|
||||||
border-radius: 15px;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.map_card_contents {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 4;
|
|
||||||
.map_card_title_bg {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 70px;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.map_data_contents {
|
|
||||||
position: relative;
|
|
||||||
z-index: 100;
|
|
||||||
padding-top: 18px;
|
|
||||||
}
|
|
||||||
.map_card_title {
|
|
||||||
color: #2a7efb;
|
|
||||||
font-size: 1.8rem;
|
|
||||||
font-weight: 500;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.map_card_data_contents {
|
|
||||||
position: absolute;
|
|
||||||
top: 70px;
|
|
||||||
left: 30px;
|
|
||||||
z-index: 100;
|
|
||||||
.map_card_data {
|
|
||||||
// display: inline-block;
|
|
||||||
// 换为 2 行
|
|
||||||
// justify-content: center;
|
|
||||||
// flex-wrap: wrap;
|
|
||||||
// justify-content: space-between;
|
|
||||||
// align-items: center;
|
|
||||||
// display: inline-flex;
|
|
||||||
// text-align: center;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
}
|
|
||||||
.map_card_data_title {
|
|
||||||
color: #3d3d3d;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #0083ff;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
// justify-content: space-between;
|
|
||||||
span {
|
|
||||||
padding: 0 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.map_card_data_number {
|
|
||||||
padding: 10px 0 0 25px;
|
|
||||||
color: #0083ff;
|
|
||||||
font-size: 28px;
|
|
||||||
font-weight: 500;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.others_project {
|
|
||||||
position: absolute;
|
|
||||||
right: 1px;
|
|
||||||
bottom: 10px;
|
|
||||||
z-index: 100;
|
|
||||||
.others_project_cell_list {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
background: linear-gradient(
|
|
||||||
270deg,
|
|
||||||
rgba(124, 191, 255, 0) 0%,
|
|
||||||
rgba(217, 236, 255, 0.67) 95%
|
|
||||||
);
|
|
||||||
padding: 0 10px 0 0;
|
|
||||||
border-left: 5px solid #0083ff;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
width: 200px;
|
|
||||||
color: #0083ff;
|
|
||||||
img {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
margin: 0 3px;
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,112 +0,0 @@
|
|||||||
.ranking_item_content {
|
|
||||||
width: 100%;
|
|
||||||
padding: 0 0 32px 0;
|
|
||||||
}
|
|
||||||
.overview_ranking_right {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.ranking_item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
background-color: #f3f8fb;
|
|
||||||
border-left: 5px solid #2a7efb;
|
|
||||||
padding: 0 15px;
|
|
||||||
margin-top: 24px;
|
|
||||||
height: 73px;
|
|
||||||
width: 100%;
|
|
||||||
img {
|
|
||||||
width: 33px;
|
|
||||||
height: 40px;
|
|
||||||
}
|
|
||||||
.name {
|
|
||||||
flex: 1;
|
|
||||||
padding: 0 15px;
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #3d3d3d;
|
|
||||||
}
|
|
||||||
.number {
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #333;
|
|
||||||
padding-right: 5px;
|
|
||||||
}
|
|
||||||
.ranking_number {
|
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
border-radius: 5px;
|
|
||||||
font-size: 20px;
|
|
||||||
color: #333;
|
|
||||||
font-weight: 500;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
&:first-child {
|
|
||||||
background-color: #fff8eb;
|
|
||||||
margin-top: 10px;
|
|
||||||
border-left: 5px solid #faad14;
|
|
||||||
.number {
|
|
||||||
color: #faad14;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&:nth-child(2) {
|
|
||||||
background-color: #f3f8fb;
|
|
||||||
border-left: 5px solid #b7c7d6;
|
|
||||||
.number {
|
|
||||||
color: #5f8db8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&:nth-child(3) {
|
|
||||||
background-color: #fff9f4;
|
|
||||||
border-left: 5px solid #dcb08e;
|
|
||||||
.number {
|
|
||||||
color: #d08143;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 平板端 */
|
|
||||||
@media (min-width: 768px) and (max-width: 1024px) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 笔记本端 */
|
|
||||||
@media (min-width: 1025px) and (max-width: 2000px) {
|
|
||||||
.ranking_item {
|
|
||||||
padding: 15px;
|
|
||||||
.name {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
.number {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
.ranking_number {
|
|
||||||
width: 26px;
|
|
||||||
height: 26px;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 台式机大屏幕 */
|
|
||||||
@media (min-width: 2001px) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// @media (min-width: 1400px) and (max-width: 2000px) {
|
|
||||||
// .overview_ranking {
|
|
||||||
// width: 100%;
|
|
||||||
// }
|
|
||||||
// .overview_ranking_right {
|
|
||||||
// display: flex;
|
|
||||||
// width: 100%;
|
|
||||||
// align-items: self-start;
|
|
||||||
// justify-content: space-between;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @media (max-width: 1400px) {
|
|
||||||
// .overview_ranking {
|
|
||||||
// width: 100%;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
// import MyModalsMapLeaflet from '@/components/ModalsMapLeaflet';
|
|
||||||
import { Apis } from '@/gen/Apis';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import MyMap from './components/MapContents';
|
|
||||||
import MyOverviewContractData from './components/OverviewContractData';
|
|
||||||
import MyRanking from './components/Ranking';
|
|
||||||
import './style.scss';
|
|
||||||
export default function Index() {
|
|
||||||
const [overviewData, setOverviewData] = useState<any>({});
|
|
||||||
const [rankingData, setRankingData] = useState<any>({});
|
|
||||||
const getFinancialWorkOverview = async () => {
|
|
||||||
const res =
|
|
||||||
await Apis.Statistics.IndexCount.FinancialAndWorkOrderOverview();
|
|
||||||
setOverviewData(res?.data);
|
|
||||||
const res_s =
|
|
||||||
await Apis.Statistics.IndexCount.ProjectDistributionAndPaymentRanking();
|
|
||||||
setRankingData(res_s?.data);
|
|
||||||
console.log(res, 'res');
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getFinancialWorkOverview();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="overview_content">
|
|
||||||
<div className="overview_contract_data">
|
|
||||||
{/* <MyModalsMapLeaflet /> */}
|
|
||||||
<MyOverviewContractData />
|
|
||||||
</div>
|
|
||||||
<div className="overview_map">
|
|
||||||
<div className="overview_map_content">
|
|
||||||
<MyMap
|
|
||||||
item={{ overviewData: overviewData, rankingData: rankingData }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="overview_ranking">
|
|
||||||
<MyRanking
|
|
||||||
item={{ overviewData: overviewData, rankingData: rankingData }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
.overview_content {
|
|
||||||
margin: -20px !important;
|
|
||||||
margin: 0 auto;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.overview_map {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
.overview_contract_data {
|
|
||||||
margin-right: 10px;
|
|
||||||
min-width: 280px;
|
|
||||||
}
|
|
||||||
.overview_map_content {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
.overview_ranking {
|
|
||||||
margin-left: 10px;
|
|
||||||
min-width: 280px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border_radius_15px {
|
|
||||||
border-radius: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 平板端 */
|
|
||||||
@media (min-width: 768px) and (max-width: 1024px) {
|
|
||||||
}
|
|
||||||
/* 笔记本端 */
|
|
||||||
@media (min-width: 1025px) and (max-width: 2000px) {
|
|
||||||
.overview_contract_data {
|
|
||||||
width: 28%;
|
|
||||||
}
|
|
||||||
.overview_ranking {
|
|
||||||
width: 32%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 台式机大屏幕 */
|
|
||||||
@media (min-width: 2001px) {
|
|
||||||
.overview_contract_data {
|
|
||||||
width: 380px;
|
|
||||||
margin-right: 20px;
|
|
||||||
}
|
|
||||||
.overview_ranking {
|
|
||||||
width: 430px;
|
|
||||||
margin-left: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @media (min-width: 1400px) and (max-width: 2000px) {
|
|
||||||
// .overview_content {
|
|
||||||
// width: 100%;
|
|
||||||
// margin: 0 auto;
|
|
||||||
// flex-wrap: wrap;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @media (max-width: 1400px) {
|
|
||||||
// .overview_content {
|
|
||||||
// flex-wrap: wrap;
|
|
||||||
// width: 100%;
|
|
||||||
// margin: 0 auto;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
import { MyBetaModalFormProps } from '@/common';
|
|
||||||
import { Column } from '@ant-design/plots';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
export default function AnalysisClient(props: MyBetaModalFormProps) {
|
|
||||||
const [configData, setConfigData] = useState({});
|
|
||||||
const config = {
|
|
||||||
data: [],
|
|
||||||
xField: '月份',
|
|
||||||
yField: '数量',
|
|
||||||
group: true,
|
|
||||||
style: {
|
|
||||||
// 矩形四个方向的内边距
|
|
||||||
inset: 3,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
useEffect(() => {
|
|
||||||
setConfigData({ ...config, data: props?.item?.chart || [] });
|
|
||||||
}, [props?.item?.chart]);
|
|
||||||
return (
|
|
||||||
<div style={{ height: 303 }}>
|
|
||||||
<Column {...configData} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,155 +0,0 @@
|
|||||||
export const workChartsData = [
|
|
||||||
{
|
|
||||||
name: '物业费',
|
|
||||||
月份: '1月',
|
|
||||||
数量: 70,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '工单',
|
|
||||||
月份: '1月',
|
|
||||||
数量: 20,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '停车费',
|
|
||||||
月份: '2月',
|
|
||||||
数量: 10,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '物业费',
|
|
||||||
月份: '2月',
|
|
||||||
数量: 80,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '工单',
|
|
||||||
月份: '2月',
|
|
||||||
数量: 40,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '停车费',
|
|
||||||
月份: '2月',
|
|
||||||
数量: 6,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '物业费',
|
|
||||||
月份: '3月',
|
|
||||||
数量: 67,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '工单',
|
|
||||||
月份: '3月',
|
|
||||||
数量: 27,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '停车费',
|
|
||||||
月份: '3月',
|
|
||||||
数量: 7,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '物业费',
|
|
||||||
月份: '4月',
|
|
||||||
数量: 55,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '工单',
|
|
||||||
月份: '4月',
|
|
||||||
数量: 17,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '停车费',
|
|
||||||
月份: '4月',
|
|
||||||
数量: 9,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '物业费',
|
|
||||||
月份: '5月',
|
|
||||||
数量: 32,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '工单',
|
|
||||||
月份: '5月',
|
|
||||||
数量: 27,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '停车费',
|
|
||||||
月份: '5月',
|
|
||||||
数量: 11,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '物业费',
|
|
||||||
月份: '6月',
|
|
||||||
数量: 42,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '工单',
|
|
||||||
月份: '6月',
|
|
||||||
数量: 7,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '停车费',
|
|
||||||
月份: '6月',
|
|
||||||
数量: 21,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const FinanceClientData = [
|
|
||||||
{
|
|
||||||
name: '应收',
|
|
||||||
月份: '1月',
|
|
||||||
数量: 200,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '实收',
|
|
||||||
月份: '1月',
|
|
||||||
数量: 210,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '应收',
|
|
||||||
月份: '2月',
|
|
||||||
数量: 170,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '实收',
|
|
||||||
月份: '2月',
|
|
||||||
数量: 200,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '应收',
|
|
||||||
月份: '3月',
|
|
||||||
数量: 270,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '实收',
|
|
||||||
月份: '3月',
|
|
||||||
数量: 310,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '应收',
|
|
||||||
月份: '4月',
|
|
||||||
数量: 230,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '实收',
|
|
||||||
月份: '4月',
|
|
||||||
数量: 190,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '应收',
|
|
||||||
月份: '5月',
|
|
||||||
数量: 170,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '实收',
|
|
||||||
月份: '5月',
|
|
||||||
数量: 160,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '应收',
|
|
||||||
月份: '6月',
|
|
||||||
数量: 250,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '实收',
|
|
||||||
月份: '6月',
|
|
||||||
数量: 280,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@ -1,91 +0,0 @@
|
|||||||
import { Apis } from '@/gen/Apis';
|
|
||||||
import { Pie } from '@ant-design/plots';
|
|
||||||
import { Space } from 'antd';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
export default function FinancialAnalysisLine() {
|
|
||||||
const [getPieCount, setPieCount] = useState<any>({});
|
|
||||||
const config = {
|
|
||||||
data: [],
|
|
||||||
angleField: '数量',
|
|
||||||
colorField: 'name',
|
|
||||||
innerRadius: 0.8,
|
|
||||||
radius: 0.5,
|
|
||||||
style: {
|
|
||||||
width: '60px',
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
text: '数量',
|
|
||||||
style: {
|
|
||||||
fontWeight: 'bold',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const getPieData = async () => {
|
|
||||||
const res = await Apis.Statistics.IndexCount.ContractStatistics();
|
|
||||||
setPieCount({
|
|
||||||
...config,
|
|
||||||
data: res?.data?.items,
|
|
||||||
legend: {
|
|
||||||
color: {
|
|
||||||
render: (legendItem: any, item: any) => {
|
|
||||||
console.log(legendItem, item, 'legendItem');
|
|
||||||
// 这里可以返回 React 节点或 HTML 字符串
|
|
||||||
return (
|
|
||||||
<Space size="small">
|
|
||||||
{legendItem?.map((row: any, index: number) => {
|
|
||||||
return (
|
|
||||||
<Space key={`item_${index}`}>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
width: 8,
|
|
||||||
height: 8,
|
|
||||||
backgroundColor: row?.color,
|
|
||||||
borderRadius: 100,
|
|
||||||
fontSize: 12,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{row?.label}
|
|
||||||
{
|
|
||||||
res?.data?.items?.find(
|
|
||||||
(i: any) => i.name === row?.label,
|
|
||||||
)?.数量
|
|
||||||
}
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
title: false,
|
|
||||||
position: 'top',
|
|
||||||
rowPadding: 5,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
annotations: [
|
|
||||||
{
|
|
||||||
type: 'text',
|
|
||||||
style: {
|
|
||||||
text: `${res?.data?.total}\n合同总数`,
|
|
||||||
x: '50%',
|
|
||||||
y: '50%',
|
|
||||||
textAlign: 'center',
|
|
||||||
fontSize: 20,
|
|
||||||
fontStyle: 'bold',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
console.log(res, 'res');
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getPieData();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ height: 430 }}>
|
|
||||||
<Pie {...getPieCount} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
import { MyBetaModalFormProps } from '@/common';
|
|
||||||
import { Line } from '@ant-design/plots';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
export default function FinancialAnalysisLine(props: MyBetaModalFormProps) {
|
|
||||||
const [houseBillsCount, setHouseBillsCount] = useState<any>({});
|
|
||||||
const config = {
|
|
||||||
data: [],
|
|
||||||
xField: '月份',
|
|
||||||
yField: '金额',
|
|
||||||
colorField: 'name',
|
|
||||||
point: {
|
|
||||||
size: 7,
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
position: 'top',
|
|
||||||
},
|
|
||||||
tooltip: {},
|
|
||||||
style: {
|
|
||||||
// 矩形四个方向的内边距
|
|
||||||
inset: 5,
|
|
||||||
},
|
|
||||||
|
|
||||||
// 使用双Y轴,因为两个指标数值范围差异大
|
|
||||||
yAxis: [
|
|
||||||
{
|
|
||||||
title: {
|
|
||||||
text: '月收款(万元)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: {
|
|
||||||
text: '收缴率(%)',
|
|
||||||
},
|
|
||||||
grid: null,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (props?.item?.chart?.length) {
|
|
||||||
setHouseBillsCount({ ...config, data: props?.item?.chart || [] });
|
|
||||||
}
|
|
||||||
}, [props?.item?.chart]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ height: 290 }}>
|
|
||||||
<Line {...houseBillsCount} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,93 +0,0 @@
|
|||||||
import { MyBetaModalFormProps } from '@/common';
|
|
||||||
import { Pie } from '@ant-design/plots';
|
|
||||||
import { Space } from 'antd';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
export default function WorkOrderPie(props: MyBetaModalFormProps) {
|
|
||||||
const [getPieCount, setPieCount] = useState<any>({});
|
|
||||||
const config = {
|
|
||||||
data: [],
|
|
||||||
angleField: '数量',
|
|
||||||
colorField: 'name',
|
|
||||||
innerRadius: 0.8,
|
|
||||||
radius: 0.5,
|
|
||||||
style: {
|
|
||||||
width: '60px',
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
text: '数量',
|
|
||||||
style: {
|
|
||||||
fontWeight: 'bold',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setPieCount({
|
|
||||||
...config,
|
|
||||||
data: props?.item?.statistics?.items,
|
|
||||||
legend: {
|
|
||||||
color: {
|
|
||||||
render: (legendItem: any, item: any) => {
|
|
||||||
console.log(legendItem, item, 'legendItem');
|
|
||||||
// 这里可以返回 React 节点或 HTML 字符串
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
fontSize: 12,
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
flexWrap: 'wrap',
|
|
||||||
gap: '10px',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{legendItem?.map((row: any, index: number) => {
|
|
||||||
return (
|
|
||||||
<Space key={`item_${index}`}>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
width: 8,
|
|
||||||
height: 8,
|
|
||||||
backgroundColor: row?.color,
|
|
||||||
borderRadius: 100,
|
|
||||||
fontSize: 12,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{row?.label}
|
|
||||||
{
|
|
||||||
props?.item?.statistics?.items?.find(
|
|
||||||
(i: any) => i.name === row?.label,
|
|
||||||
)?.数量
|
|
||||||
}
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
title: false,
|
|
||||||
position: 'top',
|
|
||||||
rowPadding: 5,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
annotations: [
|
|
||||||
{
|
|
||||||
type: 'text',
|
|
||||||
style: {
|
|
||||||
text: `${props?.item?.statistics?.total}\n工单总数`,
|
|
||||||
x: '50%',
|
|
||||||
y: '50%',
|
|
||||||
textAlign: 'center',
|
|
||||||
fontSize: 20,
|
|
||||||
fontStyle: 'bold',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}, [props?.item?.statistics?.items]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ height: 430 }}>
|
|
||||||
<Pie {...getPieCount} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,132 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"name": "上城区",
|
|
||||||
"level": "district",
|
|
||||||
"adcode": 330102,
|
|
||||||
"lng": 120.19732,
|
|
||||||
"lat": 30.226543,
|
|
||||||
"childrenNum": 0,
|
|
||||||
"parent": 330100,
|
|
||||||
"value": 41.040194955144216
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "拱墅区",
|
|
||||||
"level": "district",
|
|
||||||
"adcode": 330105,
|
|
||||||
"lng": 120.141503,
|
|
||||||
"lat": 30.319126,
|
|
||||||
"childrenNum": 0,
|
|
||||||
"parent": 330100,
|
|
||||||
"value": 741.6573303294999
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "西湖区",
|
|
||||||
"level": "district",
|
|
||||||
"adcode": 330106,
|
|
||||||
"lng": 120.130396,
|
|
||||||
"lat": 30.259242,
|
|
||||||
"childrenNum": 0,
|
|
||||||
"parent": 330100,
|
|
||||||
"value": 2948.4079430920074
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "滨江区",
|
|
||||||
"level": "district",
|
|
||||||
"adcode": 330108,
|
|
||||||
"lng": 120.211981,
|
|
||||||
"lat": 30.208332,
|
|
||||||
"childrenNum": 0,
|
|
||||||
"parent": 330100,
|
|
||||||
"value": 49.89546143372991
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "萧山区",
|
|
||||||
"level": "district",
|
|
||||||
"adcode": 330109,
|
|
||||||
"lng": 120.264263,
|
|
||||||
"lat": 30.184119,
|
|
||||||
"childrenNum": 0,
|
|
||||||
"parent": 330100,
|
|
||||||
"value": 2384.034354262634
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "余杭区",
|
|
||||||
"level": "district",
|
|
||||||
"adcode": 330110,
|
|
||||||
"lng": 119.978742,
|
|
||||||
"lat": 30.273705,
|
|
||||||
"childrenNum": 0,
|
|
||||||
"parent": 330100,
|
|
||||||
"value": 1882.4494466789638
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "富阳区",
|
|
||||||
"level": "district",
|
|
||||||
"adcode": 330111,
|
|
||||||
"lng": 119.96022,
|
|
||||||
"lat": 30.048803,
|
|
||||||
"childrenNum": 0,
|
|
||||||
"parent": 330100,
|
|
||||||
"value": 560.1787727190821
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "临安区",
|
|
||||||
"level": "district",
|
|
||||||
"adcode": 330112,
|
|
||||||
"lng": 119.724457,
|
|
||||||
"lat": 30.234375,
|
|
||||||
"childrenNum": 0,
|
|
||||||
"parent": 330100,
|
|
||||||
"value": 4051.1361966943305
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "临平区",
|
|
||||||
"level": "district",
|
|
||||||
"adcode": 330113,
|
|
||||||
"lng": 120.299222,
|
|
||||||
"lat": 30.419154,
|
|
||||||
"childrenNum": 0,
|
|
||||||
"parent": 330100,
|
|
||||||
"value": 4071.9384042194924
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "钱塘区",
|
|
||||||
"level": "district",
|
|
||||||
"adcode": 330114,
|
|
||||||
"lng": 120.493941,
|
|
||||||
"lat": 30.32304,
|
|
||||||
"childrenNum": 0,
|
|
||||||
"parent": 330100,
|
|
||||||
"value": 1813.6359839537997
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "桐庐县",
|
|
||||||
"level": "district",
|
|
||||||
"adcode": 330122,
|
|
||||||
"lng": 119.691755,
|
|
||||||
"lat": 29.79418,
|
|
||||||
"childrenNum": 0,
|
|
||||||
"parent": 330100,
|
|
||||||
"value": 2089.953961851202
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "淳安县",
|
|
||||||
"level": "district",
|
|
||||||
"adcode": 330127,
|
|
||||||
"lng": 119.042015,
|
|
||||||
"lat": 29.609678,
|
|
||||||
"childrenNum": 0,
|
|
||||||
"parent": 330100,
|
|
||||||
"value": 978.0639544756548
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "建德市",
|
|
||||||
"level": "district",
|
|
||||||
"adcode": 330182,
|
|
||||||
"lng": 119.281195,
|
|
||||||
"lat": 29.474964,
|
|
||||||
"childrenNum": 0,
|
|
||||||
"parent": 330100,
|
|
||||||
"value": 4427.419741967931
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
import { Apis } from '@/gen/Apis';
|
|
||||||
import { RightOutlined } from '@ant-design/icons';
|
|
||||||
import { useNavigate } from '@umijs/max';
|
|
||||||
import { Space } from 'antd';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import AnalysisClient from '../charts/AnalysisClient';
|
|
||||||
|
|
||||||
export default function AssetManagementAnalysis() {
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const [getAssetAnalysis, setAssetAnalysis] = useState<any>({});
|
|
||||||
const getAssetAnalysisApi = async () => {
|
|
||||||
const res = await Apis.Statistics.IndexCount.AssetAnalysis();
|
|
||||||
setAssetAnalysis(res?.data);
|
|
||||||
console.log(res, 'res');
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getAssetAnalysisApi();
|
|
||||||
}, []);
|
|
||||||
return (
|
|
||||||
<Space direction="vertical" size="middle" style={{ width: '100%' }}>
|
|
||||||
<div className="asset_management_analysis_data">
|
|
||||||
<div
|
|
||||||
style={{ cursor: 'pointer' }}
|
|
||||||
onClick={() => {
|
|
||||||
navigate('/asset/asset_items');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="label">
|
|
||||||
资产仓库 <RightOutlined />
|
|
||||||
</div>
|
|
||||||
<div className="value">{getAssetAnalysis?.total || 0}</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{ cursor: 'pointer' }}
|
|
||||||
onClick={() => {
|
|
||||||
navigate('/asset/asset_items');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="label">
|
|
||||||
资产总数 <RightOutlined />
|
|
||||||
</div>
|
|
||||||
<div className="value">{getAssetAnalysis?.total_price || 0}</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{ cursor: 'pointer' }}
|
|
||||||
onClick={() => {
|
|
||||||
navigate('/asset/asset_items');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="label">
|
|
||||||
闲置资产 <RightOutlined />
|
|
||||||
</div>
|
|
||||||
<div className="value">{getAssetAnalysis?.idle_count || 0}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<AnalysisClient item={getAssetAnalysis} />
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
import { Apis } from '@/gen/Apis';
|
|
||||||
import { ProCard } from '@ant-design/pro-components';
|
|
||||||
import { Space } from 'antd';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import AssetManagementAnalysis from './AssetManagementAnalysis';
|
|
||||||
import ImgLeftIcon from './images/LeftIcon.png';
|
|
||||||
import ImgMapTitleBg from './images/map_title_bg_img.svg';
|
|
||||||
import MapAntL7 from './MapAntL7';
|
|
||||||
import './styleCenter.scss';
|
|
||||||
import './styleMap.scss';
|
|
||||||
|
|
||||||
export default function CardCenter() {
|
|
||||||
const [loginStatus, setLoginStatus] = useState<boolean>(false);
|
|
||||||
const [dataInfo, setDataInfo] = useState<any>({});
|
|
||||||
const getProjectDistributionAndPaymentRanking = async () => {
|
|
||||||
const res =
|
|
||||||
await Apis.Statistics.IndexCount.ProjectDistributionAndPaymentRanking();
|
|
||||||
setLoginStatus(true);
|
|
||||||
setDataInfo(res?.data);
|
|
||||||
};
|
|
||||||
useEffect(() => {
|
|
||||||
getProjectDistributionAndPaymentRanking();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Space direction="vertical" size="middle" style={{ width: '100%' }}>
|
|
||||||
<div className="map_card">
|
|
||||||
{loginStatus ? <MapAntL7 item={dataInfo} /> : ''}
|
|
||||||
<div className="map_card_contents">
|
|
||||||
<img src={ImgMapTitleBg} className="map_card_title_bg" />
|
|
||||||
<div className="map_data_contents">
|
|
||||||
<div className="map_card_title">项目分布数据</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="map_card_data_contents">
|
|
||||||
<div className="map_card_data">
|
|
||||||
<div>
|
|
||||||
<div className="map_card_data_title">
|
|
||||||
<img src={ImgLeftIcon} />
|
|
||||||
<span>管理户数</span>
|
|
||||||
{/* <img src={ImgRightIcon} /> */}
|
|
||||||
</div>
|
|
||||||
<div className="map_card_data_number">
|
|
||||||
{dataInfo?.total_users || 0}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="map_card_data">
|
|
||||||
<div>
|
|
||||||
<div className="map_card_data_title">
|
|
||||||
<img src={ImgLeftIcon} />
|
|
||||||
<span>员工总数</span>
|
|
||||||
{/* <img src={ImgRightIcon} /> */}
|
|
||||||
</div>
|
|
||||||
<div className="map_card_data_number">
|
|
||||||
{dataInfo?.total_occupants || 0}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* <div className="others_project">
|
|
||||||
<div className="others_project_cell_list">
|
|
||||||
<img src={AddressIcon} alt="" />
|
|
||||||
<div>苏州3个项目</div>
|
|
||||||
</div>
|
|
||||||
<div className="others_project_cell_list">
|
|
||||||
<img src={AddressIcon} alt="" />
|
|
||||||
<div>南京3个项目</div>
|
|
||||||
</div>
|
|
||||||
<div className="others_project_cell_list">
|
|
||||||
<img src={AddressIcon} alt="" />
|
|
||||||
<div>上海8个项目</div>
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
|
||||||
<ProCard title="资产管理分析" style={{ borderRadius: '10px' }}>
|
|
||||||
<AssetManagementAnalysis />
|
|
||||||
</ProCard>
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
import { Apis } from '@/gen/Apis';
|
|
||||||
import { ProCard } from '@ant-design/pro-components';
|
|
||||||
import { Space } from 'antd';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import ContractStatisticalAnalysis from '../charts/ContractStatisticalAnalysis';
|
|
||||||
import FinancialAnalysisLine from '../charts/FinancialAnalysisLine';
|
|
||||||
import FinancialAnalysis from './FinancialAnalysis';
|
|
||||||
import './styleLeft.scss';
|
|
||||||
export default function CardLeft() {
|
|
||||||
const [getFinancialAnalysis, setFinancialAnalysis] = useState<any>({});
|
|
||||||
const getFinancialWorkOverview = async () => {
|
|
||||||
const res = await Apis.Statistics.IndexCount.FinancialAnalysis();
|
|
||||||
setFinancialAnalysis(res?.data);
|
|
||||||
|
|
||||||
console.log(res, 'res');
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getFinancialWorkOverview();
|
|
||||||
}, []);
|
|
||||||
return (
|
|
||||||
<Space direction="vertical" size="middle" style={{ width: '100%' }}>
|
|
||||||
<ProCard title="财务分析">
|
|
||||||
<Space direction="vertical" size="middle" style={{ width: '100%' }}>
|
|
||||||
<FinancialAnalysis item={getFinancialAnalysis} />
|
|
||||||
<FinancialAnalysisLine item={getFinancialAnalysis} />
|
|
||||||
</Space>
|
|
||||||
</ProCard>
|
|
||||||
<ProCard title="合同统计分析">
|
|
||||||
<ContractStatisticalAnalysis />
|
|
||||||
</ProCard>
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,77 +0,0 @@
|
|||||||
import { Apis } from '@/gen/Apis';
|
|
||||||
import { ProCard } from '@ant-design/pro-components';
|
|
||||||
import { Progress, Space } from 'antd';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import WorkOrderPie from '../charts/WorkOrderPie';
|
|
||||||
import PendingApplicationForm from './PendingApplicationForm';
|
|
||||||
import './styleRight.scss';
|
|
||||||
export default function CardRight() {
|
|
||||||
const [getAssetAnalysis, setAssetAnalysis] = useState<any>({});
|
|
||||||
const getAssetAnalysisApi = async () => {
|
|
||||||
const res = await Apis.Statistics.IndexCount.WorkOrderAnalysis();
|
|
||||||
setAssetAnalysis(res);
|
|
||||||
console.log(res, 'res');
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getAssetAnalysisApi();
|
|
||||||
}, []);
|
|
||||||
return (
|
|
||||||
<div className="card_right">
|
|
||||||
<Space direction="vertical" size="middle" style={{ width: '100%' }}>
|
|
||||||
<ProCard title="工单分析">
|
|
||||||
<PendingApplicationForm item={getAssetAnalysis?.data} />
|
|
||||||
</ProCard>
|
|
||||||
<ProCard title="工单统计">
|
|
||||||
<WorkOrderPie item={getAssetAnalysis} />
|
|
||||||
</ProCard>
|
|
||||||
<ProCard title="工单数据">
|
|
||||||
<div className="work_order_data">
|
|
||||||
<div className="work_order_data_item">
|
|
||||||
<Progress
|
|
||||||
type="dashboard"
|
|
||||||
size={[160, 30]}
|
|
||||||
percent={getAssetAnalysis?.data?.metrics?.completion_rate || 0}
|
|
||||||
format={(percent) => {
|
|
||||||
return (
|
|
||||||
<div className="dashboard_progress">
|
|
||||||
<div className="dashboard_value">{`${percent}%`}</div>
|
|
||||||
<div className="dashboard_label">完成率</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<div className="work_order_data_cell">
|
|
||||||
已完成:{getAssetAnalysis?.data?.metrics?.completed_count || 0}
|
|
||||||
</div>
|
|
||||||
<div className="work_order_data_cell">
|
|
||||||
已关闭:{getAssetAnalysis?.data?.metrics?.closed_count || 0}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="work_order_data_item">
|
|
||||||
<Progress
|
|
||||||
type="dashboard"
|
|
||||||
size={[160, 30]}
|
|
||||||
percent={getAssetAnalysis?.data?.metrics?.approval_rate || 0}
|
|
||||||
format={(percent) => {
|
|
||||||
return (
|
|
||||||
<div className="dashboard_progress">
|
|
||||||
<div className="dashboard_value">{`${percent}%`}</div>
|
|
||||||
<div className="dashboard_label">好评率</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<div className="work_order_data_cell">
|
|
||||||
已评价:{getAssetAnalysis?.data?.metrics?.evaluated_count || 0}
|
|
||||||
</div>
|
|
||||||
<div className="work_order_data_cell">
|
|
||||||
已好评:{getAssetAnalysis?.data?.metrics?.positive_count || 0}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ProCard>
|
|
||||||
</Space>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
import { MyBetaModalFormProps } from '@/common';
|
|
||||||
|
|
||||||
export default function FinancialAnalysis(props: MyBetaModalFormProps) {
|
|
||||||
return (
|
|
||||||
<div className="financial_analysis">
|
|
||||||
<div className="financial_analysis_item">
|
|
||||||
<div className="value">
|
|
||||||
{props?.item?.month_received || '0'}
|
|
||||||
<span>元</span>
|
|
||||||
</div>
|
|
||||||
<div className="title">本月收款</div>
|
|
||||||
</div>
|
|
||||||
<div className="financial_analysis_item">
|
|
||||||
<div className="value">
|
|
||||||
{props?.item?.year_received || '0'}
|
|
||||||
<span>元</span>
|
|
||||||
</div>
|
|
||||||
<div className="title">年度收款</div>
|
|
||||||
</div>
|
|
||||||
<div className="financial_analysis_item">
|
|
||||||
<div className="value">
|
|
||||||
{props?.item?.month_rate || '0'}
|
|
||||||
<span>%</span>
|
|
||||||
</div>
|
|
||||||
<div className="title">月度收缴率</div>
|
|
||||||
</div>
|
|
||||||
<div className="financial_analysis_item">
|
|
||||||
<div className="value">
|
|
||||||
{props?.item?.year_rate || '0'}
|
|
||||||
<span>%</span>
|
|
||||||
</div>
|
|
||||||
<div className="title">年度收缴率</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,129 +0,0 @@
|
|||||||
import { MyBetaModalFormProps } from '@/common';
|
|
||||||
import { Scene } from '@antv/l7';
|
|
||||||
import { L7Layer } from '@antv/l7-leaflet';
|
|
||||||
import { Choropleth } from '@antv/l7plot';
|
|
||||||
import * as L from 'leaflet';
|
|
||||||
import 'leaflet/dist/leaflet.css';
|
|
||||||
import { useEffect, useRef } from 'react';
|
|
||||||
import ListArea from './AreaInfoList.json';
|
|
||||||
import map_bg_img from './images/map_bg_img.png';
|
|
||||||
|
|
||||||
export default function MapInfo(props: MyBetaModalFormProps) {
|
|
||||||
const sceneRef = useRef<Scene>();
|
|
||||||
|
|
||||||
const getProjectDistributionAndPaymentRanking = async () => {
|
|
||||||
let dataJson: any = [];
|
|
||||||
console.log(props?.item?.area_stats, 'props?.item?.area_stats');
|
|
||||||
props?.item?.area_stats?.map((item: any) => {
|
|
||||||
ListArea?.map((i: any) => {
|
|
||||||
if (i?.name === item?.name) {
|
|
||||||
dataJson?.push({
|
|
||||||
...i,
|
|
||||||
name: `${i?.name}(${item?.value}个)`,
|
|
||||||
数量: `${item?.value}个项目`,
|
|
||||||
区: i?.name,
|
|
||||||
});
|
|
||||||
console.log(i, 'i');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
console.log(dataJson, 'skkskck');
|
|
||||||
return dataJson;
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (sceneRef.current) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 初始化地图场景
|
|
||||||
const map = L.map('map', {
|
|
||||||
center: [29.909571, 119.600006],
|
|
||||||
zoom: 10,
|
|
||||||
minZoom: 9,
|
|
||||||
maxZoom: 10,
|
|
||||||
zoomControl: false,
|
|
||||||
attributionControl: false,
|
|
||||||
}).setView([29.909571, 119.600006], 9);
|
|
||||||
|
|
||||||
const l7layer = new L7Layer({
|
|
||||||
logoVisible: false,
|
|
||||||
}).addTo(map);
|
|
||||||
|
|
||||||
const scene: any = l7layer.getScene();
|
|
||||||
sceneRef.current = scene;
|
|
||||||
|
|
||||||
scene.on('loaded', async () => {
|
|
||||||
let dataAreaJson = await getProjectDistributionAndPaymentRanking();
|
|
||||||
console.log(dataAreaJson, 'dataAreaJson');
|
|
||||||
const choropleth = new Choropleth({
|
|
||||||
chinaBorder: false,
|
|
||||||
source: {
|
|
||||||
data: dataAreaJson || [],
|
|
||||||
joinBy: {
|
|
||||||
sourceField: 'adcode',
|
|
||||||
geoField: 'adcode',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
viewLevel: {
|
|
||||||
level: 'city',
|
|
||||||
adcode: 330100,
|
|
||||||
},
|
|
||||||
autoFit: true,
|
|
||||||
style: {
|
|
||||||
opacity: 1,
|
|
||||||
stroke: '#0083FF',
|
|
||||||
lineWidth: 1,
|
|
||||||
lineOpacity: 1,
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
field: 'name',
|
|
||||||
style: {
|
|
||||||
fill: '#000',
|
|
||||||
opacity: 1,
|
|
||||||
fontSize: 15,
|
|
||||||
strokeWidth: 1.5,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
items: ['区', '数量'],
|
|
||||||
},
|
|
||||||
state: {
|
|
||||||
active: { stroke: '#0083FF', lineWidth: 1, fill: '#E4F2FF' },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
choropleth.addToScene(scene);
|
|
||||||
});
|
|
||||||
scene.on('resize', () => {
|
|
||||||
console.log('resize');
|
|
||||||
});
|
|
||||||
|
|
||||||
// 组件卸载时清理
|
|
||||||
return () => {
|
|
||||||
if (sceneRef.current) {
|
|
||||||
sceneRef.current.destroy();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, [props?.item]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
height: '594px',
|
|
||||||
position: 'relative',
|
|
||||||
zIndex: 1,
|
|
||||||
backgroundColor: '#fff',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
id="map"
|
|
||||||
style={{
|
|
||||||
width: '100%',
|
|
||||||
height: '594px',
|
|
||||||
background: `url(${map_bg_img}) no-repeat bottom`,
|
|
||||||
backgroundSize: '100%',
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,86 +0,0 @@
|
|||||||
import { MyBetaModalFormProps } from '@/common';
|
|
||||||
import { RightOutlined } from '@ant-design/icons';
|
|
||||||
import { useNavigate } from '@umijs/max';
|
|
||||||
|
|
||||||
export default function PendingApplicationForm(props: MyBetaModalFormProps) {
|
|
||||||
const navigate = useNavigate();
|
|
||||||
return (
|
|
||||||
<div className="pending_application_form">
|
|
||||||
<div className="pending_application_form_title">待处理工单</div>
|
|
||||||
<div className="pending_application_form_container">
|
|
||||||
<div className="pending_application_form_item">
|
|
||||||
<div
|
|
||||||
className="label"
|
|
||||||
onClick={() => {
|
|
||||||
navigate('/emergency');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
突发事件
|
|
||||||
<RightOutlined />
|
|
||||||
</div>
|
|
||||||
<div className="value">{props?.item?.pending?.emergency || 0}</div>
|
|
||||||
</div>
|
|
||||||
<div className="pending_application_form_item">
|
|
||||||
<div
|
|
||||||
className="label"
|
|
||||||
onClick={() => {
|
|
||||||
navigate('/work_order/list');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
报修工单
|
|
||||||
<RightOutlined />
|
|
||||||
</div>
|
|
||||||
<div className="value">{props?.item?.pending?.repair || 0}</div>
|
|
||||||
</div>
|
|
||||||
<div className="pending_application_form_item">
|
|
||||||
<div
|
|
||||||
className="label"
|
|
||||||
onClick={() => {
|
|
||||||
navigate('/work_order/list');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
报事工单
|
|
||||||
<RightOutlined />
|
|
||||||
</div>
|
|
||||||
<div className="value">{props?.item?.pending?.incident || 0}</div>
|
|
||||||
</div>
|
|
||||||
<div className="pending_application_form_item">
|
|
||||||
<div
|
|
||||||
className="label"
|
|
||||||
onClick={() => {
|
|
||||||
navigate('/work_order/list');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
投诉工单
|
|
||||||
<RightOutlined />
|
|
||||||
</div>
|
|
||||||
<div className="value">{props?.item?.pending?.complaint || 0}</div>
|
|
||||||
</div>
|
|
||||||
<div className="pending_application_form_item">
|
|
||||||
<div
|
|
||||||
className="label"
|
|
||||||
onClick={() => {
|
|
||||||
navigate('/attendance/attendance_schedules');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
巡检工单
|
|
||||||
<RightOutlined />
|
|
||||||
</div>
|
|
||||||
<div className="value">{props?.item?.pending?.inspection || 0}</div>
|
|
||||||
</div>
|
|
||||||
<div className="pending_application_form_item">
|
|
||||||
<div
|
|
||||||
className="label"
|
|
||||||
onClick={() => {
|
|
||||||
navigate('/asset/asset_items_maintenances');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
维保工单
|
|
||||||
<RightOutlined />
|
|
||||||
</div>
|
|
||||||
<div className="value">{props?.item?.pending?.maintenance || 0}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 532 B |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 562 B |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 759 B |
|
Before Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 1.0 KiB |
@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="714" height="47" viewBox="0 0 714 47"><g><g><g><path d="M212,17L231.661898,39.996876C235.461674,44.441154,241.016041,47,246.863251,47L467.13675,47C472.98395,47,478.53833,44.441154,482.3381,39.996877999999995L502,17L212,17Z" fill="#2A7EFB" fill-opacity="1"/></g><g><path d="M0,17L714,17L714,12.000001C714,6.4771528,709.52283,2,704,2L10.000001,2C4.4771528,2,0,6.4771528,0,12.000001L0,17Z" fill="#2A7EFB" fill-opacity="1"/></g></g><g><g><path d="M212,15L231.661898,37.996876C235.461674,42.441154,241.016041,45,246.863251,45L467.13675,45C472.98395,45,478.53833,42.441154,482.3381,37.996877999999995L502,15L212,15Z" fill="#E2F1FF" fill-opacity="1"/></g><g><path d="M0,15L714,15L714,10.000001C714,4.4771528,709.52283,0,704,0L10.000001,0C4.4771528,0,0,4.4771528,0,10.000001L0,15Z" fill="#E2F1FF" fill-opacity="1"/></g></g></g></svg>
|
|
||||||
|
Before Width: | Height: | Size: 941 B |
@ -1,19 +0,0 @@
|
|||||||
.asset_management_analysis_data {
|
|
||||||
background-color: #f3f8fb;
|
|
||||||
border-radius: 10px;
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 20px 15px;
|
|
||||||
.label {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 400;
|
|
||||||
color: #666666;
|
|
||||||
}
|
|
||||||
.value {
|
|
||||||
color: #333333;
|
|
||||||
font-size: 30px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
.financial_analysis {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 15px;
|
|
||||||
&_item {
|
|
||||||
color: #fff;
|
|
||||||
background: linear-gradient(134deg, #6499ff 34%, #95b8ff 100%);
|
|
||||||
border-radius: 10px;
|
|
||||||
text-align: center;
|
|
||||||
width: 48%;
|
|
||||||
height: 100px;
|
|
||||||
.value {
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 500;
|
|
||||||
padding-top: 17px;
|
|
||||||
span {
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.title {
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,102 +0,0 @@
|
|||||||
.map_card {
|
|
||||||
width: 100%;
|
|
||||||
border-radius: 15px;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.map_card_contents {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 4;
|
|
||||||
.map_card_title_bg {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 70px;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.map_data_contents {
|
|
||||||
position: relative;
|
|
||||||
z-index: 100;
|
|
||||||
padding-top: 18px;
|
|
||||||
}
|
|
||||||
.map_card_title {
|
|
||||||
color: #2a7efb;
|
|
||||||
font-size: 1.8rem;
|
|
||||||
font-weight: 500;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.map_card_data_contents {
|
|
||||||
position: absolute;
|
|
||||||
top: 70px;
|
|
||||||
left: 30px;
|
|
||||||
z-index: 100;
|
|
||||||
display: flex;
|
|
||||||
right: 30px;
|
|
||||||
justify-content: space-between;
|
|
||||||
.map_card_data {
|
|
||||||
// display: inline-block;
|
|
||||||
// 换为 2 行
|
|
||||||
// justify-content: center;
|
|
||||||
// flex-wrap: wrap;
|
|
||||||
// justify-content: space-between;
|
|
||||||
// align-items: center;
|
|
||||||
// display: inline-flex;
|
|
||||||
// text-align: center;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
}
|
|
||||||
.map_card_data_title {
|
|
||||||
color: #3d3d3d;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #0083ff;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
// justify-content: space-between;
|
|
||||||
span {
|
|
||||||
padding: 0 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.map_card_data_number {
|
|
||||||
padding: 10px 0 0 25px;
|
|
||||||
color: #0083ff;
|
|
||||||
font-size: 28px;
|
|
||||||
font-weight: 500;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.others_project {
|
|
||||||
position: absolute;
|
|
||||||
right: 1px;
|
|
||||||
bottom: 10px;
|
|
||||||
z-index: 100;
|
|
||||||
.others_project_cell_list {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
background: linear-gradient(
|
|
||||||
270deg,
|
|
||||||
rgba(124, 191, 255, 0) 0%,
|
|
||||||
rgba(217, 236, 255, 0.67) 95%
|
|
||||||
);
|
|
||||||
padding: 0 10px 0 0;
|
|
||||||
border-left: 5px solid #0083ff;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
width: 200px;
|
|
||||||
color: #0083ff;
|
|
||||||
img {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
margin: 0 3px;
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
.card_right {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
.pending_application_form {
|
|
||||||
background-color: #f3faff;
|
|
||||||
border-radius: 10px;
|
|
||||||
&_title {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 600;
|
|
||||||
padding: 15px 20px;
|
|
||||||
}
|
|
||||||
&_container {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
padding: 0 30px;
|
|
||||||
}
|
|
||||||
&_item {
|
|
||||||
width: 33.333%;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
.label {
|
|
||||||
color: #666666;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 12px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.value {
|
|
||||||
color: #333333;
|
|
||||||
font-size: 27px;
|
|
||||||
font-weight: 550;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.work_order_data {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding-top: 10px;
|
|
||||||
&_item {
|
|
||||||
width: 50%;
|
|
||||||
text-align: center;
|
|
||||||
color: #3d3d3d;
|
|
||||||
font-size: 16rpx;
|
|
||||||
}
|
|
||||||
&_cell {
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dashboard_progress {
|
|
||||||
width: 100%;
|
|
||||||
position: relative;
|
|
||||||
text-align: center;
|
|
||||||
// padding-top: 100px;
|
|
||||||
.dashboard_label {
|
|
||||||
font-size: 16px;
|
|
||||||
color: #3d3d3d;
|
|
||||||
width: 100%;
|
|
||||||
position: relative;
|
|
||||||
top: 50px;
|
|
||||||
}
|
|
||||||
.dashboard_value {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,20 +1,5 @@
|
|||||||
// import MyModalsMapLeaflet from '@/components/ModalsMapLeaflet';
|
// import MyModalsMapLeaflet from '@/components/ModalsMapLeaflet';
|
||||||
import CardCenter from './components/CardCenter';
|
|
||||||
import CardLeft from './components/CardLeft';
|
|
||||||
import CardRight from './components/CardRight';
|
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
export default function Index() {
|
export default function Index() {
|
||||||
return (
|
return <div className="overview_content">2</div>;
|
||||||
<div className="overview_content">
|
|
||||||
<div className="overview_left">
|
|
||||||
<CardLeft />
|
|
||||||
</div>
|
|
||||||
<div className="overview_center">
|
|
||||||
<CardCenter />
|
|
||||||
</div>
|
|
||||||
<div className="overview_right">
|
|
||||||
<CardRight />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,14 +5,14 @@ export default function Login() {
|
|||||||
<div>
|
<div>
|
||||||
<MyLoginPage />
|
<MyLoginPage />
|
||||||
<div className="filing_info">
|
<div className="filing_info">
|
||||||
浙江国彩城市服务有限公司 |{' '}
|
XXXX有限公司 |
|
||||||
<a
|
<a
|
||||||
href="https://beian.miit.gov.cn/#/Integrated/index"
|
href="https://beian.miit.gov.cn/#/Integrated/index"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
key="icp"
|
key="icp"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
>
|
>
|
||||||
浙ICP备2025210789号-3
|
粤ICP备2025210号-3
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,27 +1,17 @@
|
|||||||
import {
|
import { MyPageContainer, MyProTableProps } from '@/common';
|
||||||
MyButtons,
|
|
||||||
MyColumns,
|
|
||||||
MyPageContainer,
|
|
||||||
MyProTableProps,
|
|
||||||
} from '@/common';
|
|
||||||
import { Apis } from '@/gen/Apis';
|
import { Apis } from '@/gen/Apis';
|
||||||
import { SysPermissionsTypeEnum } from '@/gen/Enums';
|
|
||||||
import { DownOutlined, UpOutlined } from '@ant-design/icons';
|
|
||||||
import { ActionType, ProTable } from '@ant-design/pro-components';
|
import { ActionType, ProTable } from '@ant-design/pro-components';
|
||||||
import { Button, Space, Tag } from 'antd';
|
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import Create from './modals/Create';
|
|
||||||
import Update from './modals/Update';
|
|
||||||
|
|
||||||
export default function Index({ title = '功能' }) {
|
export default function Index({ title = '功能' }) {
|
||||||
const [data, setData] = useState<any>([]);
|
const [data, setData] = useState<any>([]);
|
||||||
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
const actionRef = useRef<ActionType>();
|
const actionRef = useRef<ActionType>();
|
||||||
const [guardName] = useState<string>('Admin');
|
const [guardName] = useState<string>('Admin');
|
||||||
|
|
||||||
const getData = async () => {
|
const getData = async () => {
|
||||||
let data = await Apis.Permission.SysPermissions.List({
|
let data = await Apis.Permission.Roles.PermissionTree();
|
||||||
guard_name: guardName,
|
setLoading(true);
|
||||||
});
|
|
||||||
setData(data.data);
|
setData(data.data);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -38,19 +28,11 @@ export default function Index({ title = '功能' }) {
|
|||||||
actionRef={actionRef}
|
actionRef={actionRef}
|
||||||
headerTitle="功能管理"
|
headerTitle="功能管理"
|
||||||
expandable={{
|
expandable={{
|
||||||
// defaultExpandAllRows: true,
|
defaultExpandAllRows: true,
|
||||||
defaultExpandedRowKeys: [1],
|
// defaultExpandedRowKeys: [1],
|
||||||
}}
|
}}
|
||||||
options={false}
|
options={false}
|
||||||
dataSource={data}
|
dataSource={data}
|
||||||
toolBarRender={() => [
|
|
||||||
<Create
|
|
||||||
key="Create"
|
|
||||||
reload={getData}
|
|
||||||
title={title}
|
|
||||||
guardName={guardName}
|
|
||||||
/>,
|
|
||||||
]}
|
|
||||||
columns={[
|
columns={[
|
||||||
{
|
{
|
||||||
title: '名称',
|
title: '名称',
|
||||||
@ -58,88 +40,7 @@ export default function Index({ title = '功能' }) {
|
|||||||
return `${record.id}_${record?.name}`;
|
return `${record.id}_${record?.name}`;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ title: 'icon', dataIndex: 'icon' },
|
|
||||||
MyColumns.EnumTag({
|
|
||||||
title: '类型',
|
|
||||||
dataIndex: 'type',
|
|
||||||
valueEnum: SysPermissionsTypeEnum,
|
|
||||||
}),
|
|
||||||
{ title: '链接', dataIndex: 'path' },
|
|
||||||
// { title: '前端表示', dataIndex: 'key' },
|
// { title: '前端表示', dataIndex: 'key' },
|
||||||
{
|
|
||||||
title: '后端API',
|
|
||||||
dataIndex: 'backend_apis',
|
|
||||||
render: (_, item) => {
|
|
||||||
return (
|
|
||||||
<Space direction="vertical">
|
|
||||||
{item.backend_apis?.map((item: string) => (
|
|
||||||
<Tag key={item}>{item}</Tag>
|
|
||||||
))}
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MyColumns.Option({
|
|
||||||
render: (_, item: any, index) => (
|
|
||||||
<Space key={index}>
|
|
||||||
<Button
|
|
||||||
size="small"
|
|
||||||
key={`up_${item.id}`}
|
|
||||||
icon={<UpOutlined />}
|
|
||||||
disabled={!item.parent_id}
|
|
||||||
onClick={() => {
|
|
||||||
Apis.Permission.SysPermissions.Move({
|
|
||||||
id: item.id,
|
|
||||||
type: 'up',
|
|
||||||
}).then(() => {
|
|
||||||
getData();
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
size="small"
|
|
||||||
icon={<DownOutlined />}
|
|
||||||
key={`down_${item.id}`}
|
|
||||||
disabled={!item.parent_id}
|
|
||||||
onClick={() => {
|
|
||||||
Apis.Permission.SysPermissions.Move({
|
|
||||||
id: item.id,
|
|
||||||
type: 'down',
|
|
||||||
}).then(() => {
|
|
||||||
getData();
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
></Button>
|
|
||||||
<Create
|
|
||||||
reload={getData}
|
|
||||||
title={title}
|
|
||||||
item={item}
|
|
||||||
key={`create_sub_${item.id}`}
|
|
||||||
guardName={guardName}
|
|
||||||
buttonProps={{
|
|
||||||
size: 'small',
|
|
||||||
title: '添加下级功能',
|
|
||||||
type: 'link',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Update
|
|
||||||
item={item}
|
|
||||||
reload={getData}
|
|
||||||
title={title}
|
|
||||||
key={`update_${item.id}`}
|
|
||||||
guardName={guardName}
|
|
||||||
/>
|
|
||||||
<MyButtons.Delete
|
|
||||||
key={`delete_${item.id}`}
|
|
||||||
onConfirm={() =>
|
|
||||||
Apis.Permission.SysPermissions.Delete({ id: item.id }).then(
|
|
||||||
() => getData(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -152,7 +53,7 @@ export default function Index({ title = '功能' }) {
|
|||||||
tabKey="system-permissions"
|
tabKey="system-permissions"
|
||||||
tabLabel={title}
|
tabLabel={title}
|
||||||
>
|
>
|
||||||
<ShowTable />
|
{loading ? <ShowTable /> : null}
|
||||||
</MyPageContainer>
|
</MyPageContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,9 @@
|
|||||||
import { MyButtons, MyPageContainer, MyProTableProps } from '@/common';
|
import {
|
||||||
|
MyButtons,
|
||||||
|
MyPageContainer,
|
||||||
|
MyProTableProps,
|
||||||
|
useCurrentPermissions,
|
||||||
|
} from '@/common';
|
||||||
import { flattenToMultiLevelFormatWithRowSpanAdvancedNew } from '@/common/utils/flattenIterative';
|
import { flattenToMultiLevelFormatWithRowSpanAdvancedNew } from '@/common/utils/flattenIterative';
|
||||||
import { Apis } from '@/gen/Apis';
|
import { Apis } from '@/gen/Apis';
|
||||||
import { ProCard, ProTable } from '@ant-design/pro-components';
|
import { ProCard, ProTable } from '@ant-design/pro-components';
|
||||||
@ -10,6 +15,7 @@ interface SelectedBuilding {
|
|||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
export default function Index({ title = '角色' }) {
|
export default function Index({ title = '角色' }) {
|
||||||
|
const getCurrentPermissions = useCurrentPermissions();
|
||||||
const [selectedBuilding, setSelectedBuilding] =
|
const [selectedBuilding, setSelectedBuilding] =
|
||||||
useState<SelectedBuilding | null>(null);
|
useState<SelectedBuilding | null>(null);
|
||||||
const [selectedPermissionsIds, setSelectedPermissionsIds] = useState<any[]>(
|
const [selectedPermissionsIds, setSelectedPermissionsIds] = useState<any[]>(
|
||||||
@ -19,7 +25,7 @@ export default function Index({ title = '角色' }) {
|
|||||||
const [dataTabsSource, setDataTabsSource] = useState<any>([]);
|
const [dataTabsSource, setDataTabsSource] = useState<any>([]);
|
||||||
const [tabsKey, setTabsKey] = useState<any>('');
|
const [tabsKey, setTabsKey] = useState<any>('');
|
||||||
const getSysPermissions = () => {
|
const getSysPermissions = () => {
|
||||||
Apis.Permission.SysPermissions.List({ guard_name: 'Admin' }).then((res) => {
|
Apis.Permission.Roles.PermissionTree().then((res) => {
|
||||||
setDataSource(
|
setDataSource(
|
||||||
flattenToMultiLevelFormatWithRowSpanAdvancedNew(
|
flattenToMultiLevelFormatWithRowSpanAdvancedNew(
|
||||||
res?.data[0]?.children || [],
|
res?.data[0]?.children || [],
|
||||||
@ -31,7 +37,7 @@ export default function Index({ title = '角色' }) {
|
|||||||
|
|
||||||
const onSave = () => {
|
const onSave = () => {
|
||||||
if (selectedPermissionsIds?.length && selectedBuilding?.id) {
|
if (selectedPermissionsIds?.length && selectedBuilding?.id) {
|
||||||
Apis.Permission.SysRoles.SetPermissions({
|
Apis.Permission.Roles.SetPermissions({
|
||||||
permissions_ids: selectedPermissionsIds,
|
permissions_ids: selectedPermissionsIds,
|
||||||
id: selectedBuilding?.id || 0,
|
id: selectedBuilding?.id || 0,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
@ -52,7 +58,7 @@ export default function Index({ title = '角色' }) {
|
|||||||
name: selectedRole.name,
|
name: selectedRole.name,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Apis.Permission.SysRoles.GetPermissions({
|
Apis.Permission.Roles.GetPermissions({
|
||||||
id: id ?? 0,
|
id: id ?? 0,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
setSelectedPermissionsIds(res?.data?.permissions_ids || []);
|
setSelectedPermissionsIds(res?.data?.permissions_ids || []);
|
||||||
@ -60,15 +66,15 @@ export default function Index({ title = '角色' }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getSysRoles = () => {
|
const getSysRoles = () => {
|
||||||
Apis.Permission.SysRoles.List().then((res) => {
|
Apis.Permission.Roles.List().then((res) => {
|
||||||
setDataTabsSource(res?.data || []);
|
setDataTabsSource(res?.data || []);
|
||||||
if (res?.data?.length) {
|
if (res?.data?.length) {
|
||||||
const firstRole = res.data[0];
|
const firstRole = res?.data[0];
|
||||||
getPermissions(firstRole?.id || 0);
|
getPermissions(firstRole?.id || 0);
|
||||||
// 初始化选中第一个角色
|
// 初始化选中第一个角色
|
||||||
setSelectedBuilding({
|
setSelectedBuilding({
|
||||||
id: firstRole.id,
|
id: firstRole?.id,
|
||||||
name: firstRole.name,
|
name: firstRole?.name,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
console.log(res, 'res');
|
console.log(res, 'res');
|
||||||
@ -77,7 +83,7 @@ export default function Index({ title = '角色' }) {
|
|||||||
|
|
||||||
const onSelect = () => {
|
const onSelect = () => {
|
||||||
//删除角色
|
//删除角色
|
||||||
Apis.Permission.SysRoles.Delete({
|
Apis.Permission.Roles.Delete({
|
||||||
id: tabsKey,
|
id: tabsKey,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
getSysRoles();
|
getSysRoles();
|
||||||
@ -88,21 +94,11 @@ export default function Index({ title = '角色' }) {
|
|||||||
getSysRoles();
|
getSysRoles();
|
||||||
getSysPermissions();
|
getSysPermissions();
|
||||||
}, []);
|
}, []);
|
||||||
return (
|
|
||||||
<MyPageContainer
|
let toolBarRender = () => {
|
||||||
title={title}
|
return getCurrentPermissions({
|
||||||
enableTabs={true}
|
add: <Create key="Create" reload={() => getSysRoles()} title={title} />,
|
||||||
tabKey="system-roles"
|
delete: (
|
||||||
tabLabel={title}
|
|
||||||
>
|
|
||||||
<ProCard
|
|
||||||
title="权限配置"
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
headerBordered
|
|
||||||
extra={
|
|
||||||
<Space size="large">
|
|
||||||
<Space size="small">
|
|
||||||
<Create key="Create" reload={() => getSysRoles()} title={title} />
|
|
||||||
<MyButtons.Default
|
<MyButtons.Default
|
||||||
key="delete"
|
key="delete"
|
||||||
size="middle"
|
size="middle"
|
||||||
@ -115,7 +111,8 @@ export default function Index({ title = '角色' }) {
|
|||||||
// 如果当前选中角色是管理员,则禁用删除按钮
|
// 如果当前选中角色是管理员,则禁用删除按钮
|
||||||
disabled={selectedBuilding?.name === '管理员'}
|
disabled={selectedBuilding?.name === '管理员'}
|
||||||
/>
|
/>
|
||||||
</Space>
|
),
|
||||||
|
save: (
|
||||||
<MyButtons.Default
|
<MyButtons.Default
|
||||||
key="save"
|
key="save"
|
||||||
type="primary"
|
type="primary"
|
||||||
@ -123,8 +120,22 @@ export default function Index({ title = '角色' }) {
|
|||||||
title="保存权限"
|
title="保存权限"
|
||||||
onClick={() => onSave()}
|
onClick={() => onSave()}
|
||||||
/>
|
/>
|
||||||
</Space>
|
),
|
||||||
}
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MyPageContainer
|
||||||
|
title={title}
|
||||||
|
enableTabs={true}
|
||||||
|
tabKey="system-roles"
|
||||||
|
tabLabel={title}
|
||||||
|
>
|
||||||
|
<ProCard
|
||||||
|
title="权限配置"
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
headerBordered
|
||||||
|
extra={<Space size="small">{toolBarRender()}</Space>}
|
||||||
>
|
>
|
||||||
<div style={{ display: 'flex' }}>
|
<div style={{ display: 'flex' }}>
|
||||||
<div style={{ width: '130px' }}>
|
<div style={{ width: '130px' }}>
|
||||||
|
|||||||
@ -26,7 +26,7 @@ export default function Create(props: MyBetaModalFormProps) {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onFinish={async (values) =>
|
onFinish={async (values) =>
|
||||||
Apis.Permission.SysRoles.Store(values)
|
Apis.Permission.Roles.Store(values)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
props.reload?.();
|
props.reload?.();
|
||||||
message.success(props.title + '成功');
|
message.success(props.title + '成功');
|
||||||
|
|||||||