index.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. import wxParse from '../../../wxParse/wxParse.js';
  2. import util from '../../../utils/util.js';
  3. import ActiveStatusEnum from '../../../utils/enum/sharp/GoodsStatus.js';
  4. const App = getApp();
  5. // 记录规格的数组
  6. let goodsSpecArr = [];
  7. Page({
  8. /**
  9. * 页面的初始数据
  10. */
  11. data: {
  12. indicatorDots: true, // 是否显示面板指示点
  13. autoplay: true, // 是否自动切换
  14. interval: 3000, // 自动切换时间间隔
  15. duration: 800, // 滑动动画时长
  16. currentIndex: 1, // 轮播图指针
  17. floorstatus: false, // 返回顶部
  18. seckill_price: 0, // 商品价格
  19. original_price: 0, // 商品原价
  20. seckill_stock: 0, // 库存数量
  21. goods_num: 1, // 商品数量
  22. goods_sku_id: 0, // 规格id
  23. cart_total_num: 0, // 购物车商品总数量
  24. goodsMultiSpec: {}, // 多规格信息
  25. ActiveStatusEnum, // 秒杀活动商品状态
  26. // 分享按钮组件
  27. share: {
  28. show: false,
  29. cancelWithMask: true,
  30. cancelText: '关闭',
  31. actions: [{
  32. name: '生成商品海报',
  33. className: 'action-class',
  34. loading: false
  35. }, {
  36. name: '发送给朋友',
  37. openType: 'share'
  38. }],
  39. // 商品海报
  40. showPopup: false,
  41. },
  42. // 返回顶部
  43. showTopWidget: false,
  44. active: {}, // 秒杀活动详情
  45. goods: {}, // 商品详情
  46. countDownTime: false // 倒计时
  47. },
  48. /**
  49. * 生命周期函数--监听页面加载
  50. */
  51. onLoad(options) {
  52. const _this = this,
  53. scene = App.getSceneData(options);
  54. // 秒杀商品id
  55. _this.setData({
  56. active_time_id: options.active_time_id ? options.active_time_id : scene.aid,
  57. sharp_goods_id: options.sharp_goods_id ? options.sharp_goods_id : scene.gid,
  58. });
  59. // 获取秒杀商品信息
  60. _this.onRefreshPage();
  61. },
  62. /**
  63. * 刷新页面数据
  64. */
  65. onRefreshPage() {
  66. // 获取秒杀商品信息
  67. const _this = this
  68. _this.getActiveDetail()
  69. },
  70. /**
  71. * 获取秒杀商品信息
  72. */
  73. getActiveDetail() {
  74. let _this = this;
  75. App._get('sharp.goods/detail', {
  76. active_time_id: _this.data.active_time_id,
  77. sharp_goods_id: _this.data.sharp_goods_id,
  78. }, (result) => {
  79. const data = result.data
  80. // 初始化详情数据
  81. _this._initData(data);
  82. // 初始化倒计时组件
  83. _this._initCountDownData(data);
  84. })
  85. },
  86. /**
  87. * 初始化详情数据
  88. */
  89. _initData(data) {
  90. let _this = this;
  91. // 商品详情
  92. let goodsDetail = data.goods;
  93. // 富文本转码
  94. if (goodsDetail.content.length > 0) {
  95. wxParse.wxParse('content', 'html', goodsDetail.content, _this, 0);
  96. }
  97. // 商品价格/划线价/库存
  98. data.goods_sku_id = goodsDetail.goods_sku.spec_sku_id;
  99. data.seckill_price = goodsDetail.goods_sku.seckill_price;
  100. data.original_price = goodsDetail.goods_sku.original_price;
  101. data.seckill_stock = goodsDetail.goods_sku.seckill_stock;
  102. // 商品封面图(确认弹窗)
  103. data.skuCoverImage = goodsDetail.goods_image;
  104. // 多规格商品封面图(确认弹窗)
  105. if (goodsDetail.spec_type == 20 && goodsDetail.goods_sku['image']) {
  106. data.skuCoverImage = goodsDetail.goods_sku['image']['file_path'];
  107. }
  108. // 初始化商品多规格
  109. if (goodsDetail.spec_type == 20) {
  110. data.goodsMultiSpec = _this._initManySpecData(goodsDetail.goods_multi_spec);
  111. }
  112. _this.setData(data)
  113. },
  114. /**
  115. * 初始化倒计时组件
  116. */
  117. _initCountDownData(data) {
  118. const app = this
  119. // 记录倒计时的时间
  120. const countDownTime = data.active.active_status == ActiveStatusEnum.STATE_SOON.value ?
  121. data.active.start_time : data.active.end_time
  122. app.setData({
  123. countDownTime
  124. })
  125. },
  126. /**
  127. * 初始化商品多规格
  128. */
  129. _initManySpecData(data) {
  130. goodsSpecArr = [];
  131. for (let i in data.spec_attr) {
  132. for (let j in data.spec_attr[i].spec_items) {
  133. if (j < 1) {
  134. data.spec_attr[i].spec_items[0].checked = true;
  135. goodsSpecArr[i] = data.spec_attr[i].spec_items[0].item_id;
  136. }
  137. }
  138. }
  139. return data;
  140. },
  141. // 倒计时结束刷新页面
  142. onCountDownEnd() {
  143. const app = this
  144. console.log('onCountDownEnd')
  145. setTimeout(() => {
  146. app.onRefreshPage()
  147. }, 200)
  148. },
  149. /**
  150. * 点击切换不同规格
  151. */
  152. onSwitchSpec(e) {
  153. let _this = this,
  154. attrIdx = e.currentTarget.dataset.attrIdx,
  155. itemIdx = e.currentTarget.dataset.itemIdx,
  156. goodsMultiSpec = _this.data.goodsMultiSpec;
  157. for (let i in goodsMultiSpec.spec_attr) {
  158. for (let j in goodsMultiSpec.spec_attr[i].spec_items) {
  159. if (attrIdx == i) {
  160. goodsMultiSpec.spec_attr[i].spec_items[j].checked = false;
  161. if (itemIdx == j) {
  162. goodsMultiSpec.spec_attr[i].spec_items[itemIdx].checked = true;
  163. goodsSpecArr[i] = goodsMultiSpec.spec_attr[i].spec_items[itemIdx].item_id;
  164. }
  165. }
  166. }
  167. }
  168. _this.setData({
  169. goodsMultiSpec
  170. });
  171. // 更新商品规格信息
  172. _this._updateSpecGoods();
  173. },
  174. /**
  175. * 更新商品规格信息
  176. */
  177. _updateSpecGoods() {
  178. let _this = this,
  179. specSkuId = goodsSpecArr.join('_');
  180. // 查找skuItem
  181. let spec_list = _this.data.goodsMultiSpec.spec_list,
  182. skuItem = spec_list.find((val) => {
  183. return val.spec_sku_id == specSkuId;
  184. });
  185. // 记录goods_sku_id
  186. // 更新商品价格、划线价、库存
  187. if (typeof skuItem === 'object') {
  188. _this.setData({
  189. goods_sku_id: skuItem.spec_sku_id,
  190. seckill_price: skuItem.form.seckill_price,
  191. original_price: skuItem.form.original_price,
  192. seckill_stock: skuItem.form.seckill_stock,
  193. skuCoverImage: skuItem.form.image_id > 0 ? skuItem.form.image_path : _this.data.goods.goods_image
  194. });
  195. }
  196. },
  197. /**
  198. * 设置轮播图当前指针 数字
  199. */
  200. setCurrent(e) {
  201. let _this = this;
  202. _this.setData({
  203. currentIndex: e.detail.current + 1
  204. });
  205. },
  206. /**
  207. * 浏览商品图片
  208. */
  209. onPreviewImages(e) {
  210. let _this = this;
  211. let index = e.currentTarget.dataset.index,
  212. imageUrls = [];
  213. _this.data.goods.image.forEach(item => {
  214. imageUrls.push(item.file_path);
  215. });
  216. wx.previewImage({
  217. current: imageUrls[index],
  218. urls: imageUrls
  219. })
  220. },
  221. /**
  222. * 预览Sku规格图片
  223. */
  224. onPreviewSkuImage(e) {
  225. let _this = this;
  226. wx.previewImage({
  227. current: _this.data.skuCoverImage,
  228. urls: [_this.data.skuCoverImage]
  229. })
  230. },
  231. /**
  232. * 跳转到评论
  233. */
  234. onTargetToComment() {
  235. let _this = this;
  236. wx.navigateTo({
  237. url: `../../goods/comment/comment?goods_id=${_this.data.goods.goods_id}`
  238. });
  239. },
  240. /**
  241. * 返回顶部
  242. */
  243. onScrollTop(t) {
  244. let _this = this;
  245. _this.setData({
  246. scrollTop: 0
  247. });
  248. },
  249. /**
  250. * 显示/隐藏 返回顶部按钮
  251. */
  252. onScrollEvent(e) {
  253. let _this = this;
  254. _this.setData({
  255. showTopWidget: e.detail.scrollTop > 200
  256. })
  257. },
  258. /**
  259. * 显示分享选项
  260. */
  261. onClickShare(e) {
  262. let _this = this;
  263. _this.setData({
  264. 'share.show': true
  265. });
  266. },
  267. /**
  268. * 关闭分享选项
  269. */
  270. onCloseShare() {
  271. let _this = this;
  272. _this.setData({
  273. 'share.show': false
  274. });
  275. },
  276. /**
  277. * 点击生成商品海报
  278. */
  279. onClickShareItem(e) {
  280. let _this = this;
  281. if (e.detail.index === 0) {
  282. // 显示商品海报
  283. _this._showPoster();
  284. }
  285. _this.onCloseShare();
  286. },
  287. /**
  288. * 切换商品海报
  289. */
  290. onTogglePopup() {
  291. let _this = this;
  292. _this.setData({
  293. 'share.showPopup': !_this.data.share.showPopup
  294. });
  295. },
  296. /**
  297. * 显示商品海报图
  298. */
  299. _showPoster() {
  300. let _this = this;
  301. wx.showLoading({
  302. title: '加载中',
  303. });
  304. App._get('sharp.goods/poster', {
  305. active_time_id: _this.data.active_time_id,
  306. sharp_goods_id: _this.data.sharp_goods_id,
  307. }, (result) => {
  308. _this.setData(result.data, () => {
  309. _this.onTogglePopup();
  310. });
  311. }, null, () => {
  312. wx.hideLoading();
  313. });
  314. },
  315. /**
  316. * 保存海报图片
  317. */
  318. onSavePoster(e) {
  319. let _this = this;
  320. wx.showLoading({
  321. title: '加载中',
  322. });
  323. // 下载海报图片
  324. wx.downloadFile({
  325. url: _this.data.qrcode,
  326. success(res) {
  327. wx.hideLoading();
  328. // 图片保存到本地
  329. wx.saveImageToPhotosAlbum({
  330. filePath: res.tempFilePath,
  331. success(data) {
  332. wx.showToast({
  333. title: '保存成功',
  334. icon: 'success',
  335. duration: 2000
  336. });
  337. // 关闭商品海报
  338. _this.onTogglePopup();
  339. },
  340. fail(err) {
  341. console.log(err.errMsg);
  342. if (err.errMsg === 'saveImageToPhotosAlbum:fail auth deny') {
  343. wx.showToast({
  344. title: "请允许访问相册后重试",
  345. icon: "none",
  346. duration: 1000
  347. });
  348. setTimeout(() => {
  349. wx.openSetting();
  350. }, 1000);
  351. }
  352. },
  353. complete(res) {
  354. console.log('complete');
  355. // wx.hideLoading();
  356. }
  357. })
  358. }
  359. })
  360. },
  361. /**
  362. * 增加商品数量
  363. */
  364. onIncGoodsNumber(e) {
  365. let _this = this;
  366. _this.setData({
  367. goods_num: ++_this.data.goods_num
  368. })
  369. },
  370. /**
  371. * 减少商品数量
  372. */
  373. onDecGoodsNumber(e) {
  374. let _this = this;
  375. if (_this.data.goods_num > 1) {
  376. _this.setData({
  377. goods_num: --_this.data.goods_num
  378. });
  379. }
  380. },
  381. /**
  382. * 自定义输入商品数量
  383. */
  384. onInputGoodsNum(e) {
  385. let _this = this,
  386. iptValue = e.detail.value;
  387. if (!util.isPositiveInteger(iptValue) && iptValue !== '') {
  388. iptValue = 1;
  389. }
  390. _this.setData({
  391. goods_num: iptValue
  392. });
  393. },
  394. /**
  395. * 确认购买弹窗
  396. */
  397. onToggleTrade() {
  398. let _this = this;
  399. _this.setData({
  400. showBottomPopup: !_this.data.showBottomPopup
  401. });
  402. },
  403. /**
  404. * 确认购买
  405. */
  406. onCheckout(e) {
  407. let _this = this;
  408. // 表单验证
  409. if (!_this._onVerify()) {
  410. return false;
  411. }
  412. // 立即购买
  413. wx.navigateTo({
  414. url: '../../flow/checkout?' + util.urlEncode({
  415. order_type: 'sharp',
  416. active_time_id: _this.data.active_time_id,
  417. sharp_goods_id: _this.data.sharp_goods_id,
  418. goods_sku_id: _this.data.goods_sku_id,
  419. goods_num: _this.data.goods_num,
  420. }),
  421. success() {
  422. // 关闭弹窗
  423. _this.onToggleTrade();
  424. }
  425. });
  426. },
  427. /**
  428. * 表单验证
  429. */
  430. _onVerify() {
  431. let _this = this;
  432. if (_this.data.goods_num === '') {
  433. App.showError('请输入购买数量');
  434. return false;
  435. }
  436. // 将购买数量转为整型,防止出错
  437. _this.setData({
  438. goods_num: parseInt(_this.data.goods_num)
  439. });
  440. if (_this.data.goods_num <= 0) {
  441. App.showError('购买数量不能为0');
  442. return false;
  443. }
  444. // 判断限购数量
  445. return true;
  446. },
  447. /**
  448. * 跳转到首页
  449. */
  450. onTargetHome(e) {
  451. wx.switchTab({
  452. url: '../../index/index',
  453. })
  454. },
  455. /**
  456. * 分享当前页面
  457. */
  458. onShareAppMessage() {
  459. const _this = this;
  460. // 构建页面参数
  461. const params = App.getShareUrlParams({
  462. active_time_id: _this.data.active_time_id,
  463. sharp_goods_id: _this.data.sharp_goods_id,
  464. });
  465. return {
  466. title: _this.data.goods.goods_name,
  467. path: `/pages/sharp/goods/index?${params}`
  468. };
  469. },
  470. /**
  471. * 分享到朋友圈
  472. * 本接口为 Beta 版本,暂只在 Android 平台支持,详见分享到朋友圈 (Beta)
  473. * https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html
  474. */
  475. onShareTimeline() {
  476. const _this = this;
  477. // 构建页面参数
  478. const params = App.getShareUrlParams({
  479. active_time_id: _this.data.active_time_id,
  480. sharp_goods_id: _this.data.sharp_goods_id,
  481. });
  482. return {
  483. title: _this.data.goods.goods_name,
  484. path: `/pages/sharp/goods/index?${params}`
  485. };
  486. },
  487. })