mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 04:22:33 +08:00
feat: 清理代码
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
"build": "run-s gen-auto-import type-check build-only copy",
|
||||
"preview": "vite preview",
|
||||
"build-only": "vite build",
|
||||
"type-check": "vue-tsc --noEmit",
|
||||
"type-check": "vue-tsc --noEmit -p tsconfig.app.json",
|
||||
"lint": "run-s gen-auto-import lint-only",
|
||||
"lint-only": "eslint . --fix",
|
||||
"format": "prettier --write src/",
|
||||
|
||||
@@ -39,7 +39,7 @@ const parseDescription = computed((): string => {
|
||||
return $gettext('Cron expression: %{cron}', { cron })
|
||||
}
|
||||
|
||||
const [minute, hour, day, month, weekday] = parts
|
||||
const [minute, hour, day, month, weekday] = parts as [string, string, string, string, string]
|
||||
|
||||
try {
|
||||
// 每 N 分钟:*/N * * * *
|
||||
|
||||
@@ -27,7 +27,6 @@ const minimized = defineModel<boolean>('minimized', { default: false })
|
||||
|
||||
// 窗口状态
|
||||
const isMaximized = ref(false)
|
||||
const windowRef = ref<HTMLDivElement>()
|
||||
|
||||
// 窗口位置和大小
|
||||
const position = ref({ x: 0, y: 0 })
|
||||
|
||||
@@ -69,7 +69,7 @@ const updateKey = (oldKey: string, newKey: string) => {
|
||||
if (props.modelValue[newKey] !== undefined) return // 键已存在
|
||||
|
||||
const data = { ...props.modelValue }
|
||||
data[newKey] = data[oldKey]
|
||||
data[newKey] = data[oldKey] ?? ''
|
||||
delete data[oldKey]
|
||||
emit('update:modelValue', data)
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ function handleLanguageChange(value: string) {
|
||||
|
||||
// 更新缩进
|
||||
function handleIndentChange(value: string) {
|
||||
const [size, type] = value.split('-')
|
||||
const [size, type] = value.split('-') as [string, string]
|
||||
editorStore.updateSettings({
|
||||
tabSize: parseInt(size),
|
||||
insertSpaces: type === 'spaces'
|
||||
|
||||
@@ -187,17 +187,18 @@ function showCreate(type: 'file' | 'dir') {
|
||||
|
||||
// 确定父目录
|
||||
if (selectedKeys.value.length > 0) {
|
||||
const selectedNode = findNode(treeData.value, selectedKeys.value[0])
|
||||
const selectedKey = selectedKeys.value[0] ?? ''
|
||||
const selectedNode = findNode(treeData.value, selectedKey)
|
||||
if (selectedNode && !selectedNode.isLeaf) {
|
||||
// 选中的是目录,在该目录下新建
|
||||
inlineCreateParentPath.value = selectedKeys.value[0]
|
||||
inlineCreateParentPath.value = selectedKey
|
||||
// 确保目录已展开
|
||||
if (!expandedKeys.value.includes(selectedKeys.value[0])) {
|
||||
expandedKeys.value = [...expandedKeys.value, selectedKeys.value[0]]
|
||||
if (!expandedKeys.value.includes(selectedKey)) {
|
||||
expandedKeys.value = [...expandedKeys.value, selectedKey]
|
||||
}
|
||||
} else {
|
||||
// 选中的是文件,在其父目录下新建
|
||||
const parts = selectedKeys.value[0].split('/')
|
||||
const parts = selectedKey.split('/')
|
||||
parts.pop()
|
||||
inlineCreateParentPath.value = parts.join('/') || props.rootPath
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@ import { translateTitle } from '@/locales/menu'
|
||||
import { usePermissionStore, useTabStore, useThemeStore } from '@/store'
|
||||
import { isUrl, renderIcon } from '@/utils'
|
||||
|
||||
import { MenuInst, MenuOption, useThemeVars } from 'naive-ui'
|
||||
import type { MenuInst, MenuOption } from 'naive-ui'
|
||||
import { useThemeVars } from 'naive-ui'
|
||||
import type { VNodeChild } from 'vue'
|
||||
import { RouterLink } from 'vue-router'
|
||||
import type { Meta, RouteType } from '~/types/router'
|
||||
|
||||
@@ -57,7 +57,7 @@ const options = computed(() => [
|
||||
{
|
||||
label: $gettext('Close Left'),
|
||||
key: 'close-left',
|
||||
disabled: tabStore.tabs.length <= 1 || props.currentPath === tabStore.tabs[0].path,
|
||||
disabled: tabStore.tabs.length <= 1 || props.currentPath === tabStore.tabs[0]?.path,
|
||||
icon: renderIcon('mdi:arrow-expand-left', { size: 14 })
|
||||
},
|
||||
{
|
||||
@@ -65,7 +65,7 @@ const options = computed(() => [
|
||||
key: 'close-right',
|
||||
disabled:
|
||||
tabStore.tabs.length <= 1 ||
|
||||
props.currentPath === tabStore.tabs[tabStore.tabs.length - 1].path,
|
||||
props.currentPath === tabStore.tabs[tabStore.tabs.length - 1]?.path,
|
||||
icon: renderIcon('mdi:arrow-expand-right', { size: 14 })
|
||||
}
|
||||
])
|
||||
|
||||
@@ -38,7 +38,8 @@ const modules = import.meta.glob('@/views/**/route.ts', {
|
||||
}) as RouteModule
|
||||
const asyncRoutes: RoutesType = []
|
||||
Object.keys(modules).forEach((key) => {
|
||||
asyncRoutes.push(modules[key].default)
|
||||
const route = modules[key]?.default
|
||||
if (route) asyncRoutes.push(route)
|
||||
})
|
||||
|
||||
export { asyncRoutes }
|
||||
|
||||
@@ -137,9 +137,9 @@ export const useEditorStore = defineStore('editor', {
|
||||
if (this.tabs.length === 0) {
|
||||
this.activeTabPath = null
|
||||
} else if (index >= this.tabs.length) {
|
||||
this.activeTabPath = this.tabs[this.tabs.length - 1].path
|
||||
this.activeTabPath = this.tabs[this.tabs.length - 1]?.path ?? null
|
||||
} else {
|
||||
this.activeTabPath = this.tabs[index].path
|
||||
this.activeTabPath = this.tabs[index]?.path ?? null
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -162,7 +162,7 @@ export const useEditorStore = defineStore('editor', {
|
||||
if (this.tabs.length === 0) {
|
||||
this.activeTabPath = null
|
||||
} else if (!this.tabs.find((tab) => tab.path === this.activeTabPath)) {
|
||||
this.activeTabPath = this.tabs[0].path
|
||||
this.activeTabPath = this.tabs[0]?.path ?? null
|
||||
}
|
||||
},
|
||||
|
||||
@@ -255,7 +255,7 @@ export const useEditorStore = defineStore('editor', {
|
||||
if (toIndex < 0 || toIndex >= this.tabs.length) return
|
||||
|
||||
const [movedTab] = this.tabs.splice(fromIndex, 1)
|
||||
this.tabs.splice(toIndex, 0, movedTab)
|
||||
if (movedTab) this.tabs.splice(toIndex, 0, movedTab)
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -64,28 +64,28 @@ export const useTabStore = defineStore('tab', {
|
||||
removeTab(path: string) {
|
||||
if (path === this.active) {
|
||||
const activeIndex = this.tabs.findIndex((item) => item.path === path)
|
||||
if (activeIndex > 0) router.push(this.tabs[activeIndex - 1].path)
|
||||
else router.push(this.tabs[activeIndex + 1].path)
|
||||
if (activeIndex > 0) router.push(this.tabs[activeIndex - 1]?.path ?? '/')
|
||||
else router.push(this.tabs[activeIndex + 1]?.path ?? '/')
|
||||
}
|
||||
this.setTabs(this.tabs.filter((tab) => tab.path !== path))
|
||||
},
|
||||
removeOther(curPath: string) {
|
||||
this.setTabs(this.tabs.filter((tab) => tab.path === curPath))
|
||||
if (curPath !== this.active) router.push(this.tabs[this.tabs.length - 1].path)
|
||||
if (curPath !== this.active) router.push(this.tabs[this.tabs.length - 1]?.path ?? '/')
|
||||
},
|
||||
removeLeft(curPath: string) {
|
||||
const curIndex = this.tabs.findIndex((item) => item.path === curPath)
|
||||
const filterTabs = this.tabs.filter((item, index) => index >= curIndex)
|
||||
this.setTabs(filterTabs)
|
||||
if (!filterTabs.find((item) => item.path === this.active))
|
||||
router.push(filterTabs[filterTabs.length - 1].path)
|
||||
router.push(filterTabs[filterTabs.length - 1]?.path ?? '/')
|
||||
},
|
||||
removeRight(curPath: string) {
|
||||
const curIndex = this.tabs.findIndex((item) => item.path === curPath)
|
||||
const filterTabs = this.tabs.filter((item, index) => index <= curIndex)
|
||||
this.setTabs(filterTabs)
|
||||
if (!filterTabs.find((item) => item.path === this.active))
|
||||
router.push(filterTabs[filterTabs.length - 1].path)
|
||||
router.push(filterTabs[filterTabs.length - 1]?.path ?? '/')
|
||||
},
|
||||
resetTabs() {
|
||||
this.setTabs([])
|
||||
|
||||
@@ -20,10 +20,10 @@ export const useThemeStore = defineStore('theme', {
|
||||
return this.darkMode ? darkTheme : undefined
|
||||
},
|
||||
naiveLocale(): NLocale {
|
||||
return locales[this.locale].locale
|
||||
return locales[this.locale]?.locale ?? enUS
|
||||
},
|
||||
naiveDateLocale(): NDateLocale {
|
||||
return locales[this.locale].dateLocale
|
||||
return locales[this.locale]?.dateLocale ?? dateEnUS
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
|
||||
@@ -11,7 +11,7 @@ export function encodeBase64(str: string): string {
|
||||
const bytes = new TextEncoder().encode(str)
|
||||
let binary = ''
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
binary += String.fromCharCode(bytes[i])
|
||||
binary += String.fromCharCode(bytes[i] ?? 0)
|
||||
}
|
||||
return btoa(binary)
|
||||
}
|
||||
|
||||
@@ -47,9 +47,10 @@ export function generateRandomString(length: number) {
|
||||
for (let i = 0; i < randomBytes.length && result.length < length; i++) {
|
||||
// Only use values that map evenly to the character set to avoid bias
|
||||
const maxValue = Math.floor(256 / charactersLength) * charactersLength
|
||||
if (randomBytes[i] < maxValue) {
|
||||
const randomIndex = randomBytes[i] % charactersLength
|
||||
result += characters[randomIndex]
|
||||
const byteValue = randomBytes[i] ?? 0
|
||||
if (byteValue < maxValue) {
|
||||
const randomIndex = byteValue % charactersLength
|
||||
result += characters[randomIndex] ?? ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import api from '@/api/panel/backup'
|
||||
const { $gettext } = useGettext()
|
||||
const show = defineModel<boolean>('show', { type: Boolean, required: true })
|
||||
const type = defineModel<string>('type', { type: String, required: true })
|
||||
const upload = ref<any>(null)
|
||||
|
||||
const uploadRequest = ({ file, onFinish, onError, onProgress }: UploadCustomRequestOptions) => {
|
||||
const formData = new FormData()
|
||||
|
||||
@@ -94,7 +94,7 @@ const getNetworks = () => {
|
||||
value: item.id
|
||||
}))
|
||||
if (networks.value.length > 0) {
|
||||
createModel.network = networks.value[0].value
|
||||
createModel.network = networks.value[0]?.value ?? ''
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -13,8 +13,6 @@ const show = defineModel<boolean>('show', { type: Boolean, required: true })
|
||||
const minimized = defineModel<boolean>('minimized', { type: Boolean, default: false })
|
||||
const filePath = defineModel<string>('file', { type: String, required: true })
|
||||
|
||||
const editorRef = ref<InstanceType<typeof FileEditorView>>()
|
||||
|
||||
// 窗口默认尺寸
|
||||
const defaultWidth = Math.min(1400, window.innerWidth * 0.9)
|
||||
const defaultHeight = Math.min(900, window.innerHeight * 0.85)
|
||||
|
||||
@@ -120,7 +120,7 @@ const handleDrop = async (e: DragEvent) => {
|
||||
// 使用 webkitGetAsEntry 来支持文件夹
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const item = items[i]
|
||||
if (item.kind === 'file') {
|
||||
if (item?.kind === 'file') {
|
||||
const entry = item.webkitGetAsEntry()
|
||||
if (entry) {
|
||||
if (entry.isFile) {
|
||||
|
||||
@@ -184,7 +184,7 @@ const selectionBox = computed(() => {
|
||||
const hexToRgb = (hex: string) => {
|
||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
|
||||
return result
|
||||
? `${parseInt(result[1], 16)}, ${parseInt(result[2], 16)}, ${parseInt(result[3], 16)}`
|
||||
? `${parseInt(result[1] ?? '0', 16)}, ${parseInt(result[2] ?? '0', 16)}, ${parseInt(result[3] ?? '0', 16)}`
|
||||
: '24, 160, 88'
|
||||
}
|
||||
|
||||
@@ -843,7 +843,8 @@ const handlePaste = () => {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
if (data[i]) {
|
||||
flag = true
|
||||
paths[i].force = true
|
||||
const pathItem = paths[i]
|
||||
if (pathItem) pathItem.force = true
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
|
||||
@@ -53,7 +53,7 @@ const handleUp = () => {
|
||||
const handleBack = () => {
|
||||
if (current > 0) {
|
||||
current--
|
||||
path.value = history[current]
|
||||
path.value = history[current] ?? '/'
|
||||
input.value = path.value.slice(1)
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,7 @@ const handleBack = () => {
|
||||
const handleForward = () => {
|
||||
if (current < history.length - 1) {
|
||||
current++
|
||||
path.value = history[current]
|
||||
path.value = history[current] ?? '/'
|
||||
input.value = path.value.slice(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,10 +34,12 @@ watch(
|
||||
(newVal) => {
|
||||
if (newVal && fileInfoList.value.length > 0) {
|
||||
const firstFile = fileInfoList.value[0]
|
||||
mode.value = normalizeMode(firstFile.mode)
|
||||
owner.value = firstFile.owner || 'www'
|
||||
group.value = firstFile.group || 'www'
|
||||
updateCheckboxes()
|
||||
if (firstFile) {
|
||||
mode.value = normalizeMode(firstFile.mode)
|
||||
owner.value = firstFile.owner || 'www'
|
||||
group.value = firstFile.group || 'www'
|
||||
updateCheckboxes()
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -73,7 +75,7 @@ const calculateMode = () => {
|
||||
|
||||
const updateCheckboxes = () => {
|
||||
const paddedMode = normalizeMode(mode.value)
|
||||
const permissions = paddedMode.split('').map(Number)
|
||||
const permissions = paddedMode.split('').map(Number) as [number, number, number]
|
||||
|
||||
checkbox.value.owner = permissions[0] & 4 ? ['read'] : []
|
||||
if (permissions[0] & 2) checkbox.value.owner.push('write')
|
||||
@@ -94,7 +96,7 @@ const title = computed(() => {
|
||||
}
|
||||
return selected.value.length > 1
|
||||
? $gettext('Batch modify permissions')
|
||||
: $gettext('Modify permissions - %{ path }', { path: selected.value[0] })
|
||||
: $gettext('Modify permissions - %{ path }', { path: selected.value[0] ?? '' })
|
||||
})
|
||||
|
||||
watch(mode, updateCheckboxes, { immediate: true })
|
||||
|
||||
@@ -105,7 +105,8 @@ const handlePaste = () => {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
if (data[i]) {
|
||||
flag = true
|
||||
paths[i].force = true
|
||||
const pathItem = paths[i]
|
||||
if (pathItem) pathItem.force = true
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
|
||||
@@ -540,13 +540,13 @@ if (import.meta.hot) {
|
||||
<n-table :single-line="false" striped>
|
||||
<tr>
|
||||
<th>{{ $gettext('Model') }}</th>
|
||||
<td>{{ realtime.cpus[0].modelName }}</td>
|
||||
<td>{{ realtime.cpus[0]?.modelName }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ $gettext('Parameters') }}</th>
|
||||
<td>
|
||||
{{ realtime.cpus.length }} CPU {{ cores }} {{ $gettext('cores') }}
|
||||
{{ formatBytes(realtime.cpus[0].cacheSize * 1024) }} {{ $gettext('cache') }}
|
||||
{{ formatBytes((realtime.cpus[0]?.cacheSize ?? 0) * 1024) }} {{ $gettext('cache') }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-for="item in realtime.cpus" :key="item.modelName">
|
||||
|
||||
@@ -83,6 +83,7 @@ const getOption = (route: RouteType): TreeSelectOption => {
|
||||
if (visibleChildren.length === 1) {
|
||||
// 单个子路由处理
|
||||
const singleRoute = visibleChildren[0]
|
||||
if (!singleRoute) return menuItem
|
||||
const isSingleDisabled = forbiddenHiddenMenus.includes(singleRoute.name as string)
|
||||
menuItem.label = singleRoute.meta?.title
|
||||
? translateTitle(singleRoute.meta.title)
|
||||
@@ -93,7 +94,8 @@ const getOption = (route: RouteType): TreeSelectOption => {
|
||||
? singleRoute.children.filter((item: RouteType) => item.name && !item.isHidden)
|
||||
: []
|
||||
|
||||
if (visibleItems.length === 1) menuItem = getOption(visibleItems[0])
|
||||
const firstVisibleItem = visibleItems[0]
|
||||
if (visibleItems.length === 1 && firstVisibleItem) menuItem = getOption(firstVisibleItem)
|
||||
else if (visibleItems.length > 1)
|
||||
menuItem.children = visibleItems.map((item) => getOption(item))
|
||||
} else {
|
||||
|
||||
@@ -180,13 +180,14 @@ const closeTab = (tabId: string) => {
|
||||
if (index === -1) return
|
||||
|
||||
const tab = tabs.value[index]
|
||||
disposeTab(tab)
|
||||
if (tab) disposeTab(tab)
|
||||
tabs.value.splice(index, 1)
|
||||
|
||||
// 如果关闭的是当前标签,切换到其他标签
|
||||
if (activeTabId.value === tabId && tabs.value.length > 0) {
|
||||
const newIndex = Math.min(index, tabs.value.length - 1)
|
||||
switchTab(tabs.value[newIndex].id)
|
||||
const newTab = tabs.value[newIndex]
|
||||
if (newTab) switchTab(newTab.id)
|
||||
}
|
||||
|
||||
// 如果没有标签了,创建一个本机标签
|
||||
|
||||
@@ -64,7 +64,7 @@ const handleTest = async () => {
|
||||
inTest.value = true
|
||||
progress.value = 0
|
||||
for (let i = 0; i < tests.length; i++) {
|
||||
const test = tests[i]
|
||||
const test = tests[i] ?? ''
|
||||
current.value = test
|
||||
if (test != 'memory' && test != 'disk') {
|
||||
cpu.value[test as keyof typeof cpu.value] = await benchmark.test(test)
|
||||
|
||||
@@ -6,6 +6,7 @@ defineOptions({
|
||||
import { useRequest } from 'alova/client'
|
||||
import type { DataTableColumns } from 'naive-ui'
|
||||
import { NButton, NProgress, NTag } from 'naive-ui'
|
||||
import { h } from 'vue'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
|
||||
import disk from '@/api/panel/toolbox-disk'
|
||||
|
||||
@@ -76,24 +76,28 @@ const scanResults = ref<Record<string, ScanResult>>({
|
||||
|
||||
// 扫描日志
|
||||
const handleScan = async (type: string) => {
|
||||
scanResults.value[type].loading = true
|
||||
scanResults.value[type].scanned = false
|
||||
scanResults.value[type].items = []
|
||||
const result = scanResults.value[type]
|
||||
if (!result) return
|
||||
result.loading = true
|
||||
result.scanned = false
|
||||
result.items = []
|
||||
|
||||
try {
|
||||
const { data } = await useRequest(toolboxLog.scan(type))
|
||||
scanResults.value[type].items = data || []
|
||||
scanResults.value[type].scanned = true
|
||||
result.items = data || []
|
||||
result.scanned = true
|
||||
} catch (e) {
|
||||
window.$message.error($gettext('Scan failed'))
|
||||
} finally {
|
||||
scanResults.value[type].loading = false
|
||||
result.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
// 清理日志
|
||||
const handleClean = async (type: string) => {
|
||||
scanResults.value[type].cleaning = true
|
||||
const result = scanResults.value[type]
|
||||
if (!result) return
|
||||
result.cleaning = true
|
||||
|
||||
try {
|
||||
const { data } = await useRequest(toolboxLog.clean(type))
|
||||
@@ -103,7 +107,7 @@ const handleClean = async (type: string) => {
|
||||
} catch (e) {
|
||||
window.$message.error($gettext('Clean failed'))
|
||||
} finally {
|
||||
scanResults.value[type].cleaning = false
|
||||
result.cleaning = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +121,8 @@ const handleScanAll = async () => {
|
||||
// 清理所有
|
||||
const handleCleanAll = async () => {
|
||||
for (const logType of logTypes) {
|
||||
if (scanResults.value[logType.key].items.length > 0) {
|
||||
const result = scanResults.value[logType.key]
|
||||
if (result && result.items.length > 0) {
|
||||
await handleClean(logType.key)
|
||||
}
|
||||
}
|
||||
@@ -132,6 +137,11 @@ const totalItems = computed(() => {
|
||||
const anyLoading = computed(() => {
|
||||
return Object.values(scanResults.value).some((r) => r.loading || r.cleaning)
|
||||
})
|
||||
|
||||
// 获取扫描结果
|
||||
const getResult = (key: string): ScanResult => {
|
||||
return scanResults.value[key] ?? { loading: false, items: [], scanned: false, cleaning: false }
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -163,7 +173,7 @@ const anyLoading = computed(() => {
|
||||
<n-flex :size="8">
|
||||
<n-button
|
||||
size="small"
|
||||
:loading="scanResults[logType.key].loading"
|
||||
:loading="getResult(logType.key).loading"
|
||||
@click="handleScan(logType.key)"
|
||||
>
|
||||
<template #icon>
|
||||
@@ -174,8 +184,8 @@ const anyLoading = computed(() => {
|
||||
<n-button
|
||||
size="small"
|
||||
type="warning"
|
||||
:loading="scanResults[logType.key].cleaning"
|
||||
:disabled="scanResults[logType.key].items.length === 0"
|
||||
:loading="getResult(logType.key).cleaning"
|
||||
:disabled="getResult(logType.key).items.length === 0"
|
||||
@click="handleClean(logType.key)"
|
||||
>
|
||||
<template #icon>
|
||||
@@ -189,15 +199,15 @@ const anyLoading = computed(() => {
|
||||
<n-flex vertical>
|
||||
<n-text depth="3">{{ logType.description }}</n-text>
|
||||
|
||||
<template v-if="scanResults[logType.key].loading">
|
||||
<template v-if="getResult(logType.key).loading">
|
||||
<n-flex justify="center" align="center" style="min-height: 60px">
|
||||
<n-spin size="small" />
|
||||
<n-text>{{ $gettext('Scanning...') }}</n-text>
|
||||
</n-flex>
|
||||
</template>
|
||||
|
||||
<template v-else-if="scanResults[logType.key].scanned">
|
||||
<template v-if="scanResults[logType.key].items.length === 0">
|
||||
<template v-else-if="getResult(logType.key).scanned">
|
||||
<template v-if="getResult(logType.key).items.length === 0">
|
||||
<n-empty :description="$gettext('No logs found')" size="small" />
|
||||
</template>
|
||||
<template v-else>
|
||||
@@ -206,7 +216,7 @@ const anyLoading = computed(() => {
|
||||
{ title: $gettext('Name'), key: 'name', ellipsis: { tooltip: true } },
|
||||
{ title: $gettext('Size'), key: 'size', width: 120 }
|
||||
]"
|
||||
:data="scanResults[logType.key].items"
|
||||
:data="getResult(logType.key).items"
|
||||
:bordered="false"
|
||||
size="small"
|
||||
:max-height="200"
|
||||
|
||||
@@ -5,7 +5,6 @@ import { useGettext } from 'vue3-gettext'
|
||||
import website from '@/api/panel/website'
|
||||
|
||||
const show = defineModel<boolean>('show', { type: Boolean, required: true })
|
||||
const type = defineModel<string>('type', { type: String, required: true })
|
||||
|
||||
const { $gettext } = useGettext()
|
||||
|
||||
@@ -24,16 +23,16 @@ const handleCreate = async () => {
|
||||
return
|
||||
}
|
||||
// 去除空格
|
||||
const name = parts[0].trim()
|
||||
const domains = parts[1]
|
||||
const name = (parts[0] ?? '').trim()
|
||||
const domains = (parts[1] ?? '')
|
||||
.trim()
|
||||
.split(',')
|
||||
.map((item) => item.trim())
|
||||
const listens = parts[2]
|
||||
const listens = (parts[2] ?? '')
|
||||
.trim()
|
||||
.split(',')
|
||||
.map((item) => item.trim())
|
||||
const path = parts[3].trim()
|
||||
const path = (parts[3] ?? '').trim()
|
||||
const remark = parts[4] ? parts[4].trim() : ''
|
||||
let model = {
|
||||
name: '',
|
||||
|
||||
Reference in New Issue
Block a user