适配多语言
Squashed commit of the following: commit 632f86c0228c68391c01865c7576f3aa0408c102 Author: Sun <95302870@qq.com> Date: Sun Jan 7 14:47:55 2024 +0800 退出的时候清除appstore commit b9d805e49a3c6b2ad38bc8d527cb12cc8709012e Author: Sun <95302870@qq.com> Date: Sun Jan 7 13:55:20 2024 +0800 系统状态监控适配国际化 commit daece99723ec96d210241d2ca4e5a85dc5ae69bd Author: Sun <95302870@qq.com> Date: Sun Jan 7 13:09:46 2024 +0800 适配添加项目页面的国际化配置还有时钟的星期* commit 8ea2b2fe951f6266415c96a197cb8d00faef4058 Author: Sun <95302870@qq.com> Date: Sun Jan 7 12:01:55 2024 +0800 完成适配所有apps国际化 commit 21ef54e0d4afb10f560c8cb7aff666374afe0f87 Author: Sun <95302870@qq.com> Date: Sat Jan 6 21:36:07 2024 +0800 增加读取默认浏览器语言 commit 6f710bbebe63ab2800193f27c71e5c0034f11978 Author: Sun <95302870@qq.com> Date: Sat Jan 6 21:09:58 2024 +0800 登录页面增加语言选择选项 commit cb7c4a89a160ed3ef91ad566ec98e75325e7601f Author: Sun <95302870@qq.com> Date: Sat Jan 6 20:37:16 2024 +0800 首次尝试增加英文语言,并在我的信息设置 commit fb996e17cd11611d30c0e12feee00ddf7b225e32 Author: Sun <95302870@qq.com> Date: Sat Jan 6 18:22:40 2024 +0800 完成基础设置页面的语言国际化适配
This commit is contained in:
parent
ffc378a38f
commit
394c6ce20c
1
src/assets/svg-icons/ion-language.svg
Normal file
1
src/assets/svg-icons/ion-language.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 512 512"><path fill="#888888" d="m478.33 433.6l-90-218a22 22 0 0 0-40.67 0l-90 218a22 22 0 1 0 40.67 16.79L316.66 406h102.67l18.33 44.39A22 22 0 0 0 458 464a22 22 0 0 0 20.32-30.4ZM334.83 362L368 281.65L401.17 362Zm-66.99-19.08a22 22 0 0 0-4.89-30.7c-.2-.15-15-11.13-36.49-34.73c39.65-53.68 62.11-114.75 71.27-143.49H330a22 22 0 0 0 0-44H214V70a22 22 0 0 0-44 0v20H54a22 22 0 0 0 0 44h197.25c-9.52 26.95-27.05 69.5-53.79 108.36c-31.41-41.68-43.08-68.65-43.17-68.87a22 22 0 0 0-40.58 17c.58 1.38 14.55 34.23 52.86 83.93c.92 1.19 1.83 2.35 2.74 3.51c-39.24 44.35-77.74 71.86-93.85 80.74a22 22 0 1 0 21.07 38.63c2.16-1.18 48.6-26.89 101.63-85.59c22.52 24.08 38 35.44 38.93 36.1a22 22 0 0 0 30.75-4.9Z"/></svg>
|
After Width: | Height: | Size: 782 B |
@ -35,7 +35,7 @@ onMounted(() => {
|
||||
</div>
|
||||
<div class="text-xl">
|
||||
<NGradientText type="info">
|
||||
<a href="https://github.com/hslr-s/sun-panel/releases" class="font-semibold" title="点此查看更新说明" target="_blank">v{{ versionName }}</a>
|
||||
<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>
|
||||
@ -43,19 +43,19 @@ onMounted(() => {
|
||||
<NDivider> • </NDivider>
|
||||
<div class="flex flex-col items-center justify-center text-base">
|
||||
<div>
|
||||
建议反馈:<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>
|
||||
QQ交流群:<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">276594668</a>
|
||||
{{ $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">276594668</a>
|
||||
|
|
||||
<span class="link cursor-pointer" @click="qqGroupQRShow = !qqGroupQRShow">
|
||||
二维码(推荐)
|
||||
{{ $t('apps.about.QR') }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
开发者:<a href="https://blog.enianteam.com/u/sun/content/11" 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">🧧打赏</a>
|
||||
{{ $t('apps.about.author') }}<a href="https://blog.enianteam.com/u/sun/content/11" 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]">
|
||||
|
@ -91,9 +91,9 @@ async function importIcons(): Promise<string | null> {
|
||||
}
|
||||
catch (error) {
|
||||
if (error instanceof Error)
|
||||
return `发生错误: ${error.message}`
|
||||
return `${t('common.failed')}: ${error.message}`
|
||||
else
|
||||
return '发生未知错误'
|
||||
return t('common.unknownError')
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,7 +162,7 @@ function handleFileChange(options: { file: UploadFileInfo; fileList: Array<Uploa
|
||||
importCheck()
|
||||
}
|
||||
else {
|
||||
ms.error('异常请重新上传')
|
||||
ms.error(`${t('common.failed')}: ${t('common.repeatLater')}`)
|
||||
}
|
||||
uploadLoading.value = false
|
||||
}
|
||||
@ -178,13 +178,13 @@ function importCheck() {
|
||||
importObj.value = importJsonString(jsonData.value)
|
||||
if (importObj.value) {
|
||||
if (!importObj.value.isPassCheckMd5())
|
||||
importWarning.value.push('文件被修改过,谨慎导入')
|
||||
importWarning.value.push(t('apps.exportImport.fileModified'))
|
||||
|
||||
if (!importObj.value.isPassCheckConfigVersionOld())
|
||||
importWarning.value.push('配置文件版本过低,但是兼容')
|
||||
importWarning.value.push(t('apps.exportImport.warnConfigFileLow'))
|
||||
|
||||
if (!importObj.value.isPassCheckConfigVersionNew())
|
||||
importWarning.value.push('当前软件版本可能过旧,很有可能无法兼容该配置文件,请谨慎导入。推荐将软件更新到新版后再次导入')
|
||||
importWarning.value.push(t('apps.exportImport.softwareVersionLow'))
|
||||
|
||||
// (暂时不做)此处可以判断,当前的配置文件是否存在的导入项目(不存在隐藏importItems里面的值)操作变量:importItems
|
||||
|
||||
@ -196,24 +196,24 @@ function importCheck() {
|
||||
}
|
||||
catch (error) {
|
||||
if (error instanceof ConfigVersionLowError) {
|
||||
ms.error('配置文件版本过低,无法兼容')
|
||||
console.log('配置文件版本过低')
|
||||
ms.error(t('apps.exportImport.errorConfigFileLow'))
|
||||
console.error('The configuration file version is too low to be compatible')
|
||||
}
|
||||
else if (error instanceof FormatError) {
|
||||
ms.error('格式不正确,无法导入')
|
||||
console.log('格式不正确')
|
||||
ms.error(t('apps.exportImport.errorConfigFileFormat'))
|
||||
console.error('The format is incorrect and cannot be imported')
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ms.error('数据不正确')
|
||||
ms.error(t('apps.exportImport.errorConfigFileFormat'))
|
||||
}
|
||||
}
|
||||
|
||||
// 开始导出
|
||||
async function handleStartExport() {
|
||||
loading.value = true
|
||||
console.log('要导出的项目', checkedItems.value)
|
||||
// console.log('要导出的项目', checkedItems.value)
|
||||
// 获取软件版本号
|
||||
const exportResult = exportJson(version.value)
|
||||
if (checkedItems.value.includes('icons')) {
|
||||
@ -223,7 +223,7 @@ async function handleStartExport() {
|
||||
console.log('export icons finish', iconGroups)
|
||||
}
|
||||
|
||||
console.log('导出结果')
|
||||
// console.log('导出结果')
|
||||
|
||||
jsonData.value = exportResult.string()
|
||||
exportResult.exportFile()
|
||||
@ -244,14 +244,14 @@ async function handleStartImport() {
|
||||
|
||||
loading.value = false
|
||||
importRoundModalShow.value = false
|
||||
ms.success(`${t('common.success')},请手动刷新页面`)
|
||||
ms.success(`${t('common.success')}, ${t('common.refreshPage')}`)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="pt-2">
|
||||
<NAlert type="info" :bordered="false">
|
||||
<p>导入图标配置数据不会清空现有图标数据</p>
|
||||
<p>{{ $t('apps.exportImport.tip') }}</p>
|
||||
</NAlert>
|
||||
<div class="flex justify-center m-[50px]">
|
||||
<div class="m-[10px]">
|
||||
@ -266,7 +266,7 @@ async function handleStartImport() {
|
||||
<template #icon>
|
||||
<SvgIcon icon="fa6:solid-file-import" />
|
||||
</template>
|
||||
导入配置
|
||||
{{ $t('apps.exportImport.import') }}
|
||||
</NButton>
|
||||
</NUpload>
|
||||
</div>
|
||||
@ -275,7 +275,7 @@ async function handleStartImport() {
|
||||
<template #icon>
|
||||
<SvgIcon icon="fa6:solid-file-export" />
|
||||
</template>
|
||||
导出配置
|
||||
{{ $t('apps.exportImport.export') }}
|
||||
</NButton>
|
||||
</div>
|
||||
</div>
|
||||
@ -310,7 +310,7 @@ async function handleStartImport() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<RoundCardModal v-model:show="importRoundModalShow" style="max-width: 400px;" title="导入">
|
||||
<RoundCardModal v-model:show="importRoundModalShow" style="max-width: 400px;" :title=" $t('apps.exportImport.import')">
|
||||
<div v-if="importWarning.length > 0">
|
||||
<NAlert :title="$t('common.warning')" type="warning">
|
||||
<div v-for="(text, index) in importWarning " :key="index">
|
||||
@ -319,39 +319,39 @@ async function handleStartImport() {
|
||||
</NAlert>
|
||||
</div>
|
||||
<NDivider title-placement="left">
|
||||
请选择要导入的配置数据
|
||||
{{ $t('apps.exportImport.selectImportData') }}
|
||||
</NDivider>
|
||||
|
||||
<NSpace justify="center" style="margin-top: 20px;">
|
||||
<NCheckboxGroup v-model:value="checkedItems">
|
||||
<NCheckbox v-if="importItems.includes('icons')" value="icons" label="图标" />
|
||||
<NCheckbox v-if="importItems.includes('style')" value="style" label="样式配置" />
|
||||
<NCheckbox v-if="importItems.includes('icons')" value="icons" :label="$t('apps.exportImport.moduleIcon')" />
|
||||
<NCheckbox v-if="importItems.includes('style')" value="style" :label="$t('apps.exportImport.moduleStyle')" />
|
||||
</NCheckboxGroup>
|
||||
</NSpace>
|
||||
<NSpace justify="center">
|
||||
<div class="mt-[50px]">
|
||||
<NButton type="success" :disabled="checkedItems.length === 0" :loading="loading" @click="handleStartImport">
|
||||
继续导入
|
||||
{{ $t('common.continue') }}
|
||||
</NButton>
|
||||
</div>
|
||||
</NSpace>
|
||||
</RoundCardModal>
|
||||
|
||||
<RoundCardModal v-model:show="exportRoundModalShow" style="max-width: 400px;" title="导出">
|
||||
<RoundCardModal v-model:show="exportRoundModalShow" style="max-width: 400px;" :title=" $t('apps.exportImport.export')">
|
||||
<NDivider title-placement="left">
|
||||
请选择要导出的配置数据
|
||||
{{ $t('apps.exportImport.selectExportData') }}
|
||||
</NDivider>
|
||||
|
||||
<NSpace justify="center" style="margin-top: 20px;">
|
||||
<NCheckboxGroup v-model:value="checkedItems">
|
||||
<NCheckbox v-if="importItems.includes('icons')" value="icons" label="图标" />
|
||||
<NCheckbox v-if="importItems.includes('style')" value="style" label="样式配置" />
|
||||
<NCheckbox v-if="importItems.includes('icons')" value="icons" :label="$t('apps.exportImport.moduleIcon')" />
|
||||
<NCheckbox v-if="importItems.includes('style')" value="style" :label="$t('apps.exportImport.moduleStyle')" />
|
||||
</NCheckboxGroup>
|
||||
</NSpace>
|
||||
<NSpace justify="center">
|
||||
<div class="mt-[50px]">
|
||||
<NButton type="success" :disabled="checkedItems.length === 0" :loading="loading" @click="handleStartExport">
|
||||
继续导出
|
||||
{{ $t('common.continue') }}
|
||||
</NButton>
|
||||
</div>
|
||||
</NSpace>
|
||||
|
@ -5,6 +5,7 @@ import { NButton, NCard, NForm, NFormItem, NInput, useDialog, useMessage } from
|
||||
import { VueDraggable } from 'vue-draggable-plus'
|
||||
import { deletes, edit, getList, saveSort } from '@/api/panel/itemIconGroup'
|
||||
import { RoundCardModal, SvgIcon } from '@/components/common'
|
||||
import { t } from '@/locales'
|
||||
|
||||
interface EditModalArg {
|
||||
show: boolean
|
||||
@ -33,7 +34,7 @@ const editModalArg = ref<EditModalArg>({
|
||||
{
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
message: '必填项',
|
||||
message: t('form.required'),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -66,26 +67,26 @@ function handleSaveSort() {
|
||||
}
|
||||
saveSort(saveItems).then(({ code, msg }) => {
|
||||
if (code === 0) {
|
||||
ms.success('保存成功')
|
||||
ms.success(t('common.saveSuccess'))
|
||||
sortStatus.value = false
|
||||
}
|
||||
else {
|
||||
ms.error(`保存失败:${msg}`)
|
||||
ms.error(`${t('common.saveFail')}:${msg}`)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function handleDelete(groupInfo: Panel.ItemIconGroup) {
|
||||
dialog.warning({
|
||||
title: '警告',
|
||||
content: `你确定删除此分组[ ${groupInfo.title} ],删除后此分组应用图标将丢失?`,
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
title: t('common.warning'),
|
||||
content: t('apps.itemGroupManage.deleteWarnText', { name: groupInfo.title }),
|
||||
positiveText: t('common.confirm'),
|
||||
negativeText: t('common.cancel'),
|
||||
onPositiveClick: () => {
|
||||
if (groupInfo.id) {
|
||||
deletes([groupInfo.id]).then(({ code, msg }) => {
|
||||
if (code !== 0)
|
||||
ms.error(`删除失败:${msg}`)
|
||||
ms.error(t('common.deleteFail'))
|
||||
else
|
||||
refreshList()
|
||||
})
|
||||
@ -126,15 +127,15 @@ onMounted(() => {
|
||||
<div class="h-full">
|
||||
<div class="p-2">
|
||||
<NButton type="success" size="small" style="margin-right: 10px;" @click="handleAddGroup">
|
||||
新增分组
|
||||
{{ $t('common.add') }}
|
||||
</NButton>
|
||||
|
||||
<NButton v-if="!sortStatus" size="small" @click="handleDragSort">
|
||||
排序
|
||||
{{ $t('common.sort') }}
|
||||
</NButton>
|
||||
|
||||
<NButton v-else type="warning" size="small" @click="handleSaveSort">
|
||||
保存排序
|
||||
{{ $t('common.saveSort') }}
|
||||
</NButton>
|
||||
</div>
|
||||
|
||||
@ -181,8 +182,8 @@ onMounted(() => {
|
||||
|
||||
<RoundCardModal v-model:show="editModalArg.show" size="small" type="small" :title="editModalArg.editStatus === 1 ? '添加' : '编辑'" style="width: 400px;">
|
||||
<NForm ref="formRef" :model="editModalArg.model" :rules="editModalArg.rules">
|
||||
<NFormItem path="title" label="分组名称">
|
||||
<NInput v-model:value="editModalArg.model.title" type="text" :maxlength="20" show-count placeholder="请输入" />
|
||||
<NFormItem path="title" :label="$t('apps.itemGroupManage.groupName')">
|
||||
<NInput v-model:value="editModalArg.model.title" type="text" :maxlength="20" show-count />
|
||||
</NFormItem>
|
||||
|
||||
<!-- <NFormItem path="name" label="昵称">
|
||||
@ -191,7 +192,7 @@ onMounted(() => {
|
||||
</NForm>
|
||||
<template #footer>
|
||||
<NButton type="success" size="small" class="float-right" @click="handleSaveGroup">
|
||||
确定
|
||||
{{ $t('common.confirm') }}
|
||||
</NButton>
|
||||
</template>
|
||||
</RoundCardModal>
|
||||
|
@ -5,6 +5,7 @@ import { NButton, NCard, NColorPicker, NGrid, NGridItem, NInput, NInputGroup, NP
|
||||
import { useAuthStore, usePanelState } from '@/store'
|
||||
import { set as setUserConfig } from '@/api/panel/userConfig'
|
||||
import { PanelPanelConfigStyleEnum } from '@/enums/panel'
|
||||
import { t } from '@/locales'
|
||||
|
||||
const authStore = useAuthStore()
|
||||
const panelState = usePanelState()
|
||||
@ -14,11 +15,11 @@ const isSaveing = ref(false)
|
||||
|
||||
const iconTypeOptions = [
|
||||
{
|
||||
label: '详情图标',
|
||||
label: t('apps.baseSettings.detailIcon'),
|
||||
value: PanelPanelConfigStyleEnum.info,
|
||||
},
|
||||
{
|
||||
label: '小图标',
|
||||
label: t('apps.baseSettings.smallIcon'),
|
||||
value: PanelPanelConfigStyleEnum.icon,
|
||||
},
|
||||
]
|
||||
@ -61,9 +62,9 @@ function handleUploadBackgroundFinish({
|
||||
function uploadCloud() {
|
||||
setUserConfig({ panel: panelState.panelConfig }).then((res) => {
|
||||
if (res.code === 0)
|
||||
ms.success('配置已保存')
|
||||
ms.success(t('apps.baseSettings.configSaved'))
|
||||
else
|
||||
ms.error(`配置已保存${res.msg}`)
|
||||
ms.error(t('apps.baseSettings.configFailed', { message: res.msg }))
|
||||
})
|
||||
}
|
||||
|
||||
@ -82,7 +83,7 @@ function resetPanelConfig() {
|
||||
|
||||
<div>
|
||||
<div>
|
||||
文本内容
|
||||
{{ $t('apps.baseSettings.textContent') }}
|
||||
</div>
|
||||
<div class="flex items-center mt-[5px]">
|
||||
<NInput v-model:value="panelState.panelConfig.logoText" type="text" show-count :maxlength="20" placeholder="请输入文字" />
|
||||
@ -92,53 +93,53 @@ function resetPanelConfig() {
|
||||
|
||||
<NCard style="border-radius:10px" class="mt-[10px]" size="small">
|
||||
<div class="text-slate-500 mb-[5px] font-bold">
|
||||
时钟
|
||||
{{ $t('apps.baseSettings.clock') }}
|
||||
</div>
|
||||
<div class="flex items-center mt-[5px]">
|
||||
<span class="mr-[10px]">显示秒</span>
|
||||
<span class="mr-[10px]">{{ $t('apps.baseSettings.clockSecondShow') }}</span>
|
||||
<NSwitch v-model:value="panelState.panelConfig.clockShowSecond" />
|
||||
</div>
|
||||
</NCard>
|
||||
|
||||
<NCard style="border-radius:10px" class="mt-[10px]" size="small">
|
||||
<div class="text-slate-500 mb-[5px] font-bold">
|
||||
搜索框
|
||||
{{ $t('apps.baseSettings.searchBar') }}
|
||||
</div>
|
||||
<div class="flex items-center mt-[5px]">
|
||||
<span class="mr-[10px]">显示</span>
|
||||
<span class="mr-[10px]">{{ $t('common.show') }}</span>
|
||||
<NSwitch v-model:value="panelState.panelConfig.searchBoxShow" />
|
||||
</div>
|
||||
<div v-if="panelState.panelConfig.searchBoxShow" class="flex items-center mt-[5px]">
|
||||
<span class="mr-[10px]">允许搜索快捷图标</span>
|
||||
<span class="mr-[10px]">{{ $t('apps.baseSettings.searchBarSearchItem') }}</span>
|
||||
<NSwitch v-model:value="panelState.panelConfig.searchBoxSearchIcon" />
|
||||
</div>
|
||||
</NCard>
|
||||
|
||||
<NCard style="border-radius:10px" class="mt-[10px]" size="small">
|
||||
<div class="text-slate-500 mb-[5px] font-bold">
|
||||
系统监控
|
||||
{{ $t('apps.baseSettings.systemMonitorStatus') }}
|
||||
</div>
|
||||
<div class="flex items-center mt-[5px]">
|
||||
<span class="mr-[10px]">显示</span>
|
||||
<span class="mr-[10px]">{{ $t('common.show') }}</span>
|
||||
<NSwitch v-model:value="panelState.panelConfig.systemMonitorShow" />
|
||||
</div>
|
||||
<div v-if="panelState.panelConfig.systemMonitorShow" class="flex items-center mt-[5px]">
|
||||
<span class="mr-[10px]">显示标题</span>
|
||||
<span class="mr-[10px]">{{ $t('apps.baseSettings.showTitle') }}</span>
|
||||
<NSwitch v-model:value="panelState.panelConfig.systemMonitorShowTitle" />
|
||||
</div>
|
||||
<div v-if="panelState.panelConfig.systemMonitorShow" class="flex items-center mt-[5px]">
|
||||
<span class="mr-[10px]">公开模式允许显示</span>
|
||||
<span class="mr-[10px]">{{ $t('apps.baseSettings.publicVisitModeShow') }}</span>
|
||||
<NSwitch v-model:value="panelState.panelConfig.systemMonitorPublicVisitModeShow" />
|
||||
</div>
|
||||
</NCard>
|
||||
|
||||
<NCard style="border-radius:10px" class="mt-[10px]" size="small">
|
||||
<div class="text-slate-500 mb-[5px] font-bold">
|
||||
图标
|
||||
{{ $t('common.icon') }}
|
||||
</div>
|
||||
<div class="mt-[5px]">
|
||||
<div>
|
||||
样式
|
||||
{{ $t('common.style') }}
|
||||
</div>
|
||||
<div class="flex items-center mt-[5px]">
|
||||
<NSelect v-model:value="panelState.panelConfig.iconStyle" :options="iconTypeOptions" />
|
||||
@ -147,7 +148,7 @@ function resetPanelConfig() {
|
||||
|
||||
<div v-if="panelState.panelConfig.iconStyle === PanelPanelConfigStyleEnum.info" class="mt-[5px]">
|
||||
<div>
|
||||
隐藏描述信息
|
||||
{{ $t('apps.baseSettings.hideDescription') }}
|
||||
</div>
|
||||
<div class="flex items-center mt-[5px]">
|
||||
<NSwitch v-model:value="panelState.panelConfig.iconTextInfoHideDescription" />
|
||||
@ -156,7 +157,7 @@ function resetPanelConfig() {
|
||||
|
||||
<div v-if="panelState.panelConfig.iconStyle === PanelPanelConfigStyleEnum.icon" class="mt-[5px]">
|
||||
<div>
|
||||
隐藏标题
|
||||
{{ $t('apps.baseSettings.hideTitle') }}
|
||||
</div>
|
||||
<div class="flex items-center mt-[5px]">
|
||||
<NSwitch v-model:value="panelState.panelConfig.iconTextIconHideTitle" />
|
||||
@ -165,7 +166,7 @@ function resetPanelConfig() {
|
||||
|
||||
<div class="mt-[5px]">
|
||||
<div>
|
||||
文字颜色
|
||||
{{ $t('common.textColor') }}
|
||||
</div>
|
||||
<div class="flex items-center mt-[5px]">
|
||||
<NColorPicker
|
||||
@ -186,7 +187,7 @@ function resetPanelConfig() {
|
||||
</NCard>
|
||||
<NCard style="border-radius:10px" class="mt-[10px]" size="small">
|
||||
<div class="text-slate-500 mb-[5px] font-bold">
|
||||
壁纸
|
||||
{{ $t('apps.baseSettings.customFooter') }}
|
||||
</div>
|
||||
<NUpload
|
||||
action="/api/file/uploadImg"
|
||||
@ -204,32 +205,32 @@ function resetPanelConfig() {
|
||||
:style="{ background: `url(${panelState.panelConfig.backgroundImageSrc}) no-repeat`, backgroundSize: 'cover' }"
|
||||
>
|
||||
<div class="text-shadow text-white">
|
||||
点击上传替换图片或拖拽到框内
|
||||
{{ $t('apps.baseSettings.uploadOrDragText') }}
|
||||
</div>
|
||||
</div>
|
||||
</NUploadDragger>
|
||||
</NUpload>
|
||||
|
||||
<div class="flex items-center mt-[10px]">
|
||||
<span class="mr-[10px]">模糊</span>
|
||||
<span class="mr-[10px]">{{ $t('apps.baseSettings.vague') }}</span>
|
||||
<NSlider v-model:value="panelState.panelConfig.backgroundBlur" class="max-w-[200px]" :step="2" :max="20" />
|
||||
</div>
|
||||
|
||||
<div class="flex items-center mt-[10px]">
|
||||
<span class="mr-[10px]">遮罩</span>
|
||||
<span class="mr-[10px]">{{ $t('apps.baseSettings.mask') }}</span>
|
||||
<NSlider v-model:value="panelState.panelConfig.backgroundMaskNumber" class="max-w-[200px]" :step="0.1" :max="1" />
|
||||
</div>
|
||||
</NCard>
|
||||
|
||||
<NCard style="border-radius:10px" class="mt-[10px]" size="small">
|
||||
<div class="text-slate-500 mb-[5px] font-bold">
|
||||
内容区域
|
||||
{{ $t('apps.baseSettings.contentArea') }}
|
||||
</div>
|
||||
|
||||
<NGrid cols="2">
|
||||
<NGridItem span="12 400:12">
|
||||
<div class="flex items-center mt-[10px]">
|
||||
<span class="mr-[10px]">最大宽度</span>
|
||||
<span class="mr-[10px]">{{ $t('apps.baseSettings.maxWidth') }}</span>
|
||||
<div class="flex">
|
||||
<NInputGroup>
|
||||
<NInput v-model:value="panelState.panelConfig.maxWidth" size="small" type="number" :maxlength="10" :style="{ width: '100px' }" placeholder="1200" />
|
||||
@ -240,19 +241,19 @@ function resetPanelConfig() {
|
||||
</NGridItem>
|
||||
<NGridItem span="12 400:12">
|
||||
<div class="flex items-center mt-[10px]">
|
||||
<span class="mr-[10px]">左右边距</span>
|
||||
<span class="mr-[10px]">{{ $t('apps.baseSettings.leftRightMargin') }}</span>
|
||||
<NSlider v-model:value="panelState.panelConfig.marginX" class="max-w-[200px]" :step="1" :max="100" />
|
||||
</div>
|
||||
</NGridItem>
|
||||
<NGridItem span="12 400:12">
|
||||
<div class="flex items-center mt-[10px]">
|
||||
<span class="mr-[10px]">上边距 (%)</span>
|
||||
<span class="mr-[10px]">{{ $t('apps.baseSettings.topMargin') }} (%)</span>
|
||||
<NSlider v-model:value="panelState.panelConfig.marginTop" class="max-w-[200px]" :step="1" :max="50" />
|
||||
</div>
|
||||
</NGridItem>
|
||||
<NGridItem span="12 400:6">
|
||||
<div class="flex items-center mt-[10px]">
|
||||
<span class="mr-[10px]">下边距 (%)</span>
|
||||
<span class="mr-[10px]">{{ $t('apps.baseSettings.bottomMargin') }} (%)</span>
|
||||
<NSlider v-model:value="panelState.panelConfig.marginBottom" class="max-w-[200px]" :step="1" :max="50" />
|
||||
</div>
|
||||
</NGridItem>
|
||||
@ -261,7 +262,7 @@ function resetPanelConfig() {
|
||||
|
||||
<NCard style="border-radius:10px" class="mt-[10px]" size="small">
|
||||
<div class="text-slate-500 mb-[5px] font-bold">
|
||||
自定义footer
|
||||
{{ $t('apps.baseSettings.customFooter') }}
|
||||
</div>
|
||||
|
||||
<NInput
|
||||
@ -276,14 +277,14 @@ function resetPanelConfig() {
|
||||
>
|
||||
<template #trigger>
|
||||
<NButton size="small" quaternary type="error">
|
||||
重置
|
||||
{{ $t('common.reset') }}
|
||||
</NButton>
|
||||
</template>
|
||||
确定要重置这些样式吗?
|
||||
{{ $t('apps.baseSettings.resetWarnText') }}
|
||||
</NPopconfirm>
|
||||
|
||||
<NButton size="small" quaternary type="success" class="ml-[10px]" @click="uploadCloud">
|
||||
立即保存
|
||||
{{ $t('common.save') }}
|
||||
</NButton>
|
||||
</NCard>
|
||||
</div>
|
||||
|
@ -1,10 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import type { FormInst, FormRules } from 'naive-ui'
|
||||
import { NButton, NCard, NDivider, NForm, NFormItem, NInput, useDialog, useMessage } from 'naive-ui'
|
||||
import { NButton, NCard, NDivider, NForm, NFormItem, NInput, NSelect, useDialog, useMessage } from 'naive-ui'
|
||||
import { ref } from 'vue'
|
||||
import { useAuthStore, usePanelState, useUserStore } from '@/store'
|
||||
import { useAppStore, useAuthStore, usePanelState, useUserStore } from '@/store'
|
||||
import { languageOptions } from '@/utils/defaultData'
|
||||
import type { Language } from '@/store/modules/app/helper'
|
||||
import { logout } from '@/api'
|
||||
import { router } from '@/router'
|
||||
import { RoundCardModal, SvgIcon } from '@/components/common/'
|
||||
import { updateInfo, updatePassword } from '@/api/system/user'
|
||||
import { updateLocalUserInfo } from '@/utils/cmn'
|
||||
@ -12,10 +13,12 @@ import { t } from '@/locales'
|
||||
|
||||
const userStore = useUserStore()
|
||||
const authStore = useAuthStore()
|
||||
const appStore = useAppStore()
|
||||
const panelState = usePanelState()
|
||||
const ms = useMessage()
|
||||
const dialog = useDialog()
|
||||
|
||||
const languageValue = ref(appStore.language)
|
||||
const nickName = ref(authStore.userInfo?.name || '')
|
||||
const isEditNickNameStatus = ref(false)
|
||||
const formRef = ref<FormInst | null>(null)
|
||||
@ -59,8 +62,9 @@ async function logoutApi() {
|
||||
userStore.resetUserInfo()
|
||||
authStore.removeToken()
|
||||
panelState.removeState()
|
||||
appStore.removeToken()
|
||||
ms.success(t('settingUserInfo.logoutSuccess'))
|
||||
router.push({ path: '/login' })
|
||||
// router.push({ path: '/login' })
|
||||
location.reload()// 强制刷新一下页面
|
||||
}
|
||||
|
||||
@ -122,6 +126,12 @@ function handleLogout() {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
function handleChangeLanuage(value: Language) {
|
||||
languageValue.value = value
|
||||
appStore.setLanguage(value)
|
||||
location.reload()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -157,6 +167,14 @@ function handleLogout() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-[10px]">
|
||||
<div class="text-slate-500 font-bold">
|
||||
{{ $t('common.language') }}
|
||||
</div>
|
||||
<div class="max-w-[200px]">
|
||||
<NSelect v-model:value="languageValue" :options="languageOptions" @update-value="handleChangeLanuage" />
|
||||
</div>
|
||||
</div>
|
||||
<NDivider style="margin: 10px 0;" dashed />
|
||||
<div>
|
||||
<NButton size="small" text type="info" @click="updatePasswordModalState.show = !updatePasswordModalState.show">
|
||||
|
@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
import { t } from '@/locales'
|
||||
|
||||
const props = defineProps<{
|
||||
hideSecond?: boolean
|
||||
@ -35,7 +36,15 @@ function updateCurrentDate() {
|
||||
const month = now.getMonth() + 1 // 月份从0开始,所以要加1
|
||||
// const year = now.getFullYear()
|
||||
|
||||
const daysOfWeek = ['日', '一', '二', '三', '四', '五', '六']
|
||||
const daysOfWeek = [
|
||||
t('deskModule.clock.sun'),
|
||||
t('deskModule.clock.mon'),
|
||||
t('deskModule.clock.tue'),
|
||||
t('deskModule.clock.wed'),
|
||||
t('deskModule.clock.thu'),
|
||||
t('deskModule.clock.fri'),
|
||||
t('deskModule.clock.sat'),
|
||||
]
|
||||
// const daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
|
||||
currentDate.value.week = daysOfWeek[now.getDay()]
|
||||
currentDate.value.date = `${month}-${day}`
|
||||
@ -63,11 +72,11 @@ onBeforeUnmount(() => {
|
||||
{{ currentDate.time }}
|
||||
</span>
|
||||
<div class="hidden sm:hidden md:block">
|
||||
<span>
|
||||
<span class="mr-1">
|
||||
{{ currentDate.date }}
|
||||
</span>
|
||||
<span>
|
||||
星期{{ currentDate.week }}
|
||||
{{ currentDate.week }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -103,19 +103,19 @@ onMounted(() => {
|
||||
</div>
|
||||
|
||||
<NForm ref="formRef" v-model="extendParam">
|
||||
<NFormItem label="磁盘挂载点">
|
||||
<NFormItem :label="$t('deskModule.systemMonitor.diskMountPoint')">
|
||||
<NSelect v-model:value="extendParam.path" size="small" :options="mountPointList" />
|
||||
</NFormItem>
|
||||
<NFormItem label="主色">
|
||||
<NFormItem :label="$t('deskModule.systemMonitor.progressColor')">
|
||||
<NColorPicker v-model:value="extendParam.progressColor" :swatches="defautSwatchesBackground" :modes="['hex']" size="small" />
|
||||
</NFormItem>
|
||||
<NFormItem label="副色">
|
||||
<NFormItem :label="$t('deskModule.systemMonitor.progressRailColor')">
|
||||
<NColorPicker v-model:value="extendParam.progressRailColor" :swatches="defautSwatchesBackground" :modes="['hex']" size="small" />
|
||||
</NFormItem>
|
||||
<NFormItem label="文字图标颜色">
|
||||
<NFormItem :label="$t('common.textColor')">
|
||||
<NColorPicker v-model:value="extendParam.color" :swatches="defautSwatchesBackground" :modes="['hex']" size="small" />
|
||||
</NFormItem>
|
||||
<NFormItem label="卡片背景色">
|
||||
<NFormItem :label="$t('common.backgroundColor')">
|
||||
<NColorPicker v-model:value="extendParam.backgroundColor" :swatches="defautSwatchesBackground" :modes="['hex']" size="small" />
|
||||
</NFormItem>
|
||||
</NForm>
|
||||
|
@ -74,16 +74,16 @@ const data = computed({
|
||||
</div>
|
||||
|
||||
<NForm ref="formRef" v-model="data">
|
||||
<NFormItem label="主色">
|
||||
<NFormItem :label="$t('deskModule.systemMonitor.progressColor')">
|
||||
<NColorPicker v-model:value="data.progressColor" :swatches="defautSwatchesBackground" :modes="['hex']" size="small" />
|
||||
</NFormItem>
|
||||
<NFormItem label="副色">
|
||||
<NFormItem :label="$t('deskModule.systemMonitor.progressRailColor')">
|
||||
<NColorPicker v-model:value="data.progressRailColor" :swatches="defautSwatchesBackground" :modes="['hex']" size="small" />
|
||||
</NFormItem>
|
||||
<NFormItem label="文字图标颜色">
|
||||
<NFormItem :label="$t('common.textColor')">
|
||||
<NColorPicker v-model:value="data.color" :swatches="defautSwatchesBackground" :modes="['hex']" size="small" />
|
||||
</NFormItem>
|
||||
<NFormItem label="卡片背景色">
|
||||
<NFormItem :label="$t('common.backgroundColor')">
|
||||
<NColorPicker v-model:value="data.backgroundColor" :swatches="defautSwatchesBackground" :modes="['hex']" size="small" />
|
||||
</NFormItem>
|
||||
</NForm>
|
||||
|
@ -7,6 +7,7 @@ import { add, saveByIndex } from '../common'
|
||||
|
||||
import GenericProgressStyleEditor from './GenericProgressStyleEditor/index.vue'
|
||||
import DiskEditor from './DiskEditor/index.vue'
|
||||
import { t } from '@/locales'
|
||||
|
||||
interface Props {
|
||||
visible: boolean
|
||||
@ -84,7 +85,7 @@ async function handleSubmit() {
|
||||
else if (currentMonitorData.value.monitorType === MonitorType.disk)
|
||||
currentMonitorData.value.extendParam = currentDiskExtendParam
|
||||
|
||||
console.log('保存', currentMonitorData.value.extendParam)
|
||||
// console.log('保存', currentMonitorData.value.extendParam)
|
||||
|
||||
if (props.index !== null) {
|
||||
const res = await saveByIndex(props.index, currentMonitorData.value)
|
||||
@ -93,7 +94,7 @@ async function handleSubmit() {
|
||||
emit('done', true)
|
||||
}
|
||||
else {
|
||||
ms.error('保存失败')
|
||||
ms.error(t('common.saveFail'))
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -103,43 +104,36 @@ async function handleSubmit() {
|
||||
emit('done', true)
|
||||
}
|
||||
else {
|
||||
ms.error('保存失败')
|
||||
ms.error(t('common.saveFail'))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NModal v-model:show="show" preset="card" size="small" style="width: 600px;border-radius: 1rem;" :title="monitorData ? '修改项目' : '添加项目'">
|
||||
<NModal v-model:show="show" preset="card" size="small" style="width: 600px;border-radius: 1rem;" :title="monitorData ? t('common.edit') : t('common.add')">
|
||||
<!-- 选择监视器 -->
|
||||
<!-- <div>
|
||||
{{ JSON.stringify(currentGenericProgressStyleExtendParam) }}
|
||||
{{ JSON.stringify(currentDiskExtendParam) }}
|
||||
</div> -->
|
||||
<NTabs v-model:value="active" type="segment">
|
||||
<NTabPane :name="MonitorType.cpu" tab="CPU状态">
|
||||
<NTabPane :name="MonitorType.cpu" :tab="$t('deskModule.systemMonitor.cpuState')">
|
||||
<GenericProgressStyleEditor v-model:genericProgressStyleExtendParam="currentGenericProgressStyleExtendParam" />
|
||||
<NButton @click="handleResetExtendParam">
|
||||
重置
|
||||
</NButton>
|
||||
</NTabPane>
|
||||
<NTabPane :name="MonitorType.memory" tab="内存状态">
|
||||
<NTabPane :name="MonitorType.memory" :tab="$t('deskModule.systemMonitor.memoryState')">
|
||||
<GenericProgressStyleEditor v-model:genericProgressStyleExtendParam="currentGenericProgressStyleExtendParam" />
|
||||
<NButton @click="handleResetExtendParam">
|
||||
重置
|
||||
</NButton>
|
||||
</NTabPane>
|
||||
<NTabPane :name="MonitorType.disk" tab="磁盘状态">
|
||||
<NTabPane :name="MonitorType.disk" :tab="$t('deskModule.systemMonitor.diskState')">
|
||||
<DiskEditor v-model:disk-extend-param="currentDiskExtendParam" />
|
||||
<NButton @click="handleResetExtendParam">
|
||||
重置
|
||||
</NButton>
|
||||
</NTabPane>
|
||||
</NTabs>
|
||||
|
||||
<NButton @click="handleResetExtendParam">
|
||||
{{ t('common.reset') }}
|
||||
</NButton>
|
||||
<template #footer>
|
||||
<NButton type="success" :loading="submitLoading" style="float: right;" @click="handleSubmit">
|
||||
确定
|
||||
{{ t('common.confirm') }}
|
||||
</NButton>
|
||||
</template>
|
||||
</NModal>
|
||||
|
@ -1,171 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onUnmounted, ref } from 'vue'
|
||||
import { NProgress } from 'naive-ui'
|
||||
import { getAll } from '@/api/system/systemMonitor'
|
||||
import { SvgIcon } from '@/components/common'
|
||||
import { bytesToSize } from '@/utils/cmn'
|
||||
|
||||
interface ProgressStyle {
|
||||
color: string
|
||||
railColor: string
|
||||
height: number
|
||||
}
|
||||
|
||||
const systemMonitorData = ref<SystemMonitor.GetAllRes | null>(null)
|
||||
const progressStyle = ref<ProgressStyle>({
|
||||
color: 'white',
|
||||
railColor: 'rgba(0, 0, 0, 0.5)',
|
||||
height: 5,
|
||||
})
|
||||
const svgStyle = {
|
||||
width: '25px',
|
||||
height: '25px',
|
||||
}
|
||||
|
||||
async function getData() {
|
||||
try {
|
||||
const { data, code } = await getAll<SystemMonitor.GetAllRes>()
|
||||
if (code === 0)
|
||||
systemMonitorData.value = data
|
||||
}
|
||||
catch (error) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function correctionNumber(v: number, keepNum = 2): number {
|
||||
return v === 0 ? 0 : Number(v.toFixed(keepNum))
|
||||
}
|
||||
|
||||
function formatMemorySize(v: number): string {
|
||||
return bytesToSize(v)
|
||||
}
|
||||
|
||||
function formatdiskSize(v: number): string {
|
||||
return bytesToSize(v)
|
||||
}
|
||||
|
||||
function formatdiskToByte(v: number): number {
|
||||
return v * 1024 * 1024
|
||||
}
|
||||
onMounted(() => {
|
||||
getData()
|
||||
// timer = setInterval(() => {
|
||||
// getData()
|
||||
// }, 5000)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
// clearInterval(timer)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full system-monitor flex items-center px-2 text-white overflow-auto">
|
||||
<!-- <div class="flex flex-col items-center justify-center ">
|
||||
<div>
|
||||
<NProgress type="dashboard" :percentage="correctionNumber(systemMonitorData?.cpuInfo.usages[0] || 0)" :stroke-width="15" style="width: 50px;">
|
||||
<div class="text-white text-xs">
|
||||
{{ correctionNumber(systemMonitorData?.cpuInfo.usages[0] || 0, 1) }}%
|
||||
</div>
|
||||
</NProgress>
|
||||
</div>
|
||||
<span>
|
||||
CPU
|
||||
</span>
|
||||
</div> -->
|
||||
<div class="text-xs mr-10 flex justify-center items-center">
|
||||
<div class="mr-2">
|
||||
<SvgIcon icon="solar-cpu-bold" :style="svgStyle" />
|
||||
</div>
|
||||
<div>
|
||||
<div class="mb-1">
|
||||
<span>
|
||||
CPU
|
||||
</span>
|
||||
<span class="float-right">
|
||||
{{ correctionNumber(systemMonitorData?.cpuInfo.usages[0] || 0) }}%
|
||||
</span>
|
||||
</div>
|
||||
<NProgress
|
||||
type="line"
|
||||
:color="progressStyle.color"
|
||||
:rail-color="progressStyle.railColor"
|
||||
:height="progressStyle.height"
|
||||
:percentage="correctionNumber(systemMonitorData?.cpuInfo.usages[0] || 0)"
|
||||
:show-indicator="false"
|
||||
:stroke-width="15"
|
||||
style="width: 150px;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-xs mr-10 flex justify-center items-center">
|
||||
<div class="mr-2">
|
||||
<SvgIcon icon="material-symbols-memory-alt-rounded" :style="svgStyle" />
|
||||
</div>
|
||||
<div>
|
||||
<div class="mb-1">
|
||||
<span>
|
||||
RAM
|
||||
</span>
|
||||
<span class="float-right">
|
||||
{{ formatMemorySize(systemMonitorData?.memoryInfo.total || 0) }}/{{ formatMemorySize(systemMonitorData?.memoryInfo.free || 0) }}
|
||||
</span>
|
||||
</div>
|
||||
<NProgress
|
||||
type="line"
|
||||
:color="progressStyle.color"
|
||||
:rail-color="progressStyle.railColor"
|
||||
:height="progressStyle.height"
|
||||
:percentage="systemMonitorData?.memoryInfo.usedPercent"
|
||||
:show-indicator="false"
|
||||
:stroke-width="15" style="width: 150px;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="text-xs mr-2">
|
||||
<div class="mb-1">
|
||||
<span>
|
||||
网络:{{ systemMonitorData?.netIOCountersInfo[0].name }}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="float-right">
|
||||
上行:{{ netIOToKB(systemMonitorData?.netIOCountersInfo[0].bytesSent || 0) }}
|
||||
下行:{{ netIOToKB(systemMonitorData?.netIOCountersInfo[0].bytesRecv || 0) }}
|
||||
</span>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- 磁盘信息 -->
|
||||
<div v-for=" item, index in systemMonitorData?.diskInfo" :key="index">
|
||||
<div class="text-xs mr-10 flex justify-center items-center">
|
||||
<div class="mr-2">
|
||||
<SvgIcon icon="clarity-hard-disk-solid" :style="svgStyle" />
|
||||
</div>
|
||||
<div>
|
||||
<div class="mb-1">
|
||||
<span>
|
||||
{{ item.mountpoint }}
|
||||
</span>
|
||||
<span class="float-right">
|
||||
{{ formatdiskSize(formatdiskToByte(item.total || 0)) }}/{{ formatdiskSize(formatdiskToByte(item.free || 0)) }}
|
||||
</span>
|
||||
</div>
|
||||
<NProgress
|
||||
:color="progressStyle.color"
|
||||
:rail-color="progressStyle.railColor"
|
||||
:height="progressStyle.height"
|
||||
type="line"
|
||||
:percentage="item.usedPercent"
|
||||
:show-indicator="false"
|
||||
:stroke-width="15"
|
||||
style="width: 150px;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
@ -149,10 +149,10 @@ function handleRightMenuSelect(key: string | number) {
|
||||
switch (key) {
|
||||
case 'delete':
|
||||
dialog.warning({
|
||||
title: '警告',
|
||||
content: '你确定要删除吗?',
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
title: t('common.warning'),
|
||||
content: t('common.deleteConfirm'),
|
||||
positiveText: t('common.confirm'),
|
||||
negativeText: t('common.cancel'),
|
||||
onPositiveClick: () => {
|
||||
if (monitorDatas.value.length <= 1) {
|
||||
ms.warning(t('common.leastOne'))
|
||||
@ -181,17 +181,17 @@ function handleRightMenuSelect(key: string | number) {
|
||||
<!-- 分组标题 -->
|
||||
<div class="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="monitorGroup.hoverStatus ? 'opacity-100' : 'opacity-0'"
|
||||
>
|
||||
<span class="mr-2 cursor-pointer" title="添加快捷图标" @click="handleAddItem()">
|
||||
<span class="mr-2 cursor-pointer" @click="handleAddItem()">
|
||||
<SvgIcon class="text-white font-xl" icon="typcn:plus" />
|
||||
</span>
|
||||
<span class="mr-2 cursor-pointer " title="排序组快捷图标" @click="handleSetSortStatus(!monitorGroup.sortStatus)">
|
||||
<span class="mr-2 cursor-pointer" @click="handleSetSortStatus(!monitorGroup.sortStatus)">
|
||||
<SvgIcon class="text-white font-xl" icon="ri:drag-drop-line" />
|
||||
</span>
|
||||
</div>
|
||||
@ -259,7 +259,7 @@ function handleRightMenuSelect(key: string | number) {
|
||||
<SvgIcon class="text-white font-xl" icon="material-symbols:save" />
|
||||
</template>
|
||||
<div>
|
||||
保存排序
|
||||
{{ $t('common.saveSort') }}
|
||||
</div>
|
||||
</NButton>
|
||||
</div>
|
||||
|
@ -1,94 +1,232 @@
|
||||
export default {
|
||||
common: {
|
||||
appName: 'Sun-Panel',
|
||||
add: 'Add',
|
||||
addSuccess: 'Add Success',
|
||||
addSuccess: 'Added successfully',
|
||||
edit: 'Edit',
|
||||
editSuccess: 'Edit Success',
|
||||
editSuccess: 'Edited successfully',
|
||||
editFail: 'Edit failed',
|
||||
delete: 'Delete',
|
||||
deleteSuccess: 'Delete Success',
|
||||
deleteSuccess: 'Deleted successfully',
|
||||
deleteFail: 'Delete failed',
|
||||
save: 'Save',
|
||||
saveSuccess: 'Save Success',
|
||||
saveSuccess: 'Saved successfully',
|
||||
saveFail: 'Save failed',
|
||||
reset: 'Reset',
|
||||
action: 'Action',
|
||||
export: 'Export',
|
||||
exportSuccess: 'Export Success',
|
||||
exportSuccess: 'Exported successfully',
|
||||
import: 'Import',
|
||||
importSuccess: 'Import Success',
|
||||
clear: 'Clear',
|
||||
clearSuccess: 'Clear Success',
|
||||
importSuccess: 'Imported successfully',
|
||||
yes: 'Yes',
|
||||
no: 'No',
|
||||
confirm: 'Confirm',
|
||||
cancel: 'Cancel',
|
||||
warning: 'Warning',
|
||||
download: 'Download',
|
||||
noData: 'No Data',
|
||||
wrong: 'Something went wrong, please try again later.',
|
||||
success: 'Success',
|
||||
failed: 'Failed',
|
||||
noData: 'No data available',
|
||||
success: 'Operation successful',
|
||||
failed: 'Operation failed',
|
||||
uploadFail: 'Upload failed',
|
||||
repeatLater: 'Please try again later',
|
||||
verify: 'Verify',
|
||||
unauthorizedTips: 'Unauthorized, please verify first.',
|
||||
},
|
||||
chat: {
|
||||
newChatButton: 'New Chat',
|
||||
placeholder: 'Ask me anything...(Shift + Enter = line break, "/" to trigger prompts)',
|
||||
placeholderMobile: 'Ask me anything...',
|
||||
copy: 'Copy',
|
||||
copied: 'Copied',
|
||||
copyCode: 'Copy Code',
|
||||
clearChat: 'Clear Chat',
|
||||
clearChatConfirm: 'Are you sure to clear this chat?',
|
||||
exportImage: 'Export Image',
|
||||
exportImageConfirm: 'Are you sure to export this chat to png?',
|
||||
exportSuccess: 'Export Success',
|
||||
exportFailed: 'Export Failed',
|
||||
usingContext: 'Context Mode',
|
||||
turnOnContext: 'In the current mode, sending messages will carry previous chat records.',
|
||||
turnOffContext: 'In the current mode, sending messages will not carry previous chat records.',
|
||||
deleteMessage: 'Delete Message',
|
||||
deleteMessageConfirm: 'Are you sure to delete this message?',
|
||||
deleteHistoryConfirm: 'Are you sure to clear this history?',
|
||||
clearHistoryConfirm: 'Are you sure to clear chat history?',
|
||||
preview: 'Preview',
|
||||
showRawText: 'Show as raw text',
|
||||
},
|
||||
setting: {
|
||||
setting: 'Setting',
|
||||
general: 'General',
|
||||
advanced: 'Advanced',
|
||||
config: 'Config',
|
||||
avatarLink: 'Avatar Link',
|
||||
name: 'Name',
|
||||
description: 'Description',
|
||||
role: 'Role',
|
||||
temperature: 'Temperature',
|
||||
top_p: 'Top_p',
|
||||
resetUserInfo: 'Reset UserInfo',
|
||||
chatHistory: 'ChatHistory',
|
||||
theme: 'Theme',
|
||||
inputPlaceholder: 'Please enter',
|
||||
inputPlaceholderByText: 'Please enter {text}',
|
||||
deleteConfirm: 'Are you sure you want to delete?',
|
||||
deleteConfirmByName: 'Are you sure you want to delete {name}?',
|
||||
username: 'Username',
|
||||
nikeName: 'Nickname',
|
||||
password: 'Password',
|
||||
serverError: 'Server error',
|
||||
unknownError: 'Unknown error',
|
||||
role: {
|
||||
regularUser: 'Regular',
|
||||
admin: 'Admin',
|
||||
},
|
||||
leastOne: 'Please keep at least one',
|
||||
icon: 'Icon',
|
||||
style: 'Style',
|
||||
show: 'Show',
|
||||
text: 'Text',
|
||||
textColor: 'Text color',
|
||||
sort: 'Sort',
|
||||
saveSort: 'Save sort',
|
||||
language: 'Language',
|
||||
api: 'API',
|
||||
reverseProxy: 'Reverse Proxy',
|
||||
timeout: 'Timeout',
|
||||
socks: 'Socks',
|
||||
httpsProxy: 'HTTPS Proxy',
|
||||
balance: 'API Balance',
|
||||
monthlyUsage: 'Monthly Usage',
|
||||
},
|
||||
store: {
|
||||
siderButton: 'Prompt Store',
|
||||
local: 'Local',
|
||||
online: 'Online',
|
||||
refreshPage: 'Please refresh the page',
|
||||
continue: 'Continue',
|
||||
title: 'Title',
|
||||
image: 'Image',
|
||||
backgroundColor: 'Background color',
|
||||
description: 'Description',
|
||||
clearStoreConfirm: 'Whether to clear the data?',
|
||||
importPlaceholder: 'Please paste the JSON data here',
|
||||
addRepeatTitleTips: 'Title duplicate, please re-enter',
|
||||
addRepeatContentTips: 'Content duplicate: {msg}, please re-enter',
|
||||
editRepeatTitleTips: 'Title conflict, please revise',
|
||||
editRepeatContentTips: 'Content conflict {msg} , please re-modify',
|
||||
importError: 'Key value mismatch',
|
||||
importRepeatTitle: 'Title repeatedly skipped: {msg}',
|
||||
importRepeatContent: 'Content is repeatedly skipped: {msg}',
|
||||
onlineImportWarning: 'Note: Please check the JSON file source!',
|
||||
downloadError: 'Please check the network status and JSON file validity',
|
||||
},
|
||||
form: {
|
||||
required: 'Required field',
|
||||
},
|
||||
panelHome: {
|
||||
openLanUrl: 'Open LAN URL',
|
||||
openWanUrl: 'Open WAN URL',
|
||||
changeToLanModel: 'Switch to LAN mode',
|
||||
changeToWanModel: 'Switch to WAN mode',
|
||||
goToLogin: 'Go to login',
|
||||
changeToLanModelSuccess: 'Switched to LAN mode (mode status saved locally)',
|
||||
changeToWanModelSuccess: 'Switched to WAN mode (mode status saved locally)',
|
||||
},
|
||||
appLauncher: {
|
||||
title: 'System Applications & Settings',
|
||||
},
|
||||
login: {
|
||||
loginButton: 'Login',
|
||||
usernamePlaceholder: 'Enter username',
|
||||
passwordPlaceholder: 'Enter password',
|
||||
welcomeMessage: 'Welcome back!',
|
||||
},
|
||||
settingUserInfo: {
|
||||
updatePassword: 'Change password',
|
||||
oldPassword: 'Old password',
|
||||
newPassword: 'New password',
|
||||
confirmPassword: 'Confirm new password',
|
||||
confirmPasswordInconsistentMsg: 'Passwords do not match',
|
||||
logout: 'Logout',
|
||||
confirmLogoutText: 'Are you sure you want to logout?',
|
||||
logoutSuccess: 'You have safely logged out. Looking forward to seeing you again!',
|
||||
},
|
||||
adminSettingUsers: {
|
||||
appName: 'User Management',
|
||||
passwordPlaceholder: 'Enter password',
|
||||
EditpasswordPlaceholder: 'Enter new password, leave blank to keep the current password',
|
||||
role: 'Role',
|
||||
formRules: {
|
||||
usernameRequired: 'Enter username with at least 5 characters',
|
||||
roleRequired: 'Please select a role',
|
||||
passwordLimit: '6-20 characters',
|
||||
},
|
||||
alertText: 'Data between accounts is not shared',
|
||||
userCountText: 'Total {count} users',
|
||||
deletePromptContent: 'Are you sure you want to delete {name} ({username})?',
|
||||
currentUseUsername: 'Current username',
|
||||
setOrUnsetPublicMode: 'Set/Unset public access',
|
||||
pblicText: 'Public',
|
||||
},
|
||||
deskModule: {
|
||||
searchBox: {
|
||||
openWithNewOpen: 'Open in new window',
|
||||
inputPlaceholder: 'Enter search content',
|
||||
},
|
||||
clock: {
|
||||
mon: 'Monday',
|
||||
tue: 'Tuesday',
|
||||
wed: 'Wednesday',
|
||||
thu: 'Thursday',
|
||||
fri: 'Friday',
|
||||
sat: 'Saturday',
|
||||
sun: 'Sunday',
|
||||
},
|
||||
systemMonitor: {
|
||||
systemState: 'System status',
|
||||
diskMountPoint: 'Mount point',
|
||||
progressColor: 'Main color',
|
||||
progressRailColor: 'Secondary color',
|
||||
cpuState: 'CPU status',
|
||||
memoryState: 'Memory status',
|
||||
diskState: 'Disk status',
|
||||
},
|
||||
},
|
||||
iconItem: {
|
||||
add: 'Add item',
|
||||
edit: 'Edit item',
|
||||
url: 'URL',
|
||||
lanUrl: 'LAN URL',
|
||||
getIcon: 'Get icon',
|
||||
geticonFail: 'Failed to get icon',
|
||||
openMethod: 'Open method',
|
||||
onlineIcon: 'Online icon',
|
||||
onlineIconLibrary: 'Online icon library',
|
||||
inputIconName: 'Enter icon name',
|
||||
inputIconUrlOrUpload: 'Enter icon URL or upload',
|
||||
selectUpload: 'Local upload',
|
||||
currentPageOpen: 'Open in current page',
|
||||
newWindowOpen: 'Open in new window',
|
||||
currentPageLayerOpen: 'Open in current page as layer',
|
||||
getGroupFail: 'Failed to get group information',
|
||||
iconGroup: 'Group',
|
||||
lanUrlInputPlaceholder: 'http(s):// (LAN mode, will redirect to this address)',
|
||||
},
|
||||
apps: {
|
||||
baseSettings: {
|
||||
appName: 'Basic Settings',
|
||||
configSaved: 'Configuration saved',
|
||||
configFailed: 'Configuration save failed, {message}',
|
||||
show: 'Show',
|
||||
hideTitle: 'Hide title',
|
||||
textContent: 'Text content',
|
||||
clock: 'Clock component',
|
||||
clockSecondShow: 'Show seconds',
|
||||
searchBar: 'Search bar component',
|
||||
searchBarShow: 'Configuration saved',
|
||||
searchBarSearchItem: 'Allow search bar to search items',
|
||||
systemMonitorStatus: 'System status component',
|
||||
showTitle: 'Show title',
|
||||
publicVisitModeShow: 'Allow public mode display',
|
||||
hideDescription: 'Hide description information',
|
||||
wallpaper: 'Wallpaper',
|
||||
uploadOrDragText: 'Click to upload or drag and drop into the box to replace the image',
|
||||
vague: 'Blur',
|
||||
mask: 'Mask',
|
||||
contentArea: 'Content area',
|
||||
maxWidth: 'Max width',
|
||||
leftRightMargin: 'Left-right margin',
|
||||
topMargin: 'Top margin',
|
||||
bottomMargin: 'Bottom margin',
|
||||
customFooter: 'Custom footer',
|
||||
resetWarnText: 'Are you sure you want to reset these styles?',
|
||||
detailIcon: 'Detail icon',
|
||||
smallIcon: 'Small icon',
|
||||
},
|
||||
itemGroupManage: {
|
||||
appName: 'Group Management',
|
||||
deleteWarnText: 'Are you sure you want to delete this group [{name}]? The application icons in this group will be lost after deletion.',
|
||||
groupName: 'Group name',
|
||||
},
|
||||
exportImport: {
|
||||
appName: 'Export/Import',
|
||||
tip: 'Importing icon configuration data will not clear existing icon data',
|
||||
export: 'Export configuration',
|
||||
import: 'Import configuration',
|
||||
selectImportData: 'Select the configuration data to import',
|
||||
selectExportData: 'Select the configuration data to export',
|
||||
fileModified: 'The file has been modified, import with caution',
|
||||
warnConfigFileLow: 'The configuration file version is too low but compatible',
|
||||
softwareVersionLow: 'The current software version may be too old and may not be compatible with this configuration file. It is recommended to update the software to the latest version before importing again.',
|
||||
errorConfigFileLow: 'The configuration file version is too low and cannot be compatible',
|
||||
errorConfigFileFormat: 'The configuration file format is incorrect and cannot be imported',
|
||||
moduleIcon: 'Icon configuration',
|
||||
moduleStyle: 'Style configuration',
|
||||
},
|
||||
userInfo: {
|
||||
appName: 'My Information',
|
||||
},
|
||||
about: {
|
||||
appName: 'About',
|
||||
viewUpdateLog: 'Click here to view update log',
|
||||
issue: 'Feedback:',
|
||||
QQGroup: 'QQ Group:',
|
||||
QR: 'QR Code (Recommended)',
|
||||
author: 'Author:',
|
||||
donate: '🧧 Donate',
|
||||
},
|
||||
uploadsFileManager: {
|
||||
appName: 'Uploads File Management',
|
||||
copyLink: 'Copy link',
|
||||
infoTitle: 'File details',
|
||||
fileName: 'Original file name',
|
||||
path: 'File path',
|
||||
uploadTime: 'Upload time',
|
||||
deleteWarningText: 'Cannot be recovered after deletion. Are you sure you want to continue?',
|
||||
copySuccess: 'Link copied successfully. You can paste it in the address bar.',
|
||||
copyFailed: 'Copy failed',
|
||||
setWallpaper: 'Set as wallpaper',
|
||||
alertText: 'Here you can manage wallpapers and icons you have uploaded.',
|
||||
nothingText: 'You haven\'t uploaded any images yet.',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -8,16 +8,16 @@ export default {
|
||||
editFail: '编辑失败',
|
||||
delete: '删除',
|
||||
deleteSuccess: '删除成功',
|
||||
deleteFail: '删除失败',
|
||||
save: '保存',
|
||||
saveSuccess: '保存成功',
|
||||
saveFail: '保存成功',
|
||||
reset: '重置',
|
||||
action: '操作',
|
||||
export: '导出',
|
||||
exportSuccess: '导出成功',
|
||||
import: '导入',
|
||||
importSuccess: '导入成功',
|
||||
// clear: '清空',
|
||||
// clearSuccess: '清空成功',
|
||||
yes: '是',
|
||||
no: '否',
|
||||
confirm: '确定',
|
||||
@ -25,46 +25,54 @@ export default {
|
||||
warning: '警告',
|
||||
download: '下载',
|
||||
noData: '暂无数据',
|
||||
// wrong: '好像出错了,请稍后再试。',
|
||||
success: '操作成功',
|
||||
failed: '操作失败',
|
||||
uploadFail: '上传失败',
|
||||
repeatLater: '请稍后重试',
|
||||
verify: '验证',
|
||||
unauthorizedTips: '未经授权,请先进行验证。',
|
||||
inputPlaceholder: '请输入',
|
||||
inputPlaceholderByText: '请输入{text}',
|
||||
deleteConfirm: '你确定要删除吗?',
|
||||
deleteConfirmByName: '你确定要删除{name}吗?',
|
||||
username: '账号',
|
||||
nikeName: '昵称',
|
||||
password: '密码',
|
||||
serverError: '服务器错误',
|
||||
unknownError: '未知错误',
|
||||
role: {
|
||||
regularUser: '普通',
|
||||
admin: '管理',
|
||||
},
|
||||
leastOne: '请至少保留一项',
|
||||
},
|
||||
setting: {
|
||||
setting: '设置',
|
||||
general: '总览',
|
||||
advanced: '高级',
|
||||
config: '配置',
|
||||
avatarLink: '头像链接',
|
||||
avatar: '头像',
|
||||
name: '名称',
|
||||
description: '描述',
|
||||
role: '角色设定',
|
||||
temperature: 'Temperature',
|
||||
top_p: '回答多样性',
|
||||
resetUserInfo: '重置用户信息',
|
||||
chatHistory: '聊天记录',
|
||||
theme: '主题',
|
||||
icon: '图标',
|
||||
style: '样式',
|
||||
show: '显示',
|
||||
text: '文字',
|
||||
textColor: '文字颜色',
|
||||
sort: '排序',
|
||||
saveSort: '保存排序',
|
||||
language: '语言',
|
||||
api: 'API',
|
||||
reverseProxy: '反向代理',
|
||||
timeout: '超时',
|
||||
socks: 'Socks',
|
||||
httpsProxy: 'HTTPS Proxy',
|
||||
balance: 'API余额',
|
||||
monthlyUsage: '本月使用量',
|
||||
refreshPage: '请刷新页面',
|
||||
continue: '继续',
|
||||
title: '标题',
|
||||
image: '图片',
|
||||
backgroundColor: '背景颜色',
|
||||
description: '描述信息',
|
||||
},
|
||||
form: {
|
||||
required: '必填项',
|
||||
},
|
||||
panelHome: {
|
||||
openLanUrl: '打开局域网地址',
|
||||
openWanUrl: '打开公网地址',
|
||||
changeToLanModel: '切换为内网模式',
|
||||
changeToWanModel: '切换为公网模式',
|
||||
goToLogin: '前往登录',
|
||||
changeToLanModelSuccess: '已经切换到内网模式(模式状态仅保存在本地)',
|
||||
changeToWanModelSuccess: '已经切换到公网模式(模式状态仅保存在本地)',
|
||||
},
|
||||
appLauncher: {
|
||||
title: '系统应用 & 设置',
|
||||
},
|
||||
login: {
|
||||
loginButton: '登录',
|
||||
@ -83,6 +91,7 @@ export default {
|
||||
logoutSuccess: '您已经安全退出,期待与你再次相见!',
|
||||
},
|
||||
adminSettingUsers: {
|
||||
appName: '用户管理',
|
||||
passwordPlaceholder: '请输入密码',
|
||||
EditpasswordPlaceholder: '请输入新密码,留空密码不变',
|
||||
role: '角色',
|
||||
@ -103,9 +112,111 @@ export default {
|
||||
openWithNewOpen: '新窗口打开',
|
||||
inputPlaceholder: '请输入搜索内容',
|
||||
},
|
||||
clock: {
|
||||
mon: '星期一',
|
||||
tue: '星期二',
|
||||
wed: '星期三',
|
||||
thu: '星期四',
|
||||
fri: '星期五',
|
||||
sat: '星期六',
|
||||
sun: '星期日',
|
||||
},
|
||||
systemMonitor: {
|
||||
systemState: '系统状态',
|
||||
diskMountPoint: '挂载点',
|
||||
progressColor: '主色',
|
||||
progressRailColor: '副色',
|
||||
cpuState: 'CPU状态',
|
||||
memoryState: '内存状态',
|
||||
diskState: '磁盘状态',
|
||||
},
|
||||
},
|
||||
iconItem: {
|
||||
add: '添加项目',
|
||||
edit: '修改项目',
|
||||
url: '地址',
|
||||
lanUrl: '局域网地址',
|
||||
getIcon: '获取图标',
|
||||
geticonFail: '图标获取失败',
|
||||
openMethod: '打开方式',
|
||||
onlineIcon: '在线图标',
|
||||
onlineIconLibrary: '在线图标库',
|
||||
inputIconName: '请输入图标名称',
|
||||
inputIconUrlOrUpload: '输入图标地址或上传',
|
||||
selectUpload: '本地上传',
|
||||
currentPageOpen: '当前页面打开',
|
||||
newWindowOpen: '新窗口打开',
|
||||
currentPageLayerOpen: '当前页面弹窗打开',
|
||||
getGroupFail: '分组信息获取失败',
|
||||
iconGroup: '分组',
|
||||
lanUrlInputPlaceholder: 'http(s)://(局域网模式,会跳转该地址)',
|
||||
},
|
||||
apps: {
|
||||
baseSettings: {
|
||||
appName: '基础设置',
|
||||
configSaved: '配置已保存',
|
||||
configFailed: '配置保存失败,{message}',
|
||||
show: '显示',
|
||||
hideTitle: '隐藏标题',
|
||||
textContent: '文本内容',
|
||||
clock: '时钟组件',
|
||||
clockSecondShow: '显示秒',
|
||||
searchBar: '搜索栏组件',
|
||||
searchBarShow: '配置已保存',
|
||||
searchBarSearchItem: '允许搜索栏搜索项目',
|
||||
systemMonitorStatus: '系统状态组件',
|
||||
showTitle: '显示标题',
|
||||
publicVisitModeShow: '公开模式允许显示',
|
||||
hideDescription: '隐藏描述信息',
|
||||
wallpaper: '壁纸',
|
||||
uploadOrDragText: '点击上传替换图片或拖拽到框内',
|
||||
vague: '模糊',
|
||||
mask: '遮罩',
|
||||
contentArea: '内容区域',
|
||||
maxWidth: '最大宽度',
|
||||
leftRightMargin: '左右边距',
|
||||
topMargin: '上边距',
|
||||
bottomMargin: '下边距',
|
||||
customFooter: '自定义footer',
|
||||
resetWarnText: '确定要重置这些样式吗?',
|
||||
detailIcon: '详情图标',
|
||||
smallIcon: '小图标',
|
||||
},
|
||||
itemGroupManage: {
|
||||
appName: '分组管理',
|
||||
deleteWarnText: '你确定删除此分组[{name}],删除后此分组应用图标将丢失?',
|
||||
groupName: '分组名称',
|
||||
},
|
||||
exportImport: {
|
||||
appName: '导出导入',
|
||||
tip: '导入图标配置数据不会清空现有图标数据',
|
||||
export: '导出配置',
|
||||
import: '导入配置',
|
||||
selectImportData: '请选择要导入的配置数据',
|
||||
selectExportData: '请选择要导出的配置数据',
|
||||
fileModified: '文件被修改过,谨慎导入',
|
||||
warnConfigFileLow: '配置文件版本过低,但是兼容',
|
||||
softwareVersionLow: '当前软件版本可能过旧,很有可能无法兼容该配置文件,请谨慎导入。推荐将软件更新到新版后再次导入',
|
||||
errorConfigFileLow: '配置文件版本过低,无法兼容',
|
||||
errorConfigFileFormat: '配置文件格式不正确,无法导入',
|
||||
moduleIcon: '图标配置',
|
||||
moduleStyle: '样式配置',
|
||||
|
||||
},
|
||||
userInfo: {
|
||||
appName: '我的信息',
|
||||
},
|
||||
about: {
|
||||
appName: '关于',
|
||||
viewUpdateLog: '点此查看更新说明',
|
||||
issue: '建议反馈:',
|
||||
QQGroup: 'QQ交流群:',
|
||||
QR: '二维码(推荐)',
|
||||
author: '作者:',
|
||||
donate: '🧧打赏',
|
||||
},
|
||||
uploadsFileManager: {
|
||||
appName: '上传文件管理',
|
||||
copyLink: '复制链接',
|
||||
infoTitle: '文件详情',
|
||||
fileName: '原文件名',
|
||||
|
@ -13,7 +13,12 @@ export interface AppState {
|
||||
}
|
||||
|
||||
export function defaultSetting(): AppState {
|
||||
return { siderCollapsed: false, theme: 'light', language: 'zh-CN' }
|
||||
const lan = (navigator.language).toLowerCase()
|
||||
let language: Language = 'en-US'
|
||||
if (lan.includes('zh'))
|
||||
language = 'zh-CN'
|
||||
|
||||
return { siderCollapsed: false, theme: 'light', language }
|
||||
}
|
||||
|
||||
export function getLocalSetting(): AppState {
|
||||
@ -24,3 +29,7 @@ export function getLocalSetting(): AppState {
|
||||
export function setLocalSetting(setting: AppState): void {
|
||||
ss.set(LOCAL_NAME, setting)
|
||||
}
|
||||
|
||||
export function removeLocalState() {
|
||||
ss.remove(LOCAL_NAME)
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import type { AppState, Language, Theme } from './helper'
|
||||
import { getLocalSetting, setLocalSetting } from './helper'
|
||||
import { defaultSetting, getLocalSetting, removeLocalState, setLocalSetting } from './helper'
|
||||
import { store } from '@/store'
|
||||
|
||||
export const useAppStore = defineStore('app-store', {
|
||||
@ -26,6 +26,11 @@ export const useAppStore = defineStore('app-store', {
|
||||
recordState() {
|
||||
setLocalSetting(this.$state)
|
||||
},
|
||||
|
||||
removeToken() {
|
||||
this.$state = defaultSetting()
|
||||
removeLocalState()
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
import type { Language } from '@/store/modules/app/helper'
|
||||
|
||||
export const defautSwatchesBackground = [
|
||||
'#00000000',
|
||||
'#000000',
|
||||
@ -8,3 +10,8 @@ export const defautSwatchesBackground = [
|
||||
'rgba(208, 48, 80, 1)',
|
||||
'#C418D1FF',
|
||||
]
|
||||
|
||||
export const languageOptions: { label: string; key: Language; value: Language }[] = [
|
||||
{ label: 'English', key: 'en-US', value: 'en-US' },
|
||||
{ label: '简体中文', key: 'zh-CN', value: 'zh-CN' },
|
||||
]
|
||||
|
@ -3,6 +3,7 @@ import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
import { NLayout, NLayoutContent, NLayoutSider, NSpace } from 'naive-ui'
|
||||
import { useAuthStore } from '@/store'
|
||||
import { AppLoader, RoundCardModal, SvgIcon } from '@/components/common'
|
||||
import { t } from '@/locales'
|
||||
|
||||
interface App {
|
||||
name: string
|
||||
@ -23,38 +24,38 @@ const componentName = ref('UserInfo')
|
||||
const collapsed = ref(false)
|
||||
const screenWidth = ref(0)
|
||||
const isSmallScreen = ref(false)
|
||||
const defaultTitle = '系统应用 & 设置'
|
||||
const defaultTitle = t('appLauncher.title')
|
||||
const title = ref('')
|
||||
const height = ref('500px')
|
||||
|
||||
const apps = ref<App[]>([
|
||||
{
|
||||
name: '用户信息',
|
||||
name: t('apps.userInfo.appName'),
|
||||
componentName: 'UserInfo',
|
||||
icon: 'material-symbols-person-edit-outline-rounded',
|
||||
},
|
||||
{
|
||||
name: '基本设置',
|
||||
name: t('apps.baseSettings.appName'),
|
||||
componentName: 'Style',
|
||||
icon: 'ep-setting',
|
||||
},
|
||||
{
|
||||
name: '分组管理',
|
||||
name: t('apps.itemGroupManage.appName'),
|
||||
componentName: 'ItemGroupManage',
|
||||
icon: 'material-symbols-ad-group-outline-rounded',
|
||||
},
|
||||
{
|
||||
name: '导入导出',
|
||||
name: t('apps.exportImport.appName'),
|
||||
componentName: 'ImportExport',
|
||||
icon: 'icon-park-outline-import-and-export',
|
||||
},
|
||||
{
|
||||
name: '上传文件管理',
|
||||
name: t('apps.uploadsFileManager.appName'),
|
||||
componentName: 'UploadFileManager',
|
||||
icon: 'tabler:file-upload',
|
||||
},
|
||||
{
|
||||
name: '关于',
|
||||
name: t('apps.about.appName'),
|
||||
componentName: 'About',
|
||||
icon: 'lucide-info',
|
||||
},
|
||||
@ -93,7 +94,7 @@ function handleResize() {
|
||||
|
||||
onMounted(() => {
|
||||
const adminApp: App = {
|
||||
name: '用户管理',
|
||||
name: t('adminSettingUsers.appName'),
|
||||
componentName: 'Users',
|
||||
icon: 'lucide-users',
|
||||
auth: 1,
|
||||
@ -116,7 +117,6 @@ onUnmounted(() => {
|
||||
<RoundCardModal
|
||||
v-model:show="show"
|
||||
style="max-width: 900px;"
|
||||
title="应用列表"
|
||||
size="small"
|
||||
>
|
||||
<template #header>
|
||||
|
@ -4,6 +4,7 @@ import type { UploadFileInfo } from 'naive-ui'
|
||||
import { computed, defineProps } from 'vue'
|
||||
import { ItemIcon } from '@/components/common'
|
||||
import { useAuthStore } from '@/store'
|
||||
import { t } from '@/locales'
|
||||
|
||||
const props = defineProps<{
|
||||
itemIcon: Panel.ItemIcon | null
|
||||
@ -41,7 +42,6 @@ const itemIconInfo = computed({
|
||||
return v
|
||||
},
|
||||
set() {
|
||||
console.log('aaaa')
|
||||
handleChange()
|
||||
},
|
||||
})
|
||||
@ -53,7 +53,6 @@ function handleIconTypeRadioChange(type: number) {
|
||||
}
|
||||
|
||||
function handleChange() {
|
||||
console.log('21222')
|
||||
emit('update:itemIcon', itemIconInfo.value || null)
|
||||
}
|
||||
|
||||
@ -76,7 +75,7 @@ const handleUploadFinish = ({
|
||||
emit('update:itemIcon', itemIconInfo.value || null)
|
||||
}
|
||||
else {
|
||||
ms.error(`上传错误:${res.msg}`)
|
||||
ms.error(`${t('common.uploadFail')}:${res.msg}`)
|
||||
}
|
||||
|
||||
return file
|
||||
@ -92,7 +91,7 @@ const handleUploadFinish = ({
|
||||
name="iconType"
|
||||
@change="handleIconTypeRadioChange(1)"
|
||||
>
|
||||
文字
|
||||
{{ $t('common.text') }}
|
||||
</NRadio>
|
||||
|
||||
<NRadio
|
||||
@ -101,7 +100,7 @@ const handleUploadFinish = ({
|
||||
name="iconType"
|
||||
@change="handleIconTypeRadioChange(2)"
|
||||
>
|
||||
图片/SVG
|
||||
{{ $t('common.image') }}
|
||||
</NRadio>
|
||||
|
||||
<NRadio
|
||||
@ -110,7 +109,7 @@ const handleUploadFinish = ({
|
||||
name="iconType"
|
||||
@change="handleIconTypeRadioChange(3)"
|
||||
>
|
||||
在线图标
|
||||
{{ $t('iconItem.onlineIcon') }}
|
||||
</NRadio>
|
||||
</div>
|
||||
|
||||
@ -125,22 +124,22 @@ const handleUploadFinish = ({
|
||||
<div class="ml-[20px]">
|
||||
<!-- <NImage :src="model.icon" preview-disabled /> -->
|
||||
<div v-if="itemIconInfo.itemType === 1">
|
||||
<NInput v-model:value="itemIconInfo.text" class="mb-[5px]" size="small" type="text" placeholder="请输入文字作为图标" @input="handleChange" />
|
||||
<NInput v-model:value="itemIconInfo.text" class="mb-[5px]" size="small" type="text" @input="handleChange" />
|
||||
</div>
|
||||
|
||||
<div v-if="itemIconInfo.itemType === 3">
|
||||
<div>
|
||||
<NInput v-model:value="itemIconInfo.text" class="mb-[5px]" size="small" type="text" placeholder="请输入图标名字" @input="handleChange" />
|
||||
<NInput v-model:value="itemIconInfo.text" class="mb-[5px]" size="small" type="text" :placeholder="$t('iconItem.inputIconName')" @input="handleChange" />
|
||||
|
||||
<NButton quaternary type="info">
|
||||
<a target="_blank" href="https://icon-sets.iconify.design/">在线图标库</a>
|
||||
<a target="_blank" href="https://icon-sets.iconify.design/">{{ $t('iconItem.onlineIconLibrary') }}</a>
|
||||
</NButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图片 -->
|
||||
<div v-if="itemIconInfo.itemType === 2">
|
||||
<NInput v-model:value="itemIconInfo.src" class="mb-[5px] w-full" size="small" type="text" placeholder="输入图标地址或上传" @input="handleChange" />
|
||||
<NInput v-model:value="itemIconInfo.src" class="mb-[5px] w-full" size="small" type="text" :placeholder="$t('iconItem.inputIconUrlOrUpload')" @input="handleChange" />
|
||||
<NUpload
|
||||
action="/api/file/uploadImg"
|
||||
:show-file-list="false"
|
||||
@ -151,7 +150,7 @@ const handleUploadFinish = ({
|
||||
@finish="handleUploadFinish"
|
||||
>
|
||||
<NButton size="small">
|
||||
本地上传
|
||||
{{ $t('iconItem.selectUpload') }}
|
||||
</NButton>
|
||||
</NUpload>
|
||||
</div>
|
||||
@ -160,7 +159,7 @@ const handleUploadFinish = ({
|
||||
|
||||
<div class="flex items-center mt-[10px]">
|
||||
<div class="w-auto text-slate-500 mr-[10px]">
|
||||
背景色:
|
||||
{{ $t('common.backgroundColor') }}
|
||||
</div>
|
||||
<div class="w-[150px] flex items-center mr-[10px]">
|
||||
<NColorPicker
|
||||
@ -174,7 +173,7 @@ const handleUploadFinish = ({
|
||||
</div>
|
||||
<div v-if="itemIconInfo.backgroundColor !== initData.backgroundColor" class="w-auto text-slate-500 mr-[10px] cursor-pointer">
|
||||
<NButton quaternary type="info" @click="handleResetBackgroundColor">
|
||||
恢复默认
|
||||
{{ $t('common.reset') }}
|
||||
</NButton>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -5,6 +5,7 @@ import { NButton, NForm, NFormItem, NGrid, NGridItem, NInput, NInputGroup, NModa
|
||||
import IconEditor from './IconEditor.vue'
|
||||
import { edit, getSiteFavicon } from '@/api/panel/itemIcon'
|
||||
import { getList as getGroupList } from '@/api/panel/itemIconGroup'
|
||||
import { t } from '@/locales'
|
||||
|
||||
interface Props {
|
||||
visible: boolean
|
||||
@ -43,33 +44,33 @@ const rules: FormRules = {
|
||||
title: {
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
message: '必填项',
|
||||
message: t('form.required'),
|
||||
},
|
||||
url: {
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
type: 'string',
|
||||
message: '必填项',
|
||||
message: t('form.required'),
|
||||
},
|
||||
// itemIconGroupId: {
|
||||
// required: true,
|
||||
// trigger: ['blur', 'change'],
|
||||
// message: '必填项',
|
||||
// message: t('form.required'),
|
||||
// },
|
||||
}
|
||||
|
||||
const options = [
|
||||
{
|
||||
default: true,
|
||||
label: '当前页面打开',
|
||||
label: t('iconItem.currentPageOpen'),
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '新窗口打开',
|
||||
label: t('iconItem.newWindowOpen'),
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: '当前页面弹窗打开',
|
||||
label: t('iconItem.currentPageLayerOpen'),
|
||||
value: 3,
|
||||
},
|
||||
]
|
||||
@ -89,16 +90,15 @@ async function editApi() {
|
||||
if (code === 0) {
|
||||
show.value = false
|
||||
model.value = { ...restoreDefault }
|
||||
console.log('重置完成', model.value)
|
||||
|
||||
emit('done', data)
|
||||
}
|
||||
else {
|
||||
ms.error(`保存失败:${msg}`)
|
||||
ms.error(`${t('common.saveFail')}:${msg}`)
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
ms.error('保存失败')
|
||||
ms.error(t('common.saveFail'))
|
||||
}
|
||||
submitLoading.value = false
|
||||
}
|
||||
@ -122,11 +122,11 @@ async function getIconByUrl(url: string, loadingIndex: number) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
ms.error('图标获取失败')
|
||||
ms.error(t('iconItem.geticonFail'))
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
ms.error('图标获取失败')
|
||||
ms.error(t('iconItem.geticonFail'))
|
||||
}
|
||||
getIconLoading.value[loadingIndex] = false
|
||||
}
|
||||
@ -160,53 +160,53 @@ function getGroupListOptions() {
|
||||
}
|
||||
}
|
||||
else {
|
||||
ms.error(`分组信息获取失败:${msg}`)
|
||||
ms.error(`${t('iconItem.getGroupFail')}:${msg}`)
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NModal v-model:show="show" preset="card" size="small" style="width: 600px;border-radius: 1rem;" :title="itemInfo ? '修改项目' : '添加项目'">
|
||||
<NModal v-model:show="show" preset="card" size="small" style="width: 600px;border-radius: 1rem;" :title="itemInfo ? t('iconItem.edit') : t('iconItem.add')">
|
||||
<div class="h-[600px] overflow-auto p-[5px]">
|
||||
<NForm ref="formRef" :model="model" :rules="rules">
|
||||
<NGrid cols="2" :x-gap="10" item-responsive>
|
||||
<NGridItem span="2 500:1">
|
||||
<NFormItem path="itemIconGroupId" label="分组">
|
||||
<NFormItem path="itemIconGroupId" :label="t('iconItem.iconGroup')">
|
||||
<NSelect v-model:value="model.itemIconGroupId" :options="itemIconGroupOptions" />
|
||||
</NFormItem>
|
||||
</NGridItem>
|
||||
<NGridItem span="2 500:1">
|
||||
<NFormItem path="title" label="标题">
|
||||
<NInput v-model:value="model.title" type="text" show-count :maxlength="20" placeholder="请输入标题" />
|
||||
<NFormItem path="title" :label="$t('common.title')">
|
||||
<NInput v-model:value="model.title" type="text" show-count :maxlength="20" />
|
||||
</NFormItem>
|
||||
</NGridItem>
|
||||
</NGrid>
|
||||
|
||||
<NFormItem path="icon" label="图标">
|
||||
<NFormItem path="icon" :label="$t('common.icon')">
|
||||
<IconEditor v-model:item-icon="model.icon" />
|
||||
</NFormItem>
|
||||
<NFormItem path="url" label="跳转地址">
|
||||
<NFormItem path="url" :label="$t('iconItem.url')">
|
||||
<!-- <NSelect :style="{ width: '100px' }" :options="urlProtocolOptions" /> -->
|
||||
<NInputGroup>
|
||||
<NInput v-model:value="model.url" type="text" :maxlength="1000" placeholder="http(s)://" />
|
||||
<NButton :disabled="!model.url" :loading="getIconLoading[0]" @click="getIconByUrl(model.url, 0)">
|
||||
获取图标
|
||||
{{ $t('iconItem.getIcon') }}
|
||||
</NButton>
|
||||
</NInputGroup>
|
||||
</NFormItem>
|
||||
<NFormItem path="lanUrl" label="局域网跳转地址">
|
||||
<NFormItem path="lanUrl" :label="$t('iconItem.lanUrl')">
|
||||
<NInputGroup>
|
||||
<NInput v-model:value="model.lanUrl" type="text" :maxlength="1000" placeholder="http(s)://(可以留空,切换到局域网模式,点击会使用该地址)" />
|
||||
<NInput v-model:value="model.lanUrl" type="text" :maxlength="1000" :placeholder="$t('iconItem.lanUrlInputPlaceholder')" />
|
||||
<NButton :disabled="!model.lanUrl" :loading="getIconLoading[1]" @click="getIconByUrl(model.lanUrl || '', 1)">
|
||||
获取图标
|
||||
{{ $t('iconItem.getIcon') }}
|
||||
</NButton>
|
||||
</NInputGroup>
|
||||
</NFormItem>
|
||||
<NFormItem path="description" label="描述信息">
|
||||
<NInput v-model:value="model.description" type="text" show-count :maxlength="100" placeholder="请填写描述信息" />
|
||||
<NFormItem path="description" :label="$t('common.description')">
|
||||
<NInput v-model:value="model.description" type="text" show-count :maxlength="100" />
|
||||
</NFormItem>
|
||||
<NFormItem path="openMethod" label="打开方式">
|
||||
<NFormItem path="openMethod" :label="$t('iconItem.openMethod')">
|
||||
<NSelect v-model:value="model.openMethod" :options="options" />
|
||||
</NFormItem>
|
||||
</NForm>
|
||||
@ -214,7 +214,7 @@ function getGroupListOptions() {
|
||||
|
||||
<template #footer>
|
||||
<NButton type="success" :loading="submitLoading" style="float: right;" @click="handleValidateButtonClick">
|
||||
确定
|
||||
{{ $t('common.save') }}
|
||||
</NButton>
|
||||
</template>
|
||||
</NModal>
|
||||
|
@ -13,6 +13,7 @@ import { useAuthStore, usePanelState } from '@/store'
|
||||
import { PanelPanelConfigStyleEnum, PanelStateNetworkModeEnum } from '@/enums'
|
||||
import { VisitMode } from '@/enums/auth'
|
||||
import { router } from '@/router'
|
||||
import { t } from '@/locales'
|
||||
|
||||
interface ItemGroup extends Panel.ItemIconGroup {
|
||||
sortStatus?: boolean
|
||||
@ -134,18 +135,18 @@ function handleRightMenuSelect(key: string | number) {
|
||||
break
|
||||
case 'delete':
|
||||
dialog.warning({
|
||||
title: '警告',
|
||||
content: `你确定要删除图标 ${currentRightSelectItem.value?.title} ?`,
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
title: t('common.warning'),
|
||||
content: t('common.deleteConfirmByName', { name: currentRightSelectItem.value?.title }),
|
||||
positiveText: t('common.confirm'),
|
||||
negativeText: t('common.cancel'),
|
||||
onPositiveClick: () => {
|
||||
deletes([currentRightSelectItem.value?.id as number]).then(({ code, msg }) => {
|
||||
if (code === 0) {
|
||||
ms.success('已删除')
|
||||
ms.success(t('common.deleteSuccess'))
|
||||
getList()
|
||||
}
|
||||
else {
|
||||
ms.error(`删除失败:${msg}`)
|
||||
ms.error(`${t('common.deleteFail')}:${msg}`)
|
||||
}
|
||||
})
|
||||
},
|
||||
@ -183,10 +184,10 @@ function handleEditSuccess(item: Panel.ItemInfo) {
|
||||
function handleChangeNetwork(mode: PanelStateNetworkModeEnum) {
|
||||
panelState.setNetworkMode(mode)
|
||||
if (mode === PanelStateNetworkModeEnum.lan)
|
||||
ms.success('已经切换成局域网模式(此配置仅保存在本地)')
|
||||
ms.success(t('panelHome.changeToLanModelSuccess'))
|
||||
|
||||
else
|
||||
ms.success('已经切换成互联网模式(此配置仅保存在本地)')
|
||||
ms.success(t('panelHome.changeToWanModelSuccess'))
|
||||
}
|
||||
|
||||
// 结束拖拽
|
||||
@ -208,11 +209,11 @@ function handleSaveSort(itemGroup: ItemGroup) {
|
||||
|
||||
saveSort({ itemIconGroupId: itemGroup.id as number, sortItems: saveItems }).then(({ code, msg }) => {
|
||||
if (code === 0) {
|
||||
ms.success('保存成功')
|
||||
ms.success(t('common.saveSuccess'))
|
||||
itemGroup.sortStatus = false
|
||||
}
|
||||
else {
|
||||
ms.error(`保存失败:${msg}`)
|
||||
ms.error(`${t('common.saveFail')}:${msg}`)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -221,7 +222,7 @@ function handleSaveSort(itemGroup: ItemGroup) {
|
||||
function getDropdownMenuOptions() {
|
||||
const dropdownMenuOptions = [
|
||||
{
|
||||
label: '新窗口打开',
|
||||
label: t('iconItem.newWindowOpen'),
|
||||
key: 'newWindows',
|
||||
},
|
||||
|
||||
@ -229,24 +230,24 @@ function getDropdownMenuOptions() {
|
||||
|
||||
if (currentRightSelectItem.value?.lanUrl && panelState.networkMode === PanelStateNetworkModeEnum.wan) {
|
||||
dropdownMenuOptions.push({
|
||||
label: '打开局域网地址',
|
||||
label: t('panelHome.openLanUrl'),
|
||||
key: 'openLanUrl',
|
||||
})
|
||||
}
|
||||
|
||||
if (currentRightSelectItem.value?.lanUrl && panelState.networkMode === PanelStateNetworkModeEnum.lan) {
|
||||
dropdownMenuOptions.push({
|
||||
label: '打开互联网地址',
|
||||
label: t('panelHome.openWanUrl'),
|
||||
key: 'openWanUrl',
|
||||
})
|
||||
}
|
||||
|
||||
if (authStore.visitMode === VisitMode.VISIT_MODE_LOGIN) {
|
||||
dropdownMenuOptions.push({
|
||||
label: '编辑',
|
||||
label: t('common.edit'),
|
||||
key: 'edit',
|
||||
}, {
|
||||
label: '删除',
|
||||
label: t('common.delete'),
|
||||
key: 'delete',
|
||||
})
|
||||
}
|
||||
@ -394,10 +395,10 @@ function handleAddItem(itemIconGroupId?: number) {
|
||||
class="ml-2 delay-100 transition-opacity flex"
|
||||
:class="itemGroup.hoverStatus ? 'opacity-100' : 'opacity-0'"
|
||||
>
|
||||
<span class="mr-2 cursor-pointer" title="添加快捷图标" @click="handleAddItem(itemGroup.id)">
|
||||
<span class="mr-2 cursor-pointer" :title="t('common.add')" @click="handleAddItem(itemGroup.id)">
|
||||
<SvgIcon class="text-white font-xl" icon="typcn:plus" />
|
||||
</span>
|
||||
<span class="mr-2 cursor-pointer " title="排序组快捷图标" @click="handleSetSortStatus(itemGroupIndex, !itemGroup.sortStatus)">
|
||||
<span class="mr-2 cursor-pointer " :title="t('common.sort')" @click="handleSetSortStatus(itemGroupIndex, !itemGroup.sortStatus)">
|
||||
<SvgIcon class="text-white font-xl" icon="ri:drag-drop-line" />
|
||||
</span>
|
||||
</div>
|
||||
@ -427,7 +428,7 @@ function handleAddItem(itemIconGroupId?: number) {
|
||||
<div v-if="itemGroup.items.length === 0" class="not-drag">
|
||||
<AppIcon
|
||||
:class="itemGroup.sortStatus ? 'cursor-move' : 'cursor-pointer'"
|
||||
:item-info="{ icon: { itemType: 3, text: 'subway:add' }, title: '添加图标', url: '', openMethod: 0 }"
|
||||
:item-info="{ icon: { itemType: 3, text: 'subway:add' }, title: t('common.add'), url: '', openMethod: 0 }"
|
||||
:icon-text-color="panelState.panelConfig.iconTextColor"
|
||||
:icon-text-info-hide-description="panelState.panelConfig.iconTextInfoHideDescription || false"
|
||||
:icon-text-icon-hide-title="panelState.panelConfig.iconTextIconHideTitle || false"
|
||||
@ -464,7 +465,7 @@ function handleAddItem(itemIconGroupId?: number) {
|
||||
<div v-if="itemGroup.items.length === 0" class="not-drag">
|
||||
<AppIcon
|
||||
class="cursor-pointer"
|
||||
:item-info="{ icon: { itemType: 3, text: 'subway:add' }, title: '添加图标', url: '', openMethod: 0 }"
|
||||
:item-info="{ icon: { itemType: 3, text: 'subway:add' }, title: $t('common.add'), url: '', openMethod: 0 }"
|
||||
:icon-text-color="panelState.panelConfig.iconTextColor"
|
||||
:icon-text-info-hide-description="!panelState.panelConfig.iconTextInfoHideDescription"
|
||||
:icon-text-icon-hide-title="panelState.panelConfig.iconTextIconHideTitle || false"
|
||||
@ -484,7 +485,7 @@ function handleAddItem(itemIconGroupId?: number) {
|
||||
<SvgIcon class="text-white font-xl" icon="material-symbols:save" />
|
||||
</template>
|
||||
<div>
|
||||
保存排序
|
||||
{{ $t('common.saveSort') }}
|
||||
</div>
|
||||
</NButton>
|
||||
</div>
|
||||
@ -506,7 +507,7 @@ function handleAddItem(itemIconGroupId?: number) {
|
||||
<NButtonGroup vertical>
|
||||
<NButton
|
||||
v-if="panelState.networkMode === PanelStateNetworkModeEnum.lan" color="#2a2a2a6b"
|
||||
title="当前:局域网模式,点击切换成互联网模式" @click="handleChangeNetwork(PanelStateNetworkModeEnum.wan)"
|
||||
:title="t('panelHome.changeToWanModel')" @click="handleChangeNetwork(PanelStateNetworkModeEnum.wan)"
|
||||
>
|
||||
<template #icon>
|
||||
<SvgIcon class="text-white font-xl" icon="material-symbols:lan-outline-rounded" />
|
||||
@ -515,7 +516,7 @@ function handleAddItem(itemIconGroupId?: number) {
|
||||
|
||||
<NButton
|
||||
v-if="panelState.networkMode === PanelStateNetworkModeEnum.wan" color="#2a2a2a6b"
|
||||
title="当前:互联网模式,点击切换成局域网模式" @click="handleChangeNetwork(PanelStateNetworkModeEnum.lan)"
|
||||
:title="t('panelHome.changeToLanModel')" @click="handleChangeNetwork(PanelStateNetworkModeEnum.lan)"
|
||||
>
|
||||
<template #icon>
|
||||
<SvgIcon class="text-white font-xl" icon="mdi:wan" />
|
||||
@ -528,7 +529,7 @@ function handleAddItem(itemIconGroupId?: number) {
|
||||
</template>
|
||||
</NButton>
|
||||
|
||||
<NButton v-if="authStore.visitMode === VisitMode.VISIT_MODE_PUBLIC" color="#2a2a2a6b" title="登录" @click="router.push('/login')">
|
||||
<NButton v-if="authStore.visitMode === VisitMode.VISIT_MODE_PUBLIC" color="#2a2a2a6b" :title="t('panelHome.goToLogin')" @click="router.push('/login')">
|
||||
<template #icon>
|
||||
<SvgIcon class="text-white font-xl" icon="material-symbols:account-circle" />
|
||||
</template>
|
||||
|
@ -1,16 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import { NButton, NCard, NForm, NFormItem, NGradientText, NInput, useMessage } from 'naive-ui'
|
||||
import { NButton, NCard, NForm, NFormItem, NGradientText, NInput, NSelect, useMessage } from 'naive-ui'
|
||||
import { ref } from 'vue'
|
||||
import { login } from '@/api'
|
||||
import { useAuthStore } from '@/store'
|
||||
import { useAppStore, useAuthStore } from '@/store'
|
||||
import { SvgIcon } from '@/components/common'
|
||||
import { router } from '@/router'
|
||||
import { t } from '@/locales'
|
||||
import { languageOptions } from '@/utils/defaultData'
|
||||
import type { Language } from '@/store/modules/app/helper'
|
||||
|
||||
// const userStore = useUserStore()
|
||||
const authStore = useAuthStore()
|
||||
const appStore = useAppStore()
|
||||
const ms = useMessage()
|
||||
const loading = ref(false)
|
||||
const languageValue = ref<Language>(appStore.language)
|
||||
|
||||
// const isShowCaptcha = ref<boolean>(false)
|
||||
// const isShowRegister = ref<boolean>(false)
|
||||
|
||||
@ -45,11 +50,25 @@ function handleSubmit() {
|
||||
// 点击登录按钮触发
|
||||
loginPost()
|
||||
}
|
||||
|
||||
function handleChangeLanuage(value: Language) {
|
||||
languageValue.value = value
|
||||
appStore.setLanguage(value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="login-container">
|
||||
<NCard class="login-card" style="border-radius: 20px;">
|
||||
<div class="mb-5 flex items-center justify-end">
|
||||
<div class="mr-2">
|
||||
<SvgIcon icon="ion-language" style="width: 20;height: 20;" />
|
||||
</div>
|
||||
<div class="min-w-[100px]">
|
||||
<NSelect v-model:value="languageValue" size="small" :options="languageOptions" @update-value="handleChangeLanuage" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="login-title ">
|
||||
<NGradientText :size="30" type="success" class="!font-bold">
|
||||
{{ $t('common.appName') }}
|
||||
|
Loading…
x
Reference in New Issue
Block a user