index.js 11 KB

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