feat(wordcloud): 贴纸持久化(决策#4)+ dispatchOrder/persistDesignMedia 辅助
This commit is contained in:
@@ -4,6 +4,7 @@ import { useState, useEffect } from 'react'
|
||||
import './index.scss'
|
||||
import { getProductById } from '../../utils/productConfig'
|
||||
import { getDesignList, setDesignList, updateDesign, type DesignItem, type StickerItem } from '../../utils/store'
|
||||
import { persistDesignMedia } from '../../utils/api'
|
||||
import { useThemeContext } from '../../context/ThemeContext'
|
||||
import { useSafeArea } from '../../hooks/useSafeArea'
|
||||
import { useStatusBar } from '../../hooks/useStatusBar'
|
||||
@@ -241,18 +242,15 @@ export default function DIYPage() {
|
||||
return base
|
||||
}
|
||||
|
||||
const handleComplete = () => {
|
||||
const handleComplete = async () => {
|
||||
if (hasOverlap) {
|
||||
Taro.showToast({ title: '贴纸不能重叠', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (designId) {
|
||||
updateDesign(designId, {
|
||||
designData: {
|
||||
stickers,
|
||||
category
|
||||
}
|
||||
})
|
||||
// 贴纸/底图持久化(决策#4,R4 负责):本地图 → COS 持久 URL,保证后端 WCD 打包可下载素材
|
||||
const data = await persistDesignMedia({ stickers, category, version: 1 })
|
||||
updateDesign(designId, { designData: data })
|
||||
}
|
||||
setPreviewMode(false)
|
||||
Taro.navigateTo({ url: `/pages/checkout/index?designId=${designId}` })
|
||||
|
||||
@@ -2,7 +2,10 @@ import Taro from '@tarojs/taro'
|
||||
import http, { BASE_URL, getToken } from '../request'
|
||||
import type {
|
||||
CosCredentials,
|
||||
DesignDataV1,
|
||||
SketchResult,
|
||||
StickerItem,
|
||||
WordCloudDispatchResult,
|
||||
WordCloudJob,
|
||||
WordCloudStatus,
|
||||
} from '../../types'
|
||||
@@ -101,4 +104,49 @@ export function getWordCloudResult(jobId: string): Promise<{ imageUrl: string; s
|
||||
return http.get<{ imageUrl: string; svgUrl?: string }>(`/api/wordcloud/jobs/${jobId}/result`)
|
||||
}
|
||||
|
||||
/** 是否为设备本地临时路径(后端/wordcloud 无法消费,需先转 COS 持久 URL) */
|
||||
function isLocalPath(url?: string): boolean {
|
||||
return !!url && /^(wxfile:|http:\/\/tmp\/|tmp\/)/i.test(url)
|
||||
}
|
||||
|
||||
/** 单张本地图 → COS 持久 URL;COS 未配置等失败时保留原路径,不阻断保存 */
|
||||
async function persistLocalImage(localPath: string): Promise<string> {
|
||||
try {
|
||||
const key = `uploads/sticker/${Date.now()}_${Math.floor(Math.random() * 1e6)}.jpg`
|
||||
const cred = await getUploadCredentials(key)
|
||||
return await uploadToCos(localPath, cred)
|
||||
} catch {
|
||||
return localPath
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设计媒体持久化(契约 design-data-contract-v1.md 决策#4:贴纸持久化由 R4 完成)。
|
||||
* 保存/下单前调用,把 designData 里的本地贴纸/底图上传为 COS 持久 URL 写回 src,
|
||||
* 保证 WCD 打包时后端能下载到素材字节。
|
||||
*/
|
||||
export async function persistDesignMedia(designData: DesignDataV1): Promise<DesignDataV1> {
|
||||
if (!designData) return designData
|
||||
const next: DesignDataV1 = { ...designData }
|
||||
if (designData.background && isLocalPath(designData.background.src)) {
|
||||
next.background = {
|
||||
...designData.background,
|
||||
src: await persistLocalImage(designData.background.src),
|
||||
}
|
||||
}
|
||||
if (designData.stickers && designData.stickers.length) {
|
||||
const list: StickerItem[] = []
|
||||
for (const s of designData.stickers) {
|
||||
list.push(isLocalPath(s.src) ? { ...s, src: await persistLocalImage(s.src) } : s)
|
||||
}
|
||||
next.stickers = list
|
||||
}
|
||||
return next
|
||||
}
|
||||
|
||||
/** 下单后 WCD 派单(幂等触发;WORDCLOUD 未配置返回 not_configured,见 api-contract §8) */
|
||||
export function dispatchOrder(orderId: string): Promise<WordCloudDispatchResult> {
|
||||
return http.post<WordCloudDispatchResult>(`/api/orders/${orderId}/dispatch`)
|
||||
}
|
||||
|
||||
export type { WordCloudStatus }
|
||||
|
||||
Reference in New Issue
Block a user