Relax limits that do not protect payments

- Replacement links after an operator-verified decline are no longer capped
  at three; each still needs the unpaid attestation and decline evidence.
- A payment node with a transport failure cools for 30 minutes, not 6 hours.
- Review orders keep being reconciled for 7 days instead of 24 hours.
- Recovery previews stay valid for an hour instead of 10 minutes.
- Code generation allows up to 2000 per batch and moves up to 1000 codes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mizorewwwandClaude Opus 5.5 committed 2026-10-07 12:38:46 +08:00
1 parent 4310a225e1
commit 9c41404b4f
14 files changed
+21 -24

No files matched your search

+1 -1
View File
@@ -41,7 +41,7 @@ npm run preview
3. **代理(可选)**:服务器能直接访问 x.com 就选「直连」;否则准备一个代理节点。支持 sing-box 的任意 outbound 类型(anytls、socks、http、shadowsocks、vmess、vless、trojan 等),也可以直接粘贴完整 sing-box 配置。
4. **Stripe 公钥**:X 结账页面使用的 `pk_live_` 开头公钥。使用默认 X Premium 目录时向导会说明;它与商户、商品、价格一起保存在「目录」配置中,也可以完全自定义。
网络路径独立配置:X 账号与资格检查始终直连;生成付款链接所需的地区报价校验与创建链接使用同一个 `proxy` 出口,避免币种和金额因地区不同而变化;X 请求不读取环境代理;Stripe 可使用包含 `direct` 的 `payment-outbounds` 节点池。连接故障触发 6 小时冷却,安全查询最多尝试 3 个出口;付款确认不会自动重放。未配置或空数组时,新订单直连。Stripe 不读取环境代理。详见 [付款节点池配置](docs/payment-outbounds.md)。直接在浏览器打开 Stripe 链接时使用浏览器网络。
网络路径独立配置:X 账号与资格检查始终直连;生成付款链接所需的地区报价校验与创建链接使用同一个 `proxy` 出口,避免币种和金额因地区不同而变化;X 请求不读取环境代理;Stripe 可使用包含 `direct` 的 `payment-outbounds` 节点池。连接故障触发 30 分钟冷却,安全查询最多尝试 3 个出口;付款确认不会自动重放。未配置或空数组时,新订单直连。Stripe 不读取环境代理。详见 [付款节点池配置](docs/payment-outbounds.md)。直接在浏览器打开 Stripe 链接时使用浏览器网络。
另外需要:一台 Linux 服务器、一个指向该服务器的域名、服务器上安装 Go 1.27+(或在自己电脑上构建后上传二进制)。
+2 -2
View File
@@ -95,9 +95,9 @@ PY
- 以前没有节点绑定的待处理订单,在功能启用后首次访问 Stripe 时建立绑定。绑定不代表已付款。
- 明确银行卡拒付不会在同一个组合上重复扣款。金额校验、幂等、付款间隔和支付方禁止重试指令继续生效。
## 网络重试与 6 小时冷却
## 网络重试与 30 分钟冷却
- Stripe 连接失败、TLS/连接超时或成功响应中断,会把当前节点冷却 6 小时;银行卡拒付触发的是 30 分钟的出口 IP 冷却(先冷却 IP 再考虑冷却卡)。冷却按节点、服务器地址,以及最近探测到的公网 IP 共同排除;共享出口 IP 的节点一起退出可选池。`direct` 也适用。取消操作和 API 重定向拒绝不触发冷却。
- Stripe 连接失败、TLS/连接超时或成功响应中断,会把当前节点冷却 30 分钟;银行卡拒付触发的是 30 分钟的出口 IP 冷却(先冷却 IP 再考虑冷却卡)。冷却按节点、服务器地址,以及最近探测到的公网 IP 共同排除;共享出口 IP 的节点一起退出可选池。`direct` 也适用。取消操作和 API 重定向拒绝不触发冷却。
- 冷却记录保存在加密的 `payment-node-cooldown:*`,服务重启不会清除;到期自动恢复候选资格。所有节点均冷却时停止,不偷偷走未配置出口。
- **GET 查询及 `payment_pages/<session>/init` 初始化核验**可换节点重试,每个请求最多 3 次(含首次)。这不包含生成新账单的 X mutation。
- **卡信息提交、付款确认等写请求不自动重放**。即使网络出错并记录冷却,也立即返回失败/待核实状态;之后只能查询原结果,不会在别的出口重新扣款。
+1 -1
View File
@@ -157,7 +157,7 @@ function NetworkCard({
component="p"
sx={{ mt: 2 }}
>
节点连接故障后冷却 6 小时;安全查询每个请求最多尝试 3
节点连接故障后冷却 30 分钟;安全查询每个请求最多尝试 3
次;付款提交失败不自动重扣。
</Typography>
</>
+4 -4
View File
@@ -487,7 +487,7 @@ function Admin() {
<Typography variant="h2">生成兑换码</Typography>
</Stack>
<Typography variant="body2" color="text.secondary" sx={{ mb: 3 }}>
每批最多 500 枚。同名批次自动归入同一个文件夹。
每批最多 2000 枚。同名批次自动归入同一个文件夹。
</Typography>
<Box
component="form"
@@ -500,7 +500,7 @@ function Admin() {
const invalidCount =
!Number.isInteger(Number(count)) ||
Number(count) < 1 ||
Number(count) > 500;
Number(count) > 2000;
setBatchError(invalidBatch);
setCountError(invalidCount);
if (
@@ -548,9 +548,9 @@ function Admin() {
disabled={busy}
error={countError}
helperText={
countError ? "请输入 1–500 之间的整数" : "每批 1–500 枚"
countError ? "请输入 1–2000 之间的整数" : "每批 1–2000 枚"
}
slotProps={{ htmlInput: { min: 1, max: 500, step: 1 } }}
slotProps={{ htmlInput: { min: 1, max: 2000, step: 1 } }}
/>
<TextField
label="批次名称(可选)"
+1 -1
View File
@@ -13,7 +13,7 @@ import (
)
const (
paymentNodeCooldown = 6 * time.Hour
paymentNodeCooldown = 30 * time.Minute
paymentNodeDeclineCooldown = 30 * time.Minute
)
+2 -2
View File
@@ -79,8 +79,8 @@ func TestNetworkFailoverOnlyReplaysSafeRequests(t *testing.T) {
}
if until > time.Now().Unix() {
cooling++
if until < before.Add(6*time.Hour).Unix() || until > time.Now().Add(6*time.Hour).Unix() {
t.Fatal("cooldown duration not six hours")
if until < before.Add(paymentNodeCooldown).Unix() || until > time.Now().Add(paymentNodeCooldown).Unix() {
t.Fatal("cooldown duration wrong")
}
}
}
-3
View File
@@ -171,9 +171,6 @@ func replacementEvidence(v *vault.Vault, r *Record) error {
if r.Status == "succeeded" || r.Status == "requires_action" {
return errors.New("original payment is not replaceable")
}
if r.ReplacementCount >= 3 {
return errors.New("replacement link limit reached")
}
if unsubmitted(r) && r.Status == "created" {
return nil
}
+1 -1
View File
@@ -29,7 +29,7 @@
/>
<title>XGift · 兑换码管理</title>
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<script type="module" src="/admin.js?v=3d9b15f61f3e"></script>
<script type="module" src="/admin.js?v=4ca5f7113260"></script>
</head>
<body>
<div id="root"></div>
+2 -2
View File
@@ -233,9 +233,9 @@ To suppress this warning, you need to explicitly provide the \`palette.${t}Chann
transparent
)`,content:'""',position:"absolute",transform:"translateX(-100%)",bottom:0,left:0,right:0,top:0}}},{props:{animation:"wave"},style:d8||{"&::after":{animation:`${Rv} 2s linear 0.5s infinite`}}}]}})),y8=aw.forwardRef(function(t,o){let r=G({props:t,name:"MuiSkeleton"}),{animation:n="pulse",className:a,component:s="span",height:i,style:l,variant:p="text",width:c,...d}=r,f={...r,animation:n,component:s,variant:p,hasChildren:!!d.children},u=u8(f);return(0,sw.jsx)(m8,{as:s,ref:o,className:B(u.root,a),ownerState:f,...d,style:{width:c,height:i,...l}})}),Ya=y8;var th=P(L(),1);var Zp=P(L(),1);function h8(e={}){let{autoHideDuration:t=null,disableWindowBlurListener:o=!1,onClose:r,open:n,resumeHideDuration:a}=e,s=ar();Zp.useEffect(()=>{if(!n)return;function m(y){y.defaultPrevented||y.key==="Escape"&&r?.(y,"escapeKeyDown")}return document.addEventListener("keydown",m),()=>{document.removeEventListener("keydown",m)}},[n,r]);let i=zr((m,y)=>{r?.(m,y)}),l=zr(m=>{!r||m==null||s.start(m,()=>{i(null,"timeout")})});Zp.useEffect(()=>(n&&l(t),s.clear),[n,t,l,s]);let p=m=>{r?.(m,"clickaway")},c=s.clear,d=Zp.useCallback(()=>{t!=null&&l(a??t*.5)},[t,a,l]),f=m=>y=>{let h=m.onBlur;h?.(y),d()},u=m=>y=>{let h=m.onFocus;h?.(y),c()},g=m=>y=>{let h=m.onMouseEnter;h?.(y),c()},b=m=>y=>{let h=m.onMouseLeave;h?.(y),d()};return Zp.useEffect(()=>{if(!o&&n)return window.addEventListener("focus",d),window.addEventListener("blur",c),()=>{window.removeEventListener("focus",d),window.removeEventListener("blur",c)}},[o,n,d,c]),{getRootProps:(m={})=>{let y={...Cs(e),...Cs(m)};return{role:"presentation",...m,...y,onBlur:f(y),onFocus:u(y),onMouseEnter:g(y),onMouseLeave:b(y)}},onClickAway:p}}var iw=h8;var pw=P(L(),1);function lw(e){return V("MuiSnackbarContent",e)}var D0e=q("MuiSnackbarContent",["root","message","action"]);var vf=P(_(),1),g8=e=>{let{classes:t}=e;return F({root:["root"],action:["action"],message:["message"]},lw,t)},T8=M(tt,{name:"MuiSnackbarContent",slot:"Root"})(J(({theme:e})=>{let t=e.palette.mode==="light"?.8:.98;return{...e.typography.body2,color:e.vars?e.vars.palette.SnackbarContent.color:e.palette.getContrastText(Cm(e.palette.background.default,t)),backgroundColor:e.vars?e.vars.palette.SnackbarContent.bg:Cm(e.palette.background.default,t),display:"flex",alignItems:"center",flexWrap:"wrap",padding:"6px 16px",flexGrow:1,[e.breakpoints.up("sm")]:{flexGrow:"initial",minWidth:288}}})),b8=M("div",{name:"MuiSnackbarContent",slot:"Message"})({padding:"8px 0"}),v8=M("div",{name:"MuiSnackbarContent",slot:"Action"})({display:"flex",alignItems:"center",marginLeft:"auto",paddingLeft:16,marginRight:-8}),x8=pw.forwardRef(function(t,o){let r=G({props:t,name:"MuiSnackbarContent"}),{action:n,className:a,message:s,role:i="alert",...l}=r,p=r,c=g8(p);return(0,vf.jsxs)(T8,{role:i,elevation:6,className:B(c.root,a),ownerState:p,ref:o,...l,children:[(0,vf.jsx)(b8,{className:c.message,ownerState:p,children:s}),n?(0,vf.jsx)(v8,{className:c.action,ownerState:p,children:n}):null]})}),wv=x8;function cw(e){return V("MuiSnackbar",e)}var K0e=q("MuiSnackbar",["root","anchorOriginTopCenter","anchorOriginBottomCenter","anchorOriginTopRight","anchorOriginBottomRight","anchorOriginTopLeft","anchorOriginBottomLeft"]);var xf=P(_(),1),P8=e=>{let{classes:t,anchorOrigin:o}=e,r={root:["root",`anchorOrigin${I(o.vertical)}${I(o.horizontal)}`]};return F(r,cw,t)},S8=M("div",{name:"MuiSnackbar",slot:"Root",overridesResolver:(e,t)=>{let{ownerState:o}=e;return[t.root,t[`anchorOrigin${I(o.anchorOrigin.vertical)}${I(o.anchorOrigin.horizontal)}`]]}})(J(({theme:e})=>({zIndex:(e.vars||e).zIndex.snackbar,position:"fixed",display:"flex",left:8,right:8,justifyContent:"center",alignItems:"center",variants:[{props:({ownerState:t})=>t.anchorOrigin.vertical==="top",style:{top:8,[e.breakpoints.up("sm")]:{top:24}}},{props:({ownerState:t})=>t.anchorOrigin.vertical!=="top",style:{bottom:8,[e.breakpoints.up("sm")]:{bottom:24}}},{props:({ownerState:t})=>t.anchorOrigin.horizontal==="left",style:{justifyContent:"flex-start",[e.breakpoints.up("sm")]:{left:24,right:"auto"}}},{props:({ownerState:t})=>t.anchorOrigin.horizontal==="right",style:{justifyContent:"flex-end",[e.breakpoints.up("sm")]:{right:24,left:"auto"}}},{props:({ownerState:t})=>t.anchorOrigin.horizontal==="center",style:{[e.breakpoints.up("sm")]:{left:"50%",right:"auto",transform:"translateX(-50%)"}}}]}))),C8=th.forwardRef(function(t,o){let r=G({props:t,name:"MuiSnackbar"}),n=qt(),a={enter:n.transitions.duration.enteringScreen,exit:n.transitions.duration.leavingScreen},{action:s,anchorOrigin:{vertical:i,horizontal:l}={vertical:"bottom",horizontal:"left"},autoHideDuration:p=null,children:c,className:d,ClickAwayListenerProps:f,ContentProps:u,disableWindowBlurListener:g=!1,message:b,onBlur:x,onClose:m,onFocus:y,onMouseEnter:h,onMouseLeave:T,open:S,resumeHideDuration:C,slots:E={},slotProps:R={},TransitionComponent:O,transitionDuration:w=a,TransitionProps:{onEnter:A,onExited:v,...N}={},...k}=r,z={...r,anchorOrigin:{vertical:i,horizon Line truncated
${e.palette.mode==="light"?e.lighten(e.alpha(e.palette.divider,1),.88):e.darken(e.alpha(e.palette.divider,1),.68)}`,textAlign:"left",padding:16,variants:[{props:{variant:"head"},style:{color:(e.vars||e).palette.text.primary,lineHeight:e.typography.pxToRem(24),fontWeight:e.typography.fontWeightMedium}},{props:{variant:"body"},style:{color:(e.vars||e).palette.text.primary}},{props:{variant:"footer"},style:{color:(e.vars||e).palette.text.secondary,lineHeight:e.typography.pxToRem(21),fontSize:e.typography.pxToRem(12)}},{props:{size:"small"},style:{padding:"6px 16px",[`&.${_w.paddingCheckbox}`]:{width:24,padding:"0 12px 0 16px","& > *":{padding:0}}}},{props:{padding:"checkbox"},style:{width:48,padding:"0 0 0 4px"}},{props:{padding:"none"},style:{padding:0}},{props:{align:"left"},style:{textAlign:"left"}},{props:{align:"center"},style:{textAlign:"center"}},{props:{align:"right"},style:{textAlign:"right",flexDirection:"row-reverse"}},{props:{align:"justify"},style:{textAlign:"justify"}},{props:({ownerState:t})=>t.stickyHeader,style:{position:"sticky",top:0,zIndex:2,backgroundColor:(e.vars||e).palette.background.default}}]}))),mU=Rf.forwardRef(function(t,o){let r=G({props:t,name:"MuiTableCell"}),{align:n="inherit",className:a,component:s,padding:i,scope:l,size:p,sortDirection:c,variant:d,...f}=r,u=Rf.useContext(ch),g=Rf.useContext(Us),b=g&&g.variant==="head",x;s?x=s:x=b?"th":"td";let m=l;x==="td"?m=void 0:!m&&b&&(m="col");let y=d||g&&g.variant,h={...r,align:n,component:x,padding:i||(u&&u.padding?u.padding:"normal"),size:p||(u&&u.size?u.size:"medium"),sortDirection:c,stickyHeader:y==="head"&&u&&u.stickyHeader,variant:y},T=fU(h),S=null;return c&&(S=c==="asc"?"ascending":"descending"),(0,Dw.jsx)(dU,{as:x,ref:o,className:B(T.root,a),"aria-sort":S,scope:m,ownerState:h,...f})}),io=mU;var jw=P(L(),1);function zw(e){return V("MuiTableContainer",e)}var bCe=q("MuiTableContainer",["root"]);var Bw=P(_(),1),yU=e=>{let{classes:t}=e;return F({root:["root"]},zw,t)},hU=M("div",{name:"MuiTableContainer",slot:"Root"})({width:"100%",overflowX:"auto"}),gU=jw.forwardRef(function(t,o){let r=G({props:t,name:"MuiTableContainer"}),{className:n,component:a="div",...s}=r,i={...r,component:a},l=yU(i);return(0,Bw.jsx)(hU,{ref:o,as:a,className:B(l.root,n),ownerState:i,...s})}),oc=gU;var Iw=P(L(),1);function Lw(e){return V("MuiTableHead",e)}var kCe=q("MuiTableHead",["root"]);var jv=P(_(),1),TU=e=>{let{classes:t}=e;return F({root:["root"]},Lw,t)},bU=M("thead",{name:"MuiTableHead",slot:"Root"})({display:"table-header-group"}),vU={variant:"head"},Uw="thead",xU=Iw.forwardRef(function(t,o){let r=G({props:t,name:"MuiTableHead"}),{className:n,component:a=Uw,...s}=r,i={...r,component:a},l=TU(i);return(0,jv.jsx)(Us.Provider,{value:vU,children:(0,jv.jsx)(bU,{as:a,className:B(l.root,n),ref:o,role:a===Uw?null:"rowgroup",ownerState:i,...s})})}),rc=xU;var fh=P(L(),1);function $w(e){return V("MuiTableRow",e)}var PU=q("MuiTableRow",["root","selected","hover","head","footer"]),Bv=PU;var Vw=P(_(),1),SU=e=>{let{classes:t,selected:o,hover:r,head:n,footer:a}=e;return F({root:["root",o&&"selected",r&&"hover",n&&"head",a&&"footer"]},$w,t)},CU=M("tr",{name:"MuiTableRow",slot:"Root",overridesResolver:(e,t)=>{let{ownerState:o}=e;return[t.root,o.head&&t.head,o.footer&&t.footer]}})(J(({theme:e})=>({color:"inherit",display:"table-row",verticalAlign:"middle",outline:0,[`&.${Bv.hover}:hover`]:{backgroundColor:(e.vars||e).palette.action.hover},[`&.${Bv.selected}`]:{backgroundColor:e.alpha((e.vars||e).palette.primary.main,(e.vars||e).palette.action.selectedOpacity),"&:hover":{backgroundColor:e.alpha((e.vars||e).palette.primary.main,`${(e.vars||e).palette.action.selectedOpacity} + ${(e.vars||e).palette.action.hoverOpacity}`)}}}))),Hw="tr",EU=fh.forwardRef(function(t,o){let r=G({props:t,name:"MuiTableRow"}),{className:n,component:a=Hw,hover:s=!1,selected:i=!1,...l}=r,p=fh.useContext(Us),c={...r,component:a,hover:s,selected:i,head:p&&p.variant==="head",footer:p&&p.variant==="footer"},d=SU(c);return(0,Vw.jsx)(CU,{as:a,ref:o,className:B(d.root,n),role:a===Hw?null:"row",ownerState:c,...l})}),Xa=EU;var qw=P(L(),1);function Fw(e){return V("MuiTextField",e)}var s2e=q("MuiTextField",["root"]);var il=P(_(),1),RU={standard:uf,filled:pf,outlined:Tf},wU=e=>{let{classes:t}=e;return F({root:["root"]},Fw,t)},OU=M(Zb,{name:"MuiTextField",slot:"Root"})({}),NU=qw.forwardRef(function(t,o){let r=G({props:t,name:"MuiTextField"}),{autoComplete:n,autoFocus:a=!1,children:s,className:i,color:l="primary",defaultValue:p,disabled:c=!1,error:d=!1,FormHelperTextProps:f,fullWidth:u=!1,helperText:g,id:b,InputLabelProps:x,inputProps:m,InputProps:y,inputRef:h,label:T,maxRows:S,minRows:C,multiline:E=!1,name:R,onBlur:O,onChange:w,onFocus:A,placeholder:v,required:N=!1,rows:k,select:z=!1,SelectProps:j,slots:W={},slotProps:Z={},type:X,value:de,variant:me="outlined",...fe}=r,ie={...r,autoFocus:a,color:l,disabled:c,error:d,fullWidth:u,multiline:E,required:N,select:z,variant:me},we=wU(ie),Te=rn(b),le=g&&Te?`${Te}-helLine truncated
`):e[s]),o(s),n(!1)}catch{o(null),n(!0)}}return(0,hr.jsxs)(oe,{sx:{my:2},children:[(0,hr.jsxs)(ce,{direction:"row",alignItems:"center",justifyContent:"space-between",spacing:1,sx:{mb:1},children:[(0,hr.jsx)(D,{variant:"body2",color:"text.secondary",children:"\u70B9\u51FB\u5355\u679A\u5151\u6362\u7801\u5373\u53EF\u590D\u5236"}),(0,hr.jsx)(ue,{size:"small",color:"secondary",startIcon:(0,hr.jsx)(U1,{}),onClick:()=>{a("all")},sx:{px:1.5,flexShrink:0},children:"\u590D\u5236\u5168\u90E8"})]}),(0,hr.jsx)(oe,{component:"ul","aria-label":"\u65B0\u751F\u6210\u7684\u5151\u6362\u7801",tabIndex:0,sx:{m:0,p:0,listStyle:"none",maxHeight:300,overflowY:"auto",border:1,borderColor:"divider",borderRadius:2},children:e.map((s,i)=>(0,hr.jsx)(oe,{component:"li",children:(0,hr.jsx)(ue,{fullWidth:!0,"aria-label":`\u590D\u5236\u7B2C ${i+1} \u679A\u5151\u6362\u7801`,onClick:()=>{a(i)},endIcon:t===i?(0,hr.jsx)(CM,{}):(0,hr.jsx)(U1,{}),sx:{py:1.5,px:2,borderRadius:0,justifyContent:"space-between",textAlign:"left",borderBottom:i<e.length-1?1:0,borderColor:"divider",color:"text.primary",gap:1},children:(0,hr.jsx)(oe,{component:"code",sx:{fontFamily:"monospace",fontSize:".8125rem",overflowWrap:"anywhere",userSelect:"text"},children:s})})},s))}),t!==null&&(0,hr.jsx)(D,{role:"status",variant:"body2",color:"success.main",sx:{mt:1},children:t==="all"?`\u5DF2\u590D\u5236\u5168\u90E8 ${e.length} \u679A\u5151\u6362\u7801\u3002`:`\u5DF2\u590D\u5236\u7B2C ${t+1} \u679A\u5151\u6362\u7801\u3002`}),r&&(0,hr.jsx)(ze,{severity:"warning",sx:{mt:1},children:"\u6D4F\u89C8\u5668\u672A\u5141\u8BB8\u8BBF\u95EE\u526A\u8D34\u677F\u3002\u8BF7\u9009\u4E2D\u5151\u6362\u7801\u624B\u52A8\u590D\u5236\uFF0C\u6216\u4F7F\u7528\u4E0B\u65B9\u300C\u4E0B\u8F7D TXT\u300D\u3002"})]})}async function vo(e,t){let{ok:o,data:r}=await Sa(e,t);if(!o)throw new Error(r.message||"\u8BF7\u6C42\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");return r}function RM(){return vo("/api/admin/stats")}function _l(e){let t=new Date(e*1e3),o=r=>String(r).padStart(2,"0");return`${t.getFullYear()}-${o(t.getMonth()+1)}-${o(t.getDate())} ${o(t.getHours())}:${o(t.getMinutes())}:${o(t.getSeconds())}`}var hi={active:{label:"\u53EF\u4F7F\u7528",color:"primary"},processing:{label:"\u5904\u7406\u4E2D",color:"primary"},succeeded:{label:"\u5DF2\u5B8C\u6210",color:"success"},review:{label:"\u5F85\u6838\u5B9E",color:"warning"},revoked:{label:"\u5DF2\u505C\u7528",color:"default"}};var kd=P(L(),1);var wM=P(_(),1),OM=ae((0,wM.jsx)("path",{d:"m9.17 6 2 2H20v10H4V6zM10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8z"}),"FolderOutlined");var NM=P(_(),1),MM=ae((0,NM.jsx)("path",{d:"m14.06 9.02.92.92L5.92 19H5v-.92zM17.66 3c-.25 0-.51.1-.7.29l-1.83 1.83 3.75 3.75 1.83-1.83c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.2-.2-.45-.29-.71-.29m-3.6 3.19L3 17.25V21h3.75L17.81 9.94z"}),"EditOutlined");var jt=P(_(),1);function AM({folders:e,stats:t,filter:o,disabled:r,onSelect:n,onBusyChange:a,onChanged:s}){let[i,l]=(0,kd.useState)(null),[p,c]=(0,kd.useState)(""),[d,f]=(0,kd.useState)(""),[u,g]=(0,kd.useState)(!1);async function b(){if(!(!i||u)){if(!p.trim()||new TextEncoder().encode(p.trim()).length>120){f("\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u6700\u591A 120 \u5B57\u8282\u3002");return}g(!0),a(!0);try{await vo("/api/admin/folders/rename",{id:i.id,name:p.trim()}),await s(),l(null)}catch(x){f(x.message)}finally{g(!1),a(!1)}}}return(0,jt.jsxs)(oe,{sx:{mb:3},children:[(0,jt.jsxs)(ce,{direction:"row",justifyContent:"space-between",alignItems:"baseline",sx:{mb:1.5},children:[(0,jt.jsx)(D,{variant:"h2",children:"\u6279\u6B21"}),(0,jt.jsxs)(D,{variant:"body2",color:"text.secondary",children:[t?.total??"\u2014"," \u679A\u5151\u6362\u7801"]})]}),(0,jt.jsx)(D,{variant:"body2",color:"text.secondary",sx:{mb:2},children:"\u70B9\u51FB\u6279\u6B21\u6587\u4EF6\u5939\u67E5\u770B\u5151\u6362\u7801\uFF0C\u5DE6\u53F3\u6ED1\u52A8\u53EF\u67E5\u770B\u5168\u90E8\u6279\u6B21\u3002"}),(0,jt.jsx)(ce,{direction:"row",useFlexGap:!0,gap:1,sx:{minHeight:80,overflowX:"auto",alignItems:"center",pb:1},role:"region","aria-label":"\u6279\u6B21\u6587\u4EF6\u5939\uFF0C\u53EF\u6A2A\u5411\u6EDA\u52A8",tabIndex:0,children:[{id:"",name:"\u5168\u90E8\u5151\u6362\u7801",count:t?.total??0},...t?.unfiled?[{id:"unfiled",name:"\u672A\u5206\u7C7B",count:t.unfiled}]:[],...e].map(x=>(0,jt.jsxs)(oe,{sx:{display:"flex",border:1,borderColor:o===x.id?"primary.main":"divider",borderRadius:2,bgcolor:o===x.id?"action.selected":"background.paper",maxWidth:"100%",flexShrink:0},children:[(0,jt.jsxs)(ue,{disabled:r,"aria-pressed":o===x.id,startIcon:(0,jt.jsx)(OM,{}),onClick:()=>n(x.id),sx:{px:2,py:1.5,justifyContent:"flex-start",textAlign:"left",overflowWrap:"anywhere",minWidth:0},children:[x.name," \xB7 ",x.count]}),x.id&&x.id!=="unfiled"&&(0,jt.jsx)($n,{describeChild:!0,title:`\u91CD\u547D\u540D\u6279\u6B21\uFF1A${x.name}`,children:(0,jt.jsx)("span",{children:(0,jt.jsx)(sn,{"aria-label":`\u91CD\u547D\u540D\u6279\u6B21\uFF1A${x.name}`,disabled: Line truncated
`):e[s]),o(s),n(!1)}catch{o(null),n(!0)}}return(0,hr.jsxs)(oe,{sx:{my:2},children:[(0,hr.jsxs)(ce,{direction:"row",alignItems:"center",justifyContent:"space-between",spacing:1,sx:{mb:1},children:[(0,hr.jsx)(D,{variant:"body2",color:"text.secondary",children:"\u70B9\u51FB\u5355\u679A\u5151\u6362\u7801\u5373\u53EF\u590D\u5236"}),(0,hr.jsx)(ue,{size:"small",color:"secondary",startIcon:(0,hr.jsx)(U1,{}),onClick:()=>{a("all")},sx:{px:1.5,flexShrink:0},children:"\u590D\u5236\u5168\u90E8"})]}),(0,hr.jsx)(oe,{component:"ul","aria-label":"\u65B0\u751F\u6210\u7684\u5151\u6362\u7801",tabIndex:0,sx:{m:0,p:0,listStyle:"none",maxHeight:300,overflowY:"auto",border:1,borderColor:"divider",borderRadius:2},children:e.map((s,i)=>(0,hr.jsx)(oe,{component:"li",children:(0,hr.jsx)(ue,{fullWidth:!0,"aria-label":`\u590D\u5236\u7B2C ${i+1} \u679A\u5151\u6362\u7801`,onClick:()=>{a(i)},endIcon:t===i?(0,hr.jsx)(CM,{}):(0,hr.jsx)(U1,{}),sx:{py:1.5,px:2,borderRadius:0,justifyContent:"space-between",textAlign:"left",borderBottom:i<e.length-1?1:0,borderColor:"divider",color:"text.primary",gap:1},children:(0,hr.jsx)(oe,{component:"code",sx:{fontFamily:"monospace",fontSize:".8125rem",overflowWrap:"anywhere",userSelect:"text"},children:s})})},s))}),t!==null&&(0,hr.jsx)(D,{role:"status",variant:"body2",color:"success.main",sx:{mt:1},children:t==="all"?`\u5DF2\u590D\u5236\u5168\u90E8 ${e.length} \u679A\u5151\u6362\u7801\u3002`:`\u5DF2\u590D\u5236\u7B2C ${t+1} \u679A\u5151\u6362\u7801\u3002`}),r&&(0,hr.jsx)(ze,{severity:"warning",sx:{mt:1},children:"\u6D4F\u89C8\u5668\u672A\u5141\u8BB8\u8BBF\u95EE\u526A\u8D34\u677F\u3002\u8BF7\u9009\u4E2D\u5151\u6362\u7801\u624B\u52A8\u590D\u5236\uFF0C\u6216\u4F7F\u7528\u4E0B\u65B9\u300C\u4E0B\u8F7D TXT\u300D\u3002"})]})}async function vo(e,t){let{ok:o,data:r}=await Sa(e,t);if(!o)throw new Error(r.message||"\u8BF7\u6C42\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");return r}function RM(){return vo("/api/admin/stats")}function _l(e){let t=new Date(e*1e3),o=r=>String(r).padStart(2,"0");return`${t.getFullYear()}-${o(t.getMonth()+1)}-${o(t.getDate())} ${o(t.getHours())}:${o(t.getMinutes())}:${o(t.getSeconds())}`}var hi={active:{label:"\u53EF\u4F7F\u7528",color:"primary"},processing:{label:"\u5904\u7406\u4E2D",color:"primary"},succeeded:{label:"\u5DF2\u5B8C\u6210",color:"success"},review:{label:"\u5F85\u6838\u5B9E",color:"warning"},revoked:{label:"\u5DF2\u505C\u7528",color:"default"}};var kd=P(L(),1);var wM=P(_(),1),OM=ae((0,wM.jsx)("path",{d:"m9.17 6 2 2H20v10H4V6zM10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8z"}),"FolderOutlined");var NM=P(_(),1),MM=ae((0,NM.jsx)("path",{d:"m14.06 9.02.92.92L5.92 19H5v-.92zM17.66 3c-.25 0-.51.1-.7.29l-1.83 1.83 3.75 3.75 1.83-1.83c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.2-.2-.45-.29-.71-.29m-3.6 3.19L3 17.25V21h3.75L17.81 9.94z"}),"EditOutlined");var jt=P(_(),1);function AM({folders:e,stats:t,filter:o,disabled:r,onSelect:n,onBusyChange:a,onChanged:s}){let[i,l]=(0,kd.useState)(null),[p,c]=(0,kd.useState)(""),[d,f]=(0,kd.useState)(""),[u,g]=(0,kd.useState)(!1);async function b(){if(!(!i||u)){if(!p.trim()||new TextEncoder().encode(p.trim()).length>120){f("\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u6700\u591A 120 \u5B57\u8282\u3002");return}g(!0),a(!0);try{await vo("/api/admin/folders/rename",{id:i.id,name:p.trim()}),await s(),l(null)}catch(x){f(x.message)}finally{g(!1),a(!1)}}}return(0,jt.jsxs)(oe,{sx:{mb:3},children:[(0,jt.jsxs)(ce,{direction:"row",justifyContent:"space-between",alignItems:"baseline",sx:{mb:1.5},children:[(0,jt.jsx)(D,{variant:"h2",children:"\u6279\u6B21"}),(0,jt.jsxs)(D,{variant:"body2",color:"text.secondary",children:[t?.total??"\u2014"," \u679A\u5151\u6362\u7801"]})]}),(0,jt.jsx)(D,{variant:"body2",color:"text.secondary",sx:{mb:2},children:"\u70B9\u51FB\u6279\u6B21\u6587\u4EF6\u5939\u67E5\u770B\u5151\u6362\u7801\uFF0C\u5DE6\u53F3\u6ED1\u52A8\u53EF\u67E5\u770B\u5168\u90E8\u6279\u6B21\u3002"}),(0,jt.jsx)(ce,{direction:"row",useFlexGap:!0,gap:1,sx:{minHeight:80,overflowX:"auto",alignItems:"center",pb:1},role:"region","aria-label":"\u6279\u6B21\u6587\u4EF6\u5939\uFF0C\u53EF\u6A2A\u5411\u6EDA\u52A8",tabIndex:0,children:[{id:"",name:"\u5168\u90E8\u5151\u6362\u7801",count:t?.total??0},...t?.unfiled?[{id:"unfiled",name:"\u672A\u5206\u7C7B",count:t.unfiled}]:[],...e].map(x=>(0,jt.jsxs)(oe,{sx:{display:"flex",border:1,borderColor:o===x.id?"primary.main":"divider",borderRadius:2,bgcolor:o===x.id?"action.selected":"background.paper",maxWidth:"100%",flexShrink:0},children:[(0,jt.jsxs)(ue,{disabled:r,"aria-pressed":o===x.id,startIcon:(0,jt.jsx)(OM,{}),onClick:()=>n(x.id),sx:{px:2,py:1.5,justifyContent:"flex-start",textAlign:"left",overflowWrap:"anywhere",minWidth:0},children:[x.name," \xB7 ",x.count]}),x.id&&x.id!=="unfiled"&&(0,jt.jsx)($n,{describeChild:!0,title:`\u91CD\u547D\u540D\u6279\u6B21\uFF1A${x.name}`,children:(0,jt.jsx)("span",{children:(0,jt.jsx)(sn,{"aria-label":`\u91CD\u547D\u540D\u6279\u6B21\uFF1A${x.name}`,disabled: Line truncated
`)+`
`],{type:"text/plain;charset=utf-8"})),Ge=document.createElement("a");Ge.href=Q,Ge.download=`xgift-${ye.months}mo-${Date.now()}.txt`,Ge.click(),setTimeout(()=>URL.revokeObjectURL(Q),1e3)}let gr=Z&&de?de.filter(Z.match):null,Ca=gr?.length??0,Qn=Math.max(1,Math.ceil(Ca/100)),Zr=Math.min(fe,Qn-1),ve=gr?gr.slice(Zr*100,Zr*100+100):n?.codes??[],qe=ve.map(Q=>Q.id),Bt=qe.filter(Q=>E.includes(Q));return(0,$.jsxs)(mM,{admin:!0,children:[(0,$.jsxs)(ce,{direction:{xs:"column",sm:"row"},justifyContent:"space-between",alignItems:{xs:"start",sm:"center"},spacing:2,sx:{mb:4},children:[(0,$.jsxs)(oe,{children:[(0,$.jsx)(D,{variant:"h1",sx:{fontSize:{xs:30,sm:36},mt:.5},children:"\u5151\u6362\u7801\u7BA1\u7406"}),(0,$.jsx)(D,{color:"text.secondary",sx:{mt:1},children:"\u751F\u6210\u5151\u6362\u7801\u3001\u67E5\u770B\u5151\u6362\u72B6\u6001\u548C\u7BA1\u7406\u6279\u6B21\u3002"})]}),(0,$.jsxs)(ce,{direction:"row",alignItems:"center",spacing:1,children:[(0,$.jsx)(jo,{variant:"outlined",color:n?.payments_enabled?"success":"default",label:n?n.payments_enabled?"\u5145\u503C\u5DF2\u5F00\u653E":"\u7528\u6237\u5145\u503C\u5165\u53E3\u5DF2\u6682\u505C":"\u6B63\u5728\u83B7\u53D6\u670D\u52A1\u72B6\u6001"}),(0,$.jsx)(xM,{})]})]}),(0,$.jsxs)(oe,{sx:{display:"grid",gridTemplateColumns:{xs:"1fr",md:"minmax(0, 1fr) minmax(0, 1fr)"},gap:3,mb:3,alignItems:"stretch"},children:[(0,$.jsx)(YM,{selected:e,onPrepare:(Q,Ge)=>r({id:Q,mode:Ge,seq:Date.now()})}),(0,$.jsx)(KM,{disabled:c||s,refreshSignal:ot,onCopy:Q=>{Re(Q)},onViewCustomer:Q=>t({id:Q,seq:Date.now()}),onRevoke:Q=>H({kind:"revoke",code:Q})})]}),(0,$.jsx)(EA,{}),(0,$.jsx)(lA,{selection:o}),(0,$.jsx)(fA,{refreshSignal:ot}),(0,$.jsx)(AM,{folders:n?.folders??[],stats:n?.stats,filter:n?.folder??"",disabled:c||s,onSelect:Q=>{if(Z){rt(!1);let Ge=Q==="unfiled"?"\u672A\u5206\u7C7B":Q?n?.folders.find(Lt=>Lt.id===Q)?.name??"":"";Ge&&Pe(Lt=>({seq:Lt.seq+1,text:`\u7B5B\u9009\u5DF2\u6E05\u9664\uFF0C\u5DF2\u663E\u793A\u6279\u6B21\uFF1A${Ge}`}))}Ne(0,Q)},onBusyChange:Q=>{Me.current=Q,d(Q)},onChanged:async()=>{Z?Ot():await Ne(0)}}),Z&&(0,$.jsx)(D,{variant:"body2",color:"text.secondary",sx:{mt:-1.5,mb:3},children:"\u8868\u8FBE\u5F0F\u7B5B\u9009\u751F\u6548\u4E2D\uFF0C\u70B9\u51FB\u6279\u6B21\u6587\u4EF6\u5939\u53EF\u6E05\u9664\u7B5B\u9009\u5E76\u67E5\u770B\u8BE5\u6279\u6B21\u3002"}),(0,$.jsx)(qM,{value:k,onChange:Q=>{z(Q),j&&W("")},onApply:()=>{k.trim()&&Ae(k.trim())},onClear:()=>rt(),applied:!!Z,error:j,disabled:c||s,folders:n?.folders??[],appliedSource:Z?.source??"",resultCount:Z?Ca:void 0,applySeq:we,clearNotice:le}),(0,$.jsxs)(tt,{variant:"outlined",sx:{p:{xs:2.5,sm:3},mb:3},children:[(0,$.jsxs)(ce,{direction:"row",spacing:1,alignItems:"center",sx:{mb:1},children:[(0,$.jsx)(Uv,{color:"primary"}),(0,$.jsx)(D,{variant:"h2",children:"\u751F\u6210\u5151\u6362\u7801"})]}),(0,$.jsx)(D,{variant:"body2",color:"text.secondary",sx:{mb:3},children:"\u6BCF\u6279\u6700\u591A 500 \u679A\u3002\u540C\u540D\u6279\u6B21\u81EA\u52A8\u5F52\u5165\u540C\u4E00\u4E2A\u6587\u4EF6\u5939\u3002"}),(0,$.jsx)(oe,{component:"form",ref:je,noValidate:!0,onSubmit:Q=>{Q.preventDefault();let Ge=new TextEncoder().encode(x.trim()).length>120,Lt=!Number.isInteger(Number(g))||Number(g)<1||Number(g)>500;Se(Ge),Ce(Lt),!(Ge||Lt||!je.current.reportValidity()||c)&&Ft()},children:(0,$.jsxs)(oe,{sx:{display:"grid",gridTemplateColumns:{xs:"1fr",sm:"1fr 1fr",md:"1fr 1fr 2fr"},gap:2,alignItems:"start"},children:[(0,$.jsxs)(Ht,{select:!0,label:"\u5957\u9910\u65F6\u957F",value:f,onChange:Q=>u(Number(Q.target.value)),disabled:c,helperText:"\u7ED1\u5B9A\u540E\u4E0D\u53EF\u66F4\u6539",children:[(0,$.jsx)(In,{value:3,children:"3 \u4E2A\u6708 Premium"}),(0,$.jsx)(In,{value:6,children:"6 \u4E2A\u6708 Premium"})]}),(0,$.jsx)(Ht,{label:"\u751F\u6210\u6570\u91CF",type:"number",required:!0,value:g,onChange:Q=>{b(Q.target.value),De&&Ce(!1)},disabled:c,error:De,helperText:De?"\u8BF7\u8F93\u5165 1\u2013500 \u4E4B\u95F4\u7684\u6574\u6570":"\u6BCF\u6279 1\u2013500 \u679A",slotProps:{htmlInput:{min:1,max:500,step:1}}}),(0,$.jsx)(Ht,{label:"\u6279\u6B21\u540D\u79F0\uFF08\u53EF\u9009\uFF09",placeholder:"\u4F8B\u5982\uFF1A\u5341\u6708\u8D60\u793C",value:x,onChange:Q=>{m(Q.target.value),U&&Se(!1)},disabled:c,error:U,helperText:U?"\u6279\u6B21\u540D\u79F0\u4E0D\u80FD\u8D85\u8FC7 120 \u5B57\u8282\uFF08\u7EA6 40 \u4E2A\u6C49\u5B57\uFF09":"\u6279\u6B21\u540D\u79F0\u5C31\u662F\u6587\u4EF6\u5939\u540D\u79F0\uFF0C\u7559\u7A7A\u81EA\u52A8\u547D\u540D"}),(0,$.jsx)(ue,{type:"submit",variant:"contained",startIcon:(0,$.jsx)(Zw,{}),disabled:c||s||!!l,sx:{gridColumn:{sm:"1 / -1"},justifySelf:{sm:"end"}},children:c?"\u6B63\u5728\u5904\u7406\u2026":"\u751F\u6210\u5151\u6362\u7801"})]})})]}),he&&(0,$.jsx)(ze,{severity:he.error?"error":"success",role:"status",closeText:"\u5173\u95ED",onClose:he.error?void 0:()=>ge(null),sx:{mb:3},children:he.text}),ye&&(0,$.jsxs)(tt,{ref:Mt,variant:"outlined",sx:{p:3,mb:3,borderColor:"primary.main"},children:[(0,$.jsx)(D,{variant:"h2",children:"\u672C\u627 Line truncated
`],{type:"text/plain;charset=utf-8"})),Ge=document.createElement("a");Ge.href=Q,Ge.download=`xgift-${ye.months}mo-${Date.now()}.txt`,Ge.click(),setTimeout(()=>URL.revokeObjectURL(Q),1e3)}let gr=Z&&de?de.filter(Z.match):null,Ca=gr?.length??0,Qn=Math.max(1,Math.ceil(Ca/100)),Zr=Math.min(fe,Qn-1),ve=gr?gr.slice(Zr*100,Zr*100+100):n?.codes??[],qe=ve.map(Q=>Q.id),Bt=qe.filter(Q=>E.includes(Q));return(0,$.jsxs)(mM,{admin:!0,children:[(0,$.jsxs)(ce,{direction:{xs:"column",sm:"row"},justifyContent:"space-between",alignItems:{xs:"start",sm:"center"},spacing:2,sx:{mb:4},children:[(0,$.jsxs)(oe,{children:[(0,$.jsx)(D,{variant:"h1",sx:{fontSize:{xs:30,sm:36},mt:.5},children:"\u5151\u6362\u7801\u7BA1\u7406"}),(0,$.jsx)(D,{color:"text.secondary",sx:{mt:1},children:"\u751F\u6210\u5151\u6362\u7801\u3001\u67E5\u770B\u5151\u6362\u72B6\u6001\u548C\u7BA1\u7406\u6279\u6B21\u3002"})]}),(0,$.jsxs)(ce,{direction:"row",alignItems:"center",spacing:1,children:[(0,$.jsx)(jo,{variant:"outlined",color:n?.payments_enabled?"success":"default",label:n?n.payments_enabled?"\u5145\u503C\u5DF2\u5F00\u653E":"\u7528\u6237\u5145\u503C\u5165\u53E3\u5DF2\u6682\u505C":"\u6B63\u5728\u83B7\u53D6\u670D\u52A1\u72B6\u6001"}),(0,$.jsx)(xM,{})]})]}),(0,$.jsxs)(oe,{sx:{display:"grid",gridTemplateColumns:{xs:"1fr",md:"minmax(0, 1fr) minmax(0, 1fr)"},gap:3,mb:3,alignItems:"stretch"},children:[(0,$.jsx)(YM,{selected:e,onPrepare:(Q,Ge)=>r({id:Q,mode:Ge,seq:Date.now()})}),(0,$.jsx)(KM,{disabled:c||s,refreshSignal:ot,onCopy:Q=>{Re(Q)},onViewCustomer:Q=>t({id:Q,seq:Date.now()}),onRevoke:Q=>H({kind:"revoke",code:Q})})]}),(0,$.jsx)(EA,{}),(0,$.jsx)(lA,{selection:o}),(0,$.jsx)(fA,{refreshSignal:ot}),(0,$.jsx)(AM,{folders:n?.folders??[],stats:n?.stats,filter:n?.folder??"",disabled:c||s,onSelect:Q=>{if(Z){rt(!1);let Ge=Q==="unfiled"?"\u672A\u5206\u7C7B":Q?n?.folders.find(Lt=>Lt.id===Q)?.name??"":"";Ge&&Pe(Lt=>({seq:Lt.seq+1,text:`\u7B5B\u9009\u5DF2\u6E05\u9664\uFF0C\u5DF2\u663E\u793A\u6279\u6B21\uFF1A${Ge}`}))}Ne(0,Q)},onBusyChange:Q=>{Me.current=Q,d(Q)},onChanged:async()=>{Z?Ot():await Ne(0)}}),Z&&(0,$.jsx)(D,{variant:"body2",color:"text.secondary",sx:{mt:-1.5,mb:3},children:"\u8868\u8FBE\u5F0F\u7B5B\u9009\u751F\u6548\u4E2D\uFF0C\u70B9\u51FB\u6279\u6B21\u6587\u4EF6\u5939\u53EF\u6E05\u9664\u7B5B\u9009\u5E76\u67E5\u770B\u8BE5\u6279\u6B21\u3002"}),(0,$.jsx)(qM,{value:k,onChange:Q=>{z(Q),j&&W("")},onApply:()=>{k.trim()&&Ae(k.trim())},onClear:()=>rt(),applied:!!Z,error:j,disabled:c||s,folders:n?.folders??[],appliedSource:Z?.source??"",resultCount:Z?Ca:void 0,applySeq:we,clearNotice:le}),(0,$.jsxs)(tt,{variant:"outlined",sx:{p:{xs:2.5,sm:3},mb:3},children:[(0,$.jsxs)(ce,{direction:"row",spacing:1,alignItems:"center",sx:{mb:1},children:[(0,$.jsx)(Uv,{color:"primary"}),(0,$.jsx)(D,{variant:"h2",children:"\u751F\u6210\u5151\u6362\u7801"})]}),(0,$.jsx)(D,{variant:"body2",color:"text.secondary",sx:{mb:3},children:"\u6BCF\u6279\u6700\u591A 2000 \u679A\u3002\u540C\u540D\u6279\u6B21\u81EA\u52A8\u5F52\u5165\u540C\u4E00\u4E2A\u6587\u4EF6\u5939\u3002"}),(0,$.jsx)(oe,{component:"form",ref:je,noValidate:!0,onSubmit:Q=>{Q.preventDefault();let Ge=new TextEncoder().encode(x.trim()).length>120,Lt=!Number.isInteger(Number(g))||Number(g)<1||Number(g)>2e3;Se(Ge),Ce(Lt),!(Ge||Lt||!je.current.reportValidity()||c)&&Ft()},children:(0,$.jsxs)(oe,{sx:{display:"grid",gridTemplateColumns:{xs:"1fr",sm:"1fr 1fr",md:"1fr 1fr 2fr"},gap:2,alignItems:"start"},children:[(0,$.jsxs)(Ht,{select:!0,label:"\u5957\u9910\u65F6\u957F",value:f,onChange:Q=>u(Number(Q.target.value)),disabled:c,helperText:"\u7ED1\u5B9A\u540E\u4E0D\u53EF\u66F4\u6539",children:[(0,$.jsx)(In,{value:3,children:"3 \u4E2A\u6708 Premium"}),(0,$.jsx)(In,{value:6,children:"6 \u4E2A\u6708 Premium"})]}),(0,$.jsx)(Ht,{label:"\u751F\u6210\u6570\u91CF",type:"number",required:!0,value:g,onChange:Q=>{b(Q.target.value),De&&Ce(!1)},disabled:c,error:De,helperText:De?"\u8BF7\u8F93\u5165 1\u20132000 \u4E4B\u95F4\u7684\u6574\u6570":"\u6BCF\u6279 1\u20132000 \u679A",slotProps:{htmlInput:{min:1,max:2e3,step:1}}}),(0,$.jsx)(Ht,{label:"\u6279\u6B21\u540D\u79F0\uFF08\u53EF\u9009\uFF09",placeholder:"\u4F8B\u5982\uFF1A\u5341\u6708\u8D60\u793C",value:x,onChange:Q=>{m(Q.target.value),U&&Se(!1)},disabled:c,error:U,helperText:U?"\u6279\u6B21\u540D\u79F0\u4E0D\u80FD\u8D85\u8FC7 120 \u5B57\u8282\uFF08\u7EA6 40 \u4E2A\u6C49\u5B57\uFF09":"\u6279\u6B21\u540D\u79F0\u5C31\u662F\u6587\u4EF6\u5939\u540D\u79F0\uFF0C\u7559\u7A7A\u81EA\u52A8\u547D\u540D"}),(0,$.jsx)(ue,{type:"submit",variant:"contained",startIcon:(0,$.jsx)(Zw,{}),disabled:c||s||!!l,sx:{gridColumn:{sm:"1 / -1"},justifySelf:{sm:"end"}},children:c?"\u6B63\u5728\u5904\u7406\u2026":"\u751F\u6210\u5151\u6362\u7801"})]})})]}),he&&(0,$.jsx)(ze,{severity:he.error?"error":"success",role:"status",closeText:"\u5173\u95ED",onClose:he.error?void 0:()=>ge(null),sx:{mb:3},children:he.text}),ye&&(0,$.jsxs)(tt,{ref:Mt,variant:"outlined",sx:{p:3,mb:3,borderColor:"primary.main"},children:[(0,$.jsx)(D,{variant:"h2",children:"\u672C\uLine truncated
/*! Bundled license information:
react/cjs/react.production.js:
Binary file not shown.
+2 -2
View File
@@ -160,8 +160,8 @@ func (s *server) moveCodes(w http.ResponseWriter, r *http.Request) {
if !decode(w, r, &q) {
return
}
if len(q.IDs) < 1 || len(q.IDs) > 100 || (q.Folder != "" && !folderIDPattern.MatchString(q.Folder)) {
message(w, 400, "请选择 1–100 枚兑换码和有效的目标文件夹。")
if len(q.IDs) < 1 || len(q.IDs) > 1000 || (q.Folder != "" && !folderIDPattern.MatchString(q.Folder)) {
message(w, 400, "请选择 1–1000 枚兑换码和有效的目标文件夹。")
return
}
seen := map[string]bool{}
+2 -2
View File
@@ -80,7 +80,7 @@ func (s *server) reconcileLoop() {
case <-ticker.C:
}
var c codeRow
err := s.db.QueryRow("SELECT id,recipient_id,username,months,status,progress,updated FROM codes WHERE status='review' AND recipient_id IS NOT NULL AND id>? AND updated>? ORDER BY id LIMIT 1", cursor, time.Now().Add(-24*time.Hour).Unix()).Scan(&c.ID, &c.RecipientID, &c.Username, &c.Months, &c.Status, &c.Progress, &c.Updated)
err := s.db.QueryRow("SELECT id,recipient_id,username,months,status,progress,updated FROM codes WHERE status='review' AND recipient_id IS NOT NULL AND id>? AND updated>? ORDER BY id LIMIT 1", cursor, time.Now().Add(-7*24*time.Hour).Unix()).Scan(&c.ID, &c.RecipientID, &c.Username, &c.Months, &c.Status, &c.Progress, &c.Updated)
if err != nil {
cursor = ""
continue
@@ -98,7 +98,7 @@ func (s *server) reconcileLoop() {
}
func (s *server) autoChecking(c *codeRow) bool {
if c.Status != "review" || c.RecipientID == "" || c.Updated < time.Now().Add(-24*time.Hour).Unix() {
if c.Status != "review" || c.RecipientID == "" || c.Updated < time.Now().Add(-7*24*time.Hour).Unix() {
return false
}
raw, err := s.vault.Get("checkout:" + c.RecipientID)
+1 -1
View File
@@ -305,7 +305,7 @@ func (s *server) recoveryStart(w http.ResponseWriter, r *http.Request) {
reply(w, 200, map[string]any{"batch": recoveryView(q)})
return
}
if time.Now().Unix()-q.Created > 600 {
if time.Now().Unix()-q.Created > 3600 {
message(w, 409, "预览已过期,请重新生成。")
return
}
+2 -2
View File
@@ -777,8 +777,8 @@ func (s *server) generate(w http.ResponseWriter, r *http.Request) {
return
}
q.Batch = strings.TrimSpace(q.Batch)
if (q.Months != 3 && q.Months != 6) || q.Count < 1 || q.Count > 500 || len(q.Batch) > 120 || (q.Folder != "" && !folderIDPattern.MatchString(q.Folder)) {
message(w, 400, "请选择 3 或 6 个月,数量 1–500,批次名称不超过 120 字节。")
if (q.Months != 3 && q.Months != 6) || q.Count < 1 || q.Count > 2000 || len(q.Batch) > 120 || (q.Folder != "" && !folderIDPattern.MatchString(q.Folder)) {
message(w, 400, "请选择 3 或 6 个月,数量 1–2000,批次名称不超过 120 字节。")
return
}
if q.Batch == "" {