更新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
|
||||
|
||||
EXPOSE 3002
|
||||
|
||||
RUN apk add --no-cache bash ca-certificates su-exec tzdata \
|
||||
&& chmod +x ./sun-panel \
|
||||
&& ./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",
|
||||
"version": "2.10.9",
|
||||
"version": "0.0.0",
|
||||
"private": false,
|
||||
"description": "ChatGPT Web",
|
||||
"author": "ChenZhaoYu <chenzhaoyu1994@gmail.com>",
|
||||
"description": "Sun-Panel Web",
|
||||
"author": "BraisedHunter <95302870@qq.com>",
|
||||
"keywords": [
|
||||
"Sun-Panel",
|
||||
"chatgpt",
|
||||
"chatbot",
|
||||
"vue"
|
||||
],
|
||||
"scripts": {
|
||||
"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",
|
||||
"build-only": "vite build",
|
||||
"type-check": "vue-tsc --noEmit",
|
||||
|
@ -1,12 +1,15 @@
|
||||
package apiReturn
|
||||
|
||||
var ErrorCodeMap = map[int]string{
|
||||
// -1:操作失败
|
||||
// -1:操作失败(前端会自动弹窗)
|
||||
// 100: "operation failed",
|
||||
|
||||
1000: "Not logged in yet", // 还未登录
|
||||
1003: "Incorrect username or password", // 用户名或密码错误
|
||||
1004: "Account disabled or not activated", // 账号已停用或未激活
|
||||
1005: "No current permission for operation", // 当前无权限操作
|
||||
1006: "Account does not exist", // 账号不存在
|
||||
1007: "Old password error", // 旧密码不正确
|
||||
|
||||
// 数据类
|
||||
1200: "Database error", // 数据库错误
|
||||
|
@ -28,7 +28,8 @@ func (a *ItemIcon) Edit(c *gin.Context) {
|
||||
}
|
||||
|
||||
if req.ItemIconGroupId == 0 {
|
||||
apiReturn.Error(c, "Group is mandatory")
|
||||
// apiReturn.Error(c, "Group is mandatory")
|
||||
apiReturn.ErrorParamFomat(c, "Group is mandatory")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ func (a *UserApi) UpdatePasssword(c *gin.Context) {
|
||||
} else {
|
||||
if v.Password != cmn.PasswordEncryption(params.OldPassword) {
|
||||
// 旧密码不正确
|
||||
apiReturn.Error(c, global.Lang.Get("user.api_old_pass_error"))
|
||||
apiReturn.ErrorByCode(c, 1007)
|
||||
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 {
|
||||
log.Panicln("日志初始化错误", err)
|
||||
log.Panicln("Log initialization error", err)
|
||||
panic(err)
|
||||
} else {
|
||||
global.Logger = logger
|
||||
@ -47,7 +47,7 @@ func InitApp() error {
|
||||
// 配置初始化
|
||||
{
|
||||
if config, err := config.ConfigInit(); err != nil {
|
||||
global.Logger.Errorln("配置初始化错误", err)
|
||||
global.Logger.Errorln("Configuration initialization error", err)
|
||||
return err
|
||||
} else {
|
||||
global.Config = config
|
||||
@ -74,7 +74,7 @@ func InitApp() error {
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Panicln("Redis初始化错误", err)
|
||||
log.Panicln("Redis initialization error", err)
|
||||
panic(err)
|
||||
// return err
|
||||
}
|
||||
@ -114,7 +114,7 @@ func DatabaseConnect() {
|
||||
}
|
||||
|
||||
if db, err := database.DbInit(dbClientInfo); err != nil {
|
||||
log.Panicln("数据库初始化错误", err)
|
||||
log.Panicln("Database initialization error", err)
|
||||
panic(err)
|
||||
} else {
|
||||
global.Db = db
|
||||
@ -133,17 +133,17 @@ func CommandRun() {
|
||||
pwd bool
|
||||
)
|
||||
|
||||
flag.BoolVar(&cfg, "config", false, "生成配置文件")
|
||||
flag.BoolVar(&pwd, "password-reset", false, "重置第一个用户的密码")
|
||||
flag.BoolVar(&cfg, "config", false, "Generate configuration file")
|
||||
flag.BoolVar(&pwd, "password-reset", false, "Reset the password of the first user")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
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.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) // 务必退出
|
||||
} else if pwd {
|
||||
// 重置密码
|
||||
@ -171,9 +171,9 @@ func CommandRun() {
|
||||
os.Exit(0) // 务必退出
|
||||
}
|
||||
|
||||
fmt.Println("密码已经重置成功,以下是账号信息")
|
||||
fmt.Println("用户名 ", userInfo.Username)
|
||||
fmt.Println("密码 ", newPassword)
|
||||
fmt.Println("The password has been successfully reset. Here is the account information")
|
||||
fmt.Println("Username ", userInfo.Username)
|
||||
fmt.Println("Password ", newPassword)
|
||||
os.Exit(0) // 务必退出
|
||||
} else {
|
||||
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">
|
||||
import { NDivider, NGradientText } from 'naive-ui'
|
||||
import { NDivider, NGradientText, NTag } from 'naive-ui'
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { get } from '@/api/system/about'
|
||||
import { useAppStore } from '@/store'
|
||||
import srcSvglogo from '@/assets/logo.svg'
|
||||
import srcGitee from '@/assets/about_image/gitee.png'
|
||||
import srcGithub from '@/assets/about_image/github.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'
|
||||
|
||||
interface Version {
|
||||
@ -14,8 +17,10 @@ interface Version {
|
||||
versionCode: number
|
||||
}
|
||||
|
||||
const appStore = useAppStore()
|
||||
const versionName = ref('')
|
||||
const qqGroupQRShow = ref(false)
|
||||
const frontVersion = import.meta.env.VITE_APP_VERSION || 'unknown'
|
||||
|
||||
onMounted(() => {
|
||||
get<Version>().then((res) => {
|
||||
@ -26,43 +31,44 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="pt-10">
|
||||
<div>
|
||||
<div class="flex flex-col items-center justify-center">
|
||||
<img :src="srcSvglogo" width="100" height="100" alt="">
|
||||
<div class="text-3xl font-semibold">
|
||||
{{ $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 class="pt-5">
|
||||
<div class="flex flex-col items-center justify-center">
|
||||
<img :src="srcSvglogo" width="100" height="100" alt="">
|
||||
<div class="text-3xl font-semibold">
|
||||
{{ $t('common.appName') }}
|
||||
</div>
|
||||
</div>
|
||||
<NDivider> • </NDivider>
|
||||
<div class="flex flex-col items-center justify-center text-base">
|
||||
<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 class="mt-2">
|
||||
<a href="https://github.com/hslr-s/sun-panel/releases" target="_blank" class="link">{{ $t('apps.about.checkUpdate') }}</a>
|
||||
</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>
|
||||
{{ $t('apps.about.issue') }}<a href="https://github.com/hslr-s/sun-panel/issues" target="_blank" class="link">Github Issues</a>
|
||||
</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">
|
||||
{{ $t('apps.about.QR') }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<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 class="flex mt-[10px]">
|
||||
<div class="flex mt-[10px] flex-wrap justify-center">
|
||||
<div class="flex items-center mx-[10px]">
|
||||
<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>
|
||||
@ -75,6 +81,21 @@ onMounted(() => {
|
||||
<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>
|
||||
</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>
|
||||
|
||||
<RoundCardModal v-model:show="qqGroupQRShow" title="交流群二维码" style="width: 300px;">
|
||||
|
@ -237,6 +237,13 @@ function resetPanelConfig() {
|
||||
</div>
|
||||
|
||||
<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">
|
||||
<div class="flex items-center mt-[10px]">
|
||||
<span class="mr-[10px]">{{ $t('apps.baseSettings.maxWidth') }}</span>
|
||||
|
@ -104,14 +104,6 @@ function handleUpdatePassword(e: MouseEvent) {
|
||||
updatePasswordModalState.value.show = false
|
||||
ms.success(t('common.success'))
|
||||
}
|
||||
else if (code === 0) {
|
||||
// 旧密码错误
|
||||
|
||||
}
|
||||
else {
|
||||
// 其他错误
|
||||
ms.error(`${t('common.failed')}:${msg}`)
|
||||
}
|
||||
}).finally(() => {
|
||||
updatePasswordModalState.value.loading = false
|
||||
}).catch(() => {
|
||||
|
@ -18,11 +18,11 @@ const propClass = ref(props.class)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full">
|
||||
<div class="item-card w-full">
|
||||
<!-- 详情图标 -->
|
||||
<div
|
||||
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"
|
||||
:style="{ backgroundColor: backgroundColor ?? defaultBackground }"
|
||||
>
|
||||
@ -32,9 +32,10 @@ const propClass = ref(props.class)
|
||||
<!-- 极简图标(APP) -->
|
||||
<div
|
||||
v-if="cardTypeStyle === PanelPanelConfigStyleEnum.icon"
|
||||
class="item-card-small"
|
||||
>
|
||||
<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"
|
||||
:style="{ backgroundColor: backgroundColor ?? defaultBackground }"
|
||||
>
|
||||
@ -43,7 +44,7 @@ const propClass = ref(props.class)
|
||||
|
||||
<div
|
||||
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 }"
|
||||
>
|
||||
{{ iconText }}
|
||||
|
@ -21,32 +21,32 @@ const iconExt = computed(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :style="defaultStyle">
|
||||
<div class="item-icon" :style="defaultStyle">
|
||||
<slot>
|
||||
<div v-if="itemIcon">
|
||||
<div v-if="itemIcon?.itemType === 1">
|
||||
<template v-if="itemIcon">
|
||||
<template v-if="itemIcon?.itemType === 1">
|
||||
<NAvatar :size="props.size" :style="{ backgroundColor: (forceBackground ?? itemIcon?.backgroundColor) || defaultBackground }">
|
||||
{{ itemIcon.text }}
|
||||
</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">
|
||||
<img :src="itemIcon?.src" class="w-[35px] h-[35px]">
|
||||
</div>
|
||||
<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 }">
|
||||
<SvgIconOnline style="font-size: 35px;" :icon="itemIcon.text" />
|
||||
</NAvatar>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<div v-else>
|
||||
<template v-else>
|
||||
<NAvatar :size="props.size" />
|
||||
</div>
|
||||
</template>
|
||||
</slot>
|
||||
</div>
|
||||
</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>
|
||||
|
||||
<template>
|
||||
<div class="w-full text-center">
|
||||
<span class="text-2xl sm:text-2xl md:text-3xl font-[600]">
|
||||
<div class="clock w-full text-center">
|
||||
<span class="clock-time text-2xl sm:text-2xl md:text-3xl font-[600]">
|
||||
{{ currentDate.time }}
|
||||
</span>
|
||||
<div class="hidden sm:hidden md:block">
|
||||
<span class="mr-1">
|
||||
<span class="clock-date mr-1">
|
||||
{{ currentDate.date }}
|
||||
</span>
|
||||
<span>
|
||||
<span class="clock-week">
|
||||
{{ currentDate.week }}
|
||||
</span>
|
||||
</div>
|
||||
|
@ -120,18 +120,18 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<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="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" />
|
||||
</div>
|
||||
|
||||
<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" />
|
||||
</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" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onUnmounted, ref } from 'vue'
|
||||
import GenericProgress from '../components/GenericProgress/index.vue'
|
||||
import { correctionNumber, correctionNumberByCardStyle } from './common'
|
||||
import { getCpuState } from '@/api/system/systemMonitor'
|
||||
import type { PanelPanelConfigStyleEnum } from '@/enums'
|
||||
|
||||
@ -16,10 +17,6 @@ const props = defineProps<Prop>()
|
||||
let timer: NodeJS.Timer
|
||||
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() {
|
||||
try {
|
||||
const { data, code } = await getCpuState<SystemMonitor.CPUInfo>()
|
||||
@ -44,16 +41,15 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full">
|
||||
<GenericProgress
|
||||
:progress-color="progressColor"
|
||||
:progress-rail-color="progressRailColor"
|
||||
:progress-height="5"
|
||||
:percentage="correctionNumber(cpuState?.usages[0] || 0)"
|
||||
:card-type-style="cardTypeStyle"
|
||||
:info-card-right-text="`${correctionNumber(cpuState?.usages[0] || 0)}%`"
|
||||
info-card-left-text="CPU"
|
||||
:text-color="textColor"
|
||||
/>
|
||||
</div>
|
||||
<GenericProgress
|
||||
:progress-color="progressColor"
|
||||
:progress-rail-color="progressRailColor"
|
||||
:progress-height="5"
|
||||
:percentage="correctionNumberByCardStyle(cpuState?.usages[0] || 0, cardTypeStyle)"
|
||||
:card-type-style="cardTypeStyle"
|
||||
:info-card-right-text="`${correctionNumber(cpuState?.usages[0] || 0)}%`"
|
||||
info-card-left-text="CPU"
|
||||
:text-color="textColor"
|
||||
style="width: 100%;"
|
||||
/>
|
||||
</template>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onUnmounted, ref } from 'vue'
|
||||
import GenericProgress from '../components/GenericProgress/index.vue'
|
||||
import { correctionNumberByCardStyle } from './common'
|
||||
import type { PanelPanelConfigStyleEnum } from '@/enums'
|
||||
import { bytesToSize } from '@/utils/cmn'
|
||||
import { getDiskStateByPath } from '@/api/system/systemMonitor'
|
||||
@ -18,10 +19,6 @@ const props = defineProps<Prop>()
|
||||
let timer: NodeJS.Timer
|
||||
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 {
|
||||
return bytesToSize(v)
|
||||
}
|
||||
@ -54,16 +51,14 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full">
|
||||
<GenericProgress
|
||||
:progress-color="progressColor"
|
||||
:progress-rail-color="progressRailColor"
|
||||
:progress-height="5"
|
||||
:percentage="correctionNumber(diskState?.usedPercent || 0)"
|
||||
:card-type-style="cardTypeStyle"
|
||||
:info-card-right-text="`${formatdiskSize(formatdiskToByte(diskState?.used || 0))}/${formatdiskSize(formatdiskToByte(diskState?.free || 0))}`"
|
||||
:info-card-left-text="diskState?.mountpoint"
|
||||
:text-color="textColor"
|
||||
/>
|
||||
</div>
|
||||
<GenericProgress
|
||||
:progress-color="progressColor"
|
||||
:progress-rail-color="progressRailColor"
|
||||
:progress-height="5"
|
||||
:percentage="correctionNumberByCardStyle(diskState?.usedPercent || 0, cardTypeStyle)"
|
||||
:card-type-style="cardTypeStyle"
|
||||
:info-card-right-text="`${formatdiskSize(formatdiskToByte(diskState?.used || 0))}/${formatdiskSize(formatdiskToByte(diskState?.free || 0))}`"
|
||||
:info-card-left-text="diskState?.mountpoint"
|
||||
:text-color="textColor"
|
||||
/>
|
||||
</template>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onUnmounted, ref } from 'vue'
|
||||
import GenericProgress from '../components/GenericProgress/index.vue'
|
||||
import { correctionNumberByCardStyle } from './common'
|
||||
import { getMemonyState } from '@/api/system/systemMonitor'
|
||||
import type { PanelPanelConfigStyleEnum } from '@/enums'
|
||||
import { bytesToSize } from '@/utils/cmn'
|
||||
@ -17,10 +18,6 @@ const props = defineProps<Prop>()
|
||||
let timer: NodeJS.Timer
|
||||
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 {
|
||||
return bytesToSize(v)
|
||||
}
|
||||
@ -49,16 +46,14 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full">
|
||||
<GenericProgress
|
||||
:progress-color="progressColor"
|
||||
:progress-rail-color="progressRailColor"
|
||||
:progress-height="5"
|
||||
:percentage="correctionNumber(memoryState?.usedPercent || 0)"
|
||||
:card-type-style="cardTypeStyle"
|
||||
:info-card-right-text="`${formatMemorySize(memoryState?.used || 0)}/${formatMemorySize((memoryState?.total || 0) - (memoryState?.used || 0) || 0)}`"
|
||||
info-card-left-text="RAM"
|
||||
:text-color="textColor"
|
||||
/>
|
||||
</div>
|
||||
<GenericProgress
|
||||
:progress-color="progressColor"
|
||||
:progress-rail-color="progressRailColor"
|
||||
:progress-height="5"
|
||||
:percentage="correctionNumberByCardStyle(memoryState?.usedPercent || 0, cardTypeStyle)"
|
||||
:card-type-style="cardTypeStyle"
|
||||
:info-card-right-text="`${formatMemorySize(memoryState?.used || 0)}/${formatMemorySize((memoryState?.total || 0) - (memoryState?.used || 0) || 0)}`"
|
||||
info-card-left-text="RAM"
|
||||
:text-color="textColor"
|
||||
/>
|
||||
</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>
|
||||
<!-- 图标 -->
|
||||
<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.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" />
|
||||
|
@ -27,7 +27,7 @@ const propClass = ref(props.class)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full">
|
||||
<div class="generic-monitor-card w-full">
|
||||
<ItemCard
|
||||
:card-type-style="cardTypeStyle"
|
||||
:icon-text="iconText"
|
||||
|
@ -17,8 +17,8 @@ defineProps<Prop>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full">
|
||||
<div v-if="cardTypeStyle === PanelPanelConfigStyleEnum.info">
|
||||
<template v-if="cardTypeStyle === PanelPanelConfigStyleEnum.info">
|
||||
<div class="w-full">
|
||||
<div class="mb-1 text-xs" :style="{ color: textColor }">
|
||||
<span>
|
||||
{{ infoCardLeftText }}
|
||||
@ -38,20 +38,20 @@ defineProps<Prop>()
|
||||
style="max-width: 135px;"
|
||||
/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="flex justify-center h-full w-full mt-3">
|
||||
<NProgress
|
||||
:color="progressColor"
|
||||
:rail-color="progressRailColor"
|
||||
type="dashboard"
|
||||
:percentage="percentage" :stroke-width="15"
|
||||
style="width: 50px;"
|
||||
>
|
||||
<div class="text-white" style="font-size: 8px;" :style="{ color: textColor }">
|
||||
{{ percentage }}%
|
||||
</div>
|
||||
</NProgress>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="w-full flex justify-center h-full w-full mt-3">
|
||||
<NProgress
|
||||
:color="progressColor"
|
||||
:rail-color="progressRailColor"
|
||||
type="dashboard"
|
||||
:percentage="percentage" :stroke-width="15"
|
||||
style="width: 50px;"
|
||||
>
|
||||
<div class="text-white" style="font-size: 8px;" :style="{ color: textColor }">
|
||||
{{ percentage }}%
|
||||
</div>
|
||||
</NProgress>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
@ -171,7 +171,7 @@ function handleRightMenuSelect(key: string | number) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full">
|
||||
<div class="system-monitor w-full">
|
||||
<div
|
||||
class="mt-[50px]"
|
||||
: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)"
|
||||
>
|
||||
<!-- 分组标题 -->
|
||||
<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">
|
||||
{{ $t('deskModule.systemMonitor.systemState') }}
|
||||
</span>
|
||||
<div
|
||||
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'"
|
||||
>
|
||||
<span class="mr-2 cursor-pointer" @click="handleAddItem()">
|
||||
@ -198,7 +198,7 @@ function handleRightMenuSelect(key: string | number) {
|
||||
</div>
|
||||
|
||||
<!-- 详情图标 -->
|
||||
<div v-if="panelState.panelConfig.iconStyle === PanelPanelConfigStyleEnum.info">
|
||||
<template v-if="panelState.panelConfig.iconStyle === PanelPanelConfigStyleEnum.info">
|
||||
<VueDraggable
|
||||
v-model="monitorDatas" item-key="sort" :animation="300"
|
||||
class="icon-info-box"
|
||||
@ -221,39 +221,37 @@ function handleRightMenuSelect(key: string | number) {
|
||||
/>
|
||||
</div>
|
||||
</VueDraggable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- APP图标宫型盒子 -->
|
||||
<div v-if="panelState.panelConfig.iconStyle === PanelPanelConfigStyleEnum.icon">
|
||||
<div v-if="monitorDatas">
|
||||
<VueDraggable
|
||||
v-model="monitorDatas" item-key="sort" :animation="300"
|
||||
class="icon-small-box"
|
||||
filter=".not-drag"
|
||||
:disabled="!monitorGroup.sortStatus"
|
||||
<template v-if="panelState.panelConfig.iconStyle === PanelPanelConfigStyleEnum.icon">
|
||||
<VueDraggable
|
||||
v-model="monitorDatas" item-key="sort" :animation="300"
|
||||
class="icon-small-box"
|
||||
filter=".not-drag"
|
||||
: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
|
||||
v-for="item, index in monitorDatas" :key="index"
|
||||
:title="item.description"
|
||||
@click="handleClick(index, item)"
|
||||
@contextmenu="(e) => handleContextMenu(e, index, item)"
|
||||
>
|
||||
<AppIconSystemMonitor
|
||||
:extend-param="item.extendParam"
|
||||
:icon-text-icon-hide-title="false"
|
||||
:card-type-style="panelState.panelConfig.iconStyle"
|
||||
:monitor-type="item.monitorType"
|
||||
:card-style="cardStyle"
|
||||
:icon-text-color="panelState.panelConfig.iconTextColor"
|
||||
/>
|
||||
</div>
|
||||
</vuedraggable>
|
||||
</div>
|
||||
</div>
|
||||
<AppIconSystemMonitor
|
||||
:extend-param="item.extendParam"
|
||||
:icon-text-icon-hide-title="false"
|
||||
:card-type-style="panelState.panelConfig.iconStyle"
|
||||
:monitor-type="item.monitorType"
|
||||
:card-style="cardStyle"
|
||||
:icon-text-color="panelState.panelConfig.iconTextColor"
|
||||
/>
|
||||
</div>
|
||||
</vuedraggable>
|
||||
</template>
|
||||
|
||||
<!-- 编辑栏 -->
|
||||
<div v-if="monitorGroup.sortStatus && allowEdit" class="flex mt-[10px]">
|
||||
<div>
|
||||
<template v-if="monitorGroup.sortStatus && allowEdit">
|
||||
<div class="system-monitor-edit-bar flex mt-[10px]">
|
||||
<NButton color="#2a2a2a6b" @click="handleSaveSort()">
|
||||
<template #icon>
|
||||
<SvgIcon class="text-white font-xl" icon="material-symbols:save" />
|
||||
@ -263,7 +261,7 @@ function handleRightMenuSelect(key: string | number) {
|
||||
</div>
|
||||
</NButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<Edit v-model:visible="editShowStatus" :monitor-data="editData" :index="editIndex" @done="handleSaveDone" />
|
||||
|
@ -25,6 +25,7 @@
|
||||
"1004": "Account has been deactivated or inactivated",
|
||||
"1005": "Currently no permission to operate",
|
||||
"1006": "Account does not exist",
|
||||
"1007": "Old password error",
|
||||
"1200": "database error",
|
||||
"1201": "Please keep at least one",
|
||||
"1202": "Data record not found",
|
||||
@ -38,12 +39,14 @@
|
||||
"apps": {
|
||||
"about": {
|
||||
"QQGroup": "QQ Group:",
|
||||
"QR": "QR Code (Recommended)",
|
||||
"QR": "QR Code(recommend)",
|
||||
"addQQGroupUrl": "Click to join",
|
||||
"appName": "About",
|
||||
"author": "Author:",
|
||||
"checkUpdate": "Check for new version",
|
||||
"discussions": "Discussions:",
|
||||
"donate": "☕Donate",
|
||||
"frontVersionText": "Front-end version number",
|
||||
"issue": "Feedback:",
|
||||
"viewUpdateLog": "Click here to view update log"
|
||||
},
|
||||
@ -63,6 +66,7 @@
|
||||
"leftRightMargin": "Left-right margin",
|
||||
"mask": "Mask",
|
||||
"maxWidth": "Max width",
|
||||
"netModeChangeButtonShow": "Show network mode switch button",
|
||||
"publicVisitModeShow": "Allow public mode display",
|
||||
"resetWarnText": "Are you sure you want to reset these styles?",
|
||||
"searchBar": "Search bar component",
|
||||
|
@ -25,6 +25,7 @@
|
||||
"1004": "账号已停用或未激活",
|
||||
"1005": "当前无权限操作",
|
||||
"1006": "账号不存在",
|
||||
"1007": "旧密码错误",
|
||||
"1200": "数据库出错",
|
||||
"1201": "请至少保留一个",
|
||||
"1202": "未找到数据记录",
|
||||
@ -43,7 +44,9 @@
|
||||
"appName": "关于",
|
||||
"author": "作者:",
|
||||
"checkUpdate": "检查新版本",
|
||||
"discussions": "交流社区:",
|
||||
"donate": "🧧打赏",
|
||||
"frontVersionText": "前端版本号",
|
||||
"issue": "建议反馈:",
|
||||
"viewUpdateLog": "点此查看更新说明"
|
||||
},
|
||||
@ -55,7 +58,7 @@
|
||||
"configFailed": "配置保存失败,{message}",
|
||||
"configSaved": "配置已保存",
|
||||
"contentArea": "内容区域",
|
||||
"customFooter": "自定义footer",
|
||||
"customFooter": "自定义页脚",
|
||||
"customImageAddress": "展开图片链接输入框",
|
||||
"detailIcon": "详情图标",
|
||||
"hideDescription": "隐藏描述信息",
|
||||
@ -63,6 +66,7 @@
|
||||
"leftRightMargin": "左右边距",
|
||||
"mask": "遮罩",
|
||||
"maxWidth": "最大宽度",
|
||||
"netModeChangeButtonShow": "显示网络模式切换按钮",
|
||||
"publicVisitModeShow": "公开模式允许显示",
|
||||
"resetWarnText": "确定要重置这些样式吗?",
|
||||
"searchBar": "搜索栏组件",
|
||||
@ -222,8 +226,8 @@
|
||||
"iconGroup": "分组",
|
||||
"inputIconName": "请输入图标名称",
|
||||
"inputIconUrlOrUpload": "输入图标地址或上传",
|
||||
"lanUrl": "局域网地址",
|
||||
"lanUrlInputPlaceholder": "http(s)://(局域网模式,会跳转该地址)",
|
||||
"lanUrl": "内网地址",
|
||||
"lanUrlInputPlaceholder": "http(s)://(内网模式,会跳转该地址)",
|
||||
"newWindowOpen": "新窗口打开",
|
||||
"onlineIcon": "在线图标",
|
||||
"onlineIconLibrary": "在线图标库",
|
||||
|
@ -28,6 +28,7 @@ export function defaultStatePanelConfig(): Panel.panelConfig {
|
||||
systemMonitorShow: false,
|
||||
systemMonitorShowTitle: true,
|
||||
systemMonitorPublicVisitModeShow: false,
|
||||
netModeChangeButtonShow: true,
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ export const usePanelState = defineStore('panel', {
|
||||
this.recordState()
|
||||
},
|
||||
|
||||
// 获取云端的面板配置
|
||||
// 获取云端(搭建的服务器)的面板配置
|
||||
updatePanelConfigByCloud() {
|
||||
getUserConfig<Panel.userConfig>().then((res) => {
|
||||
if (res.code === 0)
|
||||
|
@ -17,7 +17,6 @@ export function defaultSetting(): UserState {
|
||||
userInfo: {
|
||||
// headImage: userDefaultAvatar,
|
||||
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
|
||||
systemMonitorShowTitle?:boolean
|
||||
systemMonitorPublicVisitModeShow?:boolean
|
||||
netModeChangeButtonShow?:boolean
|
||||
}
|
||||
|
||||
interface userConfig{
|
||||
|
@ -35,15 +35,15 @@ const textColor = computed(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full">
|
||||
<div class="app-icon w-full">
|
||||
<!-- 详情图标 -->
|
||||
<div
|
||||
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 }"
|
||||
>
|
||||
<!-- 图标 -->
|
||||
<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 ">
|
||||
<ItemIcon :item-icon="itemInfo?.icon" force-background="transparent" :size="50" class="overflow-hidden rounded-xl" />
|
||||
</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="w-full">
|
||||
<div class="font-semibold w-full">
|
||||
<div class="app-icon-info-text-box w-full">
|
||||
<div class="app-icon-info-text-box-title font-semibold w-full">
|
||||
<NEllipsis>
|
||||
{{ itemInfo?.title }}
|
||||
</NEllipsis>
|
||||
</div>
|
||||
<div v-if="!iconTextInfoHideDescription">
|
||||
<div v-if="!iconTextInfoHideDescription" class="app-icon-info-text-box-description">
|
||||
<NEllipsis :line-clamp="2" class="text-xs">
|
||||
{{ itemInfo?.description }}
|
||||
</NEllipsis>
|
||||
@ -67,17 +67,17 @@ const textColor = computed(() => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 极简图标(APP) -->
|
||||
<div v-if="style === PanelPanelConfigStyleEnum.icon">
|
||||
<!-- 极简(小)图标(APP) -->
|
||||
<div v-if="style === PanelPanelConfigStyleEnum.icon" class="app-icon-small">
|
||||
<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"
|
||||
>
|
||||
<ItemIcon :item-icon="itemInfo?.icon" />
|
||||
</div>
|
||||
<div
|
||||
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 }"
|
||||
>
|
||||
<span>{{ itemInfo?.title }}</span>
|
||||
|
@ -323,9 +323,9 @@ function handleAddItem(itemIconGroupId?: number) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full h-full sun-main ">
|
||||
<div class="w-full h-full sun-main">
|
||||
<div
|
||||
class="cover" :style="{
|
||||
class="cover wallpaper" :style="{
|
||||
filter: `blur(${panelState.panelConfig.backgroundBlur}px)`,
|
||||
background: `url(${panelState.panelConfig.backgroundImageSrc}) no-repeat`,
|
||||
backgroundSize: 'cover',
|
||||
@ -345,12 +345,12 @@ function handleAddItem(itemIconGroupId?: number) {
|
||||
<!-- 头 -->
|
||||
<div class="mx-[auto] w-[80%]">
|
||||
<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">
|
||||
{{ panelState.panelConfig.logoText }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-base lg:text-2xl mx-[10px]">
|
||||
<div class="divider text-base lg:text-2xl mx-[10px]">
|
||||
|
|
||||
</div>
|
||||
<div class="text-shadow">
|
||||
@ -380,19 +380,19 @@ function handleAddItem(itemIconGroupId?: number) {
|
||||
<!-- 组纵向排列 -->
|
||||
<div
|
||||
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' : ''"
|
||||
@mouseenter="handleSetHoverStatus(itemGroupIndex, true)"
|
||||
@mouseleave="handleSetHoverStatus(itemGroupIndex, false)"
|
||||
>
|
||||
<!-- 分组标题 -->
|
||||
<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 }}
|
||||
</span>
|
||||
<div
|
||||
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'"
|
||||
>
|
||||
<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>
|
||||
<!-- 网络模式切换按钮组 -->
|
||||
<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)"
|
||||
>
|
||||
<template #icon>
|
||||
@ -515,7 +516,7 @@ function handleAddItem(itemIconGroupId?: number) {
|
||||
</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)"
|
||||
>
|
||||
<template #icon>
|
||||
@ -536,25 +537,25 @@ function handleAddItem(itemIconGroupId?: number) {
|
||||
</NButton>
|
||||
</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" />
|
||||
<!-- <Setting v-model:visible="settingModalShow" /> -->
|
||||
</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" />
|
||||
|
||||
<!-- 弹窗 -->
|
||||
|
Loading…
x
Reference in New Issue
Block a user