优化后台金山状态:登录后静默预取并在系统配置页复用缓存
This commit is contained in:
@@ -17,6 +17,7 @@ import {
|
||||
import { api } from '../api/client'
|
||||
import { fetchFeedbackStats } from '../api/feedbacks'
|
||||
import { fetchSystemStats } from '../api/stats'
|
||||
import { clearCachedKdocsStatus, preloadKdocsStatus } from '../utils/kdocsStatusCache'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
@@ -102,6 +103,9 @@ onMounted(async () => {
|
||||
mediaQuery.addEventListener?.('change', syncIsMobile)
|
||||
syncIsMobile()
|
||||
|
||||
// 后台登录后预加载金山文档登录状态,系统配置页可直接复用缓存。
|
||||
void preloadKdocsStatus({ maxAgeMs: 60_000, silent: true }).catch(() => {})
|
||||
|
||||
await refreshStats()
|
||||
await refreshNavBadges()
|
||||
scheduleBadgePolling()
|
||||
@@ -160,6 +164,7 @@ async function logout() {
|
||||
try {
|
||||
await api.post('/logout')
|
||||
} finally {
|
||||
clearCachedKdocsStatus()
|
||||
window.location.href = '/yuyx'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { fetchSystemConfig, updateSystemConfig } from '../api/system'
|
||||
import { fetchKdocsQr, fetchKdocsStatus, clearKdocsLogin } from '../api/kdocs'
|
||||
import { fetchProxyConfig, testProxy, updateProxyConfig } from '../api/proxy'
|
||||
import { getCachedKdocsStatus, preloadKdocsStatus, updateCachedKdocsStatus } from '../utils/kdocsStatusCache'
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
@@ -33,14 +34,15 @@ const kdocsRowEnd = ref(0)
|
||||
const kdocsAdminNotifyEnabled = ref(false)
|
||||
const kdocsAdminNotifyEmail = ref('')
|
||||
|
||||
const kdocsStatus = ref({})
|
||||
const initialKdocsStatus = getCachedKdocsStatus({ maxAgeMs: 10 * 60 * 1000 })
|
||||
const kdocsStatus = ref(initialKdocsStatus || {})
|
||||
const kdocsQrOpen = ref(false)
|
||||
const kdocsQrImage = ref('')
|
||||
const kdocsPolling = ref(false)
|
||||
const kdocsStatusLoading = ref(false)
|
||||
const kdocsQrLoading = ref(false)
|
||||
const kdocsClearLoading = ref(false)
|
||||
const kdocsSilentRefreshing = ref(false)
|
||||
const kdocsSilentRefreshing = ref(!initialKdocsStatus)
|
||||
const kdocsActionHint = ref('')
|
||||
let kdocsPollingTimer = null
|
||||
|
||||
@@ -116,7 +118,13 @@ async function loadAll() {
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
// 金山登录状态改为静默异步获取,避免阻塞系统配置首屏渲染
|
||||
const cachedStatus = getCachedKdocsStatus({ maxAgeMs: 10 * 60 * 1000 })
|
||||
if (cachedStatus) {
|
||||
kdocsStatus.value = cachedStatus
|
||||
kdocsSilentRefreshing.value = false
|
||||
}
|
||||
|
||||
// 静默刷新金山登录状态,确保状态持续更新且不阻塞首屏。
|
||||
void refreshKdocsStatusSilently()
|
||||
}
|
||||
|
||||
@@ -124,14 +132,12 @@ async function refreshKdocsStatusSilently() {
|
||||
if (kdocsSilentRefreshing.value || kdocsStatusLoading.value) return
|
||||
kdocsSilentRefreshing.value = true
|
||||
try {
|
||||
const status = await fetchKdocsStatus(
|
||||
{},
|
||||
{
|
||||
__silent: true,
|
||||
__no_retry: true,
|
||||
timeout: 8000,
|
||||
},
|
||||
)
|
||||
const status = await preloadKdocsStatus({
|
||||
force: false,
|
||||
maxAgeMs: 60_000,
|
||||
silent: true,
|
||||
live: 0,
|
||||
})
|
||||
kdocsStatus.value = status || {}
|
||||
} catch {
|
||||
// silent mode
|
||||
@@ -255,7 +261,9 @@ async function refreshKdocsStatus() {
|
||||
kdocsStatusLoading.value = true
|
||||
setKdocsHint('正在刷新状态')
|
||||
try {
|
||||
kdocsStatus.value = await fetchKdocsStatus({ live: 1 })
|
||||
const status = await fetchKdocsStatus({ live: 1 })
|
||||
kdocsStatus.value = status || {}
|
||||
updateCachedKdocsStatus(kdocsStatus.value)
|
||||
setKdocsHint('状态已刷新')
|
||||
} catch {
|
||||
setKdocsHint('刷新失败,请稍后重试')
|
||||
@@ -267,7 +275,8 @@ async function refreshKdocsStatus() {
|
||||
async function pollKdocsStatus() {
|
||||
try {
|
||||
const status = await fetchKdocsStatus({ live: 1 })
|
||||
kdocsStatus.value = status
|
||||
kdocsStatus.value = status || {}
|
||||
updateCachedKdocsStatus(kdocsStatus.value)
|
||||
const loggedIn = status?.logged_in === true || status?.last_login_ok === true
|
||||
if (loggedIn) {
|
||||
ElMessage.success('扫码成功,已登录')
|
||||
@@ -332,6 +341,12 @@ async function onClearKdocsLogin() {
|
||||
await clearKdocsLogin()
|
||||
kdocsQrOpen.value = false
|
||||
kdocsQrImage.value = ''
|
||||
kdocsStatus.value = updateCachedKdocsStatus({
|
||||
...(kdocsStatus.value || {}),
|
||||
logged_in: false,
|
||||
last_login_ok: false,
|
||||
login_required: true,
|
||||
})
|
||||
ElMessage.success('登录态已清除')
|
||||
setKdocsHint('登录态已清除')
|
||||
await refreshKdocsStatus()
|
||||
|
||||
121
admin-frontend/src/utils/kdocsStatusCache.js
Normal file
121
admin-frontend/src/utils/kdocsStatusCache.js
Normal file
@@ -0,0 +1,121 @@
|
||||
import { fetchKdocsStatus } from '../api/kdocs'
|
||||
|
||||
const CACHE_KEY = 'admin:kdocs:status:v1'
|
||||
const DEFAULT_MAX_AGE_MS = 5 * 60 * 1000
|
||||
|
||||
let memoryStatus = null
|
||||
let memoryUpdatedAt = 0
|
||||
let inflightPromise = null
|
||||
|
||||
function nowTs() {
|
||||
return Date.now()
|
||||
}
|
||||
|
||||
function normalizeStatus(raw) {
|
||||
if (!raw || typeof raw !== 'object') return {}
|
||||
return raw
|
||||
}
|
||||
|
||||
function readSessionCache() {
|
||||
try {
|
||||
const raw = window.sessionStorage.getItem(CACHE_KEY)
|
||||
if (!raw) return null
|
||||
const parsed = JSON.parse(raw)
|
||||
if (!parsed || typeof parsed !== 'object') return null
|
||||
const updatedAt = Number(parsed.updated_at || 0)
|
||||
const status = normalizeStatus(parsed.status)
|
||||
if (!updatedAt) return null
|
||||
return { status, updatedAt }
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
function writeSessionCache(status, updatedAt) {
|
||||
try {
|
||||
window.sessionStorage.setItem(
|
||||
CACHE_KEY,
|
||||
JSON.stringify({
|
||||
status: normalizeStatus(status),
|
||||
updated_at: Number(updatedAt || nowTs()),
|
||||
}),
|
||||
)
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
function hydrateFromSessionIfNeeded() {
|
||||
if (memoryStatus !== null) return
|
||||
const cached = readSessionCache()
|
||||
if (!cached) return
|
||||
memoryStatus = cached.status
|
||||
memoryUpdatedAt = cached.updatedAt
|
||||
}
|
||||
|
||||
function commitStatus(status) {
|
||||
memoryStatus = normalizeStatus(status)
|
||||
memoryUpdatedAt = nowTs()
|
||||
writeSessionCache(memoryStatus, memoryUpdatedAt)
|
||||
return memoryStatus
|
||||
}
|
||||
|
||||
function isFresh(maxAgeMs) {
|
||||
if (memoryStatus === null || !memoryUpdatedAt) return false
|
||||
const ageLimit = Number(maxAgeMs)
|
||||
if (!Number.isFinite(ageLimit) || ageLimit < 0) return true
|
||||
return nowTs() - memoryUpdatedAt <= ageLimit
|
||||
}
|
||||
|
||||
export function getCachedKdocsStatus(options = {}) {
|
||||
hydrateFromSessionIfNeeded()
|
||||
const maxAgeMs = options.maxAgeMs ?? DEFAULT_MAX_AGE_MS
|
||||
if (!isFresh(maxAgeMs)) return null
|
||||
return normalizeStatus(memoryStatus)
|
||||
}
|
||||
|
||||
export function updateCachedKdocsStatus(status) {
|
||||
return commitStatus(status)
|
||||
}
|
||||
|
||||
export function clearCachedKdocsStatus() {
|
||||
memoryStatus = null
|
||||
memoryUpdatedAt = 0
|
||||
inflightPromise = null
|
||||
try {
|
||||
window.sessionStorage.removeItem(CACHE_KEY)
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
export async function preloadKdocsStatus(options = {}) {
|
||||
const {
|
||||
force = false,
|
||||
maxAgeMs = DEFAULT_MAX_AGE_MS,
|
||||
silent = true,
|
||||
live = 0,
|
||||
} = options
|
||||
|
||||
if (!force) {
|
||||
const cached = getCachedKdocsStatus({ maxAgeMs })
|
||||
if (cached) return cached
|
||||
}
|
||||
|
||||
if (inflightPromise) return inflightPromise
|
||||
|
||||
const params = live ? { live: 1 } : {}
|
||||
const requestConfig = {
|
||||
__silent: Boolean(silent),
|
||||
__no_retry: true,
|
||||
timeout: 8000,
|
||||
}
|
||||
|
||||
inflightPromise = fetchKdocsStatus(params, requestConfig)
|
||||
.then((status) => commitStatus(status || {}))
|
||||
.finally(() => {
|
||||
inflightPromise = null
|
||||
})
|
||||
|
||||
return inflightPromise
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"_MetricGrid-BW8H4wTM.js": {
|
||||
"file": "assets/MetricGrid-BW8H4wTM.js",
|
||||
"_MetricGrid-BnihYB_8.js": {
|
||||
"file": "assets/MetricGrid-BnihYB_8.js",
|
||||
"name": "MetricGrid",
|
||||
"imports": [
|
||||
"index.html",
|
||||
@@ -14,29 +14,29 @@
|
||||
"file": "assets/MetricGrid-yP_dkP6X.css",
|
||||
"src": "_MetricGrid-yP_dkP6X.css"
|
||||
},
|
||||
"_email-CZFN9gLR.js": {
|
||||
"file": "assets/email-CZFN9gLR.js",
|
||||
"_email-px7YBG2O.js": {
|
||||
"file": "assets/email-px7YBG2O.js",
|
||||
"name": "email",
|
||||
"imports": [
|
||||
"index.html"
|
||||
]
|
||||
},
|
||||
"_system-CiDlQnoe.js": {
|
||||
"file": "assets/system-CiDlQnoe.js",
|
||||
"_system-ZDPnxnIu.js": {
|
||||
"file": "assets/system-ZDPnxnIu.js",
|
||||
"name": "system",
|
||||
"imports": [
|
||||
"index.html"
|
||||
]
|
||||
},
|
||||
"_tasks-DqqATNe_.js": {
|
||||
"file": "assets/tasks-DqqATNe_.js",
|
||||
"_tasks-Bep0SUyu.js": {
|
||||
"file": "assets/tasks-Bep0SUyu.js",
|
||||
"name": "tasks",
|
||||
"imports": [
|
||||
"index.html"
|
||||
]
|
||||
},
|
||||
"_users-BowyvQzr.js": {
|
||||
"file": "assets/users-BowyvQzr.js",
|
||||
"_users-te9ySk34.js": {
|
||||
"file": "assets/users-te9ySk34.js",
|
||||
"name": "users",
|
||||
"imports": [
|
||||
"index.html"
|
||||
@@ -73,7 +73,7 @@
|
||||
"name": "vendor-vue"
|
||||
},
|
||||
"index.html": {
|
||||
"file": "assets/index-BNslg8wp.js",
|
||||
"file": "assets/index-C1f9ticl.js",
|
||||
"name": "index",
|
||||
"src": "index.html",
|
||||
"isEntry": true,
|
||||
@@ -95,11 +95,11 @@
|
||||
"src/pages/SettingsPage.vue"
|
||||
],
|
||||
"css": [
|
||||
"assets/index-CVq5QfHO.css"
|
||||
"assets/index-Dh0BbqTX.css"
|
||||
]
|
||||
},
|
||||
"src/pages/AnnouncementsPage.vue": {
|
||||
"file": "assets/AnnouncementsPage-C0u6p8a8.js",
|
||||
"file": "assets/AnnouncementsPage-C6UgwLIT.js",
|
||||
"name": "AnnouncementsPage",
|
||||
"src": "src/pages/AnnouncementsPage.vue",
|
||||
"isDynamicEntry": true,
|
||||
@@ -115,14 +115,14 @@
|
||||
]
|
||||
},
|
||||
"src/pages/EmailPage.vue": {
|
||||
"file": "assets/EmailPage-DbZ8F1_b.js",
|
||||
"file": "assets/EmailPage-CATruPK6.js",
|
||||
"name": "EmailPage",
|
||||
"src": "src/pages/EmailPage.vue",
|
||||
"isDynamicEntry": true,
|
||||
"imports": [
|
||||
"_email-CZFN9gLR.js",
|
||||
"_email-px7YBG2O.js",
|
||||
"index.html",
|
||||
"_MetricGrid-BW8H4wTM.js",
|
||||
"_MetricGrid-BnihYB_8.js",
|
||||
"_vendor-element-B5S5pUKo.js",
|
||||
"_vendor-vue-CVxSw_oJ.js",
|
||||
"_vendor-axios-B9ygI19o.js",
|
||||
@@ -133,13 +133,13 @@
|
||||
]
|
||||
},
|
||||
"src/pages/FeedbacksPage.vue": {
|
||||
"file": "assets/FeedbacksPage-Dwzul2Z8.js",
|
||||
"file": "assets/FeedbacksPage-BAnFKHSL.js",
|
||||
"name": "FeedbacksPage",
|
||||
"src": "src/pages/FeedbacksPage.vue",
|
||||
"isDynamicEntry": true,
|
||||
"imports": [
|
||||
"index.html",
|
||||
"_MetricGrid-BW8H4wTM.js",
|
||||
"_MetricGrid-BnihYB_8.js",
|
||||
"_vendor-element-B5S5pUKo.js",
|
||||
"_vendor-vue-CVxSw_oJ.js",
|
||||
"_vendor-axios-B9ygI19o.js",
|
||||
@@ -150,13 +150,13 @@
|
||||
]
|
||||
},
|
||||
"src/pages/LogsPage.vue": {
|
||||
"file": "assets/LogsPage-Bs3Ge-t3.js",
|
||||
"file": "assets/LogsPage-DFPeq0bL.js",
|
||||
"name": "LogsPage",
|
||||
"src": "src/pages/LogsPage.vue",
|
||||
"isDynamicEntry": true,
|
||||
"imports": [
|
||||
"_users-BowyvQzr.js",
|
||||
"_tasks-DqqATNe_.js",
|
||||
"_users-te9ySk34.js",
|
||||
"_tasks-Bep0SUyu.js",
|
||||
"index.html",
|
||||
"_vendor-element-B5S5pUKo.js",
|
||||
"_vendor-vue-CVxSw_oJ.js",
|
||||
@@ -168,17 +168,17 @@
|
||||
]
|
||||
},
|
||||
"src/pages/ReportPage.vue": {
|
||||
"file": "assets/ReportPage-CqUGYZcC.js",
|
||||
"file": "assets/ReportPage-fzVH-d9u.js",
|
||||
"name": "ReportPage",
|
||||
"src": "src/pages/ReportPage.vue",
|
||||
"isDynamicEntry": true,
|
||||
"imports": [
|
||||
"_vendor-element-B5S5pUKo.js",
|
||||
"index.html",
|
||||
"_email-CZFN9gLR.js",
|
||||
"_tasks-DqqATNe_.js",
|
||||
"_system-CiDlQnoe.js",
|
||||
"_MetricGrid-BW8H4wTM.js",
|
||||
"_email-px7YBG2O.js",
|
||||
"_tasks-Bep0SUyu.js",
|
||||
"_system-ZDPnxnIu.js",
|
||||
"_MetricGrid-BnihYB_8.js",
|
||||
"_vendor-vue-CVxSw_oJ.js",
|
||||
"_vendor-misc-BeoNyvBp.js",
|
||||
"_vendor-axios-B9ygI19o.js"
|
||||
@@ -188,13 +188,13 @@
|
||||
]
|
||||
},
|
||||
"src/pages/SecurityPage.vue": {
|
||||
"file": "assets/SecurityPage-BARcvvk8.js",
|
||||
"file": "assets/SecurityPage-xwMQfhuh.js",
|
||||
"name": "SecurityPage",
|
||||
"src": "src/pages/SecurityPage.vue",
|
||||
"isDynamicEntry": true,
|
||||
"imports": [
|
||||
"index.html",
|
||||
"_MetricGrid-BW8H4wTM.js",
|
||||
"_MetricGrid-BnihYB_8.js",
|
||||
"_vendor-element-B5S5pUKo.js",
|
||||
"_vendor-vue-CVxSw_oJ.js",
|
||||
"_vendor-axios-B9ygI19o.js",
|
||||
@@ -205,7 +205,7 @@
|
||||
]
|
||||
},
|
||||
"src/pages/SettingsPage.vue": {
|
||||
"file": "assets/SettingsPage-Bblx2O3L.js",
|
||||
"file": "assets/SettingsPage-DRqlQLxJ.js",
|
||||
"name": "SettingsPage",
|
||||
"src": "src/pages/SettingsPage.vue",
|
||||
"isDynamicEntry": true,
|
||||
@@ -221,12 +221,12 @@
|
||||
]
|
||||
},
|
||||
"src/pages/SystemPage.vue": {
|
||||
"file": "assets/SystemPage-BVr94jQh.js",
|
||||
"file": "assets/SystemPage-D3eBPCNe.js",
|
||||
"name": "SystemPage",
|
||||
"src": "src/pages/SystemPage.vue",
|
||||
"isDynamicEntry": true,
|
||||
"imports": [
|
||||
"_system-CiDlQnoe.js",
|
||||
"_system-ZDPnxnIu.js",
|
||||
"index.html",
|
||||
"_vendor-element-B5S5pUKo.js",
|
||||
"_vendor-vue-CVxSw_oJ.js",
|
||||
@@ -234,16 +234,16 @@
|
||||
"_vendor-misc-BeoNyvBp.js"
|
||||
],
|
||||
"css": [
|
||||
"assets/SystemPage-CfMGkvmW.css"
|
||||
"assets/SystemPage-BhhEz4Qz.css"
|
||||
]
|
||||
},
|
||||
"src/pages/UsersPage.vue": {
|
||||
"file": "assets/UsersPage-CwfHMchI.js",
|
||||
"file": "assets/UsersPage-DJZUCpfb.js",
|
||||
"name": "UsersPage",
|
||||
"src": "src/pages/UsersPage.vue",
|
||||
"isDynamicEntry": true,
|
||||
"imports": [
|
||||
"_users-BowyvQzr.js",
|
||||
"_users-te9ySk34.js",
|
||||
"index.html",
|
||||
"_vendor-element-B5S5pUKo.js",
|
||||
"_vendor-vue-CVxSw_oJ.js",
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{_}from"./index-BNslg8wp.js";import{aj as c,n as s,q as t,K as r,a3 as u,y as p,t as o,G as l,L as y,E as h,D as i,H as v,J as n,I as k,x as f}from"./vendor-vue-CVxSw_oJ.js";const b={class:"metric-top"},x={key:0,class:"metric-icon"},g={class:"metric-label"},B={class:"metric-value"},C={key:0,class:"metric-hint app-muted"},N={__name:"MetricGrid",props:{items:{type:Array,default:()=>[]},loading:{type:Boolean,default:!1},minWidth:{type:Number,default:180}},setup(a){return(V,D)=>{const d=c("el-icon"),m=c("el-skeleton");return t(),s("div",{class:"metric-grid",style:f({"--metric-min":`${a.minWidth}px`})},[(t(!0),s(r,null,u(a.items,e=>(t(),s("div",{key:e?.key||e?.label,class:p(["metric-card",`metric-tone--${e?.tone||"blue"}`])},[o("div",b,[e?.icon?(t(),s("div",x,[y(d,null,{default:h(()=>[(t(),i(v(e.icon)))]),_:2},1024)])):l("",!0),o("div",g,n(e?.label||"-"),1)]),o("div",B,[a.loading?(t(),i(m,{key:0,rows:1,animated:""})):(t(),s(r,{key:1},[k(n(e?.value??0),1)],64))]),e?.hint||e?.sub?(t(),s("div",C,n(e?.hint||e?.sub),1)):l("",!0)],2))),128))],4)}}},w=_(N,[["__scopeId","data-v-00e217d4"]]);export{w as M};
|
||||
import{_}from"./index-C1f9ticl.js";import{aj as c,n as s,q as t,K as r,a3 as u,y as p,t as o,G as l,L as y,E as h,D as i,H as v,J as n,I as k,x as f}from"./vendor-vue-CVxSw_oJ.js";const b={class:"metric-top"},x={key:0,class:"metric-icon"},g={class:"metric-label"},B={class:"metric-value"},C={key:0,class:"metric-hint app-muted"},N={__name:"MetricGrid",props:{items:{type:Array,default:()=>[]},loading:{type:Boolean,default:!1},minWidth:{type:Number,default:180}},setup(a){return(V,D)=>{const d=c("el-icon"),m=c("el-skeleton");return t(),s("div",{class:"metric-grid",style:f({"--metric-min":`${a.minWidth}px`})},[(t(!0),s(r,null,u(a.items,e=>(t(),s("div",{key:e?.key||e?.label,class:p(["metric-card",`metric-tone--${e?.tone||"blue"}`])},[o("div",b,[e?.icon?(t(),s("div",x,[y(d,null,{default:h(()=>[(t(),i(v(e.icon)))]),_:2},1024)])):l("",!0),o("div",g,n(e?.label||"-"),1)]),o("div",B,[a.loading?(t(),i(m,{key:0,rows:1,animated:""})):(t(),s(r,{key:1},[k(n(e?.value??0),1)],64))]),e?.hint||e?.sub?(t(),s("div",C,n(e?.hint||e?.sub),1)):l("",!0)],2))),128))],4)}}},w=_(N,[["__scopeId","data-v-00e217d4"]]);export{w as M};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
static/admin/assets/SystemPage-BhhEz4Qz.css
Normal file
1
static/admin/assets/SystemPage-BhhEz4Qz.css
Normal file
@@ -0,0 +1 @@
|
||||
.page-stack[data-v-ca313705]{display:flex;flex-direction:column;gap:14px;min-width:0}.config-grid[data-v-ca313705]{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}.card[data-v-ca313705]{border-radius:var(--app-radius);border:1px solid var(--app-border);background:var(--app-card-bg);box-shadow:var(--app-shadow-soft)}.section-card[data-v-ca313705]{min-width:0}.section-title[data-v-ca313705]{margin:0;font-size:15px;font-weight:800;letter-spacing:.2px}.section-sub[data-v-ca313705]{margin-top:6px;margin-bottom:10px;font-size:12px}.section-head[data-v-ca313705]{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:10px}.status-inline[data-v-ca313705]{font-size:12px;display:inline-flex;align-items:center;gap:6px}.status-chip[data-v-ca313705]{display:inline-flex;align-items:center;min-height:22px;padding:0 8px;border-radius:999px;font-size:12px;font-weight:700;border:1px solid transparent}.status-chip.is-checking[data-v-ca313705]{color:#1d4ed8;background:#dbeafe;border-color:#93c5fd}.status-chip.is-online[data-v-ca313705]{color:#065f46;background:#d1fae5;border-color:#6ee7b7}.status-chip.is-offline[data-v-ca313705]{color:#92400e;background:#fef3c7;border-color:#fcd34d}.status-chip.is-error[data-v-ca313705]{color:#991b1b;background:#fee2e2;border-color:#fca5a5}.status-chip.is-unknown[data-v-ca313705]{color:#374151;background:#f3f4f6;border-color:#d1d5db}.status-dots[data-v-ca313705]{display:inline-flex;align-items:center;gap:3px;margin-left:3px}.status-dots i[data-v-ca313705]{width:4px;height:4px;border-radius:50%;background:currentColor;opacity:.25;animation:dotPulse-ca313705 1.2s infinite ease-in-out}.status-dots i[data-v-ca313705]:nth-child(2){animation-delay:.2s}.status-dots i[data-v-ca313705]:nth-child(3){animation-delay:.4s}@keyframes dotPulse-ca313705{0%,80%,to{opacity:.25;transform:translateY(0)}40%{opacity:1;transform:translateY(-1px)}}.kdocs-form[data-v-ca313705]{margin-top:6px}.kdocs-inline[data-v-ca313705]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;width:100%}.kdocs-range[data-v-ca313705]{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.kdocs-qr[data-v-ca313705]{display:flex;flex-direction:column;align-items:center;gap:12px}.kdocs-qr img[data-v-ca313705]{width:260px;max-width:100%;border:1px solid var(--app-border);border-radius:8px;padding:8px;background:#fff}.help[data-v-ca313705]{margin-top:6px;font-size:12px;color:var(--app-muted)}.row-actions[data-v-ca313705]{display:flex;flex-wrap:wrap;gap:10px}@media(max-width:1200px){.config-grid[data-v-ca313705]{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(max-width:768px){.config-grid[data-v-ca313705],.kdocs-inline[data-v-ca313705]{grid-template-columns:1fr}.kdocs-range[data-v-ca313705]{align-items:stretch}}
|
||||
@@ -1 +0,0 @@
|
||||
.page-stack[data-v-cef111cd]{display:flex;flex-direction:column;gap:14px;min-width:0}.config-grid[data-v-cef111cd]{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}.card[data-v-cef111cd]{border-radius:var(--app-radius);border:1px solid var(--app-border);background:var(--app-card-bg);box-shadow:var(--app-shadow-soft)}.section-card[data-v-cef111cd]{min-width:0}.section-title[data-v-cef111cd]{margin:0;font-size:15px;font-weight:800;letter-spacing:.2px}.section-sub[data-v-cef111cd]{margin-top:6px;margin-bottom:10px;font-size:12px}.section-head[data-v-cef111cd]{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:10px}.status-inline[data-v-cef111cd]{font-size:12px;display:inline-flex;align-items:center;gap:6px}.status-chip[data-v-cef111cd]{display:inline-flex;align-items:center;min-height:22px;padding:0 8px;border-radius:999px;font-size:12px;font-weight:700;border:1px solid transparent}.status-chip.is-checking[data-v-cef111cd]{color:#1d4ed8;background:#dbeafe;border-color:#93c5fd}.status-chip.is-online[data-v-cef111cd]{color:#065f46;background:#d1fae5;border-color:#6ee7b7}.status-chip.is-offline[data-v-cef111cd]{color:#92400e;background:#fef3c7;border-color:#fcd34d}.status-chip.is-error[data-v-cef111cd]{color:#991b1b;background:#fee2e2;border-color:#fca5a5}.status-chip.is-unknown[data-v-cef111cd]{color:#374151;background:#f3f4f6;border-color:#d1d5db}.status-dots[data-v-cef111cd]{display:inline-flex;align-items:center;gap:3px;margin-left:3px}.status-dots i[data-v-cef111cd]{width:4px;height:4px;border-radius:50%;background:currentColor;opacity:.25;animation:dotPulse-cef111cd 1.2s infinite ease-in-out}.status-dots i[data-v-cef111cd]:nth-child(2){animation-delay:.2s}.status-dots i[data-v-cef111cd]:nth-child(3){animation-delay:.4s}@keyframes dotPulse-cef111cd{0%,80%,to{opacity:.25;transform:translateY(0)}40%{opacity:1;transform:translateY(-1px)}}.kdocs-form[data-v-cef111cd]{margin-top:6px}.kdocs-inline[data-v-cef111cd]{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;width:100%}.kdocs-range[data-v-cef111cd]{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.kdocs-qr[data-v-cef111cd]{display:flex;flex-direction:column;align-items:center;gap:12px}.kdocs-qr img[data-v-cef111cd]{width:260px;max-width:100%;border:1px solid var(--app-border);border-radius:8px;padding:8px;background:#fff}.help[data-v-cef111cd]{margin-top:6px;font-size:12px;color:var(--app-muted)}.row-actions[data-v-cef111cd]{display:flex;flex-wrap:wrap;gap:10px}@media(max-width:1200px){.config-grid[data-v-cef111cd]{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(max-width:768px){.config-grid[data-v-cef111cd],.kdocs-inline[data-v-cef111cd]{grid-template-columns:1fr}.kdocs-range[data-v-cef111cd]{align-items:stretch}}
|
||||
6
static/admin/assets/SystemPage-D3eBPCNe.js
Normal file
6
static/admin/assets/SystemPage-D3eBPCNe.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{c as s,a as e}from"./index-BNslg8wp.js";const n=s(async()=>{const{data:a}=await e.get("/email/stats");return a},1e4);async function i(){const{data:a}=await e.get("/email/settings");return a}async function r(a){const{data:t}=await e.post("/email/settings",a);return n.clear(),t}async function o(a={}){return n.run(a)}async function l(a){const{data:t}=await e.get("/email/logs",{params:a});return t}async function u(a){const{data:t}=await e.post("/email/logs/cleanup",{days:a});return n.clear(),t}export{l as a,i as b,u as c,o as f,r as u};
|
||||
import{c as s,a as e}from"./index-C1f9ticl.js";const n=s(async()=>{const{data:a}=await e.get("/email/stats");return a},1e4);async function i(){const{data:a}=await e.get("/email/settings");return a}async function r(a){const{data:t}=await e.post("/email/settings",a);return n.clear(),t}async function o(a={}){return n.run(a)}async function l(a){const{data:t}=await e.get("/email/logs",{params:a});return t}async function u(a){const{data:t}=await e.post("/email/logs/cleanup",{days:a});return n.clear(),t}export{l as a,i as b,u as c,o as f,r as u};
|
||||
File diff suppressed because one or more lines are too long
2
static/admin/assets/index-C1f9ticl.js
Normal file
2
static/admin/assets/index-C1f9ticl.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{c as s,a}from"./index-BNslg8wp.js";const e=s(async()=>{const{data:t}=await a.get("/system/config");return t},15e3);async function o(t={}){return e.run(t)}async function r(t){const{data:n}=await a.post("/system/config",t);return e.clear(),n}export{o as f,r as u};
|
||||
import{c as s,a}from"./index-C1f9ticl.js";const e=s(async()=>{const{data:t}=await a.get("/system/config");return t},15e3);async function o(t={}){return e.run(t)}async function r(t){const{data:n}=await a.post("/system/config",t);return e.clear(),n}export{o as f,r as u};
|
||||
@@ -1 +1 @@
|
||||
import{c as s,a}from"./index-BNslg8wp.js";const c=s(async()=>{const{data:t}=await a.get("/server/info");return t},3e4),o=s(async()=>{const{data:t}=await a.get("/docker_stats");return t},8e3),u=s(async()=>{const{data:t}=await a.get("/request_metrics");return t},1e4),i=s(async()=>{const{data:t}=await a.get("/slow_sql_metrics");return t},1e4),e=s(async()=>{const{data:t}=await a.get("/task/stats");return t},4e3),r=s(async()=>{const{data:t}=await a.get("/task/running");return t},2e3);async function g(t={}){return c.run(t)}async function y(t={}){return o.run(t)}async function d(t={}){return u.run(t)}async function k(t={}){return i.run(t)}async function l(t={}){return e.run(t)}async function w(t={}){return r.run(t)}async function _(t){const{data:n}=await a.get("/task/logs",{params:t});return n}async function h(t){const{data:n}=await a.post("/task/logs/clear",{days:t});return e.clear(),r.clear(),n}export{w as a,g as b,y as c,d,k as e,l as f,_ as g,h};
|
||||
import{c as s,a}from"./index-C1f9ticl.js";const c=s(async()=>{const{data:t}=await a.get("/server/info");return t},3e4),o=s(async()=>{const{data:t}=await a.get("/docker_stats");return t},8e3),u=s(async()=>{const{data:t}=await a.get("/request_metrics");return t},1e4),i=s(async()=>{const{data:t}=await a.get("/slow_sql_metrics");return t},1e4),e=s(async()=>{const{data:t}=await a.get("/task/stats");return t},4e3),r=s(async()=>{const{data:t}=await a.get("/task/running");return t},2e3);async function g(t={}){return c.run(t)}async function y(t={}){return o.run(t)}async function d(t={}){return u.run(t)}async function k(t={}){return i.run(t)}async function l(t={}){return e.run(t)}async function w(t={}){return r.run(t)}async function _(t){const{data:n}=await a.get("/task/logs",{params:t});return n}async function h(t){const{data:n}=await a.post("/task/logs/clear",{days:t});return e.clear(),r.clear(),n}export{w as a,g as b,y as c,d,k as e,l as f,_ as g,h};
|
||||
@@ -1 +1 @@
|
||||
import{a as t}from"./index-BNslg8wp.js";async function n(){const{data:s}=await t.get("/users");return s}async function o(s){const{data:a}=await t.post(`/users/${s}/approve`);return a}async function c(s){const{data:a}=await t.post(`/users/${s}/reject`);return a}async function i(s){const{data:a}=await t.delete(`/users/${s}`);return a}async function u(s,a){const{data:e}=await t.post(`/users/${s}/vip`,{days:a});return e}async function p(s){const{data:a}=await t.delete(`/users/${s}/vip`);return a}async function d(s,a){const{data:e}=await t.post(`/users/${s}/reset_password`,{new_password:a});return e}export{o as a,p as b,d as c,i as d,n as f,c as r,u as s};
|
||||
import{a as t}from"./index-C1f9ticl.js";async function n(){const{data:s}=await t.get("/users");return s}async function o(s){const{data:a}=await t.post(`/users/${s}/approve`);return a}async function c(s){const{data:a}=await t.post(`/users/${s}/reject`);return a}async function i(s){const{data:a}=await t.delete(`/users/${s}`);return a}async function u(s,a){const{data:e}=await t.post(`/users/${s}/vip`,{days:a});return e}async function p(s){const{data:a}=await t.delete(`/users/${s}/vip`);return a}async function d(s,a){const{data:e}=await t.post(`/users/${s}/reset_password`,{new_password:a});return e}export{o as a,p as b,d as c,i as d,n as f,c as r,u as s};
|
||||
@@ -5,13 +5,13 @@
|
||||
<link rel="icon" type="image/svg+xml" href="./vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>后台管理 - 知识管理平台</title>
|
||||
<script type="module" crossorigin src="./assets/index-BNslg8wp.js"></script>
|
||||
<script type="module" crossorigin src="./assets/index-C1f9ticl.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="./assets/vendor-vue-CVxSw_oJ.js">
|
||||
<link rel="modulepreload" crossorigin href="./assets/vendor-misc-BeoNyvBp.js">
|
||||
<link rel="modulepreload" crossorigin href="./assets/vendor-element-B5S5pUKo.js">
|
||||
<link rel="modulepreload" crossorigin href="./assets/vendor-axios-B9ygI19o.js">
|
||||
<link rel="stylesheet" crossorigin href="./assets/vendor-element-C68yOrAy.css">
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-CVq5QfHO.css">
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-Dh0BbqTX.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
Reference in New Issue
Block a user