feat(distribution): 独立分销前台商城多租户体系、货源与订单数据严格隔离
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
AccountBookOutlined,
|
||||
ApiOutlined,
|
||||
DashboardOutlined,
|
||||
EyeOutlined,
|
||||
FileSearchOutlined,
|
||||
LogoutOutlined,
|
||||
SettingOutlined,
|
||||
@@ -20,6 +21,7 @@ import Accounts from './pages/Accounts'
|
||||
import Settlements from './pages/Settlements'
|
||||
import Orders from './pages/Orders'
|
||||
import Login from './pages/Login'
|
||||
import Storefront from './pages/Storefront'
|
||||
import './style.css'
|
||||
|
||||
type MenuItem = Required<MenuProps>['items'][number] & { superadminOnly?: boolean }
|
||||
@@ -83,6 +85,26 @@ function MainLayout({ member, onLogout }: { member: CurrentMember; onLogout: ()
|
||||
</div>
|
||||
<div className="header-right">
|
||||
<Space size="middle">
|
||||
{member.site_code && (
|
||||
<Button
|
||||
type="primary"
|
||||
ghost
|
||||
icon={<EyeOutlined />}
|
||||
size="small"
|
||||
onClick={() => {
|
||||
const isLocal = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'
|
||||
const targetUrl = isLocal
|
||||
? `http://${window.location.hostname}:5189/?site=${member.site_code}`
|
||||
: member.domain
|
||||
? `https://${member.domain}`
|
||||
: `/?site=${member.site_code}`
|
||||
window.open(targetUrl, '_blank')
|
||||
}}
|
||||
style={{ borderColor: '#1677ff', color: '#1677ff' }}
|
||||
>
|
||||
预览分销前台商城 ↗
|
||||
</Button>
|
||||
)}
|
||||
<div className="user-profile">
|
||||
<UserOutlined style={{ color: '#1677ff' }} />
|
||||
<Typography.Text strong style={{ fontSize: 13 }}>
|
||||
@@ -127,9 +149,24 @@ function AppContent() {
|
||||
const navigate = useNavigate()
|
||||
const location = useLocation()
|
||||
|
||||
const isPublicStorefront = location.pathname.startsWith('/site')
|
||||
|
||||
useEffect(() => {
|
||||
let active = true
|
||||
const checkAuth = async () => {
|
||||
// For public storefront, we do not force login
|
||||
if (isPublicStorefront) {
|
||||
try {
|
||||
const profile = await getMe()
|
||||
if (active) setMember(profile)
|
||||
} catch {
|
||||
// ignore auth error on public storefront
|
||||
} finally {
|
||||
if (active) setLoading(false)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// If no token exists and no session, skip getMe
|
||||
if (!getStoredToken() && location.pathname === '/login') {
|
||||
if (active) setLoading(false)
|
||||
@@ -158,7 +195,7 @@ function AppContent() {
|
||||
return () => {
|
||||
active = false
|
||||
}
|
||||
}, [location.pathname, navigate])
|
||||
}, [location.pathname, navigate, isPublicStorefront])
|
||||
|
||||
const handleLogout = async () => {
|
||||
await logout()
|
||||
@@ -171,6 +208,16 @@ function AppContent() {
|
||||
navigate('/', { replace: true })
|
||||
}
|
||||
|
||||
if (isPublicStorefront) {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/site" element={<Navigate to="/site/demo" replace />} />
|
||||
<Route path="/site/:siteCode" element={<Storefront />} />
|
||||
<Route path="*" element={<Navigate to="/" replace />} />
|
||||
</Routes>
|
||||
)
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div style={{ height: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
|
||||
Reference in New Issue
Block a user