feat: app detail
199
client/src/components/Charts/Line.tsx
Normal file
@@ -0,0 +1,199 @@
|
||||
import React, { useEffect, useMemo, useRef } from 'react';
|
||||
import * as echarts from 'echarts';
|
||||
import { useGlobalStore } from '@/store/global';
|
||||
|
||||
const LineChart = ({
|
||||
type,
|
||||
limit = 1000000,
|
||||
data
|
||||
}: {
|
||||
type: 'blue' | 'deepBlue' | 'green' | 'purple';
|
||||
limit: number;
|
||||
data: number[];
|
||||
}) => {
|
||||
const { screenWidth } = useGlobalStore();
|
||||
|
||||
const Dom = useRef<HTMLDivElement>(null);
|
||||
const myChart = useRef<echarts.ECharts>();
|
||||
|
||||
const map = {
|
||||
blue: {
|
||||
backgroundColor: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(3, 190, 232, 0.42)' // 0% 处的颜色
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(0, 182, 240, 0)'
|
||||
}
|
||||
],
|
||||
global: false // 缺省为 false
|
||||
},
|
||||
lineColor: '#36ADEF'
|
||||
},
|
||||
deepBlue: {
|
||||
backgroundColor: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(47, 112, 237, 0.42)' // 0% 处的颜色
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(94, 159, 235, 0)'
|
||||
}
|
||||
],
|
||||
global: false
|
||||
},
|
||||
lineColor: '#3293EC'
|
||||
},
|
||||
purple: {
|
||||
backgroundColor: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(211, 190, 255, 0.42)' // 0% 处的颜色
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(52, 60, 255, 0)'
|
||||
}
|
||||
],
|
||||
global: false // 缺省为 false
|
||||
},
|
||||
lineColor: '#8172D8'
|
||||
},
|
||||
green: {
|
||||
backgroundColor: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(4, 209, 148, 0.42)' // 0% 处的颜色
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(19, 217, 181, 0)'
|
||||
}
|
||||
],
|
||||
global: false // 缺省为 false
|
||||
},
|
||||
lineColor: '#00A9A6',
|
||||
max: 100
|
||||
}
|
||||
};
|
||||
|
||||
const option = useMemo(
|
||||
() => ({
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
show: false,
|
||||
boundaryGap: false,
|
||||
data: data.map((_, i) => i)
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
boundaryGap: false,
|
||||
splitNumber: 2,
|
||||
max: 100,
|
||||
min: 0
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
bottom: 2
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'line'
|
||||
},
|
||||
formatter: (e: any[]) => `${e[0]?.value || 0}%`
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: new Array(data.length).fill(0),
|
||||
type: 'line',
|
||||
showSymbol: false,
|
||||
smooth: true,
|
||||
animationDuration: 300,
|
||||
animationEasingUpdate: 'linear',
|
||||
areaStyle: {
|
||||
color: map[type].backgroundColor
|
||||
},
|
||||
lineStyle: {
|
||||
width: '1',
|
||||
color: map[type].lineColor
|
||||
},
|
||||
itemStyle: {
|
||||
width: 1.5,
|
||||
color: map[type].lineColor
|
||||
},
|
||||
emphasis: {
|
||||
// highlight
|
||||
disabled: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}),
|
||||
[limit, type]
|
||||
);
|
||||
|
||||
// init chart
|
||||
useEffect(() => {
|
||||
if (!Dom.current || myChart?.current?.getOption()) return;
|
||||
myChart.current = echarts.init(Dom.current);
|
||||
myChart.current && myChart.current.setOption(option);
|
||||
}, [Dom]);
|
||||
|
||||
// data changed, update
|
||||
useEffect(() => {
|
||||
if (!myChart.current || !myChart?.current?.getOption()) return;
|
||||
|
||||
const uniData = data.map((item) => ((item / limit) * 100).toFixed(2));
|
||||
|
||||
const x = option.xAxis.data;
|
||||
option.xAxis.data = [...x.slice(1), x[x.length - 1] + 1];
|
||||
option.series[0].data = uniData;
|
||||
myChart.current.setOption(option);
|
||||
}, [data, limit]);
|
||||
|
||||
// limit changed, update
|
||||
useEffect(() => {
|
||||
if (!myChart.current || !myChart?.current?.getOption()) return;
|
||||
myChart.current.setOption(option);
|
||||
}, [limit, option, type]);
|
||||
|
||||
// resize chart
|
||||
useEffect(() => {
|
||||
if (!myChart.current || !myChart.current.getOption()) return;
|
||||
myChart.current.resize();
|
||||
}, [screenWidth]);
|
||||
|
||||
return <div ref={Dom} style={{ width: '100%', height: '100%' }} />;
|
||||
};
|
||||
|
||||
export default React.memo(LineChart);
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
@@ -1 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1688888958304" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2590" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667a424.96 424.96 0 0 1-198.144-48.725334l-183.04 47.658667a36.266667 36.266667 0 0 1-44.245333-44.202667l47.616-182.997333A424.917333 424.917333 0 0 1 85.333333 512C85.333333 276.352 276.352 85.333333 512 85.333333z m53.418667 469.333334H373.333333l-4.352 0.298666a32 32 0 0 0 0 63.402667l4.352 0.298667h192.085334l4.309333-0.298667a32 32 0 0 0 0-63.402667L565.418667 554.666667z m85.248-149.333334h-277.333334l-4.352 0.298667a32 32 0 0 0 0 63.402667L373.333333 469.333333h277.333334l4.352-0.298666a32 32 0 0 0 0-63.402667L650.666667 405.333333z" p-id="2591"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1689170427347" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1982" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M512 26.54814777c268.11505778 0 485.45185223 217.33679445 485.45185223 485.45185223s-217.33679445 485.45185223-485.45185223 485.45185223a483.51004445 483.51004445 0 0 1-225.44384-55.43860224l-208.25884445 54.22497223a41.26340779 41.26340779 0 0 1-50.34135665-50.29281223l54.17642667-208.21029888A483.46149888 483.46149888 0 0 1 26.54814777 512C26.54814777 243.88494222 243.88494222 26.54814777 512 26.54814777z m60.77857223 533.9970378H354.22814777l-4.95160889 0.33981553a36.40888889 36.40888889 0 0 0 0 72.13814557l4.95160889 0.33981667h218.55042446l4.90306332-0.33981667a36.40888889 36.40888889 0 0 0 0-72.13814557L572.77857223 560.54518557z m96.99328-169.90814891h-315.54370446l-4.95160889 0.33981667a36.40888889 36.40888889 0 0 0 0 72.13814557L354.22814777 463.45481443h315.54370446l4.95160889-0.33981553a36.40888889 36.40888889 0 0 0 0-72.13814557L669.77185223 390.63703666z" p-id="1983"></path></svg>
|
Before Width: | Height: | Size: 1014 B After Width: | Height: | Size: 1.2 KiB |
@@ -1 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1688888938208" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2436" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667a424.96 424.96 0 0 1-195.712-47.445334l-163.242667 45.525334a53.333333 53.333333 0 0 1-65.706666-65.706667l45.568-163.114667A424.96 424.96 0 0 1 85.333333 512C85.333333 276.352 276.352 85.333333 512 85.333333z m0 64A362.666667 362.666667 0 0 0 149.333333 512c0 62.72 15.914667 123.008 45.781334 176.512l6.4 11.52-47.445334 169.984 170.112-47.445333 11.52 6.4A362.666667 362.666667 0 1 0 512 149.333333zM373.333333 554.666667h191.914667a32 32 0 0 1 4.352 63.701333l-4.352 0.298667H373.333333a32 32 0 0 1-4.352-63.701334L373.333333 554.666667h191.914667H373.333333z m0-149.333334h277.546667a32 32 0 0 1 4.309333 63.701334l-4.309333 0.298666H373.333333a32 32 0 0 1-4.352-63.701333L373.333333 405.333333h277.546667H373.333333z" p-id="2437"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1689170412707" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1828" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M512 26.54814777c268.11505778 0 485.45185223 217.33679445 485.45185223 485.45185223s-217.33679445 485.45185223-485.45185223 485.45185223a483.51004445 483.51004445 0 0 1-222.67676445-53.98224668l-185.73387889 51.79771335a60.6814811 60.6814811 0 0 1-74.75958443-74.75958557l51.84625778-185.58824334A483.51004445 483.51004445 0 0 1 26.54814777 512C26.54814777 243.88494222 243.88494222 26.54814777 512 26.54814777z m0 72.81777778A412.63407445 412.63407445 0 0 0 99.36592555 512c0 71.36142222 18.10735445 139.95576889 52.08898446 200.83143111l7.28177778 13.1072-53.98224669 193.40401778 193.54965333-53.98224555 13.1072 7.28177778A412.63407445 412.63407445 0 1 0 512 99.36592555zM354.22814777 560.54518557h218.35624334a36.40888889 36.40888889 0 0 1 4.95160889 72.4779611l-4.95160889 0.33981667H354.22814777a36.40888889 36.40888889 0 0 1-4.95160889-72.47796224L354.22814777 560.54518557h218.35624334H354.22814777z m0-169.90814891h315.78643001a36.40888889 36.40888889 0 0 1 4.90306332 72.47796224l-4.90306332 0.33981553H354.22814777a36.40888889 36.40888889 0 0 1-4.95160889-72.4779611L354.22814777 390.63703666h315.78643001H354.22814777z" p-id="1829"></path></svg>
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.5 KiB |
1
client/src/components/Icon/icons/light/fullScreen.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1689170193460" class="icon" viewBox="0 0 1027 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2859" data-spm-anchor-id="a313x.7781069.0.i1" xmlns:xlink="http://www.w3.org/1999/xlink" width="64.1875" height="64"><path d="M733.549304 0l116.434359 116.23452-226.402521 226.40252 57.053835 57.068109 226.459617-226.445342 120.616689 120.41685V0H733.549304zM689.513507 619.855586l-57.068108 57.068109 224.232847 224.232847-122.64362 122.843458h293.676657V729.838022l-114.007751 114.207588-224.190025-224.190024zM338.197775 404.144414l57.068109-57.068109L171.033037 122.843458 293.676657 0H0v294.161978l114.022025-114.207588 224.17575 224.190024zM347.076305 624.294851L120.616689 850.754468 0 730.323343v293.676657h294.161978l-116.420084-116.23452 226.40252-226.40252-57.068109-57.068109z" p-id="2860"></path></svg>
|
After Width: | Height: | Size: 965 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
@@ -1 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1688217440856" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2309" xmlns:xlink="http://www.w3.org/1999/xlink" ><path d="M819.823 83.694H206.991c-67.703 0-122.588 54.885-122.588 122.588v612.833c0 67.703 54.885 122.588 122.588 122.588h612.833c67.703 0 122.588-54.885 122.588-122.588V206.282c-0.001-67.703-54.885-122.588-122.589-122.588z m-124.435 63.313v241.142H331.772V147.007h363.616z m185.787 672.274c0.027 33.765-27.323 61.158-61.088 61.185H207.133c-16.389 0-31.864-6.297-43.454-17.887s-18.039-26.91-18.039-43.298v-612.94c0.061-33.923 27.57-61.395 61.493-61.41h61.327v245.294c-0.05 33.771 27.286 61.187 61.057 61.237h367.888c33.853 0 61.299-27.387 61.299-61.237V144.931h61.206c33.872 0.036 61.301 27.524 61.265 61.396V819.281z" fill="" p-id="2310"></path><path d="M574.817 329.936c17.483 0 31.656-14.173 31.656-31.656v-61.292c0-17.483-14.173-31.656-31.656-31.656s-31.656 14.173-31.656 31.656v61.292c0 17.483 14.173 31.656 31.656 31.656z" fill="" p-id="2311"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1689170210122" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3013" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M862.23416889 24.68295111H164.96753778c-77.03096889 0-139.47790222 62.44693333-139.47790223 139.47790222v697.26776889c0 77.03096889 62.44693333 139.47790222 139.47790223 139.47790223h697.26776889c77.03096889 0 139.47790222-62.44693333 139.47790222-139.47790223V164.16085333c-0.00113778-77.03096889-62.44693333-139.47790222-139.47904-139.47790222z m-141.57937778 72.03612444v274.3660089H306.94058667V96.71907555h413.71420444z m211.38432 764.89841778c0.03072 38.41706667-31.08750222 69.58421333-69.50456889 69.61493334H165.12910222c-18.64704 0-36.25415111-7.16458667-49.44099555-20.35143112s-20.52437333-30.6176-20.52437334-49.26350222v-697.38951111c0.06940445-38.59683555 31.36853333-69.85386667 69.96536889-69.87093333h69.77649778v279.09006222c-0.05688889 38.42389333 31.04540445 69.61720889 69.46929778 69.67409778h418.57479111c38.51719111 0 69.74464-31.16032 69.74464-69.67409778V94.35704889h69.63882666c38.53880889 0.04096 69.74691555 31.31619555 69.70595556 69.85500444V861.61749333z" p-id="3014"></path><path d="M583.47178667 304.85162667c19.89176889 0 36.01749333-16.12572445 36.01749333-36.01749334v-69.73667555c0-19.89176889-16.12572445-36.01749333-36.01749333-36.01749333s-36.01749333 16.12572445-36.01749334 36.01749333v69.73667555c0 19.89176889 16.12572445 36.01749333 36.01749334 36.01749334z" p-id="3015"></path></svg>
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.6 KiB |
@@ -3,7 +3,7 @@ import type { IconProps } from '@chakra-ui/react';
|
||||
import { Icon } from '@chakra-ui/react';
|
||||
|
||||
const map = {
|
||||
model: require('./icons/model.svg').default,
|
||||
app: require('./icons/app.svg').default,
|
||||
copy: require('./icons/copy.svg').default,
|
||||
chatSend: require('./icons/chatSend.svg').default,
|
||||
delete: require('./icons/delete.svg').default,
|
||||
@@ -16,7 +16,7 @@ const map = {
|
||||
backFill: require('./icons/fill/back.svg').default,
|
||||
more: require('./icons/more.svg').default,
|
||||
tabbarChat: require('./icons/phoneTabbar/chat.svg').default,
|
||||
tabbarModel: require('./icons/phoneTabbar/model.svg').default,
|
||||
tabbarModel: require('./icons/phoneTabbar/app.svg').default,
|
||||
tabbarMore: require('./icons/phoneTabbar/more.svg').default,
|
||||
tabbarMe: require('./icons/phoneTabbar/me.svg').default,
|
||||
closeSolid: require('./icons/closeSolid.svg').default,
|
||||
@@ -50,6 +50,7 @@ const map = {
|
||||
welcomeText: require('./icons/modules/welcomeText.svg').default,
|
||||
variable: require('./icons/modules/variable.svg').default,
|
||||
setTop: require('./icons/light/setTop.svg').default,
|
||||
fullScreenLight: require('./icons/light/fullScreen.svg').default,
|
||||
voice: require('./icons/voice.svg').default
|
||||
};
|
||||
|
||||
|
@@ -16,21 +16,21 @@ export enum NavbarTypeEnum {
|
||||
|
||||
const Navbar = ({ unread }: { unread: number }) => {
|
||||
const router = useRouter();
|
||||
const { userInfo, lastModelId } = useUserStore();
|
||||
const { lastChatAppId, lastChatId } = useChatStore();
|
||||
const { userInfo } = useUserStore();
|
||||
const { lastChatAppId, lastHistoryId } = useChatStore();
|
||||
const navbarList = useMemo(
|
||||
() => [
|
||||
{
|
||||
label: '聊天',
|
||||
icon: 'chatLight',
|
||||
activeIcon: 'chatFill',
|
||||
link: `/chat?appId=${lastChatAppId}&chatId=${lastChatId}`,
|
||||
link: `/chat?appId=${lastChatAppId}&historyId=${lastHistoryId}`,
|
||||
activeLink: ['/chat']
|
||||
},
|
||||
{
|
||||
label: '应用',
|
||||
icon: 'tabbarModel',
|
||||
activeIcon: 'model',
|
||||
activeIcon: 'app',
|
||||
link: `/app/list`,
|
||||
activeLink: ['/app/list', '/app/detail']
|
||||
},
|
||||
@@ -56,7 +56,7 @@ const Navbar = ({ unread }: { unread: number }) => {
|
||||
activeLink: ['/number']
|
||||
}
|
||||
],
|
||||
[lastChatId, lastChatAppId]
|
||||
[lastHistoryId, lastChatAppId]
|
||||
);
|
||||
|
||||
const itemStyles: any = {
|
||||
@@ -99,10 +99,8 @@ const Navbar = ({ unread }: { unread: number }) => {
|
||||
{/* 导航列表 */}
|
||||
<Box flex={1}>
|
||||
{navbarList.map((item) => (
|
||||
<Link
|
||||
<Box
|
||||
key={item.link}
|
||||
as={NextLink}
|
||||
href={item.link}
|
||||
{...itemStyles}
|
||||
{...(item.activeLink.includes(router.pathname)
|
||||
? {
|
||||
@@ -114,6 +112,7 @@ const Navbar = ({ unread }: { unread: number }) => {
|
||||
color: 'myGray.500',
|
||||
backgroundColor: 'transparent'
|
||||
})}
|
||||
onClick={() => router.push(item.link)}
|
||||
>
|
||||
<MyIcon
|
||||
name={
|
||||
@@ -127,7 +126,7 @@ const Navbar = ({ unread }: { unread: number }) => {
|
||||
<Box fontSize={'12px'} transform={'scale(0.9)'} mt={'5px'} lineHeight={1}>
|
||||
{item.label}
|
||||
</Box>
|
||||
</Link>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
{unread > 0 && (
|
||||
|
@@ -7,13 +7,13 @@ import Badge from '../Badge';
|
||||
|
||||
const NavbarPhone = ({ unread }: { unread: number }) => {
|
||||
const router = useRouter();
|
||||
const { lastChatAppId, lastChatId } = useChatStore();
|
||||
const { lastChatAppId, lastHistoryId } = useChatStore();
|
||||
const navbarList = useMemo(
|
||||
() => [
|
||||
{
|
||||
label: '聊天',
|
||||
icon: 'tabbarChat',
|
||||
link: `/chat?appId=${lastChatAppId}&chatId=${lastChatId}`,
|
||||
link: `/chat?appId=${lastChatAppId}&historyId=${lastHistoryId}`,
|
||||
activeLink: ['/chat'],
|
||||
unread: 0
|
||||
},
|
||||
@@ -39,7 +39,7 @@ const NavbarPhone = ({ unread }: { unread: number }) => {
|
||||
unread
|
||||
}
|
||||
],
|
||||
[lastChatId, lastChatAppId, unread]
|
||||
[lastHistoryId, lastChatAppId, unread]
|
||||
);
|
||||
|
||||
return (
|
||||
|