topfans/frontend/utils/craftMintSubmit.js
2026-05-16 02:42:32 +08:00

143 lines
4.4 KiB
JavaScript

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 }
}