Initial commit
This commit is contained in:
173
wechat-mini-program/pages/detail/detail.js
Normal file
173
wechat-mini-program/pages/detail/detail.js
Normal file
@@ -0,0 +1,173 @@
|
||||
const app = getApp()
|
||||
|
||||
Page({
|
||||
data: {
|
||||
project: null,
|
||||
bestCoupon: null,
|
||||
finalPrice: 0,
|
||||
isEnrolled: false,
|
||||
tagStyle: {
|
||||
video: 'width: 100%;',
|
||||
img: 'width: 100%; height: auto; display: block;'
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
const { id } = options;
|
||||
this.fetchProject(id);
|
||||
this.checkEnrollment(id);
|
||||
},
|
||||
checkEnrollment(projectId) {
|
||||
const user = app.globalData.userInfo;
|
||||
if (!user) return;
|
||||
|
||||
const { request } = require('../../utils/request')
|
||||
request({
|
||||
url: `/student-projects/?student=${user.id}&project=${projectId}`
|
||||
}).then(res => {
|
||||
// Search result from list
|
||||
if (res && res.results && res.results.length > 0) {
|
||||
this.setData({ isEnrolled: true });
|
||||
} else if (Array.isArray(res) && res.length > 0) {
|
||||
this.setData({ isEnrolled: true });
|
||||
}
|
||||
}).catch(err => console.error('Check enrollment failed', err));
|
||||
},
|
||||
fetchProject(id) {
|
||||
const { request } = require('../../utils/request')
|
||||
// Fetch project details
|
||||
request({ url: `/projects/${id}/` })
|
||||
.then((data) => {
|
||||
this.setData({ project: data })
|
||||
// Fetch coupons to calculate best discount
|
||||
if (parseFloat(data.price) > 0 && data.show_price) {
|
||||
this.fetchCoupons(data.id, data.price);
|
||||
} else {
|
||||
this.setData({
|
||||
finalPrice: data.price,
|
||||
bestCoupon: null,
|
||||
bestCouponId: null
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// Mock data fallback
|
||||
this.setData({
|
||||
project: {
|
||||
id: id,
|
||||
title: '示例项目',
|
||||
category: '示例分类',
|
||||
rating: 4.8,
|
||||
students: 120,
|
||||
duration: '4周',
|
||||
price: 299,
|
||||
show_price: true,
|
||||
detail: '<p>这是一个示例项目详情。</p>',
|
||||
image: 'https://images.unsplash.com/photo-1526379095098-d400fd0bf935'
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
fetchCoupons(projectId, originalPrice) {
|
||||
const { request } = require('../../utils/request')
|
||||
request({ url: '/user-coupons/' }).then(coupons => {
|
||||
// Filter applicable coupons
|
||||
const validCoupons = coupons.filter(sc => {
|
||||
// Check if coupon is applicable to this project
|
||||
const c = sc.coupon_detail;
|
||||
const isApplicable = c.applicable_project_titles.length === 0 || c.applicable_project_titles.includes(this.data.project.title);
|
||||
return isApplicable && sc.status === 'assigned';
|
||||
});
|
||||
|
||||
if (validCoupons.length > 0) {
|
||||
// Find the best coupon (highest discount)
|
||||
let maxDiscount = 0;
|
||||
let bestCoupon = null;
|
||||
|
||||
validCoupons.forEach(sc => {
|
||||
const c = sc.coupon_detail;
|
||||
const discount = parseFloat(c.amount);
|
||||
if (discount > maxDiscount) {
|
||||
maxDiscount = discount;
|
||||
bestCoupon = sc; // Keep the student_coupon object to get ID
|
||||
}
|
||||
});
|
||||
|
||||
if (bestCoupon) {
|
||||
const finalPrice = Math.max(0, originalPrice - maxDiscount);
|
||||
this.setData({
|
||||
bestCoupon: bestCoupon.coupon_detail, // For display
|
||||
bestCouponId: bestCoupon.id, // For submission (StudentCoupon ID)
|
||||
finalPrice: finalPrice.toFixed(2)
|
||||
});
|
||||
} else {
|
||||
this.setData({ finalPrice: originalPrice });
|
||||
}
|
||||
} else {
|
||||
this.setData({ finalPrice: originalPrice });
|
||||
}
|
||||
}).catch(() => {
|
||||
this.setData({ finalPrice: originalPrice });
|
||||
});
|
||||
},
|
||||
handleEnroll() {
|
||||
const { request } = require('../../utils/request')
|
||||
const user = app.globalData.userInfo;
|
||||
|
||||
if (!user) {
|
||||
wx.showToast({ title: '请先登录', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.data.isEnrolled) {
|
||||
wx.showToast({ title: '您已报名该项目', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
|
||||
const payload = {
|
||||
student: user.id,
|
||||
project: this.data.project.id,
|
||||
coupon_id: this.data.bestCouponId || null
|
||||
};
|
||||
|
||||
wx.showLoading({ title: '报名中...' });
|
||||
|
||||
request({
|
||||
url: '/student-projects/',
|
||||
method: 'POST',
|
||||
data: payload
|
||||
}).then(res => {
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: '报名成功', icon: 'success' });
|
||||
this.setData({ isEnrolled: true });
|
||||
}).catch(err => {
|
||||
wx.hideLoading();
|
||||
console.error('Enrollment error:', err);
|
||||
|
||||
let msg = '报名失败';
|
||||
if (err.data) {
|
||||
if (err.data.detail) {
|
||||
msg = err.data.detail;
|
||||
} else if (err.data.coupon_id) {
|
||||
msg = Array.isArray(err.data.coupon_id) ? err.data.coupon_id[0] : err.data.coupon_id;
|
||||
} else if (typeof err.data === 'string') {
|
||||
msg = err.data;
|
||||
} else {
|
||||
// Try to find first error value
|
||||
const keys = Object.keys(err.data);
|
||||
if (keys.length > 0) {
|
||||
const firstVal = err.data[keys[0]];
|
||||
msg = Array.isArray(firstVal) ? firstVal[0] : firstVal;
|
||||
}
|
||||
}
|
||||
} else if (err.detail) {
|
||||
msg = err.detail;
|
||||
}
|
||||
|
||||
wx.showToast({ title: msg, icon: 'none' });
|
||||
|
||||
if (msg && (msg.includes('重复') || msg.includes('exist'))) {
|
||||
this.setData({ isEnrolled: true });
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user