feat(huya): raise recharge quantity limit to 10000

This commit is contained in:
yml2213
2026-10-17 12:35:29 +08:00
parent 82c59bb4af
commit ac2508e8dd
3 changed files with 13 additions and 11 deletions
+1 -1
View File
@@ -491,7 +491,7 @@ class RechargeMixin:
return
count = self._to_int(self.payload.get("count")) or 1
count = max(1, min(count, 999))
count = max(1, min(count, 10000))
pay_channel = self._normalize_pay_channel(
self.payload.get("pay_channel") or config_info.get("pay_channel")
)
+11 -9
View File
@@ -29,6 +29,8 @@ const ELITE_SPU_KEY = 'huya_elite_elite_spu';
// 与后端 ELITE_HANDBOOK_SPU_IDS 对齐:精英宝典单独一块,不和其他开通商品混在一个下拉里
const ELITE_HANDBOOK_SPU_IDS = ['hy-8328015', 'hy-5879340', 'hy-3845257', 'hy-2947756'];
const ELITE_HANDBOOK_NAME_KEYWORD = '精英宝典';
// 单个账号一次可开通的份数上限(与后端 clamp 对齐)
const RECHARGE_COUNT_MAX = 10000;
const TASK_LABELS: Record<string, string> = {
query_act_tasks: '读取宝典任务', get_bind_qr: '获取绑定二维码', query_game_name: '查询游戏角色',
@@ -66,10 +68,10 @@ function savedRechargeSpu(): string {
return localStorage.getItem(RECHARGE_SPU_KEY) || '';
}
/** 上次填的开通数量(后端 clamp 1~999)。 */
/** 上次填的开通数量(后端 clamp 1~10000)。 */
function savedRechargeCount(): number {
const value = Number(localStorage.getItem(RECHARGE_COUNT_KEY));
return Number.isInteger(value) && value >= 1 && value <= 999 ? value : 1;
return Number.isInteger(value) && value >= 1 && value <= RECHARGE_COUNT_MAX ? value : 1;
}
/** 上次选的精英宝典商品(就一个时基本用不上)。 */
@@ -173,7 +175,7 @@ export default function HuyaElitePage() {
const [selectedRechargeSpu, setSelectedRechargeSpu] = useState(savedRechargeSpu);
// 精英宝典单独一块:和自己的商品选择分开记
const [selectedEliteSpu, setSelectedEliteSpu] = useState(savedEliteSpu);
// 开通/充值数量:一个账号按这个份数下单(后端 payload.count,1~999),记住上次填的值
// 开通/充值数量:一个账号按这个份数下单(后端 payload.count,1~10000),记住上次填的值
const [rechargeCount, setRechargeCount] = useState(savedRechargeCount);
const [search, setSearch] = useState('');
const [loading, setLoading] = useState(false);
@@ -266,12 +268,12 @@ export default function HuyaElitePage() {
const eliteRechargeGoods = rechargeGoodsSorted.filter(isEliteHandbookGood);
const otherRechargeGoods = rechargeGoodsSorted.filter((item) => !isEliteHandbookGood(item));
const selectedEliteGoods = eliteRechargeGoods.find((item) => item.spu_id === selectedEliteSpu) || eliteRechargeGoods[0];
const rechargeEliteLimit = Math.max(1, Math.min(999, selectedEliteGoods?.buy_limit || 999));
const rechargeEliteLimit = Math.max(1, Math.min(RECHARGE_COUNT_MAX, selectedEliteGoods?.buy_limit || RECHARGE_COUNT_MAX));
// 其他开通商品的数量:上限取商品的 buy_limit(限购商品只能 1 份),
// 下单时作为后端 payload.count(1~999,走 createOrder 的 item_count)。
// 下单时作为后端 payload.count(1~10000,走 createOrder 的 item_count)。
const selectedRechargeGoods = otherRechargeGoods.find((item) => item.spu_id === selectedRechargeSpu);
const rechargeBuyLimit = Math.max(1, Math.min(999, selectedRechargeGoods?.buy_limit || 999));
const rechargeBuyLimit = Math.max(1, Math.min(RECHARGE_COUNT_MAX, selectedRechargeGoods?.buy_limit || RECHARGE_COUNT_MAX));
const rechargeCountValue = Math.max(1, Math.min(rechargeCount, rechargeBuyLimit));
const rechargeAmountText = selectedRechargeGoods?.price
? `单价 ¥${(selectedRechargeGoods.price / 100).toFixed(2)} × ${rechargeCountValue}`
@@ -279,7 +281,7 @@ export default function HuyaElitePage() {
// 换商品:按新商品的限购把数量压回合法范围,并把这次选择写进浏览器,下次进来还是它
const selectRechargeGoods = (spu: string) => {
const limit = Math.max(1, Math.min(999, otherRechargeGoods.find((item) => item.spu_id === spu)?.buy_limit || 999));
const limit = Math.max(1, Math.min(RECHARGE_COUNT_MAX, otherRechargeGoods.find((item) => item.spu_id === spu)?.buy_limit || RECHARGE_COUNT_MAX));
const nextCount = Math.max(1, Math.min(rechargeCount, limit));
setSelectedRechargeSpu(spu);
setRechargeCount(nextCount);
@@ -457,8 +459,8 @@ export default function HuyaElitePage() {
<Button size="small" type="primary" icon={<SearchOutlined />} onClick={() => void startTask('query_all')} disabled={starting || !selectedIds.length}>一键查询</Button><Button size="small" icon={<QrcodeOutlined />} onClick={() => void startTask('get_bind_qr')} disabled={starting || !selectedIds.length}>绑定二维码</Button><Button size="small" icon={<SearchOutlined />} onClick={() => void startTask('query_game_name')} disabled={starting || !selectedIds.length}>查询角色</Button><Button size="small" icon={<CheckCircleOutlined />} onClick={() => void startTask('confirm_bind')} disabled={starting || !selectedIds.length}>确认绑定</Button><Button size="small" icon={<SearchOutlined />} onClick={() => void startTask('query_points')} disabled={starting || !selectedIds.length}>刷新积分</Button><Button size="small" onClick={() => void startTask('query_act_tasks')} disabled={starting || !selectedIds.length}>宝典任务</Button><Button size="small" onClick={() => void startTask('query_exchange_records')} disabled={starting || !selectedIds.length}>兑换记录</Button>
</div></div>
<div className="huya-operation-section"><div className="huya-operation-title"><ShoppingOutlined /><span>兑换</span></div><Select size="small" showSearch optionFilterProp="label" value={selectedGoodsId || undefined} onChange={setSelectedGoodsId} options={filteredGoods.map((item) => ({ value: item.product_id, label: item.label }))} placeholder="选择兑换商品" style={{ width: '100%' }} /><div className="huya-action-grid"><Button size="small" icon={<ReloadOutlined />} onClick={() => void startTask('refresh_goods')} disabled={starting || !selectedIds.length}>刷新商品</Button><Button size="small" type="primary" icon={<ShoppingOutlined />} onClick={() => void startTask('exchange_goods')} disabled={starting || !selectedIds.length || !selectedGoodsId}>兑换商品</Button></div></div>
<div className="huya-operation-section"><div className="huya-operation-title"><GiftOutlined /><span>开通宝典</span></div>{eliteRechargeGoods.length > 1 ? <Select size="small" showSearch optionFilterProp="label" value={selectedEliteGoods?.spu_id} onChange={selectEliteGoods} options={eliteRechargeGoods.map((item) => ({ value: item.spu_id, label: rechargeGoodsLabel(item) }))} style={{ width: '100%' }} /> : <Text style={{ fontSize: 12 }} ellipsis>{selectedEliteGoods ? `${rechargeGoodsLabel(selectedEliteGoods)}${rechargeEliteLimit < 999 ? ` · 限购 ${rechargeEliteLimit} 份` : ''}` : '列表里还没有精英宝典,请先刷新开通商品'}</Text>}<Button block size="small" type="primary" icon={<QrcodeOutlined />} onClick={() => { if (selectedEliteGoods) void startTask('create_recharge_order', selectedIds, { spu: selectedEliteGoods.spu_id, count: 1 }); }} disabled={starting || !selectedIds.length || !selectedEliteGoods} style={{ marginTop: 6 }}>确认开通宝典并生成支付码</Button></div>
<div className="huya-operation-section"><div className="huya-operation-title"><ShoppingOutlined /><span>其他开通商品</span></div><Select size="small" showSearch optionFilterProp="label" value={selectedRechargeSpu || undefined} onChange={selectRechargeGoods} options={otherRechargeGoods.map((item) => ({ value: item.spu_id, label: rechargeGoodsLabel(item) }))} placeholder="先刷新开通商品" style={{ width: '100%' }} /><div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 6 }}><Text type="secondary" style={{ fontSize: 12 }}>数量</Text><InputNumber size="small" min={1} max={rechargeBuyLimit} value={rechargeCountValue} onChange={changeRechargeCount} style={{ width: 80 }} /><Text type="secondary" style={{ fontSize: 12 }}>{rechargeAmountText}{rechargeBuyLimit < 999 ? ` · 限购 ${rechargeBuyLimit} 份` : ''}</Text></div><Button block size="small" type="primary" icon={<QrcodeOutlined />} onClick={() => void startTask('create_recharge_order')} disabled={starting || !selectedIds.length || !selectedRechargeSpu} style={{ marginTop: 6 }}>{rechargeCountValue > 1 ? `确认充值并生成支付码 ×${rechargeCountValue}` : '确认充值并生成支付码'}</Button><Button block size="small" icon={<ReloadOutlined />} onClick={() => void startTask('refresh_recharge_goods')} disabled={starting || !selectedIds.length} style={{ marginTop: 6 }}>刷新开通商品</Button></div>
<div className="huya-operation-section"><div className="huya-operation-title"><GiftOutlined /><span>开通宝典</span></div>{eliteRechargeGoods.length > 1 ? <Select size="small" showSearch optionFilterProp="label" value={selectedEliteGoods?.spu_id} onChange={selectEliteGoods} options={eliteRechargeGoods.map((item) => ({ value: item.spu_id, label: rechargeGoodsLabel(item) }))} style={{ width: '100%' }} /> : <Text style={{ fontSize: 12 }} ellipsis>{selectedEliteGoods ? `${rechargeGoodsLabel(selectedEliteGoods)}${rechargeEliteLimit < RECHARGE_COUNT_MAX ? ` · 限购 ${rechargeEliteLimit} 份` : ''}` : '列表里还没有精英宝典,请先刷新开通商品'}</Text>}<Button block size="small" type="primary" icon={<QrcodeOutlined />} onClick={() => { if (selectedEliteGoods) void startTask('create_recharge_order', selectedIds, { spu: selectedEliteGoods.spu_id, count: 1 }); }} disabled={starting || !selectedIds.length || !selectedEliteGoods} style={{ marginTop: 6 }}>确认开通宝典并生成支付码</Button></div>
<div className="huya-operation-section"><div className="huya-operation-title"><ShoppingOutlined /><span>其他开通商品</span></div><Select size="small" showSearch optionFilterProp="label" value={selectedRechargeSpu || undefined} onChange={selectRechargeGoods} options={otherRechargeGoods.map((item) => ({ value: item.spu_id, label: rechargeGoodsLabel(item) }))} placeholder="先刷新开通商品" style={{ width: '100%' }} /><div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 6 }}><Text type="secondary" style={{ fontSize: 12 }}>数量</Text><InputNumber size="small" min={1} max={rechargeBuyLimit} value={rechargeCountValue} onChange={changeRechargeCount} style={{ width: 80 }} /><Text type="secondary" style={{ fontSize: 12 }}>{rechargeAmountText}{rechargeBuyLimit < RECHARGE_COUNT_MAX ? ` · 限购 ${rechargeBuyLimit} 份` : ''}</Text></div><Button block size="small" type="primary" icon={<QrcodeOutlined />} onClick={() => void startTask('create_recharge_order')} disabled={starting || !selectedIds.length || !selectedRechargeSpu} style={{ marginTop: 6 }}>{rechargeCountValue > 1 ? `确认充值并生成支付码 ×${rechargeCountValue}` : '确认充值并生成支付码'}</Button><Button block size="small" icon={<ReloadOutlined />} onClick={() => void startTask('refresh_recharge_goods')} disabled={starting || !selectedIds.length} style={{ marginTop: 6 }}>刷新开通商品</Button></div>
<RealtimeLogPanel logs={logs.logs} connected={logs.connected} title="实时日志" emptyText="暂无任务日志" height={150} collapsible defaultVisible={false} />
</Space>
);
+1 -1
View File
@@ -1787,7 +1787,7 @@ export default function HuyaTasksPage() {
<Space.Compact style={{ width: '100%' }}>
<InputNumber
min={1}
max={999}
max={10000}
value={rechargeCount}
onChange={(value) => setRechargeCount(value || 1)}
style={{ width: '100%' }}