refactor: 产品大图迁移OSS,小图标本地打包,资源基址改为.env配置
@@ -4,14 +4,15 @@ import { useEffect, useState } from 'react'
|
||||
import { getTheme, resolveTheme } from '../utils/store'
|
||||
import { THEME_CHANGE_EVENT } from '../context/ThemeContext'
|
||||
import { applyPageBackground } from '../utils/themeBackground'
|
||||
import { assetUrl } from '../utils/asset'
|
||||
import './index.scss'
|
||||
|
||||
const TABS = [
|
||||
{ pagePath: '/pages/index/index', label: '首页', icon: '/icon/首页.svg', iconActive: '/icon/首页-fill.svg' },
|
||||
{ pagePath: '/pages/shop/index', label: '商品', icon: '/icon/商品.svg', iconActive: '/icon/商品-fill.svg' },
|
||||
{ pagePath: '/pages/designList/index', label: '设计清单', icon: '/icon/调色盘.svg', iconActive: '/icon/调色盘-fill.svg' },
|
||||
{ pagePath: '/pages/orders/index', label: '订单', icon: '/icon/包裹.svg', iconActive: '/icon/包裹-fill.svg' },
|
||||
{ pagePath: '/pages/profile/index', label: '我的', icon: '/icon/个人.svg', iconActive: '/icon/个人-fill.svg' }
|
||||
{ pagePath: '/pages/index/index', label: '首页', icon: assetUrl('/icon/首页.svg'), iconActive: assetUrl('/icon/首页-fill.svg') },
|
||||
{ pagePath: '/pages/shop/index', label: '商品', icon: assetUrl('/icon/商品.svg'), iconActive: assetUrl('/icon/商品-fill.svg') },
|
||||
{ pagePath: '/pages/designList/index', label: '设计清单', icon: assetUrl('/icon/调色盘.svg'), iconActive: assetUrl('/icon/调色盘-fill.svg') },
|
||||
{ pagePath: '/pages/orders/index', label: '订单', icon: assetUrl('/icon/包裹.svg'), iconActive: assetUrl('/icon/包裹-fill.svg') },
|
||||
{ pagePath: '/pages/profile/index', label: '我的', icon: assetUrl('/icon/个人.svg'), iconActive: assetUrl('/icon/个人-fill.svg') }
|
||||
]
|
||||
|
||||
function matchTab(path: string): string {
|
||||
|
||||
|
Before Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 45 KiB |
@@ -8,6 +8,7 @@ import { useThemeContext } from '../../context/ThemeContext'
|
||||
import { useSafeArea } from '../../hooks/useSafeArea'
|
||||
import { useStatusBar } from '../../hooks/useStatusBar'
|
||||
import ThemedPageMeta from '../../components/ThemedPageMeta'
|
||||
import { assetUrl } from '../../utils/asset'
|
||||
|
||||
export default function AddressPage() {
|
||||
const { theme, resolvedTheme } = useThemeContext()
|
||||
@@ -132,7 +133,7 @@ export default function AddressPage() {
|
||||
|
||||
{list.length === 0 && (
|
||||
<View className='empty-state'>
|
||||
<Image className='empty-icon-img' src='/icon/地址.png' mode='aspectFit' />
|
||||
<Image className='empty-icon-img' src={assetUrl('/icon/地址.png')} mode='aspectFit' />
|
||||
<Text className='empty-text'>还没有收货地址</Text>
|
||||
<Text className='empty-sub'>点击下方按钮添加新地址</Text>
|
||||
</View>
|
||||
|
||||
@@ -210,7 +210,7 @@ export default function DesignListPage() {
|
||||
|
||||
{filtered.length === 0 && (
|
||||
<View className='empty-state'>
|
||||
<Image className='empty-icon-img' src='/icon/调色盘.png' mode='aspectFit' />
|
||||
<Image className='empty-icon-img' src={assetUrl('/icon/调色盘.png')} mode='aspectFit' />
|
||||
<Text className='empty-text'>还没有设计清单</Text>
|
||||
<Text className='empty-sub'>去首页逛逛,找到喜欢的定制品</Text>
|
||||
<View className='btn-gradient' onTap={() => Taro.switchTab({ url: '/pages/index/index' })}>
|
||||
|
||||
@@ -62,7 +62,7 @@ export default function Index() {
|
||||
<View className='search-card dashed-card'>
|
||||
<View className='star-badge' />
|
||||
<View className='search-inner'>
|
||||
<Image className='search-icon-img' src='/icon/搜索.png' mode='aspectFit' />
|
||||
<Image className='search-icon-img' src={assetUrl('/icon/搜索.png')} mode='aspectFit' />
|
||||
<Input
|
||||
className='search-input'
|
||||
type='text'
|
||||
@@ -132,7 +132,7 @@ export default function Index() {
|
||||
<View className='category-img-wrapper'>
|
||||
<Image
|
||||
className='category-img-real'
|
||||
src={PRODUCT_IMG_MAP[cat.id] || '/icon/四角星.png'}
|
||||
src={PRODUCT_IMG_MAP[cat.id] || assetUrl('/icon/四角星.png')}
|
||||
mode='aspectFill'
|
||||
/>
|
||||
</View>
|
||||
@@ -144,7 +144,7 @@ export default function Index() {
|
||||
</View>
|
||||
{filteredCategories.length === 0 && (
|
||||
<View className='empty-category dashed-card'>
|
||||
<Image className='empty-icon-img' src='/icon/搜索.png' mode='aspectFit' />
|
||||
<Image className='empty-icon-img' src={assetUrl('/icon/搜索.png')} mode='aspectFit' />
|
||||
<Text className='empty-text'>未找到匹配的品类</Text>
|
||||
<Text className='empty-sub'>尝试搜索“笔记本”、“杯垫”等</Text>
|
||||
</View>
|
||||
|
||||
@@ -100,7 +100,7 @@ export default function OrderDetailPage() {
|
||||
<View className='star-badge' />
|
||||
<View className='logistics-header'>
|
||||
<View className='flex-center'>
|
||||
<Image className='card-icon-img' src='/icon/包裹.png' mode='aspectFit' />
|
||||
<Image className='card-icon-img' src={assetUrl('/icon/包裹.png')} mode='aspectFit' />
|
||||
<Text className='logistics-title'>物流信息</Text>
|
||||
</View>
|
||||
<Text className='logistics-num'>单号: SF1234567890</Text>
|
||||
@@ -161,7 +161,7 @@ export default function OrderDetailPage() {
|
||||
<View className='star-badge' />
|
||||
<View className='address-header'>
|
||||
<View className='flex-center'>
|
||||
<Image className='card-icon-img' src='/icon/地址.png' mode='aspectFit' />
|
||||
<Image className='card-icon-img' src={assetUrl('/icon/地址.png')} mode='aspectFit' />
|
||||
<Text className='address-title'>收货地址</Text>
|
||||
</View>
|
||||
<View className='address-change' onTap={() => setShowAddrPicker(true)}>
|
||||
|
||||
@@ -174,7 +174,7 @@ export default function OrdersPage() {
|
||||
|
||||
{filteredOrders.length === 0 && (
|
||||
<View className='empty-state'>
|
||||
<Image className='empty-icon-img' src='/icon/包裹.png' mode='aspectFit' />
|
||||
<Image className='empty-icon-img' src={assetUrl('/icon/包裹.png')} mode='aspectFit' />
|
||||
<Text className='empty-text'>暂无订单</Text>
|
||||
<Text className='empty-sub'>去首页开始定制吧</Text>
|
||||
<View className='btn-gradient' onTap={() => Taro.switchTab({ url: '/pages/index/index' })}>
|
||||
|
||||
@@ -9,22 +9,23 @@ import { useStatusBar } from '../../hooks/useStatusBar'
|
||||
import ThemedPageMeta from '../../components/ThemedPageMeta'
|
||||
import { login, getMe, updateProfile, getToken } from '../../utils/api'
|
||||
import { safeHideLoading } from '../../utils/request'
|
||||
import { assetUrl } from '../../utils/asset'
|
||||
|
||||
const ICON_MAP: Record<string, string> = {
|
||||
'我的设计': '/icon/调色盘.png',
|
||||
'词云生成': '/icon/词云生成.png',
|
||||
'收货地址': '/icon/地址.png',
|
||||
'联系客服': '/icon/电话.png',
|
||||
'使用帮助': '/icon/使用帮助.png',
|
||||
'设置': '/icon/设置.png'
|
||||
'我的设计': assetUrl('/icon/调色盘.png'),
|
||||
'词云生成': assetUrl('/icon/词云生成.png'),
|
||||
'收货地址': assetUrl('/icon/地址.png'),
|
||||
'联系客服': assetUrl('/icon/电话.png'),
|
||||
'使用帮助': assetUrl('/icon/使用帮助.png'),
|
||||
'设置': assetUrl('/icon/设置.png')
|
||||
}
|
||||
|
||||
const STATUS_MAP = [
|
||||
{ key: 'toDesign', label: '待设计', icon: '/icon/三角尺.png' },
|
||||
{ key: 'pending', label: '待付款', icon: '/icon/四角星.png' },
|
||||
{ key: 'paid', label: '待发货', icon: '/icon/包裹.png' },
|
||||
{ key: 'shipping', label: '待收货', icon: '/icon/杯子.png' },
|
||||
{ key: 'done', label: '已完成', icon: '/icon/书本.png' }
|
||||
{ key: 'toDesign', label: '待设计', icon: assetUrl('/icon/三角尺.png') },
|
||||
{ key: 'pending', label: '待付款', icon: assetUrl('/icon/四角星.png') },
|
||||
{ key: 'paid', label: '待发货', icon: assetUrl('/icon/包裹.png') },
|
||||
{ key: 'shipping', label: '待收货', icon: assetUrl('/icon/杯子.png') },
|
||||
{ key: 'done', label: '已完成', icon: assetUrl('/icon/书本.png') }
|
||||
]
|
||||
|
||||
const MENU_ITEMS = [
|
||||
@@ -288,7 +289,7 @@ export default function ProfilePage() {
|
||||
<Image className='avatar' src={userInfo.avatarUrl} mode='aspectFill' />
|
||||
) : (
|
||||
<View className='avatar-placeholder' onTap={handleOpenLogin}>
|
||||
<Image className='avatar-icon-img' src='/icon/个人.png' mode='aspectFit' />
|
||||
<Image className='avatar-icon-img' src={assetUrl('/icon/个人.png')} mode='aspectFit' />
|
||||
</View>
|
||||
)}
|
||||
<View className='user-meta'>
|
||||
@@ -351,7 +352,7 @@ export default function ProfilePage() {
|
||||
<View className='flex-between'>
|
||||
<View className='flex-column'>
|
||||
<View className='flex-center'>
|
||||
<Image className='enterprise-icon' src='/icon/企业批量定制.png' mode='aspectFit' />
|
||||
<Image className='enterprise-icon' src={assetUrl('/icon/企业批量定制.png')} mode='aspectFit' />
|
||||
<Text className='enterprise-title'>企业批量定制</Text>
|
||||
</View>
|
||||
<Text className='enterprise-desc'>年会礼品、入职纪念、团建伴手礼</Text>
|
||||
@@ -394,7 +395,7 @@ export default function ProfilePage() {
|
||||
{loginAvatarUrl ? (
|
||||
<Image className='avatar-img' src={loginAvatarUrl} mode='aspectFill' />
|
||||
) : (
|
||||
<Image className='avatar-placeholder-img' src='/icon/个人.png' mode='aspectFit' />
|
||||
<Image className='avatar-placeholder-img' src={assetUrl('/icon/个人.png')} mode='aspectFit' />
|
||||
)}
|
||||
</Button>
|
||||
<Input
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useThemeContext } from '../../context/ThemeContext'
|
||||
import { useSafeArea } from '../../hooks/useSafeArea'
|
||||
import { useStatusBar } from '../../hooks/useStatusBar'
|
||||
import ThemedPageMeta from '../../components/ThemedPageMeta'
|
||||
import { assetUrl } from '../../utils/asset'
|
||||
|
||||
const FAQ_ITEMS = [
|
||||
{ q: '定制周期需要多久?', a: '通常下单后3-5个工作日内发货,批量订单(50件以上)可能需要7-10个工作日。' },
|
||||
@@ -30,7 +31,7 @@ export default function ServicePage() {
|
||||
{/* 客服入口 */}
|
||||
<View className='service-hero dashed-card mt-20'>
|
||||
<View className='star-badge' />
|
||||
<Image className='service-hero-icon' src='/icon/电话.png' mode='aspectFit' />
|
||||
<Image className='service-hero-icon' src={assetUrl('/icon/电话.png')} mode='aspectFit' />
|
||||
<Text className='service-title'>智绘微刻客服中心</Text>
|
||||
<Text className='service-desc'>工作日 09:00 - 18:00 在线为您服务</Text>
|
||||
<View className='btn-gradient service-btn' onTap={() => Taro.showToast({ title: '跳转客服会话', icon: 'none' })}>
|
||||
@@ -44,7 +45,7 @@ export default function ServicePage() {
|
||||
<View className='contact-list'>
|
||||
<View className='contact-item dashed-card'>
|
||||
<View className='star-badge' />
|
||||
<Image className='contact-icon-img' src='/icon/电话.png' mode='aspectFit' />
|
||||
<Image className='contact-icon-img' src={assetUrl('/icon/电话.png')} mode='aspectFit' />
|
||||
<View className='contact-info'>
|
||||
<Text className='contact-label'>客服电话</Text>
|
||||
<Text className='contact-value'>400-XXX-XXXX</Text>
|
||||
@@ -52,7 +53,7 @@ export default function ServicePage() {
|
||||
</View>
|
||||
<View className='contact-item dashed-card' onTap={() => Taro.setClipboardData({ data: 'smart_engraving' })}>
|
||||
<View className='star-badge' />
|
||||
<Image className='contact-icon-img' src='/icon/词云生成.png' mode='aspectFit' />
|
||||
<Image className='contact-icon-img' src={assetUrl('/icon/词云生成.png')} mode='aspectFit' />
|
||||
<View className='contact-info'>
|
||||
<Text className='contact-label'>客服微信</Text>
|
||||
<Text className='contact-value'>smart_engraving(点击复制)</Text>
|
||||
@@ -60,7 +61,7 @@ export default function ServicePage() {
|
||||
</View>
|
||||
<View className='contact-item dashed-card'>
|
||||
<View className='star-badge' />
|
||||
<Image className='contact-icon-img' src='/icon/使用帮助.png' mode='aspectFit' />
|
||||
<Image className='contact-icon-img' src={assetUrl('/icon/使用帮助.png')} mode='aspectFit' />
|
||||
<View className='contact-info'>
|
||||
<Text className='contact-label'>商务邮箱</Text>
|
||||
<Text className='contact-value'>biz@smart-engraving.com</Text>
|
||||
@@ -85,7 +86,7 @@ export default function ServicePage() {
|
||||
<View className='enterprise-service dashed-card mt-20 mb-20'>
|
||||
<View className='star-badge' />
|
||||
<View className='flex-center'>
|
||||
<Image className='enterprise-icon' src='/icon/企业批量定制.png' mode='aspectFit' />
|
||||
<Image className='enterprise-icon' src={assetUrl('/icon/企业批量定制.png')} mode='aspectFit' />
|
||||
<Text className='enterprise-title'>企业专属客户经理</Text>
|
||||
</View>
|
||||
<Text className='enterprise-desc'>批量订单(50件以上)享专属报价、优先排产、专人对接</Text>
|
||||
|
||||
@@ -7,6 +7,7 @@ import { useSafeArea } from '../../hooks/useSafeArea'
|
||||
import { useStatusBar } from '../../hooks/useStatusBar'
|
||||
import ThemedPageMeta from '../../components/ThemedPageMeta'
|
||||
import { getUserInfo, setUserInfo, clearUserInfo, getAddressList, getDefaultAddress, type AddressItem } from '../../utils/store'
|
||||
import { assetUrl } from '../../utils/asset'
|
||||
|
||||
const THEME_OPTIONS: { label: string; value: 'light' | 'dark' | 'auto' }[] = [
|
||||
{ label: '浅色模式', value: 'light' },
|
||||
@@ -15,10 +16,10 @@ const THEME_OPTIONS: { label: string; value: 'light' | 'dark' | 'auto' }[] = [
|
||||
]
|
||||
|
||||
const MENU = [
|
||||
{ label: '个人信息', icon: '/icon/个人.png', action: (s: any) => s.setShowEdit(true) },
|
||||
{ label: '账号管理', icon: '/icon/账号管理.png', action: () => Taro.navigateTo({ url: '/pages/userDatabase/index' }) },
|
||||
{ label: '定制协议', icon: '/icon/定制协议.png', action: () => Taro.navigateTo({ url: '/pages/agreement/index' }) },
|
||||
{ label: '关于我们', icon: '/icon/关于我们.png', action: () => Taro.showToast({ title: '智绘微刻 v1.0', icon: 'none' }) }
|
||||
{ label: '个人信息', icon: assetUrl('/icon/个人.png'), action: (s: any) => s.setShowEdit(true) },
|
||||
{ label: '账号管理', icon: assetUrl('/icon/账号管理.png'), action: () => Taro.navigateTo({ url: '/pages/userDatabase/index' }) },
|
||||
{ label: '定制协议', icon: assetUrl('/icon/定制协议.png'), action: () => Taro.navigateTo({ url: '/pages/agreement/index' }) },
|
||||
{ label: '关于我们', icon: assetUrl('/icon/关于我们.png'), action: () => Taro.showToast({ title: '智绘微刻 v1.0', icon: 'none' }) }
|
||||
]
|
||||
|
||||
export default function SettingsPage() {
|
||||
@@ -87,7 +88,7 @@ export default function SettingsPage() {
|
||||
<Image className='settings-avatar' src={user.avatarUrl} mode='aspectFill' />
|
||||
) : (
|
||||
<View className='settings-avatar-placeholder'>
|
||||
<Image className='settings-avatar-icon' src='/icon/个人.png' mode='aspectFit' />
|
||||
<Image className='settings-avatar-icon' src={assetUrl('/icon/个人.png')} mode='aspectFit' />
|
||||
</View>
|
||||
)}
|
||||
<View style={{ marginLeft: '20px' }}>
|
||||
@@ -150,7 +151,7 @@ export default function SettingsPage() {
|
||||
{editAvatar ? (
|
||||
<Image className='avatar-img' src={editAvatar} mode='aspectFill' />
|
||||
) : (
|
||||
<Image className='avatar-placeholder-img' src='/icon/个人.png' mode='aspectFit' />
|
||||
<Image className='avatar-placeholder-img' src={assetUrl('/icon/个人.png')} mode='aspectFit' />
|
||||
)}
|
||||
</Button>
|
||||
<Input
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
* 留空表示继续使用小程序包内本地资源(/icon、/img);
|
||||
* 配置阿里云 OSS / CDN 后,所有经 assetUrl 处理的资源会自动拼接远程地址。
|
||||
*/
|
||||
export const ASSET_BASE_URL = 'https://wordcloudwechat.oss-cn-hangzhou.aliyuncs.com'
|
||||
declare const __OSS_BASE_URL__: string | undefined
|
||||
|
||||
export const ASSET_BASE_URL = typeof __OSS_BASE_URL__ !== 'undefined' ? __OSS_BASE_URL__ : ''
|
||||
|
||||
/** 把本地资源路径转成远程 URL;已经是 http(s) 或 wxfile/data 的保持不变 */
|
||||
export function assetUrl(path?: string | null): string {
|
||||
@@ -12,6 +14,8 @@ export function assetUrl(path?: string | null): string {
|
||||
if (/^(https?:|wxfile:|data:)/i.test(path)) return path
|
||||
if (!ASSET_BASE_URL) return path
|
||||
const base = ASSET_BASE_URL.replace(/\/+$/, '')
|
||||
// 小图标(/icon/*)保持本地打包,只有 /img/* 大图走 OSS
|
||||
if (!path.startsWith('/img/')) return path
|
||||
const normalized = path.startsWith('/') ? path : `/${path}`
|
||||
return `${base}${normalized}`
|
||||
}
|
||||
|
||||