refactor: request in DutyInfo & Welcome

mgy
Dawn_Ocean 2024-04-20 21:57:50 +08:00
parent 311d67a1b1
commit 9fc19a3ebd
5 changed files with 187 additions and 125 deletions

View File

@ -1,7 +1,14 @@
import { PageContainer, ProForm, ProFormRadio, ProFormText } from '@ant-design/pro-components'; import { getDutyInfo } from '@/services/api';
import {
PageContainer,
ProForm,
ProFormDateTimeRangePicker,
ProFormDigit,
ProFormRadio,
ProFormText,
} from '@ant-design/pro-components';
import { Card, Col, Row, Space, message } from 'antd'; import { Card, Col, Row, Space, message } from 'antd';
// import { useState } from 'react'; import { useEffect, useState } from 'react';
import request from 'umi-request';
import { Info } from './info'; import { Info } from './info';
const waitTime = (time: number = 100) => { const waitTime = (time: number = 100) => {
@ -13,59 +20,107 @@ const waitTime = (time: number = 100) => {
}; };
const DutyInfo: React.FC = () => { const DutyInfo: React.FC = () => {
// const [isNormalDuty, setIsNormalDuty] = useState(true); const [dutyInfo, setDutyInfo] = useState<Info>();
const [loading, setLoading] = useState(true);
const [messageApi, contextHolder] = message.useMessage();
useEffect(() => {
getDutyInfo()
.then((res) => {
setDutyInfo(res.data);
setLoading(false);
})
.catch((err) => {
messageApi.open({
type: 'error',
content: '获取失败!' + err,
});
});
});
// const [editableKeys, setEditableRowKeys] = useState<React.Key[]>(() =>
// defaultData.map((item) => item.id),
// );
return ( return (
<PageContainer> <PageContainer>
{contextHolder}
<Card> <Card>
<ProForm<Info> {!loading && (
submitter={{ <ProForm<Info>
render: (props, doms) => { submitter={{
return ( render: (props, doms) => {
<Row> return (
<Col span={14} offset={4}> <Row>
<Space>{doms}</Space> <Col span={14} offset={4}>
</Col> <Space>{doms}</Space>
</Row> </Col>
); </Row>
}, );
}} },
onFinish={async (values) => {
await waitTime(2000);
console.log(values);
message.success('提交成功');
}}
params={{}}
request={async (params = {} as Record<string, any>) =>
request<Info>('/admin/duty/current', {
params,
})
}
>
<ProFormRadio.Group
style={{
margin: 16,
}} }}
/> onFinish={async (values) => {
<ProFormText await waitTime(2000);
width="md" console.log(values);
name="inDutyCnt" message.success('提交成功');
label="值班人数" }}
tooltip="请输入数字" initialValues={dutyInfo}
placeholder="请输入值班人数" >
/> <ProFormRadio.Group
<ProFormText style={{
width="md" margin: 16,
name="offDutyReason" }}
label="暂停值班原因" />
placeholder="请输入暂停值班的原因" <ProFormDigit
/> label="值班人数"
<ProFormText name="inDutyCnt"
name="dutyRecoverTime" placeholder="请输入值班人数"
width="md" width="sm"
label="值班恢复时间" min={0}
placeholder="请输入值班恢复的时间" max={10}
/> />
</ProForm> <ProFormText
width="md"
name="offDutyReason"
label="暂停值班原因"
placeholder="请输入暂停值班的原因"
/>
<ProFormText
width="md"
name="place"
label="其他值班地点"
placeholder="请输入特殊值班地点"
/>
<ProFormText
name="dutyRecoverTime"
width="md"
label="值班恢复时间"
placeholder="请输入值班恢复的时间"
/>
<ProForm.Item label="值班时间" name="dataSource" trigger="onValuesChange">
{/* <EditableProTable<DataSourceType>
rowKey="id"
toolBarRender={false}
columns={columns}
recordCreatorProps={{
newRecordType: 'dataSource',
position: 'top',
record: () => ({
id: Date.now(),
addonBefore: 'ccccccc',
decs: 'testdesc',
}),
}}
editable={{
type: 'multiple',
editableKeys,
onChange: setEditableRowKeys,
actionRender: (row, _, dom) => {
return [dom.delete];
},
}}
/> */}
</ProForm.Item>
<ProFormDateTimeRangePicker name="dateTimeRange" label="值班时间" />
</ProForm>
)}
</Card> </Card>
</PageContainer> </PageContainer>
); );

View File

@ -5,6 +5,7 @@ import { PageContainer, ProCard, StatisticCard } from '@ant-design/pro-component
import { Card, Statistic, message } from 'antd'; import { Card, Statistic, message } from 'antd';
import RcResizeObserver from 'rc-resize-observer'; import RcResizeObserver from 'rc-resize-observer';
import { useLayoutEffect, useState } from 'react'; import { useLayoutEffect, useState } from 'react';
import { Stat } from './stat';
const percentRing = (percent: number, frontColor: string): React.JSX.Element => { const percentRing = (percent: number, frontColor: string): React.JSX.Element => {
const TinyRing = Tiny.Ring as (props: TinyRingConfig) => JSX.Element; const TinyRing = Tiny.Ring as (props: TinyRingConfig) => JSX.Element;
@ -34,24 +35,21 @@ const percentRing = (percent: number, frontColor: string): React.JSX.Element =>
const Logs: React.FC = () => { const Logs: React.FC = () => {
const [responsive, setResponsive] = useState(false); const [responsive, setResponsive] = useState(false);
const [messageApi, contextHolder] = message.useMessage(); const [messageApi, contextHolder] = message.useMessage();
const [stat, setStat] = useState<Stat>({
const [todayPT, setTodayPT] = useState(0); todayPT: 0,
const [report, setReport] = useState(0); totalPT: 0,
const [oreo, setOreo] = useState(0); oreo: 0,
const [totalPT, setTotalPT] = useState(0); report: 0,
const [allSuccess, setAllSuccess] = useState(0); allSuccess: 0,
const [all, setAll] = useState(0); all: 0,
});
const [loading, setLoading] = useState(true);
useLayoutEffect(() => { useLayoutEffect(() => {
getStat() getStat()
.then((res) => { .then((res) => {
const data = res.data; setStat(res.data);
setTodayPT(data.todayPT); setLoading(false);
setReport(data.report);
setOreo(data.oreo);
setTotalPT(data.totalPT);
setAllSuccess(data.allSuccess);
setAll(data.all);
}) })
.catch((err) => { .catch((err) => {
messageApi.open({ messageApi.open({
@ -63,62 +61,70 @@ const Logs: React.FC = () => {
return ( return (
<PageContainer> <PageContainer>
{contextHolder} {contextHolder}
<Card style={{ color: '#f5f5f5' }}> {!loading && (
<RcResizeObserver <Card style={{ color: '#f5f5f5' }}>
key="resize-observer" <RcResizeObserver
onResize={(offset) => { key="resize-observer"
setResponsive(offset.width < 596); onResize={(offset) => {
}} setResponsive(offset.width < 596);
> }}
<ProCard split={responsive ? 'horizontal' : 'vertical'}> >
<ProCard colSpan="Auto"> <ProCard split={responsive ? 'horizontal' : 'vertical'}>
<ProCard hoverable></ProCard> <ProCard colSpan="Auto">
</ProCard> <ProCard hoverable></ProCard>
<ProCard colSpan="170px"> </ProCard>
<StatisticCard <ProCard colSpan="170px">
hoverable
style={{ marginTop: '0vh' }}
statistic={{
title: '今日预填写工单数',
value: todayPT,
description: (
<Statistic
style={{ marginTop: '15vh', marginBottom: '8vh' }}
title="今日反馈数"
value={report}
/>
),
}}
/>
</ProCard>
<ProCard colSpan="360px">
<StatisticCard.Group direction={responsive ? 'row' : 'column'}>
<StatisticCard <StatisticCard
hoverable hoverable
chart={percentRing(Math.round(((oreo / totalPT) * 1000) / 10), '#00CC66')} style={{ marginTop: '0vh' }}
statistic={{ statistic={{
title: '加入 Oreo 工单数', title: '今日预填写工单数',
value: oreo, value: stat.todayPT,
description: <Statistic title="预填写工单总数" value={totalPT} />, description: (
<Statistic
style={{ marginTop: '15vh', marginBottom: '8vh' }}
title="今日反馈数"
value={stat.report}
/>
),
}} }}
chartPlacement="left"
/> />
<StatisticCard </ProCard>
hoverable <ProCard colSpan="360px">
style={{ marginTop: '3vh' }} <StatisticCard.Group direction={responsive ? 'row' : 'column'}>
chart={percentRing(Math.round((allSuccess / all) * 1000) / 10, '#66AFF4')} <StatisticCard
statistic={{ hoverable
title: '维修成功次数', chart={percentRing(
value: allSuccess, Math.round(((stat.oreo / stat.totalPT) * 1000) / 10),
description: <Statistic title="Oreo、ETA 总工单数" value={all} />, '#00CC66',
}} )}
chartPlacement="left" statistic={{
/> title: '加入 Oreo 工单数',
</StatisticCard.Group> value: stat.oreo,
description: <Statistic title="预填写工单总数" value={stat.totalPT} />,
}}
chartPlacement="left"
/>
<StatisticCard
hoverable
style={{ marginTop: '3vh' }}
chart={percentRing(
Math.round((stat.allSuccess / stat.all) * 1000) / 10,
'#66AFF4',
)}
statistic={{
title: '维修成功次数',
value: stat.allSuccess,
description: <Statistic title="Oreo、ETA 总工单数" value={stat.all} />,
}}
chartPlacement="left"
/>
</StatisticCard.Group>
</ProCard>
</ProCard> </ProCard>
</ProCard> </RcResizeObserver>
</RcResizeObserver> </Card>
</Card> )}
</PageContainer> </PageContainer>
); );
}; };

View File

@ -0,0 +1,8 @@
export type Stat = {
todayPT: number;
totalPT: number;
oreo: number;
report: number;
allSuccess: number;
all: number;
};

View File

@ -1,6 +1,7 @@
// @ts-ignore // @ts-ignore
/* eslint-disable */ /* eslint-disable */
import { Info } from '@/pages/Admin/DutyInfo/info'; import { Info } from '@/pages/Admin/DutyInfo/info';
import { Stat } from '@/pages/Welcome/stat';
import { request } from '@umijs/max'; import { request } from '@umijs/max';
import { API } from './typings'; import { API } from './typings';
@ -37,7 +38,7 @@ export async function login(body: API.LoginParams, options?: { [key: string]: an
/** 获取首页信息 GET /stats */ /** 获取首页信息 GET /stats */
export async function getStat(options?: { [key: string]: any }) { export async function getStat(options?: { [key: string]: any }) {
return request<{ return request<{
data: API.Stat; data: Stat;
}>('/stats', { }>('/stats', {
method: 'GET', method: 'GET',
...(options || {}), ...(options || {}),

View File

@ -41,12 +41,4 @@ declare namespace API {
size: number; size: number;
data: LogsItem[]; data: LogsItem[];
}; };
type Stat = {
todayPT: number;
totalPT: number;
oreo: number;
report: number;
allSuccess: number;
all: number;
};
} }