fix:更新首页bi
This commit is contained in:
parent
96f0ac68de
commit
7501a60dc7
@ -31,6 +31,7 @@
|
||||
"leaflet": "^1.9.4",
|
||||
"lodash": "^4.17.21",
|
||||
"react-activation": "^0.13.4",
|
||||
"react-countup": "^6.5.3",
|
||||
"react-use": "^17.5.1",
|
||||
"valtio": "^1.13.2"
|
||||
},
|
||||
|
||||
@ -42,6 +42,7 @@ export default function AvatarProps({ user }: { user: any }) {
|
||||
onClick={() => {
|
||||
Apis.Common.Auth.Logout().then(() => {
|
||||
stateActions.setLogout();
|
||||
sessionStorage.removeItem('loginUserInfo');
|
||||
history.push('/login');
|
||||
});
|
||||
}}
|
||||
@ -56,7 +57,7 @@ export default function AvatarProps({ user }: { user: any }) {
|
||||
useEffect(() => {
|
||||
let loginUserInfo = sessionStorage.getItem('loginUserInfo');
|
||||
console.log(loginUserInfo, 'loginUserInfo');
|
||||
if (loginUserInfo === 'dW5kZWZpbmVkXzAx') {
|
||||
if (loginUserInfo === 'I0xZMDEyM18wMQ==') {
|
||||
setOpen(true);
|
||||
console.log('登录成功');
|
||||
}
|
||||
|
||||
@ -60,7 +60,8 @@ export function MyLoginPage() {
|
||||
...{ captcha_key: getCaptcha?.key },
|
||||
})
|
||||
.then(async (res: any) => {
|
||||
let pass = btoa(`${res?.password}_01`);
|
||||
let pass = btoa(`${values?.password}_01`);
|
||||
console.log(pass, 'pass', values?.password);
|
||||
sessionStorage.setItem('loginUserInfo', pass);
|
||||
await stateActions.setLogin(res);
|
||||
navigate('/');
|
||||
|
||||
@ -11,3 +11,41 @@ export const isInTimeRange = (startTime?: string, endTime?: string) => {
|
||||
export function showTime(time?: string, num?: number) {
|
||||
return time?.substring(0, num || 5) || '';
|
||||
}
|
||||
|
||||
export function useCurrentDayTime() {
|
||||
let currentTime = dayjs().format('HH:mm:ss');
|
||||
let intervalId: NodeJS.Timeout;
|
||||
|
||||
const start = () => {
|
||||
intervalId = setInterval(() => {
|
||||
currentTime = dayjs().format('HH:mm:ss');
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
const stop = () => {
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
};
|
||||
|
||||
const getTime = () => {
|
||||
return currentTime;
|
||||
};
|
||||
|
||||
return {
|
||||
start,
|
||||
stop,
|
||||
getTime,
|
||||
};
|
||||
}
|
||||
|
||||
// 保持原有函数兼容性
|
||||
export function ShowCurrentDayTime() {
|
||||
const timeString = dayjs().format('HH:mm:ss');
|
||||
return timeString;
|
||||
}
|
||||
|
||||
export function GetFromNow(time: string) {
|
||||
//获取时间距离现在的时间
|
||||
return time ? dayjs(time).fromNow() : '';
|
||||
}
|
||||
|
||||
@ -27,11 +27,7 @@ export const renderTextHelper = {
|
||||
let item: any = Object.values(Enums).find((data: any) => {
|
||||
return data.value === '' + value;
|
||||
});
|
||||
return isColor ? (
|
||||
<Tag color={item?.color}>{item?.text}</Tag>
|
||||
) : (
|
||||
<Tag>{item?.text}</Tag>
|
||||
);
|
||||
return isColor ? <Tag color={item?.color}>{item?.text}</Tag> : item?.text;
|
||||
// return <Tag style={{ color: item.color }}>{item.text}</Tag>;
|
||||
},
|
||||
Images(images: string[]) {
|
||||
|
||||
@ -1126,6 +1126,18 @@ export const Apis = {
|
||||
FinancialAnalysis(): Promise<MyResponseType> {
|
||||
return request('company/statistics/index_count/financial_analysis', {});
|
||||
},
|
||||
TodayDynamics(): Promise<MyResponseType> {
|
||||
return request('company/statistics/index_count/today_dynamics', {});
|
||||
},
|
||||
WorkOrderAnalysis(): Promise<MyResponseType> {
|
||||
return request('company/statistics/index_count/work_order_analysis', {});
|
||||
},
|
||||
CommunityOverview(): Promise<MyResponseType> {
|
||||
return request('company/statistics/index_count/community_overview', {});
|
||||
},
|
||||
ClearCache(): Promise<MyResponseType> {
|
||||
return request('company/statistics/index_count/clear_cache', {});
|
||||
},
|
||||
},
|
||||
},
|
||||
Visitor: {
|
||||
|
||||
@ -282,7 +282,7 @@ export const BannersTypeEnum= {
|
||||
|
||||
// 缓存类型
|
||||
export const CacheTypeEnum= {
|
||||
'MobilePhoneVerificationCode': {"text":"手机验证码","color":"#ba2dfa","value":"MobilePhoneVerificationCode"},
|
||||
'MobilePhoneVerificationCode': {"text":"手机验证码","color":"#d249bd","value":"MobilePhoneVerificationCode"},
|
||||
};
|
||||
|
||||
// CompaniesMerchantTypeEnum
|
||||
|
||||
@ -1,13 +1,6 @@
|
||||
import { MyPageContainer } from '@/common';
|
||||
import { ProCard } from '@ant-design/pro-components';
|
||||
import { Space } from 'antd';
|
||||
import MyDemoLine from './charts/DemoLine';
|
||||
import MyOverviewClient from './charts/OverviewClient';
|
||||
import MyOverviewFinancialData from './components/OverviewFinancialData';
|
||||
import MyRanking from './components/Ranking';
|
||||
import './style.scss';
|
||||
export default function Index({ title = '财务Bi' }) {
|
||||
|
||||
return (
|
||||
<MyPageContainer
|
||||
title={title}
|
||||
@ -23,18 +16,7 @@ export default function Index({ title = '财务Bi' }) {
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
<Space
|
||||
direction="vertical"
|
||||
style={{ flex: 1, minWidth: '500px', marginRight: '20px' }}
|
||||
size="middle"
|
||||
>
|
||||
<MyOverviewFinancialData />
|
||||
<MyOverviewClient />
|
||||
<MyDemoLine />
|
||||
</Space>
|
||||
<ProCard style={{ maxWidth: '33vw' }} title="项目收款排名">
|
||||
<MyRanking />
|
||||
</ProCard>
|
||||
2
|
||||
</div>
|
||||
</MyPageContainer>
|
||||
);
|
||||
|
||||
@ -1,30 +1,10 @@
|
||||
import { MyBetaModalFormProps } from '@/common';
|
||||
import { Line } from '@ant-design/plots';
|
||||
import { useEffect, useState } from 'react';
|
||||
export default function FinancialAnalysisLine() {
|
||||
export default function FinancialAnalysisLine(props: MyBetaModalFormProps) {
|
||||
const [houseBillsCount, setHouseBillsCount] = useState<any>({});
|
||||
const config = {
|
||||
data: [
|
||||
{
|
||||
name: '收缴率',
|
||||
月份: '01',
|
||||
金额: 79.0,
|
||||
},
|
||||
{
|
||||
name: '月收款(万元)',
|
||||
月份: '01',
|
||||
金额: 69.0,
|
||||
},
|
||||
{
|
||||
name: '收缴率',
|
||||
月份: '02',
|
||||
金额: 89.0,
|
||||
},
|
||||
{
|
||||
name: '月收款(万元)',
|
||||
月份: '02',
|
||||
金额: 62.0,
|
||||
},
|
||||
],
|
||||
data: [],
|
||||
xField: '月份',
|
||||
yField: '金额',
|
||||
colorField: 'name',
|
||||
@ -57,12 +37,12 @@ export default function FinancialAnalysisLine() {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setHouseBillsCount({ ...config, data: [] });
|
||||
}, []);
|
||||
setHouseBillsCount({ ...config, data: props.item || [] });
|
||||
}, [props.item]);
|
||||
|
||||
return (
|
||||
<div style={{ height: 290 }}>
|
||||
<Line {...config} />
|
||||
<Line {...houseBillsCount} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
95
src/pages/index/charts/WorkOrderPie.tsx
Normal file
95
src/pages/index/charts/WorkOrderPie.tsx
Normal file
@ -0,0 +1,95 @@
|
||||
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?.list || [],
|
||||
legend: {
|
||||
color: {
|
||||
render: (legendItem: any, item: any) => {
|
||||
console.log(legendItem, item, 'legendItem');
|
||||
// 这里可以返回 React 节点或 HTML 字符串
|
||||
return (
|
||||
<Space
|
||||
size="small"
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
flexWrap: 'wrap',
|
||||
gap: '5px',
|
||||
}}
|
||||
>
|
||||
{legendItem?.map((row: any, index: number) => {
|
||||
return (
|
||||
<div key={`item_${index}`}>
|
||||
<div
|
||||
style={{
|
||||
width: 8,
|
||||
height: 8,
|
||||
display: 'inline-block',
|
||||
backgroundColor: row?.color,
|
||||
borderRadius: 100,
|
||||
fontSize: 14,
|
||||
marginRight: 4,
|
||||
}}
|
||||
/>
|
||||
{row?.label}:
|
||||
{
|
||||
props?.item?.list?.find(
|
||||
(i: any) => i.name === row?.label,
|
||||
)?.数量
|
||||
}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</Space>
|
||||
);
|
||||
},
|
||||
title: false,
|
||||
position: 'top',
|
||||
rowPadding: 5,
|
||||
},
|
||||
},
|
||||
annotations: [
|
||||
{
|
||||
type: 'text',
|
||||
style: {
|
||||
text: `${props?.item?.total || ''}\n工单总数`,
|
||||
x: '50%',
|
||||
y: '50%',
|
||||
textAlign: 'center',
|
||||
fontSize: 20,
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}, [props?.item]);
|
||||
|
||||
return (
|
||||
<div style={{ height: 400 }}>
|
||||
<Pie {...getPieCount} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -1,173 +1,269 @@
|
||||
import { ProCard } from '@ant-design/pro-components';
|
||||
import { MyColumns, MyProTableProps, renderTextHelper } from '@/common';
|
||||
import { GetFromNow, ShowCurrentDayTime } from '@/common/utils/day';
|
||||
import { Apis } from '@/gen/Apis';
|
||||
import {
|
||||
CompanyEmployeeBacklogsTypeEnum,
|
||||
HouseBillsTypeEnum,
|
||||
} from '@/gen/Enums';
|
||||
import { ClockCircleOutlined, FundOutlined } from '@ant-design/icons';
|
||||
import { ProCard, ProTable } from '@ant-design/pro-components';
|
||||
import { Col, Row, Space } from 'antd';
|
||||
import { useEffect, useState } from 'react';
|
||||
import CountUp from 'react-countup';
|
||||
import MyFinancialAnalysisLine from '../charts/FinancialAnalysisLine';
|
||||
import './style_left.scss';
|
||||
const RealTimeDynamicsEmployeeBacklogsTypeEnum = {
|
||||
...HouseBillsTypeEnum,
|
||||
...CompanyEmployeeBacklogsTypeEnum,
|
||||
};
|
||||
export default function LayoutLeft() {
|
||||
const [financialAnalysis, setFinancialAnalysis] = useState<any>({});
|
||||
const [todayDynamics, setTodayDynamics] = useState<any>({});
|
||||
const [currentTime, setCurrentTime] = useState<string>(ShowCurrentDayTime());
|
||||
const getFinancialAnalysis = async () => {
|
||||
let res = await Apis.Statistics.IndexCount.FinancialAnalysis();
|
||||
setFinancialAnalysis(res?.data);
|
||||
};
|
||||
const getTodayDynamics = async () => {
|
||||
let res = await Apis.Statistics.IndexCount.TodayDynamics();
|
||||
setTodayDynamics(res?.data);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getFinancialAnalysis();
|
||||
getTodayDynamics();
|
||||
|
||||
// 每5分钟调用一次 getTodayDynamics()
|
||||
const intervalId = setInterval(() => {
|
||||
getFinancialAnalysis();
|
||||
getTodayDynamics();
|
||||
}, 5 * 60 * 1000); // 5分钟
|
||||
|
||||
return () => {
|
||||
clearInterval(intervalId);
|
||||
};
|
||||
}, []);
|
||||
|
||||
// 每秒更新当前时间
|
||||
useEffect(() => {
|
||||
const intervalId = setInterval(() => {
|
||||
setCurrentTime(ShowCurrentDayTime());
|
||||
}, 1000);
|
||||
|
||||
return () => {
|
||||
clearInterval(intervalId);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
|
||||
<Space>
|
||||
<ProCard title="财务分析" style={{ width: '450px', color: '#fff' }}>
|
||||
<Space direction="vertical" style={{ width: '100%' }}>
|
||||
<div
|
||||
<div style={{ display: 'flex', gap: '15px', flexWrap: 'wrap' }}>
|
||||
<ProCard
|
||||
title="财务分析"
|
||||
className="finance_pro_card financial_analysis_card"
|
||||
style={{ flex: '0.5 1 400px', minWidth: '300px' }}
|
||||
>
|
||||
<div className="finance_pro_card_content pt-15">
|
||||
<Row>
|
||||
<Col span={8}>
|
||||
<div className="finance_pro_card_item">
|
||||
<div className="finance_pro_card_item_val">
|
||||
{financialAnalysis?.month_receivable}
|
||||
<span>元</span>
|
||||
</div>
|
||||
<div style={{ fontSize: '14px' }}>本月应收款</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<div className="finance_pro_card_item">
|
||||
<div className="finance_pro_card_item_val">
|
||||
{financialAnalysis?.month_received}
|
||||
<span>元</span>
|
||||
</div>
|
||||
<div style={{ fontSize: '14px' }}>本月实收款</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<div className="finance_pro_card_item">
|
||||
<div className="finance_pro_card_item_val">
|
||||
{financialAnalysis?.month_rate}%
|
||||
</div>
|
||||
<div style={{ fontSize: '14px' }}>本月收款率</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
<div className="finance_pro_card_content">
|
||||
<Row>
|
||||
<Col span={8}>
|
||||
<div className="finance_pro_card_item">
|
||||
<div className="finance_pro_card_item_val">
|
||||
{financialAnalysis?.year_receivable}
|
||||
<span>元</span>
|
||||
</div>
|
||||
<div style={{ fontSize: '14px' }}>年度应收款</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<div className="finance_pro_card_item">
|
||||
<div className="finance_pro_card_item_val">
|
||||
{financialAnalysis?.year_received}
|
||||
<span>元</span>
|
||||
</div>
|
||||
<div style={{ fontSize: '14px' }}>年度实收款</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<div className="finance_pro_card_item">
|
||||
<div className="finance_pro_card_item_val">
|
||||
{financialAnalysis?.year_rate}%
|
||||
</div>
|
||||
<div style={{ fontSize: '14px' }}>年度收款率</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
<MyFinancialAnalysisLine item={financialAnalysis?.chart_data || []} />
|
||||
</ProCard>
|
||||
<ProCard
|
||||
title="今日动态"
|
||||
style={{ flex: '1.5 1 400px', minWidth: '300px' }}
|
||||
className="finance_pro_card"
|
||||
extra={
|
||||
<Space align="center">
|
||||
<ClockCircleOutlined />
|
||||
{currentTime}
|
||||
<div className="circle_content">
|
||||
<div className="circle_center"></div>
|
||||
</div>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<Space
|
||||
direction="vertical"
|
||||
style={{
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<ProCard
|
||||
style={{
|
||||
background:
|
||||
'linear-gradient(115deg, #6499FF 45%, #95B8FF 100%)',
|
||||
padding: '20px 0',
|
||||
borderRadius: '10px',
|
||||
backgroundColor: '#F3F8FB',
|
||||
width: '100%',
|
||||
borderRadius: '8px',
|
||||
}}
|
||||
title="今日收款"
|
||||
extra={
|
||||
<div className="today_amount_contents">
|
||||
<span className="amount">
|
||||
<CountUp
|
||||
end={todayDynamics?.today_amount}
|
||||
duration={3}
|
||||
separator=","
|
||||
prefix="¥"
|
||||
decimals={2}
|
||||
/>
|
||||
</span>
|
||||
<span className="unit">元</span>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Row>
|
||||
<Col span={8}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
color: 'white',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontSize: '18px',
|
||||
fontWeight: 'bold',
|
||||
marginBottom: '5px',
|
||||
}}
|
||||
>
|
||||
79.00
|
||||
</div>
|
||||
<div style={{ fontSize: '14px' }}>本月应收款</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
color: 'white',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontSize: '18px',
|
||||
fontWeight: 'bold',
|
||||
marginBottom: '5px',
|
||||
}}
|
||||
>
|
||||
79.00
|
||||
</div>
|
||||
<div style={{ fontSize: '14px' }}>本月实收款</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
color: 'white',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontSize: '18px',
|
||||
fontWeight: 'bold',
|
||||
marginBottom: '5px',
|
||||
}}
|
||||
>
|
||||
79.00%
|
||||
</div>
|
||||
<div style={{ fontSize: '14px' }}>本月收款率</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Row gutter={[15, 15]}>
|
||||
{todayDynamics?.type_distribution?.map(
|
||||
(res: any, index: number) => {
|
||||
return (
|
||||
<Col span={6} key={`item_${index}`}>
|
||||
<div className="card_item">
|
||||
<div className="card_item_title">{res?.name}</div>
|
||||
<div>
|
||||
<CountUp
|
||||
end={res?.value}
|
||||
duration={3}
|
||||
separator=","
|
||||
prefix="¥"
|
||||
decimals={2}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
);
|
||||
},
|
||||
)}
|
||||
</Row>
|
||||
</ProCard>
|
||||
|
||||
<div>
|
||||
<Space className="bi_min_title">
|
||||
<FundOutlined />
|
||||
<div className="title">实时动态</div>
|
||||
</Space>
|
||||
<div className="dynamics_contents">
|
||||
{todayDynamics?.dynamics?.map((res: any, index: number) => {
|
||||
return (
|
||||
<div key={`item_${index}`} className="real_time_dynamics">
|
||||
<div className={`dynamics_type type_${res?.type}`}></div>
|
||||
<span>{GetFromNow(res?.time)}</span>
|
||||
{res?.type === 'WorkOrder' ? '提报' : '收到'}【
|
||||
{res?.target}】 【
|
||||
<renderTextHelper.Tag
|
||||
Enums={RealTimeDynamicsEmployeeBacklogsTypeEnum}
|
||||
value={res?.type}
|
||||
isColor={false}
|
||||
key="type"
|
||||
/>
|
||||
】{res?.amount ? `${res?.amount}元` : ''}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
background:
|
||||
'linear-gradient(115deg, #6499FF 45%, #95B8FF 100%)',
|
||||
padding: '20px 0',
|
||||
borderRadius: '10px',
|
||||
}}
|
||||
>
|
||||
<Row>
|
||||
<Col span={8}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
color: 'white',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontSize: '18px',
|
||||
fontWeight: 'bold',
|
||||
marginBottom: '5px',
|
||||
}}
|
||||
>
|
||||
79.00
|
||||
</div>
|
||||
<div style={{ fontSize: '14px' }}>年度应收款</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
color: 'white',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontSize: '18px',
|
||||
fontWeight: 'bold',
|
||||
marginBottom: '5px',
|
||||
}}
|
||||
>
|
||||
79.00
|
||||
</div>
|
||||
<div style={{ fontSize: '14px' }}>年度实收款</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
color: 'white',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontSize: '18px',
|
||||
fontWeight: 'bold',
|
||||
marginBottom: '5px',
|
||||
}}
|
||||
>
|
||||
79.00%
|
||||
</div>
|
||||
<div style={{ fontSize: '14px' }}>年度收款率</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
<MyFinancialAnalysisLine />
|
||||
</Space>
|
||||
</ProCard>
|
||||
</Space>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
flex: 1,
|
||||
padding: '15px',
|
||||
backgroundColor: '#f0f0f0',
|
||||
borderRadius: '4px',
|
||||
marginTop: '15px',
|
||||
}}
|
||||
>
|
||||
下部分内容
|
||||
<ProCard title="小区概括分析" className="finance_pro_card">
|
||||
<ProTable
|
||||
{...MyProTableProps.props}
|
||||
request={async (params, sort) => {
|
||||
return MyProTableProps.request(
|
||||
params,
|
||||
sort,
|
||||
Apis.Statistics.IndexCount.CommunityOverview,
|
||||
);
|
||||
}}
|
||||
search={false}
|
||||
options={false}
|
||||
columns={[
|
||||
MyColumns.ID({
|
||||
search: false,
|
||||
}),
|
||||
{
|
||||
title: '项目名称',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: '房屋数',
|
||||
dataIndex: 'house_count',
|
||||
},
|
||||
{
|
||||
title: '车位数',
|
||||
dataIndex: 'car_port_count',
|
||||
},
|
||||
{
|
||||
title: '绑定客户数',
|
||||
dataIndex: 'customer_count',
|
||||
},
|
||||
{
|
||||
title: '收缴率',
|
||||
dataIndex: 'collection_rate',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</ProCard>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -1,3 +1,175 @@
|
||||
import { Apis } from '@/gen/Apis';
|
||||
import { RightOutlined } from '@ant-design/icons';
|
||||
import { useNavigate } from '@umijs/max';
|
||||
import { Col, Progress, Row, Space } from 'antd';
|
||||
import { useEffect, useState } from 'react';
|
||||
import CountUp from 'react-countup';
|
||||
import WorkOrderPie from '../charts/WorkOrderPie';
|
||||
import './style_right.scss';
|
||||
export default function LayoutRight() {
|
||||
return <div>LayoutRight</div>;
|
||||
const navigate = useNavigate();
|
||||
const [workOrderAnalysis, setWorkOrderAnalysis] = useState<any>({});
|
||||
const getWorkOrderAnalysis = () => {
|
||||
Apis.Statistics.IndexCount.WorkOrderAnalysis().then((res) => {
|
||||
setWorkOrderAnalysis(res.data);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getWorkOrderAnalysis();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="right_content">
|
||||
<div
|
||||
style={{
|
||||
padding: '0 0 20px 0',
|
||||
fontSize: 16,
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
工单分析
|
||||
</div>
|
||||
<Space direction="vertical" style={{ width: '100%' }}>
|
||||
<div
|
||||
style={{ backgroundColor: '#F3FAFF', borderRadius: 8, padding: 20 }}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
padding: '0 0 15px 0',
|
||||
fontSize: 16,
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
待处理工单
|
||||
</div>
|
||||
<Row gutter={[12, 12]}>
|
||||
<Col span={12}>
|
||||
<div
|
||||
className="work_card_title"
|
||||
onClick={() => {
|
||||
navigate('/work_order/list');
|
||||
}}
|
||||
>
|
||||
报修工单 <RightOutlined />
|
||||
</div>
|
||||
<div className="work_card_number">
|
||||
{/* {workOrderAnalysis?.repair || 0} */}
|
||||
<CountUp
|
||||
end={workOrderAnalysis?.repair}
|
||||
duration={3}
|
||||
separator=","
|
||||
prefix=""
|
||||
/>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div
|
||||
className="work_card_title"
|
||||
onClick={() => {
|
||||
navigate('/work_order/list');
|
||||
}}
|
||||
>
|
||||
报事工单 <RightOutlined />
|
||||
</div>
|
||||
<div className="work_card_number">
|
||||
<CountUp
|
||||
end={workOrderAnalysis?.incident}
|
||||
duration={3}
|
||||
separator=","
|
||||
prefix=""
|
||||
/>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div
|
||||
className="work_card_title"
|
||||
onClick={() => {
|
||||
navigate('/work_order/complaint');
|
||||
}}
|
||||
>
|
||||
投诉工单 <RightOutlined size={12} />
|
||||
</div>
|
||||
<div className="work_card_number">
|
||||
<CountUp
|
||||
end={workOrderAnalysis?.complaint}
|
||||
duration={3}
|
||||
separator=","
|
||||
prefix=""
|
||||
/>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
style={{
|
||||
padding: '15px 0',
|
||||
fontSize: 16,
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
工单统计
|
||||
</div>
|
||||
<WorkOrderPie
|
||||
item={{
|
||||
list: workOrderAnalysis?.distribution || [],
|
||||
total: workOrderAnalysis?.total || 0,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
style={{
|
||||
padding: '15px 0',
|
||||
fontSize: 16,
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
工单数据
|
||||
</div>
|
||||
<div className="work_order_data">
|
||||
<div className="work_order_data_item">
|
||||
<Progress
|
||||
type="dashboard"
|
||||
size={[160, 30]}
|
||||
percent={workOrderAnalysis?.data?.completion_rate}
|
||||
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">
|
||||
已完成:{workOrderAnalysis?.data?.completed_count || 0}
|
||||
</div>
|
||||
<div className="work_order_data_cell">已关闭:{0}</div>
|
||||
</div>
|
||||
<div className="work_order_data_item">
|
||||
<Progress
|
||||
type="dashboard"
|
||||
size={[160, 30]}
|
||||
percent={workOrderAnalysis?.data?.satisfaction_rate}
|
||||
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">
|
||||
已评价:{workOrderAnalysis?.data?.evaluated_count || 0}
|
||||
</div>
|
||||
<div className="work_order_data_cell">已好评:{0}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Space>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
294
src/pages/index/components/style_left.scss
Normal file
294
src/pages/index/components/style_left.scss
Normal file
@ -0,0 +1,294 @@
|
||||
.finance_pro_card {
|
||||
border-radius: 8px;
|
||||
}
|
||||
.financial_analysis_card {
|
||||
width: 470px;
|
||||
}
|
||||
.finance_pro_card_content {
|
||||
background: linear-gradient(135deg, #6499ff 0%, #95b8ff 100%);
|
||||
padding: 25px 0;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 10px 25px -5px rgba(42, 126, 251, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 15px 30px -5px rgba(42, 126, 251, 0.4);
|
||||
}
|
||||
|
||||
// animation: fadeInUp 0.6s ease-out forwards;
|
||||
// opacity: 0;
|
||||
// transform: translateY(20px);
|
||||
|
||||
// &.pt-15 {
|
||||
// animation-delay: 0.2s;
|
||||
// }
|
||||
|
||||
.finance_pro_card_item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
animation: scaleIn 0.8s ease-out forwards;
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
|
||||
&:nth-child(1) {
|
||||
animation-delay: 0.3s;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
&:nth-child(3) {
|
||||
animation-delay: 0.5s;
|
||||
}
|
||||
}
|
||||
|
||||
.finance_pro_card_item_val {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 8px;
|
||||
animation: textSlideUp 0.8s ease-out forwards;
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
|
||||
span {
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
margin-left: 4px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
.finance_pro_card_item > div:last-child {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
animation: textFadeIn 1s ease-out forwards;
|
||||
opacity: 0;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
// 为每个子元素添加不同的动画延迟
|
||||
.finance_pro_card_item {
|
||||
&:nth-child(1) {
|
||||
.finance_pro_card_item_val {
|
||||
animation-delay: 0.5s;
|
||||
}
|
||||
> div:last-child {
|
||||
animation-delay: 0.7s;
|
||||
}
|
||||
}
|
||||
&:nth-child(2) {
|
||||
.finance_pro_card_item_val {
|
||||
animation-delay: 0.6s;
|
||||
}
|
||||
> div:last-child {
|
||||
animation-delay: 0.8s;
|
||||
}
|
||||
}
|
||||
&:nth-child(3) {
|
||||
.finance_pro_card_item_val {
|
||||
animation-delay: 0.7s;
|
||||
}
|
||||
> div:last-child {
|
||||
animation-delay: 0.9s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes scaleIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes textSlideUp {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes textFadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.pt-15 {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.card_item {
|
||||
background-color: #fff;
|
||||
padding: 25px 20px;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
color: #3d3d3d;
|
||||
font-size: 16px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||
transition: all 0.3s ease;
|
||||
border: 1px solid #f0f0f0;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12);
|
||||
border-color: #e0e7ff;
|
||||
}
|
||||
|
||||
&_title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
font-size: 16px;
|
||||
color: #1f2937;
|
||||
}
|
||||
|
||||
> div:last-child {
|
||||
font-size: 18px;
|
||||
color: #3d3d3d;
|
||||
}
|
||||
}
|
||||
|
||||
.bi_min_title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
padding: 12px 0;
|
||||
color: #2a7efb;
|
||||
.title {
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.dynamics_contents {
|
||||
height: 170px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.real_time_dynamics {
|
||||
color: #333;
|
||||
width: 100%;
|
||||
font-size: 16px;
|
||||
padding: 0 0 15px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.dynamics_type {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 100px;
|
||||
background-color: #eee;
|
||||
}
|
||||
span {
|
||||
color: #666;
|
||||
padding: 0 10px;
|
||||
}
|
||||
.type_WorkOrder {
|
||||
background-color: #faad14;
|
||||
}
|
||||
.type_PropertyFee {
|
||||
background-color: #00a154;
|
||||
}
|
||||
.type_MaintenanceFund {
|
||||
background-color: #1bc0c4;
|
||||
}
|
||||
.type_WaterFee {
|
||||
background-color: #007bff;
|
||||
}
|
||||
.type_ElectricityFee {
|
||||
background-color: #f8860c;
|
||||
}
|
||||
.type_SharedWaterFee {
|
||||
background-color: #60ffb2;
|
||||
}
|
||||
.type_SharedElectricityFee {
|
||||
background-color: #7912ff;
|
||||
}
|
||||
.type_CarPortFee {
|
||||
background-color: #ffb547;
|
||||
}
|
||||
.type_WorkOrderRepairFee {
|
||||
background-color: #ff4141;
|
||||
}
|
||||
}
|
||||
|
||||
.today_amount_contents {
|
||||
.amount {
|
||||
font-size: 19px;
|
||||
font-weight: 500;
|
||||
color: #389e0d;
|
||||
}
|
||||
.unit {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.circle_content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #deffcb;
|
||||
padding: 6px;
|
||||
border-radius: 100px;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
background-color: rgba(73, 213, 13, 0.3);
|
||||
animation: ripple 2.4s infinite;
|
||||
}
|
||||
|
||||
&::after {
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
.circle_center {
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
border-radius: 100px;
|
||||
background-color: #389e0d;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ripple {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: scale(1.5);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
49
src/pages/index/components/style_right.scss
Normal file
49
src/pages/index/components/style_right.scss
Normal file
@ -0,0 +1,49 @@
|
||||
.work_card_title {
|
||||
color: #666666;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.right_content {
|
||||
flex: 1;
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
height: 92vh;
|
||||
}
|
||||
.work_card_number {
|
||||
color: #333333;
|
||||
font-size: 28px;
|
||||
font-weight: 500;
|
||||
padding-top: 5px;
|
||||
}
|
||||
.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,4 +1,6 @@
|
||||
// import MyModalsMapLeaflet from '@/components/ModalsMapLeaflet';
|
||||
import { Apis } from '@/gen/Apis';
|
||||
import { FloatButton } from 'antd';
|
||||
import LayoutLeft from './components/LayoutLeft';
|
||||
import LayoutRight from './components/LayoutRight';
|
||||
import './style.scss';
|
||||
@ -11,6 +13,16 @@ export default function Index() {
|
||||
<div className="overview_right">
|
||||
<LayoutRight />
|
||||
</div>
|
||||
<FloatButton
|
||||
// icon={<Loading3QuartersOutlined />}
|
||||
description="刷新"
|
||||
onClick={() => {
|
||||
Apis.Statistics.IndexCount.ClearCache().then(() => {
|
||||
// message.success('刷新成功');
|
||||
window.location.reload();
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
43
yarn.lock
43
yarn.lock
@ -4870,6 +4870,11 @@ cosmiconfig@^9.0.0:
|
||||
js-yaml "^4.1.0"
|
||||
parse-json "^5.2.0"
|
||||
|
||||
countup.js@^2.8.0:
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/countup.js/-/countup.js-2.9.0.tgz#599e6482e502e5e3f00f8816637120c9b21856ed"
|
||||
integrity sha512-llqrvyXztRFPp6+i8jx25phHWcVWhrHO4Nlt0uAOSKHB8778zzQswa4MU3qKBvkXfJKftRYFJuVHez67lyKdHg==
|
||||
|
||||
create-ecdh@^4.0.4:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz"
|
||||
@ -10584,6 +10589,13 @@ react-activation@^0.13.4:
|
||||
react-node-key "^0.4.0"
|
||||
szfe-tools "^0.0.0-beta.7"
|
||||
|
||||
react-countup@^6.5.3:
|
||||
version "6.5.3"
|
||||
resolved "https://registry.yarnpkg.com/react-countup/-/react-countup-6.5.3.tgz#e892aa3eab2d6ba9c3cdba30bf4ed6764826d848"
|
||||
integrity sha512-udnqVQitxC7QWADSPDOxVWULkLvKUWrDapn5i53HE4DPRVgs+Y5rr4bo25qEl8jSh+0l2cToJgGMx+clxPM3+w==
|
||||
dependencies:
|
||||
countup.js "^2.8.0"
|
||||
|
||||
react-dom@18.3.1:
|
||||
version "18.3.1"
|
||||
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz"
|
||||
@ -11635,16 +11647,7 @@ string-convert@^0.2.0:
|
||||
resolved "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz"
|
||||
integrity sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==
|
||||
|
||||
"string-width-cjs@npm:string-width@^4.2.0":
|
||||
version "4.2.3"
|
||||
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
dependencies:
|
||||
emoji-regex "^8.0.0"
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.1"
|
||||
|
||||
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
@ -11734,14 +11737,7 @@ string_decoder@~1.1.1:
|
||||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
@ -12645,16 +12641,7 @@ word-wrap@^1.2.5:
|
||||
resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz"
|
||||
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
|
||||
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
dependencies:
|
||||
ansi-styles "^4.0.0"
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrap-ansi@^7.0.0:
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user