Files
zsglpt/static/admin/assets/FeedbacksPage-BKxylUkG.js
yuyx 89f3fd9759 feat: 安全增强 + 删除密码重置申请功能 + 登录提醒开关
安全增强:
- 新增 SSRF、XXE、模板注入、敏感路径探测检测规则
- security/constants.py: 添加新的威胁类型和检测模式
- security/threat_detector.py: 实现新检测逻辑

删除密码重置申请功能:
- 移除 /api/password_resets 相关API
- 删除 password_reset_requests 数据库表
- 前端移除密码重置申请页面和菜单
- 用户只能通过邮��找回密码,未绑定邮箱需联系管理员

登录提醒全局开关:
- email_service.py: 添加 login_alert_enabled 字段
- routes/api_auth.py: 检查开关状态再发送登录提醒
- EmailPage.vue: 添加新设备登录提醒开关

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 12:08:36 +08:00

2 lines
5.4 KiB
JavaScript

import{_ as j,i as L,r as m,o as q,d as o,G,e as k,f as b,g as s,h as e,w as a,F as V,q as H,n as u,p as i,H as J,j as K,m as O,K as R,I as B,L as U,J as C,M as A,N as Q}from"./index-C9w-iZIr.js";const W={class:"page-stack"},X={class:"app-page-title"},Y={class:"toolbar"},Z={class:"stat-value"},ee={class:"stat-value warn"},te={class:"stat-value ok"},ae={class:"stat-value"},le={class:"table-wrap"},se={class:"ellipsis"},ne={class:"ellipsis"},oe={class:"ellipsis"},de={class:"actions"},ie={__name:"FeedbacksPage",setup(ce){const N=L("refreshNavBadges",null),y=m(!1),g=m(""),c=m({total:0,pending:0,replied:0,closed:0}),w=m([]),M=[{label:"全部状态",value:""},{label:"待处理",value:"pending"},{label:"已回复",value:"replied"},{label:"已关闭",value:"closed"}];function F(n){return n==="pending"?{label:"待处理",type:"warning"}:n==="replied"?{label:"已回复",type:"success"}:n==="closed"?{label:"已关闭",type:"info"}:{label:n||"-",type:"info"}}async function r(){y.value=!0;try{const n=await R(g.value);w.value=n?.feedbacks||[],c.value=n?.stats||{total:0,pending:0,replied:0,closed:0}}catch{w.value=[],c.value={total:0,pending:0,replied:0,closed:0}}finally{y.value=!1}await N?.({pendingFeedbacks:c.value.pending||0})}async function D(n){let t;try{t=(await B.prompt("请输入回复内容","回复反馈",{inputType:"textarea",inputPlaceholder:"回复内容",confirmButtonText:"提交",cancelButtonText:"取消",inputValidator:h=>!!String(h||"").trim(),inputErrorMessage:"回复内容不能为空"})).value}catch{return}try{const _=await U(n.id,String(t||"").trim());C.success(_?.message||"回复成功"),await r()}catch{}}async function E(n){try{await B.confirm("确定要关闭这个反馈吗?","关闭反馈",{confirmButtonText:"关闭",cancelButtonText:"取消",type:"warning"})}catch{return}try{const t=await A(n.id);C.success(t?.message||"反馈已关闭"),await r()}catch{}}async function z(n){try{await B.confirm("确定要删除这个反馈吗?此操作不可恢复!","删除反馈",{confirmButtonText:"删除",cancelButtonText:"取消",type:"error"})}catch{return}try{const t=await Q(n.id);C.success(t?.message||"反馈已删除"),await r()}catch{}}return q(r),(n,t)=>{const _=o("el-option"),h=o("el-select"),f=o("el-button"),p=o("el-card"),v=o("el-col"),I=o("el-row"),d=o("el-table-column"),x=o("el-tooltip"),P=o("el-tag"),S=o("el-table"),$=G("loading");return b(),k("div",W,[s("div",X,[t[2]||(t[2]=s("h2",null,"反馈管理",-1)),s("div",Y,[e(h,{modelValue:g.value,"onUpdate:modelValue":t[0]||(t[0]=l=>g.value=l),style:{width:"160px"},onChange:r},{default:a(()=>[(b(),k(V,null,H(M,l=>e(_,{key:l.value,label:l.label,value:l.value},null,8,["label","value"])),64))]),_:1},8,["modelValue"]),e(f,{onClick:r},{default:a(()=>[...t[1]||(t[1]=[u("刷新",-1)])]),_:1})])]),e(I,{gutter:12},{default:a(()=>[e(v,{xs:12,sm:6},{default:a(()=>[e(p,{shadow:"never",class:"stat-card","body-style":{padding:"14px"}},{default:a(()=>[s("div",Z,i(c.value.total||0),1),t[3]||(t[3]=s("div",{class:"stat-label"},"总计",-1))]),_:1})]),_:1}),e(v,{xs:12,sm:6},{default:a(()=>[e(p,{shadow:"never",class:"stat-card","body-style":{padding:"14px"}},{default:a(()=>[s("div",ee,i(c.value.pending||0),1),t[4]||(t[4]=s("div",{class:"stat-label"},"待处理",-1))]),_:1})]),_:1}),e(v,{xs:12,sm:6},{default:a(()=>[e(p,{shadow:"never",class:"stat-card","body-style":{padding:"14px"}},{default:a(()=>[s("div",te,i(c.value.replied||0),1),t[5]||(t[5]=s("div",{class:"stat-label"},"已回复",-1))]),_:1})]),_:1}),e(v,{xs:12,sm:6},{default:a(()=>[e(p,{shadow:"never",class:"stat-card","body-style":{padding:"14px"}},{default:a(()=>[s("div",ae,i(c.value.closed||0),1),t[6]||(t[6]=s("div",{class:"stat-label"},"已关闭",-1))]),_:1})]),_:1})]),_:1}),e(p,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:a(()=>[s("div",le,[J((b(),K(S,{data:w.value,style:{width:"100%"}},{default:a(()=>[e(d,{prop:"id",label:"ID",width:"80"}),e(d,{prop:"username",label:"用户",width:"140"}),e(d,{label:"标题","min-width":"180"},{default:a(({row:l})=>[e(x,{content:l.title,placement:"top","show-after":300},{default:a(()=>[s("span",se,i(l.title),1)]),_:2},1032,["content"])]),_:1}),e(d,{label:"描述","min-width":"220"},{default:a(({row:l})=>[e(x,{content:l.description,placement:"top","show-after":300},{default:a(()=>[s("span",ne,i(l.description),1)]),_:2},1032,["content"])]),_:1}),e(d,{prop:"contact",label:"联系方式","min-width":"160"},{default:a(({row:l})=>[u(i(l.contact||"-"),1)]),_:1}),e(d,{label:"状态",width:"110"},{default:a(({row:l})=>[e(P,{type:F(l.status).type,effect:"light"},{default:a(()=>[u(i(F(l.status).label),1)]),_:2},1032,["type"])]),_:1}),e(d,{prop:"created_at",label:"提交时间",width:"180"}),e(d,{label:"回复","min-width":"180"},{default:a(({row:l})=>[e(x,{content:l.admin_reply||"",placement:"top","show-after":300},{default:a(()=>[s("span",oe,i(l.admin_reply||"-"),1)]),_:2},1032,["content"])]),_:1}),e(d,{label:"操作",width:"220",fixed:"right"},{default:a(({row:l})=>[s("div",de,[l.status!=="closed"?(b(),k(V,{key:0},[e(f,{type:"primary",size:"small",onClick:T=>D(l)},{default:a(()=>[...t[7]||(t[7]=[u("回复",-1)])]),_:1},8,["onClick"]),e(f,{size:"small",onClick:T=>E(l)},{default:a(()=>[...t[8]||(t[8]=[u("关闭",-1)])]),_:1},8,["onClick"])],64)):O("",!0),e(f,{type:"danger",size:"small",onClick:T=>z(l)},{default:a(()=>[...t[9]||(t[9]=[u("删除",-1)])]),_:1},8,["onClick"])])]),_:1})]),_:1},8,["data"])),[[$,y.value]])])]),_:1})])}}},ue=j(ie,[["__scopeId","data-v-97c1e509"]]);export{ue as default};