topfans/frontend/composables/useLaserSegment.js
2026-06-03 22:19:22 +08:00

100 lines
2.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 镭射卡人像抠图 — 网关 POST /api/v1/segmentimageseg / VIAPI
* 抠图失败即抛错,中断 thinking不做椭圆降级。
*/
import { segmentPortraitApi } from '@/utils/api.js'
import { CASTLOVE_FORM_KEY } from '@/utils/castloveGenerationFlow.js'
async function downloadToLocal(url) {
const target = String(url || '').trim()
if (!target) {
throw new Error('缺少抠图下载地址')
}
// H5OSS 跨域时 uni.downloadFile 易丢 PNG alpha改用 fetch + blob URL
// #ifdef H5
const response = await fetch(target)
if (!response.ok) {
throw new Error(`下载抠图失败 HTTP ${response.status}`)
}
const blob = await response.blob()
return URL.createObjectURL(blob)
// #endif
// #ifndef H5
return new Promise((resolve, reject) => {
uni.downloadFile({
url: target,
timeout: 120000,
success: (res) => {
if (res.statusCode === 200 && res.tempFilePath) {
resolve(res.tempFilePath)
return
}
reject(new Error(`下载抠图失败 HTTP ${res.statusCode}`))
},
fail: (e) => reject(new Error(e?.errMsg || '下载抠图失败')),
})
})
// #endif
}
/** 将抠图本地路径写入 castlove 表单,供 craftMintSubmit 上传 cutout 层 */
export function persistCutoutToForm(cutoutLocalPath, cutoutOssKey = '') {
try {
const raw = uni.getStorageSync(CASTLOVE_FORM_KEY)
if (!raw) return
const form = typeof raw === 'string' ? JSON.parse(raw) : { ...raw }
form.cutoutImage = cutoutLocalPath
if (cutoutOssKey) {
form.cutout_oss_key = cutoutOssKey
}
uni.setStorageSync(CASTLOVE_FORM_KEY, JSON.stringify(form))
} catch (e) {
console.warn('[useLaserSegment] persistCutoutToForm failed:', e)
}
}
export function clearCutoutFromForm() {
try {
const raw = uni.getStorageSync(CASTLOVE_FORM_KEY)
if (!raw) return
const form = typeof raw === 'string' ? JSON.parse(raw) : { ...raw }
delete form.cutoutImage
delete form.cutout_oss_key
uni.setStorageSync(CASTLOVE_FORM_KEY, JSON.stringify(form))
} catch (e) {
/* noop */
}
}
/**
* 服务端人像抠图
* @param {string} imagePath 用户原图本地路径
* @returns {Promise<{ localPath: string, ossKey: string }>}
*/
export async function segmentPortrait(imagePath, options = {}) {
const path = String(imagePath || '').trim()
if (!path) {
throw new Error('缺少原图')
}
const res = await segmentPortraitApi(path, {
imageBase64: options.imageBase64 || '',
})
const data = res?.data
if (!data?.success || !data?.cutout_url_signed) {
const msg = data?.message || data?.error_code || 'LC_SEGMENT_FAILED'
throw new Error(msg)
}
const localPath = await downloadToLocal(data.cutout_url_signed)
persistCutoutToForm(localPath, data.cutout_oss_key || '')
return {
localPath,
ossKey: data.cutout_oss_key || '',
cutoutUrl: data.cutout_url_signed || '', // OSS 签名的抠图 PNG 地址,供 Dify 使用
}
}