ai-clone/frontend-ai/unpackage/dist/build/mp-weixin/utils/payment.js

2 lines
10 KiB
JavaScript
Raw Permalink 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.

"use strict";const e=require("../common/vendor.js"),n=require("../config/api.js");const t={CREATE_VOICE:"voice_clone",PHOTO_REVIVAL:"photo_revival",VOLCENGINE_VIDEO:"volcengine_video",SYNTHESIZE:"tts_synthesis",VIDEO_CALL:"video_call",AI_CALL:"conversation"},o={VOICE_CLONE:{type:"voice_clone",backendType:"CREATE_VOICE",name:"声音克隆",desc:"克隆您的声音让AI学会您的音色",price:0,freeTrialCount:0},PHOTO_REVIVAL:{type:"photo_revival",backendType:"PHOTO_REVIVAL",name:"照片复活",desc:"让照片中的人开口说话",price:0,freeTrialCount:0},VOLCENGINE_VIDEO:{type:"volcengine_video",backendType:"VOLCENGINE_VIDEO",name:"火山视频复活",desc:"火山视频复活",price:0,freeTrialCount:0},TTS_SYNTHESIS:{type:"tts_synthesis",backendType:"SYNTHESIZE",name:"语音合成",desc:"使用已有音色合成语音",price:0,freeTrialCount:0},VIDEO_CALL:{type:"video_call",backendType:"VIDEO_CALL",name:"AI视频通话",desc:"AI视频通话",price:0,freeTrialCount:0},CONVERSATION:{type:"conversation",backendType:"AI_CALL",name:"实时对话",desc:"与AI进行实时语音对话",price:0,freeTrialCount:0}};let a=null,r=0;async function s(){const s=Date.now();return a&&s-r<3e5?(console.log("[Payment] 使用缓存价格数据"),a):(console.log("[Payment] 开始获取服务价格API地址:",`${n.API_BASE}/api/pay/prices`),new Promise(((i,c)=>{e.index.request({url:`${n.API_BASE}/api/pay/prices`,method:"GET",success:e=>{if(console.log("[Payment] 价格API响应:",e),200===e.statusCode&&e.data){a=e.data,r=s,console.log("[Payment] 后端返回价格数据:",e.data);let n=0;e.data.forEach((e=>{console.log("[Payment] 处理价格项:",e);const a=t[e.serviceType];if(console.log("[Payment] 映射类型:",e.serviceType,"->",a),a){const t=Object.keys(o).find((e=>o[e].type===a));t&&o[t]&&(console.log("[Payment] 更新服务:",t,"价格:",e.price,"免费次数:",e.freeTrialCount),o[t].price=e.price,o[t].freeTrialCount=e.freeTrialCount||0,o[t].name=e.serviceName,o[t].desc=e.description||o[t].desc,n++)}else console.warn("[Payment] 未找到映射的前端类型:",e.serviceType)})),console.log("[Payment] 价格更新完成,共更新",n,"个服务"),console.log("[Payment] 最终SERVICE_TYPES:",JSON.stringify(o,null,2)),i(e.data)}else{if(console.error("[Payment] 获取价格失败,状态码:",e.statusCode),a)return void i(a);c(new Error("获取价格失败"))}},fail:e=>{console.error("[Payment] 获取价格请求失败:",e),a?i(a):c(e)}})})))}function i(){return`ORD${Date.now()}${Math.floor(1e4*Math.random()).toString().padStart(4,"0")}`}function c(){return{userId:e.index.getStorageSync("userId")||"",token:e.index.getStorageSync("token")||""}}async function l(t){try{const{userId:a,token:r}=c();if(!a)return!1;const s=Object.values(o).find((e=>e.type===t)),i=s?s.backendType:t;return await new Promise((t=>{e.index.request({url:`${n.API_BASE}/api/pay/check?userId=${a}&serviceType=${i}`,method:"GET",header:{"X-User-Id":a,Authorization:r?`Bearer ${r}`:""},success:e=>{if(200===e.statusCode&&e.data&&"boolean"==typeof e.data.paid){const n=e.data||{};if(console.log("[Payment] /api/pay/check 响应:",i,n),!1===n.paid)return void t(!1);const o="number"==typeof n.remainingTotal?n.remainingTotal:"number"==typeof n.remaining?n.remaining:"number"==typeof n.remainingCount?n.remainingCount:"number"==typeof n.remainingTimes?n.remainingTimes:null,a="number"==typeof n.freeTrialRemaining?n.freeTrialRemaining:"number"==typeof n.freeTrialLeft?n.freeTrialLeft:null;return"number"==typeof o&&o>0||"number"==typeof a&&a>0?void t(!0):void t(!1)}t(!1)},fail:()=>t(!1)})}))}catch(a){return console.error("[Payment] 后端资格校验异常:",a),!1}}async function d(t,a){try{if(await l(t))return console.log("[Payment] 后端校验通过,跳过支付:",t),{success:!0,message:"已具备使用资格,无需支付",skipPayment:!0}}catch(c){console.error("[Payment] 后端资格校验失败(忽略继续走支付):",c)}await s();const r=Object.values(o).find((e=>e.type===t));if(r&&0===r.price){console.log("[Payment] 服务价格为0跳过支付流程");const n={success:!0,orderNo:i(),payTime:(new Date).toISOString(),message:"免费服务,无需支付",free:!0};return e.index.showToast({title:"免费使用",icon:"success",duration:1500}),console.log("[Payment] 免费服务,直接返回成功:",n),n}try{e.index.showLoading({title:"创建订单中...",mask:!0});const r=await async function(t,a){const r="wechat",s=Object.values(o).find((e=>e.type===t)),i=s?s.backendType:t;console.log("[Payment] 服务类型转换:",t,"->",i);let c=null;{const n=e.index.getStorageSync("wx_openid");if(console.log("[Payment] wx_openid:",n),!n)return console.error("[Payment] 缺少wx_openid无法创建微信小程序支付订单"),Promise.reject(new Error("缺少openid请先退出并重新微信登录"));c="wx_openid_"+n}return console.log("[Payment] 下单参数:",{userId:a,serviceType:i,paymentChannel:r,bizId:c}),new Promise(((t,o)=>{e.index.request({url:`${n.API_BASE}/api/pay/orders`,method:"POST",header:{"Content-Type":"application/json",Authorization:`Bearer ${e.index.getStorageSync("token")||""}`},data:{userId:a,serviceType:i,paymentChannel:r,bizId:c},success:e=>{var n;200===e.statusCode&&e.data?(console.log("[Payment] 后端订单创建成功:",e.data),t(e.data)):(console.error("[Payment] 后端订单创建失败:",{statusCode:e.statusCode,data:e.data,header:e.header}),e.data&&e.data.message&&console.error("[Payment] 后端错误信息:",e.data.message),o(new Error((null==(n=e.data)?void 0:n.message)||"创建订单失败")))},fail:e=>{console.error("[Payment] 创建订单请求失败:",e),o(e)}})}))}(t,a);e.index.showLoading({title:"正在调起支付...",mask:!0});const s="wechat";let i;if("wechat"===s)i=await function(t){return new Promise(((o,a)=>{e.index.requestPayment({timeStamp:t.timeStamp||String(Date.now()),nonceStr:t.nonceStr||"",package:t.package||"",signType:t.signType||"RSA",paySign:t.paySign||"",success:r=>{console.log("[Payment] 微信支付成功:",r),e.index.request({url:`${n.API_BASE}/api/pay/orders/${t.orderNo}/sync/wechat`,method:"POST",header:{"Content-Type":"application/json",Authorization:`Bearer ${e.index.getStorageSync("token")||""}`},success:e=>{var n;200===e.statusCode?(console.log("[Payment] 订单同步成功:",e.data),o({success:!0,orderNo:t.orderNo,payTime:(new Date).toISOString(),message:"支付成功"})):(console.error("[Payment] 订单同步失败:",e),a(new Error((null==(n=e.data)?void 0:n.message)||"支付成功但订单同步失败")))},fail:e=>{console.error("[Payment] 订单同步请求失败:",e),a(new Error("支付成功但订单同步请求失败"))}})},fail:e=>{console.error("[Payment] 微信支付失败:",e),e.errMsg&&e.errMsg.includes("cancel")?a(new Error("用户取消支付")):a(new Error(e.errMsg||"支付失败"))}})}))}(r);else{if("alipay"!==s)throw new Error("不支持的支付渠道");i=await new Promise(((e,n)=>{}))}return e.index.hideLoading(),i}catch(d){throw e.index.hideLoading(),d}}exports.SERVICE_TYPES=o,exports.fetchServicePrices=s,exports.handlePaymentConfirm=async function(n,t){try{const o=c().userId,a=await d(t.serviceType,o);n.$refs.paymentModal&&n.$refs.paymentModal.paymentSuccess(),n.paymentModalData.show=!1,e.index.showToast({title:"支付成功",icon:"success"}),n._paymentOnSuccess&&n._paymentOnSuccess(a),n._paymentResolve&&n._paymentResolve(a)}catch(o){console.error("[Payment] 支付失败:",o),n.$refs.paymentModal&&n.$refs.paymentModal.paymentFailed(o),e.index.showToast({title:o.message||"支付失败",icon:"none"}),n._paymentOnFailed&&n._paymentOnFailed(o),n._paymentReject&&n._paymentReject(o)}},exports.mapOfficialVoiceDisplay=function(e){const n={"湾区大叔":"台湾","台湾小何":"台湾","双节棍小哥":"台湾","广州德哥":"广州","浩宇小哥":"大陆","湾湾小何":"台湾","北京小爷":"北京","京腔侃爷/Harmony":"北京","林北浩儿":"台湾","粤语小灿":"广东","泉州子轩":"福建","豫州子轩":"河南","呆萌川妹":"四川","广西远舟":"广西","妹坨洁儿":"湖南"};return(e||[]).map((e=>{if(!e)return e;if("OFFICIAL"!==(e.voice_type||"CLONE"))return e;const t=e.voice_name?String(e.voice_name):"",o=t&&n[t]?n[t]:"";return o&&t?0===t.indexOf(o+"-")?e:{...e,voice_name:`${o}-${t}`}:e}))},exports.showPaymentModal=async function(t,a,r,y){try{await s()}catch(p){}try{if(await l(a)){console.log("[Payment] 后端校验通过,跳过支付弹窗:",a);try{const t=await async function(t){try{const{userId:a,token:r}=c();if(!a)return null;const s=Object.values(o).find((e=>e.type===t)),i=s?s.backendType:t;return await new Promise((t=>{e.index.request({url:`${n.API_BASE}/api/pay/usage-preview?serviceType=${i}`,method:"GET",header:{"X-User-Id":a,Authorization:r?`Bearer ${r}`:""},success:e=>{200===e.statusCode&&e.data&&e.data.success?t(e.data):t(null)},fail:()=>t(null)})}))}catch(p){return null}}(a);t&&"FREE_TRIAL"===t.consumeType&&e.index.showToast({title:"本次使用免费次数",icon:"none",duration:1500})}catch(p){}return void(r&&r({success:!0,skipPayment:!0,message:"已具备使用资格,无需支付"}))}}catch(p){console.error("[Payment] 后端资格校验失败(忽略继续弹窗):",p)}const m=Object.values(o).find((e=>e.type===a));if(!m){const n=new Error("无效的服务类型");return console.error("[Payment] 显示支付弹窗失败:",n),e.index.showToast({title:"无效的服务类型",icon:"none"}),void(y&&y(n))}if(0!==m.price)(async function(e,n={}){try{await s();const t=Object.values(o).find((n=>n.type===e));if(!t)throw new Error("无效的服务类型");const a=i();return console.log("[Payment] 创建订单:",{orderNo:a,serviceType:e,serviceName:t.name,amount:t.price}),{orderNo:a,serviceType:e,serviceName:t.name,amount:t.price,service:t,...n}}catch(t){throw console.error("[Payment] 创建订单失败:",t),t}})(a).then((e=>{t.paymentModalData={show:!0,serviceType:m.type,serviceName:m.name,serviceDesc:m.desc,price:m.price,orderNo:e.orderNo},t._paymentOnSuccess=r,t._paymentOnFailed=y})).catch((n=>{console.error("[Payment] 创建订单失败:",n),e.index.showToast({title:n.message||"创建订单失败",icon:"none"}),y&&y(n)}));else{console.log("[Payment] 服务价格为0跳过支付弹窗直接执行");try{const e=c().userId,n=await d(a,e);r&&r(n)}catch(u){console.error("[Payment] 免费服务执行失败:",u),y&&y(u)}}};