style(distribution): 完成分销后台品牌与登录页轻改

This commit is contained in:
yml2213
2026-10-30 12:52:38 +08:00
parent e8a20ebea7
commit d96e07e2d3
22 changed files with 343 additions and 88 deletions
+3 -1
View File
@@ -3,7 +3,9 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>分销网管理后台</title>
<meta name="theme-color" content="#1E4D42" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>解忧商行 · 分销管理后台</title>
</head>
<body>
<div id="root"></div>
+2 -2
View File
@@ -1,11 +1,11 @@
{
"name": "hfb-distribution-admin",
"name": "jieyou-distribution-admin",
"version": "0.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "hfb-distribution-admin",
"name": "jieyou-distribution-admin",
"version": "0.1.0",
"dependencies": {
"@ant-design/icons": "^6.0.0",
+1 -1
View File
@@ -1,5 +1,5 @@
{
"name": "hfb-distribution-admin",
"name": "jieyou-distribution-admin",
"private": true,
"version": "0.1.0",
"type": "module",
+8
View File
@@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-labelledby="title desc">
<title id="title">解忧商行印章</title>
<desc id="desc">解忧商行方形朱砂印章</desc>
<rect x="2" y="2" width="60" height="60" rx="8" fill="#A64332"/>
<rect x="7" y="7" width="50" height="50" rx="3" fill="none" stroke="#ECD0B1" stroke-width="1.4"/>
<text x="32" y="31" text-anchor="middle" font-family="'Noto Serif SC','Source Han Serif SC','Songti SC',serif" font-size="20" font-weight="700" fill="#FFFDF8">解</text>
<text x="32" y="52" text-anchor="middle" font-family="'Noto Serif SC','Source Han Serif SC','Songti SC',serif" font-size="20" font-weight="700" fill="#FFFDF8">忧</text>
</svg>

After

Width:  |  Height:  |  Size: 722 B

+33 -9
View File
@@ -20,6 +20,7 @@ import {
TeamOutlined,
} from '@ant-design/icons'
import { getMe, logout, type CurrentMember, getStoredToken } from './api'
import { BrandLogo } from './BrandLogo'
import { MemberContext } from './MemberContext'
import Dashboard from './pages/Dashboard'
import Sites from './pages/Sites'
@@ -89,11 +90,12 @@ function MainLayout({ member, onLogout }: { member: CurrentMember; onLogout: ()
return (
<MemberContext.Provider value={member}>
<Layout className="app">
<Layout.Sider breakpoint="lg" collapsedWidth="0" className="app-sider" width={220}>
<Layout.Sider breakpoint="lg" collapsedWidth="0" className="app-sider" width={232}>
<div className="brand">
<ShopOutlined style={{ fontSize: 20, color: '#1677ff' }} />
<span>HFB 分销后台</span>
<BrandLogo height={30} variant="dark" />
<span className="brand__tag">分销台</span>
</div>
<div className="brand__sub">JIEYOU DISTRIBUTION</div>
<Menu
theme="dark"
mode="inline"
@@ -109,12 +111,12 @@ function MainLayout({ member, onLogout }: { member: CurrentMember; onLogout: ()
平台全局管理模式
</Tag>
) : (
<Tag color="blue" style={{ fontSize: 13, padding: '2px 8px' }}>
<Tag color="green" style={{ fontSize: 13, padding: '2px 8px' }}>
{member.site_name || '当前分销站点'} · {member.domain || member.site_code}
</Tag>
)}
<Typography.Text type="secondary" style={{ fontSize: 12 }}>
主站 zuhaoc.com · 分销管理系统
解忧商行 · 主站 zuhaoc.com · 分销运营台
</Typography.Text>
</div>
<div className="header-right">
@@ -134,13 +136,13 @@ function MainLayout({ member, onLogout }: { member: CurrentMember; onLogout: ()
: `/?site=${member.site_code}`
window.open(targetUrl, '_blank')
}}
style={{ borderColor: '#1677ff', color: '#1677ff' }}
style={{ borderColor: 'var(--brand-ink)', color: 'var(--brand-ink)' }}
>
预览分销前台商城 ↗
</Button>
)}
<div className="user-profile">
<UserOutlined style={{ color: '#1677ff' }} />
<UserOutlined style={{ color: 'var(--brand-ink)' }} />
<Typography.Text strong style={{ fontSize: 13 }}>
{member.nickname || member.username}
</Typography.Text>
@@ -283,8 +285,30 @@ export default function AppShell() {
<ConfigProvider
theme={{
token: {
colorPrimary: '#1677ff',
borderRadius: 6,
colorPrimary: '#1e4d42',
colorInfo: '#1e4d42',
colorSuccess: '#2f7d5c',
colorWarning: '#c17a2b',
colorError: '#a64332',
colorBgLayout: '#f6f2e8',
colorBorderSecondary: '#e4ded2',
borderRadius: 8,
fontFamily:
"'Noto Sans SC', 'Source Han Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif",
},
components: {
Layout: {
siderBg: '#153a32',
headerBg: '#fffdf8',
},
Menu: {
darkItemBg: 'transparent',
darkSubMenuItemBg: 'transparent',
darkItemColor: 'rgba(240, 244, 242, 0.72)',
darkItemHoverBg: 'rgba(236, 208, 177, 0.08)',
darkItemSelectedBg: 'rgba(236, 208, 177, 0.16)',
darkItemSelectedColor: '#ecd0b1',
},
},
}}
>
+28
View File
@@ -0,0 +1,28 @@
import logoDark from './assets/brand/logo-dark.svg'
import logoLight from './assets/brand/logo-light.svg'
import logoSeal from './assets/brand/logo-seal.svg'
export type BrandLogoVariant = 'light' | 'dark' | 'seal'
interface BrandLogoProps {
height?: number
variant?: BrandLogoVariant
className?: string
}
const logoSources: Record<BrandLogoVariant, string> = {
light: logoLight,
dark: logoDark,
seal: logoSeal,
}
export function BrandLogo({ height = 36, variant = 'light', className }: BrandLogoProps) {
return (
<img
src={logoSources[variant]}
alt="解忧商行 JIEYOU TRADING HOUSE"
className={className}
style={{ height, width: 'auto', display: 'block' }}
/>
)
}
@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 80" role="img" aria-labelledby="title desc">
<title id="title">解忧商行</title>
<desc id="desc">解忧商行横版 logo,深色背景反白使用</desc>
<rect x="2" y="10" width="60" height="60" rx="7" fill="#A64332"/>
<rect x="7" y="15" width="50" height="50" rx="3" fill="none" stroke="#ECD0B1" stroke-width="1.2"/>
<text x="32" y="39" text-anchor="middle" font-family="'Noto Serif SC','Source Han Serif SC','Songti SC',serif" font-size="20" font-weight="700" fill="#FFFDF8">解</text>
<text x="32" y="60" text-anchor="middle" font-family="'Noto Serif SC','Source Han Serif SC','Songti SC',serif" font-size="20" font-weight="700" fill="#FFFDF8">忧</text>
<text x="78" y="46" font-family="'Noto Serif SC','Source Han Serif SC','Songti SC',serif" font-size="34" font-weight="600" letter-spacing="4" fill="#F0F4F2">解忧商行</text>
<text x="80" y="66" font-family="'Inter','PingFang SC',sans-serif" font-size="9.5" font-weight="500" letter-spacing="2.8" fill="#ECD0B1">JIEYOU TRADING HOUSE</text>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 80" role="img" aria-labelledby="title desc">
<title id="title">解忧商行</title>
<desc id="desc">解忧商行横版 logo,浅色背景使用</desc>
<rect x="2" y="10" width="60" height="60" rx="7" fill="#A64332"/>
<rect x="7" y="15" width="50" height="50" rx="3" fill="none" stroke="#ECD0B1" stroke-width="1.2"/>
<text x="32" y="39" text-anchor="middle" font-family="'Noto Serif SC','Source Han Serif SC','Songti SC',serif" font-size="20" font-weight="700" fill="#FFFDF8">解</text>
<text x="32" y="60" text-anchor="middle" font-family="'Noto Serif SC','Source Han Serif SC','Songti SC',serif" font-size="20" font-weight="700" fill="#FFFDF8">忧</text>
<text x="78" y="46" font-family="'Noto Serif SC','Source Han Serif SC','Songti SC',serif" font-size="34" font-weight="600" letter-spacing="4" fill="#1E4D42">解忧商行</text>
<text x="80" y="66" font-family="'Inter','PingFang SC',sans-serif" font-size="9.5" font-weight="500" letter-spacing="2.8" fill="#6F857C">JIEYOU TRADING HOUSE</text>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-labelledby="title desc">
<title id="title">解忧商行印章</title>
<desc id="desc">解忧商行方形朱砂印章</desc>
<rect x="2" y="2" width="60" height="60" rx="8" fill="#A64332"/>
<rect x="7" y="7" width="50" height="50" rx="3" fill="none" stroke="#ECD0B1" stroke-width="1.4"/>
<text x="32" y="31" text-anchor="middle" font-family="'Noto Serif SC','Source Han Serif SC','Songti SC',serif" font-size="20" font-weight="700" fill="#FFFDF8">解</text>
<text x="32" y="52" text-anchor="middle" font-family="'Noto Serif SC','Source Han Serif SC','Songti SC',serif" font-size="20" font-weight="700" fill="#FFFDF8">忧</text>
</svg>

After

Width:  |  Height:  |  Size: 722 B

+6 -6
View File
@@ -596,7 +596,7 @@ export default function Accounts() {
icon={<SyncOutlined spin={syncing} />}
loading={syncing}
onClick={handleOpenSyncModal}
style={{ background: '#1677ff' }}
style={{ background: '#1e4d42' }}
>
一键同步主站商品
</Button>
@@ -660,7 +660,7 @@ export default function Accounts() {
{/* Batch actions */}
{selectedRowKeys.length > 0 && (
<Space>
<Typography.Text strong style={{ color: '#1677ff' }}>
<Typography.Text strong style={{ color: '#1e4d42' }}>
已选 {selectedRowKeys.length} 项
</Typography.Text>
<Button
@@ -776,7 +776,7 @@ export default function Accounts() {
className="mono-code"
style={{
fontSize: 13,
color: '#1677ff',
color: '#1e4d42',
whiteSpace: 'nowrap',
wordBreak: 'keep-all',
display: 'inline-flex',
@@ -1004,7 +1004,7 @@ export default function Accounts() {
</Col>
<Col span={12}>
<Typography.Text type="secondary">主站基准价:</Typography.Text>
<strong style={{ color: '#1677ff' }}>¥{((targetAccount.price_cent || 0) / 100).toFixed(2)}</strong>
<strong style={{ color: '#1e4d42' }}>¥{((targetAccount.price_cent || 0) / 100).toFixed(2)}</strong>
</Col>
<Col span={12}>
<Typography.Text type="secondary">主站基准比例:</Typography.Text>
@@ -1265,7 +1265,7 @@ export default function Accounts() {
<Modal
title={
<Space>
<SyncOutlined style={{ color: '#1677ff' }} />
<SyncOutlined style={{ color: '#1e4d42' }} />
<span>一键同步主站商品设置</span>
</Space>
}
@@ -1362,7 +1362,7 @@ export default function Accounts() {
<Statistic
title="已在货架保持"
value={syncResult?.skipped_count ?? 0}
valueStyle={{ color: '#1677ff', fontWeight: 'bold' }}
valueStyle={{ color: '#1e4d42', fontWeight: 'bold' }}
suffix="个"
/>
</Card>
@@ -235,7 +235,7 @@ export default function Announcements() {
<Card>
<Space direction="vertical" size="small" style={{ width: '100%' }}>
<Space align="center" size={8}>
<BellOutlined style={{ color: '#1677ff' }} />
<BellOutlined style={{ color: '#1e4d42' }} />
<Typography.Title level={4} style={{ margin: 0 }}>
公告中心
</Typography.Title>
+5 -5
View File
@@ -260,7 +260,7 @@ export default function Dashboard() {
title="今日收号 / 累计收号"
value={analytics?.today_received_count ?? 0}
suffix={`/ ${analytics?.total_received_count ?? 0} 个`}
valueStyle={{ color: '#1677ff', fontWeight: 'bold' }}
valueStyle={{ color: '#1e4d42', fontWeight: 'bold' }}
/>
<div style={{ marginTop: 8 }}>
<Link to="/receive" style={{ fontSize: 12 }}>查看收号资产 <ArrowRightOutlined /></Link>
@@ -300,9 +300,9 @@ export default function Dashboard() {
<Statistic
title="钱包可提现余额"
value={((analytics?.available_balance_cent ?? 0) / 100).toFixed(2)}
prefix={<WalletOutlined style={{ color: '#1677ff' }} />}
prefix={<WalletOutlined style={{ color: '#1e4d42' }} />}
suffix="元"
valueStyle={{ color: '#1677ff', fontWeight: 'bold' }}
valueStyle={{ color: '#1e4d42', fontWeight: 'bold' }}
/>
<div style={{ marginTop: 8 }}>
<Link to="/wallet" style={{ fontSize: 12 }}>立即提现 <ArrowRightOutlined /></Link>
@@ -422,7 +422,7 @@ export default function Dashboard() {
className="mono-code"
style={{
fontSize: 13,
color: '#1677ff',
color: '#1e4d42',
fontWeight: 600,
whiteSpace: 'nowrap',
wordBreak: 'keep-all',
@@ -461,7 +461,7 @@ export default function Dashboard() {
title: '实付金额',
width: 120,
render: (_: unknown, row: DistributionOrder) => (
<Typography.Text strong style={{ color: '#1677ff', fontSize: 15, whiteSpace: 'nowrap' }}>
<Typography.Text strong style={{ color: '#1e4d42', fontSize: 15, whiteSpace: 'nowrap' }}>
{formatMoney(row.net_paid_amount_cent || row.gross_paid_amount_cent || 0)}
</Typography.Text>
),
+24 -7
View File
@@ -1,7 +1,8 @@
import { useState } from 'react'
import { Card, Form, Input, Button, Alert, Typography, Space } from 'antd'
import { UserOutlined, LockOutlined, SafetyCertificateOutlined } from '@ant-design/icons'
import { UserOutlined, LockOutlined } from '@ant-design/icons'
import { login, type CurrentMember } from '../api'
import { BrandLogo } from '../BrandLogo'
interface LoginProps {
onSuccess: (member: CurrentMember) => void
@@ -28,16 +29,32 @@ export default function Login({ onSuccess }: LoginProps) {
return (
<div className="login-container">
<aside className="login-brand">
<BrandLogo height={46} variant="light" className="login-brand__logo" />
<div className="login-brand__eyebrow">JIEYOU · DISTRIBUTION</div>
<h1>
分销运营台
<span>把站点、订单与结算放在一处</span>
</h1>
<p>独立站点、独立流水与周期对账。每一笔分销收益都能回溯到订单。</p>
<ul>
<li>多站点隔离,权限按角色收敛</li>
<li>订单归属与分成比例逐单留痕</li>
<li>结算批次、钱包与提现统一核对</li>
</ul>
<span className="login-brand__seal">解忧</span>
</aside>
<Card className="login-card" bordered={false}>
<div className="login-header">
<div className="login-logo">
<SafetyCertificateOutlined style={{ fontSize: 32, color: '#1677ff' }} />
<div className="login-header__mobile-logo">
<BrandLogo height={34} />
</div>
<Typography.Title level={3} style={{ margin: '12px 0 4px' }}>
HFB 分销系统
<Typography.Title level={3} style={{ margin: '0 0 6px' }}>
登录分销台
</Typography.Title>
<Typography.Text type="secondary">
独立分销商 · 多站点综合管理后台
使用分销管理员账号进入 · distribution.zuhaoc.com
</Typography.Text>
</div>
@@ -83,7 +100,7 @@ export default function Login({ onSuccess }: LoginProps) {
block
style={{ height: 44, fontWeight: 500 }}
>
登录分销后台
进入解忧分销台
</Button>
</Form.Item>
</Form>
+6 -6
View File
@@ -348,7 +348,7 @@ export default function Orders({ kind }: { kind: 'all' | 'sold' | 'receive' }) {
copyable={{ text: row.listing_no }}
style={{
fontSize: 13,
color: '#1677ff',
color: '#1e4d42',
fontWeight: 600,
fontFamily: 'monospace',
whiteSpace: 'nowrap',
@@ -406,7 +406,7 @@ export default function Orders({ kind }: { kind: 'all' | 'sold' | 'receive' }) {
const netPaid = row.net_paid_amount_cent || row.gross_paid_amount_cent || 0
return (
<div>
<Typography.Text strong style={{ color: '#1677ff', fontSize: 15, whiteSpace: 'nowrap', display: 'block' }}>
<Typography.Text strong style={{ color: '#1e4d42', fontSize: 15, whiteSpace: 'nowrap', display: 'block' }}>
{formatMoney(netPaid)}
</Typography.Text>
{row.deposit_amount_cent ? (
@@ -611,7 +611,7 @@ export default function Orders({ kind }: { kind: 'all' | 'sold' | 'receive' }) {
strong
style={{
fontSize: 13,
color: '#1677ff',
color: '#1e4d42',
fontFamily: 'monospace',
whiteSpace: 'nowrap',
display: 'inline-flex',
@@ -908,7 +908,7 @@ export default function Orders({ kind }: { kind: 'all' | 'sold' | 'receive' }) {
).toFixed(2)}
precision={2}
prefix="¥"
valueStyle={{ color: '#1677ff' }}
valueStyle={{ color: '#1e4d42' }}
/>
</Col>
<Col span={8}>
@@ -952,7 +952,7 @@ export default function Orders({ kind }: { kind: 'all' | 'sold' | 'receive' }) {
copyable={{ text: selectedOrder.listing_no, tooltips: ['复制商品编号', '已复制'] }}
strong
className="mono-code"
style={{ color: '#1677ff', fontSize: 13, whiteSpace: 'nowrap', wordBreak: 'keep-all', display: 'inline-flex', alignItems: 'center' }}
style={{ color: '#1e4d42', fontSize: 13, whiteSpace: 'nowrap', wordBreak: 'keep-all', display: 'inline-flex', alignItems: 'center' }}
>
{selectedOrder.listing_no}
</Typography.Text>
@@ -1040,7 +1040,7 @@ export default function Orders({ kind }: { kind: 'all' | 'sold' | 'receive' }) {
>
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 8 }}>
<span style={{ color: '#595959' }}>1. 租客实付租金总额:</span>
<strong style={{ color: '#1677ff' }}>
<strong style={{ color: '#1e4d42' }}>
¥
{(
(selectedOrder.net_paid_amount_cent || selectedOrder.gross_paid_amount_cent || 0) /
+2 -2
View File
@@ -146,8 +146,8 @@ export default function Rules() {
>
<Space direction="vertical" style={{ width: '100%' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<DollarCircleOutlined style={{ color: '#1677ff', fontSize: 20 }} />
<Typography.Text strong style={{ fontSize: 16, color: '#0958d9' }}>
<DollarCircleOutlined style={{ color: '#1e4d42', fontSize: 20 }} />
<Typography.Text strong style={{ fontSize: 16, color: '#153a32' }}>
卖号分成 40%
</Typography.Text>
</div>
@@ -625,7 +625,7 @@ export default function SiteSettings() {
<Space direction="vertical" style={{ width: '100%' }} size="middle">
<div>
<Space align="center">
<MessageOutlined style={{ fontSize: 18, color: '#1677ff' }} />
<MessageOutlined style={{ fontSize: 18, color: '#1e4d42' }} />
<Typography.Title level={5} style={{ margin: 0 }}>
独立短信验证码配置
</Typography.Title>
@@ -1277,8 +1277,8 @@ export default function SiteSettings() {
<img src={logoUrl} alt="Logo" style={{ height: 26, objectFit: 'contain' }} />
) : (
<span style={{ display: 'flex', flexDirection: 'column' }}>
<strong style={{ fontSize: 14, color: '#1677ff' }}>
{currentSite?.site_name || 'HFB 分销商城'}
<strong style={{ fontSize: 14, color: '#1e4d42' }}>
{currentSite?.site_name || '解忧分销商城'}
</strong>
<small style={{ fontSize: 10, color: '#94a3b8' }}>
{storefrontText.tagline.trim() || DEFAULT_STOREFRONT_TEXT.tagline}
@@ -1405,7 +1405,7 @@ export default function SiteSettings() {
>
<div>{footerInfo.copyright || `© 2026 ${currentSite?.site_name || '分销网'}`}</div>
{footerInfo.icp && <div>{footerInfo.icp}</div>}
{footerInfo.contact && <div style={{ color: '#1677ff' }}>{footerInfo.contact}</div>}
{footerInfo.contact && <div style={{ color: '#1e4d42' }}>{footerInfo.contact}</div>}
</div>
</div>
</Card>
+1 -1
View File
@@ -301,7 +301,7 @@ export default function Sites({ isSuperadmin = true }: { isSuperadmin?: boolean
width: 180,
render: (v: string) => (
<Space>
<ShopOutlined style={{ color: '#1677ff' }} />
<ShopOutlined style={{ color: '#1e4d42' }} />
<strong>{v}</strong>
</Space>
),
+5 -5
View File
@@ -155,7 +155,7 @@ export default function Users() {
width: 170,
render: (phone: string) => (
<Space size="small">
<Typography.Text strong style={{ fontFamily: 'monospace', fontSize: 13, color: '#1677ff' }}>
<Typography.Text strong style={{ fontFamily: 'monospace', fontSize: 13, color: '#1e4d42' }}>
{phone}
</Typography.Text>
<Tooltip title={copiedPhone === phone ? '已复制' : '点击复制完整手机号'}>
@@ -179,7 +179,7 @@ export default function Users() {
size="small"
src={row.avatar_url || undefined}
icon={!row.avatar_url ? <UserOutlined /> : undefined}
style={{ backgroundColor: '#1677ff' }}
style={{ backgroundColor: '#1e4d42' }}
/>
<Typography.Text style={{ fontSize: 13 }}>{row.nickname || '-'}</Typography.Text>
</Space>
@@ -351,11 +351,11 @@ export default function Users() {
<Statistic
title="关联用户总规模"
value={total}
prefix={<UserOutlined style={{ color: '#1677ff' }} />}
prefix={<UserOutlined style={{ color: '#1e4d42' }} />}
suffix="人"
valueStyle={{ color: '#1677ff', fontWeight: 'bold' }}
valueStyle={{ color: '#1e4d42', fontWeight: 'bold' }}
/>
<div style={{ marginTop: 6, fontSize: 12, color: '#1677ff' }}>
<div style={{ marginTop: 6, fontSize: 12, color: '#1e4d42' }}>
本站注册或产生过消费行为的全部用户总计
</div>
</Card>
+3 -3
View File
@@ -198,7 +198,7 @@ export default function Wallet() {
<Row gutter={16}>
<Col flex="1">
<Card bordered={false} style={{ background: 'linear-gradient(135deg, #1677ff 0%, #0958d9 100%)', color: '#fff' }}>
<Card bordered={false} style={{ background: 'linear-gradient(135deg, #1e4d42 0%, #153a32 100%)', color: '#fff' }}>
<Statistic
title={<span style={{ color: 'rgba(255,255,255,0.85)' }}>可提现余额</span>}
value={((wallet?.available_balance_cent ?? 0) / 100).toFixed(2)}
@@ -213,9 +213,9 @@ export default function Wallet() {
<Statistic
title="待释放收益 (冷却期内)"
value={((wallet?.pending_release_cent ?? 0) / 100).toFixed(2)}
prefix={<HourglassOutlined style={{ color: '#1677ff' }} />}
prefix={<HourglassOutlined style={{ color: '#1e4d42' }} />}
suffix="元"
valueStyle={{ color: '#1677ff' }}
valueStyle={{ color: '#1e4d42' }}
/>
</Card>
</Col>
+169 -32
View File
@@ -1,7 +1,15 @@
:root {
font-family: Inter, -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
color: #1f2937;
background: #f5f7fa;
--brand-ink: #1e4d42;
--brand-ink-deep: #153a32;
--brand-seal: #a64332;
--brand-brass: #b08a4a;
--brand-line: #e4ded2;
--brand-paper: #f6f2e8;
--brand-paper-warm: #fffdf8;
font-family: 'Noto Sans SC', Inter, -apple-system, BlinkMacSystemFont, 'PingFang SC',
'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
color: #1c2521;
background: var(--brand-paper);
}
* {
@@ -32,7 +40,8 @@ body,
overflow: hidden;
flex-shrink: 0;
z-index: 100;
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.12);
background: var(--brand-ink-deep);
box-shadow: 4px 0 24px rgba(21, 58, 50, 0.18);
}
.app-sider .ant-layout-sider-children {
@@ -56,17 +65,38 @@ body,
.brand {
height: 64px;
line-height: 64px;
padding: 0 20px;
color: #fff;
font-size: 16px;
padding: 0 18px;
color: #f0f4f2;
font-size: 15px;
font-weight: 600;
letter-spacing: 0.5px;
display: flex;
align-items: center;
gap: 10px;
flex-shrink: 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
border-bottom: 1px solid rgba(236, 208, 177, 0.14);
}
.brand__tag {
padding: 2px 7px;
border: 1px solid rgba(236, 208, 177, 0.45);
border-radius: 2px;
color: #ecd0b1;
font-size: 10px;
font-weight: 400;
letter-spacing: 0.12em;
}
.brand__sub {
padding: 8px 20px 10px;
color: rgba(236, 208, 177, 0.5);
font-size: 9px;
letter-spacing: 0.2em;
}
.app-sider .ant-menu {
background: transparent;
border-inline-end: 0 !important;
}
.app-layout {
@@ -76,7 +106,7 @@ body,
flex-direction: column;
overflow: hidden;
min-width: 0;
background: #f5f7fa;
background: var(--brand-paper);
}
.header {
@@ -86,10 +116,10 @@ body,
display: flex;
align-items: center;
justify-content: space-between;
background: #fff;
background: var(--brand-paper-warm);
padding: 0 24px;
border-bottom: 1px solid #edf0f5;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
border-bottom: 1px solid var(--brand-line);
box-shadow: 0 1px 2px rgba(30, 77, 66, 0.03);
z-index: 99;
}
@@ -116,7 +146,7 @@ body,
min-height: 0;
overflow-y: auto;
overflow-x: hidden;
background: #f5f7fa;
background: var(--brand-paper);
}
.app-content::-webkit-scrollbar {
@@ -136,6 +166,8 @@ body,
.page {
width: 100%;
max-width: 1600px;
margin: 0 auto;
padding: 24px;
}
@@ -172,43 +204,148 @@ body,
/* Login Page Styles */
.login-container {
min-height: 100vh;
display: grid;
grid-template-columns: minmax(0, 1.05fr) minmax(420px, 0.95fr);
gap: 28px;
padding: 28px;
background:
radial-gradient(circle at 16% 18%, rgba(166, 67, 50, 0.07), transparent 42%),
var(--brand-paper);
}
.login-brand {
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
overflow: hidden;
padding: 48px 54px;
border-radius: 14px;
background: var(--brand-ink);
color: #f0f4f2;
}
.login-brand::after {
content: '';
position: absolute;
inset: 14px;
border: 1px solid rgba(236, 208, 177, 0.22);
border-radius: 10px;
pointer-events: none;
}
.login-brand__logo {
margin-bottom: 34px;
}
.login-brand__eyebrow {
color: #ecd0b1;
font-size: 10px;
letter-spacing: 0.22em;
}
.login-brand h1 {
margin: 12px 0 16px;
color: #f6f2e8;
font-family: 'Noto Serif SC', 'Songti SC', serif;
font-size: 38px;
font-weight: 600;
line-height: 1.28;
letter-spacing: 0.04em;
}
.login-brand h1 span {
display: block;
margin-top: 8px;
color: #b9cbc3;
font-size: 15px;
font-weight: 400;
letter-spacing: 0.08em;
}
.login-brand p {
max-width: 430px;
margin: 0 0 24px;
color: #b9cbc3;
font-size: 13px;
line-height: 1.9;
}
.login-brand ul {
display: flex;
flex-direction: column;
gap: 10px;
margin: 0;
padding: 0;
color: #d9e5df;
font-size: 12px;
list-style: none;
}
.login-brand li::before {
content: '·';
margin-right: 8px;
color: #ecd0b1;
}
.login-brand__seal {
position: absolute;
right: 42px;
bottom: 40px;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #0f172a 100%);
padding: 20px;
width: 64px;
height: 64px;
border: 2px solid var(--brand-seal);
color: #ecd0b1;
font-family: 'Noto Serif SC', 'Songti SC', serif;
font-size: 15px;
transform: rotate(-4deg);
}
.login-card {
align-self: center;
width: 100%;
max-width: 420px;
border-radius: 16px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.25);
background: #ffffff;
padding: 12px 8px;
max-width: 460px;
margin: 0 auto;
padding: 20px 16px;
border: 1px solid var(--brand-line);
border-radius: 14px;
background: var(--brand-paper-warm);
box-shadow: 0 24px 48px rgba(30, 77, 66, 0.08);
}
.login-header {
margin-bottom: 26px;
text-align: center;
margin-bottom: 28px;
}
.login-logo {
width: 56px;
height: 56px;
margin: 0 auto 8px;
background: #e6f4ff;
border-radius: 14px;
display: flex;
align-items: center;
justify-content: center;
.login-header__mobile-logo {
display: none;
margin-bottom: 18px;
}
.login-footer {
text-align: center;
margin-top: 24px;
padding-top: 16px;
border-top: 1px solid #f0f0f0;
border-top: 1px solid var(--brand-line);
}
@media (max-width: 980px) {
.login-container {
grid-template-columns: minmax(0, 1fr);
padding: 16px;
}
.login-brand {
display: none;
}
.login-header__mobile-logo {
display: block;
}
}
@media (max-width: 720px) {
+1
View File
@@ -0,0 +1 @@
/// <reference types="vite/client" />
+13 -3
View File
@@ -101,10 +101,20 @@
- `MobileHomePage`:深绿品牌首屏、搜索、快捷筛选、PullToRefresh、商品卡列表、空/错误状态。
- `MobileListingDetailPage`:商品图、价格/押金/哈夫币、账号说明、资产摘要、在线时间、固定底部操作栏。
- `MobileProfilePage`:登录状态、实名状态、订单/消息入口、退出登录。
- `/m/orders`、`/m/messages` 先用统一占位页,下一批迁移真实业务。
- `/m/orders`、`/m/messages` 已在后续批次接入真实接口(见 `Phase2-移动端订单与消息验收.md`)。
- 移动端 CSS 变量已接入解忧商行品牌色,不使用 Vant/旧站视觉。
### 1.9 分销后台品牌轻改
- 品牌 SVG 复制到 `distribution-admin/src/assets/brand/`,新增 `BrandLogo` 组件。
- `ConfigProvider` 主题改为深绿 `#1E4D42`,同步 Layout / Menu 深色侧栏 token。
- 侧栏改深绿底 + 反白横版 Logo + 「分销台」印记;顶栏改暖白底。
- 登录页改为双栏:左侧品牌介绍与印章,右侧登录表单;窄屏自动收起品牌栏。
- `index.html` 标题、favicon、`theme-color` 改为解忧商行。
- 全量替换旧蓝 `#1677ff` → `#1E4D42`、`#0958d9` → `#153A32`,页面结构未重写。
- `package.json` 包名改为 `jieyou-distribution-admin`。
---
## 2. 验证结果
@@ -183,11 +193,11 @@ dist/assets/MobileListingDetailPage-*.js 27.31 kB │ gzip 10.70 kB
1. 移动端订单列表/详情与消息中心已接入真实接口;下单、支付、交接、归还、结账等操作仍待迁移。
2. 后台除仪表盘、订单列表与订单详情外,其余页面仍为统一占位。
3. 分销后台尚未做品牌轻改。
3. 分销后台已完成主题、Logo、登录页与 Shell 轻改,页面结构未重写。
4. 后台菜单权限码基于旧项目推断:订单页已核对为 `order:list`(列表)与 `order:view`(详情),其余页面仍需逐一核对。
5. SVG 中文尚未转曲。
6. 首屏包体仍偏大。
7. 移动端批次 `ef01486`、后台订单批次 `17b985a` 已提交;移动订单与消息在后续批次提交。
7. 移动端 `ef01486`、后台订单 `17b985a`、移动订单与消息 `e8a20eb` 已提交;分销后台轻改在后续批次提交。
---