feat: 阿里云 OSS 资源桶接入,商品图与icon支持远程基址

This commit is contained in:
2026-08-06 22:42:35 +08:00
parent b1ca212a40
commit 2f5e12d252
13 changed files with 90 additions and 32 deletions
+29
View File
@@ -0,0 +1,29 @@
/**
* 静态资源基址。
*
* 留空表示继续使用小程序包内本地资源(/icon、/img);
* 配置阿里云 OSS / CDN 后,所有经 assetUrl 处理的资源会自动拼接远程地址。
*/
export const ASSET_BASE_URL = ''
/** 把本地资源路径转成远程 URL;已经是 http(s) 或 wxfile/data 的保持不变 */
export function assetUrl(path?: string | null): string {
if (!path) return ''
if (/^(https?:|wxfile:|data:)/i.test(path)) return path
if (!ASSET_BASE_URL) return path
const base = ASSET_BASE_URL.replace(/\/+$/, '')
const normalized = path.startsWith('/') ? path : `/${path}`
return `${base}${normalized}`
}
/** 从旧存储中解析商品图标:兼容本地 /icon、远程 URL 和老版 emoji 缺省值 */
export function resolveStoredIcon(
value?: string,
fallback = '/icon/四角星.png',
): string {
if (!value) return assetUrl(fallback)
if (value.startsWith('/icon/') || /^https?:/i.test(value)) {
return assetUrl(value)
}
return assetUrl(fallback)
}
+17 -9
View File
@@ -6,8 +6,9 @@
*/
import { ProductCategory } from '../types'
import { assetUrl } from './asset'
export const PRODUCTS: ProductCategory[] = [
const PRODUCTS_LOCAL: ProductCategory[] = [
{
id: 'notebook-small',
name: '微雕笔记本(小)',
@@ -169,6 +170,13 @@ export const PRODUCTS: ProductCategory[] = [
}
]
/** 导出产品列表:资源地址统一经过 assetUrl,配置 ASSET_BASE_URL 后自动切远程 */
export const PRODUCTS = PRODUCTS_LOCAL.map(p => ({
...p,
images: (p.images || []).map(image => assetUrl(image)),
iconImg: assetUrl(p.iconImg),
}))
/** CATEGORIES 为 PRODUCTS 的别名,供页面引用 */
export const CATEGORIES = PRODUCTS
@@ -184,11 +192,11 @@ export const getProductById = (id: string): ProductCategory | undefined => {
* 用于兼容旧数据(旧数据 productIcon 存的是 emoji
*/
export const PRODUCT_ICON_MAP: Record<string, string> = {
'notebook-small': '/icon/书本.png',
'notebook-large': '/icon/书本_大.png',
'coaster': '/icon/杯子.png',
'penbox': '/icon/笔盒.png',
'booklamp': '/icon/书灯.png'
'notebook-small': assetUrl('/icon/书本.png'),
'notebook-large': assetUrl('/icon/书本_大.png'),
'coaster': assetUrl('/icon/杯子.png'),
'penbox': assetUrl('/icon/笔盒.png'),
'booklamp': assetUrl('/icon/书灯.png')
}
/**
@@ -198,7 +206,7 @@ export const PRODUCT_ICON_MAP: Record<string, string> = {
* - 兜底:返回四角星
*/
export function getProductIconImg(product: any): string {
if (product?.iconImg) return product.iconImg
if (product?.id) return PRODUCT_ICON_MAP[product.id] || '/icon/四角星.png'
return '/icon/四角星.png'
if (product?.iconImg) return assetUrl(product.iconImg)
if (product?.id) return assetUrl(PRODUCT_ICON_MAP[product.id] || '/icon/四角星.png')
return assetUrl('/icon/四角星.png')
}
+5 -2
View File
@@ -1,6 +1,7 @@
import Taro from '@tarojs/taro'
import type { DesignItem, OrderItem, AddressItem, StickerItem } from '../types'
import { PRODUCT_ICON_MAP } from './productConfig'
import { assetUrl } from './asset'
import { invalidateAuthCache } from './authState'
// 重新导出类型,供各页面从 store 直接引用(修正原「声明但不导出」的编译错误)
@@ -175,7 +176,7 @@ export function setDesignList(list: DesignItem[]) {
export function addDesign(product: any, count: number): DesignItem {
const list = getDesignList()
const iconImg = product?.iconImg || PRODUCT_ICON_MAP[product?.id] || '/icon/四角星.png'
const iconImg = assetUrl(product?.iconImg || PRODUCT_ICON_MAP[product?.id] || '/icon/四角星.png')
const item: DesignItem = {
id: 'DSG' + Date.now(),
productId: product.id,
@@ -226,10 +227,12 @@ export function designToOrder(designId: string): OrderItem | null {
const design = dList.find(d => d.id === designId)
if (!design) return null
const iconImg = design.productIcon?.startsWith('/icon/')
const rawIcon = design.productIcon?.startsWith('/icon/') || /^https?:/i.test(design.productIcon || '')
? design.productIcon
: PRODUCT_ICON_MAP[design.productId] || '/icon/四角星.png'
const iconImg = assetUrl(rawIcon)
const order: OrderItem = {
id: 'ORD' + Date.now().toString().slice(-9),
productName: design.productName,