import { getOssSignatureApi, createMintOrderApi } from '@/utils/api.js' import { resolveH5OssPostUrl } from '@/utils/h5OssPostUrl.js' import { buildCastloveFormSnapshot } from '@/utils/castloveMintForm.js' function uploadFileToOss(tempFilePath, ossData) { return new Promise((resolve, reject) => { const fileName = `${Date.now()}.jpg` uni.uploadFile({ url: ossData.host, filePath: tempFilePath, name: 'file', formData: { key: ossData.dir + fileName, policy: ossData.policy, success_action_status: '200', 'x-oss-credential': ossData.x_oss_credential, 'x-oss-date': ossData.x_oss_date, 'x-oss-security-token': ossData.security_token, 'x-oss-signature': ossData.signature, 'x-oss-signature-version': ossData.x_oss_signature_version, }, success: (res) => { if (res.statusCode === 200 || res.statusCode === 204) { resolve(`${ossData.host}/${ossData.dir}${fileName}`) } else { reject(new Error(`上传失败 ${res.statusCode}`)) } }, fail: reject, }) }) } /** * 铸爱确认页:上传选中图并创建铸造订单 * @param {{ imagePath: string, bgImagePath?: string, formData: object }} opts */ export async function submitCraftMintFromPath({ imagePath, bgImagePath, formData }) { const path = String(imagePath || '').trim() if (!path) { throw new Error('缺少作品图片') } const signRes = await getOssSignatureApi('asset') if (!signRes || signRes.code !== 200 || !signRes.data) { throw new Error(signRes?.message || '获取签名失败') } const ossData = signRes.data const orderId = ossData.order_id || '' let imageUrl = path if (!path.startsWith('http')) { // #ifdef H5 if (path.startsWith('data:')) { const blob = await fetch(path).then((r) => r.blob()) const fd = new FormData() const fileName = `${Date.now()}.jpg` fd.append('key', ossData.dir + fileName) fd.append('policy', ossData.policy) fd.append('success_action_status', '200') fd.append('x-oss-credential', ossData.x_oss_credential) fd.append('x-oss-date', ossData.x_oss_date) fd.append('x-oss-security-token', ossData.security_token) fd.append('x-oss-signature', ossData.signature) fd.append('x-oss-signature-version', ossData.x_oss_signature_version) fd.append('file', blob, fileName) const res = await fetch(resolveH5OssPostUrl(ossData.host), { method: 'POST', body: fd }) if (!res.ok && res.status !== 204) { throw new Error('上传失败') } imageUrl = `${ossData.host}/${ossData.dir}${fileName}` } else { imageUrl = await uploadFileToOss(path, ossData) } // #endif // #ifndef H5 imageUrl = await uploadFileToOss(path, ossData) // #endif } const snap = buildCastloveFormSnapshot({ nftInfo: formData.info || formData.nftInfo || '', materialTypes: formData.materialTypes || ['粉丝自制'], materialTypeIndex: formData.materialTypeIndex ?? 0, pageName: formData.craft_name || formData.typeName || '', uploadedImage: path, uploadedImageBase64: formData.imageBase64 || '', }) const isLenticular = Array.isArray(snap.tags) && snap.tags.includes('craft:lenticular') let bgUrl = '' if (isLenticular && bgImagePath) { const bgPath = String(bgImagePath || '').trim() if (bgPath && !bgPath.startsWith('http')) { bgUrl = await uploadFileToOss(bgPath, ossData) } else if (bgPath) { bgUrl = bgPath } } const materialUrl = isLenticular && bgUrl ? JSON.stringify({ main: imageUrl, bg: bgUrl }) : imageUrl const orderData = { order_id: orderId, name: snap.name, material_url: materialUrl, description: snap.description || '', grade: snap.grade ?? 0, tags: Array.isArray(snap.tags) ? snap.tags : [], material_type: snap.material_type, info: snap.info || '', } const response = await createMintOrderApi(orderData) if (!response || response.code !== 200) { throw new Error(response?.message || '创建订单失败') } const assetId = response.data?.asset?.asset_id || response.data?.asset_id || response.data?.assetId || '' const nftData = { image: imageUrl, name: snap.name, description: snap.description || '', material_type: snap.material_type, tags: snap.tags, order_id: orderId, asset_id: assetId, info: snap.info, event: snap.info, ...(isLenticular && bgUrl ? { bg_image: bgUrl } : {}), } uni.setStorageSync('temp_nft_data', JSON.stringify(nftData)) uni.removeStorageSync('castlove_form_data') return { imageUrl, orderId } }