提交 3e9e786e 编写于 作者: I InsCode

Fri Jan 3 11:48:47 CST 2025 inscode

上级 669eac6d
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
package-lock.json
# Editor directories and files
.idea
.vscode/*
!.vscode/preview.yml
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
run = "npm i && npm run dev"
language = "node"
[env]
PATH = "/root/${PROJECT_DIR}/.config/npm/node_global/bin:/root/${PROJECT_DIR}/node_modules/.bin:${PATH}"
XDG_CONFIG_HOME = "/root/.config"
npm_config_prefix = "/root/${PROJECT_DIR}/.config/npm/node_global"
[debugger]
program = "main.js"
run = "npm i && npm run dev"
language = "node"
[deployment]
build = "npm i && npm run build"
run = "npm run preview"
[env]
PATH = "/root/${PROJECT_DIR}/.config/npm/node_global/bin:/root/${PROJECT_DIR}/node_modules/.bin:${PATH}"
XDG_CONFIG_HOME = "/root/.config"
npm_config_prefix = "/root/${PROJECT_DIR}/.config/npm/node_global"
[debugger]
program = "main.js"
\ No newline at end of file
{
"recommendations": ["Vue.volar"]
}
# Vue 3 + Vite
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
Learn more about IDE Support for Vue in the [Vue Docs Scaling up Guide](https://vuejs.org/guide/scaling-up/tooling.html#ide-support).
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="./src/assets/devui-logo.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>DevUI Admin</title>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
</head>
<body>
<div id="app" style="height: 100%;"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
console.log("欢迎来到 InsCode");
\ No newline at end of file
{ pkgs }: {
deps = [
pkgs.nodejs-18_x
pkgs.yarn
];
}
\ No newline at end of file
此差异已折叠。
{
"name": "nodejs",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@types/node": "^18.0.6",
"node-fetch": "^3.2.6"
}
}
\ No newline at end of file
{
"name": "mate-chat-template",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@devui-design/icons": "^1.4.0",
"@floating-ui/dom": "^1.6.12",
"@matechat/core": "^0.0.1-alpha",
"@microsoft/fetch-event-source": "^2.0.1",
"axios": "^1.7.9",
"clipboard-copy": "^4.0.1",
"devui-theme": "^0.0.7",
"echarts": "^5.6.0",
"highlight.js": "^11.11.0",
"lodash": "^4.17.21",
"markdown-it": "^14.1.0",
"openai": "^4.77.0",
"sass": "^1.83.0",
"vue": "^3.5.13",
"vue-devui": "^1.6.29",
"vue-i18n": "^11.0.0-beta.2",
"vue3-sfc-loader": "^0.9.5",
"vuedraggable": "^2.24.3"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.2.1",
"sass-embedded": "^1.83.0",
"vite": "^6.0.3"
}
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
\ No newline at end of file
<script setup>
import Page from './components/Page.vue';
import * as Vue from 'vue';
import * as echarts from 'echarts';
window.Vue = Vue;
window.echarts = echarts;
</script>
<template>
<Page/>
</template>
<style scoped>
</style>
<svg viewBox="0 0 26 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient x1="89.5364583%" y1="21.60078%" x2="7.57349918%" y2="65.7395747%" id="linearGradient-1">
<stop stop-color="#2954C8" offset="0%"></stop>
<stop stop-color="#5170FF" offset="100%"></stop>
</linearGradient>
<linearGradient x1="89.5364583%" y1="21.4573588%" x2="7.57349918%" y2="65.8190624%" id="linearGradient-2">
<stop stop-color="#2954C8" offset="0%"></stop>
<stop stop-color="#5170FF" offset="100%"></stop>
</linearGradient>
<linearGradient x1="-11.5260417%" y1="24.3907324%" x2="87.1145833%" y2="74.8850926%" id="linearGradient-3">
<stop stop-color="#89D2FF" offset="0%"></stop>
<stop stop-color="#5170FF" offset="100%"></stop>
</linearGradient>
<linearGradient x1="0%" y1="18.4813953%" x2="75.9513522%" y2="81.5186047%" id="linearGradient-4">
<stop stop-color="#89D2FF" offset="0%"></stop>
<stop stop-color="#5170FF" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Devui-Logo" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group-2" transform="translate(3.000000, 0.000000)">
<g>
<path
d="M4.28576801,9.22873192 L9.32098286,6.02205882 L13.1143389,8.49673203 L0.010890596,17.0193525 L0.010890596,17.0193525 C0.010890596,13.8625823 1.62310848,10.9244448 4.28576801,9.22873192 Z"
id="Path-39-Copy-3"
fill="url(#linearGradient-1)"
></path>
<path
d="M8.76945593,17.4828869 L14.1939212,14.0196078 L18.2867527,16.6963836 L4.14882163,25.9150327 L4.14882163,25.9150327 C4.14882163,22.4998846 5.89095741,19.3206798 8.76945593,17.4828869 Z"
id="Path-39-Copy-2"
fill="url(#linearGradient-2)"
transform="translate(11.217787, 19.967320) scale(-1, 1) translate(-11.217787, -19.967320) "
></path>
<path
d="M0.183304389,2.48689958e-13 L13.1143389,8.49673203 L9.42310099,10.9017055 L9.42310099,10.9017055 C4.36778167,11.0371959 0.159798979,7.04888649 0.0243085926,1.99356717 C0.00937841938,1.43650334 0.0453320846,0.879239543 0.13172203,0.32871271 L0.183304389,2.48689958e-13 Z"
id="Path-38-Copy-3"
fill="url(#linearGradient-3)"
></path>
<path
d="M4.54131151,6.55708742 L19.8945577,16.6535948 L16.2033199,19.0585682 L11.1830136,17.9470593 C6.34348625,16.8755752 3.2888836,12.0837536 4.36036765,7.24422626 C4.41158805,7.01288123 4.47194996,6.78365535 4.54131151,6.55708742 L4.54131151,6.55708742 Z"
id="Path-38-Copy-2"
fill="url(#linearGradient-4)"
transform="translate(12.021690, 12.807828) scale(-1, 1) translate(-12.021690, -12.807828) "
></path>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.27413 23.9492C5.35011 24.002 4.76293 22.9766 5.27617 22.2064L8.12463 17.9319C8.19666 17.8238 8.22896 17.6941 8.21604 17.5649L7.78881 13.2908C7.72637 12.666 8.18863 12.1116 8.81443 12.0606L19.7344 11.1714L13.845 23.5164L6.27413 23.9492V23.9492Z" fill="url(#paint0_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M27.562 22.7377C28.093 23.4959 27.5294 24.5347 26.6043 24.5031L21.4724 24.3273C21.3425 24.3229 21.2151 24.3637 21.112 24.4427L17.7033 27.0531C17.2048 27.4349 16.49 27.3334 16.1175 26.8279L9.61586 18.005L23.2107 16.5243L27.562 22.7377V22.7377Z" fill="url(#paint1_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.0849 4.87764C16.4883 4.0445 17.6701 4.0305 18.0932 4.85382L20.4401 9.42097C20.4994 9.53655 20.5971 9.62792 20.7163 9.67952L24.6567 11.3843C25.233 11.6336 25.4926 12.3073 25.2327 12.8789L20.6955 22.8555L12.7789 11.705L16.0849 4.87764V4.87764Z" fill="url(#paint2_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.0849 4.87764C16.4883 4.0445 17.6701 4.0305 18.0932 4.85382L20.4401 9.42097C20.4994 9.53655 20.5971 9.62792 20.7163 9.67952L24.6567 11.3843C25.233 11.6336 25.4926 12.3073 25.2327 12.8789L20.6955 22.8555L12.7789 11.705L16.0849 4.87764V4.87764Z" fill="url(#paint3_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.7344 11.1713L16.6931 17.2345L8.77569 17.7308C8.47445 17.7497 8.21224 17.5269 8.18223 17.2266L7.7888 13.2907C7.72635 12.666 8.18862 12.1115 8.81442 12.0605L19.7344 11.1713V11.1713Z" fill="url(#paint4_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.66794 15.9878C4.0491 15.9878 3.54742 16.4897 3.54742 17.1088C3.54742 17.7279 4.0491 18.2298 4.66794 18.2298C4.96882 18.2298 5.242 18.1112 5.4433 17.9181V17.9223L6.29747 17.0678H5.78772C5.76614 16.4677 5.27305 15.9878 4.66794 15.9878Z" fill="url(#paint5_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.7432 7.31465C24.0528 6.7786 23.8693 6.0931 23.3334 5.78355C22.7975 5.474 22.112 5.65761 21.8024 6.19366C21.653 6.45236 21.6184 6.74588 21.6828 7.01515L21.679 7.01293L21.9914 8.18009L22.2441 7.74253C22.775 8.02692 23.4397 7.84011 23.7432 7.31465Z" fill="url(#paint6_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.6784 28.0533C21.988 28.5894 22.6734 28.773 23.2094 28.4634C23.7453 28.1539 23.9288 27.4684 23.6191 26.9323C23.4686 26.6716 23.2291 26.4943 22.9611 26.4165L22.9633 26.4153L21.7962 26.1026L22.0513 26.5444C21.5439 26.8636 21.3759 27.5297 21.6784 28.0533Z" fill="url(#paint7_linear_0_201)"/>
<defs>
<linearGradient id="paint0_linear_0_201" x1="19.7344" y1="11.1714" x2="4.0293" y2="11.1714" gradientUnits="userSpaceOnUse">
<stop stop-color="#3EB9FC"/>
<stop offset="1" stop-color="#3AE5F6"/>
</linearGradient>
<linearGradient id="paint1_linear_0_201" x1="27.0039" y1="23.0876" x2="19.7513" y2="11.6611" gradientUnits="userSpaceOnUse">
<stop stop-color="#3CB2FD"/>
<stop offset="1" stop-color="#2170F3"/>
</linearGradient>
<linearGradient id="paint2_linear_0_201" x1="28.3377" y1="9.12939" x2="17.0651" y2="2.85327" gradientUnits="userSpaceOnUse">
<stop stop-color="#50D3AB"/>
<stop offset="1" stop-color="#6DBFFF"/>
</linearGradient>
<linearGradient id="paint3_linear_0_201" x1="18.0504" y1="5.12277" x2="11.8945" y2="16.7948" gradientUnits="userSpaceOnUse">
<stop stop-color="#F280FF"/>
<stop offset="1" stop-color="#A723E4"/>
</linearGradient>
<linearGradient id="paint4_linear_0_201" x1="19.7344" y1="11.1713" x2="7.67511" y2="11.1713" gradientUnits="userSpaceOnUse">
<stop stop-color="#3EB9FC"/>
<stop offset="1" stop-color="#3AE5F6"/>
</linearGradient>
<linearGradient id="paint5_linear_0_201" x1="3.54715" y1="15.9878" x2="3.54715" y2="18.2298" gradientUnits="userSpaceOnUse">
<stop stop-color="#3EB9FC"/>
<stop offset="1" stop-color="#3AE5F6"/>
</linearGradient>
<linearGradient id="paint6_linear_0_201" x1="21.3846" y1="7.34636" x2="23.0292" y2="8.26318" gradientUnits="userSpaceOnUse">
<stop stop-color="#F280FF"/>
<stop offset="1" stop-color="#A723E4"/>
</linearGradient>
<linearGradient id="paint7_linear_0_201" x1="22.611" y1="25.8261" x2="20.9466" y2="26.8049" gradientUnits="userSpaceOnUse">
<stop stop-color="#3CB2FD"/>
<stop offset="1" stop-color="#2170F3"/>
</linearGradient>
</defs>
</svg>
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.5483 47.8994C10.7002 48.005 9.52586 45.9542 10.5523 44.4138L16.2493 35.8647C16.3933 35.6486 16.4579 35.3892 16.4321 35.1308L15.5776 26.5826C15.4527 25.333 16.3773 24.2241 17.6289 24.1222L39.4688 22.3438L27.6899 47.0337L12.5483 47.8994V47.8994Z" fill="url(#paint0_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M55.124 45.4762C56.1859 46.9926 55.0588 49.0703 53.2086 49.007L42.9447 48.6555C42.685 48.6467 42.4303 48.7282 42.224 48.8862L35.4066 54.1071C34.4095 54.8707 32.98 54.6676 32.235 53.6566L19.2317 36.0109L46.4213 33.0494L55.124 45.4762V45.4762Z" fill="url(#paint1_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M32.1698 9.75638C32.9767 8.0901 35.3402 8.06209 36.1864 9.70873L40.8801 18.843C40.9989 19.0742 41.1942 19.2569 41.4327 19.3601L49.3134 22.7697C50.466 23.2684 50.9852 24.6157 50.4653 25.7589L41.3911 45.7121L25.5578 23.411L32.1698 9.75638V9.75638Z" fill="url(#paint2_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M32.1698 9.75638C32.9767 8.0901 35.3402 8.06209 36.1864 9.70873L40.8801 18.843C40.9989 19.0742 41.1942 19.2569 41.4327 19.3601L49.3134 22.7697C50.466 23.2684 50.9852 24.6157 50.4653 25.7589L41.3911 45.7121L25.5578 23.411L32.1698 9.75638V9.75638Z" fill="url(#paint3_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M39.4687 22.3438L33.3862 34.4701L17.5514 35.4628C16.9489 35.5006 16.4245 35.055 16.3645 34.4543L15.5776 26.5826C15.4527 25.333 16.3772 24.2241 17.6288 24.1222L39.4687 22.3438V22.3438Z" fill="url(#paint4_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.33589 31.9765C8.0982 31.9765 7.09485 32.9802 7.09485 34.2185C7.09485 35.4567 8.0982 36.4604 9.33589 36.4604C9.93765 36.4604 10.484 36.2232 10.8866 35.837V35.8456L12.5949 34.1365H11.5755C11.5323 32.9362 10.5461 31.9765 9.33589 31.9765Z" fill="url(#paint5_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M47.4867 14.6305C48.1059 13.5584 47.739 12.1874 46.6671 11.5683C45.5952 10.9492 44.2243 11.3164 43.6051 12.3885C43.3062 12.9059 43.2371 13.4929 43.366 14.0314L43.358 14.0268L43.9828 16.3611L44.4882 15.4861C45.5502 16.0551 46.8796 15.6815 47.4867 14.6305Z" fill="url(#paint6_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M43.3568 56.1077C43.976 57.1798 45.347 57.547 46.4188 56.9279C47.4907 56.3088 47.8576 54.9378 47.2384 53.8657C46.9372 53.3442 46.4582 52.9895 45.9222 52.834L45.9265 52.8315L43.5923 52.2062L44.1027 53.0899C43.0879 53.7282 42.752 55.0605 43.3568 56.1077Z" fill="url(#paint7_linear_0_201)"/>
<defs>
<linearGradient id="paint0_linear_0_201" x1="39.4688" y1="22.3438" x2="8.05859" y2="22.3438" gradientUnits="userSpaceOnUse">
<stop stop-color="#3EB9FC"/>
<stop offset="1" stop-color="#3AE5F6"/>
</linearGradient>
<linearGradient id="paint1_linear_0_201" x1="54.0079" y1="46.1761" x2="39.5026" y2="23.3232" gradientUnits="userSpaceOnUse">
<stop stop-color="#3CB2FD"/>
<stop offset="1" stop-color="#2170F3"/>
</linearGradient>
<linearGradient id="paint2_linear_0_201" x1="56.6755" y1="18.2599" x2="34.1303" y2="5.70763" gradientUnits="userSpaceOnUse">
<stop stop-color="#50D3AB"/>
<stop offset="1" stop-color="#6DBFFF"/>
</linearGradient>
<linearGradient id="paint3_linear_0_201" x1="36.1009" y1="10.2466" x2="23.789" y2="33.5907" gradientUnits="userSpaceOnUse">
<stop stop-color="#F280FF"/>
<stop offset="1" stop-color="#A723E4"/>
</linearGradient>
<linearGradient id="paint4_linear_0_201" x1="39.4687" y1="22.3437" x2="15.3502" y2="22.3437" gradientUnits="userSpaceOnUse">
<stop stop-color="#3EB9FC"/>
<stop offset="1" stop-color="#3AE5F6"/>
</linearGradient>
<linearGradient id="paint5_linear_0_201" x1="7.0949" y1="31.9764" x2="7.0949" y2="36.4604" gradientUnits="userSpaceOnUse">
<stop stop-color="#3EB9FC"/>
<stop offset="1" stop-color="#3AE5F6"/>
</linearGradient>
<linearGradient id="paint6_linear_0_201" x1="42.7688" y1="14.6941" x2="46.058" y2="16.5277" gradientUnits="userSpaceOnUse">
<stop stop-color="#F280FF"/>
<stop offset="1" stop-color="#A723E4"/>
</linearGradient>
<linearGradient id="paint7_linear_0_201" x1="45.2215" y1="51.6527" x2="41.8927" y2="53.6102" gradientUnits="userSpaceOnUse">
<stop stop-color="#3CB2FD"/>
<stop offset="1" stop-color="#2170F3"/>
</linearGradient>
</defs>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
\ No newline at end of file
<template>
<svg width="56px" height="56px" viewBox="0 0 56 56" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>用户数量(UV)</title>
<defs>
<linearGradient x1="0%" y1="17.2335601%" x2="79.0455666%" y2="72.9606973%" id="linearGradient-1">
<stop stop-color="#FFD240" offset="0%"></stop>
<stop stop-color="#FA9841" offset="100%"></stop>
</linearGradient>
<linearGradient x1="50%" y1="19.2345794%" x2="77.0508104%" y2="71.7407152%" id="linearGradient-2">
<stop stop-color="#FF854A" offset="0%"></stop>
<stop stop-color="#FA8E5A" stop-opacity="0" offset="100%"></stop>
</linearGradient>
<filter x="-81.6%" y="-60.0%" width="263.1%" height="220.0%" filterUnits="objectBoundingBox" id="filter-3">
<feGaussianBlur stdDeviation="3.2" in="SourceGraphic"></feGaussianBlur>
</filter>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-4">
<stop stop-color="#FFFFFF" offset="0%"></stop>
<stop stop-color="#FFFFFF" stop-opacity="0" offset="100%"></stop>
</linearGradient>
<path
d="M23.3194685,22 C25.5882337,22 27.478256,23.7390716 27.6666667,26 L27.8796616,28.5559394 C27.9408146,29.2897754 27.3954973,29.9342413 26.6616612,29.9953943 C26.6248319,29.9984635 26.5878909,30 26.5509339,30 L17.4490661,30 C16.7126864,30 16.1157327,29.4030463 16.1157327,28.6666667 C16.1157327,28.6297097 16.1172693,28.5927687 16.1203384,28.5559394 L16.3333333,26 C16.521744,23.7390716 18.4117663,22 20.6805315,22 L23.3194685,22 Z M22,14 C24.209139,14 26,15.790861 26,18 C26,20.209139 24.209139,22 22,22 C19.790861,22 18,20.209139 18,18 C18,15.790861 19.790861,14 22,14 Z"
id="path-5"></path>
<filter x="-36.8%" y="-27.1%" width="173.6%" height="154.2%" filterUnits="objectBoundingBox" id="filter-6">
<feGaussianBlur stdDeviation="3.5" in="SourceAlpha" result="shadowBlurInner1"></feGaussianBlur>
<feOffset dx="0" dy="1" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
<feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1"
result="shadowInnerInner1"></feComposite>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.801981466 0" type="matrix"
in="shadowInnerInner1"></feColorMatrix>
</filter>
<path
d="M23.3194685,22 C23.5835058,22 23.8424134,22.0235542 24.094106,22.0687441 L24.3570597,22.3333333 L23.3330144,23.3573107 L23.3333333,26.6666667 C23.3333333,27.4030463 22.7363797,28 22,28 C21.2636203,28 20.6666667,27.4030463 20.6666667,26.6666667 L20.6660144,23.3563107 L19.6430144,22.3333333 L19.9068928,22.0685649 C20.1582716,22.023492 20.4168434,22 20.6805315,22 L23.3194685,22 Z"
id="path-7"></path>
<filter x="-74.2%" y="-41.7%" width="248.5%" height="216.7%" filterUnits="objectBoundingBox" id="filter-8">
<feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0.980392157 0 0 0 0 0.596078431 0 0 0 0 0.254901961 0 0 0 0.19630955 0"
type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
</defs>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="小卡片" transform="translate(-75.000000, -788.000000)">
<g id="编组-5备份-4" transform="translate(51.000000, 764.000000)">
<g id="编组" transform="translate(0.000000, 0.000000)">
<g id="用户数量(UV)" transform="translate(24.000000, 24.000000)">
<path
d="M28,56 C43.463973,56 56,43.463973 56,28 C56,12.536027 43.463973,0 28,0 C12.536027,0 0,12.536027 0,28 C0,43.463973 12.536027,56 28,56 Z"
id="Ellipse-1" fill="#FFF3DC"></path>
<g id="UV" transform="translate(12.000000, 12.000000)">
<rect id="矩形" opacity="0.200000003" x="0" y="0" width="32" height="32"></rect>
<path
d="M30,12 L30,25.7333333 C30,26.6169889 29.2836556,27.3333333 28.4,27.3333333 L3.6,27.3333333 C2.7163444,27.3333333 2,26.6169889 2,25.7333333 L2,12 L30,12 Z M10,18 L5.33333333,18 C4.9651435,18 4.66666667,18.2984768 4.66666667,18.6666667 C4.66666667,19.0348565 4.9651435,19.3333333 5.33333333,19.3333333 L5.33333333,19.3333333 L10,19.3333333 C10.3681898,19.3333333 10.6666667,19.0348565 10.6666667,18.6666667 C10.6666667,18.2984768 10.3681898,18 10,18 L10,18 Z M10,14.6666667 L5.33333333,14.6666667 C4.9651435,14.6666667 4.66666667,14.9651435 4.66666667,15.3333333 C4.66666667,15.7015232 4.9651435,16 5.33333333,16 L5.33333333,16 L10,16 C10.3681898,16 10.6666667,15.7015232 10.6666667,15.3333333 C10.6666667,14.9651435 10.3681898,14.6666667 10,14.6666667 L10,14.6666667 Z M28.4,4.66666667 C29.2836556,4.66666667 30,5.38301107 30,6.26666667 L30,10.6666667 L2,10.6666667 L2,6.26666667 C2,5.38301107 2.7163444,4.66666667 3.6,4.66666667 L28.4,4.66666667 Z M5,6.66666667 C4.44771525,6.66666667 4,7.11438192 4,7.66666667 C4,8.21895142 4.44771525,8.66666667 5,8.66666667 C5.55228475,8.66666667 6,8.21895142 6,7.66666667 C6,7.11438192 5.55228475,6.66666667 5,6.66666667 Z M9,6.66666667 C8.44771525,6.66666667 8,7.11438192 8,7.66666667 C8,8.21895142 8.44771525,8.66666667 9,8.66666667 C9.55228475,8.66666667 10,8.21895142 10,7.66666667 C10,7.11438192 9.55228475,6.66666667 9,6.66666667 Z M13,6.66666667 C12.4477153,6.66666667 12,7.11438192 12,7.66666667 C12,8.21895142 12.4477153,8.66666667 13,8.66666667 C13.5522847,8.66666667 14,8.21895142 14,7.66666667 C14,7.11438192 13.5522847,6.66666667 13,6.66666667 Z"
id="形状结合" fill="url(#linearGradient-1)" fill-rule="nonzero"></path>
<path
d="M20.6528018,20.6666667 C22.9215671,20.6666667 24.8115893,22.4057383 25,24.6666667 L25.2129949,27.222606 C25.2741479,27.9564421 24.7288306,28.600908 23.9949946,28.662061 C23.9581653,28.6651301 23.9212242,28.6666667 23.8842673,28.6666667 L14.7823994,28.6666667 C14.0460197,28.6666667 13.4490661,28.069713 13.4490661,27.3333333 C13.4490661,27.2963764 13.4506026,27.2594353 13.4536717,27.222606 L13.6666667,24.6666667 C13.8550774,22.4057383 15.7450996,20.6666667 18.0138649,20.6666667 L20.6528018,20.6666667 Z M19.3333333,12.6666667 C21.5424723,12.6666667 23.3333333,14.4575277 23.3333333,16.6666667 C23.3333333,18.8758057 21.5424723,20.6666667 19.3333333,20.6666667 C17.1241943,20.6666667 15.3333333,18.8758057 15.3333333,16.6666667 C15.3333333,14.4575277 17.1241943,12.6666667 19.3333333,12.6666667 Z"
id="形状结合" fill="url(#linearGradient-2)" filter="url(#filter-3)"></path>
<g id="形状结合" fill-rule="nonzero">
<use fill-opacity="0.3" fill="#FFBE80" xlink:href="#path-5"></use>
<use fill="black" fill-opacity="1" filter="url(#filter-6)" xlink:href="#path-5"></use>
<use stroke="url(#linearGradient-4)" stroke-width="0.666666667" xlink:href="#path-5"></use>
</g>
<g id="形状结合">
<use fill="black" fill-opacity="1" filter="url(#filter-8)" xlink:href="#path-7"></use>
<use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-7"></use>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>
</template>
<script>
</script>
<style scoped></style>
\ No newline at end of file
@import 'devui-theme/styles-var/devui-var.scss';
.content-card {
margin: 8px;
overflow: hidden;
background-color: $devui-base-bg;
border-radius: $devui-border-radius-card;
box-shadow: $devui-shadow-length-base $devui-light-shadow;
height: 400px;
transition: transform 0.3s, box-shadow 0.3s;
&:hover {
transform: translateY(-5px);
box-shadow: $devui-shadow-length-base $devui-shadow;
}
}
.content-card-sm {
margin: 8px;
overflow: hidden;
background-color: $devui-base-bg;
border-radius: $devui-border-radius-card;
box-shadow: $devui-shadow-length-base $devui-light-shadow;
height: 192px;
transition: transform 0.3s, box-shadow 0.3s;
&:hover {
transform: translateY(-5px);
box-shadow: $devui-shadow-length-base $devui-shadow;
}
}
.dark-card {
position: relative;
background-image: linear-gradient(-50deg, #242222, #555454);
border-radius: 16px;
box-shadow: $devui-shadow-length-base $devui-light-shadow;
padding: 20px;
overflow: hidden !important;
}
.grade-number {
display: inline-block;
font-size: 26px;
vertical-align: text-top;
background-image: linear-gradient(to right, $devui-yellow-20, $devui-yellow-80);
background-clip: text;
color: transparent;
font-weight: bold;
margin-right: 20px;
}
.radar-descript {
position: absolute;
top: 24%;
right: 16px;
width: 20%;
color: #ced1db;
padding-right: 16px;
font-size: 14px;
line-height: 22px;
&-title {
color: #ffffff;
line-height: 22px;
margin: 0 8px;
font-weight: bold;
}
}
.indicator-card {
padding: 24px;
background: $devui-base-bg;
display: flex;
border-radius: 16px;
width: 100%;
height: 100%;
.indicator-content {
display: flex;
flex-direction: column;
text-align: left;
flex: 1;
font-size: 12px;
.indicator-content-item {
margin-bottom: 4px;
padding: 4px 0;
}
}
.indicator-charts {
display: flex;
flex-direction: column;
justify-content: space-between;
flex: 1;
}
}
.trend-number {
line-height: 1em;
font-weight: 600;
color: $devui-text;
font-size: 24px;
}
.chart-card {
box-shadow: $devui-shadow-length-base $devui-light-shadow;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
padding: 20px;
position: relative;
background-color: $devui-base-bg;
.card-title {
font-size: 14px;
line-height: 22px;
font-weight: 700;
}
.card-subtitle {
font-size: 12px;
line-height: 18px;
margin-top: 4px;
color: $devui-aide-text-stress;
}
.card-content {
flex: 1;
margin-top: 12px;
}
}
\ No newline at end of file
<template>
<d-row class="docs-devui-row">
<d-col :span="8">
<div class="content-card dark-card">
<div style="display: flex; flex-direction: column; align-items: flex-start;">
<p style="color: #ced1db; font-weight: bold; font-size: 16px">性能评分</p>
<div class="grade-number">{{ 58 }}</div>
</div>
<div style="width: 100%; height: 90%;">
<d-chart ref="chart1" :option="useRadarOptions" style="width: 100%; height: 90%; "></d-chart>
<div class="radar-descript">
<span style="font-size: 40px"></span><br />
<span class="radar-descript-title">成功率</span>
<span>低于电商场景的通用指标SLA水平,建议从失败请求的业务日志中分析</span><br />
<span style="margin-top: 8px" class="radar-descript-title">异常数</span>
<span>建议分析微服务的调用关系,是否存在性能瓶颈</span><br />
<span style="font-size: 40px; float: right; margin-top: 20px"></span>
</div>
</div>
</div>
</d-col>
<d-col :span="16">
<d-row>
<d-col :span="6">
<div class="content-card-sm">
<div class="indicator-card">
<div class="indicator-content">
<div>
<AvatarSvg />
</div>
<div class="indicator-content-item">
用户数量
</div>
<div class="indicator-content-item trend-number">
95%
</div>
</div>
<div class="indicator-charts">
<p style="color: #babbc0">this week <span style="color: #66cb9f">+263</span></p>
<d-chart ref="chart2" :option="useSimpleBarOptions" style="width: 100%; height: 100px;"></d-chart>
</div>
</div>
</div>
</d-col>
<d-col :span="9">
<div class="content-card-sm">
<div class="indicator-card">
<div class="indicator-content">
<div class="indicator-content-item">
<AvatarSvg />
</div>
<div class="indicator-content-item">
增长趋势
</div>
<div class="indicator-content-item trend-number">
95%
</div>
</div>
<div class="indicator-charts" style="flex: 2;">
<p style="color: #babbc0">this week <span style="color: #66cb9f">+263</span></p>
<d-chart ref="chart3" :option="usesimpleLineOptions2" style="width: 100%; height: 100px;"></d-chart>
</div>
</div>
</div>
</d-col>
<d-col :span="9">
<div class="content-card-sm">
<div class="indicator-card">
<div class="indicator-content">
<div class="indicator-content-item">
<AvatarSvg />
</div>
<div class="indicator-content-item">
季度变化
</div>
<div class="indicator-content-item trend-number">
95%
</div>
</div>
<div class="indicator-charts" style="flex: 2;">
<p style="color: #babbc0">this week <span style="color: #66cb9f">+263</span></p>
<d-chart ref="chart4" :option="usesimpleBarOptions2" style="width: 100%; height: 100px;"></d-chart>
</div>
</div>
</div>
</d-col>
</d-row>
<d-row>
<d-col :span="6">
<div class="content-card-sm">
<div class="indicator-card">
<div class="indicator-content">
<div class="indicator-content-item">
<AvatarSvg />
</div>
<div class="indicator-content-item">
季度变化
</div>
<div class="indicator-content-item trend-number">
95%
</div>
</div>
<div class="indicator-charts" style="flex: 2;">
<p style="color: #babbc0">this week <span style="color: #66cb9f">+263</span></p>
<d-chart ref="chart5" :option="usesimpleBarOptions2" style="width: 100%; height: 100px;"></d-chart>
</div>
</div>
</div>
</d-col>
<d-col :span="9">
<div class="content-card-sm">
<div class="indicator-card">
<div class="indicator-content">
<div class="indicator-content-item">
<AvatarSvg />
</div>
<div class="indicator-content-item">
全年趋势
</div>
<div class="indicator-content-item trend-number">
95%
</div>
</div>
<div class="indicator-charts" style="flex: 2;">
<p style="color: #babbc0">this week <span style="color: #66cb9f">+263</span></p>
<d-chart ref="chart6" :option="usesimpleLineOptions2" style="width: 100%; height: 100px;"></d-chart>
</div>
</div>
</div>
</d-col>
<d-col :span="9">
<div class="content-card-sm">
<div class="indicator-card">
<div class="indicator-content">
<div class="indicator-content-item">
<AvatarSvg />
</div>
<div class="indicator-content-item">
年度变化
</div>
<div class="indicator-content-item trend-number">
70%
</div>
</div>
<div class="indicator-charts" style="flex: 2;">
<p style="color: #babbc0">this week <span style="color: #66cb9f">+263</span></p>
<d-chart ref="chart7" :option="usesimpleBarOptions2" style="width: 100%; height: 100px;"></d-chart>
</div>
</div>
</div>
</d-col>
</d-row>
</d-col>
</d-row>
<d-row class="docs-devui-row">
<d-col :span="8">
<div class="content-card">
<div class="chart-card">
<div class="card-title">告警统计</div>
<div class="card-subtitle">华南华北大区外数据正在建设中</div>
<div class="card-content">
<d-chart ref="chart8" :option="useBarOption" style="width: 100%; height: 300px;"></d-chart>
</div>
</div>
</div>
</d-col>
<d-col :span="8">
<div class="content-card">
<div class="chart-card">
<div class="card-title">地域数据</div>
<div class="card-subtitle">各地域响应数据统计</div>
<div class="card-content">
<d-chart ref="chart9" :option="usePieOption" style="width: 100%; height: 300px;"></d-chart>
</div>
</div>
</div>
</d-col>
<d-col :span="8">
<div class="content-card">
<div class="chart-card">
<div class="card-title">CPU负载</div>
<div class="card-subtitle">各地域响应数据统计</div>
<div class="card-content">
<d-chart ref="chart10" :option="usegGugeOption" style="width: 100%; height: 300px;"></d-chart>
</div>
</div>
</div>
</d-col>
</d-row>
<d-row class="docs-devui-row">
<d-col :span="8">
<div class="content-card">
<div class="chart-card">
<div class="card-title">问题统计</div>
<div class="card-subtitle">各类型问题统计</div>
<div class="card-content">
<d-chart ref="chart11" :option="useHorizontalOption" style="width: 100%; height: 300px;"></d-chart>
</div>
</div>
</div>
</d-col>
<d-col :span="8">
<div class="content-card">
<div class="chart-card">
<div class="card-title">本周变化</div>
<div class="card-subtitle">各类型问题统计</div>
<div class="card-content">
<d-chart ref="chart12" :option="useLineOption" style="width: 100%; height: 300px;"></d-chart>
</div>
</div>
</div>
</d-col>
<d-col :span="8">
<div class="content-card">
<div class="chart-card">
<div class="card-title">未来趋势</div>
<div class="card-subtitle">各类型问题统计</div>
<div class="card-content">
<d-chart ref="chart13" :option="usetrendLineOption" style="width: 100%; height: 300px;"></d-chart>
</div>
</div>
</div>
</d-col>
</d-row>
</template>
<script>
import AvatarSvg from './AvatarSvg.vue';
import { defineComponent, reactive, onMounted, onBeforeUnmount, ref } from 'vue'
import { barOption, gaugeOption, lineOption, horizontalOption, pieOption, radarOptions, simpleBarOptions, trendLineOption, simpleLineOptions2, simpleBarOptions2 } from './mockData.ts';
export default defineComponent({
components: {
AvatarSvg,
},
setup() {
const useRadarOptions = reactive({...radarOptions})
const useSimpleBarOptions = reactive({...simpleBarOptions})
const useBarOption = reactive({...barOption})
const usePieOption = reactive({...pieOption})
const usegGugeOption = reactive({...gaugeOption})
const useHorizontalOption = reactive({...horizontalOption})
const useLineOption = reactive({...lineOption})
const usetrendLineOption = reactive({...trendLineOption})
const usesimpleLineOptions2 = reactive({...simpleLineOptions2})
const usesimpleBarOptions2 = reactive({...simpleBarOptions2})
return {
useRadarOptions,useSimpleBarOptions,useBarOption,usePieOption,usegGugeOption,useHorizontalOption, useLineOption, usetrendLineOption,usesimpleLineOptions2,usesimpleBarOptions2
}
}
})
</script>
<style lang="scss" scoped>
@import './Content.scss';
</style>
\ No newline at end of file
<template>
<div class="da-footer">
<div class="da-footer-intro">
<span class="da-production-name"><a href="https://devui.design/admin-page/home" target="_blank">DevUI Admin</a></span>
<a
href="https://github.com/DevCloudFE/ng-devui-admin"
rel="noopener noreferrer"
target="_blank"
aria-label="Star DevCloudFE/ng-devui-admin on GitHub"
><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20px" height="20px">
<path
d="M10.9,2.1c-4.6,0.5-8.3,4.2-8.8,8.7c-0.6,5,2.5,9.3,6.9,10.7v-2.3c0,0-0.4,0.1-0.9,0.1c-1.4,0-2-1.2-2.1-1.9 c-0.1-0.4-0.3-0.7-0.6-1C5.1,16.3,5,16.3,5,16.2C5,16,5.3,16,5.4,16c0.6,0,1.1,0.7,1.3,1c0.5,0.8,1.1,1,1.4,1c0.4,0,0.7-0.1,0.9-0.2 c0.1-0.7,0.4-1.4,1-1.8c-2.3-0.5-4-1.8-4-4c0-1.1,0.5-2.2,1.2-3C7.1,8.8,7,8.3,7,7.6C7,7.2,7,6.6,7.3,6c0,0,1.4,0,2.8,1.3 C10.6,7.1,11.3,7,12,7s1.4,0.1,2,0.3C15.3,6,16.8,6,16.8,6C17,6.6,17,7.2,17,7.6c0,0.8-0.1,1.2-0.2,1.4c0.7,0.8,1.2,1.8,1.2,3 c0,2.2-1.7,3.5-4,4c0.6,0.5,1,1.4,1,2.3v3.3c4.1-1.3,7-5.1,7-9.5C22,6.1,16.9,1.4,10.9,2.1z"
/>
</svg>
</a>
<span class="da-organization">
<a href="https://devui.design/home" rel="noopener noreferrer" target="_blank" aria-label="Learn more about ng-devui">
DevUI Design
</a>
</span>
</div>
<div class="da-presented">DevUI Design 出品</div>
</div>
</template>
<style scoped lang="scss">
@import 'devui-theme/styles-var/devui-var.scss';
.da-footer {
font-size: 12px;
margin-top: 20px;
.da-footer-intro {
display: flex;
align-items: center;
justify-content: center;
.da-production-name {
a {
color: $devui-text-weak;
cursor: pointer;
transition: color 0.2s ease-in-out;
&:hover {
color: $devui-text;
}
}
}
.da-organization {
a {
color: $devui-text-weak;
cursor: pointer;
transition: color 0.2s ease-in-out;
&:hover {
color: $devui-text;
}
}
}
.da-homepage-active {
outline: none;
}
a {
display: flex;
align-items: center;
svg {
fill: $devui-text-weak;
margin: 0 20px;
transition: fill 0.2s ease-in-out;
&:hover {
fill: $devui-text;
}
}
}
}
.da-presented {
text-align: center;
color: $devui-text-weak;
padding-top: 12px;
}
}
</style>
\ No newline at end of file
<template>
<section class="header-container header">
<div class="left-nav">
</div>
<div class="right-nav">
<d-search id="search" v-model="search" icon-position="left" size="sm" :no-border="true"></d-search>
<d-button class="nav-drop-btn" icon="icon-project-nav" variant="text"></d-button>
<div class="theme">
<!-- MateChat抽屉 -->
<img :class="['opt', {'active': props.drawerOpen}]" @click="openDrawer()" src="../assets/logo.svg">
<div class="opt">
<d-icon name="dark" color="var(--devui-text)" @click="changeTheme()">
<template #suffix>
</template>
</d-icon>
</div>
<div style="display: flex; align-items: center; gap: 20px; margin-left: 20px; cursor: pointer; font-size: 14px;">
<i class="icon-helping"></i>
<d-badge :count="5" >
<i class="icon icon-notice"></i>
</d-badge>
<div style="display: flex; align-items: center; gap: 8px;">
<d-avatar :name="'admin'" :width="22" :height="22"></d-avatar>
<span>Admin</span>
</div>
</div>
</div>
</div>
</section>
</template>
<script setup lang="ts">
import { HtmlHTMLAttributes, onMounted, ref, defineProps } from 'vue';
import { themeServiceInstance } from '../main';
import { infinityTheme, galaxyTheme } from 'devui-theme';
const props = defineProps(['drawerOpen']);
const theme = ref('dark');
const emit = defineEmits(['openDrawer']);
const openDrawer = () => {
emit('openDrawer');
}
const search = ref('');
const changeTheme = () => {
const currentTheme = localStorage.getItem('theme');
if (currentTheme === 'infinity-theme' || !currentTheme) {
theme.value = 'light';
localStorage.setItem('theme', 'galaxy-theme');
themeServiceInstance?.applyTheme(galaxyTheme);
} else {
theme.value = 'dark';
localStorage.setItem('theme', 'infinity-theme');
themeServiceInstance?.applyTheme(infinityTheme);
}
}
onMounted(() => {
let currentTheme = localStorage.getItem('theme');
theme.value = (!currentTheme || currentTheme === 'infinity-theme') ? 'dark' : 'light ';
})
</script>
<style lang="scss" scoped>
@import 'devui-theme/styles-var/devui-var.scss';
.header {
z-index: 20;
display: flex;
justify-content: space-between;
align-items: center;
top: 0;
width: calc(100% - 240px);
height: 48px;
background-color: $devui-base-bg;
transition: 0.5s;
img {
height: 32px;
margin: 8px 20px;
cursor: pointer;
}
.left-nav {
display: flex;
align-items: center;
button {
display: none;
}
}
.right-nav {
display: flex;
align-items: center;
.nav-drop-btn {
display: none;
}
.nav-list {
margin-right: 24px;
& > a:not(:first-child) {
margin-left: 12px;
}
& > a {
text-decoration: none;
}
.nav-active {
color: $devui-link-active;
}
}
}
.theme {
display: flex;
margin-right: 20px;
align-items: center;
.opt {
padding: 5px;
cursor: pointer;
transition: 0.5s;
border-radius: 25%;
}
}
}
.active {
background: $devui-list-item-hover-bg;
box-shadow: var(--devui-shadow-length-base, 0 2px 6px 0) var(--devui-light-shadow, rgba(37, 43, 58, .12));
border-radius: $devui-border-radius-card;
}
</style>
<style>
.devui-drawer {
top: 49px;
}
</style>
\ No newline at end of file
<template>
<div class="demo-test">
<McHeader :logoImg="'/src/assets/logo.svg'" :title="'MateChat'">
<template #operationArea>
<div class="operations">
<i class="icon-close" @click="closeDrawer()"></i>
</div>
</template>
</McHeader>
<div v-if="startChat" ref="conversationRef" class="conversation-area">
<template v-for="(msg, idx) in messages" :key="idx">
<McBubble v-if="msg.from === 'user'" :content="msg.content" :align="'right'" :avatarConfig="msg.avatarConfig"></McBubble>
<McBubble v-else :loading="msg.loading ?? false" :avatarPosition="msg.avatarPosition" :avatarConfig="msg.avatarConfig">
<RenderMarkdown v-if="msg.type === 'common'" :content="msg.content"></RenderMarkdown>
<div :id="'demoChart'+idx"
draggable="true"
v-if="msg.type === 'card'"
@dragstart="ondragstart($event, msg)"
@dragover.prevent="ondragover($event)"
@dragleave.prevent="ondragleave($event)"
@drop.prevent="ondrop($event)"
:class="['content-card']"
>
<DemoCard :chartStr="msg.componentStr" :containerId="'demoChart'+idx"></DemoCard>
</div>
<template #bottom>
<div class="bubble-bottom-operations">
<i class="icon-copy-new"></i>
<i class="icon-like"></i>
<i class="icon-dislike"></i>
<i class="icon-switch" :title="msg.type === 'card' ? '切换为代码' : '切换为组件'" @click="changeType(msg, idx)"></i>
</div>
</template>
</McBubble>
</template>
</div>
<div v-else class="welcome-page">
<McIntroduction
class="intro"
logo-img="/src/assets/logo2x.svg"
title="MateChat"
sub-title="Hi,欢迎使用 MateChat"
:description="[
'MateChat 可以辅助研发人员编码、查询知识和相关作业信息、编写文档等。',
'作为AI模型,MateChat 提供的答案可能不总是确定或准确的,但您的反馈可以帮助 MateChat 做的更好。',
]"
></McIntroduction>
<!-- <McPrompt :list="introPrompt.list" :direction="'horizontal'" class="intro-prompt" @itemClick="onItemClick($event)"></McPrompt> -->
<div class="guess-question">
<div class="guess-title">
<div>猜你想问</div>
<div>
<i class="icon-recover"></i>
<span>换一批</span>
</div>
</div>
<div class="guess-content">
<span v-for="(item, index) in guessQuestions" :key="index" @click="onItemClick(item)">{{ item.label }}</span>
</div>
</div>
</div>
<div class="new-convo-button">
<div v-if="startChat" class="prompt-list">
<!-- <McPrompt
class="simple-prompt"
style="flex: 1"
:list="simplePrompt"
:direction="'horizontal'"
@itemClick="onItemClick($event)"
></McPrompt> -->
</div>
<div v-else class="agent-knowledge">
<d-dropdown :position="['top']" @toggle="(val) => (isAgentOpen = val)">
<div class="agent-wrapper">
<img src="../assets/logo.svg" />
<span>{{ selectedAgent.label }}</span>
<i class="icon-infrastructure"></i>
<i :class="['icon-chevron-down-2', { 'is-open': isAgentOpen }]"></i>
</div>
<template #menu>
<McList :data="agentList" @select="(val) => (selectedAgent = val)"></McList>
</template>
</d-dropdown>
<span class="agent-knowledge-dividing-line"></span>
<div class="knowledge-wrapper">
<i class="icon-operation-log"></i>
<span>添加知识</span>
</div>
</div>
<d-button icon="add" shape="circle" title="新建对话" size="sm" @click="onNewConvo" />
</div>
<div style="padding: 0 12px 12px 12px">
<McInput :value="inputValue" :maxLength="2000" @change="(e) => (inputValue = e)" @submit="onSubmit">
<template #extra>
<div class="input-foot-wrapper">
<div class="input-foot-left">
<span v-for="(item, index) in inputFootIcons" :key="index" @click="() => onInputIconClick(item)">
<i :class="item.icon"></i>
{{ item.text }}
</span>
<span class="input-foot-dividing-line"></span>
<span class="input-foot-maxlength">{{ inputValue.length }}/2000</span>
</div>
<div class="input-foot-right">
<d-button icon="op-clearup" shape="round" :disabled="!inputValue" @click="inputValue = ''">清空输入</d-button>
</div>
</div>
</template>
</McInput>
</div>
</div>
</template>
<script>
import { ref, defineComponent, nextTick, defineEmits, onMounted, onUnmounted, watch, onActivated, onDeactivated } from 'vue';
import { introPrompt, simplePrompt, mockAnswer, guessQuestions } from './mock.constant';
import DemoCard from './DemoCard/DemoCard.vue';
import RenderMarkdown from './RenderMarkdown.vue';
import { fetchEventSource } from '@microsoft/fetch-event-source';
import { apiKey, apiUrl } from '../../config';
export default defineComponent({
components: {
DemoCard, RenderMarkdown
},
emits: ['closeDrawer', 'chartStrChange'],
setup(props, { emit }) {
const inputValue = ref('');
const startChat = ref(false);
const conversationRef = ref();
const isAgentOpen = ref(false);
const agentList = ref([
{ label: 'MateChat', value: 'matechat', active: true },
{ label: 'InsCode', value: 'inscode' },
]);
const selectedAgent = ref(agentList.value[0]);
const aiModelAvatar = {
imgSrc: "/src/assets/logo.svg",
width: 32,
height: 32,
};
const customerAvatar = {
name: 'Me',
width: 32,
height: 32,
};
const inputFootIcons = [
{ icon: 'icon-at', text: '智能体' },
{ icon: 'icon-standard', text: '词库' },
{ icon: 'icon-add', text: '附件' },
];
const messages = ref([]);
onActivated(() => {
if (window.savedState) {
messages.value = window.savedState.messages;
inputValue.value = window.savedState.inputValue;
startChat.value = window.savedState.startChat;
nextTick(() => {
if (conversationRef.value) {
conversationRef.value.scrollTop = conversationRef.value.scrollHeight;
}
});
}
});
onDeactivated(() => {
window.savedState = {
messages: [...messages.value], // 深拷贝数组
inputValue: inputValue.value,
startChat: startChat.value,
scrollPosition: conversationRef.value?.scrollTop || 0
};
});
const onInputIconClick = (e) => {
if (e.icon === 'icon-at') {
inputValue.value += `@${selectedAgent.value.label}`;
}
};
const onSubmit = (e, answer = undefined, type = 'common') => {
inputValue.value = '';
if (!messages.value.length) {
startChat.value = true;
}
messages.value.push({
from: 'user',
content: e,
type,
avatarPosition: 'side-right',
avatarConfig: { ...customerAvatar },
});
nextTick(() => {
conversationRef.value?.scrollTo({
top: conversationRef.value.scrollHeight,
behavior: 'smooth',
});
});
if (answer) {
getMockAnswer(answer, type);
} else {
getAIAnswer(answer ?? e, type);
}
};
const getMockAnswer = (answer, type) => {
const aiAnswer = {
from: 'ai-model',
content: answer,
type,
avatarPosition: 'side-left',
avatarConfig: { ...aiModelAvatar },
loading: true,
}
messages.value.push(aiAnswer);
setTimeout(() => {
messages.value.at(-1).loading = false;
}, 1000);
}
const getAIAnswer = (content, type) => {
const aiAnswer = {
from: 'ai-model',
content: '',
type,
avatarPosition: 'side-left',
avatarConfig: { ...aiModelAvatar },
loading: true,
}
messages.value.push(aiAnswer);
const source = fetchEventSource(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
messages: [
{
role: 'user',
content
}
],
apikey: apiKey
}),
onopen: (response) => {
},
onmessage: (msg) => {
messages.value.at(-1).loading = false;
if (msg.data === '[DONE]') {
nextTick(() => {
conversationRef.value?.scrollTo({
top: conversationRef.value.scrollHeight,
behavior: 'smooth',
});
});
return;
};
const data = JSON.parse(msg.data);
const responseContent = data.choices[0].delta.content;
messages.value.at(-1).content += responseContent;
},
onerror: (err) => {
messages.value.at(-1).loading = false;
messages.value.at(-1).content = '请求失败';
throw err;
}
});
};
const onNewConvo = () => {
startChat.value = false;
messages.value = [];
};
const onItemClick = (item) => {
if (mockAnswer[item.value]) {
// 使用 mock 数据
onSubmit(item.label, mockAnswer[item.value]);
} else {
// 使用 AI 数据
onSubmit(item.label);
}
};
const closeDrawer = () => {
emit('closeDrawer')
};
// 拖动事件
const isDragging = ref(false);
const handleDragOver = (e) => {
e.preventDefault();
if (isDragging.value) {
e.dataTransfer.dropEffect = 'move';
}
};
const handleDrop = (e) => {
e.preventDefault();
isDragging.value = false;
};
// 添加全局事件监听
onMounted(() => {
document.addEventListener('dragover', handleDragOver);
document.addEventListener('drop', handleDrop);
});
// 清理事件监听
onUnmounted(() => {
document.removeEventListener('dragover', handleDragOver);
document.removeEventListener('drop', handleDrop);
});
const ondragstart = (e, msg) => {
e.target.style.backgroundColor = 'var(--devui-float-block-shadow)';
emit('closeDrawer');
emit('chartStrChange', msg.componentStr);
};
const ondragover = (e) => {
e.preventDefault();
if (isDragging.value) {
e.dataTransfer.dropEffect = 'move';
}
};
const ondragleave = (e) => {
};
const ondrop = (e) => {
isDragging.value = false;
};
const changeType = (msg, index) => {
msg.componentStr = copyContent(msg);
messages.value[index] = {
...msg,
type: msg.type === 'card' ? 'common' : 'card'
};
}
const copyContent = (message) => {
const componentRegex = /<template>[\s\S]*?<\/template>\s*<script[\s\S]*?<\/script>\s*(?:<style[\s\S]*?<\/style>)?/g;
const match = message.content.match(componentRegex);
return match ? match[0] : null;
}
return {
inputValue,
conversationRef,
inputFootIcons,
messages,
onSubmit,
introPrompt,
simplePrompt,
onNewConvo,
onItemClick,
startChat,
guessQuestions,
closeDrawer,
isDragging,
ondragstart,
ondragover,
ondragleave,
ondrop,
changeType,
isAgentOpen,
selectedAgent,
agentList,
onInputIconClick,
copyContent
};
},
});
</script>
<style scoped lang="scss">
.demo-test {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
gap: 8px;
.conversation-area,
.welcome-page {
flex: 1;
display: flex;
flex-direction: column;
overflow: auto;
padding: 0 12px;
}
.conversation-area {
gap: 8px;
}
.welcome-page {
gap: 24px;
justify-content: space-between;
.intro {
padding-top: 40px;
flex: 1;
}
}
.guess-question {
width: 100%;
padding: 16px 12px;
border-radius: var(--devui-border-radius-card);
background-color: var(--devui-gray-form-control-bg);
.guess-title {
display: flex;
justify-content: space-between;
align-items: center;
color: var(--devui-text);
margin-bottom: 12px;
& > div:first-child {
font-weight: 700;
font-size: var(--devui-font-size);
}
& > div:last-child {
font-size: var(--devui-font-size-sm);
cursor: pointer;
span {
margin-left: 4px;
}
}
}
.guess-content {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
span {
font-size: var(--devui-font-size-sm);
color: var(--devui-text);
padding: 4px 12px;
border-radius: var(--devui-border-radius-full);
background-color: var(--devui-gray-form-control-hover-bg);
cursor: pointer;
}
}
}
.bubble-bottom-operations {
margin-top: 8px;
i {
padding: 4px;
border-radius: 4px;
cursor: pointer;
&:hover {
background-color: var(--devui-icon-hover-bg);
}
}
}
.new-convo-button {
padding: 0 12px;
display: flex;
justify-content: flex-end;
align-items: center;
height: 39px;
gap: 4px;
}
.prompt-list {
display: flex;
flex: 1;
}
:deep(.simple-prompt .mc-list) {
justify-content: unset;
}
:deep(.intro-prompt .mc-list) {
justify-content: center;
.mc-list-item {
flex: 1;
}
}
.operations {
i {
padding: 4px;
border-radius: 4px;
cursor: pointer;
&:hover {
background: var(--devui-global-bg);
}
}
}
.agent-knowledge {
flex: 1;
display: flex;
align-items: center;
.agent-wrapper {
display: flex;
align-items: center;
padding: 4px 8px;
border-radius: var(--devui-border-radius-full);
background-color: var(--devui-area);
cursor: pointer;
img {
width: 16px;
height: 16px;
margin-right: 4px;
}
span {
font-size: var(--devui-font-size);
color: var(--devui-text);
margin-right: 8px;
}
i {
font-size: var(--devui-font-size);
color: var(--devui-text);
transition: transform 0.3s ease-in-out;
&:last-child {
margin-left: 4px;
}
}
.is-open {
transform: rotate(180deg);
}
}
.agent-knowledge-dividing-line {
width: 1px;
height: 14px;
margin: 0 12px;
background-color: var(--devui-line);
}
.knowledge-wrapper {
font-size: var(--devui-font-size);
color: var(--devui-text);
cursor: pointer;
span {
margin-left: 4px;
}
}
}
.input-foot-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
height: 100%;
margin-right: 8px;
.input-foot-left {
display: flex;
align-items: center;
gap: 8px;
span {
font-size: var(--devui-font-size-sm);
color: var(--devui-text);
cursor: pointer;
}
.input-foot-dividing-line {
width: 1px;
height: 14px;
background-color: var(--devui-line);
}
.input-foot-maxlength {
font-size: var(--devui-font-size-sm);
color: var(--devui-aide-text);
}
}
.input-foot-right {
& > *:not(:first-child) {
margin-left: 8px;
}
}
}
}
.content-card {
margin: 8px;
overflow: hidden;
background-color: var(--devui-base-bg);
border-radius: var(--devui-border-radius-card);
box-shadow: var(--devui-shadow-length-base) var(--devui-light-shadow);
height: 400px;
width: 400px;
transition: transform 0.3s, box-shadow 0.3s;
&.dragging {
opacity: 1 !important;
}
&:hover {
transform: translateY(-5px);
}
}
</style>
\ No newline at end of file
<template>
</template>
<script setup>
import { createApp, defineProps, watch, onBeforeUnmount } from "vue";
import { loadModule } from 'vue3-sfc-loader'
import * as echarts from 'echarts'
const processComponentString = (str) => {
return str.replace(/import.*from.*['"]echarts['"];?\n?/g, '');
};
const props = defineProps({
chartStr: {
type: String,
default: ''
},
containerId: {
type: String,
default: ''
}
})
let currentApp = null;
let currentStyle = null;
onBeforeUnmount(() => {
if (currentApp) {
currentApp.unmount();
currentApp = null;
}
if (currentStyle) {
currentStyle.remove();
currentStyle = null;
}
})
watch(
() => props.chartStr,
async (newVal) => {
if (newVal) {
try {
// 清理之前的实例
if (currentApp) {
currentApp.unmount();
currentApp = null;
}
const options = {
moduleCache: {
vue: Vue
},
getFile(url) {
if (url === 'file.vue') {
const processedStr = processComponentString(props.chartStr);
return Promise.resolve(processedStr)
}
},
addStyle(textContent) {
const style = document.createElement('style');
style.textContent = textContent;
document.head.appendChild(style);
return style;
},
handleModule: async (type, source, path, options) => {
if (type === '.vue') {
return Vue.defineComponent(source.default);
}
}
};
// 加载组件
const component = await loadModule('file.vue', options);
// 创建新实例
const app = createApp(component).use(echarts);
app.config.globalProperties.$echarts = echarts;
app.config.globalProperties.echarts = echarts;
app.mount(`#${props.containerId}`);
currentApp = app;
} catch (error) {
console.error('创建图表失败:', error);
}
}
},
{ immediate: true }
)
</script>
<style scoped>
#demoChart {
width: 100%;
height: 100%;
}
</style>
\ No newline at end of file
export const chartComponentStr = `
\`\`\`vue
<template>
<div ref="pieChart" class="pie-chart"></div>
</template>
<script>
export default {
name: 'PieChart',
props: {
data: {
type: Array,
default: () => [
{ value: 335, name: '直接访问' },
{ value: 310, name: '邮件营销' },
{ value: 234, name: '联盟广告' },
{ value: 135, name: '视频广告' },
{ value: 1548, name: '搜索引擎' }
]
}
},
data() {
return {
chart: null
}
},
mounted() {
this.initChart()
},
methods: {
initChart() {
// 使用全局的 echarts 对象
this.chart = echarts.init(this.$refs.pieChart)
const option = {
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {
orient: 'vertical',
left: 'left'
},
series: [
{
name: '访问来源',
type: 'pie',
radius: ['50%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: true,
position: 'outside'
},
labelLine: {
show: true
},
data: this.data
}
]
}
this.chart.setOption(option)
}
},
watch: {
data: {
handler(newValue) {
this.chart && this.chart.setOption({
series: [{ data: newValue }]
})
},
deep: true
}
},
beforeDestroy() {
if (this.chart) {
this.chart.dispose()
this.chart = null
}
}
}
<\/script>
<style scoped>
.pie-chart {
width: 100%;
height: 400px;
}
</style>
\`\`\`
`;
export const lineStr = `
\`\`\`vue
<template>
<div ref="lineChart" class="line-chart"></div>
</template>
<script>
export default {
name: 'LineChart',
props: {
data: {
type: Array,
default: () => [150, 230, 224, 218, 135, 147, 260]
},
xAxisData: {
type: Array,
default: () => ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
}
},
data() {
return {
chart: null
}
},
mounted() {
this.initChart()
},
methods: {
initChart() {
this.chart = echarts.init(this.$refs.lineChart)
const option = {
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(255, 255, 255, 0.9)',
borderColor: '#ccc',
borderWidth: 1,
textStyle: {
color: '#333'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: this.xAxisData,
axisLine: {
lineStyle: {
color: '#999'
}
}
},
yAxis: {
type: 'value',
axisLine: {
lineStyle: {
color: '#999'
}
},
splitLine: {
lineStyle: {
type: 'dashed'
}
}
},
series: [
{
name: '访问量',
type: 'line',
data: this.data,
smooth: true,
symbol: 'circle',
symbolSize: 8,
itemStyle: {
color: '#409EFF'
},
lineStyle: {
width: 3,
color: '#409EFF'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: 'rgba(64,158,255,0.3)'
},
{
offset: 1,
color: 'rgba(64,158,255,0.1)'
}
]
}
}
}
]
}
this.chart.setOption(option)
}
},
watch: {
data: {
handler(newValue) {
this.chart && this.chart.setOption({
series: [{ data: newValue }]
})
},
deep: true
}
},
beforeDestroy() {
if (this.chart) {
this.chart.dispose()
this.chart = null
}
}
}
<\/script>
<style scoped>
.line-chart {
width: 100%;
height: 400px;
}
</style>
\`\`\`
`;
export const rader = `
\`\`\`vue
<template>
<div class="radar-chart">
<h2>inscode演示</h2>
<div ref="chart" class="chart"></div>
</div>
</template>
<script>
import * as echarts from 'echarts';
export default {
name: 'RadarChart',
mounted() {
this.initChart();
},
methods: {
initChart() {
const chartDom = this.$refs.chart;
const myChart = echarts.init(chartDom);
const option = {
title: {
text: '雷达图示例'
},
tooltip: {},
radar: {
// 雷达图的指示器,用来指定雷达图中的多个变量
indicator: [
{ name: '销售', max: 100 },
{ name: '管理', max: 100 },
{ name: '信息技术', max: 100 },
{ name: '客服', max: 100 },
{ name: '研发', max: 100 },
{ name: '市场', max: 100 }
]
},
series: [
{
name: '预算 vs 开销',
type: 'radar',
data: [
{
value: [80, 90, 70, 85, 95, 88],
name: '预算'
},
{
value: [70, 82, 75, 80, 90, 85],
name: '开销'
}
]
}
]
};
myChart.setOption(option);
}
}
};
</script>
<style scoped>
.radar-chart {
width: 100%;
height: 400px;
text-align: center;
}
.chart {
width: 100%;
height: 100%;
}
</style>
\`\`\`
`
<template>
<div ref="markdownCardRef" class="mc-markdown-render" v-html="markedHtml"></div>
</template>
<script setup lang="ts">
import markdownit from 'markdown-it';
import hljs from 'highlight.js';
import { computed } from 'vue';
const props = defineProps({
content: {
type: String,
default: '',
},
});
const mdt = markdownit({
breaks: true,
linkify: true,
html: true,
highlight: (str, lang) => {
if (lang && hljs.getLanguage(lang)) {
try {
return hljs.highlight(str, { language: lang }).value;
} catch (_) {}
}
return '';
},
});
const markedHtml = computed(() => {
return mdt.render(props.content);
});
</script>
<style lang="scss" scoped>
.mc-markdown-render {
overflow-x: auto;
:deep(p) {
margin: 0 !important;
}
}
</style>
<template>
<div class="demo-test">
<McHeader :logoImg="'/src/assets/logo.svg'" :title="'MateChat'">
<template #operationArea>
<div class="operations">
<i class="icon-close" @click="closeDrawer()"></i>
</div>
</template>
</McHeader>
<div v-if="startChat" ref="conversationRef" class="conversation-area">
<template v-for="(msg, idx) in messages" :key="idx">
<McBubble v-if="msg.from === 'user'" :content="msg.content" :align="'right'" :avatarConfig="msg.avatarConfig"></McBubble>
<McBubble v-else :loading="msg.loading ?? false" :avatarPosition="msg.avatarPosition" :avatarConfig="msg.avatarConfig">
<RenderMarkdown v-if="msg.type === 'common'" :content="msg.content"></RenderMarkdown>
<div :id="'demoChart'+idx"
draggable="true"
v-if="msg.type === 'card'"
@dragstart="ondragstart($event, msg)"
@dragover.prevent="ondragover($event)"
@dragleave.prevent="ondragleave($event)"
@drop.prevent="ondrop($event)"
:class="['content-card']"
>
<DemoCard :chartStr="msg.componentStr" :containerId="'demoChart'+idx"></DemoCard>
</div>
<template #bottom>
</template>
</McBubble>
</template>
</div>
<div v-else class="welcome-page">
<McIntroduction
class="intro"
logo-img="/src/assets/logo2x.svg"
title="MateChat"
sub-title="Hi,欢迎使用 MateChat"
:description="[
'MateChat 可以辅助研发人员编码、查询知识和相关作业信息、编写文档等。',
'作为AI模型,MateChat 提供的答案可能不总是确定或准确的,但您的反馈可以帮助 MateChat 做的更好。',
]"
></McIntroduction>
</div>
<div style="padding: 0 12px 12px 12px">
<McInput :value="inputValue" :maxLength="2000" @change="(e) => (inputValue = e)" @submit="onSubmit">
<template #extra>
<div class="input-foot-wrapper">
<div class="input-foot-left">
<span class="input-foot-dividing-line"></span>
<span class="input-foot-maxlength">{{ inputValue.length }}/2000</span>
</div>
<div class="input-foot-right">
<d-button icon="op-clearup" shape="round" :disabled="!inputValue" @click="inputValue = ''">清空输入</d-button>
</div>
</div>
</template>
</McInput>
</div>
</div>
</template>
<script>
import { ref, defineComponent, nextTick, defineEmits, onMounted, onUnmounted, watch, onActivated, onDeactivated } from 'vue';
import { introPrompt, simplePrompt, mockAnswer, guessQuestions } from './mock.constant';
import DemoCard from './DemoCard/DemoCard.vue';
import RenderMarkdown from './RenderMarkdown.vue';
export default defineComponent({
components: {
DemoCard, RenderMarkdown
},
emits: ['closeDrawer', 'chartStrChange'],
setup(props, { emit }) {
onActivated(() => {
if (window.savedState) {
messages.value = window.savedState.messages;
inputValue.value = window.savedState.inputValue;
startChat.value = window.savedState.startChat;
chartStr.value = window.savedState.chartStr;
nextTick(() => {
if (conversationRef.value) {
conversationRef.value.scrollTop = conversationRef.value.scrollHeight;
}
});
}
});
onDeactivated(() => {
window.savedState = {
messages: [...messages.value],
inputValue: inputValue.value,
startChat: startChat.value,
chartStr: chartStr.value,
scrollPosition: conversationRef.value?.scrollTop || 0
};
});
const inputValue = ref('');
const startChat = ref(false);
const conversationRef = ref();
const isAgentOpen = ref(false);
const agentList = ref([
{ label: 'MateChat', value: 'matechat', active: true },
{ label: 'InsCode', value: 'inscode' },
]);
const selectedAgent = ref(agentList.value[0]);
const aiModelAvatar = {
imgSrc: "/src/assets/logo.svg",
width: 32,
height: 32,
};
const customerAvatar = {
name: 'Me',
width: 32,
height: 32,
};
const inputFootIcons = [
{ icon: 'icon-at', text: '智能体' },
{ icon: 'icon-standard', text: '词库' },
{ icon: 'icon-add', text: '附件' },
];
const messages = ref([]);
const chartStr = ref('');
const onSubmit = (e, answer = undefined, type = 'common') => {
inputValue.value = '';
if (!messages.value.length) {
startChat.value = true;
}
messages.value.push({
from: 'user',
content: e,
type,
avatarPosition: 'side-right',
avatarConfig: { ...customerAvatar },
});
nextTick(() => {
conversationRef.value?.scrollTo({
top: conversationRef.value.scrollHeight,
behavior: 'smooth',
});
});
getMockAnswer(e, 'common');
};
const getMockAnswer = (answer, type) => {
const aiAnswer = {
from: 'ai-model',
content: answer,
type,
avatarPosition: 'side-left',
avatarConfig: { ...aiModelAvatar },
loading: true,
}
messages.value.push(aiAnswer);
setTimeout(() => {
messages.value.at(-1).loading = false;
}, 1000);
}
const onNewConvo = () => {
startChat.value = false;
messages.value = [];
};
const onItemClick = (item) => {
if (mockAnswer[item.value]) {
// 使用 mock 数据
onSubmit(item.label, mockAnswer[item.value]);
} else {
// 使用 AI 数据
onSubmit(item.label);
}
};
const closeDrawer = () => {
emit('closeDrawer')
};
return {
inputValue,
conversationRef,
inputFootIcons,
messages,
onSubmit,
introPrompt,
simplePrompt,
onNewConvo,
onItemClick,
startChat,
guessQuestions,
closeDrawer,
ondragstart,
ondragover,
ondragleave,
ondrop,
isAgentOpen,
selectedAgent,
agentList,
};
},
});
</script>
<style scoped lang="scss">
.demo-test {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
gap: 8px;
.conversation-area,
.welcome-page {
flex: 1;
display: flex;
flex-direction: column;
overflow: auto;
padding: 0 12px;
}
.conversation-area {
gap: 8px;
}
.welcome-page {
gap: 24px;
justify-content: space-between;
.intro {
padding-top: 40px;
flex: 1;
}
}
.guess-question {
width: 100%;
padding: 16px 12px;
border-radius: var(--devui-border-radius-card);
background-color: var(--devui-gray-form-control-bg);
.guess-title {
display: flex;
justify-content: space-between;
align-items: center;
color: var(--devui-text);
margin-bottom: 12px;
& > div:first-child {
font-weight: 700;
font-size: var(--devui-font-size);
}
& > div:last-child {
font-size: var(--devui-font-size-sm);
cursor: pointer;
span {
margin-left: 4px;
}
}
}
.guess-content {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
span {
font-size: var(--devui-font-size-sm);
color: var(--devui-text);
padding: 4px 12px;
border-radius: var(--devui-border-radius-full);
background-color: var(--devui-gray-form-control-hover-bg);
cursor: pointer;
}
}
}
.bubble-bottom-operations {
margin-top: 8px;
i {
padding: 4px;
border-radius: 4px;
cursor: pointer;
&:hover {
background-color: var(--devui-icon-hover-bg);
}
}
}
.new-convo-button {
padding: 0 12px;
display: flex;
justify-content: flex-end;
align-items: center;
height: 39px;
gap: 4px;
}
:deep(.simple-prompt .mc-list) {
justify-content: unset;
}
:deep(.intro-prompt .mc-list) {
justify-content: center;
.mc-list-item {
flex: 1;
}
}
.operations {
i {
padding: 4px;
border-radius: 4px;
cursor: pointer;
&:hover {
background: var(--devui-global-bg);
}
}
}
.agent-knowledge {
flex: 1;
display: flex;
align-items: center;
.agent-wrapper {
display: flex;
align-items: center;
padding: 4px 8px;
border-radius: var(--devui-border-radius-full);
background-color: var(--devui-area);
cursor: pointer;
img {
width: 16px;
height: 16px;
margin-right: 4px;
}
span {
font-size: var(--devui-font-size);
color: var(--devui-text);
margin-right: 8px;
}
i {
font-size: var(--devui-font-size);
color: var(--devui-text);
transition: transform 0.3s ease-in-out;
&:last-child {
margin-left: 4px;
}
}
.is-open {
transform: rotate(180deg);
}
}
.agent-knowledge-dividing-line {
width: 1px;
height: 14px;
margin: 0 12px;
background-color: var(--devui-line);
}
.knowledge-wrapper {
font-size: var(--devui-font-size);
color: var(--devui-text);
cursor: pointer;
span {
margin-left: 4px;
}
}
}
.input-foot-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
height: 100%;
margin-right: 8px;
.input-foot-left {
display: flex;
align-items: center;
gap: 8px;
span {
font-size: var(--devui-font-size-sm);
color: var(--devui-text);
cursor: pointer;
}
.input-foot-dividing-line {
width: 1px;
height: 14px;
background-color: var(--devui-line);
}
.input-foot-maxlength {
font-size: var(--devui-font-size-sm);
color: var(--devui-aide-text);
}
}
.input-foot-right {
& > *:not(:first-child) {
margin-left: 8px;
}
}
}
}
.content-card {
margin: 8px;
overflow: hidden;
background-color: var(--devui-base-bg);
border-radius: var(--devui-border-radius-card);
box-shadow: var(--devui-shadow-length-base) var(--devui-light-shadow);
height: 400px;
width: 400px;
transition: transform 0.3s, box-shadow 0.3s;
&.dragging {
opacity: 1 !important;
}
&:hover {
transform: translateY(-5px);
}
}
</style>
\ No newline at end of file
以下是我可以为你做的一些事情:
1. **语言交流**:我可以用中文和英文与你进行流畅的对话。
2. **文件阅读**:你可以上传TXT、PDF、Word文档、PPT幻灯片、Excel电子表格等格式的文件,我可以阅读文件内容后回复你。
3. **网页内容解析**:你可以发送网址给我,我会先解析网页内容,然后结合这些内容回答你的问题。
4. **搜索能力**:当你的问题需要额外信息时,我可以利用搜索能力为你提供答案。
5. **数学计算**:我可以帮你进行数学计算和逻辑推理。
6. **编程帮助**:我可以帮助你理解和编写代码,包括但不限于JavaScript、Python等。
7. **信息整理**:我可以帮助整理和总结信息,让你更容易理解复杂的概念或数据。
8. **教育辅导**:我可以提供学习资料和解释,帮助你学习新知识。
9. **日常咨询**:我可以回答你的日常问题,比如天气、新闻等。
10. **保持幽默**:在提供帮助的同时,我也会尽量保持幽默感,让对话更有趣。
如果你有任何问题或需要帮助,随时告诉我!
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.5483 47.8994C10.7002 48.005 9.52586 45.9542 10.5523 44.4138L16.2493 35.8647C16.3933 35.6486 16.4579 35.3892 16.4321 35.1308L15.5776 26.5826C15.4527 25.333 16.3773 24.2241 17.6289 24.1222L39.4688 22.3438L27.6899 47.0337L12.5483 47.8994V47.8994Z" fill="url(#paint0_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M55.124 45.4762C56.1859 46.9926 55.0588 49.0703 53.2086 49.007L42.9447 48.6555C42.685 48.6467 42.4303 48.7282 42.224 48.8862L35.4066 54.1071C34.4095 54.8707 32.98 54.6676 32.235 53.6566L19.2317 36.0109L46.4213 33.0494L55.124 45.4762V45.4762Z" fill="url(#paint1_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M32.1698 9.75638C32.9767 8.0901 35.3402 8.06209 36.1864 9.70873L40.8801 18.843C40.9989 19.0742 41.1942 19.2569 41.4327 19.3601L49.3134 22.7697C50.466 23.2684 50.9852 24.6157 50.4653 25.7589L41.3911 45.7121L25.5578 23.411L32.1698 9.75638V9.75638Z" fill="url(#paint2_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M32.1698 9.75638C32.9767 8.0901 35.3402 8.06209 36.1864 9.70873L40.8801 18.843C40.9989 19.0742 41.1942 19.2569 41.4327 19.3601L49.3134 22.7697C50.466 23.2684 50.9852 24.6157 50.4653 25.7589L41.3911 45.7121L25.5578 23.411L32.1698 9.75638V9.75638Z" fill="url(#paint3_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M39.4687 22.3438L33.3862 34.4701L17.5514 35.4628C16.9489 35.5006 16.4245 35.055 16.3645 34.4543L15.5776 26.5826C15.4527 25.333 16.3772 24.2241 17.6288 24.1222L39.4687 22.3438V22.3438Z" fill="url(#paint4_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.33589 31.9765C8.0982 31.9765 7.09485 32.9802 7.09485 34.2185C7.09485 35.4567 8.0982 36.4604 9.33589 36.4604C9.93765 36.4604 10.484 36.2232 10.8866 35.837V35.8456L12.5949 34.1365H11.5755C11.5323 32.9362 10.5461 31.9765 9.33589 31.9765Z" fill="url(#paint5_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M47.4867 14.6305C48.1059 13.5584 47.739 12.1874 46.6671 11.5683C45.5952 10.9492 44.2243 11.3164 43.6051 12.3885C43.3062 12.9059 43.2371 13.4929 43.366 14.0314L43.358 14.0268L43.9828 16.3611L44.4882 15.4861C45.5502 16.0551 46.8796 15.6815 47.4867 14.6305Z" fill="url(#paint6_linear_0_201)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M43.3568 56.1077C43.976 57.1798 45.347 57.547 46.4188 56.9279C47.4907 56.3088 47.8576 54.9378 47.2384 53.8657C46.9372 53.3442 46.4582 52.9895 45.9222 52.834L45.9265 52.8315L43.5923 52.2062L44.1027 53.0899C43.0879 53.7282 42.752 55.0605 43.3568 56.1077Z" fill="url(#paint7_linear_0_201)"/>
<defs>
<linearGradient id="paint0_linear_0_201" x1="39.4688" y1="22.3438" x2="8.05859" y2="22.3438" gradientUnits="userSpaceOnUse">
<stop stop-color="#3EB9FC"/>
<stop offset="1" stop-color="#3AE5F6"/>
</linearGradient>
<linearGradient id="paint1_linear_0_201" x1="54.0079" y1="46.1761" x2="39.5026" y2="23.3232" gradientUnits="userSpaceOnUse">
<stop stop-color="#3CB2FD"/>
<stop offset="1" stop-color="#2170F3"/>
</linearGradient>
<linearGradient id="paint2_linear_0_201" x1="56.6755" y1="18.2599" x2="34.1303" y2="5.70763" gradientUnits="userSpaceOnUse">
<stop stop-color="#50D3AB"/>
<stop offset="1" stop-color="#6DBFFF"/>
</linearGradient>
<linearGradient id="paint3_linear_0_201" x1="36.1009" y1="10.2466" x2="23.789" y2="33.5907" gradientUnits="userSpaceOnUse">
<stop stop-color="#F280FF"/>
<stop offset="1" stop-color="#A723E4"/>
</linearGradient>
<linearGradient id="paint4_linear_0_201" x1="39.4687" y1="22.3437" x2="15.3502" y2="22.3437" gradientUnits="userSpaceOnUse">
<stop stop-color="#3EB9FC"/>
<stop offset="1" stop-color="#3AE5F6"/>
</linearGradient>
<linearGradient id="paint5_linear_0_201" x1="7.0949" y1="31.9764" x2="7.0949" y2="36.4604" gradientUnits="userSpaceOnUse">
<stop stop-color="#3EB9FC"/>
<stop offset="1" stop-color="#3AE5F6"/>
</linearGradient>
<linearGradient id="paint6_linear_0_201" x1="42.7688" y1="14.6941" x2="46.058" y2="16.5277" gradientUnits="userSpaceOnUse">
<stop stop-color="#F280FF"/>
<stop offset="1" stop-color="#A723E4"/>
</linearGradient>
<linearGradient id="paint7_linear_0_201" x1="45.2215" y1="51.6527" x2="41.8927" y2="53.6102" gradientUnits="userSpaceOnUse">
<stop stop-color="#3CB2FD"/>
<stop offset="1" stop-color="#2170F3"/>
</linearGradient>
</defs>
</svg>
import quickSortMd from './quicksort.md?raw';
import helpMd from './help.md?raw';
import { lineStr } from './DemoCard/MockCardData.ts'
export const introPrompt = {
direction: 'horizontal',
list: [
{
value: 'quickSort',
label: '帮我写一个快速排序',
iconConfig: { name: 'icon-info-o', color: '#5e7ce0' },
desc: '使用 js 快速实现一个可用的快速排序',
},
{
value: 'helpMd',
label: '你可以帮我做些什么?',
iconConfig: { name: 'icon-star', color: 'rgb(255, 215, 0)' },
desc: '了解当前大模型可以帮你做的事',
},
{
value: 'helpMd',
label: '你可以帮我做些什么?',
iconConfig: { name: 'icon-star', color: 'rgb(255, 215, 0)' },
desc: '了解当前大模型可以帮你做的事',
},
],
};
export const guessQuestions = [
{ label: '怎么绑定项目空间' },
{ label: '最近执行流水线列表' },
{ label: '帮我写一个快速排序' },
{ label: '使用 js 格式化时间' },
];
export const simplePrompt = [
{
value: 'quickSort',
iconConfig: { name: 'icon-info-o', color: '#5e7ce0' },
label: '帮我写一个快速排序',
},
{
value: 'lineChart',
iconConfig: { name: 'icon-star', color: 'rgb(255, 215, 0)' },
label: '帮我生成一个折线图',
},
];
export const mockAnswer = {
quickSort: quickSortMd,
helpMd: helpMd,
lineChart: lineStr
};
当然可以。快速排序(Quick Sort)是一种高效的排序算法,它采用分治法(Divide and Conquer)的思想。以下是使用JavaScript实现的快速排序算法:
```javascript
function quickSort(arr) {
if (arr.length < 2) {
return arr;
}
const pivot = arr[0];
const left = [];
const right = [];
for (let i = 1; i < arr.length; i++) {
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return [...quickSort(left), pivot, ...quickSort(right)];
}
// 使用示例
const arr = [3, 6, 8, 10, 1, 2, 1];
console.log(quickSort(arr)); // 输出排序后的数组
```
这个快速排序的实现使用了递归。它首先选择数组的第一个元素作为基准(pivot),然后将数组分为两部分:一部分包含所有小于基准的元素,另一部分包含所有大于或等于基准的元素。这个过程递归地对左右两部分进行,直到数组被分割成单个元素,然后合并排序后的子数组。
请注意,这个实现不是原地排序(in-place),因为它创建了新的数组来存储排序过程中的中间结果。如果你需要一个原地排序的版本,可以稍作修改来实现。
<template>
<d-layout style="height: 100%">
<d-aside class="daside">
<div class="sideLogo">
<img src="../assets/devui-logo.svg">
<span>DevUI Admin</span>
</div>
<d-menu style="height: 100%;" :collapsed-indent="48" mode="vertical" width="240px" :default-select-keys="['MateChat']">
<d-menu-item key="MateChat">
<template #icon>
<i class="icon-homepage"></i>
</template>
<span>MateChat 演示</span>
</d-menu-item>
</d-menu>
</d-aside>
<d-layout style="overflow: auto">
<d-header class="dheader">
<Header @openDrawer="openDrawer()" class="page-header" :drawerOpen="visible"></Header>
</d-header>
<d-content class="main-content">
<Content></Content>
<Footer></Footer>
</d-content>
</d-layout>
</d-layout>
<d-drawer v-model="visible" position="right" style="padding: 20px; width: 650px" :show-overlay="false" :close-on-click-overlay="false">
<keep-alive>
<Demo @closeDrawer="visible = false" @chartStrChange="chartStrChange($event)"/>
</keep-alive>
<!-- <SimpleDemo @closeDrawer="visible = false"/> -->
</d-drawer>
</template>
<script>
import { defineComponent, ref, onMounted, onUnmounted, createApp } from 'vue'
import Content from './Content.vue'
import Header from './Header.vue';
import Footer from './Footer.vue';
import Demo from './MateChat/Demo.vue';
import SimpleDemo from './MateChat/SimpleDemo.vue';
import { loadModule } from 'vue3-sfc-loader';
export default defineComponent({
components: {
Content, Header, Footer, Demo, SimpleDemo
},
setup() {
const openDrawer = () => {
visible.value = true;
}
const menu = ref([
{
title: 'Dashboard',
open: true,
children: [{ title: 'MateChat Demo' }],
},
])
const chartStr = ref('');
const visible = ref(false);
// 拖动事件监听
const isDragging = ref(false);
const position = ref({ x: 0, y: 0 });
const chartStrChange = (event) => {
chartStr.value = event;
}
const handleDragOver = (e) => {
e.preventDefault();
if (isDragging.value) {
position.value = {
x: e.clientX,
y: e.clientY
};
}
};
const handleDrop = (e) => {
e.preventDefault();
const randomId = `chart-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
// 获取拖动的数据
const draggedHTML = e.dataTransfer.getData('text/html');
// 获取放下位置的元素
const dropTarget = document.elementFromPoint(e.clientX, e.clientY);
const nearestContentCard = dropTarget?.closest('.devui-col');
if (nearestContentCard) {
// 创建新的元素
const newCard = document.createElement('div');
newCard.className = nearestContentCard.className;
// 使用拖动元素的内容
if (nearestContentCard.offsetHeight > 300) {
newCard.innerHTML = `<div class='content-card'><div class='chart-card'id='${randomId}'></div></div>`;
} else {
newCard.innerHTML = `<div class='content-card-sm'><div class='chart-card'id='${randomId}'></div></div>`;
}
// 将新元素插入到目标元素之前
nearestContentCard.parentNode.insertBefore(newCard, nearestContentCard);
nearestContentCard.remove();
}
isDragging.value = false;
createChart(randomId);
};
onMounted(() => {
document.addEventListener('dragover', handleDragOver);
document.addEventListener('drop', handleDrop);
});
onUnmounted(() => {
document.removeEventListener('dragover', handleDragOver);
document.removeEventListener('drop', handleDrop);
});
// 预处理组件字符串,移除 import 语句
const processComponentString = (str) => {
return str.replace(/import.*from.*['"]echarts['"];?\n?/g, '');
};
const createChart = async (id) => {
const options = {
moduleCache: {
vue: Vue
},
getFile(url) {
if (url === 'file.vue') {
const processedStr = processComponentString(chartStr.value);
return Promise.resolve(processedStr)
}
},
addStyle(textContent) {
const style = document.createElement('style');
style.textContent = textContent;
document.head.appendChild(style);
return style;
},
handleModule: async (type, source, path, options) => {
if (type === '.vue') {
return Vue.defineComponent(source.default);
}
}
};
// 加载组件
const component = await loadModule('file.vue', options);
// 创建新实例
const app = createApp(component);
app.config.globalProperties.$echarts = echarts;
app.config.globalProperties.echarts = echarts;
app.mount(`#${id}`);
}
return {
menu, openDrawer, visible, createChart, chartStrChange
}
}
})
</script>
<style lang="scss" scoped>
@import 'devui-theme/styles-var/devui-var.scss';
.floating-card {
position: fixed;
transform: translate(-50%, -50%);
pointer-events: none;
opacity: 1;
z-index: 9999;
}
.daside {
display: flex;
flex-direction: column;
z-index: 21;
background-color: $devui-base-bg;;
width: 240px;
min-height: 200px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: var(--devui-shadow-length-connected-overlay, 0 2px 12px 0) var(--devui-light-shadow, rgba(37, 43, 58, 0.12));
}
.dheader {
z-index: 20;
position: fixed;
width: calc(100%);
}
.dfooter {
text-align: center;
line-height: 40px;
min-height: 40px;
}
.main-content {
flex: 1;
margin-top: 60px;
text-align: center;
padding: 12px;
}
.page-header {
border-bottom: 1px solid $devui-dividing-line;
box-shadow: var(--devui-shadow-length-connected-overlay, 0 2px 4px) var(--devui-light-shadow, rgba(37, 43, 58, 0.12));
}
.sideLogo {
display: flex;
align-items: center;
cursor: pointer;
width: 100%;
height: 80px;
padding-left: 16px;
gap: 8px;
span {
font-size: var(--devui-font-size-modal-title, 18px);
font-weight: 600;
white-space: nowrap;
};
img {
height: 30px;
width: 30px;
};
}
</style>
\ No newline at end of file
此差异已折叠。
export const apiKey = process.env.INSCODE_API_KEY;
export const apiUrl = 'https://inscode-api.csdn.net/api/v1/gpt/';
\ No newline at end of file
import { createApp } from 'vue'
import DevUI from 'vue-devui';
import 'vue-devui/style.css';
import '@devui-design/icons/icomoon/devui-icon.css';
import { ThemeServiceInit, infinityTheme, galaxyTheme } from 'devui-theme';
import './style.scss'
import App from './App.vue'
// import MateChat from '../src/components/MateChat/index'
import * as Vue from 'vue'
import * as echarts from 'echarts'
import MateChat from '@matechat/core'
window.Vue = Vue
window.echarts = echarts
// 默认使用无限主题
export const themeServiceInstance = ThemeServiceInit({
infinityTheme, galaxyTheme
}, 'infinityTheme');
if (localStorage.getItem('theme') === 'galaxy-theme') {
themeServiceInstance.applyTheme(galaxyTheme);
}
createApp(App).use(DevUI).use(MateChat).mount('#app');
@import 'devui-theme/styles-var/devui-var.scss';
body {
height: 100%;
min-height: 100vh;
background-color: $devui-global-bg;
}
html {
height: 100%;
}
#app {
height: 100%;
}
.content-card {
margin: 8px;
overflow: hidden;
background-color: $devui-base-bg;
border-radius: $devui-border-radius-card;
box-shadow: $devui-shadow-length-base $devui-light-shadow;
height: 400px;
transition: transform 0.3s, box-shadow 0.3s;
&:hover {
transform: translateY(-5px);
box-shadow: $devui-shadow-length-base $devui-shadow;
}
}
.content-card-sm {
margin: 8px;
overflow: hidden;
background-color: $devui-base-bg;
border-radius: $devui-border-radius-card;
box-shadow: $devui-shadow-length-base $devui-light-shadow;
height: 192px;
transition: transform 0.3s, box-shadow 0.3s;
&:hover {
transform: translateY(-5px);
box-shadow: $devui-shadow-length-base $devui-shadow;
}
}
.chart-card {
box-shadow: $devui-shadow-length-base $devui-light-shadow;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
padding: 20px;
position: relative;
background-color: $devui-base-bg;
.card-title {
font-size: 14px;
line-height: 22px;
font-weight: 700;
}
.card-subtitle {
font-size: 12px;
line-height: 18px;
margin-top: 4px;
color: $devui-aide-text-stress;
}
.card-content {
flex: 1;
margin-top: 12px;
}
}
* {
-webkit-user-drag: none;
}
[draggable="true"] {
-webkit-user-drag: element;
}
\ No newline at end of file
declare module '*.md?raw' {
const content: string
export default content
}
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vite.dev/config/
export default defineConfig({
server: {
host: true
},
resolve: {
alias: {
'vue': 'vue/dist/vue.esm-bundler.js'
}
},
plugins: [vue()],
define: {
'process.env': {
INSCODE_API_KEY: process.env.INSCODE_API_KEY
}
},
assetsInclude: ['**/*.md'],
})
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册