统一排行榜对齐星雀UI,页面资源后台配置实时刷新
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
178
miniprogram/pages/cfss/components/fakuan-pay/fakuan-pay.js
Normal file
178
miniprogram/pages/cfss/components/fakuan-pay/fakuan-pay.js
Normal file
@@ -0,0 +1,178 @@
|
||||
// components/fakuan-list/fakuan-pay/fakuan-pay.js
|
||||
import request from '../../../../utils/request.js'; // 路径保持您原来的样子
|
||||
|
||||
Component({
|
||||
properties: {
|
||||
visible: { type: Boolean, value: false, observer: 'onVisibleChange' },
|
||||
fadan: { type: Object, value: null } // { id, fakuanjine }
|
||||
},
|
||||
|
||||
data: {
|
||||
step: 'method', // method / balance / confirm / loading
|
||||
balanceOptions: [],
|
||||
selectedBalance: null,
|
||||
loadingText: '',
|
||||
payLoading: false,
|
||||
dingdanid: '' // 微信支付内部订单ID
|
||||
},
|
||||
|
||||
methods: {
|
||||
onVisibleChange(val) {
|
||||
if (val) {
|
||||
// 每次打开重置为支付方式选择
|
||||
this.setData({ step: 'method', balanceOptions: [], selectedBalance: null });
|
||||
}
|
||||
},
|
||||
|
||||
close() {
|
||||
this.setData({ visible: false });
|
||||
this.triggerEvent('close');
|
||||
},
|
||||
|
||||
// 选择支付方式
|
||||
async chooseMethod(e) {
|
||||
const method = e.currentTarget.dataset.method;
|
||||
if (method === 'wx') {
|
||||
this.wxPay();
|
||||
} else if (method === 'balance') {
|
||||
this.fetchBalanceOptions();
|
||||
}
|
||||
},
|
||||
|
||||
// ========== 微信支付流程 ==========
|
||||
async wxPay() {
|
||||
this.setData({ step: 'loading', loadingText: '发起支付中...' });
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/yonghu/fkjn',
|
||||
method: 'POST',
|
||||
data: { fadan_id: this.properties.fadan.id }
|
||||
});
|
||||
if (res.data.code !== 200) throw new Error(res.data.msg || '下单失败');
|
||||
|
||||
// 🔥 唯一修改点:后端返回格式 { code:200, payParams:{...}, dingdanid:'...' }
|
||||
const payParams = res.data.payParams;
|
||||
const dingdanid = res.data.dingdanid;
|
||||
|
||||
this.setData({ dingdanid });
|
||||
await this.requestWxPayment(payParams);
|
||||
} catch (e) {
|
||||
this.setData({ step: 'method' });
|
||||
wx.showToast({ title: e.message, icon: 'none' });
|
||||
}
|
||||
},
|
||||
|
||||
async requestWxPayment(payParams) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!payParams || !payParams.timeStamp || !payParams.paySign) {
|
||||
wx.showToast({ title: '支付参数错误', icon: 'none' });
|
||||
reject(new Error('支付参数错误'));
|
||||
return;
|
||||
}
|
||||
wx.requestPayment({
|
||||
timeStamp: payParams.timeStamp,
|
||||
nonceStr: payParams.nonceStr,
|
||||
package: payParams.package,
|
||||
signType: payParams.signType || 'MD5',
|
||||
paySign: payParams.paySign,
|
||||
success: () => {
|
||||
this.pollPayStatus();
|
||||
resolve();
|
||||
},
|
||||
fail: (err) => {
|
||||
this.setData({ step: 'method' });
|
||||
this.notifyPayFail();
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
async pollPayStatus() {
|
||||
this.setData({ step: 'loading', loadingText: '确认支付结果...' });
|
||||
for (let i = 0; i < 10; i++) {
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/yonghu/fkzffc',
|
||||
method: 'POST',
|
||||
data: { dingdanid: this.data.dingdanid }
|
||||
});
|
||||
if (res.data.code === 200) {
|
||||
this.triggerEvent('success');
|
||||
this.close();
|
||||
wx.showToast({ title: '缴纳成功', icon: 'success' });
|
||||
return;
|
||||
}
|
||||
} catch (e) {}
|
||||
await new Promise(r => setTimeout(r, 2000));
|
||||
}
|
||||
this.setData({ step: 'method' });
|
||||
wx.showToast({ title: '支付确认超时', icon: 'none' });
|
||||
},
|
||||
|
||||
async notifyPayFail() {
|
||||
try {
|
||||
await request({
|
||||
url: '/yonghu/fkzfsb',
|
||||
method: 'POST',
|
||||
data: { dingdanid: this.data.dingdanid }
|
||||
});
|
||||
} catch (e) {}
|
||||
},
|
||||
|
||||
// ========== 佣金抵扣流程 ==========
|
||||
async fetchBalanceOptions() {
|
||||
this.setData({ step: 'loading', loadingText: '获取可抵扣身份...' });
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/shangpin/czhqdy',
|
||||
method: 'POST',
|
||||
data: {
|
||||
leixing: 4,
|
||||
fadan_id: this.properties.fadan.id,
|
||||
jine: this.properties.fadan.fakuanjine
|
||||
}
|
||||
});
|
||||
if (res.data.code !== 200) throw new Error(res.data.msg || '获取失败');
|
||||
this.setData({ balanceOptions: res.data.data, step: 'balance' });
|
||||
} catch (e) {
|
||||
this.setData({ step: 'method' });
|
||||
wx.showToast({ title: e.message, icon: 'none' });
|
||||
}
|
||||
},
|
||||
|
||||
selectBalance(e) {
|
||||
const id = e.currentTarget.dataset.id;
|
||||
const info = this.data.balanceOptions.find(opt => opt.id === id);
|
||||
if (!info) return;
|
||||
this.setData({ selectedBalance: info, step: 'confirm' });
|
||||
},
|
||||
|
||||
backToMethod() {
|
||||
this.setData({ step: 'method' });
|
||||
},
|
||||
|
||||
async confirmBalance() {
|
||||
if (!this.data.selectedBalance) return;
|
||||
this.setData({ step: 'loading', loadingText: '抵扣扣款中...' });
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/shangpin/dsqrgmdh',
|
||||
method: 'POST',
|
||||
data: {
|
||||
leixing: 4,
|
||||
shenfen_id: this.data.selectedBalance.id,
|
||||
fadan_id: this.properties.fadan.id
|
||||
}
|
||||
});
|
||||
if (res.data.code !== 200) throw new Error(res.data.msg || '抵扣失败');
|
||||
this.triggerEvent('success');
|
||||
this.close();
|
||||
wx.showToast({ title: '缴纳成功', icon: 'success' });
|
||||
} catch (e) {
|
||||
this.setData({ step: 'method' });
|
||||
wx.showToast({ title: e.message, icon: 'none' });
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"component": true
|
||||
}
|
||||
61
miniprogram/pages/cfss/components/fakuan-pay/fakuan-pay.wxml
Normal file
61
miniprogram/pages/cfss/components/fakuan-pay/fakuan-pay.wxml
Normal file
@@ -0,0 +1,61 @@
|
||||
<!-- 支付组件模板 -->
|
||||
<view wx:if="{{ visible }}" class="pay-mask" catchtouchmove="prevent">
|
||||
<!-- 支付方式选择 -->
|
||||
<view wx:if="{{ step === 'method' }}" class="pay-panel">
|
||||
<view class="pay-head">
|
||||
<text class="pay-title">选择支付方式</text>
|
||||
<view class="pay-close" bindtap="close">✕</view>
|
||||
</view>
|
||||
<view class="pay-body">
|
||||
<view class="method-item" bindtap="chooseMethod" data-method="wx">
|
||||
<text class="method-icon">💳</text>
|
||||
<text class="method-name">微信支付</text>
|
||||
</view>
|
||||
<view class="method-item" bindtap="chooseMethod" data-method="balance">
|
||||
<text class="method-icon">💰</text>
|
||||
<text class="method-name">佣金抵扣</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 余额抵扣身份选择 -->
|
||||
<view wx:if="{{ step === 'balance' }}" class="pay-panel">
|
||||
<view class="pay-head">
|
||||
<text class="pay-title">选择抵扣身份</text>
|
||||
<view class="pay-close" bindtap="close">✕</view>
|
||||
</view>
|
||||
<scroll-view scroll-y class="pay-body">
|
||||
<view wx:for="{{ balanceOptions }}" wx:key="id" class="balance-item" bindtap="selectBalance" data-id="{{ item.id }}">
|
||||
<text class="balance-name">{{ item.jieshao }}</text>
|
||||
<text class="balance-amount">需¥{{ item.xuyao }}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 余额抵扣确认 -->
|
||||
<view wx:if="{{ step === 'confirm' }}" class="pay-panel">
|
||||
<view class="pay-head">
|
||||
<text class="pay-title">确认抵扣</text>
|
||||
<view class="pay-close" bindtap="close">✕</view>
|
||||
</view>
|
||||
<view class="pay-body">
|
||||
<view class="confirm-row">
|
||||
<text>抵扣身份:{{ selectedBalance.jieshao }}</text>
|
||||
</view>
|
||||
<view class="confirm-row">
|
||||
<text>需扣除:¥{{ selectedBalance.xuyao }}</text>
|
||||
</view>
|
||||
<text class="confirm-tip">确认后将从您的佣金/分红中扣除</text>
|
||||
</view>
|
||||
<view class="pay-foot">
|
||||
<view class="btn default" bindtap="backToMethod">取消</view>
|
||||
<view class="btn primary" bindtap="confirmBalance">确认</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付加载动画 -->
|
||||
<view wx:if="{{ step === 'loading' }}" class="pay-mask loading-box">
|
||||
<view class="spinner"></view>
|
||||
<text class="loading-text">{{ loadingText }}</text>
|
||||
</view>
|
||||
</view>
|
||||
59
miniprogram/pages/cfss/components/fakuan-pay/fakuan-pay.wxss
Normal file
59
miniprogram/pages/cfss/components/fakuan-pay/fakuan-pay.wxss
Normal file
@@ -0,0 +1,59 @@
|
||||
/* 支付组件样式,与罚款列表统一 */
|
||||
.pay-mask {
|
||||
position: fixed; top: 0; left: 0; right: 0; bottom: 0;
|
||||
background: rgba(0,0,0,0.5); z-index: 2000;
|
||||
display: flex; align-items: flex-end; justify-content: center;
|
||||
}
|
||||
.pay-panel {
|
||||
width: 100%; max-height: 85vh; background: #fff;
|
||||
border-radius: 24rpx 24rpx 0 0; display: flex; flex-direction: column; overflow: hidden;
|
||||
}
|
||||
.pay-head {
|
||||
display: flex; justify-content: space-between; align-items: center;
|
||||
padding: 28rpx 30rpx 16rpx; border-bottom: 1px solid #eee;
|
||||
}
|
||||
.pay-title { font-size: 32rpx; font-weight: 600; }
|
||||
.pay-close {
|
||||
width: 44rpx; height: 44rpx; background: #f5f5f5;
|
||||
border-radius: 50%; display: flex; align-items: center; justify-content: center;
|
||||
font-size: 26rpx; color: #888;
|
||||
}
|
||||
.pay-body { padding: 20rpx 30rpx; flex: 1; overflow-y: auto; }
|
||||
.pay-foot {
|
||||
display: flex; padding: 16rpx 30rpx 30rpx; gap: 20rpx; border-top: 1px solid #eee;
|
||||
}
|
||||
|
||||
.method-item {
|
||||
display: flex; flex-direction: column; align-items: center;
|
||||
padding: 40rpx 30rpx; background: #f9f9f9; border-radius: 20rpx; margin-bottom: 20rpx;
|
||||
}
|
||||
.method-icon { font-size: 48rpx; margin-bottom: 12rpx; }
|
||||
.method-name { font-size: 28rpx; color: #333; }
|
||||
|
||||
.balance-item {
|
||||
display: flex; justify-content: space-between; align-items: center;
|
||||
padding: 24rpx 0; border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
.balance-name { font-size: 28rpx; color: #333; }
|
||||
.balance-amount { font-size: 28rpx; color: #E53935; }
|
||||
|
||||
.confirm-row { font-size: 28rpx; margin-bottom: 16rpx; }
|
||||
.confirm-tip { font-size: 24rpx; color: #888; display: block; margin-top: 20rpx; }
|
||||
|
||||
.loading-box {
|
||||
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
||||
background: rgba(0,0,0,0.6);
|
||||
}
|
||||
.spinner {
|
||||
width: 60rpx; height: 60rpx;
|
||||
border: 4rpx solid rgba(255,255,255,0.3);
|
||||
border-top-color: #fff; border-radius: 50%;
|
||||
animation: spin 1s linear infinite; margin-bottom: 20rpx;
|
||||
}
|
||||
@keyframes spin { to { transform: rotate(360deg); } }
|
||||
.loading-text { color: #fff; font-size: 26rpx; }
|
||||
|
||||
.btn { flex: 1; text-align: center; padding: 22rpx 0; border-radius: 16rpx; font-size: 28rpx; font-weight: 600; }
|
||||
.primary { background: #2e7d32; color: #fff; }
|
||||
.default { background: #f0f0f0; color: #555; }
|
||||
.btn:active { opacity: 0.8; }
|
||||
Reference in New Issue
Block a user