cart.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. const Base = require('./base.js');
  2. module.exports = class extends Base {
  3. /**
  4. * 获取购物车中的数据
  5. * @returns {Promise.<{cartList: *, cartTotal: {goodsCount: number, goodsAmount: number, checkedGoodsCount: number, checkedGoodsAmount: number}}>}
  6. */
  7. async getCart() {
  8. const cartList = await this.model('cart').where({user_id: this.getLoginUserId(), session_id: 1}).select();
  9. // 获取购物车统计信息
  10. let goodsCount = 0;
  11. let goodsAmount = 0.00;
  12. let checkedGoodsCount = 0;
  13. let checkedGoodsAmount = 0.00;
  14. for (const cartItem of cartList) {
  15. goodsCount += cartItem.number;
  16. goodsAmount += cartItem.number * cartItem.retail_price;
  17. if (!think.isEmpty(cartItem.checked)) {
  18. checkedGoodsCount += cartItem.number;
  19. checkedGoodsAmount += cartItem.number * cartItem.retail_price;
  20. }
  21. // 查找商品的图片
  22. cartItem.list_pic_url = await this.model('goods').where({id: cartItem.goods_id}).getField('list_pic_url', true);
  23. }
  24. return {
  25. cartList: cartList,
  26. cartTotal: {
  27. goodsCount: goodsCount,
  28. goodsAmount: goodsAmount,
  29. checkedGoodsCount: checkedGoodsCount,
  30. checkedGoodsAmount: checkedGoodsAmount
  31. }
  32. };
  33. }
  34. /**
  35. * 获取购物车信息,所有对购物车的增删改操作,都要重新返回购物车的信息
  36. * @return {Promise} []
  37. */
  38. async indexAction() {
  39. return this.success(await this.getCart());
  40. }
  41. /**
  42. * 添加商品到购物车
  43. * @returns {Promise.<*>}
  44. */
  45. async addAction() {
  46. const goodsId = this.post('goodsId');
  47. const productId = this.post('productId');
  48. const number = this.post('number');
  49. // 判断商品是否可以购买
  50. const goodsInfo = await this.model('goods').where({id: goodsId}).find();
  51. if (think.isEmpty(goodsInfo) || goodsInfo.is_delete === 1) {
  52. return this.fail(400, '商品已下架');
  53. }
  54. // 取得规格的信息,判断规格库存
  55. const productInfo = await this.model('product').where({goods_id: goodsId, id: productId}).find();
  56. if (think.isEmpty(productInfo) || productInfo.goods_number < number) {
  57. return this.fail(400, '库存不足');
  58. }
  59. // 判断购物车中是否存在此规格商品
  60. const cartInfo = await this.model('cart').where({goods_id: goodsId, product_id: productId}).find();
  61. if (think.isEmpty(cartInfo)) {
  62. // 添加操作
  63. // 添加规格名和值
  64. let goodsSepcifitionValue = [];
  65. if (!think.isEmpty(productInfo.goods_specification_ids)) {
  66. goodsSepcifitionValue = await this.model('goods_specification').where({
  67. goods_id: goodsId,
  68. id: {'in': productInfo.goods_specification_ids.split('_')}
  69. }).getField('value');
  70. }
  71. // 添加到购物车
  72. const cartData = {
  73. goods_id: goodsId,
  74. product_id: productId,
  75. goods_sn: productInfo.goods_sn,
  76. goods_name: goodsInfo.name,
  77. list_pic_url: goodsInfo.list_pic_url,
  78. number: number,
  79. session_id: 1,
  80. user_id: this.getLoginUserId(),
  81. retail_price: productInfo.retail_price,
  82. market_price: productInfo.retail_price,
  83. goods_specifition_name_value: goodsSepcifitionValue.join(';'),
  84. goods_specifition_ids: productInfo.goods_specification_ids,
  85. checked: 1
  86. };
  87. await this.model('cart').thenAdd(cartData, {product_id: productId});
  88. } else {
  89. // 如果已经存在购物车中,则数量增加
  90. if (productInfo.goods_number < (number + cartInfo.number)) {
  91. return this.fail(400, '库存不足');
  92. }
  93. await this.model('cart').where({
  94. goods_id: goodsId,
  95. product_id: productId,
  96. id: cartInfo.id
  97. }).increment('number', number);
  98. }
  99. return this.success(await this.getCart());
  100. }
  101. // 更新指定的购物车信息
  102. async updateAction() {
  103. const goodsId = this.post('goodsId');
  104. const productId = this.post('productId'); // 新的product_id
  105. const id = this.post('id'); // cart.id
  106. const number = parseInt(this.post('number')); // 不是
  107. // 取得规格的信息,判断规格库存
  108. const productInfo = await this.model('product').where({goods_id: goodsId, id: productId}).find();
  109. if (think.isEmpty(productInfo) || productInfo.goods_number < number) {
  110. return this.fail(400, '库存不足');
  111. }
  112. // 判断是否已经存在product_id购物车商品
  113. const cartInfo = await this.model('cart').where({id: id}).find();
  114. // 只是更新number
  115. if (cartInfo.product_id === productId) {
  116. await this.model('cart').where({id: id}).update({
  117. number: number
  118. });
  119. return this.success(await this.getCart());
  120. }
  121. const newCartInfo = await this.model('cart').where({goods_id: goodsId, product_id: productId}).find();
  122. if (think.isEmpty(newCartInfo)) {
  123. // 直接更新原来的cartInfo
  124. // 添加规格名和值
  125. let goodsSepcifition = [];
  126. if (!think.isEmpty(productInfo.goods_specification_ids)) {
  127. goodsSepcifition = await this.model('goods_specification').field(['nideshop_goods_specification.*', 'nideshop_specification.name']).join('nideshop_specification ON nideshop_specification.id=nideshop_goods_specification.specification_id').where({
  128. 'nideshop_goods_specification.goods_id': goodsId,
  129. 'nideshop_goods_specification.id': {'in': productInfo.goods_specification_ids.split('_')}
  130. }).select();
  131. }
  132. const cartData = {
  133. number: number,
  134. goods_specifition_name_value: JSON.stringify(goodsSepcifition),
  135. goods_specifition_ids: productInfo.goods_specification_ids,
  136. retail_price: productInfo.retail_price,
  137. market_price: productInfo.retail_price,
  138. product_id: productId,
  139. goods_sn: productInfo.goods_sn
  140. };
  141. await this.model('cart').where({id: id}).update(cartData);
  142. } else {
  143. // 合并购物车已有的product信息,删除已有的数据
  144. const newNumber = number + newCartInfo.number;
  145. if (think.isEmpty(productInfo) || productInfo.goods_number < newNumber) {
  146. return this.fail(400, '库存不足');
  147. }
  148. await this.model('cart').where({id: newCartInfo.id}).delete();
  149. const cartData = {
  150. number: newNumber,
  151. goods_specifition_name_value: newCartInfo.goods_specifition_name_value,
  152. goods_specifition_ids: newCartInfo.goods_specification_ids,
  153. retail_price: productInfo.retail_price,
  154. market_price: productInfo.retail_price,
  155. product_id: productId,
  156. goods_sn: productInfo.goods_sn
  157. };
  158. await this.model('cart').where({id: id}).update(cartData);
  159. }
  160. return this.success(await this.getCart());
  161. }
  162. // 是否选择商品,如果已经选择,则取消选择,批量操作
  163. async checkedAction() {
  164. let productId = this.post('productIds').toString();
  165. const isChecked = this.post('isChecked');
  166. if (think.isEmpty(productId)) {
  167. return this.fail('删除出错');
  168. }
  169. productId = productId.split(',');
  170. await this.model('cart').where({product_id: {'in': productId}}).update({checked: parseInt(isChecked)});
  171. return this.success(await this.getCart());
  172. }
  173. // 删除选中的购物车商品,批量删除
  174. async deleteAction() {
  175. let productId = this.post('productIds');
  176. if (!think.isString(productId)) {
  177. return this.fail('删除出错');
  178. }
  179. productId = productId.split(',');
  180. await this.model('cart').where({product_id: {'in': productId}}).delete();
  181. return this.success(await this.getCart());
  182. }
  183. // 获取购物车商品的总件件数
  184. async goodscountAction() {
  185. const cartData = await this.getCart();
  186. return this.success({
  187. cartTotal: {
  188. goodsCount: cartData.cartTotal.goodsCount
  189. }
  190. });
  191. }
  192. /**
  193. * 订单提交前的检验和填写相关订单信息
  194. * @returns {Promise.<void>}
  195. */
  196. async checkoutAction() {
  197. const addressId = this.get('addressId'); // 收货地址id
  198. // const couponId = this.get('couponId'); // 使用的优惠券id
  199. // 选择的收货地址
  200. let checkedAddress = null;
  201. if (addressId) {
  202. checkedAddress = await this.model('address').where({is_default: 1, user_id: this.getLoginUserId()}).find();
  203. } else {
  204. checkedAddress = await this.model('address').where({id: addressId, user_id: this.getLoginUserId()}).find();
  205. }
  206. if (!think.isEmpty(checkedAddress)) {
  207. checkedAddress.province_name = await this.model('region').getRegionName(checkedAddress.province_id);
  208. checkedAddress.city_name = await this.model('region').getRegionName(checkedAddress.city_id);
  209. checkedAddress.district_name = await this.model('region').getRegionName(checkedAddress.district_id);
  210. checkedAddress.full_region = checkedAddress.province_name + checkedAddress.city_name + checkedAddress.district_name;
  211. }
  212. // 根据收货地址计算运费
  213. const freightPrice = 0.00;
  214. // 获取要购买的商品
  215. const cartData = await this.getCart();
  216. const checkedGoodsList = cartData.cartList.filter(function(v) {
  217. return v.checked === 1;
  218. });
  219. // 获取可用的优惠券信息,功能还示实现
  220. const couponList = await this.model('user_coupon').select();
  221. const couponPrice = 0.00; // 使用优惠券减免的金额
  222. // 计算订单的费用
  223. const goodsTotalPrice = cartData.cartTotal.checkedGoodsAmount; // 商品总价
  224. const orderTotalPrice = cartData.cartTotal.checkedGoodsAmount + freightPrice - couponPrice; // 订单的总价
  225. const actualPrice = orderTotalPrice - 0.00; // 减去其它支付的金额后,要实际支付的金额
  226. return this.success({
  227. checkedAddress: checkedAddress,
  228. freightPrice: freightPrice,
  229. checkedCoupon: {},
  230. couponList: couponList,
  231. couponPrice: couponPrice,
  232. checkedGoodsList: checkedGoodsList,
  233. goodsTotalPrice: goodsTotalPrice,
  234. orderTotalPrice: orderTotalPrice,
  235. actualPrice: actualPrice
  236. });
  237. }
  238. };