fix(passkey): 修复安卓端 Credential Manager 异常并增强兼容

更新说明:\n1. 优化 Passkey 注册参数(residentKey/hints),提升安卓设备兼容性。\n2. 前台与后台统一增强 Passkey 错误提示,针对 NotReadableError/小米浏览器给出明确引导。\n3. 同步更新相关前端页面逻辑与构建产物。
This commit is contained in:
2026-02-16 00:17:11 +08:00
parent cb35df5f01
commit 7627885b1b
30 changed files with 137 additions and 69 deletions

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{_}from"./index-BMIn4N2u.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-BwP1dZnj.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};

View File

@@ -0,0 +1 @@
.page-stack[data-v-fb202365]{display:flex;flex-direction:column;gap:14px;min-width:0}.card[data-v-fb202365]{border-radius:var(--app-radius);border:1px solid var(--app-border);background:var(--app-card-bg);box-shadow:var(--app-shadow-soft)}.section-title[data-v-fb202365]{margin:0 0 12px;font-size:15px;font-weight:800;letter-spacing:.2px}.help[data-v-fb202365]{margin-top:10px;font-size:12px;color:var(--app-muted)}.help-alert[data-v-fb202365]{margin-bottom:12px}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
.page-stack[data-v-bb93be75]{display:flex;flex-direction:column;gap:14px;min-width:0}.card[data-v-bb93be75]{border-radius:var(--app-radius);border:1px solid var(--app-border);background:var(--app-card-bg);box-shadow:var(--app-shadow-soft)}.section-title[data-v-bb93be75]{margin:0 0 12px;font-size:15px;font-weight:800;letter-spacing:.2px}.help[data-v-bb93be75]{margin-top:10px;font-size:12px;color:var(--app-muted)}.help-alert[data-v-bb93be75]{margin-bottom:12px}

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
import{f as Ce,u as ne}from"./system-CeJP0y2Z.js";import{a as C,_ as Se}from"./index-BMIn4N2u.js";import{E as me,a as m}from"./vendor-element-B5S5pUKo.js";import{r as n,c as le,l as Pe,R as Ie,o as Ae,aj as p,ap as Ne,F as De,q as P,n as I,t as o,L as a,E as s,I as f,G as ae,y as Ke,J as te}from"./vendor-vue-CVxSw_oJ.js";import"./vendor-axios-B9ygI19o.js";import"./vendor-misc-BeoNyvBp.js";async function ue(r={},c={}){const{data:v}=await C.get("/kdocs/status",{params:r,...c});return v}async function Ee(r={}){const c={force:!0,...r},{data:v}=await C.post("/kdocs/qr",c);return v}async function Le(){const{data:r}=await C.post("/kdocs/clear-login",{});return r}async function Qe(){const{data:r}=await C.get("/proxy/config");return r}async function Te(r){const{data:c}=await C.post("/proxy/config",r);return c}async function qe(r){const{data:c}=await C.post("/proxy/test",r);return c}const Be={class:"page-stack"},$e={class:"config-grid"},Re={class:"row-actions"},Me={class:"row-actions"},Fe={class:"row-actions"},he={class:"section-head"},ze={class:"status-inline app-muted"},He={key:0,class:"status-dots","aria-hidden":"true"},Ge={class:"kdocs-inline"},Oe={class:"kdocs-range"},je={class:"row-actions"},Je={key:0,class:"help"},We={key:1,class:"help"},Xe={class:"kdocs-qr"},Ye=["src"],Ze={__name:"SystemPage",setup(r){const c=n(!1),v=n(2),A=n(1),N=n(3),D=n(120),S=n(!1),_=n(""),K=n(3),E=n(!1),L=n(10),Q=n(7),T=n(!1),q=n(""),B=n(""),$=n(""),R=n(0),M=n("A"),F=n("D"),h=n(0),z=n(0),H=n(!1),G=n(""),y=n({}),k=n(!1),b=n(""),oe=n(!1),x=n(!1),w=n(!1),U=n(!1),O=n(!1),j=n("");let J=null;const de=le(()=>x.value||w.value||U.value),se=le(()=>O.value||x.value||oe.value),W=le(()=>{if(se.value)return"检测中";const l=y.value||{};return l?.logged_in===!0||l?.last_login_ok===!0?"已登录":l?.logged_in===!1||l?.last_login_ok===!1||l?.login_required===!0?"未登录":l?.last_error?"异常":"未知"}),ce=le(()=>se.value?"is-checking":W.value==="已登录"?"is-online":W.value==="未登录"?"is-offline":W.value==="异常"?"is-error":"is-unknown");function d(l){if(!l){j.value="";return}const e=new Date().toLocaleTimeString("zh-CN",{hour12:!1});j.value=`${l} (${e})`}async function ve(){c.value=!0;try{const[l,e]=await Promise.all([Ce(),Qe()]);v.value=l.max_concurrent_global??2,A.value=l.max_concurrent_per_account??1,N.value=l.max_screenshot_concurrent??3,D.value=l.db_slow_query_ms??120,E.value=(l.auto_approve_enabled??0)===1,L.value=l.auto_approve_hourly_limit??10,Q.value=l.auto_approve_vip_days??7,S.value=(e.proxy_enabled??0)===1,_.value=e.proxy_api_url||"",K.value=e.proxy_expire_minutes??3,T.value=(l.kdocs_enabled??0)===1,q.value=l.kdocs_doc_url||"",B.value=l.kdocs_default_unit||"",$.value=l.kdocs_sheet_name||"",R.value=l.kdocs_sheet_index??0,M.value=(l.kdocs_unit_column||"A").toUpperCase(),F.value=(l.kdocs_image_column||"D").toUpperCase(),h.value=l.kdocs_row_start??0,z.value=l.kdocs_row_end??0,H.value=(l.kdocs_admin_notify_enabled??0)===1,G.value=l.kdocs_admin_notify_email||""}catch{}finally{c.value=!1}pe()}async function pe(){if(!(O.value||x.value)){O.value=!0;try{const l=await ue({},{__silent:!0,__no_retry:!0,timeout:8e3});y.value=l||{}}catch{}finally{O.value=!1}}}async function fe(){const l={max_concurrent_global:Number(v.value),max_concurrent_per_account:Number(A.value),max_screenshot_concurrent:Number(N.value),db_slow_query_ms:Number(D.value)};try{await me.confirm(`确定更新并发配置吗?
import{f as Ce,u as ne}from"./system-Dluvi0rE.js";import{a as C,_ as Se}from"./index-BwP1dZnj.js";import{E as me,a as m}from"./vendor-element-B5S5pUKo.js";import{r as n,c as le,l as Pe,R as Ie,o as Ae,aj as p,ap as Ne,F as De,q as P,n as I,t as o,L as a,E as s,I as f,G as ae,y as Ke,J as te}from"./vendor-vue-CVxSw_oJ.js";import"./vendor-axios-B9ygI19o.js";import"./vendor-misc-BeoNyvBp.js";async function ue(r={},c={}){const{data:v}=await C.get("/kdocs/status",{params:r,...c});return v}async function Ee(r={}){const c={force:!0,...r},{data:v}=await C.post("/kdocs/qr",c);return v}async function Le(){const{data:r}=await C.post("/kdocs/clear-login",{});return r}async function Qe(){const{data:r}=await C.get("/proxy/config");return r}async function Te(r){const{data:c}=await C.post("/proxy/config",r);return c}async function qe(r){const{data:c}=await C.post("/proxy/test",r);return c}const Be={class:"page-stack"},$e={class:"config-grid"},Re={class:"row-actions"},Me={class:"row-actions"},Fe={class:"row-actions"},he={class:"section-head"},ze={class:"status-inline app-muted"},He={key:0,class:"status-dots","aria-hidden":"true"},Ge={class:"kdocs-inline"},Oe={class:"kdocs-range"},je={class:"row-actions"},Je={key:0,class:"help"},We={key:1,class:"help"},Xe={class:"kdocs-qr"},Ye=["src"],Ze={__name:"SystemPage",setup(r){const c=n(!1),v=n(2),A=n(1),N=n(3),D=n(120),S=n(!1),_=n(""),K=n(3),E=n(!1),L=n(10),Q=n(7),T=n(!1),q=n(""),B=n(""),$=n(""),R=n(0),M=n("A"),F=n("D"),h=n(0),z=n(0),H=n(!1),G=n(""),y=n({}),k=n(!1),b=n(""),oe=n(!1),x=n(!1),w=n(!1),U=n(!1),O=n(!1),j=n("");let J=null;const de=le(()=>x.value||w.value||U.value),se=le(()=>O.value||x.value||oe.value),W=le(()=>{if(se.value)return"检测中";const l=y.value||{};return l?.logged_in===!0||l?.last_login_ok===!0?"已登录":l?.logged_in===!1||l?.last_login_ok===!1||l?.login_required===!0?"未登录":l?.last_error?"异常":"未知"}),ce=le(()=>se.value?"is-checking":W.value==="已登录"?"is-online":W.value==="未登录"?"is-offline":W.value==="异常"?"is-error":"is-unknown");function d(l){if(!l){j.value="";return}const e=new Date().toLocaleTimeString("zh-CN",{hour12:!1});j.value=`${l} (${e})`}async function ve(){c.value=!0;try{const[l,e]=await Promise.all([Ce(),Qe()]);v.value=l.max_concurrent_global??2,A.value=l.max_concurrent_per_account??1,N.value=l.max_screenshot_concurrent??3,D.value=l.db_slow_query_ms??120,E.value=(l.auto_approve_enabled??0)===1,L.value=l.auto_approve_hourly_limit??10,Q.value=l.auto_approve_vip_days??7,S.value=(e.proxy_enabled??0)===1,_.value=e.proxy_api_url||"",K.value=e.proxy_expire_minutes??3,T.value=(l.kdocs_enabled??0)===1,q.value=l.kdocs_doc_url||"",B.value=l.kdocs_default_unit||"",$.value=l.kdocs_sheet_name||"",R.value=l.kdocs_sheet_index??0,M.value=(l.kdocs_unit_column||"A").toUpperCase(),F.value=(l.kdocs_image_column||"D").toUpperCase(),h.value=l.kdocs_row_start??0,z.value=l.kdocs_row_end??0,H.value=(l.kdocs_admin_notify_enabled??0)===1,G.value=l.kdocs_admin_notify_email||""}catch{}finally{c.value=!1}pe()}async function pe(){if(!(O.value||x.value)){O.value=!0;try{const l=await ue({},{__silent:!0,__no_retry:!0,timeout:8e3});y.value=l||{}}catch{}finally{O.value=!1}}}async function fe(){const l={max_concurrent_global:Number(v.value),max_concurrent_per_account:Number(A.value),max_screenshot_concurrent:Number(N.value),db_slow_query_ms:Number(D.value)};try{await me.confirm(`确定更新并发配置吗?
全局并发数: ${l.max_concurrent_global}
单账号并发数: ${l.max_concurrent_per_account}

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
import{c as s,a as e}from"./index-BMIn4N2u.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-BwP1dZnj.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

View File

@@ -1 +1 @@
import{c as s,a}from"./index-BMIn4N2u.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-BwP1dZnj.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};

View File

@@ -1 +1 @@
import{c as s,a}from"./index-BMIn4N2u.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-BwP1dZnj.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};

View File

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