535 lines
12 KiB
JavaScript
535 lines
12 KiB
JavaScript
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(';') : ''
|
||
},
|
||
})
|