369 lines
10 KiB
JavaScript
369 lines
10 KiB
JavaScript
// pages/fighter-recharge/fighter-deposit.js — 平台履约金/保证金独立页
|
||
import request from '../../utils/request';
|
||
import PopupService from '../../services/popupService.js';
|
||
import { ensurePhoneAuth } from '../../utils/phone-auth.js';
|
||
import { ICON_KEYS, resolveConfiguredIcon, resolveMiniappIcon, ICON_FOLDER, refreshPindaoConfig } from '../../utils/miniapp-icons.js';
|
||
import { resolveAvatarFromStorage, onAvatarImageError } from '../../utils/avatar.js';
|
||
|
||
const app = getApp();
|
||
|
||
const DEFAULT_RULES = [
|
||
'履约金有效期为永久有效',
|
||
'超过15天未接单,可联系客服申请退还',
|
||
'缴纳后可优先接锁单/平台单等待遇',
|
||
];
|
||
|
||
const DEFAULT_BENEFITS = [
|
||
{ label: '平台订单优先', key: ICON_KEYS.FIGHTER_DEPOSIT_BENEFIT_1 },
|
||
{ label: '快人一步', key: ICON_KEYS.FIGHTER_DEPOSIT_BENEFIT_2 },
|
||
{ label: '优质接单', key: ICON_KEYS.FIGHTER_DEPOSIT_BENEFIT_3 },
|
||
{ label: '解锁平台单', key: ICON_KEYS.FIGHTER_DEPOSIT_BENEFIT_4 },
|
||
];
|
||
|
||
Page({
|
||
data: {
|
||
imgUrls: { pageBg: '', hero: '' },
|
||
avatarUrl: '',
|
||
nickname: '',
|
||
uid: '',
|
||
yajin: 0,
|
||
yajinDisplay: '0.00',
|
||
yajinActive: false,
|
||
depositRules: DEFAULT_RULES,
|
||
depositBenefits: DEFAULT_BENEFITS,
|
||
agreed: false,
|
||
payAmountLabel: '',
|
||
yajinAmount: '100',
|
||
quickAmounts: ['100', '500', '1000', '5000'],
|
||
showAmountModal: false,
|
||
showPayMethodModal: false,
|
||
showBalanceModal: false,
|
||
showConfirmModal: false,
|
||
balanceOptions: [],
|
||
selectedBalanceId: null,
|
||
selectedBalanceInfo: null,
|
||
currentYajinAmount: null,
|
||
currentDingdanid: '',
|
||
payLoading: false,
|
||
loadingText: '处理中...',
|
||
},
|
||
|
||
onLoad(options) {
|
||
this._jumpParams = options || {};
|
||
this.initImages();
|
||
this.loadUserInfo();
|
||
},
|
||
|
||
onHide() {
|
||
this.selectComponent('#popupNotice')?.cleanup?.();
|
||
},
|
||
|
||
async onShow() {
|
||
const phoneOk = await ensurePhoneAuth({ redirect: true, role: 'dashou' });
|
||
if (!phoneOk) return;
|
||
this.registerNotification();
|
||
this.loadYajin();
|
||
this.refreshConfiguredIcons();
|
||
PopupService.checkAndShow(this, 'dashouchongzhi');
|
||
const preset = this._jumpParams?.presetAmount || this._jumpParams?.requiredYajin;
|
||
if (preset && parseFloat(preset) > 0) {
|
||
this.setData({ yajinAmount: String(parseInt(preset, 10)) });
|
||
}
|
||
},
|
||
|
||
registerNotification() {
|
||
const comp = this.selectComponent('#global-notification');
|
||
if (comp?.showNotification) {
|
||
app.globalData.globalNotification = {
|
||
show: (data) => comp.showNotification(data),
|
||
hide: () => comp.hideNotification(),
|
||
};
|
||
}
|
||
},
|
||
|
||
initImages() {
|
||
const fb = (key) => `${ICON_FOLDER}/${key}.png`;
|
||
const depositBenefits = DEFAULT_BENEFITS.map((item) => ({
|
||
label: item.label,
|
||
iconUrl: resolveMiniappIcon(app, item.key, fb(item.key)),
|
||
}));
|
||
this.setData({
|
||
imgUrls: {
|
||
pageBg: resolveConfiguredIcon(app, ICON_KEYS.FIGHTER_DEPOSIT_BG),
|
||
hero: resolveConfiguredIcon(app, ICON_KEYS.FIGHTER_DEPOSIT_HERO),
|
||
},
|
||
depositBenefits,
|
||
});
|
||
},
|
||
|
||
async refreshConfiguredIcons() {
|
||
try {
|
||
await refreshPindaoConfig(app);
|
||
} catch (e) {
|
||
console.warn('refreshConfiguredIcons failed', e);
|
||
}
|
||
this.initImages();
|
||
this.loadUserInfo();
|
||
},
|
||
|
||
loadUserInfo() {
|
||
const gd = app.globalData || {};
|
||
this.setData({
|
||
avatarUrl: resolveAvatarFromStorage(app),
|
||
nickname: gd.dashouNicheng || gd.nicheng || '打手',
|
||
uid: wx.getStorageSync('uid') || gd.uid || '',
|
||
});
|
||
},
|
||
|
||
onAvatarError() {
|
||
onAvatarImageError(this, 'avatarUrl', app);
|
||
},
|
||
|
||
loadYajin() {
|
||
const yajin = parseFloat(app.globalData.yajin || 0) || 0;
|
||
this.setData({
|
||
yajin,
|
||
yajinDisplay: yajin.toFixed(2),
|
||
yajinActive: yajin > 0,
|
||
});
|
||
},
|
||
|
||
toggleAgree() {
|
||
this.setData({ agreed: !this.data.agreed });
|
||
},
|
||
|
||
onTapPay() {
|
||
if (!this.data.agreed) {
|
||
wx.showToast({ title: '请先阅读并同意缴纳规则', icon: 'none' });
|
||
return;
|
||
}
|
||
this.setData({ showAmountModal: true });
|
||
},
|
||
|
||
hideAmountModal() {
|
||
this.setData({ showAmountModal: false });
|
||
},
|
||
|
||
onYajinInput(e) {
|
||
let v = (e.detail.value || '').replace(/[^\d]/g, '');
|
||
if (v) {
|
||
const n = parseInt(v, 10);
|
||
if (n > 10000) v = '10000';
|
||
if (n < 1) v = '1';
|
||
}
|
||
this.setData({ yajinAmount: v });
|
||
},
|
||
|
||
setQuickAmount(e) {
|
||
this.setData({ yajinAmount: e.currentTarget.dataset.amount });
|
||
},
|
||
|
||
onConfirmAmount() {
|
||
const amount = this.data.yajinAmount;
|
||
if (!amount || amount < 1 || amount > 10000) {
|
||
wx.showToast({ title: '请输入1-10000元', icon: 'none' });
|
||
return;
|
||
}
|
||
this.hideAmountModal();
|
||
this.setData({
|
||
currentYajinAmount: amount,
|
||
payAmountLabel: `(¥ ${amount})`,
|
||
showPayMethodModal: true,
|
||
});
|
||
},
|
||
|
||
hidePayMethodModal() {
|
||
this.setData({ showPayMethodModal: false });
|
||
},
|
||
|
||
onPayMethodSelect(e) {
|
||
const method = e.currentTarget.dataset.method;
|
||
this.hidePayMethodModal();
|
||
if (method === 'wx') {
|
||
this.setData({ yajinAmount: this.data.currentYajinAmount }, () => this.handleYajinPay());
|
||
} else {
|
||
this.fetchBalanceOptions();
|
||
}
|
||
},
|
||
|
||
async fetchBalanceOptions() {
|
||
this.showLoading('获取抵扣信息...');
|
||
try {
|
||
const res = await request({
|
||
url: '/shangpin/czhqdy',
|
||
method: 'POST',
|
||
data: {
|
||
leixing: 2,
|
||
yajin_jine: parseInt(this.data.currentYajinAmount, 10),
|
||
},
|
||
});
|
||
if (res.data.code === 200) {
|
||
this.setData({ balanceOptions: res.data.data || [], showBalanceModal: true });
|
||
} else {
|
||
wx.showToast({ title: res.data.message || '获取失败', icon: 'none' });
|
||
}
|
||
} catch (err) {
|
||
wx.showToast({ title: '网络错误', icon: 'none' });
|
||
} finally {
|
||
this.hideLoading();
|
||
}
|
||
},
|
||
|
||
hideBalanceModal() {
|
||
this.setData({ showBalanceModal: false });
|
||
},
|
||
|
||
onBalanceSelect(e) {
|
||
const id = e.currentTarget.dataset.id;
|
||
const selected = this.data.balanceOptions.find((o) => o.id === id);
|
||
if (!selected) return;
|
||
this.setData({
|
||
selectedBalanceId: id,
|
||
selectedBalanceInfo: selected,
|
||
showConfirmModal: true,
|
||
showBalanceModal: false,
|
||
});
|
||
},
|
||
|
||
hideConfirmModal() {
|
||
this.setData({ showConfirmModal: false });
|
||
},
|
||
|
||
async confirmBalancePay() {
|
||
const { selectedBalanceId, currentYajinAmount } = this.data;
|
||
if (!selectedBalanceId) return;
|
||
this.hideConfirmModal();
|
||
this.showLoading('抵扣支付中...');
|
||
try {
|
||
const res = await request({
|
||
url: '/shangpin/dsqrgmdh',
|
||
method: 'POST',
|
||
data: {
|
||
leixing: 2,
|
||
shenfen_id: selectedBalanceId,
|
||
yajin_jine: parseInt(currentYajinAmount, 10),
|
||
},
|
||
});
|
||
if (res.data.code === 200) {
|
||
const data = res.data.data || {};
|
||
if (data.yajin !== undefined) app.globalData.yajin = data.yajin;
|
||
this.loadYajin();
|
||
wx.showToast({ title: '缴纳成功', icon: 'success' });
|
||
} else {
|
||
wx.showToast({ title: res.data.message || '购买失败', icon: 'none' });
|
||
}
|
||
} catch (err) {
|
||
wx.showToast({ title: '网络错误', icon: 'none' });
|
||
} finally {
|
||
this.hideLoading();
|
||
}
|
||
},
|
||
|
||
confirmWechatPurchase() {
|
||
return new Promise((resolve) => {
|
||
wx.showModal({
|
||
title: '确认微信支付',
|
||
content: '您即将通过微信支付缴纳履约金。购买成功后不可随意退款,请确认无误后再继续。',
|
||
confirmText: '确认购买',
|
||
cancelText: '再想想',
|
||
success: (res) => resolve(!!res.confirm),
|
||
fail: () => resolve(false),
|
||
});
|
||
});
|
||
},
|
||
|
||
async handleYajinPay() {
|
||
const amount = this.data.yajinAmount;
|
||
if (!amount || amount < 1 || amount > 10000) {
|
||
wx.showToast({ title: '请输入1-10000元', icon: 'none' });
|
||
return;
|
||
}
|
||
if (!(await this.confirmWechatPurchase())) return;
|
||
this.showLoading('发起支付中...');
|
||
try {
|
||
const res = await request({
|
||
url: '/shangpin/yajingoumai',
|
||
method: 'POST',
|
||
data: { jine: parseInt(amount, 10) },
|
||
});
|
||
if (res.data.code === 200) {
|
||
this.setData({ currentDingdanid: res.data.dingdanid });
|
||
await this.wechatPay(res.data.payParams);
|
||
} else {
|
||
wx.showToast({ title: res.data.message || '支付发起失败', icon: 'none' });
|
||
}
|
||
} catch (err) {
|
||
wx.showToast({ title: '支付失败', icon: 'none' });
|
||
} finally {
|
||
this.hideLoading();
|
||
}
|
||
},
|
||
|
||
wechatPay(payParams) {
|
||
return new Promise((resolve, reject) => {
|
||
wx.requestPayment({
|
||
timeStamp: payParams.timeStamp,
|
||
nonceStr: payParams.nonceStr,
|
||
package: payParams.package,
|
||
signType: payParams.signType || 'MD5',
|
||
paySign: payParams.paySign,
|
||
success: async () => {
|
||
wx.showToast({ title: '支付成功!确认中...', icon: 'none' });
|
||
try {
|
||
await this.startPolling();
|
||
resolve();
|
||
} catch (e) {
|
||
reject(e);
|
||
}
|
||
},
|
||
fail: async (res) => {
|
||
wx.showToast({ title: res.errMsg?.includes('cancel') ? '已取消支付' : '支付失败', icon: 'none' });
|
||
try {
|
||
await request({
|
||
url: '/shangpin/yajinshibai',
|
||
method: 'POST',
|
||
data: { dingdanid: this.data.currentDingdanid },
|
||
});
|
||
} catch (e) { /* ignore */ }
|
||
reject(new Error(res.errMsg));
|
||
},
|
||
});
|
||
});
|
||
},
|
||
|
||
async startPolling() {
|
||
const dingdanid = this.data.currentDingdanid;
|
||
if (!dingdanid) return;
|
||
this.showLoading('确认支付结果...');
|
||
for (let i = 0; i < 10; i++) {
|
||
try {
|
||
const res = await request({
|
||
url: '/shangpin/yajinlunxun',
|
||
method: 'POST',
|
||
data: { dingdanid },
|
||
});
|
||
if (res.data.code === 200) {
|
||
if (res.data.yajin !== undefined) app.globalData.yajin = res.data.yajin;
|
||
this.loadYajin();
|
||
this.hideLoading();
|
||
wx.showToast({ title: '履约金缴纳成功', icon: 'success' });
|
||
return;
|
||
}
|
||
} catch (e) { /* retry */ }
|
||
await new Promise((r) => setTimeout(r, 2000));
|
||
}
|
||
this.hideLoading();
|
||
wx.showToast({ title: '确认超时,请稍后查看余额', icon: 'none' });
|
||
},
|
||
|
||
showLoading(text) {
|
||
this.setData({ payLoading: true, loadingText: text || '处理中...' });
|
||
},
|
||
|
||
hideLoading() {
|
||
this.setData({ payLoading: false });
|
||
},
|
||
|
||
stopPropagation() {},
|
||
});
|