index.ts 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911
  1. // index.ts
  2. import { api_queryByParamNameList, api_shopInstruments, api_shopProduct } from "../../api/login";
  3. import { api_getOpenId, api_trackPointLog } from "../../api/new";
  4. import { debounce, formatPrice, formatTime } from "../../utils/util";
  5. // 获取应用实例
  6. const app = getApp<IAppOption>();
  7. const PURCHASE_TYPE = {
  8. STUDENT: "WECHAT_MINI",
  9. TEACHER: "TEACHER_VIP",
  10. };
  11. const TEACHER_VIP_PARAM_NAME = "teacher_vip_purchase_list";
  12. const purchaseDataCache: any = {};
  13. function getProductImage(item: any, userType: string) {
  14. if (!item) {
  15. return "";
  16. }
  17. if (userType === PURCHASE_TYPE.TEACHER) {
  18. return item.coverImg || item.pic || "";
  19. }
  20. return item.pic || item.coverImg || "";
  21. }
  22. function parseTeacherVipList(paramValue: any) {
  23. if (!paramValue) {
  24. return [];
  25. }
  26. const value = typeof paramValue === "string" ? JSON.parse(paramValue) : paramValue;
  27. if (Array.isArray(value)) {
  28. return value;
  29. }
  30. return value.list || value.goodsList || value.packages || [];
  31. }
  32. function formatPeriodText(num: any, type: string) {
  33. const unitText: any = {
  34. DAY: "天",
  35. MONTH: "个月",
  36. YEAR: "年",
  37. };
  38. if (!num || !type) {
  39. return "";
  40. }
  41. return `${num}${unitText[type] || ""}`;
  42. }
  43. function formatGiftText(item: any) {
  44. if (!item) {
  45. return "";
  46. }
  47. if (item.free?.number && item.free?.unit) {
  48. return formatPeriodText(item.free.number, item.free.unit);
  49. }
  50. if (item.giftFlag && item.giftVipDay && item.giftPeriod) {
  51. return formatPeriodText(item.giftVipDay, item.giftPeriod);
  52. }
  53. return "";
  54. }
  55. function buildPeriodList(list: any[]) {
  56. return list.map((item: any) => ({
  57. label: item.typeName || item.title || item.name || formatPeriodText(item.num, item.period),
  58. value: String(item.id),
  59. disabled: Number(item.stockNum ?? 1) <= 0,
  60. }));
  61. }
  62. // pages/orders/orders.ts
  63. Page({
  64. /**
  65. * 页面的初始数据
  66. */
  67. data: {
  68. imgList: [
  69. // 'https://oss.dayaedu.com/ktyq/1732585725698.png',
  70. // 'https://oss.dayaedu.com/ktyq/1732519468124.png',
  71. // 'https://oss.dayaedu.com/ktyq/1732519479416.png',
  72. // 'https://oss.dayaedu.com/ktyq/1733110029242.png',
  73. // 'https://oss.dayaedu.com/ktyq/1732519500580.png'
  74. "https://oss.dayaedu.com/ktyq/1733449062928.png",
  75. "https://oss.dayaedu.com/ktyq/1733449075055.png",
  76. "https://oss.dayaedu.com/ktyq/1733449085983.png",
  77. "https://oss.dayaedu.com/ktyq/1733449097054.png",
  78. ],
  79. goodsImgList: [
  80. "https://oss.dayaedu.com/ktyq/1739353790443.png",
  81. "https://oss.dayaedu.com/ktyq/1739353815962.png",
  82. "https://oss.dayaedu.com/ktyq/1739353843494.png",
  83. "https://oss.dayaedu.com/ktyq/03/1772550951364.png",
  84. ],
  85. detailImgList: [
  86. {
  87. url: "https://oss.dayaedu.com/ktyq/1733403675345.png",
  88. text: "合作学校音乐数字课堂公开课",
  89. },
  90. {
  91. url: "https://oss.dayaedu.com/ktyq/1733403707851.png",
  92. text: "音乐课课堂器乐教学",
  93. },
  94. {
  95. url: "https://oss.dayaedu.com/ktyq/1733403725644.png",
  96. text: "学期末汇报演出",
  97. },
  98. ],
  99. serviceShow: true,
  100. scrollTop: 0,
  101. current: 0,
  102. detailCurrent: 0,
  103. autoplay: false,
  104. interval: 5000,
  105. duration: 500,
  106. popupShow: false,
  107. videoHeight: "255px",
  108. list: [] as any,
  109. instrumentList: [] as any,
  110. isOverSaled: false, // 是否所有商品都没有库存
  111. selected: {} as any,
  112. selectInstrumentId: '', // 选中的乐器
  113. selectedInstrument: {} as any,
  114. formatSelectGood: {
  115. typeName: '',
  116. name: '',
  117. productImage: '',
  118. giftText: '',
  119. showSalePrice: '', // 显示的现价
  120. originalPrice: 0, // 原价
  121. salePrice: 0, // 现价
  122. discountPrice: '' // 已省
  123. } as any, // 格式化所有选中的数据
  124. opacity: 0,
  125. // showSelectedProduct: false, // 是否显示选中商品值
  126. scrolIntoViewStr: "",
  127. scrolIntoView: "",
  128. scrollDiscount: false, // 是否扣减启
  129. isScrollTT: false,
  130. scrollIntoViewType: false,
  131. headerHeight: 0, // 头部的高度
  132. initialScrollHeight: 0, // 滚动高度
  133. isFromPreviewImage: false,
  134. bannerPlay: false, // 视频是否播放
  135. titleControls: false, // 详情是否显示控制条
  136. liuControls: false, // 详情是否显示控制条
  137. bannerImageloaded: false, // Banner 图片是否加载完成
  138. userTypes: PURCHASE_TYPE.STUDENT, // 用户类型:WECHAT_MINI | TEACHER_VIP
  139. periodList: [] as any,
  140. selectedPeriod: '', // 选中的期限
  141. showBonusGift: false, // 是否显示额外赠送
  142. },
  143. /**
  144. * 生命周期函数--监听页面加载
  145. */
  146. onLoad() {
  147. // this.onInit()
  148. const wxWindowInfo = wx.getWindowInfo();
  149. this.setData({
  150. videoHeight: (wxWindowInfo.windowWidth / 16) * 9 + "px",
  151. });
  152. // 首页进入页面埋点
  153. this.onHomePageTrackPoint()
  154. },
  155. onHomePageTrackPoint() {
  156. // openId
  157. const openId = wx.getStorageSync("openId")
  158. if(openId) {
  159. this.onTrackPoint({
  160. openId,
  161. elementName: '首页'
  162. })
  163. } else {
  164. wx.login({
  165. success: async (res) => {
  166. await api_getOpenId({
  167. code: res.code,
  168. appId: app.globalData.appId
  169. }).then((res: any) => {
  170. // 存储 openId
  171. const openId = res.data.data
  172. wx.setStorageSync("openId", openId);
  173. this.onTrackPoint({
  174. openId,
  175. elementName: '首页'
  176. })
  177. })
  178. }
  179. })
  180. }
  181. },
  182. onReady() {
  183. const that = this;
  184. wx.createSelectorQuery()
  185. .select("#scroll-header")
  186. .boundingClientRect(function (rect) {
  187. that.setData({
  188. headerHeight: rect.height,
  189. });
  190. })
  191. .exec();
  192. wx.createSelectorQuery()
  193. .select("#scroll-view")
  194. .boundingClientRect(function (rect) {
  195. // console.log(rect, 'rect')
  196. that.setData({
  197. initialScrollHeight: rect.height,
  198. });
  199. })
  200. .exec();
  201. },
  202. onBannerVideoLoad() {
  203. this.setData({
  204. bannerImageloaded: true,
  205. });
  206. },
  207. onBannerPlay() {
  208. const bannerVideo = wx.createVideoContext("bannerVideo");
  209. const titleVideo = wx.createVideoContext("titleVideo");
  210. //
  211. this.setData(
  212. {
  213. bannerPlay: true,
  214. },
  215. () => {
  216. bannerVideo.play();
  217. titleVideo.pause();
  218. // liuVideo.stop()
  219. }
  220. );
  221. },
  222. onBannerVideoPlay() {
  223. const titleVideo = wx.createVideoContext("titleVideo");
  224. titleVideo.pause();
  225. // const liuVideo = wx.createVideoContext('liuVideo')
  226. // liuVideo.stop()
  227. },
  228. onTitlePlay() {
  229. const bannerVideo = wx.createVideoContext("bannerVideo");
  230. bannerVideo.pause();
  231. // const liuVideo = wx.createVideoContext('liuVideo')
  232. // liuVideo.stop()
  233. },
  234. onTItleVideoPlay() {
  235. const bannerVideo = wx.createVideoContext("bannerVideo");
  236. const titleVideo = wx.createVideoContext("titleVideo");
  237. // const liuVideo = wx.createVideoContext('liuVideo')
  238. this.setData(
  239. {
  240. titleControls: true,
  241. },
  242. () => {
  243. titleVideo.play();
  244. bannerVideo.pause();
  245. // liuVideo.stop()
  246. }
  247. );
  248. },
  249. onLiuPlay() {
  250. const bannerVideo = wx.createVideoContext("bannerVideo");
  251. bannerVideo.pause();
  252. const titleVideo = wx.createVideoContext("titleVideo");
  253. titleVideo.pause();
  254. },
  255. onLiuVideoPlay() {
  256. const bannerVideo = wx.createVideoContext("bannerVideo");
  257. const titleVideo = wx.createVideoContext("titleVideo");
  258. // const liuVideo = wx.createVideoContext('liuVideo')
  259. bannerVideo.pause();
  260. titleVideo.pause();
  261. this.setData(
  262. {
  263. liuControls: true,
  264. },
  265. () => {
  266. // liuVideo.play()
  267. }
  268. );
  269. },
  270. /**
  271. * 获取基础信息
  272. */
  273. async onInit() {
  274. const userType = this.data.userTypes;
  275. if (purchaseDataCache[userType]) {
  276. this.applyPurchaseData(purchaseDataCache[userType]);
  277. return
  278. }
  279. if (userType === PURCHASE_TYPE.TEACHER) {
  280. await this.onInitTeacherVip()
  281. return
  282. }
  283. try {
  284. const result = await api_shopInstruments({ appId: app.globalData.appId })
  285. const instrumentList = result.data.data || []
  286. instrumentList.forEach((item: any) => {
  287. item.showSalePrice = formatPrice(item.salePrice || 0, 'ALL')
  288. item.showOriginalPrice = formatPrice(item.originalPrice || 0, 'ALL')
  289. })
  290. const { data } = await api_shopProduct({ appId: app.globalData.appId });
  291. const list = data.data || [];
  292. let selected: any = {};
  293. let isOverSaled = true; // 是否销售完
  294. list.forEach((item: any) => {
  295. const salePrice = Number(item.salePrice || 0);
  296. const originalPrice = Number(item.originalPrice || salePrice);
  297. item.originalPrice = originalPrice;
  298. item.salePrice = salePrice;
  299. item.showSalePrice = formatPrice(salePrice, "ALL");
  300. item.showOriginalPrice = formatPrice(originalPrice, "ALL");
  301. item.typeName = this.formatPeriod(Number(item.num), item.period);
  302. item.discountPrice = formatPrice(
  303. originalPrice - salePrice,
  304. "ALL"
  305. );
  306. const prices: any = formatPrice(salePrice);
  307. item.integerPart = prices.integerPart;
  308. item.decimalPart = prices.decimalPart;
  309. // 格式化赠送内容
  310. item.giftLongTime = item.giftFlag
  311. ? this.formatGiftPeriod(item.giftVipDay, item.giftPeriod)
  312. : "";
  313. if (item.stockNum > 0) {
  314. isOverSaled = false;
  315. if (!selected.id) {
  316. selected = item;
  317. }
  318. }
  319. });
  320. if (isOverSaled) {
  321. // 没有可销售商品则默认选中第一个商品
  322. selected = list[0];
  323. }
  324. const purchaseData = {
  325. list,
  326. periodList: buildPeriodList(list),
  327. selectedPeriod: selected?.id ? String(selected.id) : '',
  328. instrumentList, // 乐器列表
  329. isOverSaled,
  330. selected,
  331. selectInstrumentId: '',
  332. selectedInstrument: {},
  333. showBonusGift: Boolean(formatGiftText(selected))
  334. };
  335. purchaseDataCache[userType] = purchaseData;
  336. this.applyPurchaseData(purchaseData);
  337. } catch (e) {
  338. console.log(e, "e");
  339. }
  340. },
  341. // 格式化类型
  342. applyPurchaseData(purchaseData: any) {
  343. this.setData({
  344. list: purchaseData.list,
  345. periodList: purchaseData.periodList,
  346. selectedPeriod: purchaseData.selectedPeriod,
  347. instrumentList: purchaseData.instrumentList,
  348. isOverSaled: purchaseData.isOverSaled,
  349. selected: purchaseData.selected,
  350. selectInstrumentId: purchaseData.selectInstrumentId,
  351. selectedInstrument: purchaseData.selectedInstrument,
  352. showBonusGift: purchaseData.showBonusGift
  353. }, () => {
  354. this.onFormatGoods()
  355. });
  356. },
  357. async onInitTeacherVip() {
  358. try {
  359. const { data } = await api_queryByParamNameList({
  360. paramNames: TEACHER_VIP_PARAM_NAME
  361. });
  362. const configList = data.data || [];
  363. const config = Array.isArray(configList)
  364. ? configList.find((item: any) => item.paramName === TEACHER_VIP_PARAM_NAME) || configList[0]
  365. : configList;
  366. const list = parseTeacherVipList(config?.paramValue).map((item: any, index: number) => {
  367. const salePrice = Number(item.salePrice ?? item.currentPrice ?? item.price ?? item.paymentCashAmount ?? 0);
  368. const originalPrice = Number(item.originalPrice ?? item.marketPrice ?? item.originalAmount ?? salePrice);
  369. const period = item.period || item.unit;
  370. const num = item.num ?? item.number;
  371. const typeName = item.typeName || item.label || item.title || item.name || formatPeriodText(num, period);
  372. const prices: any = formatPrice(salePrice);
  373. return {
  374. ...item,
  375. id: item.id || item.goodsId || item.value || `${TEACHER_VIP_PARAM_NAME}_${index}`,
  376. name: item.name || item.title || typeName,
  377. pic: item.pic || item.coverImg || "",
  378. coverImg: item.coverImg || item.pic || "",
  379. shopId: item.shopId || "",
  380. stockNum: item.stockNum ?? 999999,
  381. originalPrice,
  382. salePrice,
  383. num,
  384. period,
  385. showSalePrice: formatPrice(salePrice, "ALL"),
  386. showOriginalPrice: formatPrice(originalPrice, "ALL"),
  387. discountPrice: formatPrice(originalPrice - salePrice, "ALL"),
  388. typeName,
  389. giftFlag: Boolean(item.free || item.giftFlag),
  390. giftVipDay: item.free?.number ?? item.giftVipDay,
  391. giftPeriod: item.free?.unit ?? item.giftPeriod,
  392. integerPart: prices.integerPart,
  393. decimalPart: prices.decimalPart,
  394. goodsType: item.goodsType || PURCHASE_TYPE.TEACHER,
  395. };
  396. });
  397. const selected = list.find((item: any) => item.isHot && item.stockNum > 0)
  398. || list.find((item: any) => item.stockNum > 0)
  399. || list[0]
  400. || {};
  401. const purchaseData = {
  402. list,
  403. periodList: buildPeriodList(list),
  404. selectedPeriod: selected?.id ? String(selected.id) : '',
  405. instrumentList: [],
  406. isOverSaled: !list.some((item: any) => item.stockNum > 0),
  407. selected,
  408. selectInstrumentId: '',
  409. selectedInstrument: {},
  410. showBonusGift: Boolean(formatGiftText(selected))
  411. };
  412. purchaseDataCache[PURCHASE_TYPE.TEACHER] = purchaseData;
  413. this.applyPurchaseData(purchaseData);
  414. } catch (e) {
  415. console.log(e, "e");
  416. this.setData({
  417. list: [],
  418. instrumentList: [],
  419. isOverSaled: true,
  420. selected: {},
  421. selectInstrumentId: '',
  422. selectedInstrument: {},
  423. showBonusGift: false
  424. }, () => {
  425. this.onFormatGoods()
  426. });
  427. }
  428. },
  429. formatPeriod(num: number, type: string) {
  430. const template: any = {
  431. DAY: "天卡",
  432. MONTH: "月卡",
  433. YEAR: "年卡",
  434. };
  435. if (type === "YEAR" && num >= 99) {
  436. return "永久卡";
  437. }
  438. return num + template[type];
  439. },
  440. formatGiftPeriod(num: number, type: string) {
  441. if (!num || !type) {
  442. return "";
  443. }
  444. const template: any = {
  445. DAY: "天",
  446. MONTH: "个月",
  447. YEAR: "年",
  448. };
  449. return num + template[type];
  450. },
  451. // 选择
  452. onSelectGoods(e: any) {
  453. const { dataset } = e.currentTarget;
  454. const item = this.data.list.find((item: any) => item.id === dataset.id);
  455. // 判断是否有库存
  456. if (item.stockNum <= 0) {
  457. return;
  458. }
  459. this.setData({
  460. selected: item || {}
  461. }, () => {
  462. this.onFormatGoods()
  463. });
  464. },
  465. /** 选中乐器 */
  466. onSelectInstrument(e: any) {
  467. if (this.data.userTypes === PURCHASE_TYPE.TEACHER) {
  468. return
  469. }
  470. const { dataset } = e.currentTarget;
  471. if (dataset.id === this.data.selectInstrumentId) {
  472. this.setData({
  473. selectInstrumentId: '',
  474. selectedInstrument: {}
  475. }, () => {
  476. this.onFormatGoods()
  477. })
  478. } else {
  479. const item = this.data.instrumentList.find((item: any) => item.id === dataset.id);
  480. this.setData({
  481. selectInstrumentId: dataset.id,
  482. selectedInstrument: item || {}
  483. }, () => {
  484. this.onFormatGoods()
  485. })
  486. }
  487. },
  488. /** 格式化选中的商品 */
  489. onFormatGoods() {
  490. const selected = this.data.selected;
  491. const selectedInstrument = this.data.selectedInstrument
  492. const params: any = {
  493. typeName: '',
  494. name: '',
  495. productImage: '',
  496. giftText: '',
  497. showSalePrice: '' as any, // 显示的现价
  498. originalPrice: 0, // 原价
  499. salePrice: 0, // 现价
  500. discountPrice: '' as any, // 已省
  501. integerPart: '',
  502. decimalPart: '',
  503. }
  504. // 选中期限
  505. if (selected.id) {
  506. params.typeName = selected.typeName
  507. params.name = selected.name
  508. params.productImage = getProductImage(selected, this.data.userTypes)
  509. params.giftText = formatGiftText(selected)
  510. params.showSalePrice = selected.showSalePrice
  511. params.originalPrice = selected.originalPrice
  512. params.salePrice = selected.salePrice
  513. params.discountPrice = selected.discountPrice
  514. const prices: any = formatPrice(params.salePrice);
  515. params.integerPart = prices.integerPart
  516. params.decimalPart = prices.decimalPart
  517. }
  518. // 选中乐器
  519. if (selectedInstrument.id) {
  520. params.typeName = selected.typeName ? selected.typeName + '+' + selectedInstrument.name : selectedInstrument.name
  521. params.name = selected.name ? selected.name + '+' + selectedInstrument.name : selectedInstrument.name
  522. params.originalPrice = Number(selected.originalPrice) + Number(selectedInstrument.originalPrice)
  523. params.salePrice = Number(selected.salePrice) + Number(selectedInstrument.salePrice)
  524. params.showSalePrice = formatPrice(params.salePrice, "ALL");
  525. params.discountPrice = formatPrice(
  526. params.originalPrice - params.salePrice,
  527. "ALL"
  528. );
  529. const prices: any = formatPrice(params.salePrice);
  530. params.integerPart = prices.integerPart
  531. params.decimalPart = prices.decimalPart
  532. }
  533. this.setData({
  534. formatSelectGood: params
  535. })
  536. },
  537. // 事件处理函数
  538. changeSwiper(e: any) {
  539. const detail = e.detail;
  540. if (detail.source === "touch" || detail.source == "autoplay") {
  541. this.setData({
  542. current: detail.current,
  543. });
  544. this.onTitlePlay();
  545. }
  546. },
  547. changeSwiperDetail(e: any) {
  548. const detail = e.detail;
  549. if (detail.source === "touch" || detail.source == "autoplay") {
  550. this.setData({
  551. detailCurrent: detail.current,
  552. });
  553. }
  554. },
  555. isLogin() {
  556. // 判断是否登录
  557. if (!app.globalData.isLogin) {
  558. wx.navigateTo({
  559. url: "../login/login",
  560. });
  561. return false;
  562. }
  563. return true;
  564. },
  565. /** 我的订单 */
  566. onOrder() {
  567. // 判断是否登录
  568. if (!this.isLogin()) {
  569. return;
  570. }
  571. wx.navigateTo({
  572. url: "../orders/orders",
  573. });
  574. },
  575. onBuyShop() {
  576. // 判断是否登录
  577. if (!this.isLogin()) {
  578. return;
  579. }
  580. this.setData({
  581. popupShow: true,
  582. // showSelectedProduct: true,
  583. });
  584. },
  585. /** 切换学生端/老师端 */
  586. onSwitchUserType(e: any) {
  587. const { dataset } = e.currentTarget;
  588. if (dataset.type === this.data.userTypes) {
  589. return
  590. }
  591. this.setData({
  592. userTypes: dataset.type
  593. }, () => {
  594. // 这里可以根据用户类型重新加载商品数据
  595. // 目前先保持逻辑不变,后续可根据后端 API 扩展
  596. this.onInit()
  597. })
  598. },
  599. /** 选择期限 */
  600. onSelectPeriod(e: any) {
  601. const { value } = e.currentTarget.dataset
  602. const periodItem = this.data.periodList.find((item: any) => item.value === value)
  603. if (periodItem?.disabled) {
  604. return
  605. }
  606. const selectedItem = this.data.list.find((item: any) => String(item.id) === String(value))
  607. if (!selectedItem) {
  608. return
  609. }
  610. this.setData({
  611. selectedPeriod: String(value),
  612. selected: selectedItem,
  613. showBonusGift: Boolean(formatGiftText(selectedItem))
  614. }, () => {
  615. // 根据选中的期限更新商品
  616. this.onFormatGoods()
  617. })
  618. },
  619. /** 根据期限更新商品列表 */
  620. onUpdatePeriodList() {
  621. if (this.data.userTypes === PURCHASE_TYPE.TEACHER) {
  622. return
  623. }
  624. const { selectedPeriod, list } = this.data
  625. const selectedItem = list.find((item: any) => String(item.id) === String(selectedPeriod))
  626. if (!selectedItem || Number(selectedItem.stockNum ?? 1) <= 0) {
  627. return
  628. }
  629. this.setData({
  630. selected: selectedItem,
  631. showBonusGift: Boolean(formatGiftText(selectedItem))
  632. }, () => {
  633. this.onFormatGoods()
  634. })
  635. },
  636. // 进行埋点
  637. onTrackPoint(options: { openId: string, elementName: string }) {
  638. const traceId = wx.getStorageSync("traceId");
  639. const deviceInfo = wx.getDeviceInfo();
  640. api_trackPointLog({
  641. traceId,
  642. openId: options.openId,
  643. elementName: options.elementName,
  644. deviceInfo: deviceInfo.brand + '_' + deviceInfo.model + '_' + deviceInfo.system + '_' + deviceInfo.platform,
  645. appName: "音乐数字 AI",
  646. // extParams: '',
  647. clickTime: formatTime(new Date(), '-') // 点击时间
  648. })
  649. },
  650. onClose() {
  651. this.setData({
  652. popupShow: false,
  653. });
  654. },
  655. onSubmit() {
  656. // 判断是否登录
  657. const that = this;
  658. debounce(function () {
  659. if (!that.isLogin()) {
  660. return;
  661. }
  662. const params = [] as any
  663. const selected = that.data.selected
  664. if (selected.id) {
  665. params.push({
  666. pic: selected.pic,
  667. name: selected.name,
  668. originalPrice: selected.originalPrice,
  669. salePrice: selected.salePrice,
  670. shopId: selected.shopId,
  671. id: selected.id,
  672. goodsType: selected.goodsType || 'ACTIVATION_CODE', // INSTRUMENTS
  673. })
  674. }
  675. const selectedInstrument = that.data.selectedInstrument
  676. if (selectedInstrument.id) {
  677. params.push({
  678. pic: selectedInstrument.pic,
  679. name: selectedInstrument.name,
  680. originalPrice: selectedInstrument.originalPrice,
  681. salePrice: selectedInstrument.salePrice,
  682. shopId: selectedInstrument.shopId,
  683. id: selectedInstrument.id,
  684. goodsType: 'INSTRUMENTS', // INSTRUMENTS
  685. })
  686. }
  687. // openId
  688. const openId = wx.getStorageSync("openId")
  689. that.onTrackPoint({
  690. openId,
  691. elementName: "立即购买"
  692. })
  693. let info = JSON.stringify({
  694. ...params
  695. });
  696. info = encodeURIComponent(info);
  697. wx.navigateTo({
  698. url: `../orders/order-detail?orderInfo=${info}&orderType=${that.data.userTypes}`,
  699. success: () => {
  700. that.setData({
  701. popupShow: false,
  702. });
  703. },
  704. });
  705. }, 200)();
  706. },
  707. onPreivewBannerImg(e: { currentTarget: { dataset: any } }) {
  708. wx.previewImage({
  709. current: e.currentTarget.dataset.src,
  710. urls: this.data.imgList,
  711. success: () => {
  712. this.setData({
  713. isFromPreviewImage: true,
  714. });
  715. },
  716. });
  717. },
  718. onPreivewDetailImg(e: { currentTarget: { dataset: any } }) {
  719. wx.previewImage({
  720. current: e.currentTarget.dataset.src,
  721. urls: [
  722. "https://oss.dayaedu.com/ktyq/1733403675345.png",
  723. "https://oss.dayaedu.com/ktyq/1733403707851.png",
  724. "https://oss.dayaedu.com/ktyq/1733403725644.png",
  725. ],
  726. success: () => {
  727. this.setData({
  728. isFromPreviewImage: true,
  729. });
  730. },
  731. });
  732. },
  733. onPreivewDetailImg2(e: { currentTarget: { dataset: any } }) {
  734. wx.previewImage({
  735. current: e.currentTarget.dataset.src,
  736. urls: [
  737. "https://oss.dayaedu.com/ktyq/03/1772461866051.png",
  738. ],
  739. success: () => {
  740. this.setData({
  741. isFromPreviewImage: true,
  742. });
  743. },
  744. });
  745. },
  746. onPreivewGoodsImg(e: { currentTarget: { dataset: any } }) {
  747. wx.previewImage({
  748. current: e.currentTarget.dataset.src,
  749. urls: this.data.goodsImgList,
  750. success: () => {
  751. this.setData({
  752. isFromPreviewImage: true,
  753. });
  754. },
  755. });
  756. },
  757. onPreivewGoods(e: { currentTarget: { dataset: any } }) {
  758. wx.previewImage({
  759. current: e.currentTarget.dataset.src,
  760. urls: [e.currentTarget.dataset.src],
  761. success: () => {
  762. this.setData({
  763. isFromPreviewImage: true,
  764. });
  765. },
  766. });
  767. },
  768. /**
  769. * 生命周期函数--监听页面显示
  770. */
  771. onShow() {
  772. if (!this.data.isFromPreviewImage) {
  773. this.onInit();
  774. } else {
  775. this.setData({
  776. isFromPreviewImage: false,
  777. });
  778. }
  779. this.setData({
  780. serviceShow: true,
  781. });
  782. },
  783. onHide() {
  784. this.setData({
  785. serviceShow: false,
  786. });
  787. },
  788. // 页面滚动时颜色变化
  789. onScrollView(e: { detail: any }) {
  790. const top = e.detail.scrollTop || 0;
  791. // const scrollHeight = e.detail.scrollHeight || 0;
  792. // 从 100 开始显示
  793. this.setData({
  794. // opacity: top < 100 ? 0 : (top - 100) > 150 ? 1 : (top - 100) / 150
  795. opacity: top < 100 ? 0 : top - 100 > 150 ? 1 : 1,
  796. });
  797. // if (top + this.data.initialScrollHeight >= scrollHeight - 80) {
  798. // // console.log('已经滑动到底部了');
  799. // // 相应业务逻辑处理
  800. // this.setData({
  801. // scrolIntoViewStr: "type2",
  802. // });
  803. // } else {
  804. // console.log(this.data.scrollDiscount, top, this.data.headerHeight, "top");
  805. if (this.data.scrollIntoViewType) {
  806. this.setData({
  807. scrollTop: this.data.scrollDiscount
  808. ? top - this.data.headerHeight
  809. : top,
  810. scrollIntoViewType: false,
  811. scrollDiscount: false,
  812. isScrollTT: true,
  813. });
  814. } else {
  815. if (!this.data.isScrollTT) {
  816. this.onChangeScroll();
  817. } else {
  818. this.setData({
  819. isScrollTT: false,
  820. });
  821. }
  822. }
  823. // }
  824. },
  825. onChangeScroll() {
  826. const that = this;
  827. debounce(function () {
  828. wx.createSelectorQuery()
  829. .select("#type3")
  830. .boundingClientRect(function (rect) {
  831. let check = false;
  832. if (rect.top > 0 && rect.top <= that.data.headerHeight) {
  833. that.setData({
  834. scrolIntoViewStr: "type3",
  835. });
  836. check = true;
  837. }
  838. if (rect.top > 0 && rect.top > that.data.headerHeight) {
  839. that.setData({
  840. scrolIntoViewStr: "type1",
  841. });
  842. check = true;
  843. }
  844. // console.log('checked', check)
  845. if (!check) {
  846. wx.createSelectorQuery()
  847. .select("#type2")
  848. .boundingClientRect(function (rect) {
  849. if (rect.top > 0 && rect.top <= that.data.headerHeight) {
  850. that.setData({
  851. scrolIntoViewStr: "type2",
  852. });
  853. }
  854. if (rect.top > 0 && rect.top > that.data.headerHeight) {
  855. that.setData({
  856. scrolIntoViewStr: "type3",
  857. });
  858. }
  859. })
  860. .exec();
  861. }
  862. })
  863. .exec();
  864. }, 100)();
  865. },
  866. onTapAnchor(e: { currentTarget: { dataset: any } }) {
  867. const type = e.currentTarget.dataset.type;
  868. this.setData({
  869. scrolIntoView: type,
  870. scrolIntoViewStr: type,
  871. scrollDiscount: true, // type !== 'type2' ? true : false,
  872. scrollIntoViewType: true,
  873. });
  874. },
  875. onShareAppMessage() {
  876. return {
  877. title: "音乐数字 AI",
  878. path: "/pages/index/index",
  879. imageUrl: "https://oss.dayaedu.com/ktyq/1739870592907.png",
  880. };
  881. },
  882. onShareTimeline() {
  883. return {
  884. title: "音乐数字 AI",
  885. path: "/pages/index/index",
  886. imageUrl: "https://oss.dayaedu.com/ktyq/1739870592907.png",
  887. };
  888. },
  889. });