feat: 仪表盘

This commit is contained in:
landaiqing
2024-07-03 14:53:33 +08:00
parent 514d6dcf33
commit 21ff0416a3
11 changed files with 376 additions and 18 deletions

View File

@@ -21,6 +21,7 @@
"axios": "^1.7.2",
"core-js": "^3.37.1",
"crypto-js": "^4.2.0",
"echarts-for-react": "^3.0.2",
"jsencrypt": "^3.3.2",
"localforage": "^1.10.0",
"mobx": "^6.12.3",

37
pnpm-lock.yaml generated
View File

@@ -38,6 +38,9 @@ dependencies:
crypto-js:
specifier: ^4.2.0
version: 4.2.0
echarts-for-react:
specifier: ^3.0.2
version: 3.0.2(echarts@5.5.1)(react@18.3.1)
jsencrypt:
specifier: ^3.3.2
version: 3.3.2
@@ -4038,6 +4041,25 @@ packages:
engines: {node: '>=12'}
dev: false
/echarts-for-react@3.0.2(echarts@5.5.1)(react@18.3.1):
resolution: {integrity: sha512-DRwIiTzx8JfwPOVgGttDytBqdp5VzCSyMRIxubgU/g2n9y3VLUmF2FK7Icmg/sNVkv4+rktmrLN9w22U2yy3fA==}
peerDependencies:
echarts: ^3.0.0 || ^4.0.0 || ^5.0.0
react: ^15.0.0 || >=16.0.0
dependencies:
echarts: 5.5.1
fast-deep-equal: 3.1.3
react: 18.3.1
size-sensor: 1.0.2
dev: false
/echarts@5.5.1:
resolution: {integrity: sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==}
dependencies:
tslib: 2.3.0
zrender: 5.6.0
dev: false
/ejs@3.1.10:
resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==}
engines: {node: '>=0.10.0'}
@@ -4466,7 +4488,6 @@ packages:
/fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
dev: true
/fast-diff@1.3.0:
resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
@@ -7323,6 +7344,10 @@ packages:
engines: {node: '>=14'}
dev: true
/size-sensor@1.0.2:
resolution: {integrity: sha512-2NCmWxY7A9pYKGXNBfteo4hy14gWu47rg5692peVMst6lQLPKrVjhY+UTEsPI5ceFRJSl3gVgMYaUi/hKuaiKw==}
dev: false
/slash@3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
@@ -7853,6 +7878,10 @@ packages:
typescript: 5.4.5
dev: true
/tslib@2.3.0:
resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==}
dev: false
/tslib@2.6.2:
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
@@ -8230,3 +8259,9 @@ packages:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
dev: true
/zrender@5.6.0:
resolution: {integrity: sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==}
dependencies:
tslib: 2.3.0
dev: false

View File

@@ -0,0 +1 @@
<svg t="1719988678909" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15225" width="200" height="200"><path d="M868.590933 569.207467h-107.281066c-16.9472 0-28.245333-5.632-33.8944-16.930134v-5.649066l-28.228267-73.403734-67.754667 197.632c-5.649067 16.9472-16.9472 28.228267-33.8944 28.228267-16.930133 0-28.228267-5.632-33.877333-22.5792l-73.403733-141.175467-11.298134 16.9472c-5.649067 11.298133-16.9472 16.930133-33.877333 16.930134H157.0816c-22.5792 0-39.5264-16.930133-39.5264-39.5264 0-22.5792 16.9472-39.5264 39.5264-39.5264h265.403733l33.877334-62.122667c5.649067-11.281067 22.596267-11.281067 33.8944-11.281067 16.930133 0 28.228267 5.632 33.877333 22.5792l62.122667 124.245334 73.386666-208.9472c5.666133-16.930133 22.596267-22.5792 39.543467-22.5792 11.298133 0 28.228267 0 39.5264 16.930133l50.824533 141.175467h79.0528c22.596267 0 39.5264 16.9472 39.5264 39.5264 0 22.596267-22.596267 39.5264-39.5264 39.5264M506.504533 0C228.181333 0 0.426667 227.7376 0.426667 506.077867c0 278.357333 227.7376 506.077867 506.077866 506.077866 278.357333 0 506.094933-227.7376 506.094934-506.077866C1012.599467 227.720533 784.8448 0 506.504533 0" fill="#13E6AA" p-id="15226"></path></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
<svg t="1719970697825" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5208" width="200" height="200"><path d="M322.37037 0h379.25926a322.37037 322.37037 0 0 1 322.37037 322.37037v379.25926a322.37037 322.37037 0 0 1-322.37037 322.37037H322.37037A322.37037 322.37037 0 0 1 0 701.62963V322.37037A322.37037 322.37037 0 0 1 322.37037 0z" fill="#DFF7F4" p-id="5209"></path><path d="M736.521481 313.837037a16.877037 16.877037 0 0 0-14.601481-5.30963 16.497778 16.497778 0 0 0-12.705185 8.912593l-43.045926 82.868148-60.491852-31.288889 43.045926-82.868148a16.877037 16.877037 0 0 0-7.395556-22.755555 22.376296 22.376296 0 0 0-5.688888-1.896297 170.666667 170.666667 0 0 0-177.114075 242.536297L455.111111 512l-102.4 196.077037a102.4 102.4 0 0 0 181.854815 93.866667l105.623704-204.231111a170.666667 170.666667 0 0 0 96.331851-284.444445z" fill="#ADEAE1" p-id="5210"></path><path d="M761.362963 343.419259a17.445926 17.445926 0 0 0-12.325926-9.481481 16.497778 16.497778 0 0 0-14.791111 4.740741l-66.180741 65.991111-48.165926-48.165926 65.991111-65.991111a17.066667 17.066667 0 0 0 0-24.082963 28.634074 28.634074 0 0 0-4.93037-3.413334 170.666667 170.666667 0 0 0-242.157037 177.493334l-6.447407 6.637037-156.254815 155.875555a102.4 102.4 0 0 0 144.877037 144.497778l162.512592-162.512593a170.666667 170.666667 0 0 0 177.872593-241.588148z" fill="#00CCA5" p-id="5211"></path><path d="M350.814815 635.259259a37.925926 37.925926 0 1 1-37.925926 37.925926 37.925926 37.925926 0 0 1 37.925926-37.925926z" fill="#FFFFFF" p-id="5212"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1 @@
<svg t="1719987558668" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7251" width="200" height="200"><path d="M998.36831369 808.03500972l-88.63608925-569.45477076c-33.85380987-101.62815163-91.51450005-218.21607951-236.61730669-218.21607953h-315.20880748c-77.67963338 0-181.90409043 37.99642711-237.67081208 222.21939995l-94.67501614 565.17051556s-5.19612263 32.65866655-5.19612262 50.07662207c0 80.4866399 62.8591539 145.80514357 140.46738303 145.80514356h702.19761827c77.67963338 0 140.60902095-65.31850367 140.60902094-145.80514356 0-17.27865868-5.26752687-49.79568727-5.26752687-49.79568729zM366.75672597 314.92309107c4.49495625 0 8.42804297 1.68560859 12.85276552 2.45817921 5.96986378-65.0375689 61.59494744-116.30699314 130.14303036-116.30699314 64.96616463 0 118.55447127 45.93400483 129.1597587 106.05404472 4.49495625-0.70350747 9.13155046-1.33444016 13.83603723-1.33444014 42.77231812 0 77.46776173 33.64193822 77.46776173 75.22028361s-34.62520991 75.22028359-77.46776173 75.2905173h-285.99159181c-40.24390524 0-72.76210441-31.74562857-72.7621044-70.72532734s32.44913603-70.65626421 72.7621044-70.65626422zM806.06846636 915.28068607h-588.06669899c-34.76567729 0-62.9293876-26.19716695-62.92938761-58.57372814 0-32.23726441 28.09347658-58.50466503 62.92938761-58.50466504h587.99646526c34.76567729 0 62.9293876 26.26857117 62.92938761 58.50466504 0 32.37773178-28.09347658 58.57372816-62.85915388 58.57372814z" fill="#ffa500" p-id="7252"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,20 @@
.home_content_main{
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.home_content_head_left {
height: 51vh;
width: 31vw;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
}
}

View File

@@ -1,7 +1,269 @@
/** @format */
import { FunctionComponent } from "react";
import { FunctionComponent, useEffect, useState } from "react";
import { Avatar, Card, Skeleton, Space } from "antd";
import Meta from "antd/es/card/Meta";
import styles from "./index.module.less";
import ReactECharts from "echarts-for-react";
// import * as echarts from "echarts/core";
import { ProCard } from "@ant-design/pro-components";
import storage from "@/assets/icons/storage.svg";
import bucket from "@/assets/icons/bucket.svg";
import file from "@/assets/icons/file.svg";
import flux from "@/assets/icons/flux.svg";
const MainHome: FunctionComponent = () => {
return <div></div>;
const [loading, setLoading] = useState(true);
const option = {
tooltip: {
trigger: "axis",
},
legend: {
color: ["#F58080", "#47D8BE", "#F9A589"],
data: ["文件", "流量", "存储桶"],
left: "center",
bottom: "bottom",
},
grid: {
top: "middle",
left: "3%",
right: "4%",
bottom: "3%",
height: "80%",
containLabel: true,
},
xAxis: {
type: "category",
data: [100, 200, 20, 30, 60, 89],
axisLine: {
lineStyle: {
color: "#999",
},
},
},
yAxis: {
type: "value",
splitLine: {
lineStyle: {
type: "dashed",
color: "#DDD",
},
},
axisLine: {
show: false,
lineStyle: {
color: "#333",
},
},
nameTextStyle: {
color: "#999",
},
splitArea: {
show: false,
},
},
series: [
{
name: "文件",
type: "line",
data: [800, 900, 220, 130, 660, 289],
color: "#F58080",
lineStyle: {
normal: {
width: 5,
color: {
type: "linear",
colorStops: [
{
offset: 0,
color: "#FFCAD4", // 0% 处的颜色
},
{
offset: 0.4,
color: "#F58080", // 100% 处的颜色
},
{
offset: 1,
color: "#F58080", // 100% 处的颜色
},
],
globalCoord: false, // 缺省为 false
},
shadowColor: "rgba(245,128,128, 0.5)",
shadowBlur: 10,
shadowOffsetY: 7,
},
},
itemStyle: {
normal: {
color: "#F58080",
borderWidth: 10,
/*shadowColor: 'rgba(72,216,191, 0.3)',
shadowBlur: 100,*/
borderColor: "#F58080",
},
},
smooth: true,
},
{
name: "流量",
type: "line",
data: [123, 568, 111, 222, 123, 56],
lineStyle: {
normal: {
width: 5,
color: {
type: "linear",
colorStops: [
{
offset: 0,
color: "#AAF487", // 0% 处的颜色
},
{
offset: 0.4,
color: "#47D8BE", // 100% 处的颜色
},
{
offset: 1,
color: "#47D8BE", // 100% 处的颜色
},
],
globalCoord: false, // 缺省为 false
},
shadowColor: "rgba(71,216,190, 0.5)",
shadowBlur: 10,
shadowOffsetY: 7,
},
},
itemStyle: {
normal: {
color: "#AAF487",
borderWidth: 10,
/*shadowColor: 'rgba(72,216,191, 0.3)',
shadowBlur: 100,*/
borderColor: "#AAF487",
},
},
smooth: true,
},
{
name: "存储桶",
type: "line",
data: [125, 568, 25, 36, 784, 56],
lineStyle: {
normal: {
width: 5,
color: {
type: "linear",
colorStops: [
{
offset: 0,
color: "#F6D06F", // 0% 处的颜色
},
{
offset: 0.4,
color: "#F9A589", // 100% 处的颜色
},
{
offset: 1,
color: "#F9A589", // 100% 处的颜色
},
],
globalCoord: false, // 缺省为 false
},
shadowColor: "rgba(249,165,137, 0.5)",
shadowBlur: 10,
shadowOffsetY: 7,
},
},
itemStyle: {
normal: {
color: "#F6D06F",
borderWidth: 10,
/*shadowColor: 'rgba(72,216,191, 0.3)',
shadowBlur: 100,*/
borderColor: "#F6D06F",
},
},
smooth: true,
},
],
};
useEffect(() => {
setTimeout(() => {
setLoading(false);
}, 2000);
}, []);
return (
<>
<Space className={styles.home_content_main}>
<div className={styles.home_content_head_left}>
<Card
style={{ width: "14.5vw", height: "21vh" }}
loading={false}
bordered
hoverable>
<Skeleton loading={loading} active avatar>
<Meta
avatar={<Avatar shape="square" size="large" src={storage} />}
title="存储"
description="This is the description"
/>
</Skeleton>
</Card>
<Card
style={{ width: "14.5vw", height: "21vh" }}
loading={false}
bordered
hoverable>
<Skeleton loading={loading} active avatar>
<Meta
avatar={<Avatar shape="square" size="large" src={bucket} />}
title="存储桶"
description="This is the description"
/>
</Skeleton>
</Card>
<Card
style={{ width: "14.5vw", height: "21vh" }}
loading={false}
bordered
hoverable>
<Skeleton loading={loading} active avatar>
<Meta
avatar={<Avatar shape="square" size="large" src={file} />}
title="文件"
description="This is the description"
/>
</Skeleton>
</Card>
<Card
style={{ width: "14.5vw", height: "21vh" }}
loading={false}
bordered
hoverable>
<Skeleton loading={loading} active avatar>
<Meta
avatar={<Avatar shape="square" size="large" src={flux} />}
title="总量"
description="This is the description"
/>
</Skeleton>
</Card>
</div>
<div>
<ProCard bordered boxShadow>
<ReactECharts
option={option}
style={{ width: "39vw", height: "42vh" }}
showLoading={loading}
/>
</ProCard>
</div>
</Space>
</>
);
};
export default MainHome;

View File

@@ -6,7 +6,7 @@
background-size: cover;
border-radius: 10px;
height: 150px;
box-shadow: rgba(15, 15, 16, 0.18) 0px 10px 10px;;
box-shadow: rgba(15, 15, 16, 0.18) 0px 10px 10px;
}
.user_info_header_avatar {
display: flex;

View File

@@ -1,6 +1,6 @@
/** @format */
import { FunctionComponent, useEffect, useState } from "react";
import { ProCard, ProFormCascader } from "@ant-design/pro-components";
import { ProCard, ProForm, ProFormCascader } from "@ant-design/pro-components";
import { AntDesignOutlined } from "@ant-design/icons";
import {
Avatar,
@@ -68,12 +68,23 @@ const UserSetting: FunctionComponent = () => {
const prefixSelector = (
<Form.Item name="prefix" noStyle>
<Select style={{ width: 90 }} defaultValue={"https://"}>
<Select style={{ width: 90 }}>
<Select.Option value="https://">https://</Select.Option>
<Select.Option value="http://">http://</Select.Option>
</Select>
</Form.Item>
);
const ProFormText = (props: any) => {
return (
<ProForm.Item {...props} style={{ height: "10px" }}>
<ProFormCascader
request={async () => city}
width="md"
name="location"
disabled={disable}></ProFormCascader>
</ProForm.Item>
);
};
useEffect(() => {
setTimeout(() => {
setLoading(false);
@@ -94,6 +105,7 @@ const UserSetting: FunctionComponent = () => {
style={{ maxWidth: 600 }}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
initialValues={{ prefix: "https://" }}
autoComplete="off">
<Form.Item<FieldType>
label="邮箱"
@@ -138,11 +150,7 @@ const UserSetting: FunctionComponent = () => {
label="地区"
name="location"
rules={[{ required: true, message: "请输入地区!" }]}>
<ProFormCascader
request={async () => city}
width="md"
name="location"
disabled={disable}></ProFormCascader>
<ProFormText />
</Form.Item>
<Form.Item<FieldType> label="公司" name="company">
<Input allowClear disabled={disable} />

View File

@@ -1,12 +1,12 @@
/** @format */
import { SmileFilled } from "@ant-design/icons";
import dashboard from "@/assets/icons/dashboard.svg";
import bucket from "@/assets/icons/bucket.svg";
import file from "@/assets/icons/file.svg";
import share from "@/assets/icons/share.svg";
import user from "@/assets/icons/user.svg";
import userInfo from "@/assets/icons/userInfo.svg";
import setting from "@/assets/icons/setting.svg";
export default {
route: {
@@ -47,7 +47,7 @@ export default {
{
path: "main/user/setting",
name: "用户设置",
icon: <SmileFilled />,
icon: setting,
},
],
},

View File

@@ -1,7 +1,12 @@
/** @format */
import { GithubFilled, InfoCircleFilled, QuestionCircleFilled } from "@ant-design/icons";
import { PageContainer, ProCard, ProLayout } from "@ant-design/pro-components";
import {
DefaultFooter,
PageContainer,
ProCard,
ProLayout,
} from "@ant-design/pro-components";
import defaultProps from "./defaultSettings.tsx";
import { Link, Outlet, useLocation } from "react-router-dom";
import logo from "@/assets/images/logo.png";
@@ -19,7 +24,12 @@ export default function Layout() {
logo={logo}
layout={"mix"}
// contentWidth={"Fluid"}
menu={{ defaultOpenAll: false, hideMenuWhenCollapsed: false }}
menu={{
defaultOpenAll: false,
hideMenuWhenCollapsed: false,
type: "group",
collapsedShowTitle: true,
}}
title={"五味子云存储"}
siderWidth={216}
menuItemRender={(menuItemProps, defaultDom) => {
@@ -45,8 +55,27 @@ export default function Layout() {
<QuestionCircleFilled key="QuestionCircleFilled" />,
<GithubFilled key="GithubFilled" />,
];
}}>
<PageContainer>
}}
breadcrumbRender={(routers = []) => [
{
path: "/main/home",
title: "主页",
},
...routers,
]}
footerRender={() => (
<DefaultFooter
links={[
{
key: "schisandra",
title: "schisandra",
href: "https://landaiqing.cn",
},
]}
copyright="2024"
/>
)}>
<PageContainer title={false}>
<ProCard>
<div>
<Suspense>