(null);
@@ -1653,7 +1721,7 @@ export default function DouyuTasksPage({ handbook }: { handbook: HandbookKind })
|| selectedXpdGoodsSoldOut
|| !xpdPaymentOptions.some((option) => option.value === xpdPayType);
}
- if (['exchange_goods', 'exchange_esports_goods'].includes(taskType)) return !selectedGoodsId;
+ if (['lock_goods', 'exchange_goods', 'exchange_esports_goods'].includes(taskType)) return !selectedGoodsId;
// 选中账号中有正在执行的任务时禁用,避免同账号并发不同类型任务(并发写状态字段)
return selectedHasRunning;
};
@@ -1854,6 +1922,7 @@ export default function DouyuTasksPage({ handbook }: { handbook: HandbookKind })
/>
{renderActionButton('refresh_goods')}
+ {renderActionButton('lock_goods')}
{renderActionButton('exchange_goods', 'primary')}
diff --git a/web/frontend/src/utils/exchangeImage.ts b/web/frontend/src/utils/exchangeImage.ts
index 5c62e04..31c0a39 100644
--- a/web/frontend/src/utils/exchangeImage.ts
+++ b/web/frontend/src/utils/exchangeImage.ts
@@ -1,6 +1,11 @@
import type { DouyuTaskItem } from '../api/types';
-const EXCHANGE_TASK_TYPES = new Set(['exchange_goods', 'exchange_esports_goods', 'exchange_xpd_goods']);
+const EXCHANGE_TASK_TYPES = new Set([
+ 'exchange_goods',
+ 'pay_locked_order',
+ 'exchange_esports_goods',
+ 'exchange_xpd_goods',
+]);
const CARD_W = 320;
const CARD_H = 470;
const FONT_FAMILY = '"PingFang SC", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif';
@@ -29,11 +34,14 @@ function goodsOf(task: DouyuTaskItem): {
const name = (rawString(goods, 'commodityName')
|| rawString(goods, 'name')
|| rawString(goods, 'sGoodsName')
- || task.message.replace(/^兑换[^::]*[::]?\s*/, '').trim()
+ || task.message.replace(/^(?:兑换[^::]*|锁单支付成功)[::]?\s*/, '').trim()
|| rawString(task.result, 'commodity_id'))
.replace(/[((]\d+\s*(?:点券|碎片|积分)[))]\s*$/, '')
.trim();
- const pic = rawString(goods, 'webPic') || rawString(goods, 'pic') || rawString(goods, 'sGoodsPic');
+ const pic = rawString(goods, 'webPic')
+ || rawString(goods, 'pic')
+ || rawString(goods, 'sGoodsPic')
+ || rawString(task.result, 'commodity_image');
const roleName = rawString(task.result, 'game_name');
const channel = rawString(task.result, 'game_channel');
const accountName = rawString(task.result, 'account_name')