goods.js 16 KB

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