Files
damai-wx/pages/custom/detail.js
MagicalKudzu f67fb8b6b3 更新
2025-12-17 14:19:22 +08:00

535 lines
12 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.

const requireCustom = wx.requireCustom
const customRequest = requireCustom(9887)
// S.Jv 生成 returnUrl
const S = requireCustom(2012)
// ko.A.getOpenId 获取 openid
const ko = requireCustom(3816)
// Uo.JV 获取 dmChannel
const Uo = requireCustom(5059)
// 生成 s1-s7 的参数
const Oo = requireCustom(3716)
Page({
data: {
id: '',
globalCode: 'ali.china.damai',
ttid: '#t#ip##_h5_2014',
getDetailParam: {
api: 'mtop.alibaba.detail.subpage.getdetail',
v: '2.0',
data: {},
},
detailResult: {},
getCustomerListParam: {
api: 'mtop.damai.wireless.user.customerlist.get',
v: '2.0',
data: {},
},
customerListResult: [],
orderBuildParam: {
api: 'mtop.damai.trade.order.build.h5',
v: '1.0',
data: {},
timeout: 15e3,
method: 'POST',
},
orderBuildResult: {},
orderCreateParam: {
api: 'mtop.damai.trade.order.create.h5',
v: '1.0',
data: {},
timeout: 15e3,
method: 'POST',
},
orderCreateResult: {},
dataTags: {},
viewDetail: {
mainImg: '',
status: '',
title: '',
time: '',
location: '',
price: '',
skuList: [],
},
selectedSku: '',
selectedCustomer: [],
customerList: [],
cd: {
days: '0',
hours: '00',
minutes: '00',
seconds: '00',
},
sellStartTime: '',
reBuildOrderCount: 0,
},
onLoad(options) {
if (!options.id) {
this.showToast('没有项目 ID')
return
}
this.setData({
id: options.id,
})
},
async onShow() {
if (!this.data.id) {
return
}
// 获取演出详情
let result = await this.getDetail()
if (result[0]) {
this.showToast(result[0].message)
return
}
let resultData = result[1]
this.setData({
detailResult: resultData,
})
const { itemBasicInfo, itemBuyBtn, perform } = resultData
// 获取观演人
result = await this.getCustomerList()
if (result[0]) {
this.showToast(result[0].message)
return
}
resultData = result[1]
this.setData({
customerListResult: resultData,
})
const viewDetail = {
mainImg: itemBasicInfo.mainImageUrl,
status: itemBuyBtn.btnText,
title: itemBasicInfo.itemTitle,
time: perform.performName,
location: itemBasicInfo.venueName,
price: itemBasicInfo.priceRange,
skuList: perform.skuList,
}
this.setData({
viewDetail,
selectedSku: perform.skuList[0].skuId,
customerList: resultData,
sellStartTime: itemBuyBtn.sellStartTime || '',
})
this.startCountdown(this.data.sellStartTime)
},
onUnload() {
this.stopCountdown()
},
onHide() {
this.stopCountdown()
},
getDetail() {
const param = {
bizCode: 'ali.china.damai',
scenario: 'itemsku',
itemId: this.data.id,
exParams: JSON.stringify({
dataType: 4,
dataId: '',
activityId: '',
}),
}
return new customRequest.p({
...this.data.getDetailParam,
...param,
}).create()
},
getCustomerList() {
const param = {
customerType: 'default',
platform: '42',
comboChannel: '4',
}
return new customRequest.p({
...this.data.getCustomerListParam,
...param,
}).create()
},
buildOrder() {
const { itemBasicInfo, actionControl } = this.data.detailResult
const { reBuildOrderCount, selectedCustomer, selectedSku, ttid, orderBuildParam, globalCode } = this.data
if (!itemBasicInfo.t) {
return [
{
message: '没有t',
},
]
}
if (selectedCustomer.length == 0) {
return [
{
message: '请选择观演人',
},
]
}
const { tradeControl } = actionControl
const exParams = {
channel: 'damai_app',
damai: '1',
umpChannel: '100031002',
subChannel: 'damai@weixin_weapp',
atomSplit: 1,
signKey: itemBasicInfo.t,
rtc: tradeControl.rtc ? 1 : 0,
}
const personCount = selectedCustomer.length
const param = {
buyNow: true,
exParams: JSON.stringify({
...exParams,
serviceVersion: '2.0.0',
customerType: 'default',
}),
buyParam: itemBasicInfo.itemId + '_' + personCount + '_' + selectedSku,
}
this.setData({
dataTags: param,
})
const currentPages = getCurrentPages()
const lastE = currentPages.length - 1
currentPages[lastE].options = {
...param,
exParams: JSON.stringify({
...exParams,
subChannel: 'weapp@damai_h5',
}),
spm: 'a2obt.project.bottom.dbuy',
}
return new customRequest.p({
...orderBuildParam,
...param,
ext_querys: {
ttid: ttid,
},
headers: {
globalCode: globalCode,
},
ext_headers: {
globalCode: globalCode,
},
}).create()
},
async createOrder() {
const { detailResult, orderBuildResult, dataTags, selectedCustomer, customerList, selectedSku } = this.data
const { itemBasicInfo, perform } = detailResult
const { global, hierarchy, data, linkage } = orderBuildResult
const step1 = {
subChannel: Uo.JV(),
returnUrl: S.Jv({
page: 'shows_pay_result',
query: {
itemId: itemBasicInfo.itemId,
},
}),
serviceVersion: '2.0.0',
wxOpenId: ko.A.getOpenId(),
}
const quantity = selectedCustomer.length
const step2 = {
$taroTimestamp: Date.now(),
...dataTags,
isQuickBuy: false,
isSpliceOrder: false,
itemId: itemBasicInfo.itemId,
quantity: quantity,
skuId: selectedSku,
spm: 'a2obt.project.buttom.dbuy',
}
const step2DataTags = this.genDataTags(step2)
if (step2DataTags) {
step1.dataTags = step2DataTags
}
const { structure } = hierarchy
const blocks = structure.dmViewerBlock_DmViewerBlock
const compName = blocks[blocks.length - 1]
data[compName]['componentDataName'] = compName
data[compName]['componentType'] = 'dmviewer'
data[compName]['inParentIndex'] = 1
data[compName]['isInParentLastIndex'] = true
data[compName]['parentComponentName'] = 'dmViewerBlock_DmViewerBlock'
data[compName]['submit'] = true
data[compName].fields.selectedNum = quantity
const indices = selectedCustomer.map((id) => customerList.findIndex((obj) => obj.identityHash == id))
for (let i = 0; i < indices.length; i++) {
const index = indices[i]
data[compName].fields.viewerList[index].isUsed = true
}
const requestData = {
params: JSON.stringify({
data: JSON.stringify(data),
linkage: JSON.stringify({
common: linkage.common,
signature: linkage.signature,
}),
hierarchy: JSON.stringify({
structure: hierarchy.structure,
}),
}),
feature: JSON.stringify(step1),
}
requestData[global.secretKey] = global.secretValue
const s17 = await Oo.A.getWasmHeader(itemBasicInfo.itemId)
const h = JSON.stringify({
...s17,
...JSON.parse(requestData.feature),
})
const v = {
...requestData,
feature: h,
}
const param = {
...this.data.orderCreateParam,
}
const querys = {
isSec: 1,
AntiCreep: true,
ttid: this.data.ttid,
tb_eagleeyex_scm_project: '20190509-aone2-join-test',
}
querys[global.secretKey] = global.secretValue
return new customRequest.p({
...this.data.orderBuildParam,
...param,
data: v,
ext_querys: querys,
headers: {
globalCode: this.data.globalCode,
},
ext_headers: {
globalCode: this.data.globalCode,
},
}).create()
},
async goPay() {
const { itemBasicInfo } = this.data.detailResult
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
if (!itemBasicInfo.t) {
console.log('没有t')
// 获取演出详情
let result = await this.getDetail()
if (result[0]) {
this.showToast(result[0].message)
return
}
let resultData = result[1]
this.setData({
detailResult: resultData,
})
await sleep(200);
console.log('重试')
await this.goPay();
return;
}
let buildOrderResult = await this.buildOrder()
if (buildOrderResult[0]) {
this.showToast(buildOrderResult[0].message)
await sleep(200);
console.log('重试')
await this.goPay();
return
}
this.setData({
orderBuildResult: buildOrderResult[1],
})
let createOrderResult = await this.createOrder()
if (createOrderResult[0]) {
this.showToast(createOrderResult[0].message)
return
}
this.setData({
orderCreateResult: createOrderResult[1],
})
const payInfo = JSON.parse(decodeURIComponent(createOrderResult[1].alipayWapCashierUrl))
wx.requestPayment({
signType: 'MD5',
timeStamp: payInfo.timeStamp + '',
nonceStr: payInfo.nonceStr,
package: payInfo.package,
paySign: payInfo.paySign,
success: function (e) {
if ('requestPayment:ok' === e.errMsg) {
wx.showToast({ title: '支付成功', icon: 'none' })
} else {
wx.showToast({ title: '支付失败', icon: 'none' })
}
},
fail: function () {
wx.showToast({ title: '拉起支付失败', icon: 'none' })
},
})
},
showToast(msg) {
wx.showToast({
title: msg,
icon: 'none',
})
},
onSelectSku(e) {
const id = e.currentTarget.dataset.id
this.setData({
selectedSku: id,
})
},
// 点击整行切换选中
onToggleSelect(e) {
const index = e.currentTarget.dataset.index
const options = this.data.customerList.slice()
const item = options[index]
item['checked'] = item.checked == undefined ? false : item.checked
item['checked'] = !item['checked']
options[index] = item
const selectedIds = options.filter((x) => x.checked).map((x) => x.identityHash)
this.setData({
customerList: options,
selectedCustomer: selectedIds,
})
},
startCountdown(rawTs) {
this.stopCountdown()
const target = this.normalizeTimestamp(rawTs)
if (!target) return
// 先立刻刷新一次,避免首次渲染延迟 1s
this.tickCountdown(target)
this._cdTimer = setInterval(() => {
this.tickCountdown(target)
}, 1000)
},
stopCountdown() {
if (this._cdTimer) {
clearInterval(this._cdTimer)
this._cdTimer = null
}
},
tickCountdown(targetMs) {
const now = Date.now()
let diff = targetMs - now
if (diff <= 0) {
// 归零并触发结束回调
this.setData({
cd: { days: '0', hours: '00', minutes: '00', seconds: '00' },
})
this.stopCountdown()
this.onCountdownFinish() // 自动执行方法
return
}
const totalSeconds = Math.floor(diff / 1000)
const days = Math.floor(totalSeconds / (24 * 3600))
const remain1 = totalSeconds % (24 * 3600)
const hours = Math.floor(remain1 / 3600)
const remain2 = remain1 % 3600
const minutes = Math.floor(remain2 / 60)
const seconds = remain2 % 60
this.setData({
cd: {
days: String(days),
hours: this.pad2(hours),
minutes: this.pad2(minutes),
seconds: this.pad2(seconds),
},
})
},
normalizeTimestamp(ts) {
const n = Number(ts)
if (!Number.isFinite(n) || n <= 0) return null
// 10位通常是秒级13位通常是毫秒级
// 这里用阈值判断:小于 1e12 认为是秒
return n < 1e12 ? n * 1000 : n
},
pad2(n) {
return n < 10 ? '0' + n : String(n)
},
// 倒计时结束后自动执行的方法(你把业务逻辑写这里)
onCountdownFinish() {
// 示例:倒计时结束后执行你的动作
// 1) 变更状态
// 2) 刷新票档/库存
// 3) 弹窗提示
this.showToast('倒计时结束')
// TODO你自己的逻辑
// this.refreshSkus();
this.setData({
sellStartTime: '',
})
// this.goPay()
},
genDataTags(param) {
const result = []
if (param.utm) {
result.push('utm:'.concat(param.utm))
}
if (param.sqm) {
result.push('sqm:'.concat(param.sqm))
}
return result.length > 0 ? result.join(';') : ''
},
})