const app = getApp(); import wxh from '../../utils/wxh.js'; import { getIndexData, getCoupons, getTplIds, getLiveList, getNotifications } from '../../api/api.js'; import { CACHE_SUBSCRIBE_MESSAGE } from '../../config.js'; import { getCategoryList, getProductHot, getProductslist } from '../../api/store.js'; import { getCouponReceive } from '../../api/user.js'; import { getSeckillIndexTime, getSeckillList } from '../../api/activity.js'; import Util from '../../utils/util.js'; import d from '../../utils/d.js'; const CATE_BLACKHOLE_ID = 199 const PAGE_LIMIT = 20 const THROTTLE_TIME = 100 // 滚动回调限流 ms const HEIGHT_OF_ROW = 500 // 摘抄自 css, 商品高度,包含图片文字 margin. rpx const ITEM_NUM_OF_ROW = 2 // 设计为一行 2 个元素 Page({ /** * 页面的初始数据 */ data: { CATE_BLACKHOLE_ID: CATE_BLACKHOLE_ID, logoUrl: '', // 左上方 logo prodCates: [], // 分类列表/活动列表 (目前只有一个,就是“活动”) banner: [], // 顶部 banner show_benefit: false, // 是否显示赔付比率 itemNew: [], // 跑马灯列表 menus: [], getCouponList: [], //@deprecated activity: [], timeList: [], //@deprecated killIndex: 0, //@deprecated 点击当前index值; seckillTimeIndex: 0, //@deprecated 当前秒杀index; killIndexTime: 0, //@deprecated 点击当前index值所对应的秒杀时间; killIndexLen: 0, //@deprecated 当前秒杀的产品列表长度 seckillList: [], //@deprecated scrollLeft: 0, //@deprecated status: 1, //@deprecated lovely: [], //@deprecated info: { fastList: [], bastBanner: [], // 精品推荐 banner firstList: [], // 首发新品 bastList: [] // 精品推荐 }, avtiveIndex: 0, // 轮播图索引 likeInfo: [], // 热门榜单 benefit: [], // 促销单品 hotProducts: [], // 海量精品 ? indicatorDots: false, // 跑马灯轮播图不带点 circular: true, // 轮播图圆点 autoplay: true, // 跑马灯轮播图自动播放 intervalNew: 3500, // 轮播图自动播放间隔 durationNew: 700, // 轮播图自动播放时长 parameter: { 'navbar': '0', 'return': '0', 'class': '5' }, window: false, // 是否显示优惠券窗口 hideTip: false, // 是否显示提示 isAuto: true, // 是否自动授权; iShidden: true, // 是否隐藏; isGoIndex: false, // 是否返回首页; recommend: { loadend: false, // 已全部加载 loading: false, // 正在加载 loadTitle: '加载更多', page: 1, limit: 20, }, /// 以下为拉洋片算法参数 navH: 0, // 标题栏高度 navPxH: 0, // rowHeight: HEIGHT_OF_ROW, rowPxHeight: HEIGHT_OF_ROW, rowProdNum: ITEM_NUM_OF_ROW, rowCacheNum: 5, // 拉洋片缓冲商品: 3 行 /// activeTabIndex: 0, countDownHour: "00", countDownMinute: "00", countDownSecond: "00", seckillCont: true, //@deprecated interval: null, timerNotification: null, newGoodsBananr: '', //@deprecated cpnMine: null, // 挖礦組件 liveList: [], // 直播列表 liveInfo: {} }, // 关闭提示添加到小程序窗口 closeTip: function () { wx.setStorageSync('msg_key', true); this.setData({ hideTip: true }) }, // 挖矿组件绑定 onNeedLogin: function () { this.setData({ iShidden: false }) }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { // 由分享链接跳转过来 // a === 'share' // id 商品ID // spid spread_id // ch 渠道 if (options.ch) { app.globalData.channel = options.ch } if (options.a && options.a == 'share' && options.id && options.spid) { wx.navigateTo({ url: '/pages/goods_details/index?id=' + options.id + '&spid=' + options.spid, }) } // 获取 nav 高度等信息 let query = wx.createSelectorQuery() query.select('.indexs').boundingClientRect((rect) => { let width = rect.width let ratio = 750 / width // px -> rpx 需要乘以的数 this.setData({ rowPxHeight: Math.floor(this.data.rowHeight / ratio), navH: app.globalData.navHeight, navPxH: Math.floor(app.globalData.navHeight / ratio), }) d.debug('width:', width, 'ratio:', ratio) d.debug('rowHeight:', this.data.rowPxHeight, 'navH:', this.data.navH, 'navPxH:', this.data.navPxH) }).exec() wxh.selfLocation(1); this.getCategoryData(); // this.getCoupon(); this.get_hot_product(); // this.get_product_list(); if (options.spid) { app.globalData.spid = options.spid; } if (options.scene) { app.globalData.code = decodeURIComponent(options.scene); } if (wx.getStorageSync('msg_key')) { this.setData({ hideTip: true }); } this.getTplIds(); this.getLiveList(); }, getTplIds() { let messageTmplIds = wx.getStorageSync(CACHE_SUBSCRIBE_MESSAGE); if (!messageTmplIds) { getTplIds().then(res => { if (res.data) { wx.setStorageSync(CACHE_SUBSCRIBE_MESSAGE, JSON.stringify(res.data)); } }).catch(err => { d.error('err:', err) }) } }, //授权 onLoadFun: function () { // 挖矿组件认证回调 if (this.data.cpnMine != null) { this.data.cpnMine.onLoadFun(); } }, catchTouchMove: function (res) { return false }, /** 关闭优惠券窗口 */ onClose: function () { this.setData({ window: false }); }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () {}, /** * 轮播监听 */ bindchange(e) { var index = e.detail.current; this.setData({ avtiveIndex: index }); }, /** * 生命周期函数--监听页面显示 */ onShow: function () { // this.getCoupon(); this.getIndexConfig(); // this.getSeckillTime(); var that = this this.setData({ timerNotification: setInterval(function () { that.loadNotifications() }, 1000 * 60 * 3) }) app.updateUnread() }, // 加载通知,目前只有跑马灯 loadNotifications: function () { var that = this getNotifications().then(res => { if (res.data.carousel.length > 0) { that.setData({ itemNew: res.data.carousel }) } }) }, getIndexConfig: function () { var that = this; getIndexData().then(res => { that.setData({ banner: res.data.banner, show_benefit: res.data.show_benefit, menus: res.data.menus, activity: res.data.activity, lovely: res.data.lovely, info: res.data.info, itemNew: res.data.roll, likeInfo: res.data.likeInfo, benefit: res.data.benefit, logoUrl: res.data.logoUrl, couponList: res.data.couponList, }); app.globalData.show_benefit = res.data.show_benefit; app.setUnread(res.data.notice); }) }, getLiveList: function () { let that = this getLiveList(1, 20).then(res => { if (res.data.length == 1) { that.setData({ liveInfo: res.data[0] }); } else { that.setData({ liveList: res.data }); } }).catch(err => { d.error('error:', err) }) }, /** * 商品详情跳转 商品点击事件 */ goDetailType: function (e) { let item = e.currentTarget.dataset.items if (item.activity && item.activity.type === "1") { wx.navigateTo({ url: `/pages/activity/goods_seckill_details/index?id=${item.activity.id}&time=${item.activity.time}&status=1` }); } else if (item.activity && item.activity.type === "2") { wx.navigateTo({ url: `/pages/activity/goods_bargain_details/index?id=${item.activity.id}` }); } else if (item.activity && item.activity.type === "3") { wx.navigateTo({ url: `/pages/activity/goods_combination_details/index?id=${item.activity.id}` }); } else { wx.navigateTo({ url: `/pages/goods_details/index?id=${item.id}` }); } }, /** * 获取我的推荐 */ get_hot_product: function (isReload) { if (this.data.recommend.loadend) return; if (this.data.recommend.loading) return; if (isReload) { this.setData({ 'recommend.page': 1, hotProducts: [] }); } this.setData({ 'recommend.loading': true, 'recommend.loadTitle': '' }); let that = this; getProductHot(this.data.recommend.page, this.data.recommend.limit).then(res => { let list = res.data; let hotProducts = app.SplitArray(list, that.data.hotProducts); let loadend = list.length < that.data.recommend.limit; that.setData({ 'recommend.loadend': loadend, 'recommend.loading': false, 'recommend.loadTitle': loadend ? '已全部加载' : '加载更多', hotProducts: hotProducts, ['recommend.page']: that.data.recommend.page + 1, }); }).catch(err => { that.setData({ 'recommend.loading': false, 'recommend.loadTitle': '加载更多' }); }); }, /** 点击上方活动标签按钮 */ onTapCategoryTabItem: function (event) { let tabIndex = event.detail.index; d.debug('this.data.prodCates.children.length:', this.data.prodCates.children.length, 'current tab index:', tabIndex) // 不能过界 0 是主场,不包含在 prodCates 内, // 主场不处理 if (tabIndex <= 0 || tabIndex > this.data.prodCates.children.length) { d.debug('tab index out of range:', tabIndex) this.setData({ activeTabIndex: tabIndex }) return } this.setData({ activeTabIndex: tabIndex, }) if (this.data.prodCates.children[tabIndex - 1].id === CATE_BLACKHOLE_ID) { // 黑洞 let mine = null if (this.data.cpnMine == null) { mine = this.selectComponent('#mine') this.setData({ cpnMine: mine, }) } var _ = this.data.cpnMine && this.data.cpnMine.show() return } var _ = this.data.cpnMine && this.data.cpnMine.hide() // 首屏 if (this.data.prodCates.children[tabIndex - 1].page <= 1) { this.get_product_list(tabIndex); } wx.pageScrollTo({ scrollTop: this.data.prodCates.children[tabIndex - 1].scrollPos }) }, // 获取商品列表 // @tabIndex 活动标签 @isReload 是否重新加载 get_product_list: function (tabIndex, isReload) { // 不处理主场和黑洞星球 if (tabIndex <= 0 || tabIndex > this.data.prodCates.children.length) { d.debug('invalid tab index:', tabIndex) return } // 大类 ID let cid = this.data.prodCates.id // 子类 let act = this.data.prodCates.children[tabIndex - 1] if (act.loading) return if (act.loaded && !isReload) return let cindex = tabIndex - 1 // tab index 转换到 数据的 index if (isReload) { this.setData({ [`prodCates.children[${cindex}].page`]: 1, [`prodCates.children[${cindex}].products`]: [], [`prodCates.children[${cindex}].aboveShowRowIndex`]: 0, [`prodCates.children[${cindex}].belowShowRowNum`]: 0 }) } this.setData({ [`prodCates.children[${cindex}].loading`]: true, [`prodCates.children[${cindex}].loadTitle`]: '' }); var that = this; getProductslist({ page: act.page, limit: PAGE_LIMIT, cid: cid, sid: act.id, }).then(res => { let list = [] // res.data // 过滤产品列表, 只保留本页用的字段 let counter = act.products.length res.data.forEach((prod) => { counter += 1 list.push({ id: prod.id, image: prod.image, activity: prod.activity, store_name: prod.store_name, price: prod.price, reputation: prod.reputation, vip_price: prod.vip_price, sales: prod.sales, isShow: (counter / 2 - act.aboveShowRowIndex) <= 2 * this.data.rowCacheNum, // 是否显示 }) }) // console.log('list.length:', list.length, 'res.data.length:', res.data.length) let products = app.SplitArray(list, act.products) let loaded = list.length < PAGE_LIMIT that.setData({ [`prodCates.children[${cindex}].loaded`]: loaded, [`prodCates.children[${cindex}].loading`]: false, [`prodCates.children[${cindex}].loadTitle`]: loaded ? '已全部加载' : '加载更多', [`prodCates.children[${cindex}].products`]: products, [`prodCates.children[${cindex}].page`]: act.page + 1 }); d.debug(that.data.prodCates) }).catch(err => { d.error(err) that.setData({ [`prodCates.children[${cindex}].loading`]: false, [`prodCates.children[${cindex}].loadTitle`]: '加载更多' }); }); }, // getSeckillTime: function () { // let that = this; // getSeckillIndexTime().then(res => { // let timeList = res.data.seckillTime, seckillTimeIndex = res.data.seckillTimeIndex; // that.setData({ // timeList: timeList, // seckillCont: res.data.seckillCont, // killIndex: seckillTimeIndex, // seckillTimeIndex: seckillTimeIndex, // killIndexTime: timeList[that.data.killIndex].stop, // status: timeList[seckillTimeIndex].status // }) // wxh.time(timeList[that.data.killIndex].stop, that,false); // that.getSeckillLists(); // }).catch(()=>{ // }); // }, // 页面事件, 不再使用 // setTime: function (e) { // let index = e.currentTarget.dataset.index; // this.setData({ // killIndex: index, // status: that.data.timeList[index].status // }) // // that.getSeckillLists(); // }, // 不再触发 // getSeckillLists: function () { // let that = this; // let timeId = that.data.timeList[that.data.killIndex].id; // getSeckillList(timeId, { // page: 1, // limit: 20 // }).then(res => { // that.setData({ // seckillList: res.data // }) // if (this.data.timeList.length) { // let query = wx.createSelectorQuery().in(this); // query.select('.timeLen').boundingClientRect(function (res) { // if (res) { // that.setData({ // scrollLeft: (that.data.killIndex - 1.8) * res.width // }); // } // }).exec(); // if (that.data.killIndex === that.data.seckillTimeIndex) { // that.setData({ // killIndexLen: res.data.length // }) // } // } // }).catch(() => {}); // }, // 获取分类列表 getCategoryData: function () { let that = this; getCategoryList().then(res => { let cates = res.data.length > 0 ? res.data[0] : {} that.setData({ prodCates: that._rebuildProdCates(cates) }) d.debug(this.data.prodCates) }); }, // 整理 this.data.prodCates _rebuildProdCates: function (cates) { cates.children.forEach(cate => { // 不处理黑洞星球 if (cate.id == CATE_BLACKHOLE_ID) { return } // 增加属性 cate.loading = false cate.loaded = false cate.loadTitle = '加载更多' cate.products = [] cate.page = 1 // 当前第几页 cate.scrollPos = 0 // 上次滚动条位置 cate.aboveShowRowIndex = 0 // 可见区域上部行索引 cate.belowShowRowNum = 0 // 底部隐藏行数 }) return cates; }, /** 获取优惠券列表 不再触发*/ // getCoupon: function () { // var that = this; // getCoupons({ // page: 1, // limit: 6 // }).then(res => { // that.setData({ // getCouponList: res.data // }) // }).catch(err => { // // app.Tips({ // // title: err // // }); // }); // }, // 页面回调,不再触发 // receiveCoupon: function (e) { // if (!app.globalData.isLog) { // this.setData({ // iShidden: false // }); // } else { // var that = this; // var list = that.data.getCouponList; // var index = e.currentTarget.dataset.index; // var id = that.data.getCouponList[index].id; // getCouponReceive({ // couponId: id // }) // .then(function () { // list[index].is_use = true; // that.setData({ // getCouponList: that.data.getCouponList // }) // app.Tips({ // title: "领取成功" // }); // }) // .catch(function (err) { // // app.Tips({ // // title: err // // }); // }); // } // }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { this.setData({ window: false }); this.data.interval !== null && clearInterval(this.data.interval); if (this.data.timerNotification != null) { clearInterval(this.data.timerNotification); this.setData({ timerNotification: null, }) } var _ = this.data.cpnMine && this.data.cpnMine.hide() }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { this.data.interval !== null && clearInterval(this.data.interval); }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { let tabIndex = this.data.activeTabIndex // 主场刷新 // 其他场刷新 if (tabIndex == 0) { this.getIndexConfig(); } else if (tabIndex > this.data.prodCates.children.length) { d.error('invalid tab index:', tabIndex) } else { if (!this.data.prodCates.children[tabIndex - 1].id == CATE_BLACKHOLE_ID) { this.get_product_list(tabIndex, true) } } this.get_hot_product(true) wx.stopPullDownRefresh(); }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { let tabIndex = this.data.activeTabIndex // 主场只加载热门 // 其他场加载商品列表 if (tabIndex == 0) { this.get_hot_product(); } else if (tabIndex > 0 && tabIndex <= this.data.prodCates.children.length && this.data.prodCates.children[tabIndex - 1].id != CATE_BLACKHOLE_ID) { this.get_product_list(this.data.activeTabIndex); if (this.data.prodCates.children[tabIndex - 1].loadend) { this.get_hot_product(); } } }, onPageScroll: throttle(function (obj) { let tabIndex = this.data.activeTabIndex if (tabIndex <= 0 || tabIndex > this.data.prodCates.children.length || this.data.prodCates.children[tabIndex - 1].id == CATE_BLACKHOLE_ID) { d.debug('ignore tab scroll event. tab index:', tabIndex) return } let pos = obj[0].scrollTop // let calcPos = pos //- this.data.navPxH calcPos = calcPos > 0 ? calcPos : 0 let rowNum = Math.floor(calcPos / this.data.rowPxHeight) // 滚动过去的总行数, 也是当前 viewport 的开始索引位置 let clearRowNum = rowNum - this.data.rowCacheNum // 隐藏总行数 let cindex = tabIndex - 1 let tabData = this.data.prodCates.children[cindex] let changingData = {} if (pos - tabData.scrollPos > 0) { // 向下 // d.debug('DOWN pos:', pos, 'rowPxHeight', this.data.rowPxHeight, // 'rowNum:', rowNum, 'clearRowNum:', clearRowNum, 'aboveShowRowIndex:', tabData.aboveShowRowIndex) if (clearRowNum > 0) { // aboveShowRowIndex 索引的行之前都不显示 for (let i = tabData.aboveShowRowIndex; i < clearRowNum; i++) { let leftIndex = i * 2 changingData[[`prodCates.children[${cindex}].products[${leftIndex}].isShow`]] = false changingData[[`prodCates.children[${cindex}].products[${leftIndex + 1}].isShow`]] = false let belowShowRowIndex = i + 2 * this.data.rowCacheNum if (belowShowRowIndex < Math.floor(tabData.products.length / 2)) { leftIndex = belowShowRowIndex * 2 changingData[[`prodCates.children[${cindex}].products[${leftIndex}].isShow`]] = true changingData[[`prodCates.children[${cindex}].products[${leftIndex + 1}].isShow`]] = true } } } } else { // 向上 // d.debug('UP pos:', pos, 'rowPxHeight', this.data.rowPxHeight, // 'rowNum:', rowNum, 'clearRowNum:', clearRowNum, 'aboveShowRowIndex:', tabData.aboveShowRowIndex) if (clearRowNum >= 0) { for (let i = tabData.aboveShowRowIndex - 1; i >= clearRowNum; i--) { let leftIndex = i * 2 changingData[[`prodCates.children[${cindex}].products[${leftIndex}].isShow`]] = true changingData[[`prodCates.children[${cindex}].products[${leftIndex + 1}].isShow`]] = true let belowShowRowIndex = i + 2 * this.data.rowCacheNum if (belowShowRowIndex < tabData.products.length / 2) { leftIndex = belowShowRowIndex * 2 changingData[[`prodCates.children[${cindex}].products[${leftIndex}].isShow`]] = false changingData[[`prodCates.children[${cindex}].products[${leftIndex + 1}].isShow`]] = false } } } else { if (tabData.aboveShowRowIndex > 0) { for (let i = 0; i < tabData.aboveShowRowIndex; i++) { this.setData({ [`prodCates.children[${cindex}].products[${i * 2}].isShow`]: true, [`prodCates.children[${cindex}].products[${i * 2 + 1}].isShow`]: true, }) // changingData[[`prodCates.children[${cindex}].products[${i * 2}].isShow`]] = true // changingData[[`prodCates.children[${cindex}].products[${i * 2 + 1}].isShow`]] = true } } } } // clearRowNum = clearRowNum > 0 ? clearRowNum : 0; if (clearRowNum >= 0 && !(clearRowNum > 0 && clearRowNum == tabData.aboveShowRowIndex)) { changingData[[`prodCates.children[${cindex}].aboveShowRowIndex`]] = clearRowNum let belowShowRowNum = tabData.products.length / 2 - (2 * this.data.rowCacheNum + clearRowNum) belowShowRowNum = belowShowRowNum > 0 ? belowShowRowNum : 0 // console.log('belowShowRowNum:', belowShowRowNum, 'tabData.products.length:', tabData.products.length, 'clearRowNum:', clearRowNum) if (belowShowRowNum >= 0) { changingData[[`prodCates.children[${cindex}].belowShowRowNum`]] = belowShowRowNum // for (let i = 0; i < belowShowRowNum; i++) { // let leftIndex = (tabData.products.length / 2 - i - 1) * 2; // changingData[[`prodCates.children[${cindex}].products[${leftIndex}].isShow`]] = false // changingData[[`prodCates.children[${cindex}].products[${leftIndex + 1}].isShow`]] = false // } } this.setData(changingData) } if (cindex >= 0 && cindex < this.data.prodCates.children.length) { this.setData({ ['prodCates.children[' + cindex + '].scrollPos']: pos }) } // this._debugProducts() }), _debugProducts: function () { let all = [], display = [], tabIndex = this.data.activeTabIndex if (tabIndex <= 0 || tabIndex > this.data.prodCates.children.length) { return } let tabData = this.data.prodCates.children[tabIndex - 1] for (let i = 0; i < tabData.products.length; i++) { if (tabData.products[i].isShow) { display.push(i) } all.push(i) } d.debug('all:', all) d.debug('display:', display) }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { } }) function throttle(fn) { let valid = true return function () { if (!valid) { return false } valid = false return setTimeout(() => { fn.call(this, arguments) valid = true }, THROTTLE_TIME) } }