KDocs 上传功能增强: - 搜索优化:只用姓名搜索 + C列验证,避免匹配到错误单元格 - 有效行范围:支持配置起始行/结束行,限制上传区域 - 图片覆盖:支持覆盖单元格已有图片(Escape + Delete) - 配置持久化:kdocs_row_start/row_end 保存到数据库(v18迁移) 二次登录功能: - 登录后立即再次登录,让"上次登录时间"显示为刚刚 KDocs 离线监控: - 每5分钟检测金山文档登录状态 - 离线时发送邮件通知管理员(每次掉线只通知一次) - 恢复在线后重置通知状态 Bug 修复: - 任务日志搜索账号关键词报错500:添加异常处理 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
18 lines
17 KiB
JavaScript
18 lines
17 KiB
JavaScript
import{f as Ee,u as oe,e as $e}from"./system-C6kBIFhi.js";import{a as A,_ as Le,r as n,c as fe,U as He,T as qe,o as Qe,f as v,I as Fe,J as Me,h as f,g as k,j as u,m as l,w as o,q as m,B as ne,n as w,F as Re,v as je,p as ue,K as se,L as i}from"./index-DKH_HvPt.js";async function ie(p={}){const{data:_}=await A.get("/kdocs/status",{params:p});return _}async function ze(p={}){const _={force:!0,...p},{data:U}=await A.post("/kdocs/qr",_);return U}async function Oe(){const{data:p}=await A.post("/kdocs/clear-login",{});return p}async function We(){const{data:p}=await A.get("/proxy/config");return p}async function Ge(p){const{data:_}=await A.post("/proxy/config",p);return _}async function Je(p){const{data:_}=await A.post("/proxy/test",p);return _}const Xe={class:"page-stack"},Ye={class:"app-page-title"},Ze={class:"row-actions"},el={class:"row-actions"},ll={style:{display:"flex","align-items":"center",gap:"8px"}},al={class:"row-actions"},tl={class:"help"},ol={key:0},nl={key:1},ul={key:2},sl={key:3},dl={key:0,class:"help"},rl={class:"kdocs-qr"},il=["src"],ml={__name:"SystemPage",setup(p){const _=n(!1),U=n(2),$=n(1),L=n(3),y=n(!1),H=n("02:00"),B=n("应读"),g=n(["1","2","3","4","5","6","7"]),T=n(!0),D=n(!1),x=n(""),q=n(3),Q=n(!1),F=n(10),M=n(7),R=n(!1),j=n(""),z=n(""),O=n(""),W=n(0),G=n("A"),J=n("D"),X=n(0),Y=n(0),Z=n(!1),ee=n(""),b=n({}),C=n(!1),P=n(""),me=n(!1),h=n(!1),S=n(!1),I=n(!1),le=n("");let ae=null;const _e=[{label:"周一",value:"1"},{label:"周二",value:"2"},{label:"周三",value:"3"},{label:"周四",value:"4"},{label:"周五",value:"5"},{label:"周六",value:"6"},{label:"周日",value:"7"}],ye={1:"周一",2:"周二",3:"周三",4:"周四",5:"周五",6:"周六",7:"周日"},be=fe(()=>(g.value||[]).map(a=>ye[Number(a)]||a).join("、")),de=fe(()=>h.value||S.value||I.value);function ke(a){return String(a)==="注册前未读"?"注册前未读":"应读"}function c(a){if(!a){le.value="";return}const e=new Date().toLocaleTimeString("zh-CN",{hour12:!1});le.value=`${a} (${e})`}async function ce(){_.value=!0;try{const[a,e,d]=await Promise.all([Ee(),We(),ie().catch(()=>({}))]);U.value=a.max_concurrent_global??2,$.value=a.max_concurrent_per_account??1,L.value=a.max_screenshot_concurrent??3,y.value=(a.schedule_enabled??0)===1,H.value=a.schedule_time||"02:00",B.value=ke(a.schedule_browse_type);const r=String(a.schedule_weekdays||"1,2,3,4,5,6,7").split(",").map(s=>s.trim()).filter(Boolean);g.value=r.length?r:["1","2","3","4","5","6","7"],T.value=(a.enable_screenshot??1)===1,Q.value=(a.auto_approve_enabled??0)===1,F.value=a.auto_approve_hourly_limit??10,M.value=a.auto_approve_vip_days??7,D.value=(e.proxy_enabled??0)===1,x.value=e.proxy_api_url||"",q.value=e.proxy_expire_minutes??3,R.value=(a.kdocs_enabled??0)===1,j.value=a.kdocs_doc_url||"",z.value=a.kdocs_default_unit||"",O.value=a.kdocs_sheet_name||"",W.value=a.kdocs_sheet_index??0,G.value=(a.kdocs_unit_column||"A").toUpperCase(),J.value=(a.kdocs_image_column||"D").toUpperCase(),X.value=a.kdocs_row_start??0,Y.value=a.kdocs_row_end??0,Z.value=(a.kdocs_admin_notify_enabled??0)===1,ee.value=a.kdocs_admin_notify_email||"",b.value=d||{}}catch{}finally{_.value=!1}}async function ge(){const a={max_concurrent_global:Number(U.value),max_concurrent_per_account:Number($.value),max_screenshot_concurrent:Number(L.value)};try{await se.confirm(`确定更新并发配置吗?
|
||
|
||
全局并发数: ${a.max_concurrent_global}
|
||
单账号并发数: ${a.max_concurrent_per_account}
|
||
截图并发数: ${a.max_screenshot_concurrent}`,"保存并发配置",{confirmButtonText:"保存",cancelButtonText:"取消",type:"warning"})}catch{return}try{const e=await oe(a);i.success(e?.message||"并发配置已更新")}catch{}}async function xe(){if(y.value&&(!g.value||g.value.length===0)){i.error("请至少选择一个执行日期");return}const a={schedule_enabled:y.value?1:0,schedule_time:H.value,schedule_browse_type:B.value,schedule_weekdays:(g.value||[]).join(","),enable_screenshot:T.value?1:0},e=T.value?"截图":"不截图",d=y.value?`确定启用定时任务吗?
|
||
|
||
执行时间: 每天 ${a.schedule_time}
|
||
执行日期: ${be.value}
|
||
浏览类型: ${a.schedule_browse_type}
|
||
截图: ${e}
|
||
|
||
系统将自动执行所有账号的浏览任务`:"确定关闭定时任务吗?";try{await se.confirm(d,"保存定时任务",{confirmButtonText:"确认",cancelButtonText:"取消",type:"warning"})}catch{return}try{const r=await oe(a);i.success(r?.message||(y.value?"定时任务已启用":"定时任务已关闭"))}catch{}}async function Ve(){const a=`确定要立即执行定时任务吗?
|
||
|
||
这将执行所有账号的浏览任务
|
||
浏览类型: ${B.value}
|
||
|
||
注意:无视定时时间和执行日期配置,立即开始执行!`;try{await se.confirm(a,"立即执行",{confirmButtonText:"立即执行",cancelButtonText:"取消",type:"warning"})}catch{return}try{const e=await $e();i.success(e?.message||"定时任务已开始执行")}catch{}}async function we(){if(D.value&&!x.value.trim()){i.error("启用代理时,API地址不能为空");return}const a={proxy_enabled:D.value?1:0,proxy_api_url:x.value.trim(),proxy_expire_minutes:Number(q.value)||3};try{const e=await Ge(a);i.success(e?.message||"代理配置已更新")}catch{}}async function Ue(){const a={kdocs_enabled:R.value?1:0,kdocs_doc_url:j.value.trim(),kdocs_default_unit:z.value.trim(),kdocs_sheet_name:O.value.trim(),kdocs_sheet_index:Number(W.value)||0,kdocs_unit_column:G.value.trim().toUpperCase(),kdocs_image_column:J.value.trim().toUpperCase(),kdocs_row_start:Number(X.value)||0,kdocs_row_end:Number(Y.value)||0,kdocs_admin_notify_enabled:Z.value?1:0,kdocs_admin_notify_email:ee.value.trim()};try{const e=await oe(a);i.success(e?.message||"表格配置已更新")}catch{}}async function re(){if(!h.value){h.value=!0,c("正在刷新状态");try{b.value=await ie({live:1}),c("状态已刷新")}catch{c("刷新失败,请稍后重试")}finally{h.value=!1}}}async function ve(){try{const a=await ie({live:1});b.value=a,(a?.logged_in===!0||a?.last_login_ok===!0)&&(i.success("扫码成功,已登录"),c("扫码成功,已登录"),C.value=!1,te())}catch{}}function Ce(){te(),me.value=!0,c("扫码检测中"),ve(),ae=setInterval(ve,2e3)}function te(){ae&&(clearInterval(ae),ae=null),me.value=!1}async function Pe(){if(!S.value){S.value=!0,c("正在获取二维码");try{P.value="";const a=await ze();if(P.value=a?.qr_image||"",!P.value){if(a?.logged_in){i.success("当前已登录,无需扫码"),c("当前已登录,无需扫码"),await re();return}i.warning("未获取到二维码"),c("未获取到二维码");return}c("二维码已获取"),C.value=!0}catch{c("获取二维码失败")}finally{S.value=!1}}}async function he(){if(!I.value){I.value=!0,c("正在清除登录态");try{await Oe(),C.value=!1,P.value="",i.success("登录态已清除"),c("登录态已清除"),await re()}catch{c("清除登录态失败")}finally{I.value=!1}}}He(C,a=>{a?Ce():te()}),qe(()=>{te()});async function Se(){if(!x.value.trim()){i.error("请先输入代理API地址");return}try{const a=await Je({api_url:x.value.trim()});await se.alert(a?.message||"测试完成","代理测试",{confirmButtonText:"知道了"})}catch{}}async function Ie(){const a=Number(F.value),e=Number(M.value);if(!Number.isFinite(a)||a<1){i.error("每小时注册限制必须大于0");return}if(!Number.isFinite(e)||e<0){i.error("VIP天数不能为负数");return}const d={auto_approve_enabled:Q.value?1:0,auto_approve_hourly_limit:a,auto_approve_vip_days:e};try{const r=await oe(d);i.success(r?.message||"注册设置已保存")}catch{}}return Qe(ce),(a,e)=>{const d=v("el-button"),r=v("el-input-number"),s=v("el-form-item"),K=v("el-form"),E=v("el-card"),N=v("el-switch"),Ne=v("el-time-picker"),pe=v("el-option"),Ae=v("el-select"),Be=v("el-checkbox"),Te=v("el-checkbox-group"),V=v("el-input"),De=v("el-dialog"),Ke=Fe("loading");return Me((f(),k("div",Xe,[u("div",Ye,[e[27]||(e[27]=u("h2",null,"系统配置",-1)),u("div",null,[l(d,{onClick:ce},{default:o(()=>[...e[26]||(e[26]=[m("刷新",-1)])]),_:1})])]),l(E,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:o(()=>[e[32]||(e[32]=u("h3",{class:"section-title"},"系统并发配置",-1)),l(K,{"label-width":"130px"},{default:o(()=>[l(s,{label:"全局最大并发数"},{default:o(()=>[l(r,{modelValue:U.value,"onUpdate:modelValue":e[0]||(e[0]=t=>U.value=t),min:1,max:200},null,8,["modelValue"]),e[28]||(e[28]=u("div",{class:"help"},"同时最多运行的账号数量(浏览任务使用 API 方式,资源占用较低)。",-1))]),_:1}),l(s,{label:"单账号最大并发数"},{default:o(()=>[l(r,{modelValue:$.value,"onUpdate:modelValue":e[1]||(e[1]=t=>$.value=t),min:1,max:50},null,8,["modelValue"]),e[29]||(e[29]=u("div",{class:"help"},"单个账号同时最多运行的任务数量(建议设为 1)。",-1))]),_:1}),l(s,{label:"截图最大并发数"},{default:o(()=>[l(r,{modelValue:L.value,"onUpdate:modelValue":e[2]||(e[2]=t=>L.value=t),min:1,max:50},null,8,["modelValue"]),e[30]||(e[30]=u("div",{class:"help"},"同时进行截图的最大数量(wkhtmltoimage 资源占用较低,可按需提高)。",-1))]),_:1})]),_:1}),l(d,{type:"primary",onClick:ge},{default:o(()=>[...e[31]||(e[31]=[m("保存并发配置",-1)])]),_:1})]),_:1}),l(E,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:o(()=>[e[37]||(e[37]=u("h3",{class:"section-title"},"定时任务配置",-1)),l(K,{"label-width":"130px"},{default:o(()=>[l(s,{label:"启用定时任务"},{default:o(()=>[l(N,{modelValue:y.value,"onUpdate:modelValue":e[3]||(e[3]=t=>y.value=t)},null,8,["modelValue"]),e[33]||(e[33]=u("div",{class:"help"},"开启后,系统会按计划自动执行浏览任务。",-1))]),_:1}),y.value?(f(),ne(s,{key:0,label:"执行时间"},{default:o(()=>[l(Ne,{modelValue:H.value,"onUpdate:modelValue":e[4]||(e[4]=t=>H.value=t),"value-format":"HH:mm",format:"HH:mm"},null,8,["modelValue"])]),_:1})):w("",!0),y.value?(f(),ne(s,{key:1,label:"浏览类型"},{default:o(()=>[l(Ae,{modelValue:B.value,"onUpdate:modelValue":e[5]||(e[5]=t=>B.value=t),style:{width:"220px"}},{default:o(()=>[l(pe,{label:"注册前未读",value:"注册前未读"}),l(pe,{label:"应读",value:"应读"})]),_:1},8,["modelValue"])]),_:1})):w("",!0),y.value?(f(),ne(s,{key:2,label:"执行日期"},{default:o(()=>[l(Te,{modelValue:g.value,"onUpdate:modelValue":e[6]||(e[6]=t=>g.value=t)},{default:o(()=>[(f(),k(Re,null,je(_e,t=>l(Be,{key:t.value,label:t.value},{default:o(()=>[m(ue(t.label),1)]),_:2},1032,["label"])),64))]),_:1},8,["modelValue"])]),_:1})):w("",!0),y.value?(f(),ne(s,{key:3,label:"定时任务截图"},{default:o(()=>[l(N,{modelValue:T.value,"onUpdate:modelValue":e[7]||(e[7]=t=>T.value=t)},null,8,["modelValue"]),e[34]||(e[34]=u("div",{class:"help"},"开启后,定时任务执行时会生成截图。",-1))]),_:1})):w("",!0)]),_:1}),u("div",Ze,[l(d,{type:"primary",onClick:xe},{default:o(()=>[...e[35]||(e[35]=[m("保存定时任务配置",-1)])]),_:1}),l(d,{type:"success",plain:"",onClick:Ve},{default:o(()=>[...e[36]||(e[36]=[m("立即执行",-1)])]),_:1})])]),_:1}),l(E,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:o(()=>[e[42]||(e[42]=u("h3",{class:"section-title"},"代理设置",-1)),l(K,{"label-width":"130px"},{default:o(()=>[l(s,{label:"启用IP代理"},{default:o(()=>[l(N,{modelValue:D.value,"onUpdate:modelValue":e[8]||(e[8]=t=>D.value=t)},null,8,["modelValue"]),e[38]||(e[38]=u("div",{class:"help"},"开启后,所有浏览任务将通过代理IP访问(失败自动重试3次)。",-1))]),_:1}),l(s,{label:"代理API地址"},{default:o(()=>[l(V,{modelValue:x.value,"onUpdate:modelValue":e[9]||(e[9]=t=>x.value=t),placeholder:"http://api.xxx/Tools/IP.ashx?..."},null,8,["modelValue"]),e[39]||(e[39]=u("div",{class:"help"},"API 应返回:IP:PORT(例如 123.45.67.89:8888)。",-1))]),_:1}),l(s,{label:"代理有效期(分钟)"},{default:o(()=>[l(r,{modelValue:q.value,"onUpdate:modelValue":e[10]||(e[10]=t=>q.value=t),min:1,max:60},null,8,["modelValue"])]),_:1})]),_:1}),u("div",el,[l(d,{type:"primary",onClick:we},{default:o(()=>[...e[40]||(e[40]=[m("保存代理配置",-1)])]),_:1}),l(d,{onClick:Se},{default:o(()=>[...e[41]||(e[41]=[m("测试代理",-1)])]),_:1})])]),_:1}),l(E,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:o(()=>[e[45]||(e[45]=u("h3",{class:"section-title"},"注册设置",-1)),l(K,{"label-width":"130px"},{default:o(()=>[l(s,{label:"注册赠送VIP"},{default:o(()=>[l(N,{modelValue:Q.value,"onUpdate:modelValue":e[11]||(e[11]=t=>Q.value=t)},null,8,["modelValue"]),e[43]||(e[43]=u("div",{class:"help"},"开启后,新用户注册成功后将赠送下方设置的VIP天数(注册已默认无需审核)。",-1))]),_:1}),l(s,{label:"每小时注册限制"},{default:o(()=>[l(r,{modelValue:F.value,"onUpdate:modelValue":e[12]||(e[12]=t=>F.value=t),min:1,max:1e4},null,8,["modelValue"])]),_:1}),l(s,{label:"注册赠送VIP天数"},{default:o(()=>[l(r,{modelValue:M.value,"onUpdate:modelValue":e[13]||(e[13]=t=>M.value=t),min:0,max:999999},null,8,["modelValue"])]),_:1})]),_:1}),l(d,{type:"primary",onClick:Ie},{default:o(()=>[...e[44]||(e[44]=[m("保存注册设置",-1)])]),_:1})]),_:1}),l(E,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:o(()=>[e[55]||(e[55]=u("h3",{class:"section-title"},"金山文档上传",-1)),l(K,{"label-width":"130px"},{default:o(()=>[l(s,{label:"启用上传"},{default:o(()=>[l(N,{modelValue:R.value,"onUpdate:modelValue":e[14]||(e[14]=t=>R.value=t)},null,8,["modelValue"]),e[46]||(e[46]=u("div",{class:"help"},"表格结构变化时可先关闭,避免错误上传。",-1))]),_:1}),l(s,{label:"文档链接"},{default:o(()=>[l(V,{modelValue:j.value,"onUpdate:modelValue":e[15]||(e[15]=t=>j.value=t),placeholder:"https://kdocs.cn/..."},null,8,["modelValue"])]),_:1}),l(s,{label:"默认县区"},{default:o(()=>[l(V,{modelValue:z.value,"onUpdate:modelValue":e[16]||(e[16]=t=>z.value=t),placeholder:"如:道县(用户可覆盖)"},null,8,["modelValue"])]),_:1}),l(s,{label:"Sheet名称"},{default:o(()=>[l(V,{modelValue:O.value,"onUpdate:modelValue":e[17]||(e[17]=t=>O.value=t),placeholder:"留空使用第一个Sheet"},null,8,["modelValue"])]),_:1}),l(s,{label:"Sheet序号"},{default:o(()=>[l(r,{modelValue:W.value,"onUpdate:modelValue":e[18]||(e[18]=t=>W.value=t),min:0,max:50},null,8,["modelValue"]),e[47]||(e[47]=u("div",{class:"help"},"0 表示第一个Sheet。",-1))]),_:1}),l(s,{label:"县区列"},{default:o(()=>[l(V,{modelValue:G.value,"onUpdate:modelValue":e[19]||(e[19]=t=>G.value=t),placeholder:"A",style:{"max-width":"120px"}},null,8,["modelValue"])]),_:1}),l(s,{label:"图片列"},{default:o(()=>[l(V,{modelValue:J.value,"onUpdate:modelValue":e[20]||(e[20]=t=>J.value=t),placeholder:"D",style:{"max-width":"120px"}},null,8,["modelValue"])]),_:1}),l(s,{label:"有效行范围"},{default:o(()=>[u("div",ll,[l(r,{modelValue:X.value,"onUpdate:modelValue":e[21]||(e[21]=t=>X.value=t),min:0,max:1e4,placeholder:"起始行",style:{width:"120px"}},null,8,["modelValue"]),e[48]||(e[48]=u("span",null,"至",-1)),l(r,{modelValue:Y.value,"onUpdate:modelValue":e[22]||(e[22]=t=>Y.value=t),min:0,max:1e4,placeholder:"结束行",style:{width:"120px"}},null,8,["modelValue"])]),e[49]||(e[49]=u("div",{class:"help"},"限制上传的行范围(如 50-100),0 表示不限制。用于防止重名导致误传到其他县区。",-1))]),_:1}),l(s,{label:"管理员通知"},{default:o(()=>[l(N,{modelValue:Z.value,"onUpdate:modelValue":e[23]||(e[23]=t=>Z.value=t)},null,8,["modelValue"])]),_:1}),l(s,{label:"通知邮箱"},{default:o(()=>[l(V,{modelValue:ee.value,"onUpdate:modelValue":e[24]||(e[24]=t=>ee.value=t),placeholder:"admin@example.com"},null,8,["modelValue"])]),_:1})]),_:1}),u("div",al,[l(d,{type:"primary",onClick:Ue},{default:o(()=>[...e[50]||(e[50]=[m("保存表格配置",-1)])]),_:1}),l(d,{loading:h.value,disabled:de.value&&!h.value,onClick:re},{default:o(()=>[...e[51]||(e[51]=[m(" 刷新状态 ",-1)])]),_:1},8,["loading","disabled"]),l(d,{type:"success",plain:"",loading:S.value,disabled:de.value&&!S.value,onClick:Pe},{default:o(()=>[...e[52]||(e[52]=[m(" 获取二维码 ",-1)])]),_:1},8,["loading","disabled"]),l(d,{type:"danger",plain:"",loading:I.value,disabled:de.value&&!I.value,onClick:he},{default:o(()=>[...e[53]||(e[53]=[m(" 清除登录 ",-1)])]),_:1},8,["loading","disabled"])]),u("div",tl,[e[54]||(e[54]=m(" 登录状态: ",-1)),b.value.last_login_ok===!0?(f(),k("span",ol,"已登录")):b.value.login_required?(f(),k("span",nl,"需要扫码")):(f(),k("span",ul,"未知")),m(" · 待上传 "+ue(b.value.queue_size||0)+" ",1),b.value.last_error?(f(),k("span",sl,"· 最近错误:"+ue(b.value.last_error),1)):w("",!0)]),le.value?(f(),k("div",dl,"操作提示:"+ue(le.value),1)):w("",!0)]),_:1}),l(De,{modelValue:C.value,"onUpdate:modelValue":e[25]||(e[25]=t=>C.value=t),title:"扫码登录",width:"min(420px, 92vw)"},{default:o(()=>[u("div",rl,[P.value?(f(),k("img",{key:0,src:`data:image/png;base64,${P.value}`,alt:"KDocs QR"},null,8,il)):w("",!0),e[56]||(e[56]=u("div",{class:"help"},"请使用管理员微信扫码登录。",-1))])]),_:1},8,["modelValue"])])),[[Ke,_.value]])}}},pl=Le(ml,[["__scopeId","data-v-b359577d"]]);export{pl as default};
|