Avoid live KDocs status on page load

This commit is contained in:
2026-01-07 14:12:54 +08:00
parent 8c150dcb7c
commit ad847888f8
22 changed files with 77 additions and 73 deletions

View File

@@ -1,7 +1,7 @@
import { api } from './client'
export async function fetchKdocsStatus() {
const { data } = await api.get('/kdocs/status')
export async function fetchKdocsStatus(params = {}) {
const { data } = await api.get('/kdocs/status', { params })
return data
}

View File

@@ -251,7 +251,7 @@ async function saveKdocsConfig() {
async function refreshKdocsStatus() {
try {
kdocsStatus.value = await fetchKdocsStatus()
kdocsStatus.value = await fetchKdocsStatus({ live: 1 })
} catch {
// handled by interceptor
}
@@ -259,7 +259,7 @@ async function refreshKdocsStatus() {
async function pollKdocsStatus() {
try {
const status = await fetchKdocsStatus()
const status = await fetchKdocsStatus({ live: 1 })
kdocsStatus.value = status
const loggedIn = status?.logged_in === true || status?.last_login_ok === true
if (loggedIn) {
@@ -545,7 +545,7 @@ onMounted(loadAll)
<span v-if="kdocsStatus.last_login_ok === true">已登录</span>
<span v-else-if="kdocsStatus.login_required">需要扫码</span>
<span v-else>未知</span>
· 队列 {{ kdocsStatus.queue_size || 0 }}
· 待上传 {{ kdocsStatus.queue_size || 0 }}
<span v-if="kdocsStatus.last_error">· 最近错误{{ kdocsStatus.last_error }}</span>
</div>
</el-card>

View File

@@ -850,14 +850,18 @@ def get_kdocs_status_api():
uploader = get_kdocs_uploader()
status = uploader.get_status()
live = uploader.refresh_login_status()
if live.get("success"):
logged_in = bool(live.get("logged_in"))
live = str(request.args.get("live", "")).lower() in ("1", "true", "yes")
if live:
live_status = uploader.refresh_login_status()
if live_status.get("success"):
logged_in = bool(live_status.get("logged_in"))
status["logged_in"] = logged_in
status["last_login_ok"] = logged_in
status["login_required"] = not logged_in
if live.get("error"):
status["last_error"] = live.get("error")
if live_status.get("error"):
status["last_error"] = live_status.get("error")
else:
status["logged_in"] = True if status.get("last_login_ok") else False if status.get("last_login_ok") is False else None
return jsonify(status)
except Exception as e:
return jsonify({"error": f"获取状态失败: {e}"}), 500

View File

@@ -1,34 +1,34 @@
{
"_email-BDvF0irD.js": {
"file": "assets/email-BDvF0irD.js",
"_email-CANx8Tja.js": {
"file": "assets/email-CANx8Tja.js",
"name": "email",
"imports": [
"index.html"
]
},
"_system-CMyTza1B.js": {
"file": "assets/system-CMyTza1B.js",
"_system-CM-zje4U.js": {
"file": "assets/system-CM-zje4U.js",
"name": "system",
"imports": [
"index.html"
]
},
"_tasks-CQlm8unE.js": {
"file": "assets/tasks-CQlm8unE.js",
"_tasks-MT8n16Cr.js": {
"file": "assets/tasks-MT8n16Cr.js",
"name": "tasks",
"imports": [
"index.html"
]
},
"_users-CwvLJNE7.js": {
"file": "assets/users-CwvLJNE7.js",
"_users-BfTiBX13.js": {
"file": "assets/users-BfTiBX13.js",
"name": "users",
"imports": [
"index.html"
]
},
"index.html": {
"file": "assets/index-DYOBdo6M.js",
"file": "assets/index-DD_NUvZR.js",
"name": "index",
"src": "index.html",
"isEntry": true,
@@ -48,7 +48,7 @@
]
},
"src/pages/AnnouncementsPage.vue": {
"file": "assets/AnnouncementsPage-Qex0pAMP.js",
"file": "assets/AnnouncementsPage-DJV9obay.js",
"name": "AnnouncementsPage",
"src": "src/pages/AnnouncementsPage.vue",
"isDynamicEntry": true,
@@ -60,12 +60,12 @@
]
},
"src/pages/EmailPage.vue": {
"file": "assets/EmailPage-DjFQXXaw.js",
"file": "assets/EmailPage-D-tsUWFT.js",
"name": "EmailPage",
"src": "src/pages/EmailPage.vue",
"isDynamicEntry": true,
"imports": [
"_email-BDvF0irD.js",
"_email-CANx8Tja.js",
"index.html"
],
"css": [
@@ -73,7 +73,7 @@
]
},
"src/pages/FeedbacksPage.vue": {
"file": "assets/FeedbacksPage-Ccz7usmm.js",
"file": "assets/FeedbacksPage-DZUE-vHi.js",
"name": "FeedbacksPage",
"src": "src/pages/FeedbacksPage.vue",
"isDynamicEntry": true,
@@ -85,13 +85,13 @@
]
},
"src/pages/LogsPage.vue": {
"file": "assets/LogsPage-DKgDsqeF.js",
"file": "assets/LogsPage-CdMEmjzm.js",
"name": "LogsPage",
"src": "src/pages/LogsPage.vue",
"isDynamicEntry": true,
"imports": [
"_users-CwvLJNE7.js",
"_tasks-CQlm8unE.js",
"_users-BfTiBX13.js",
"_tasks-MT8n16Cr.js",
"index.html"
],
"css": [
@@ -99,22 +99,22 @@
]
},
"src/pages/ReportPage.vue": {
"file": "assets/ReportPage-9KIB3iif.js",
"file": "assets/ReportPage-DAW30JOI.js",
"name": "ReportPage",
"src": "src/pages/ReportPage.vue",
"isDynamicEntry": true,
"imports": [
"index.html",
"_email-BDvF0irD.js",
"_tasks-CQlm8unE.js",
"_system-CMyTza1B.js"
"_email-CANx8Tja.js",
"_tasks-MT8n16Cr.js",
"_system-CM-zje4U.js"
],
"css": [
"assets/ReportPage-Q8rCsG8A.css"
]
},
"src/pages/SecurityPage.vue": {
"file": "assets/SecurityPage-QH4U-Y6k.js",
"file": "assets/SecurityPage-C21EbRZb.js",
"name": "SecurityPage",
"src": "src/pages/SecurityPage.vue",
"isDynamicEntry": true,
@@ -126,7 +126,7 @@
]
},
"src/pages/SettingsPage.vue": {
"file": "assets/SettingsPage-OTetedw0.js",
"file": "assets/SettingsPage-BM2ulFCL.js",
"name": "SettingsPage",
"src": "src/pages/SettingsPage.vue",
"isDynamicEntry": true,
@@ -138,25 +138,25 @@
]
},
"src/pages/SystemPage.vue": {
"file": "assets/SystemPage-agjTEZ2h.js",
"file": "assets/SystemPage-D5R5QCv7.js",
"name": "SystemPage",
"src": "src/pages/SystemPage.vue",
"isDynamicEntry": true,
"imports": [
"_system-CMyTza1B.js",
"_system-CM-zje4U.js",
"index.html"
],
"css": [
"assets/SystemPage-BgaIr3zp.css"
"assets/SystemPage-5z0b5M8t.css"
]
},
"src/pages/UsersPage.vue": {
"file": "assets/UsersPage-D513gXjG.js",
"file": "assets/UsersPage-DxOwX5c9.js",
"name": "UsersPage",
"src": "src/pages/UsersPage.vue",
"isDynamicEntry": true,
"imports": [
"_users-CwvLJNE7.js",
"_users-BfTiBX13.js",
"index.html"
],
"css": [

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{a as m,_ as B,r as p,f as u,g as T,h as P,j as r,m as a,w as l,q as x,L as i,K as b}from"./index-DYOBdo6M.js";async function C(o){const{data:s}=await m.put("/admin/username",{new_username:o});return s}async function S(o){const{data:s}=await m.put("/admin/password",{new_password:o});return s}async function U(){const{data:o}=await m.post("/logout");return o}const A={class:"page-stack"},E={__name:"SettingsPage",setup(o){const s=p(""),d=p(""),n=p(!1);function k(t){const e=String(t||"");return e.length<8?{ok:!1,message:"密码长度至少8位"}:e.length>128?{ok:!1,message:"密码长度不能超过128个字符"}:!/[a-zA-Z]/.test(e)||!/\d/.test(e)?{ok:!1,message:"密码必须包含字母和数字"}:{ok:!0,message:""}}async function f(){try{await U()}catch{}finally{window.location.href="/yuyx"}}async function V(){const t=s.value.trim();if(!t){i.error("请输入新用户名");return}try{await b.confirm(`确定将管理员用户名修改为「${t}」吗?修改后需要重新登录。`,"修改用户名",{confirmButtonText:"确认修改",cancelButtonText:"取消",type:"warning"})}catch{return}n.value=!0;try{await C(t),i.success("用户名修改成功,请重新登录"),s.value="",setTimeout(f,1200)}catch{}finally{n.value=!1}}async function h(){const t=d.value;if(!t){i.error("请输入新密码");return}const e=k(t);if(!e.ok){i.error(e.message);return}try{await b.confirm("确定修改管理员密码吗?修改后需要重新登录。","修改密码",{confirmButtonText:"确认修改",cancelButtonText:"取消",type:"warning"})}catch{return}n.value=!0;try{await S(t),i.success("密码修改成功,请重新登录"),d.value="",setTimeout(f,1200)}catch{}finally{n.value=!1}}return(t,e)=>{const g=u("el-input"),w=u("el-form-item"),v=u("el-form"),y=u("el-button"),_=u("el-card");return P(),T("div",A,[e[7]||(e[7]=r("div",{class:"app-page-title"},[r("h2",null,"设置"),r("span",{class:"app-muted"},"管理员账号设置")],-1)),a(_,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:l(()=>[e[3]||(e[3]=r("h3",{class:"section-title"},"修改管理员用户名",-1)),a(v,{"label-width":"120px"},{default:l(()=>[a(w,{label:"新用户名"},{default:l(()=>[a(g,{modelValue:s.value,"onUpdate:modelValue":e[0]||(e[0]=c=>s.value=c),placeholder:"输入新用户名",disabled:n.value},null,8,["modelValue","disabled"])]),_:1})]),_:1}),a(y,{type:"primary",loading:n.value,onClick:V},{default:l(()=>[...e[2]||(e[2]=[x("保存用户名",-1)])]),_:1},8,["loading"])]),_:1}),a(_,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:l(()=>[e[5]||(e[5]=r("h3",{class:"section-title"},"修改管理员密码",-1)),a(v,{"label-width":"120px"},{default:l(()=>[a(w,{label:"新密码"},{default:l(()=>[a(g,{modelValue:d.value,"onUpdate:modelValue":e[1]||(e[1]=c=>d.value=c),type:"password","show-password":"",placeholder:"输入新密码",disabled:n.value},null,8,["modelValue","disabled"])]),_:1})]),_:1}),a(y,{type:"primary",loading:n.value,onClick:h},{default:l(()=>[...e[4]||(e[4]=[x("保存密码",-1)])]),_:1},8,["loading"]),e[6]||(e[6]=r("div",{class:"help"},"建议使用更强密码至少8位且包含字母与数字。",-1))]),_:1})])}}},M=B(E,[["__scopeId","data-v-12a26d11"]]);export{M as default};
import{a as m,_ as B,r as p,f as u,g as T,h as P,j as r,m as a,w as l,q as x,L as i,K as b}from"./index-DD_NUvZR.js";async function C(o){const{data:s}=await m.put("/admin/username",{new_username:o});return s}async function S(o){const{data:s}=await m.put("/admin/password",{new_password:o});return s}async function U(){const{data:o}=await m.post("/logout");return o}const A={class:"page-stack"},E={__name:"SettingsPage",setup(o){const s=p(""),d=p(""),n=p(!1);function k(t){const e=String(t||"");return e.length<8?{ok:!1,message:"密码长度至少8位"}:e.length>128?{ok:!1,message:"密码长度不能超过128个字符"}:!/[a-zA-Z]/.test(e)||!/\d/.test(e)?{ok:!1,message:"密码必须包含字母和数字"}:{ok:!0,message:""}}async function f(){try{await U()}catch{}finally{window.location.href="/yuyx"}}async function V(){const t=s.value.trim();if(!t){i.error("请输入新用户名");return}try{await b.confirm(`确定将管理员用户名修改为「${t}」吗?修改后需要重新登录。`,"修改用户名",{confirmButtonText:"确认修改",cancelButtonText:"取消",type:"warning"})}catch{return}n.value=!0;try{await C(t),i.success("用户名修改成功,请重新登录"),s.value="",setTimeout(f,1200)}catch{}finally{n.value=!1}}async function h(){const t=d.value;if(!t){i.error("请输入新密码");return}const e=k(t);if(!e.ok){i.error(e.message);return}try{await b.confirm("确定修改管理员密码吗?修改后需要重新登录。","修改密码",{confirmButtonText:"确认修改",cancelButtonText:"取消",type:"warning"})}catch{return}n.value=!0;try{await S(t),i.success("密码修改成功,请重新登录"),d.value="",setTimeout(f,1200)}catch{}finally{n.value=!1}}return(t,e)=>{const g=u("el-input"),w=u("el-form-item"),v=u("el-form"),y=u("el-button"),_=u("el-card");return P(),T("div",A,[e[7]||(e[7]=r("div",{class:"app-page-title"},[r("h2",null,"设置"),r("span",{class:"app-muted"},"管理员账号设置")],-1)),a(_,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:l(()=>[e[3]||(e[3]=r("h3",{class:"section-title"},"修改管理员用户名",-1)),a(v,{"label-width":"120px"},{default:l(()=>[a(w,{label:"新用户名"},{default:l(()=>[a(g,{modelValue:s.value,"onUpdate:modelValue":e[0]||(e[0]=c=>s.value=c),placeholder:"输入新用户名",disabled:n.value},null,8,["modelValue","disabled"])]),_:1})]),_:1}),a(y,{type:"primary",loading:n.value,onClick:V},{default:l(()=>[...e[2]||(e[2]=[x("保存用户名",-1)])]),_:1},8,["loading"])]),_:1}),a(_,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:l(()=>[e[5]||(e[5]=r("h3",{class:"section-title"},"修改管理员密码",-1)),a(v,{"label-width":"120px"},{default:l(()=>[a(w,{label:"新密码"},{default:l(()=>[a(g,{modelValue:d.value,"onUpdate:modelValue":e[1]||(e[1]=c=>d.value=c),type:"password","show-password":"",placeholder:"输入新密码",disabled:n.value},null,8,["modelValue","disabled"])]),_:1})]),_:1}),a(y,{type:"primary",loading:n.value,onClick:h},{default:l(()=>[...e[4]||(e[4]=[x("保存密码",-1)])]),_:1},8,["loading"]),e[6]||(e[6]=r("div",{class:"help"},"建议使用更强密码至少8位且包含字母与数字。",-1))]),_:1})])}}},M=B(E,[["__scopeId","data-v-12a26d11"]]);export{M as default};

View File

@@ -0,0 +1 @@
.page-stack[data-v-5af0394e]{display:flex;flex-direction:column;gap:12px}.card[data-v-5af0394e]{border-radius:var(--app-radius);border:1px solid var(--app-border)}.section-title[data-v-5af0394e]{margin:0 0 12px;font-size:14px;font-weight:800}.kdocs-qr[data-v-5af0394e]{display:flex;flex-direction:column;align-items:center;gap:12px}.kdocs-qr img[data-v-5af0394e]{width:260px;max-width:100%;border:1px solid var(--app-border);border-radius:8px;padding:8px;background:#fff}.help[data-v-5af0394e]{margin-top:6px;font-size:12px;color:var(--app-muted)}.row-actions[data-v-5af0394e]{display:flex;flex-wrap:wrap;gap:10px}

View File

@@ -1 +0,0 @@
.page-stack[data-v-2e6346ad]{display:flex;flex-direction:column;gap:12px}.card[data-v-2e6346ad]{border-radius:var(--app-radius);border:1px solid var(--app-border)}.section-title[data-v-2e6346ad]{margin:0 0 12px;font-size:14px;font-weight:800}.kdocs-qr[data-v-2e6346ad]{display:flex;flex-direction:column;align-items:center;gap:12px}.kdocs-qr img[data-v-2e6346ad]{width:260px;max-width:100%;border:1px solid var(--app-border);border-radius:8px;padding:8px;background:#fff}.help[data-v-2e6346ad]{margin-top:6px;font-size:12px;color:var(--app-muted)}.row-actions[data-v-2e6346ad]{display:flex;flex-wrap:wrap;gap:10px}

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

View File

@@ -1 +1 @@
import{a as n}from"./index-DYOBdo6M.js";async function i(){const{data:a}=await n.get("/email/settings");return a}async function e(a){const{data:t}=await n.post("/email/settings",a);return t}async function c(){const{data:a}=await n.get("/email/stats");return a}async function o(a){const{data:t}=await n.get("/email/logs",{params:a});return t}async function l(a){const{data:t}=await n.post("/email/logs/cleanup",{days:a});return t}export{o as a,i as b,l as c,c as f,e as u};
import{a as n}from"./index-DD_NUvZR.js";async function i(){const{data:a}=await n.get("/email/settings");return a}async function e(a){const{data:t}=await n.post("/email/settings",a);return t}async function c(){const{data:a}=await n.get("/email/stats");return a}async function o(a){const{data:t}=await n.get("/email/logs",{params:a});return t}async function l(a){const{data:t}=await n.post("/email/logs/cleanup",{days:a});return t}export{o as a,i as b,l as c,c as f,e as u};

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{a}from"./index-DYOBdo6M.js";async function s(){const{data:t}=await a.get("/system/config");return t}async function c(t){const{data:e}=await a.post("/system/config",t);return e}async function o(){const{data:t}=await a.post("/schedule/execute",{});return t}export{o as e,s as f,c as u};
import{a}from"./index-DD_NUvZR.js";async function s(){const{data:t}=await a.get("/system/config");return t}async function c(t){const{data:e}=await a.post("/system/config",t);return e}async function o(){const{data:t}=await a.post("/schedule/execute",{});return t}export{o as e,s as f,c as u};

View File

@@ -1 +1 @@
import{a}from"./index-DYOBdo6M.js";async function c(){const{data:t}=await a.get("/server/info");return t}async function e(){const{data:t}=await a.get("/docker_stats");return t}async function o(){const{data:t}=await a.get("/task/stats");return t}async function r(){const{data:t}=await a.get("/task/running");return t}async function i(t){const{data:s}=await a.get("/task/logs",{params:t});return s}async function f(t){const{data:s}=await a.post("/task/logs/clear",{days:t});return s}export{r as a,c as b,e as c,i as d,f as e,o as f};
import{a}from"./index-DD_NUvZR.js";async function c(){const{data:t}=await a.get("/server/info");return t}async function e(){const{data:t}=await a.get("/docker_stats");return t}async function o(){const{data:t}=await a.get("/task/stats");return t}async function r(){const{data:t}=await a.get("/task/running");return t}async function i(t){const{data:s}=await a.get("/task/logs",{params:t});return s}async function f(t){const{data:s}=await a.post("/task/logs/clear",{days:t});return s}export{r as a,c as b,e as c,i as d,f as e,o as f};

View File

@@ -1 +1 @@
import{a as t}from"./index-DYOBdo6M.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-DD_NUvZR.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};

View File

@@ -5,7 +5,7 @@
<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-DYOBdo6M.js"></script>
<script type="module" crossorigin src="./assets/index-DD_NUvZR.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-DxTKnDeo.css">
</head>
<body>