更新v1.3.0-beta24-01-25
Squashed commit of the following: commit 66d0e5e94c0394d83b47b58bd130ba2addce2930 Author: Sun <95302870@qq.com> Date: Thu Jan 25 13:20:34 2024 +0800 更新1.3.0-beta24-01-25 commit 52a81e5f558b3e7b329f828adbd8255960dd750b Author: Sun <95302870@qq.com> Date: Thu Jan 25 13:13:08 2024 +0800 Squashed commit of the following: commit 908d87357c4e22868eff85f377bb8cd22f3785d7 Author: Sun <95302870@qq.com> Date: Thu Jan 25 13:12:14 2024 +0800 增加前端版本号 commit 8ed2b636476c7a14ae4e1761f7712949b7ce60fc Author: Sun <95302870@qq.com> Date: Thu Jan 25 12:29:49 2024 +0800 增加自动获取前端版本号的git tag commit ba7d70f9cabf020ab9ce682be5e593b649aed071 Author: Sun <95302870@qq.com> Date: Thu Jan 25 10:58:15 2024 +0800 优化代码 commit 104543b96fb4d5f9362d29da22390d9a0565c395 Author: Sun <95302870@qq.com> Date: Wed Jan 24 21:28:31 2024 +0800 增加系统状态组件的部分样式 commit 70c87c94c688a14d3bbe53be191c2186ec469a01 Author: Sun <95302870@qq.com> Date: Wed Jan 24 20:55:05 2024 +0800 时间组件和搜索栏组件增加样式类型 commit 6bab5a264fdb1281763d73bf022335667845dc67 Author: Sun <95302870@qq.com> Date: Wed Jan 24 20:41:33 2024 +0800 将项目列表增加样式并优化减少dom嵌套 commit 99d18df7f0a57ec1cead9bce7b2b4b11427cc2e2 Author: Sun <95302870@qq.com> Date: Wed Jan 24 20:11:07 2024 +0800 增加系统状态、logo等类名并简化部分组件dom commit bf1cc0cc0014f751b6453ebfb357b575b0a54615 Author: Sun <95302870@qq.com> Date: Wed Jan 24 17:17:41 2024 +0800 更新关于页面 commit fceacf58b87b988827f0baa6086e8296c843c495 Author: Sun <95302870@qq.com> Date: Wed Jan 24 14:54:37 2024 +0800 增加隐藏网络模式切换开关 commit e0dcc49f5b23618103c5ee15e13758164d2eddf2 Author: Sun <95302870@qq.com> Date: Wed Jan 24 13:55:28 2024 +0800 优化部分错误码 commit 863cdf0fc1fc406304784d4304ba6be31e5133ff Author: Sun <95302870@qq.com> Date: Wed Jan 24 12:54:55 2024 +0800 声明暴露端口 commit 5b25ef9c194dc0112cd10250c04344dd6f57be27 Author: Sun <95302870@qq.com> Date: Wed Jan 24 12:38:48 2024 +0800 修改命令行所有的输出内容为英文
This commit is contained in:
parent
d11e7b24e0
commit
956e645144
@ -55,6 +55,8 @@ COPY --from=server_image /build/sun-panel /app/sun-panel
|
|||||||
# 中国国内源
|
# 中国国内源
|
||||||
# RUN sed -i "s@dl-cdn.alpinelinux.org@mirrors.aliyun.com@g" /etc/apk/repositories
|
# RUN sed -i "s@dl-cdn.alpinelinux.org@mirrors.aliyun.com@g" /etc/apk/repositories
|
||||||
|
|
||||||
|
EXPOSE 3002
|
||||||
|
|
||||||
RUN apk add --no-cache bash ca-certificates su-exec tzdata \
|
RUN apk add --no-cache bash ca-certificates su-exec tzdata \
|
||||||
&& chmod +x ./sun-panel \
|
&& chmod +x ./sun-panel \
|
||||||
&& ./sun-panel -config
|
&& ./sun-panel -config
|
||||||
|
28
add-frontend-version.js
Normal file
28
add-frontend-version.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
const fs = require('fs')
|
||||||
|
// const { execSync } = require('child_process')
|
||||||
|
const moment = require('moment')
|
||||||
|
|
||||||
|
// git 最新标签
|
||||||
|
// const latestTag = execSync('git describe --tags --abbrev=0').toString().trim()
|
||||||
|
const packDate = moment().format('YYYYMMDD-HH')
|
||||||
|
|
||||||
|
// 要追加的内容
|
||||||
|
const contentToAppend = `\nVITE_APP_VERSION=${packDate}`
|
||||||
|
// 读取文件原始内容
|
||||||
|
const envFilePath = '.env'
|
||||||
|
let envContent = fs.readFileSync(envFilePath, 'utf-8')
|
||||||
|
|
||||||
|
const versionRegex = /^VITE_APP_VERSION=.*$/m
|
||||||
|
if (versionRegex.test(envContent)) {
|
||||||
|
// 使用正则表达式查找并替换 VITE_APP_VERSION=* 这一行
|
||||||
|
envContent = envContent.replace(versionRegex, contentToAppend)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 追加内容
|
||||||
|
envContent = envContent + contentToAppend
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将新内容写回 .env 文件
|
||||||
|
fs.writeFileSync(envFilePath, envContent)
|
||||||
|
|
||||||
|
console.log('update to .env file.', contentToAppend)
|
11
package.json
11
package.json
@ -1,18 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "sun-panel",
|
"name": "sun-panel",
|
||||||
"version": "2.10.9",
|
"version": "0.0.0",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "ChatGPT Web",
|
"description": "Sun-Panel Web",
|
||||||
"author": "ChenZhaoYu <chenzhaoyu1994@gmail.com>",
|
"author": "BraisedHunter <95302870@qq.com>",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"Sun-Panel",
|
"Sun-Panel",
|
||||||
"chatgpt",
|
|
||||||
"chatbot",
|
|
||||||
"vue"
|
"vue"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "run-p type-check build-only",
|
"build": "run-p add-version type-check build-only",
|
||||||
|
"add-version": "node ./add-frontend-version.js",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"build-only": "vite build",
|
"build-only": "vite build",
|
||||||
"type-check": "vue-tsc --noEmit",
|
"type-check": "vue-tsc --noEmit",
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
package apiReturn
|
package apiReturn
|
||||||
|
|
||||||
var ErrorCodeMap = map[int]string{
|
var ErrorCodeMap = map[int]string{
|
||||||
// -1:操作失败
|
// -1:操作失败(前端会自动弹窗)
|
||||||
|
// 100: "operation failed",
|
||||||
|
|
||||||
1000: "Not logged in yet", // 还未登录
|
1000: "Not logged in yet", // 还未登录
|
||||||
1003: "Incorrect username or password", // 用户名或密码错误
|
1003: "Incorrect username or password", // 用户名或密码错误
|
||||||
1004: "Account disabled or not activated", // 账号已停用或未激活
|
1004: "Account disabled or not activated", // 账号已停用或未激活
|
||||||
1005: "No current permission for operation", // 当前无权限操作
|
1005: "No current permission for operation", // 当前无权限操作
|
||||||
1006: "Account does not exist", // 账号不存在
|
1006: "Account does not exist", // 账号不存在
|
||||||
|
1007: "Old password error", // 旧密码不正确
|
||||||
|
|
||||||
// 数据类
|
// 数据类
|
||||||
1200: "Database error", // 数据库错误
|
1200: "Database error", // 数据库错误
|
||||||
|
@ -28,7 +28,8 @@ func (a *ItemIcon) Edit(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if req.ItemIconGroupId == 0 {
|
if req.ItemIconGroupId == 0 {
|
||||||
apiReturn.Error(c, "Group is mandatory")
|
// apiReturn.Error(c, "Group is mandatory")
|
||||||
|
apiReturn.ErrorParamFomat(c, "Group is mandatory")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ func (a *UserApi) UpdatePasssword(c *gin.Context) {
|
|||||||
} else {
|
} else {
|
||||||
if v.Password != cmn.PasswordEncryption(params.OldPassword) {
|
if v.Password != cmn.PasswordEncryption(params.OldPassword) {
|
||||||
// 旧密码不正确
|
// 旧密码不正确
|
||||||
apiReturn.Error(c, global.Lang.Get("user.api_old_pass_error"))
|
apiReturn.ErrorByCode(c, 1007)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
9|1.3.0-beta24-01-17-19
|
9|1.3.0-beta24-01-25
|
@ -35,7 +35,7 @@ func InitApp() error {
|
|||||||
|
|
||||||
// 日志
|
// 日志
|
||||||
if logger, err := runlog.InitRunlog(global.RUNCODE, "running.log"); err != nil {
|
if logger, err := runlog.InitRunlog(global.RUNCODE, "running.log"); err != nil {
|
||||||
log.Panicln("日志初始化错误", err)
|
log.Panicln("Log initialization error", err)
|
||||||
panic(err)
|
panic(err)
|
||||||
} else {
|
} else {
|
||||||
global.Logger = logger
|
global.Logger = logger
|
||||||
@ -47,7 +47,7 @@ func InitApp() error {
|
|||||||
// 配置初始化
|
// 配置初始化
|
||||||
{
|
{
|
||||||
if config, err := config.ConfigInit(); err != nil {
|
if config, err := config.ConfigInit(); err != nil {
|
||||||
global.Logger.Errorln("配置初始化错误", err)
|
global.Logger.Errorln("Configuration initialization error", err)
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
global.Config = config
|
global.Config = config
|
||||||
@ -74,7 +74,7 @@ func InitApp() error {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicln("Redis初始化错误", err)
|
log.Panicln("Redis initialization error", err)
|
||||||
panic(err)
|
panic(err)
|
||||||
// return err
|
// return err
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ func DatabaseConnect() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if db, err := database.DbInit(dbClientInfo); err != nil {
|
if db, err := database.DbInit(dbClientInfo); err != nil {
|
||||||
log.Panicln("数据库初始化错误", err)
|
log.Panicln("Database initialization error", err)
|
||||||
panic(err)
|
panic(err)
|
||||||
} else {
|
} else {
|
||||||
global.Db = db
|
global.Db = db
|
||||||
@ -133,17 +133,17 @@ func CommandRun() {
|
|||||||
pwd bool
|
pwd bool
|
||||||
)
|
)
|
||||||
|
|
||||||
flag.BoolVar(&cfg, "config", false, "生成配置文件")
|
flag.BoolVar(&cfg, "config", false, "Generate configuration file")
|
||||||
flag.BoolVar(&pwd, "password-reset", false, "重置第一个用户的密码")
|
flag.BoolVar(&pwd, "password-reset", false, "Reset the password of the first user")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if cfg {
|
if cfg {
|
||||||
// 生成配置文件
|
// 生成配置文件
|
||||||
fmt.Println("正在生成配置文件")
|
fmt.Println("Generating configuration file")
|
||||||
cmn.AssetsTakeFileToPath("conf.example.ini", "conf/conf.example.ini")
|
cmn.AssetsTakeFileToPath("conf.example.ini", "conf/conf.example.ini")
|
||||||
cmn.AssetsTakeFileToPath("conf.example.ini", "conf/conf.ini")
|
cmn.AssetsTakeFileToPath("conf.example.ini", "conf/conf.ini")
|
||||||
fmt.Println("配置文件已经创建 conf/conf.ini ", "请按照自己的需求修改")
|
fmt.Println("The configuration file has been created conf/conf.ini ", "Please modify according to your own needs")
|
||||||
os.Exit(0) // 务必退出
|
os.Exit(0) // 务必退出
|
||||||
} else if pwd {
|
} else if pwd {
|
||||||
// 重置密码
|
// 重置密码
|
||||||
@ -171,9 +171,9 @@ func CommandRun() {
|
|||||||
os.Exit(0) // 务必退出
|
os.Exit(0) // 务必退出
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("密码已经重置成功,以下是账号信息")
|
fmt.Println("The password has been successfully reset. Here is the account information")
|
||||||
fmt.Println("用户名 ", userInfo.Username)
|
fmt.Println("Username ", userInfo.Username)
|
||||||
fmt.Println("密码 ", newPassword)
|
fmt.Println("Password ", newPassword)
|
||||||
os.Exit(0) // 务必退出
|
os.Exit(0) // 务必退出
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
|
BIN
src/assets/about_image/bilibili.png
Normal file
BIN
src/assets/about_image/bilibili.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 2.1 KiB |
BIN
src/assets/about_image/qq_group_qr2.png
Normal file
BIN
src/assets/about_image/qq_group_qr2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 221 KiB |
BIN
src/assets/about_image/youtube.png
Normal file
BIN
src/assets/about_image/youtube.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
@ -1,12 +1,15 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { NDivider, NGradientText } from 'naive-ui'
|
import { NDivider, NGradientText, NTag } from 'naive-ui'
|
||||||
import { onMounted, ref } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
import { get } from '@/api/system/about'
|
import { get } from '@/api/system/about'
|
||||||
|
import { useAppStore } from '@/store'
|
||||||
import srcSvglogo from '@/assets/logo.svg'
|
import srcSvglogo from '@/assets/logo.svg'
|
||||||
import srcGitee from '@/assets/about_image/gitee.png'
|
import srcGitee from '@/assets/about_image/gitee.png'
|
||||||
import srcGithub from '@/assets/about_image/github.png'
|
import srcGithub from '@/assets/about_image/github.png'
|
||||||
import srcDocker from '@/assets/about_image/docker.png'
|
import srcDocker from '@/assets/about_image/docker.png'
|
||||||
import srcQQGroupQR from '@/assets/about_image/qq_group_qr.jpg'
|
import srcBilibili from '@/assets/about_image/bilibili.png'
|
||||||
|
import srcYoutube from '@/assets/about_image/youtube.png'
|
||||||
|
import srcQQGroupQR from '@/assets/about_image/qq_group_qr2.png'
|
||||||
import { RoundCardModal } from '@/components/common'
|
import { RoundCardModal } from '@/components/common'
|
||||||
|
|
||||||
interface Version {
|
interface Version {
|
||||||
@ -14,8 +17,10 @@ interface Version {
|
|||||||
versionCode: number
|
versionCode: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
const versionName = ref('')
|
const versionName = ref('')
|
||||||
const qqGroupQRShow = ref(false)
|
const qqGroupQRShow = ref(false)
|
||||||
|
const frontVersion = import.meta.env.VITE_APP_VERSION || 'unknown'
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
get<Version>().then((res) => {
|
get<Version>().then((res) => {
|
||||||
@ -26,43 +31,44 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="pt-10">
|
<div class="pt-5">
|
||||||
<div>
|
<div class="flex flex-col items-center justify-center">
|
||||||
<div class="flex flex-col items-center justify-center">
|
<img :src="srcSvglogo" width="100" height="100" alt="">
|
||||||
<img :src="srcSvglogo" width="100" height="100" alt="">
|
<div class="text-3xl font-semibold">
|
||||||
<div class="text-3xl font-semibold">
|
{{ $t('common.appName') }}
|
||||||
{{ $t('common.appName') }}
|
|
||||||
</div>
|
|
||||||
<div class="text-xl">
|
|
||||||
<NGradientText type="info">
|
|
||||||
<a href="https://github.com/hslr-s/sun-panel/releases" class="font-semibold" :title="$t('apps.about.viewUpdateLog')" target="_blank">v{{ versionName }}</a>
|
|
||||||
</NGradientText>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="text-xl">
|
||||||
<NDivider> • </NDivider>
|
<NGradientText type="info">
|
||||||
<div class="flex flex-col items-center justify-center text-base">
|
<a href="https://github.com/hslr-s/sun-panel/releases" class="font-semibold" :title="$t('apps.about.viewUpdateLog')" target="_blank">v{{ versionName }}</a>
|
||||||
<div>
|
</NGradientText>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2">
|
||||||
<a href="https://github.com/hslr-s/sun-panel/releases" target="_blank" class="link">{{ $t('apps.about.checkUpdate') }}</a>
|
<a href="https://github.com/hslr-s/sun-panel/releases" target="_blank" class="link">{{ $t('apps.about.checkUpdate') }}</a>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<NDivider style="margin:10px 0">
|
||||||
|
•
|
||||||
|
</NDivider>
|
||||||
|
<div class="flex flex-col items-center justify-center text-base">
|
||||||
|
<div>
|
||||||
|
{{ $t('apps.about.author') }}<a href="https://github.com/hslr-s" target="_blank" class="link">红烧猎人</a> | <a href="https://github.com/hslr-s/sun-panel/blob/master/doc/donate.md" target="_blank" class="text-red-600 hover:text-red-900">{{ $t('apps.about.donate') }}</a>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{{ $t('apps.about.issue') }}<a href="https://github.com/hslr-s/sun-panel/issues" target="_blank" class="link">Github Issues</a>
|
{{ $t('apps.about.issue') }}<a href="https://github.com/hslr-s/sun-panel/issues" target="_blank" class="link">Github Issues</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
{{ $t('apps.about.QQGroup') }}<a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=_I9WIoJn1roIdoaAqelSj9qClLKlXIa1&authKey=GfsQP2GagHnus0jMc7U8Sm6VhWjtsipXUzCHbFwQsGyHMgmYWx6ZbAP%2Bhut%2B4D6N&noverify=0&group_code=276594668" target="_blank" class="link">{{ $t("apps.about.addQQGroupUrl") }}</a>
|
{{ $t('apps.about.discussions') }}<a href="https://github.com/hslr-s/sun-panel/discussions" target="_blank" class="link">Github Discussions</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{ $t('apps.about.QQGroup') }}<a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=K6UII6aEPZUeDRIPOEpOSJZH-Vmr_RPu&authKey=jEXhnVekLbDDx5UkQzKtd3bRmhZggkGBxmvW4NT5LLIAFP7toMmqABwvkANGHbLb&noverify=0&group_code=831615449" target="_blank" class="link">{{ $t("apps.about.addQQGroupUrl") }}</a>
|
||||||
|
|
|
|
||||||
<span class="link cursor-pointer" @click="qqGroupQRShow = !qqGroupQRShow">
|
<span class="link cursor-pointer" @click="qqGroupQRShow = !qqGroupQRShow">
|
||||||
{{ $t('apps.about.QR') }}
|
{{ $t('apps.about.QR') }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div class="flex mt-[10px] flex-wrap justify-center">
|
||||||
{{ $t('apps.about.author') }}<a href="https://github.com/hslr-s" target="_blank" class="link">红烧猎人</a> | <a href="https://github.com/hslr-s/sun-panel/blob/master/doc/donate.md" target="_blank" class="text-red-600 hover:text-red-900">{{ $t('apps.about.donate') }}</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex mt-[10px]">
|
|
||||||
<div class="flex items-center mx-[10px]">
|
<div class="flex items-center mx-[10px]">
|
||||||
<img class="w-[20px] h-[20px] mr-[5px]" :src="srcGithub" alt="">
|
<img class="w-[20px] h-[20px] mr-[5px]" :src="srcGithub" alt="">
|
||||||
<a href="https://github.com/hslr-s/sun-panel" target="_blank" class="link">Github</a>
|
<a href="https://github.com/hslr-s/sun-panel" target="_blank" class="link">Github</a>
|
||||||
@ -75,6 +81,21 @@ onMounted(() => {
|
|||||||
<img class="w-[20px] h-[20px] mr-[5px]" :src="srcDocker" alt="">
|
<img class="w-[20px] h-[20px] mr-[5px]" :src="srcDocker" alt="">
|
||||||
<a href="https://hub.docker.com/r/hslr/sun-panel" target="_blank" class="link">Docker</a>
|
<a href="https://hub.docker.com/r/hslr/sun-panel" target="_blank" class="link">Docker</a>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex items-center mx-[10px]">
|
||||||
|
<img class="w-[20px] h-[20px] mr-[5px]" :src="srcBilibili" alt="">
|
||||||
|
<!-- <a href="https://space.bilibili.com/27407696/channel/collectiondetail?sid=2023810" target="_blank" class="link">Bilibili</a> -->
|
||||||
|
<a href="https://space.bilibili.com/27407696/channel/collectiondetail?sid=2023810" target="_blank" class="link">Bilibili</a>
|
||||||
|
</div>
|
||||||
|
<div v-if="appStore.language !== 'zh-CN'" class="flex items-center mx-[10px]">
|
||||||
|
<img class="w-[20px] h-[20px] mr-[5px]" :src="srcYoutube" alt="">
|
||||||
|
<a href="https://www.youtube.com/channel/UCKwbFmKU25R602z6P2fgPYg" target="_blank" class="link">YouTube</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-5">
|
||||||
|
<NTag :bordered="false" size="small">
|
||||||
|
{{ $t("apps.about.frontVersionText") }}: FV-{{ frontVersion }}
|
||||||
|
</NTag>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<RoundCardModal v-model:show="qqGroupQRShow" title="交流群二维码" style="width: 300px;">
|
<RoundCardModal v-model:show="qqGroupQRShow" title="交流群二维码" style="width: 300px;">
|
||||||
|
@ -237,6 +237,13 @@ function resetPanelConfig() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<NGrid cols="2">
|
<NGrid cols="2">
|
||||||
|
<NGridItem span="12 400:12">
|
||||||
|
<div class="flex items-center mt-[5px]">
|
||||||
|
<span class="mr-[10px]">{{ $t('apps.baseSettings.netModeChangeButtonShow') }}</span>
|
||||||
|
<NSwitch v-model:value="panelState.panelConfig.netModeChangeButtonShow" />
|
||||||
|
</div>
|
||||||
|
</NGridItem>
|
||||||
|
|
||||||
<NGridItem span="12 400:12">
|
<NGridItem span="12 400:12">
|
||||||
<div class="flex items-center mt-[10px]">
|
<div class="flex items-center mt-[10px]">
|
||||||
<span class="mr-[10px]">{{ $t('apps.baseSettings.maxWidth') }}</span>
|
<span class="mr-[10px]">{{ $t('apps.baseSettings.maxWidth') }}</span>
|
||||||
|
@ -104,14 +104,6 @@ function handleUpdatePassword(e: MouseEvent) {
|
|||||||
updatePasswordModalState.value.show = false
|
updatePasswordModalState.value.show = false
|
||||||
ms.success(t('common.success'))
|
ms.success(t('common.success'))
|
||||||
}
|
}
|
||||||
else if (code === 0) {
|
|
||||||
// 旧密码错误
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// 其他错误
|
|
||||||
ms.error(`${t('common.failed')}:${msg}`)
|
|
||||||
}
|
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
updatePasswordModalState.value.loading = false
|
updatePasswordModalState.value.loading = false
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
|
@ -18,11 +18,11 @@ const propClass = ref(props.class)
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full">
|
<div class="item-card w-full">
|
||||||
<!-- 详情图标 -->
|
<!-- 详情图标 -->
|
||||||
<div
|
<div
|
||||||
v-if="cardTypeStyle === PanelPanelConfigStyleEnum.info"
|
v-if="cardTypeStyle === PanelPanelConfigStyleEnum.info"
|
||||||
class="w-full rounded-2xl transition-all duration-200 flex"
|
class="item-card-info w-full rounded-2xl transition-all duration-200 flex"
|
||||||
:class="propClass"
|
:class="propClass"
|
||||||
:style="{ backgroundColor: backgroundColor ?? defaultBackground }"
|
:style="{ backgroundColor: backgroundColor ?? defaultBackground }"
|
||||||
>
|
>
|
||||||
@ -32,9 +32,10 @@ const propClass = ref(props.class)
|
|||||||
<!-- 极简图标(APP) -->
|
<!-- 极简图标(APP) -->
|
||||||
<div
|
<div
|
||||||
v-if="cardTypeStyle === PanelPanelConfigStyleEnum.icon"
|
v-if="cardTypeStyle === PanelPanelConfigStyleEnum.icon"
|
||||||
|
class="item-card-small"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="overflow-hidden rounded-2xl sunpanel w-[70px] h-[70px] mx-auto transition-all duration-200"
|
class="item-card-small-icon overflow-hidden rounded-2xl sunpanel w-[70px] h-[70px] mx-auto transition-all duration-200"
|
||||||
:class="propClass"
|
:class="propClass"
|
||||||
:style="{ backgroundColor: backgroundColor ?? defaultBackground }"
|
:style="{ backgroundColor: backgroundColor ?? defaultBackground }"
|
||||||
>
|
>
|
||||||
@ -43,7 +44,7 @@ const propClass = ref(props.class)
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="!iconTextIconHideTitle"
|
v-if="!iconTextIconHideTitle"
|
||||||
class="text-center app-icon-text-shadow cursor-pointer mt-[2px]"
|
class="item-card-small-title text-center app-icon-text-shadow cursor-pointer mt-[2px]"
|
||||||
:style="{ color: iconTextColor }"
|
:style="{ color: iconTextColor }"
|
||||||
>
|
>
|
||||||
{{ iconText }}
|
{{ iconText }}
|
||||||
|
@ -21,32 +21,32 @@ const iconExt = computed(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div :style="defaultStyle">
|
<div class="item-icon" :style="defaultStyle">
|
||||||
<slot>
|
<slot>
|
||||||
<div v-if="itemIcon">
|
<template v-if="itemIcon">
|
||||||
<div v-if="itemIcon?.itemType === 1">
|
<template v-if="itemIcon?.itemType === 1">
|
||||||
<NAvatar :size="props.size" :style="{ backgroundColor: (forceBackground ?? itemIcon?.backgroundColor) || defaultBackground }">
|
<NAvatar :size="props.size" :style="{ backgroundColor: (forceBackground ?? itemIcon?.backgroundColor) || defaultBackground }">
|
||||||
{{ itemIcon.text }}
|
{{ itemIcon.text }}
|
||||||
</NAvatar>
|
</NAvatar>
|
||||||
</div>
|
</template>
|
||||||
|
|
||||||
<div v-else-if="itemIcon?.itemType === 2">
|
<template v-else-if="itemIcon?.itemType === 2">
|
||||||
<div v-if="iconExt === 'svg'" :style="{ backgroundColor: (forceBackground ?? itemIcon?.backgroundColor) || defaultBackground, ...defaultStyle }" class="flex justify-center items-center">
|
<div v-if="iconExt === 'svg'" :style="{ backgroundColor: (forceBackground ?? itemIcon?.backgroundColor) || defaultBackground, ...defaultStyle }" class="flex justify-center items-center">
|
||||||
<img :src="itemIcon?.src" class="w-[35px] h-[35px]">
|
<img :src="itemIcon?.src" class="w-[35px] h-[35px]">
|
||||||
</div>
|
</div>
|
||||||
<NImage v-else :style="{ backgroundColor: (forceBackground ?? itemIcon?.backgroundColor) || defaultBackground, ...defaultStyle }" :src="itemIcon?.src" preview-disabled />
|
<NImage v-else :style="{ backgroundColor: (forceBackground ?? itemIcon?.backgroundColor) || defaultBackground, ...defaultStyle }" :src="itemIcon?.src" preview-disabled />
|
||||||
</div>
|
</template>
|
||||||
|
|
||||||
<div v-else-if="itemIcon?.itemType === 3">
|
<template v-else-if="itemIcon?.itemType === 3">
|
||||||
<NAvatar :size="props.size" :style="{ backgroundColor: (forceBackground ?? itemIcon?.backgroundColor) || defaultBackground }">
|
<NAvatar :size="props.size" :style="{ backgroundColor: (forceBackground ?? itemIcon?.backgroundColor) || defaultBackground }">
|
||||||
<SvgIconOnline style="font-size: 35px;" :icon="itemIcon.text" />
|
<SvgIconOnline style="font-size: 35px;" :icon="itemIcon.text" />
|
||||||
</NAvatar>
|
</NAvatar>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
</template>
|
||||||
|
|
||||||
<div v-else>
|
<template v-else>
|
||||||
<NAvatar :size="props.size" />
|
<NAvatar :size="props.size" />
|
||||||
</div>
|
</template>
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="text-neutral-400">
|
|
||||||
<span>Star on</span>
|
|
||||||
<a href="https://github.com/Chanzhaoyu/chatgpt-bot" target="_blank" class="text-blue-500">
|
|
||||||
GitHub
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
@ -1,3 +0,0 @@
|
|||||||
import GithubSite from './GithubSite.vue'
|
|
||||||
|
|
||||||
export { GithubSite }
|
|
@ -67,15 +67,15 @@ onBeforeUnmount(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full text-center">
|
<div class="clock w-full text-center">
|
||||||
<span class="text-2xl sm:text-2xl md:text-3xl font-[600]">
|
<span class="clock-time text-2xl sm:text-2xl md:text-3xl font-[600]">
|
||||||
{{ currentDate.time }}
|
{{ currentDate.time }}
|
||||||
</span>
|
</span>
|
||||||
<div class="hidden sm:hidden md:block">
|
<div class="hidden sm:hidden md:block">
|
||||||
<span class="mr-1">
|
<span class="clock-date mr-1">
|
||||||
{{ currentDate.date }}
|
{{ currentDate.date }}
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span class="clock-week">
|
||||||
{{ currentDate.week }}
|
{{ currentDate.week }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -120,18 +120,18 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full" @keydown.enter="handleSearchClick">
|
<div class="search-box w-full" @keydown.enter="handleSearchClick" @keydown.esc="handleClearSearchTerm">
|
||||||
<div class="search-container flex rounded-2xl items-center justify-center text-white w-full" :style="{ background, color: textColor }" :class="{ focused: isFocused }">
|
<div class="search-container flex rounded-2xl items-center justify-center text-white w-full" :style="{ background, color: textColor }" :class="{ focused: isFocused }">
|
||||||
<div class="w-[40px] flex justify-center cursor-pointer" @click="handleEngineClick">
|
<div class="search-box-btn-engine w-[40px] flex justify-center cursor-pointer" @click="handleEngineClick">
|
||||||
<NAvatar :src="state.currentSearchEngine.iconSrc" style="background-color: transparent;" :size="20" />
|
<NAvatar :src="state.currentSearchEngine.iconSrc" style="background-color: transparent;" :size="20" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input v-model="searchTerm" :placeholder="$t('deskModule.searchBox.inputPlaceholder')" @focus="onFocus" @blur="onBlur" @input="handleItemSearch">
|
<input v-model="searchTerm" :placeholder="$t('deskModule.searchBox.inputPlaceholder')" @focus="onFocus" @blur="onBlur" @input="handleItemSearch">
|
||||||
|
|
||||||
<div v-if="searchTerm !== ''" class="w-[25px] mr-[10px] flex justify-center cursor-pointer" @click="handleClearSearchTerm">
|
<div v-if="searchTerm !== ''" class="search-box-btn-clear w-[25px] mr-[10px] flex justify-center cursor-pointer" @click="handleClearSearchTerm">
|
||||||
<SvgIcon style="width: 20px;height: 20px;" icon="line-md:close-small" />
|
<SvgIcon style="width: 20px;height: 20px;" icon="line-md:close-small" />
|
||||||
</div>
|
</div>
|
||||||
<div class="w-[25px] flex justify-center cursor-pointer" @click="handleSearchClick">
|
<div class="search-box-btn-search w-[25px] flex justify-center cursor-pointer" @click="handleSearchClick">
|
||||||
<SvgIcon style="width: 20px;height: 20px;" icon="iconamoon:search-fill" />
|
<SvgIcon style="width: 20px;height: 20px;" icon="iconamoon:search-fill" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, onUnmounted, ref } from 'vue'
|
import { onMounted, onUnmounted, ref } from 'vue'
|
||||||
import GenericProgress from '../components/GenericProgress/index.vue'
|
import GenericProgress from '../components/GenericProgress/index.vue'
|
||||||
|
import { correctionNumber, correctionNumberByCardStyle } from './common'
|
||||||
import { getCpuState } from '@/api/system/systemMonitor'
|
import { getCpuState } from '@/api/system/systemMonitor'
|
||||||
import type { PanelPanelConfigStyleEnum } from '@/enums'
|
import type { PanelPanelConfigStyleEnum } from '@/enums'
|
||||||
|
|
||||||
@ -16,10 +17,6 @@ const props = defineProps<Prop>()
|
|||||||
let timer: NodeJS.Timer
|
let timer: NodeJS.Timer
|
||||||
const cpuState = ref<SystemMonitor.CPUInfo | null>(null)
|
const cpuState = ref<SystemMonitor.CPUInfo | null>(null)
|
||||||
|
|
||||||
function correctionNumber(v: number, keepNum = 2): number {
|
|
||||||
return v === 0 ? 0 : Number(v.toFixed(keepNum))
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getData() {
|
async function getData() {
|
||||||
try {
|
try {
|
||||||
const { data, code } = await getCpuState<SystemMonitor.CPUInfo>()
|
const { data, code } = await getCpuState<SystemMonitor.CPUInfo>()
|
||||||
@ -44,16 +41,15 @@ onUnmounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full">
|
<GenericProgress
|
||||||
<GenericProgress
|
:progress-color="progressColor"
|
||||||
:progress-color="progressColor"
|
:progress-rail-color="progressRailColor"
|
||||||
:progress-rail-color="progressRailColor"
|
:progress-height="5"
|
||||||
:progress-height="5"
|
:percentage="correctionNumberByCardStyle(cpuState?.usages[0] || 0, cardTypeStyle)"
|
||||||
:percentage="correctionNumber(cpuState?.usages[0] || 0)"
|
:card-type-style="cardTypeStyle"
|
||||||
:card-type-style="cardTypeStyle"
|
:info-card-right-text="`${correctionNumber(cpuState?.usages[0] || 0)}%`"
|
||||||
:info-card-right-text="`${correctionNumber(cpuState?.usages[0] || 0)}%`"
|
info-card-left-text="CPU"
|
||||||
info-card-left-text="CPU"
|
:text-color="textColor"
|
||||||
:text-color="textColor"
|
style="width: 100%;"
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, onUnmounted, ref } from 'vue'
|
import { onMounted, onUnmounted, ref } from 'vue'
|
||||||
import GenericProgress from '../components/GenericProgress/index.vue'
|
import GenericProgress from '../components/GenericProgress/index.vue'
|
||||||
|
import { correctionNumberByCardStyle } from './common'
|
||||||
import type { PanelPanelConfigStyleEnum } from '@/enums'
|
import type { PanelPanelConfigStyleEnum } from '@/enums'
|
||||||
import { bytesToSize } from '@/utils/cmn'
|
import { bytesToSize } from '@/utils/cmn'
|
||||||
import { getDiskStateByPath } from '@/api/system/systemMonitor'
|
import { getDiskStateByPath } from '@/api/system/systemMonitor'
|
||||||
@ -18,10 +19,6 @@ const props = defineProps<Prop>()
|
|||||||
let timer: NodeJS.Timer
|
let timer: NodeJS.Timer
|
||||||
const diskState = ref<SystemMonitor.DiskInfo | null>(null)
|
const diskState = ref<SystemMonitor.DiskInfo | null>(null)
|
||||||
|
|
||||||
function correctionNumber(v: number, keepNum = 2): number {
|
|
||||||
return v === 0 ? 0 : Number(v.toFixed(keepNum))
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatdiskSize(v: number): string {
|
function formatdiskSize(v: number): string {
|
||||||
return bytesToSize(v)
|
return bytesToSize(v)
|
||||||
}
|
}
|
||||||
@ -54,16 +51,14 @@ onUnmounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full">
|
<GenericProgress
|
||||||
<GenericProgress
|
:progress-color="progressColor"
|
||||||
:progress-color="progressColor"
|
:progress-rail-color="progressRailColor"
|
||||||
:progress-rail-color="progressRailColor"
|
:progress-height="5"
|
||||||
:progress-height="5"
|
:percentage="correctionNumberByCardStyle(diskState?.usedPercent || 0, cardTypeStyle)"
|
||||||
:percentage="correctionNumber(diskState?.usedPercent || 0)"
|
:card-type-style="cardTypeStyle"
|
||||||
:card-type-style="cardTypeStyle"
|
:info-card-right-text="`${formatdiskSize(formatdiskToByte(diskState?.used || 0))}/${formatdiskSize(formatdiskToByte(diskState?.free || 0))}`"
|
||||||
:info-card-right-text="`${formatdiskSize(formatdiskToByte(diskState?.used || 0))}/${formatdiskSize(formatdiskToByte(diskState?.free || 0))}`"
|
:info-card-left-text="diskState?.mountpoint"
|
||||||
:info-card-left-text="diskState?.mountpoint"
|
:text-color="textColor"
|
||||||
:text-color="textColor"
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, onUnmounted, ref } from 'vue'
|
import { onMounted, onUnmounted, ref } from 'vue'
|
||||||
import GenericProgress from '../components/GenericProgress/index.vue'
|
import GenericProgress from '../components/GenericProgress/index.vue'
|
||||||
|
import { correctionNumberByCardStyle } from './common'
|
||||||
import { getMemonyState } from '@/api/system/systemMonitor'
|
import { getMemonyState } from '@/api/system/systemMonitor'
|
||||||
import type { PanelPanelConfigStyleEnum } from '@/enums'
|
import type { PanelPanelConfigStyleEnum } from '@/enums'
|
||||||
import { bytesToSize } from '@/utils/cmn'
|
import { bytesToSize } from '@/utils/cmn'
|
||||||
@ -17,10 +18,6 @@ const props = defineProps<Prop>()
|
|||||||
let timer: NodeJS.Timer
|
let timer: NodeJS.Timer
|
||||||
const memoryState = ref<SystemMonitor.MemoryInfo | null>(null)
|
const memoryState = ref<SystemMonitor.MemoryInfo | null>(null)
|
||||||
|
|
||||||
function correctionNumber(v: number, keepNum = 2): number {
|
|
||||||
return v === 0 ? 0 : Number(v.toFixed(keepNum))
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatMemorySize(v: number): string {
|
function formatMemorySize(v: number): string {
|
||||||
return bytesToSize(v)
|
return bytesToSize(v)
|
||||||
}
|
}
|
||||||
@ -49,16 +46,14 @@ onUnmounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full">
|
<GenericProgress
|
||||||
<GenericProgress
|
:progress-color="progressColor"
|
||||||
:progress-color="progressColor"
|
:progress-rail-color="progressRailColor"
|
||||||
:progress-rail-color="progressRailColor"
|
:progress-height="5"
|
||||||
:progress-height="5"
|
:percentage="correctionNumberByCardStyle(memoryState?.usedPercent || 0, cardTypeStyle)"
|
||||||
:percentage="correctionNumber(memoryState?.usedPercent || 0)"
|
:card-type-style="cardTypeStyle"
|
||||||
:card-type-style="cardTypeStyle"
|
:info-card-right-text="`${formatMemorySize(memoryState?.used || 0)}/${formatMemorySize((memoryState?.total || 0) - (memoryState?.used || 0) || 0)}`"
|
||||||
:info-card-right-text="`${formatMemorySize(memoryState?.used || 0)}/${formatMemorySize((memoryState?.total || 0) - (memoryState?.used || 0) || 0)}`"
|
info-card-left-text="RAM"
|
||||||
info-card-left-text="RAM"
|
:text-color="textColor"
|
||||||
:text-color="textColor"
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
import { PanelPanelConfigStyleEnum } from '@/enums'
|
||||||
|
|
||||||
|
export function correctionNumberByCardStyle(v: number, cardStyle: PanelPanelConfigStyleEnum): number {
|
||||||
|
let keepNum = 0
|
||||||
|
if (cardStyle === PanelPanelConfigStyleEnum.small)
|
||||||
|
keepNum = 1
|
||||||
|
else if (cardStyle === PanelPanelConfigStyleEnum.info)
|
||||||
|
keepNum = 2
|
||||||
|
|
||||||
|
return correctionNumber(v, keepNum)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function correctionNumber(v: number, keepNum = 2): number {
|
||||||
|
return v === 0 ? 0 : Number(v.toFixed(keepNum))
|
||||||
|
}
|
@ -47,7 +47,7 @@ const refreshInterval = 5000
|
|||||||
<template #icon>
|
<template #icon>
|
||||||
<!-- 图标 -->
|
<!-- 图标 -->
|
||||||
<div class="w-[60px] h-[70px]">
|
<div class="w-[60px] h-[70px]">
|
||||||
<div class="w-[60px] h-full flex items-center justify-center text-white">
|
<div class="app-icon w-[60px] h-full flex items-center justify-center text-white">
|
||||||
<SvgIcon v-if="monitorType === MonitorType.cpu" icon="solar-cpu-bold" :style="{ color: extendParam.color }" style="width:35px;height:35px" />
|
<SvgIcon v-if="monitorType === MonitorType.cpu" icon="solar-cpu-bold" :style="{ color: extendParam.color }" style="width:35px;height:35px" />
|
||||||
<SvgIcon v-if="monitorType === MonitorType.memory" icon="material-symbols-memory-alt-rounded" :style="{ color: extendParam.color }" style="width:35px;height:35px" />
|
<SvgIcon v-if="monitorType === MonitorType.memory" icon="material-symbols-memory-alt-rounded" :style="{ color: extendParam.color }" style="width:35px;height:35px" />
|
||||||
<SvgIcon v-if="monitorType === MonitorType.disk" icon="clarity-hard-disk-solid" :style="{ color: extendParam.color }" style="width:35px;height:35px" />
|
<SvgIcon v-if="monitorType === MonitorType.disk" icon="clarity-hard-disk-solid" :style="{ color: extendParam.color }" style="width:35px;height:35px" />
|
||||||
|
@ -27,7 +27,7 @@ const propClass = ref(props.class)
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full">
|
<div class="generic-monitor-card w-full">
|
||||||
<ItemCard
|
<ItemCard
|
||||||
:card-type-style="cardTypeStyle"
|
:card-type-style="cardTypeStyle"
|
||||||
:icon-text="iconText"
|
:icon-text="iconText"
|
||||||
|
@ -17,8 +17,8 @@ defineProps<Prop>()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full">
|
<template v-if="cardTypeStyle === PanelPanelConfigStyleEnum.info">
|
||||||
<div v-if="cardTypeStyle === PanelPanelConfigStyleEnum.info">
|
<div class="w-full">
|
||||||
<div class="mb-1 text-xs" :style="{ color: textColor }">
|
<div class="mb-1 text-xs" :style="{ color: textColor }">
|
||||||
<span>
|
<span>
|
||||||
{{ infoCardLeftText }}
|
{{ infoCardLeftText }}
|
||||||
@ -38,20 +38,20 @@ defineProps<Prop>()
|
|||||||
style="max-width: 135px;"
|
style="max-width: 135px;"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
</template>
|
||||||
<div class="flex justify-center h-full w-full mt-3">
|
<template v-else>
|
||||||
<NProgress
|
<div class="w-full flex justify-center h-full w-full mt-3">
|
||||||
:color="progressColor"
|
<NProgress
|
||||||
:rail-color="progressRailColor"
|
:color="progressColor"
|
||||||
type="dashboard"
|
:rail-color="progressRailColor"
|
||||||
:percentage="percentage" :stroke-width="15"
|
type="dashboard"
|
||||||
style="width: 50px;"
|
:percentage="percentage" :stroke-width="15"
|
||||||
>
|
style="width: 50px;"
|
||||||
<div class="text-white" style="font-size: 8px;" :style="{ color: textColor }">
|
>
|
||||||
{{ percentage }}%
|
<div class="text-white" style="font-size: 8px;" :style="{ color: textColor }">
|
||||||
</div>
|
{{ percentage }}%
|
||||||
</NProgress>
|
</div>
|
||||||
</div>
|
</NProgress>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
@ -171,7 +171,7 @@ function handleRightMenuSelect(key: string | number) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full">
|
<div class="system-monitor w-full">
|
||||||
<div
|
<div
|
||||||
class="mt-[50px]"
|
class="mt-[50px]"
|
||||||
:class="monitorGroup.sortStatus ? 'shadow-2xl border shadow-[0_0_30px_10px_rgba(0,0,0,0.3)] p-[10px] rounded-2xl' : ''"
|
:class="monitorGroup.sortStatus ? 'shadow-2xl border shadow-[0_0_30px_10px_rgba(0,0,0,0.3)] p-[10px] rounded-2xl' : ''"
|
||||||
@ -179,13 +179,13 @@ function handleRightMenuSelect(key: string | number) {
|
|||||||
@mouseleave="handleSetHoverStatus(false)"
|
@mouseleave="handleSetHoverStatus(false)"
|
||||||
>
|
>
|
||||||
<!-- 分组标题 -->
|
<!-- 分组标题 -->
|
||||||
<div class="text-white text-xl font-extrabold mb-[20px] ml-[10px] flex items-center">
|
<div class="system-monitor-header text-white text-xl font-extrabold mb-[20px] ml-[10px] flex items-center">
|
||||||
<span v-if="showTitle" class="text-shadow">
|
<span v-if="showTitle" class="text-shadow">
|
||||||
{{ $t('deskModule.systemMonitor.systemState') }}
|
{{ $t('deskModule.systemMonitor.systemState') }}
|
||||||
</span>
|
</span>
|
||||||
<div
|
<div
|
||||||
v-if="allowEdit"
|
v-if="allowEdit"
|
||||||
class="ml-2 delay-100 transition-opacity flex"
|
class="system-monitor-buttons ml-2 delay-100 transition-opacity flex"
|
||||||
:class="monitorGroup.hoverStatus ? 'opacity-100' : 'opacity-0'"
|
:class="monitorGroup.hoverStatus ? 'opacity-100' : 'opacity-0'"
|
||||||
>
|
>
|
||||||
<span class="mr-2 cursor-pointer" @click="handleAddItem()">
|
<span class="mr-2 cursor-pointer" @click="handleAddItem()">
|
||||||
@ -198,7 +198,7 @@ function handleRightMenuSelect(key: string | number) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 详情图标 -->
|
<!-- 详情图标 -->
|
||||||
<div v-if="panelState.panelConfig.iconStyle === PanelPanelConfigStyleEnum.info">
|
<template v-if="panelState.panelConfig.iconStyle === PanelPanelConfigStyleEnum.info">
|
||||||
<VueDraggable
|
<VueDraggable
|
||||||
v-model="monitorDatas" item-key="sort" :animation="300"
|
v-model="monitorDatas" item-key="sort" :animation="300"
|
||||||
class="icon-info-box"
|
class="icon-info-box"
|
||||||
@ -221,39 +221,37 @@ function handleRightMenuSelect(key: string | number) {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</VueDraggable>
|
</VueDraggable>
|
||||||
</div>
|
</template>
|
||||||
|
|
||||||
<!-- APP图标宫型盒子 -->
|
<!-- APP图标宫型盒子 -->
|
||||||
<div v-if="panelState.panelConfig.iconStyle === PanelPanelConfigStyleEnum.icon">
|
<template v-if="panelState.panelConfig.iconStyle === PanelPanelConfigStyleEnum.icon">
|
||||||
<div v-if="monitorDatas">
|
<VueDraggable
|
||||||
<VueDraggable
|
v-model="monitorDatas" item-key="sort" :animation="300"
|
||||||
v-model="monitorDatas" item-key="sort" :animation="300"
|
class="icon-small-box"
|
||||||
class="icon-small-box"
|
filter=".not-drag"
|
||||||
filter=".not-drag"
|
:disabled="!monitorGroup.sortStatus"
|
||||||
:disabled="!monitorGroup.sortStatus"
|
>
|
||||||
|
<div
|
||||||
|
v-for="item, index in monitorDatas" :key="index"
|
||||||
|
:title="item.description"
|
||||||
|
@click="handleClick(index, item)"
|
||||||
|
@contextmenu="(e) => handleContextMenu(e, index, item)"
|
||||||
>
|
>
|
||||||
<div
|
<AppIconSystemMonitor
|
||||||
v-for="item, index in monitorDatas" :key="index"
|
:extend-param="item.extendParam"
|
||||||
:title="item.description"
|
:icon-text-icon-hide-title="false"
|
||||||
@click="handleClick(index, item)"
|
:card-type-style="panelState.panelConfig.iconStyle"
|
||||||
@contextmenu="(e) => handleContextMenu(e, index, item)"
|
:monitor-type="item.monitorType"
|
||||||
>
|
:card-style="cardStyle"
|
||||||
<AppIconSystemMonitor
|
:icon-text-color="panelState.panelConfig.iconTextColor"
|
||||||
:extend-param="item.extendParam"
|
/>
|
||||||
:icon-text-icon-hide-title="false"
|
</div>
|
||||||
:card-type-style="panelState.panelConfig.iconStyle"
|
</vuedraggable>
|
||||||
:monitor-type="item.monitorType"
|
</template>
|
||||||
:card-style="cardStyle"
|
|
||||||
:icon-text-color="panelState.panelConfig.iconTextColor"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</vuedraggable>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 编辑栏 -->
|
<!-- 编辑栏 -->
|
||||||
<div v-if="monitorGroup.sortStatus && allowEdit" class="flex mt-[10px]">
|
<template v-if="monitorGroup.sortStatus && allowEdit">
|
||||||
<div>
|
<div class="system-monitor-edit-bar flex mt-[10px]">
|
||||||
<NButton color="#2a2a2a6b" @click="handleSaveSort()">
|
<NButton color="#2a2a2a6b" @click="handleSaveSort()">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<SvgIcon class="text-white font-xl" icon="material-symbols:save" />
|
<SvgIcon class="text-white font-xl" icon="material-symbols:save" />
|
||||||
@ -263,7 +261,7 @@ function handleRightMenuSelect(key: string | number) {
|
|||||||
</div>
|
</div>
|
||||||
</NButton>
|
</NButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Edit v-model:visible="editShowStatus" :monitor-data="editData" :index="editIndex" @done="handleSaveDone" />
|
<Edit v-model:visible="editShowStatus" :monitor-data="editData" :index="editIndex" @done="handleSaveDone" />
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
"1004": "Account has been deactivated or inactivated",
|
"1004": "Account has been deactivated or inactivated",
|
||||||
"1005": "Currently no permission to operate",
|
"1005": "Currently no permission to operate",
|
||||||
"1006": "Account does not exist",
|
"1006": "Account does not exist",
|
||||||
|
"1007": "Old password error",
|
||||||
"1200": "database error",
|
"1200": "database error",
|
||||||
"1201": "Please keep at least one",
|
"1201": "Please keep at least one",
|
||||||
"1202": "Data record not found",
|
"1202": "Data record not found",
|
||||||
@ -38,12 +39,14 @@
|
|||||||
"apps": {
|
"apps": {
|
||||||
"about": {
|
"about": {
|
||||||
"QQGroup": "QQ Group:",
|
"QQGroup": "QQ Group:",
|
||||||
"QR": "QR Code (Recommended)",
|
"QR": "QR Code(recommend)",
|
||||||
"addQQGroupUrl": "Click to join",
|
"addQQGroupUrl": "Click to join",
|
||||||
"appName": "About",
|
"appName": "About",
|
||||||
"author": "Author:",
|
"author": "Author:",
|
||||||
"checkUpdate": "Check for new version",
|
"checkUpdate": "Check for new version",
|
||||||
|
"discussions": "Discussions:",
|
||||||
"donate": "☕Donate",
|
"donate": "☕Donate",
|
||||||
|
"frontVersionText": "Front-end version number",
|
||||||
"issue": "Feedback:",
|
"issue": "Feedback:",
|
||||||
"viewUpdateLog": "Click here to view update log"
|
"viewUpdateLog": "Click here to view update log"
|
||||||
},
|
},
|
||||||
@ -63,6 +66,7 @@
|
|||||||
"leftRightMargin": "Left-right margin",
|
"leftRightMargin": "Left-right margin",
|
||||||
"mask": "Mask",
|
"mask": "Mask",
|
||||||
"maxWidth": "Max width",
|
"maxWidth": "Max width",
|
||||||
|
"netModeChangeButtonShow": "Show network mode switch button",
|
||||||
"publicVisitModeShow": "Allow public mode display",
|
"publicVisitModeShow": "Allow public mode display",
|
||||||
"resetWarnText": "Are you sure you want to reset these styles?",
|
"resetWarnText": "Are you sure you want to reset these styles?",
|
||||||
"searchBar": "Search bar component",
|
"searchBar": "Search bar component",
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
"1004": "账号已停用或未激活",
|
"1004": "账号已停用或未激活",
|
||||||
"1005": "当前无权限操作",
|
"1005": "当前无权限操作",
|
||||||
"1006": "账号不存在",
|
"1006": "账号不存在",
|
||||||
|
"1007": "旧密码错误",
|
||||||
"1200": "数据库出错",
|
"1200": "数据库出错",
|
||||||
"1201": "请至少保留一个",
|
"1201": "请至少保留一个",
|
||||||
"1202": "未找到数据记录",
|
"1202": "未找到数据记录",
|
||||||
@ -43,7 +44,9 @@
|
|||||||
"appName": "关于",
|
"appName": "关于",
|
||||||
"author": "作者:",
|
"author": "作者:",
|
||||||
"checkUpdate": "检查新版本",
|
"checkUpdate": "检查新版本",
|
||||||
|
"discussions": "交流社区:",
|
||||||
"donate": "🧧打赏",
|
"donate": "🧧打赏",
|
||||||
|
"frontVersionText": "前端版本号",
|
||||||
"issue": "建议反馈:",
|
"issue": "建议反馈:",
|
||||||
"viewUpdateLog": "点此查看更新说明"
|
"viewUpdateLog": "点此查看更新说明"
|
||||||
},
|
},
|
||||||
@ -55,7 +58,7 @@
|
|||||||
"configFailed": "配置保存失败,{message}",
|
"configFailed": "配置保存失败,{message}",
|
||||||
"configSaved": "配置已保存",
|
"configSaved": "配置已保存",
|
||||||
"contentArea": "内容区域",
|
"contentArea": "内容区域",
|
||||||
"customFooter": "自定义footer",
|
"customFooter": "自定义页脚",
|
||||||
"customImageAddress": "展开图片链接输入框",
|
"customImageAddress": "展开图片链接输入框",
|
||||||
"detailIcon": "详情图标",
|
"detailIcon": "详情图标",
|
||||||
"hideDescription": "隐藏描述信息",
|
"hideDescription": "隐藏描述信息",
|
||||||
@ -63,6 +66,7 @@
|
|||||||
"leftRightMargin": "左右边距",
|
"leftRightMargin": "左右边距",
|
||||||
"mask": "遮罩",
|
"mask": "遮罩",
|
||||||
"maxWidth": "最大宽度",
|
"maxWidth": "最大宽度",
|
||||||
|
"netModeChangeButtonShow": "显示网络模式切换按钮",
|
||||||
"publicVisitModeShow": "公开模式允许显示",
|
"publicVisitModeShow": "公开模式允许显示",
|
||||||
"resetWarnText": "确定要重置这些样式吗?",
|
"resetWarnText": "确定要重置这些样式吗?",
|
||||||
"searchBar": "搜索栏组件",
|
"searchBar": "搜索栏组件",
|
||||||
@ -222,8 +226,8 @@
|
|||||||
"iconGroup": "分组",
|
"iconGroup": "分组",
|
||||||
"inputIconName": "请输入图标名称",
|
"inputIconName": "请输入图标名称",
|
||||||
"inputIconUrlOrUpload": "输入图标地址或上传",
|
"inputIconUrlOrUpload": "输入图标地址或上传",
|
||||||
"lanUrl": "局域网地址",
|
"lanUrl": "内网地址",
|
||||||
"lanUrlInputPlaceholder": "http(s)://(局域网模式,会跳转该地址)",
|
"lanUrlInputPlaceholder": "http(s)://(内网模式,会跳转该地址)",
|
||||||
"newWindowOpen": "新窗口打开",
|
"newWindowOpen": "新窗口打开",
|
||||||
"onlineIcon": "在线图标",
|
"onlineIcon": "在线图标",
|
||||||
"onlineIconLibrary": "在线图标库",
|
"onlineIconLibrary": "在线图标库",
|
||||||
|
@ -28,6 +28,7 @@ export function defaultStatePanelConfig(): Panel.panelConfig {
|
|||||||
systemMonitorShow: false,
|
systemMonitorShow: false,
|
||||||
systemMonitorShowTitle: true,
|
systemMonitorShowTitle: true,
|
||||||
systemMonitorPublicVisitModeShow: false,
|
systemMonitorPublicVisitModeShow: false,
|
||||||
|
netModeChangeButtonShow: true,
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ export const usePanelState = defineStore('panel', {
|
|||||||
this.recordState()
|
this.recordState()
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取云端的面板配置
|
// 获取云端(搭建的服务器)的面板配置
|
||||||
updatePanelConfigByCloud() {
|
updatePanelConfigByCloud() {
|
||||||
getUserConfig<Panel.userConfig>().then((res) => {
|
getUserConfig<Panel.userConfig>().then((res) => {
|
||||||
if (res.code === 0)
|
if (res.code === 0)
|
||||||
|
@ -17,7 +17,6 @@ export function defaultSetting(): UserState {
|
|||||||
userInfo: {
|
userInfo: {
|
||||||
// headImage: userDefaultAvatar,
|
// headImage: userDefaultAvatar,
|
||||||
name: '-- --',
|
name: '-- --',
|
||||||
// description: 'Star on <a href="https://github.com/Chanzhaoyu/chatgpt-bot" class="text-blue-500" target="_blank" >GitHub</a>',
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
src/typings/panel.d.ts
vendored
1
src/typings/panel.d.ts
vendored
@ -59,6 +59,7 @@ declare namespace Panel {
|
|||||||
systemMonitorShow?:boolean
|
systemMonitorShow?:boolean
|
||||||
systemMonitorShowTitle?:boolean
|
systemMonitorShowTitle?:boolean
|
||||||
systemMonitorPublicVisitModeShow?:boolean
|
systemMonitorPublicVisitModeShow?:boolean
|
||||||
|
netModeChangeButtonShow?:boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
interface userConfig{
|
interface userConfig{
|
||||||
|
@ -35,15 +35,15 @@ const textColor = computed(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full">
|
<div class="app-icon w-full">
|
||||||
<!-- 详情图标 -->
|
<!-- 详情图标 -->
|
||||||
<div
|
<div
|
||||||
v-if="style === PanelPanelConfigStyleEnum.info"
|
v-if="style === PanelPanelConfigStyleEnum.info"
|
||||||
class="w-full rounded-2xl transition-all duration-200 hover:shadow-[0_0_20px_10px_rgba(0,0,0,0.2)] flex"
|
class="app-icon-info w-full rounded-2xl transition-all duration-200 hover:shadow-[0_0_20px_10px_rgba(0,0,0,0.2)] flex"
|
||||||
:style="{ background: itemInfo?.icon?.backgroundColor || defaultBackground }"
|
:style="{ background: itemInfo?.icon?.backgroundColor || defaultBackground }"
|
||||||
>
|
>
|
||||||
<!-- 图标 -->
|
<!-- 图标 -->
|
||||||
<div class="w-[70px] h-[70px]">
|
<div class="app-icon-info-icon w-[70px] h-[70px]">
|
||||||
<div class="w-[70px] h-full flex items-center justify-center ">
|
<div class="w-[70px] h-full flex items-center justify-center ">
|
||||||
<ItemIcon :item-icon="itemInfo?.icon" force-background="transparent" :size="50" class="overflow-hidden rounded-xl" />
|
<ItemIcon :item-icon="itemInfo?.icon" force-background="transparent" :size="50" class="overflow-hidden rounded-xl" />
|
||||||
</div>
|
</div>
|
||||||
@ -52,13 +52,13 @@ const textColor = computed(() => {
|
|||||||
<!-- 文字 -->
|
<!-- 文字 -->
|
||||||
<!-- 如果为纯白色,将自动根据背景的明暗计算字体的黑白色 -->
|
<!-- 如果为纯白色,将自动根据背景的明暗计算字体的黑白色 -->
|
||||||
<div class="text-white flex items-center" :style="{ color: (iconTextColor === '#ffffff') ? textColor : iconTextColor, maxWidth: 'calc(100% - 80px)' }">
|
<div class="text-white flex items-center" :style="{ color: (iconTextColor === '#ffffff') ? textColor : iconTextColor, maxWidth: 'calc(100% - 80px)' }">
|
||||||
<div class="w-full">
|
<div class="app-icon-info-text-box w-full">
|
||||||
<div class="font-semibold w-full">
|
<div class="app-icon-info-text-box-title font-semibold w-full">
|
||||||
<NEllipsis>
|
<NEllipsis>
|
||||||
{{ itemInfo?.title }}
|
{{ itemInfo?.title }}
|
||||||
</NEllipsis>
|
</NEllipsis>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!iconTextInfoHideDescription">
|
<div v-if="!iconTextInfoHideDescription" class="app-icon-info-text-box-description">
|
||||||
<NEllipsis :line-clamp="2" class="text-xs">
|
<NEllipsis :line-clamp="2" class="text-xs">
|
||||||
{{ itemInfo?.description }}
|
{{ itemInfo?.description }}
|
||||||
</NEllipsis>
|
</NEllipsis>
|
||||||
@ -67,17 +67,17 @@ const textColor = computed(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 极简图标(APP) -->
|
<!-- 极简(小)图标(APP) -->
|
||||||
<div v-if="style === PanelPanelConfigStyleEnum.icon">
|
<div v-if="style === PanelPanelConfigStyleEnum.icon" class="app-icon-small">
|
||||||
<div
|
<div
|
||||||
class="overflow-hidden rounded-2xl sunpanel w-[70px] h-[70px] mx-auto rounded-2xl transition-all duration-200 hover:shadow-[0_0_20px_10px_rgba(0,0,0,0.2)]"
|
class="app-icon-small-icon overflow-hidden rounded-2xl sunpanel w-[70px] h-[70px] mx-auto rounded-2xl transition-all duration-200 hover:shadow-[0_0_20px_10px_rgba(0,0,0,0.2)]"
|
||||||
:title="itemInfo?.description"
|
:title="itemInfo?.description"
|
||||||
>
|
>
|
||||||
<ItemIcon :item-icon="itemInfo?.icon" />
|
<ItemIcon :item-icon="itemInfo?.icon" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="!iconTextIconHideTitle"
|
v-if="!iconTextIconHideTitle"
|
||||||
class="text-center app-icon-text-shadow cursor-pointer mt-[2px]"
|
class="app-icon-small-title text-center app-icon-text-shadow cursor-pointer mt-[2px]"
|
||||||
:style="{ color: iconTextColor }"
|
:style="{ color: iconTextColor }"
|
||||||
>
|
>
|
||||||
<span>{{ itemInfo?.title }}</span>
|
<span>{{ itemInfo?.title }}</span>
|
||||||
|
@ -323,9 +323,9 @@ function handleAddItem(itemIconGroupId?: number) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full h-full sun-main ">
|
<div class="w-full h-full sun-main">
|
||||||
<div
|
<div
|
||||||
class="cover" :style="{
|
class="cover wallpaper" :style="{
|
||||||
filter: `blur(${panelState.panelConfig.backgroundBlur}px)`,
|
filter: `blur(${panelState.panelConfig.backgroundBlur}px)`,
|
||||||
background: `url(${panelState.panelConfig.backgroundImageSrc}) no-repeat`,
|
background: `url(${panelState.panelConfig.backgroundImageSrc}) no-repeat`,
|
||||||
backgroundSize: 'cover',
|
backgroundSize: 'cover',
|
||||||
@ -345,12 +345,12 @@ function handleAddItem(itemIconGroupId?: number) {
|
|||||||
<!-- 头 -->
|
<!-- 头 -->
|
||||||
<div class="mx-[auto] w-[80%]">
|
<div class="mx-[auto] w-[80%]">
|
||||||
<div class="flex mx-[auto] items-center justify-center text-white">
|
<div class="flex mx-[auto] items-center justify-center text-white">
|
||||||
<div>
|
<div class="logo">
|
||||||
<span class="text-2xl md:text-6xl font-bold text-shadow">
|
<span class="text-2xl md:text-6xl font-bold text-shadow">
|
||||||
{{ panelState.panelConfig.logoText }}
|
{{ panelState.panelConfig.logoText }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-base lg:text-2xl mx-[10px]">
|
<div class="divider text-base lg:text-2xl mx-[10px]">
|
||||||
|
|
|
|
||||||
</div>
|
</div>
|
||||||
<div class="text-shadow">
|
<div class="text-shadow">
|
||||||
@ -380,19 +380,19 @@ function handleAddItem(itemIconGroupId?: number) {
|
|||||||
<!-- 组纵向排列 -->
|
<!-- 组纵向排列 -->
|
||||||
<div
|
<div
|
||||||
v-for="(itemGroup, itemGroupIndex) in filterItems" :key="itemGroupIndex"
|
v-for="(itemGroup, itemGroupIndex) in filterItems" :key="itemGroupIndex"
|
||||||
class="mt-[50px]"
|
class="item-list mt-[50px]"
|
||||||
:class="itemGroup.sortStatus ? 'shadow-2xl border shadow-[0_0_30px_10px_rgba(0,0,0,0.3)] p-[10px] rounded-2xl' : ''"
|
:class="itemGroup.sortStatus ? 'shadow-2xl border shadow-[0_0_30px_10px_rgba(0,0,0,0.3)] p-[10px] rounded-2xl' : ''"
|
||||||
@mouseenter="handleSetHoverStatus(itemGroupIndex, true)"
|
@mouseenter="handleSetHoverStatus(itemGroupIndex, true)"
|
||||||
@mouseleave="handleSetHoverStatus(itemGroupIndex, false)"
|
@mouseleave="handleSetHoverStatus(itemGroupIndex, false)"
|
||||||
>
|
>
|
||||||
<!-- 分组标题 -->
|
<!-- 分组标题 -->
|
||||||
<div class="text-white text-xl font-extrabold mb-[20px] ml-[10px] flex items-center">
|
<div class="text-white text-xl font-extrabold mb-[20px] ml-[10px] flex items-center">
|
||||||
<span class="text-shadow">
|
<span class="group-title text-shadow">
|
||||||
{{ itemGroup.title }}
|
{{ itemGroup.title }}
|
||||||
</span>
|
</span>
|
||||||
<div
|
<div
|
||||||
v-if="authStore.visitMode === VisitMode.VISIT_MODE_LOGIN"
|
v-if="authStore.visitMode === VisitMode.VISIT_MODE_LOGIN"
|
||||||
class="ml-2 delay-100 transition-opacity flex"
|
class="group-buttons ml-2 delay-100 transition-opacity flex"
|
||||||
:class="itemGroup.hoverStatus ? 'opacity-100' : 'opacity-0'"
|
:class="itemGroup.hoverStatus ? 'opacity-100' : 'opacity-0'"
|
||||||
>
|
>
|
||||||
<span class="mr-2 cursor-pointer" :title="t('common.add')" @click="handleAddItem(itemGroup.id)">
|
<span class="mr-2 cursor-pointer" :title="t('common.add')" @click="handleAddItem(itemGroup.id)">
|
||||||
@ -503,10 +503,11 @@ function handleAddItem(itemIconGroupId?: number) {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 悬浮按钮 -->
|
<!-- 悬浮按钮 -->
|
||||||
<div class="fixed-element shadow-[0_0_10px_2px_rgba(0,0,0,0.2)]">
|
<div class="fixed-element shadow-[0_0_10px_2px_rgba(0,0,0,0.2)]">
|
||||||
<NButtonGroup vertical>
|
<NButtonGroup vertical>
|
||||||
|
<!-- 网络模式切换按钮组 -->
|
||||||
<NButton
|
<NButton
|
||||||
v-if="panelState.networkMode === PanelStateNetworkModeEnum.lan" color="#2a2a2a6b"
|
v-if="panelState.networkMode === PanelStateNetworkModeEnum.lan && panelState.panelConfig.netModeChangeButtonShow" color="#2a2a2a6b"
|
||||||
:title="t('panelHome.changeToWanModel')" @click="handleChangeNetwork(PanelStateNetworkModeEnum.wan)"
|
:title="t('panelHome.changeToWanModel')" @click="handleChangeNetwork(PanelStateNetworkModeEnum.wan)"
|
||||||
>
|
>
|
||||||
<template #icon>
|
<template #icon>
|
||||||
@ -515,7 +516,7 @@ function handleAddItem(itemIconGroupId?: number) {
|
|||||||
</NButton>
|
</NButton>
|
||||||
|
|
||||||
<NButton
|
<NButton
|
||||||
v-if="panelState.networkMode === PanelStateNetworkModeEnum.wan" color="#2a2a2a6b"
|
v-if="panelState.networkMode === PanelStateNetworkModeEnum.wan && panelState.panelConfig.netModeChangeButtonShow" color="#2a2a2a6b"
|
||||||
:title="t('panelHome.changeToLanModel')" @click="handleChangeNetwork(PanelStateNetworkModeEnum.lan)"
|
:title="t('panelHome.changeToLanModel')" @click="handleChangeNetwork(PanelStateNetworkModeEnum.lan)"
|
||||||
>
|
>
|
||||||
<template #icon>
|
<template #icon>
|
||||||
@ -536,25 +537,25 @@ function handleAddItem(itemIconGroupId?: number) {
|
|||||||
</NButton>
|
</NButton>
|
||||||
</NButtonGroup>
|
</NButtonGroup>
|
||||||
|
|
||||||
<NBackTop
|
|
||||||
:listen-to="() => scrollContainerRef"
|
|
||||||
:right="10"
|
|
||||||
:bottom="10"
|
|
||||||
style="background-color:transparent;border: none;box-shadow: none;"
|
|
||||||
>
|
|
||||||
<div class="shadow-[0_0_10px_2px_rgba(0,0,0,0.2)]">
|
|
||||||
<NButton color="#2a2a2a6b">
|
|
||||||
<template #icon>
|
|
||||||
<SvgIcon class="text-white font-xl" icon="icon-park-outline:to-top" />
|
|
||||||
</template>
|
|
||||||
</NButton>
|
|
||||||
</div>
|
|
||||||
</NBackTop>
|
|
||||||
|
|
||||||
<AppStarter v-model:visible="settingModalShow" />
|
<AppStarter v-model:visible="settingModalShow" />
|
||||||
<!-- <Setting v-model:visible="settingModalShow" /> -->
|
<!-- <Setting v-model:visible="settingModalShow" /> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<NBackTop
|
||||||
|
:listen-to="() => scrollContainerRef"
|
||||||
|
:right="10"
|
||||||
|
:bottom="10"
|
||||||
|
style="background-color:transparent;border: none;box-shadow: none;"
|
||||||
|
>
|
||||||
|
<div class="shadow-[0_0_10px_2px_rgba(0,0,0,0.2)]">
|
||||||
|
<NButton color="#2a2a2a6b">
|
||||||
|
<template #icon>
|
||||||
|
<SvgIcon class="text-white font-xl" icon="icon-park-outline:to-top" />
|
||||||
|
</template>
|
||||||
|
</NButton>
|
||||||
|
</div>
|
||||||
|
</NBackTop>
|
||||||
|
|
||||||
<EditItem v-model:visible="editItemInfoShow" :item-info="editItemInfoData" :item-group-id="currentAddItenIconGroupId" @done="handleEditSuccess" />
|
<EditItem v-model:visible="editItemInfoShow" :item-info="editItemInfoData" :item-group-id="currentAddItenIconGroupId" @done="handleEditSuccess" />
|
||||||
|
|
||||||
<!-- 弹窗 -->
|
<!-- 弹窗 -->
|
||||||
|
Loading…
x
Reference in New Issue
Block a user