/** * 镭射工坊导出图后:OSS 上传 + 创建铸造订单(与 create.vue 原「跳过」链路一致) */ import { getOssSignatureApi, createMintOrderApi } from '@/utils/api.js' import { resolveH5OssPostUrl } from '@/utils/h5OssPostUrl.js' import { buildCastloveFormSnapshot } from '@/utils/castloveMintForm.js' /** * @param {string} base64Data data:image/jpeg;base64,... 或 data:image/png;base64,... * @param {object} ossData getOssSignatureApi 返回的 data * @returns {Promise} material_url */ function uploadDataUrlToOss(base64Data, ossData) { return new Promise((resolve, reject) => { const fileName = `${Date.now()}.jpg` // #ifdef H5 fetch(base64Data) .then((res) => res.blob()) .then((blob) => { const formData = new FormData() formData.append('key', ossData.dir + fileName) formData.append('policy', ossData.policy) formData.append('success_action_status', '200') formData.append('x-oss-credential', ossData.x_oss_credential) formData.append('x-oss-date', ossData.x_oss_date) formData.append('x-oss-security-token', ossData.security_token) formData.append('x-oss-signature', ossData.signature) formData.append('x-oss-signature-version', ossData.x_oss_signature_version) formData.append('file', blob, fileName) return fetch(resolveH5OssPostUrl(ossData.host), { method: 'POST', body: formData }) }) .then((response) => { if (response.ok || response.status === 204) { resolve(`${ossData.host}/${ossData.dir}${fileName}`) } else { reject(new Error('上传失败')) } }) .catch(reject) // #endif // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ const base64Content = base64Data.split(',')[1] const fp = `${wx.env.USER_DATA_PATH}/${fileName}` uni.getFileSystemManager().writeFile({ filePath: fp, data: base64Content, encoding: 'base64', success: () => { uni.uploadFile({ url: ossData.host, filePath: fp, 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: (uploadRes) => { if (uploadRes.statusCode === 200 || uploadRes.statusCode === 204) { resolve(`${ossData.host}/${ossData.dir}${fileName}`) } else { reject(new Error(`上传失败 HTTP ${uploadRes.statusCode}`)) } }, fail: reject }) }, fail: reject }) // #endif // #ifdef APP-PLUS const bitmap = new plus.nativeObj.Bitmap('castlove_laser_export') bitmap.loadBase64Data(base64Data, () => { const tempFilePath = `_doc/${fileName}` bitmap.save(tempFilePath, {}, () => { bitmap.clear() 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: (uploadRes) => { if (uploadRes.statusCode === 200 || uploadRes.statusCode === 204) { resolve(`${ossData.host}/${ossData.dir}${fileName}`) } else { reject(new Error(`上传失败 HTTP ${uploadRes.statusCode}`)) } }, fail: reject }) }, () => { bitmap.clear() reject(new Error('保存临时文件失败')) }) }, () => { bitmap.clear() reject(new Error('加载导出图失败')) }) // #endif }) } /** * @param {string} imageDataUrl 导出后的 data URL * @param {object} entry create 页写入的 CASTLOVE_LASER_ENTRY_KEY 解析结果 */ export async function submitCastloveAfterLaserExport(imageDataUrl, entry) { if (!entry || !imageDataUrl) { throw new Error('缺少铸爱表单或导出图') } const { nftInfo, materialTypes, materialTypeIndex, pageName, uploadedImage, uploadedImageBase64 } = entry const signRes = await getOssSignatureApi('asset') if (!signRes || signRes.code !== 200 || !signRes.data) { throw new Error((signRes && signRes.message) || '获取签名失败') } const orderId = signRes.data.order_id || '' const imageUrl = await uploadDataUrlToOss(imageDataUrl, signRes.data) const snap = buildCastloveFormSnapshot({ nftInfo, materialTypes, materialTypeIndex, pageName, uploadedImage: uploadedImage || '', uploadedImageBase64: uploadedImageBase64 || '' }) const orderData = { order_id: orderId, name: snap.name, material_url: imageUrl, description: snap.description, grade: snap.grade, 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 && response.message) || '创建订单失败') } const nftData = { image: imageUrl, name: snap.name, description: snap.description, material_type: snap.material_type, tags: snap.tags, order_id: orderId, info: snap.info, event: snap.info } uni.setStorageSync('temp_nft_data', JSON.stringify(nftData)) return { imageUrl, orderId } }