goods.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. import Notify from '../../components/notify/index';
  2. var app = getApp();
  3. var WxParse = require('../../lib/wxParse/wxParse.js');
  4. var util = require('../../utils/util.js');
  5. var api = require('../../config/api.js');
  6. var user = require('../../utils/user.js');
  7. Page({
  8. data: {
  9. id: 0,
  10. goods: {},
  11. groupon: [], //该商品支持的团购规格
  12. grouponLink: {}, //参与的团购
  13. attribute: [],
  14. issueList: [],
  15. brand: {},
  16. specificationList: [],
  17. productList: [],
  18. relatedGoods: [],
  19. // lgoods: {},
  20. // lgroupon: [], //该商品支持的团购规格
  21. // lgrouponLink: {}, //参与的团购
  22. // lattribute: [],
  23. // lissueList: [],
  24. // lbrand: {},
  25. // lspecificationList: [
  26. // ],
  27. // lproductList: [],
  28. // lrelatedGoods: [],
  29. cartGoodsCount: 0,
  30. userHasCollect: 0,
  31. number: 1,
  32. checkedSpecText: '规格数量选择',
  33. tmpSpecText: '请选择规格数量',
  34. checkedSpecPrice: 0,
  35. openAttr: false,
  36. shareImage: '',
  37. isGroupon: false, //标识是否是一个参团购买
  38. soldout: false,
  39. canWrite: false
  40. },
  41. // 页面分享
  42. onShareAppMessage: function() {
  43. let that = this;
  44. return {
  45. title: that.data.goods.name,
  46. desc: '特惠商品',
  47. path: '/pages/index/index?goodId=' + this.data.id
  48. }
  49. },
  50. handleSetting: function(e) {
  51. var that = this;
  52. // console.log(e)
  53. if (!e.detail.authSetting['scope.writePhotosAlbum']) {
  54. wx.showModal({
  55. title: '警告',
  56. content: '不授权无法保存',
  57. showCancel: false
  58. })
  59. that.setData({
  60. canWrite: false
  61. })
  62. } else {
  63. wx.showToast({
  64. title: '保存成功'
  65. })
  66. that.setData({
  67. canWrite: true
  68. })
  69. }
  70. },
  71. showShare: function() {
  72. this.sharePop.togglePopup();
  73. },
  74. //从分享的团购进入
  75. getGrouponInfo: function(grouponId) {
  76. let that = this;
  77. util.request(api.GroupOnJoin, {
  78. grouponId: grouponId
  79. }).then(function(res) {
  80. if (res.errno === 0) {
  81. that.setData({
  82. grouponLink: res.data.groupon,
  83. id: res.data.goods.id
  84. });
  85. //获取商品详情
  86. that.getGoodsInfo();
  87. }
  88. });
  89. },
  90. // 获取商品信息
  91. getGoodsInfo: function() {
  92. wx.showLoading({
  93. title: '加载中',
  94. });
  95. setTimeout(function() {
  96. wx.hideLoading()
  97. }, 2000);
  98. let that = this;
  99. util.request(api.GoodsDetail, {
  100. id: that.data.id
  101. }).then(function(res) {
  102. if (res.errno === 0) {
  103. let _specificationList = res.data.specificationList
  104. // 如果仅仅存在一种货品,那么商品页面初始化时默认checked
  105. if (_specificationList.length == 1) {
  106. if (_specificationList[0].valueList.length == 1) {
  107. _specificationList[0].valueList[0].checked = true
  108. // 如果仅仅存在一种货品,那么商品价格应该和货品价格一致
  109. // 这里检测一下
  110. let _productPrice = res.data.productList[0].price;
  111. let _goodsPrice = res.data.info.retailPrice;
  112. if (_productPrice != _goodsPrice) {
  113. console.error('商品数量价格和货品不一致');
  114. }
  115. that.setData({
  116. checkedSpecText: _specificationList[0].valueList[0].value,
  117. tmpSpecText: '已选择:' + _specificationList[0].valueList[0].value,
  118. });
  119. }
  120. }
  121. that.setData({
  122. // lgoods: res.data.info,
  123. // lattribute: res.data.attribute,
  124. // lissueList: res.data.issue,
  125. // lbrand: res.data.brand,
  126. // lspecificationList: res.data.specificationList,
  127. // lproductList: res.data.productList,
  128. // luserHasCollect: res.data.userHasCollect,
  129. // lshareImage: res.data.shareImage,
  130. // lcheckedSpecPrice: res.data.info.retailPrice,
  131. // lgroupon: res.data.groupon
  132. goods: res.data.info,
  133. attribute: res.data.attribute,
  134. issueList: res.data.issue,
  135. brand: res.data.brand,
  136. specificationList: res.data.specificationList,
  137. productList: res.data.productList,
  138. userHasCollect: res.data.userHasCollect,
  139. shareImage: res.data.shareImage,
  140. checkedSpecPrice: res.data.info.retailPrice,
  141. groupon: res.data.groupon
  142. });
  143. //如果是通过分享的团购参加团购,则团购项目应该与分享的一致并且不可更改
  144. if (that.data.isGroupon) {
  145. let groupons = that.data.groupon;
  146. for (var i = 0; i < groupons.length; i++) {
  147. if (groupons[i].id != that.data.grouponLink.rulesId) {
  148. groupons.splice(i, 1);
  149. }
  150. }
  151. groupons[0].checked = true;
  152. //重设团购规格
  153. that.setData({
  154. groupon: groupons
  155. });
  156. }
  157. WxParse.wxParse('goodsDetail', 'html', res.data.info.detail, that);
  158. //获取推荐商品
  159. that.getGoodsRelated();
  160. wx.hideLoading();
  161. }
  162. });
  163. },
  164. // 获取推荐商品
  165. getGoodsRelated: function() {
  166. let that = this;
  167. util.request(api.GoodsRelated, {
  168. id: that.data.id
  169. }).then(function(res) {
  170. if (res.errno === 0) {
  171. that.setData({
  172. relatedGoods: res.data.list,
  173. });
  174. }
  175. });
  176. },
  177. // 团购选择
  178. clickGroupon: function(event) {
  179. let that = this;
  180. //参与团购,不可更改选择
  181. if (that.data.isGroupon) {
  182. return;
  183. }
  184. let specName = event.currentTarget.dataset.name;
  185. let specValueId = event.currentTarget.dataset.valueId;
  186. let _grouponList = this.data.groupon;
  187. for (let i = 0; i < _grouponList.length; i++) {
  188. if (_grouponList[i].id == specValueId) {
  189. if (_grouponList[i].checked) {
  190. _grouponList[i].checked = false;
  191. } else {
  192. _grouponList[i].checked = true;
  193. }
  194. } else {
  195. _grouponList[i].checked = false;
  196. }
  197. }
  198. this.setData({
  199. groupon: _grouponList,
  200. });
  201. },
  202. // 规格选择
  203. clickSkuValue: function(event) {
  204. let that = this;
  205. let specName = event.currentTarget.dataset.name;
  206. let specValueId = event.currentTarget.dataset.valueId;
  207. //判断是否可以点击
  208. //TODO 性能优化,可在wx:for中添加index,可以直接获取点击的属性名和属性值,不用循环
  209. let _specificationList = this.data.specificationList;
  210. for (let i = 0; i < _specificationList.length; i++) {
  211. if (_specificationList[i].name === specName) {
  212. for (let j = 0; j < _specificationList[i].valueList.length; j++) {
  213. if (_specificationList[i].valueList[j].id == specValueId) {
  214. //如果已经选中,则反选
  215. if (_specificationList[i].valueList[j].checked) {
  216. _specificationList[i].valueList[j].checked = false;
  217. } else {
  218. _specificationList[i].valueList[j].checked = true;
  219. }
  220. } else {
  221. _specificationList[i].valueList[j].checked = false;
  222. }
  223. }
  224. }
  225. }
  226. this.setData({
  227. specificationList: _specificationList,
  228. });
  229. //重新计算spec改变后的信息
  230. this.changeSpecInfo();
  231. //重新计算哪些值不可以点击
  232. },
  233. //获取选中的团购信息
  234. getCheckedGrouponValue: function() {
  235. let checkedValues = {};
  236. let _grouponList = this.data.groupon;
  237. for (let i = 0; i < _grouponList.length; i++) {
  238. if (_grouponList[i].checked) {
  239. checkedValues = _grouponList[i];
  240. }
  241. }
  242. return checkedValues;
  243. },
  244. //获取选中的规格信息
  245. getCheckedSpecValue: function() {
  246. let checkedValues = [];
  247. let _specificationList = this.data.specificationList;
  248. for (let i = 0; i < _specificationList.length; i++) {
  249. let _checkedObj = {
  250. name: _specificationList[i].name,
  251. valueId: 0,
  252. valueText: ''
  253. };
  254. for (let j = 0; j < _specificationList[i].valueList.length; j++) {
  255. if (_specificationList[i].valueList[j].checked) {
  256. _checkedObj.valueId = _specificationList[i].valueList[j].id;
  257. _checkedObj.valueText = _specificationList[i].valueList[j].value;
  258. }
  259. }
  260. checkedValues.push(_checkedObj);
  261. }
  262. return checkedValues;
  263. },
  264. //判断规格是否选择完整
  265. isCheckedAllSpec: function() {
  266. return !this.getCheckedSpecValue().some(function(v) {
  267. if (v.valueId == 0) {
  268. return true;
  269. }
  270. });
  271. },
  272. soldoutNotify: function() {
  273. Notify("商品已售完");
  274. },
  275. getCheckedSpecKey: function() {
  276. let checkedValue = this.getCheckedSpecValue().map(function(v) {
  277. return v.valueText;
  278. });
  279. return checkedValue;
  280. },
  281. // 规格改变时,重新计算价格及显示信息
  282. changeSpecInfo: function() {
  283. let checkedNameValue = this.getCheckedSpecValue();
  284. //设置选择的信息
  285. let checkedValue = checkedNameValue.filter(function(v) {
  286. if (v.valueId != 0) {
  287. return true;
  288. } else {
  289. return false;
  290. }
  291. }).map(function(v) {
  292. return v.valueText;
  293. });
  294. if (checkedValue.length > 0) {
  295. this.setData({
  296. tmpSpecText: checkedValue.join(' ')
  297. });
  298. } else {
  299. this.setData({
  300. tmpSpecText: '请选择规格数量'
  301. });
  302. }
  303. if (this.isCheckedAllSpec()) {
  304. this.setData({
  305. checkedSpecText: this.data.tmpSpecText
  306. });
  307. // 规格所对应的货品选择以后
  308. let checkedProductArray = this.getCheckedProductItem(this.getCheckedSpecKey());
  309. if (!checkedProductArray || checkedProductArray.length <= 0) {
  310. this.setData({
  311. soldout: true
  312. });
  313. this.soldoutNotify();
  314. console.error('规格所对应货品不存在');
  315. return;
  316. }
  317. let checkedProduct = checkedProductArray[0];
  318. if (checkedProduct.number > 0) {
  319. this.setData({
  320. checkedSpecPrice: checkedProduct.price,
  321. soldout: false
  322. });
  323. this.notify.hide();
  324. } else {
  325. this.setData({
  326. checkedSpecPrice: this.data.goods.retailPrice,
  327. soldout: true
  328. });
  329. this.soldoutNotify();
  330. }
  331. } else {
  332. this.setData({
  333. checkedSpecText: '规格数量选择',
  334. checkedSpecPrice: this.data.goods.retailPrice,
  335. soldout: false
  336. });
  337. this.notify.hide();
  338. }
  339. },
  340. // 获取选中的产品(根据规格)
  341. getCheckedProductItem: function(key) {
  342. return this.data.productList.filter(function(v) {
  343. if (v.specifications.toString() == key.toString()) {
  344. return true;
  345. } else {
  346. return false;
  347. }
  348. });
  349. },
  350. onLoad: function(options) {
  351. // 页面初始化 options为页面跳转所带来的参数
  352. if (options.id) {
  353. this.setData({
  354. id: parseInt(options.id)
  355. });
  356. this.getGoodsInfo();
  357. }
  358. if (options.grouponId) {
  359. this.setData({
  360. isGroupon: true,
  361. });
  362. this.getGrouponInfo(options.grouponId);
  363. }
  364. let that = this;
  365. wx.getSetting({
  366. success: function (res) {
  367. console.log(res)
  368. //不存在相册授权
  369. if (!res.authSetting['scope.writePhotosAlbum']) {
  370. wx.authorize({
  371. scope: 'scope.writePhotosAlbum',
  372. success: function () {
  373. that.setData({
  374. canWrite: true
  375. })
  376. },
  377. fail: function (err) {
  378. that.setData({
  379. canWrite: false
  380. })
  381. }
  382. })
  383. } else {
  384. that.setData({
  385. canWrite: true
  386. });
  387. }
  388. }
  389. })
  390. },
  391. onShow: function() {
  392. // 页面显示
  393. var that = this;
  394. util.request(api.CartGoodsCount).then(function(res) {
  395. if (res.errno === 0) {
  396. that.setData({
  397. cartGoodsCount: res.data
  398. });
  399. }
  400. });
  401. },
  402. //立即购买(先自动加入购物车)
  403. addFast: function() {
  404. var that = this;
  405. if (this.data.openAttr == false) {
  406. //打开规格选择窗口
  407. this.setData({
  408. openAttr: !this.data.openAttr
  409. });
  410. } else {
  411. //提示选择完整规格
  412. if (!this.isCheckedAllSpec()) {
  413. wx.showToast({
  414. image: '/static/images/icon_error.png',
  415. title: '请选择完整规格'
  416. });
  417. return false;
  418. }
  419. //根据选中的规格,判断是否有对应的sku信息
  420. let checkedProductArray = this.getCheckedProductItem(this.getCheckedSpecKey());
  421. if (!checkedProductArray || checkedProductArray.length <= 0) {
  422. //找不到对应的product信息,提示没有库存
  423. wx.showToast({
  424. image: '/static/images/icon_error.png',
  425. title: '没有库存'
  426. });
  427. return false;
  428. }
  429. let checkedProduct = checkedProductArray[0];
  430. //验证库存
  431. if (checkedProduct.number <= 0) {
  432. wx.showToast({
  433. image: '/static/images/icon_error.png',
  434. title: '没有库存'
  435. });
  436. return false;
  437. }
  438. //验证团购是否有效
  439. let checkedGroupon = this.getCheckedGrouponValue();
  440. //立即购买
  441. util.request(api.CartFastAdd, {
  442. goodsId: this.data.goods.id,
  443. number: this.data.number,
  444. productId: checkedProduct.id
  445. }, "POST")
  446. .then(function(res) {
  447. if (res.errno == 0) {
  448. // 如果storage中设置了cartId,则是立即购买,否则是购物车购买
  449. try {
  450. wx.setStorageSync('cartId', res.data);
  451. wx.setStorageSync('grouponRulesId', checkedGroupon.id);
  452. wx.setStorageSync('grouponLinkId', that.data.grouponLink.id);
  453. wx.navigateTo({
  454. url: '/pages/shopping/checkout/checkout'
  455. })
  456. } catch (e) {}
  457. } else {
  458. wx.showToast({
  459. image: '/static/images/icon_error.png',
  460. title: res.errmsg,
  461. mask: true
  462. });
  463. }
  464. });
  465. }
  466. },
  467. //添加到购物车
  468. addToCart: function() {
  469. var that = this;
  470. if (this.data.openAttr == false) {
  471. //打开规格选择窗口
  472. this.setData({
  473. openAttr: !this.data.openAttr
  474. });
  475. } else {
  476. //提示选择完整规格
  477. if (!this.isCheckedAllSpec()) {
  478. wx.showToast({
  479. image: '/static/images/icon_error.png',
  480. title: '请选择完整规格'
  481. });
  482. return false;
  483. }
  484. //根据选中的规格,判断是否有对应的sku信息
  485. let checkedProductArray = this.getCheckedProductItem(this.getCheckedSpecKey());
  486. if (!checkedProductArray || checkedProductArray.length <= 0) {
  487. //找不到对应的product信息,提示没有库存
  488. wx.showToast({
  489. image: '/static/images/icon_error.png',
  490. title: '没有库存'
  491. });
  492. return false;
  493. }
  494. let checkedProduct = checkedProductArray[0];
  495. //验证库存
  496. if (checkedProduct.number <= 0) {
  497. wx.showToast({
  498. image: '/static/images/icon_error.png',
  499. title: '没有库存'
  500. });
  501. return false;
  502. }
  503. //添加到购物车
  504. util.request(api.CartAdd, {
  505. goodsId: this.data.goods.id,
  506. number: this.data.number,
  507. productId: checkedProduct.id
  508. }, "POST")
  509. .then(function(res) {
  510. let _res = res;
  511. if (_res.errno == 0) {
  512. wx.showToast({
  513. title: '添加成功'
  514. });
  515. that.setData({
  516. openAttr: !that.data.openAttr,
  517. cartGoodsCount: _res.data
  518. });
  519. } else {
  520. wx.showToast({
  521. image: '/static/images/icon_error.png',
  522. title: _res.errmsg,
  523. mask: true
  524. });
  525. }
  526. });
  527. }
  528. },
  529. cutNumber: function() {
  530. this.setData({
  531. number: (this.data.number - 1 > 1) ? this.data.number - 1 : 1
  532. });
  533. },
  534. addNumber: function() {
  535. this.setData({
  536. number: this.data.number + 1
  537. });
  538. },
  539. onHide: function() {
  540. // 页面隐藏
  541. },
  542. onUnload: function() {
  543. // 页面关闭
  544. },
  545. switchAttrPop: function() {
  546. if (this.data.openAttr == false) {
  547. this.setData({
  548. openAttr: !this.data.openAttr
  549. });
  550. }
  551. },
  552. closeAttr: function() {
  553. this.setData({
  554. openAttr: false,
  555. });
  556. },
  557. openCartPage: function() {
  558. wx.switchTab({
  559. url: '/pages/cart/cart'
  560. });
  561. },
  562. onReady: function() {
  563. // 页面渲染完成
  564. this.sharePop = this.selectComponent("#sharePop");
  565. this.notify = this.selectComponent("#van-notify");
  566. }
  567. })