|
|
@@ -1,10 +1,69 @@
|
|
|
// index.ts
|
|
|
|
|
|
-import { api_shopInstruments, api_shopProduct } from "../../api/login";
|
|
|
+import { api_queryByParamNameList, api_shopInstruments, api_shopProduct } from "../../api/login";
|
|
|
import { api_getOpenId, api_trackPointLog } from "../../api/new";
|
|
|
import { debounce, formatPrice, formatTime } from "../../utils/util";
|
|
|
// 获取应用实例
|
|
|
const app = getApp<IAppOption>();
|
|
|
+const PURCHASE_TYPE = {
|
|
|
+ STUDENT: "WECHAT_MINI",
|
|
|
+ TEACHER: "TEACHER_VIP",
|
|
|
+};
|
|
|
+const TEACHER_VIP_PARAM_NAME = "teacher_vip_purchase_list";
|
|
|
+
|
|
|
+function getProductImage(item: any, userType: string) {
|
|
|
+ if (!item) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ if (userType === PURCHASE_TYPE.TEACHER) {
|
|
|
+ return item.coverImg || item.pic || "";
|
|
|
+ }
|
|
|
+ return item.pic || item.coverImg || "";
|
|
|
+}
|
|
|
+
|
|
|
+function parseTeacherVipList(paramValue: any) {
|
|
|
+ if (!paramValue) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ const value = typeof paramValue === "string" ? JSON.parse(paramValue) : paramValue;
|
|
|
+ if (Array.isArray(value)) {
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+ return value.list || value.goodsList || value.packages || [];
|
|
|
+}
|
|
|
+
|
|
|
+function formatPeriodText(num: any, type: string) {
|
|
|
+ const unitText: any = {
|
|
|
+ DAY: "天",
|
|
|
+ MONTH: "个月",
|
|
|
+ YEAR: "年",
|
|
|
+ };
|
|
|
+ if (!num || !type) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ return `${num}${unitText[type] || ""}`;
|
|
|
+}
|
|
|
+
|
|
|
+function formatGiftText(item: any) {
|
|
|
+ if (!item) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ if (item.free?.number && item.free?.unit) {
|
|
|
+ return formatPeriodText(item.free.number, item.free.unit);
|
|
|
+ }
|
|
|
+ if (item.giftFlag && item.giftVipDay && item.giftPeriod) {
|
|
|
+ return formatPeriodText(item.giftVipDay, item.giftPeriod);
|
|
|
+ }
|
|
|
+ return "";
|
|
|
+}
|
|
|
+
|
|
|
+function buildPeriodList(list: any[]) {
|
|
|
+ return list.map((item: any) => ({
|
|
|
+ label: item.typeName || item.title || item.name || formatPeriodText(item.num, item.period),
|
|
|
+ value: String(item.id),
|
|
|
+ disabled: Number(item.stockNum ?? 1) <= 0,
|
|
|
+ }));
|
|
|
+}
|
|
|
// pages/orders/orders.ts
|
|
|
Page({
|
|
|
/**
|
|
|
@@ -59,6 +118,9 @@ Page({
|
|
|
selectedInstrument: {} as any,
|
|
|
formatSelectGood: {
|
|
|
typeName: '',
|
|
|
+ name: '',
|
|
|
+ productImage: '',
|
|
|
+ giftText: '',
|
|
|
showSalePrice: '', // 显示的现价
|
|
|
originalPrice: 0, // 原价
|
|
|
salePrice: 0, // 现价
|
|
|
@@ -78,15 +140,9 @@ Page({
|
|
|
titleControls: false, // 详情是否显示控制条
|
|
|
liuControls: false, // 详情是否显示控制条
|
|
|
bannerImageloaded: false, // Banner 图片是否加载完成
|
|
|
- userTypes: 'teacher', // 用户类型:student | teacher
|
|
|
- periodList: [
|
|
|
- { label: '7 天', value: '7DAY', disabled: false },
|
|
|
- { label: '14 天', value: '14DAY', disabled: false },
|
|
|
- { label: '1 个月', value: '1MONTH', disabled: false },
|
|
|
- { label: '6 个月', value: '6MONTH', disabled: false },
|
|
|
- { label: '1 年', value: '1YEAR', disabled: false }
|
|
|
- ],
|
|
|
- selectedPeriod: '14DAY', // 选中的期限
|
|
|
+ userTypes: PURCHASE_TYPE.STUDENT, // 用户类型:WECHAT_MINI | TEACHER_VIP
|
|
|
+ periodList: [] as any,
|
|
|
+ selectedPeriod: '', // 选中的期限
|
|
|
showBonusGift: false, // 是否显示额外赠送
|
|
|
},
|
|
|
|
|
|
@@ -224,6 +280,10 @@ Page({
|
|
|
* 获取基础信息
|
|
|
*/
|
|
|
async onInit() {
|
|
|
+ if (this.data.userTypes === PURCHASE_TYPE.TEACHER) {
|
|
|
+ await this.onInitTeacherVip()
|
|
|
+ return
|
|
|
+ }
|
|
|
try {
|
|
|
const result = await api_shopInstruments({ appId: app.globalData.appId })
|
|
|
const instrumentList = result.data.data || []
|
|
|
@@ -237,14 +297,18 @@ Page({
|
|
|
let selected: any = {};
|
|
|
let isOverSaled = true; // 是否销售完
|
|
|
list.forEach((item: any) => {
|
|
|
- item.originalPrice = formatPrice(item.originalPrice, "ALL");
|
|
|
- item.showSalePrice = formatPrice(item.salePrice, "ALL");
|
|
|
- item.typeName = this.formatPeriod(item.num, item.period);
|
|
|
+ const salePrice = Number(item.salePrice || 0);
|
|
|
+ const originalPrice = Number(item.originalPrice || salePrice);
|
|
|
+ item.originalPrice = originalPrice;
|
|
|
+ item.salePrice = salePrice;
|
|
|
+ item.showSalePrice = formatPrice(salePrice, "ALL");
|
|
|
+ item.showOriginalPrice = formatPrice(originalPrice, "ALL");
|
|
|
+ item.typeName = this.formatPeriod(Number(item.num), item.period);
|
|
|
item.discountPrice = formatPrice(
|
|
|
- item.originalPrice - item.salePrice,
|
|
|
+ originalPrice - salePrice,
|
|
|
"ALL"
|
|
|
);
|
|
|
- const prices: any = formatPrice(item.salePrice);
|
|
|
+ const prices: any = formatPrice(salePrice);
|
|
|
item.integerPart = prices.integerPart;
|
|
|
item.decimalPart = prices.decimalPart;
|
|
|
// 格式化赠送内容
|
|
|
@@ -265,20 +329,94 @@ Page({
|
|
|
|
|
|
this.setData({
|
|
|
list,
|
|
|
+ periodList: buildPeriodList(list),
|
|
|
+ selectedPeriod: selected?.id ? String(selected.id) : '',
|
|
|
instrumentList, // 乐器列表
|
|
|
isOverSaled,
|
|
|
selected,
|
|
|
selectInstrumentId: '',
|
|
|
- selectedInstrument: {}
|
|
|
+ selectedInstrument: {},
|
|
|
+ showBonusGift: Boolean(formatGiftText(selected))
|
|
|
}, () => {
|
|
|
this.onFormatGoods()
|
|
|
- this.onUpdatePeriodList()
|
|
|
});
|
|
|
} catch (e) {
|
|
|
console.log(e, "e");
|
|
|
}
|
|
|
},
|
|
|
// 格式化类型
|
|
|
+ async onInitTeacherVip() {
|
|
|
+ try {
|
|
|
+ const { data } = await api_queryByParamNameList({
|
|
|
+ paramNames: TEACHER_VIP_PARAM_NAME
|
|
|
+ });
|
|
|
+ const configList = data.data || [];
|
|
|
+ const config = Array.isArray(configList)
|
|
|
+ ? configList.find((item: any) => item.paramName === TEACHER_VIP_PARAM_NAME) || configList[0]
|
|
|
+ : configList;
|
|
|
+ const list = parseTeacherVipList(config?.paramValue).map((item: any, index: number) => {
|
|
|
+ const salePrice = Number(item.salePrice ?? item.currentPrice ?? item.price ?? item.paymentCashAmount ?? 0);
|
|
|
+ const originalPrice = Number(item.originalPrice ?? item.marketPrice ?? item.originalAmount ?? salePrice);
|
|
|
+ const period = item.period || item.unit;
|
|
|
+ const num = item.num ?? item.number;
|
|
|
+ const typeName = item.typeName || item.label || item.title || item.name || formatPeriodText(num, period);
|
|
|
+ const prices: any = formatPrice(salePrice);
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ id: item.id || item.goodsId || item.value || `${TEACHER_VIP_PARAM_NAME}_${index}`,
|
|
|
+ name: item.name || item.title || typeName,
|
|
|
+ pic: item.pic || item.coverImg || "",
|
|
|
+ coverImg: item.coverImg || item.pic || "",
|
|
|
+ shopId: item.shopId || "",
|
|
|
+ stockNum: item.stockNum ?? 999999,
|
|
|
+ originalPrice,
|
|
|
+ salePrice,
|
|
|
+ num,
|
|
|
+ period,
|
|
|
+ showSalePrice: formatPrice(salePrice, "ALL"),
|
|
|
+ showOriginalPrice: formatPrice(originalPrice, "ALL"),
|
|
|
+ discountPrice: formatPrice(originalPrice - salePrice, "ALL"),
|
|
|
+ typeName,
|
|
|
+ giftFlag: Boolean(item.free || item.giftFlag),
|
|
|
+ giftVipDay: item.free?.number ?? item.giftVipDay,
|
|
|
+ giftPeriod: item.free?.unit ?? item.giftPeriod,
|
|
|
+ integerPart: prices.integerPart,
|
|
|
+ decimalPart: prices.decimalPart,
|
|
|
+ goodsType: item.goodsType || PURCHASE_TYPE.TEACHER,
|
|
|
+ };
|
|
|
+ });
|
|
|
+ const selected = list.find((item: any) => item.isHot && item.stockNum > 0)
|
|
|
+ || list.find((item: any) => item.stockNum > 0)
|
|
|
+ || list[0]
|
|
|
+ || {};
|
|
|
+ this.setData({
|
|
|
+ list,
|
|
|
+ periodList: buildPeriodList(list),
|
|
|
+ selectedPeriod: selected?.id ? String(selected.id) : '',
|
|
|
+ instrumentList: [],
|
|
|
+ isOverSaled: !list.some((item: any) => item.stockNum > 0),
|
|
|
+ selected,
|
|
|
+ selectInstrumentId: '',
|
|
|
+ selectedInstrument: {},
|
|
|
+ showBonusGift: Boolean(formatGiftText(selected))
|
|
|
+ }, () => {
|
|
|
+ this.onFormatGoods()
|
|
|
+ });
|
|
|
+ } catch (e) {
|
|
|
+ console.log(e, "e");
|
|
|
+ this.setData({
|
|
|
+ list: [],
|
|
|
+ instrumentList: [],
|
|
|
+ isOverSaled: true,
|
|
|
+ selected: {},
|
|
|
+ selectInstrumentId: '',
|
|
|
+ selectedInstrument: {},
|
|
|
+ showBonusGift: false
|
|
|
+ }, () => {
|
|
|
+ this.onFormatGoods()
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
formatPeriod(num: number, type: string) {
|
|
|
const template: any = {
|
|
|
DAY: "天卡",
|
|
|
@@ -317,6 +455,9 @@ Page({
|
|
|
},
|
|
|
/** 选中乐器 */
|
|
|
onSelectInstrument(e: any) {
|
|
|
+ if (this.data.userTypes === PURCHASE_TYPE.TEACHER) {
|
|
|
+ return
|
|
|
+ }
|
|
|
const { dataset } = e.currentTarget;
|
|
|
if (dataset.id === this.data.selectInstrumentId) {
|
|
|
this.setData({
|
|
|
@@ -341,8 +482,11 @@ Page({
|
|
|
const selected = this.data.selected;
|
|
|
const selectedInstrument = this.data.selectedInstrument
|
|
|
|
|
|
- const params = {
|
|
|
+ const params: any = {
|
|
|
typeName: '',
|
|
|
+ name: '',
|
|
|
+ productImage: '',
|
|
|
+ giftText: '',
|
|
|
showSalePrice: '' as any, // 显示的现价
|
|
|
originalPrice: 0, // 原价
|
|
|
salePrice: 0, // 现价
|
|
|
@@ -353,6 +497,9 @@ Page({
|
|
|
// 选中期限
|
|
|
if (selected.id) {
|
|
|
params.typeName = selected.typeName
|
|
|
+ params.name = selected.name
|
|
|
+ params.productImage = getProductImage(selected, this.data.userTypes)
|
|
|
+ params.giftText = formatGiftText(selected)
|
|
|
params.showSalePrice = selected.showSalePrice
|
|
|
params.originalPrice = selected.originalPrice
|
|
|
params.salePrice = selected.salePrice
|
|
|
@@ -365,6 +512,7 @@ Page({
|
|
|
// 选中乐器
|
|
|
if (selectedInstrument.id) {
|
|
|
params.typeName = selected.typeName ? selected.typeName + '+' + selectedInstrument.name : selectedInstrument.name
|
|
|
+ params.name = selected.name ? selected.name + '+' + selectedInstrument.name : selectedInstrument.name
|
|
|
params.originalPrice = Number(selected.originalPrice) + Number(selectedInstrument.originalPrice)
|
|
|
params.salePrice = Number(selected.salePrice) + Number(selectedInstrument.salePrice)
|
|
|
params.showSalePrice = formatPrice(params.salePrice, "ALL");
|
|
|
@@ -449,44 +597,36 @@ Page({
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+ const selectedItem = this.data.list.find((item: any) => String(item.id) === String(value))
|
|
|
+ if (!selectedItem) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
this.setData({
|
|
|
- selectedPeriod: value
|
|
|
+ selectedPeriod: String(value),
|
|
|
+ selected: selectedItem,
|
|
|
+ showBonusGift: Boolean(formatGiftText(selectedItem))
|
|
|
}, () => {
|
|
|
// 根据选中的期限更新商品
|
|
|
- this.onUpdatePeriodList()
|
|
|
+ this.onFormatGoods()
|
|
|
})
|
|
|
},
|
|
|
/** 根据期限更新商品列表 */
|
|
|
onUpdatePeriodList() {
|
|
|
- const { selectedPeriod, list } = this.data
|
|
|
- // 将期限值映射回商品列表的筛选逻辑
|
|
|
- // 这里需要根据实际的 period 和 num 来匹配
|
|
|
- const periodMap: any = {
|
|
|
- '7DAY': { period: 'DAY', num: 7 },
|
|
|
- '14DAY': { period: 'DAY', num: 14 },
|
|
|
- '1MONTH': { period: 'MONTH', num: 1 },
|
|
|
- '6MONTH': { period: 'MONTH', num: 6 },
|
|
|
- '1YEAR': { period: 'YEAR', num: 1 }
|
|
|
+ if (this.data.userTypes === PURCHASE_TYPE.TEACHER) {
|
|
|
+ return
|
|
|
}
|
|
|
-
|
|
|
- const target = periodMap[selectedPeriod]
|
|
|
- if (target) {
|
|
|
- const selectedItem = list.find((item: any) =>
|
|
|
- item.period === target.period && item.num === target.num
|
|
|
- )
|
|
|
- if (selectedItem && selectedItem.stockNum > 0) {
|
|
|
- this.setData({
|
|
|
- selected: selectedItem
|
|
|
- }, () => {
|
|
|
- this.onFormatGoods()
|
|
|
- })
|
|
|
- }
|
|
|
+ const { selectedPeriod, list } = this.data
|
|
|
+ const selectedItem = list.find((item: any) => String(item.id) === String(selectedPeriod))
|
|
|
+ if (!selectedItem || Number(selectedItem.stockNum ?? 1) <= 0) {
|
|
|
+ return
|
|
|
}
|
|
|
|
|
|
- // 判断是否满 1 年,显示赠送提示
|
|
|
- const showBonusGift = selectedPeriod === '1YEAR'
|
|
|
this.setData({
|
|
|
- showBonusGift
|
|
|
+ selected: selectedItem,
|
|
|
+ showBonusGift: Boolean(formatGiftText(selectedItem))
|
|
|
+ }, () => {
|
|
|
+ this.onFormatGoods()
|
|
|
})
|
|
|
},
|
|
|
// 进行埋点
|
|
|
@@ -525,7 +665,7 @@ Page({
|
|
|
salePrice: selected.salePrice,
|
|
|
shopId: selected.shopId,
|
|
|
id: selected.id,
|
|
|
- goodsType: 'ACTIVATION_CODE', // INSTRUMENTS
|
|
|
+ goodsType: selected.goodsType || 'ACTIVATION_CODE', // INSTRUMENTS
|
|
|
})
|
|
|
}
|
|
|
const selectedInstrument = that.data.selectedInstrument
|
|
|
@@ -553,7 +693,7 @@ Page({
|
|
|
});
|
|
|
info = encodeURIComponent(info);
|
|
|
wx.navigateTo({
|
|
|
- url: `../orders/order-detail?orderInfo=${info}`,
|
|
|
+ url: `../orders/order-detail?orderInfo=${info}&orderType=${that.data.userTypes}`,
|
|
|
success: () => {
|
|
|
that.setData({
|
|
|
popupShow: false,
|