refactor(claim): 删除自建皮肤领取页,路径式 /claim/<token> 复用现成领取页 + 物品图片
**删掉上一轮自建的领取页** - `pages/claim-skin/*`、`services/claim-skin.ts`、`types/claim-skin.ts`、`tests/claim-skin.test.ts` 及其样式(client.css 里 `.claim-skin-*` 整段 254 行) - 后台我加的展示项:「皮肤自动发货」筛选项、执行器标签、「买家提交信息」卡片 **路径式链接复用现成领取页** - `utils/claim-path.ts`(中性命名 `isClaimPath` / `resolveClaimToken`)+ 单测 - `App.tsx`:pathname 命中 `/claim/<token>` → 独立 BrowserRouter 渲染**现成的 `ClaimPage`** (页面零复制零改动:它只用 `useParams`,不读 hash);`#/claim/:token` 仍走主站 HashRouter, 两者互不影响,且有用例断言 hash 入口不命中路径判定 **物品图片** - 后端领取详情的 `product.imageUrl` 接上(内部 SKU 在 `spec_json.code` / `sku_code` / `sku_name` 哪个字段都能回退找到图,映射不到返回空串) - 领取页新增 `ClaimProductImage`:居中大图(宽度 min(220px,62%)、圆角 16px), 空值或加载失败都降级虚线占位块,不出现破图 `npm run check`:前端 128 / 128 全绿(去掉旧用例 17 个、新增路径与图片用例)
This commit is contained in:
@@ -434,6 +434,31 @@
|
||||
background: rgba(248, 250, 252, 0.72);
|
||||
}
|
||||
|
||||
/* 待领取物品图:居中大图;imageUrl 为空或加载失败时是同一尺寸的虚线占位块(不会出现破图) */
|
||||
|
||||
.claim-product-image-wrap {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.claim-product-image {
|
||||
width: min(220px, 62%);
|
||||
aspect-ratio: 1 / 1;
|
||||
border-radius: 16px;
|
||||
object-fit: cover;
|
||||
background: #f1f5f9;
|
||||
border: 1px solid rgba(148, 163, 184, 0.24);
|
||||
}
|
||||
|
||||
.claim-product-image-fallback {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 46px;
|
||||
color: rgba(100, 116, 139, 0.55);
|
||||
border-style: dashed;
|
||||
}
|
||||
|
||||
/* ===== 收集页 (Collect Page) ===== */
|
||||
|
||||
.collect-page {
|
||||
@@ -472,260 +497,6 @@
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* ===== 买家皮肤领取页 (Skin Claim Page) =====
|
||||
路径式入口 `/claim/<token>`:按竞品的深色玻璃质感卡片做,
|
||||
但主按钮沿用仓库主题色 `--theme-primary`(橙色渐变),与 /redeem 的主色保持协调。
|
||||
所有覆盖都挂在 `.claim-skin-page` 下,保证优先级高于 antd 的运行时样式。 */
|
||||
|
||||
.claim-skin-page {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 28px 16px 40px;
|
||||
background: radial-gradient(120% 70% at 50% 0%, #27334f 0%, #141b2d 52%, #0b1020 100%);
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
.claim-skin-shell {
|
||||
width: min(480px, 100%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.claim-skin-head {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.claim-skin-page .claim-skin-title {
|
||||
margin: 0 !important;
|
||||
color: #f8fafc;
|
||||
font-size: 22px;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.claim-skin-subtitle {
|
||||
margin: 8px 0 0;
|
||||
color: rgba(226, 232, 240, 0.72);
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.claim-skin-page .claim-skin-card {
|
||||
border: 1px solid rgba(148, 163, 184, 0.22);
|
||||
border-radius: 16px;
|
||||
background: rgba(15, 23, 42, 0.66);
|
||||
box-shadow: 0 18px 40px rgba(2, 6, 23, 0.45);
|
||||
backdrop-filter: blur(12px);
|
||||
}
|
||||
|
||||
.claim-skin-card .ant-card-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
padding: 20px 18px;
|
||||
}
|
||||
|
||||
/* --- 物品卡片 --- */
|
||||
|
||||
.claim-skin-item-image-wrap {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.claim-skin-item-image {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
border-radius: 16px;
|
||||
object-fit: cover;
|
||||
background: rgba(148, 163, 184, 0.12);
|
||||
border: 1px solid rgba(148, 163, 184, 0.24);
|
||||
}
|
||||
|
||||
.claim-skin-item-image-fallback {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 46px;
|
||||
color: rgba(148, 163, 184, 0.55);
|
||||
border-style: dashed;
|
||||
}
|
||||
|
||||
.claim-skin-item-name {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
color: #f1f5f9;
|
||||
font-size: 19px;
|
||||
font-weight: 700;
|
||||
line-height: 1.4;
|
||||
text-align: center;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.claim-skin-item-qty {
|
||||
flex: 0 0 auto;
|
||||
color: #ffb27a;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.claim-skin-item-meta {
|
||||
margin: 0;
|
||||
color: rgba(148, 163, 184, 0.92);
|
||||
font-size: 12px;
|
||||
line-height: 1.6;
|
||||
text-align: center;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.claim-skin-item-meta-sub {
|
||||
color: rgba(148, 163, 184, 0.62);
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
/* --- 表单卡片 --- */
|
||||
|
||||
.claim-skin-page .claim-skin-form-title {
|
||||
margin: 0 !important;
|
||||
color: #f8fafc;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.claim-skin-form-card .ant-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.claim-skin-form-card .ant-form-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.claim-skin-form-card .ant-form-item-label > label {
|
||||
color: rgba(226, 232, 240, 0.86);
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.claim-skin-field .ant-input {
|
||||
background: rgba(8, 13, 26, 0.6);
|
||||
border-color: rgba(148, 163, 184, 0.3);
|
||||
color: #f1f5f9;
|
||||
}
|
||||
|
||||
.claim-skin-field .ant-input::placeholder {
|
||||
color: rgba(148, 163, 184, 0.62);
|
||||
}
|
||||
|
||||
.claim-skin-field .ant-input-affix-wrapper {
|
||||
background: rgba(8, 13, 26, 0.6);
|
||||
border-color: rgba(148, 163, 184, 0.3);
|
||||
}
|
||||
|
||||
.claim-skin-field .ant-input-affix-wrapper > input.ant-input {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.claim-skin-field .ant-input-affix-wrapper .anticon {
|
||||
color: rgba(148, 163, 184, 0.72);
|
||||
}
|
||||
|
||||
.claim-skin-form-hint {
|
||||
margin: 0;
|
||||
color: rgba(253, 186, 116, 0.9);
|
||||
font-size: 12px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.claim-skin-page .claim-skin-submit.ant-btn {
|
||||
height: 48px;
|
||||
border: none;
|
||||
border-radius: 14px;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
background: linear-gradient(135deg, #ff8a3d 0%, var(--theme-primary) 100%);
|
||||
box-shadow: 0 12px 24px var(--theme-primary-shadow);
|
||||
}
|
||||
|
||||
.claim-skin-page .claim-skin-submit.ant-btn:hover:not(:disabled) {
|
||||
background: linear-gradient(135deg, #ff9a55 0%, var(--theme-primary-hover) 100%);
|
||||
}
|
||||
|
||||
.claim-skin-page .claim-skin-submit.ant-btn:disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* --- 提示 / 成功态 --- */
|
||||
|
||||
.claim-skin-state .ant-result {
|
||||
padding: 8px 0 0;
|
||||
}
|
||||
|
||||
.claim-skin-state .ant-result-title {
|
||||
color: #f8fafc;
|
||||
font-size: 19px;
|
||||
}
|
||||
|
||||
.claim-skin-state .ant-result-subtitle {
|
||||
color: rgba(226, 232, 240, 0.72);
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.claim-skin-state-desc {
|
||||
margin: 0;
|
||||
color: rgba(226, 232, 240, 0.72);
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.claim-skin-contact-tip {
|
||||
margin: 0;
|
||||
color: rgba(253, 186, 116, 0.9);
|
||||
font-size: 12px;
|
||||
line-height: 1.6;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.claim-skin-account-line {
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
padding: 12px;
|
||||
border-radius: 12px;
|
||||
background: rgba(8, 13, 26, 0.55);
|
||||
border: 1px solid rgba(148, 163, 184, 0.22);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.claim-skin-account-line span {
|
||||
color: rgba(148, 163, 184, 0.9);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.claim-skin-account-line strong {
|
||||
color: #f8fafc;
|
||||
font-size: 18px;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.claim-skin-page {
|
||||
padding: 18px 12px 32px;
|
||||
}
|
||||
|
||||
.claim-skin-card .ant-card-body {
|
||||
gap: 12px;
|
||||
padding: 16px 14px;
|
||||
}
|
||||
|
||||
.claim-skin-item-image {
|
||||
width: 140px;
|
||||
height: 140px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== 买家页面响应式断点 ===== */
|
||||
|
||||
@media (max-width: 720px) {
|
||||
|
||||
Reference in New Issue
Block a user