Initial commit
This commit is contained in:
188
wechat-mini-program/pages/coupon/coupon.js
Normal file
188
wechat-mini-program/pages/coupon/coupon.js
Normal file
@@ -0,0 +1,188 @@
|
||||
const app = getApp()
|
||||
|
||||
Page({
|
||||
data: {
|
||||
coupons: [],
|
||||
user: {}
|
||||
},
|
||||
onLoad() {
|
||||
this.fetchCoupons();
|
||||
},
|
||||
onShow() {
|
||||
this.getUserInfo();
|
||||
this.fetchCoupons();
|
||||
},
|
||||
getUserInfo() {
|
||||
const { request } = require('../../utils/request')
|
||||
const app = getApp()
|
||||
|
||||
// Fetch latest user info from backend to check if phone exists in DB
|
||||
request({ url: '/user/' }).then(user => {
|
||||
app.globalData.userInfo = user; // Sync global data
|
||||
this.setData({ user: user });
|
||||
}).catch(err => {
|
||||
console.error('Failed to fetch user info', err)
|
||||
// Fallback to global data if fetch fails
|
||||
if (app.globalData.userInfo) {
|
||||
this.setData({ user: app.globalData.userInfo });
|
||||
}
|
||||
})
|
||||
},
|
||||
goToProfile() {
|
||||
const app = getApp();
|
||||
app.globalData.profileAction = 'bind_phone';
|
||||
wx.switchTab({
|
||||
url: '/pages/profile/profile'
|
||||
})
|
||||
},
|
||||
fetchCoupons() {
|
||||
const { request } = require('../../utils/request')
|
||||
|
||||
Promise.all([
|
||||
request({ url: '/user-coupons/' }).catch(() => []),
|
||||
request({ url: '/available-coupons/' }).catch(() => [])
|
||||
]).then(([userCoupons, availableCoupons]) => {
|
||||
// 1. Process User Coupons
|
||||
const userList = Array.isArray(userCoupons) ? userCoupons : (userCoupons && userCoupons.results) || [];
|
||||
const formattedUserList = userList.map(item => {
|
||||
if (item.coupon_detail) {
|
||||
let scopeText = item.coupon_detail.scope_text || '全场通用';
|
||||
if (scopeText === '通用') scopeText = '全场通用';
|
||||
|
||||
return {
|
||||
...item.coupon_detail,
|
||||
id: item.id,
|
||||
coupon_id: item.coupon_detail.id,
|
||||
status: item.status,
|
||||
expiry: item.coupon_detail.expiry,
|
||||
displayDesc: scopeText,
|
||||
is_time_limited: item.coupon_detail.is_time_limited
|
||||
}
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
displayDesc: item.desc
|
||||
}
|
||||
});
|
||||
|
||||
// 2. Process Available Coupons
|
||||
const userCouponIds = new Set(formattedUserList.map(item => item.coupon_id));
|
||||
|
||||
const availableList = Array.isArray(availableCoupons) ? availableCoupons : (availableCoupons && availableCoupons.results) || [];
|
||||
const formattedAvailableList = availableList
|
||||
.filter(c => !userCouponIds.has(c.id))
|
||||
.map(c => {
|
||||
let scopeText = c.scope_text || '全场通用';
|
||||
if (scopeText === '通用') scopeText = '全场通用';
|
||||
return {
|
||||
...c,
|
||||
id: 'avail_' + c.id, // Virtual ID
|
||||
coupon_id: c.id,
|
||||
status: 'can_claim', // Virtual Status
|
||||
displayDesc: scopeText
|
||||
}
|
||||
});
|
||||
|
||||
// 3. Merge and Sort
|
||||
const allCoupons = [...formattedAvailableList, ...formattedUserList];
|
||||
|
||||
// Sort: can_claim -> assigned -> used -> expired
|
||||
const statusOrder = { 'can_claim': 0, 'assigned': 1, 'used': 2, 'expired': 3, 'revoked': 4 };
|
||||
|
||||
allCoupons.sort((a, b) => {
|
||||
const orderA = statusOrder[a.status] !== undefined ? statusOrder[a.status] : 99;
|
||||
const orderB = statusOrder[b.status] !== undefined ? statusOrder[b.status] : 99;
|
||||
return orderA - orderB;
|
||||
});
|
||||
|
||||
this.setData({ coupons: allCoupons });
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
// Mock data fallback
|
||||
this.setData({
|
||||
coupons: [
|
||||
{
|
||||
id: 1,
|
||||
amount: '50',
|
||||
unit: '元',
|
||||
title: '新人见面礼',
|
||||
desc: '无门槛使用,适用于所有课程',
|
||||
displayDesc: '全场通用',
|
||||
expiry: '2023-12-31',
|
||||
status: 'available',
|
||||
color: 'from-blue-500 to-cyan-400',
|
||||
bgStart: 'from-blue-50',
|
||||
bgEnd: 'to-cyan-50',
|
||||
shadow: 'shadow-blue-100',
|
||||
is_time_limited: true
|
||||
},
|
||||
// ... (existing mocks)
|
||||
]
|
||||
})
|
||||
})
|
||||
},
|
||||
handleCouponClick(e) {
|
||||
if (!this.data.user.phone) {
|
||||
wx.showModal({
|
||||
title: '提示',
|
||||
content: '请先绑定手机号激活会员权益',
|
||||
confirmText: '去绑定',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
this.goToProfile();
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const status = e.currentTarget.dataset.status;
|
||||
|
||||
if (status === 'can_claim') {
|
||||
this.handleClaim(e);
|
||||
return;
|
||||
}
|
||||
|
||||
// If coupon is available/assigned, redirect to home page to use it
|
||||
if (status !== 'used') {
|
||||
wx.switchTab({
|
||||
url: '/pages/index/index'
|
||||
});
|
||||
return;
|
||||
}
|
||||
},
|
||||
handleClaim(e) {
|
||||
const id = e.currentTarget.dataset.id; // This is 'avail_ID'
|
||||
const realId = id.toString().replace('avail_', '');
|
||||
|
||||
wx.showLoading({ title: '领取中...' });
|
||||
|
||||
const { request } = require('../../utils/request')
|
||||
|
||||
request({
|
||||
url: '/user-coupons/',
|
||||
method: 'POST',
|
||||
data: {
|
||||
coupon_id: realId
|
||||
}
|
||||
}).then(() => {
|
||||
wx.hideLoading();
|
||||
wx.showToast({
|
||||
title: '领取成功',
|
||||
icon: 'success'
|
||||
});
|
||||
// Refresh list
|
||||
this.fetchCoupons();
|
||||
}).catch(err => {
|
||||
wx.hideLoading();
|
||||
console.error(err);
|
||||
// Handle specific error message from backend
|
||||
const msg = (err && err.error) || (err && err.detail) || '领取失败';
|
||||
wx.showToast({
|
||||
title: msg,
|
||||
icon: 'none'
|
||||
});
|
||||
});
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user