style(distribution): 完成分销后台品牌与登录页轻改
This commit is contained in:
@@ -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>
|
||||
|
||||
Generated
+2
-2
@@ -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,5 +1,5 @@
|
||||
{
|
||||
"name": "hfb-distribution-admin",
|
||||
"name": "jieyou-distribution-admin",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
|
||||
@@ -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 |
@@ -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',
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -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 |
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
),
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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) /
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
),
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
||||
+13
-3
@@ -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` 已提交;分销后台轻改在后续批次提交。
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user