cartStore.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. class CartStore {
  2. constructor() {
  3. this.storageKey = 'shopping_cart';
  4. this.currentShopId = ''; // 当前店铺ID
  5. }
  6. // 设置当前店铺ID
  7. setShopId() {
  8. this.currentShopId = uni.getStorageSync('shop_id');
  9. }
  10. // 获取购物车数据
  11. getCart() {
  12. try {
  13. const cartStr = uni.getStorageSync(this.storageKey);
  14. if (!cartStr) {
  15. return {};
  16. }
  17. return JSON.parse(cartStr);
  18. } catch (e) {
  19. console.error('获取购物车失败:', e);
  20. return {};
  21. }
  22. }
  23. // 保存购物车数据
  24. saveCart(cartData) {
  25. try {
  26. uni.setStorageSync(this.storageKey, JSON.stringify(cartData));
  27. } catch (e) {
  28. console.error('保存购物车失败:', e);
  29. }
  30. }
  31. // 获取指定店铺的购物车
  32. getShopCart(shopId = null) {
  33. const cart = this.getCart();
  34. const targetShopId = shopId || this.currentShopId;
  35. if (!targetShopId) return null;
  36. if (!cart[targetShopId]) {
  37. cart[targetShopId] = {
  38. total_price: 0, //所有价格总和
  39. total_num: 0,
  40. goods_list: [],
  41. pack_price: 0, //配送费总额
  42. total_goods_money: 0, //商品价格总额
  43. shop_info: null
  44. };
  45. this.saveCart(cart);
  46. }
  47. return cart[targetShopId];
  48. }
  49. // 添加商品到购物车
  50. addToCart(goods, goodsSpec = [], quantity = 1) {
  51. if (!this.currentShopId) {
  52. console.error('未设置店铺ID');
  53. return false;
  54. }
  55. const cart = this.getCart();
  56. if (!cart[this.currentShopId]) {
  57. cart[this.currentShopId] = {
  58. total_price: 0,
  59. total_num: 0,
  60. goods_list: [],
  61. pack_price: 0, //配送费总额
  62. total_goods_money: 0, //商品价格总额
  63. shop_info: null
  64. };
  65. }
  66. const shopCart = cart[this.currentShopId];
  67. // 生成商品唯一标识(结合商品ID和规格ID)
  68. const specIdStr = goodsSpec.length > 0 ?
  69. goodsSpec.map(spec => `${spec.id}_${spec.number}`).sort().join('_') :
  70. 'no_spec';
  71. const goodsKey = `${goods.goods_id}_${specIdStr}`;
  72. // 计算商品单价
  73. const unitPrice = this.calculatePrice(goods, goodsSpec);
  74. // 获取商品配送费
  75. const packPrice = parseFloat(goods.pack_price || 0);
  76. // 查找是否已存在相同商品
  77. const existingIndex = shopCart.goods_list.findIndex(
  78. item => this.getGoodsKey(item) === goodsKey
  79. );
  80. if (existingIndex > -1) {
  81. // 已存在,更新数量
  82. shopCart.goods_list[existingIndex].goods_number += quantity;
  83. } else {
  84. // 新商品,添加到列表
  85. shopCart.goods_list.push({
  86. goods_id: goods.goods_id,
  87. goods_name: goods.goods_name || '',
  88. goods_image: goods.goods_image || '',
  89. // price: this.calculatePrice(goods, goodsSpec),
  90. price: unitPrice,
  91. pack_price: packPrice, // 单个商品配送费
  92. goods_number: quantity,
  93. // goods_attr: this.getSpecAttr(goodsSpec),
  94. goods_attr: goods.goods_attr,
  95. goods_spec: goodsSpec,
  96. category_id: goods.category_id,
  97. goods_desc: goods.goods_desc || '',
  98. spec_type: goods.spec_type || 1
  99. });
  100. }
  101. // 重新计算总计
  102. this.calculateTotals(shopCart);
  103. // 保存到本地存储
  104. this.saveCart(cart);
  105. return true;
  106. }
  107. // 更新商品数量
  108. updateQuantity(goodsId, goodsSpec = [], quantity) {
  109. if (!this.currentShopId) return false;
  110. const cart = this.getCart();
  111. const shopCart = cart[this.currentShopId];
  112. if (!shopCart) return false;
  113. const specIdStr = goodsSpec.length > 0 ?
  114. goodsSpec.map(spec => `${spec.id}_${spec.number}`).sort().join('_') :
  115. 'no_spec';
  116. const goodsKey = `${goodsId}_${specIdStr}`;
  117. const goodsIndex = shopCart.goods_list.findIndex(
  118. item => this.getGoodsKey(item) === goodsKey
  119. );
  120. if (goodsIndex > -1) {
  121. if (quantity <= 0) {
  122. // 数量为0,移除商品
  123. shopCart.goods_list.splice(goodsIndex, 1);
  124. } else {
  125. // 更新数量
  126. shopCart.goods_list[goodsIndex].goods_number = quantity;
  127. }
  128. // 重新计算总计
  129. this.calculateTotals(shopCart);
  130. this.saveCart(cart);
  131. return true;
  132. }
  133. return false;
  134. }
  135. // 从购物车移除商品
  136. removeFromCart(goodsId, goodsSpec = []) {
  137. return this.updateQuantity(goodsId, goodsSpec, 0);
  138. }
  139. // 再来一单 - 从订单数据重建购物车
  140. reorderFromOrderData(shopId, orderData) {
  141. if (!shopId) {
  142. console.error('店铺ID为空');
  143. return false;
  144. }
  145. // 处理订单数据
  146. const processedData = this.processOrderData(orderData);
  147. if (!processedData) {
  148. return false;
  149. }
  150. // 设置当前店铺
  151. this.currentShopId = shopId;
  152. const cart = this.getCart();
  153. // 直接替换购物车数据
  154. cart[shopId] = processedData;
  155. console.log('处理后的购物车数据:', cart[shopId]);
  156. // 保存到本地存储
  157. this.saveCart(cart);
  158. // 触发购物车更新事件
  159. if (typeof uni.$emit === 'function') {
  160. uni.$emit('cartUpdated', {
  161. shop_id: shopId
  162. });
  163. }
  164. return true;
  165. }
  166. // 处理订单数据格式转换
  167. processOrderData(orderData) {
  168. if (!orderData) return null;
  169. // 构建标准购物车数据结构
  170. const processedData = {
  171. total_price: parseFloat(orderData.total_price) || 0,
  172. total_num: parseInt(orderData.total_num) || 0,
  173. goods_list: [],
  174. pack_price: parseFloat(orderData.pack_price) || 0,
  175. total_goods_money: parseFloat(orderData.total_goods_money) || 0,
  176. shop_info: orderData.shop_info || null
  177. };
  178. // 处理商品列表
  179. if (orderData.goods_list && Array.isArray(orderData.goods_list)) {
  180. processedData.goods_list = orderData.goods_list.map(item => {
  181. // 处理规格属性
  182. let goods_attr = '';
  183. let goods_spec = [];
  184. if (item.goods_attr) {
  185. goods_attr = item.goods_attr;
  186. }
  187. if (item.goods_spec && Array.isArray(item.goods_spec)) {
  188. goods_spec = item.goods_spec.map(spec => ({
  189. id: spec.id || spec.spec_id || 0,
  190. number: spec.number || 1,
  191. name: spec.name || spec.spec_name || '',
  192. price: spec.price || 0
  193. }));
  194. // 如果没有goods_attr,从规格生成
  195. if (!goods_attr && goods_spec.length > 0) {
  196. goods_attr = goods_spec.map(spec =>
  197. spec.number > 1 ? `${spec.name}×${spec.number}` : spec.name
  198. ).join('、');
  199. }
  200. }
  201. return {
  202. goods_id: item.goods_id,
  203. goods_name: item.goods_name || '',
  204. goods_image: item.goods_image || '',
  205. price: parseFloat(item.price) || 0,
  206. pack_price: parseFloat(item.pack_price) || 0,
  207. goods_number: parseInt(item.goods_number) || 1,
  208. goods_attr: goods_attr,
  209. goods_spec: goods_spec,
  210. category_id: item.category_id || 0,
  211. goods_desc: item.goods_desc || '',
  212. spec_type: item.spec_type || 1
  213. };
  214. });
  215. }
  216. return processedData;
  217. }
  218. // 清空当前店铺购物车
  219. clearCurrentShopCart() {
  220. if (!this.currentShopId) return false;
  221. const cart = this.getCart();
  222. cart[this.currentShopId] = {
  223. total_price: 0,
  224. total_num: 0,
  225. goods_list: [],
  226. pack_price: 0,
  227. total_goods_money: 0,
  228. shop_info: null
  229. };
  230. this.saveCart(cart);
  231. return true;
  232. }
  233. // 计算商品价格
  234. calculatePrice(goods, goodsSpec = []) {
  235. let price = goods.seckill_money > 0 ? Number(goods.seckill_money) : Number(goods.price);
  236. // 如果有规格,累加规格价格
  237. if (goodsSpec.length > 0) {
  238. goodsSpec.forEach(spec => {
  239. // 这里需要根据实际情况获取规格价格
  240. // 假设规格信息中包含价格
  241. if (spec.price) {
  242. price += Number(spec.price) * (spec.number || 1);
  243. }
  244. });
  245. }
  246. return Number(price).toFixed(2);
  247. }
  248. // 获取规格描述
  249. getSpecAttr(goodsSpec = []) {
  250. if (goodsSpec.length === 0) return '';
  251. return goodsSpec.map(spec => spec.number > 1 ? `${spec.name}x${spec.number}` : spec.name).join('、');
  252. }
  253. // 生成商品唯一键
  254. getGoodsKey(goodsItem) {
  255. const specIdStr = goodsItem.goods_spec && goodsItem.goods_spec.length > 0 ?
  256. goodsItem.goods_spec.map(spec => `${spec.id}_${spec.number}`).sort().join('_') :
  257. 'no_spec';
  258. return `${goodsItem.goods_id}_${specIdStr}`;
  259. }
  260. // 计算购物车总计
  261. calculateTotals(shopCart) {
  262. // let total_price = 0;
  263. let total_goods_money = 0; // 商品总额(不含配送费)
  264. let total_pack_price = 0; // 配送费总额
  265. let total_num = 0;
  266. // 计算商品总额和总数量
  267. shopCart.goods_list.forEach(item => {
  268. const itemGoodsMoney = item.price * item.goods_number; // 商品金额
  269. const itemPackPrice = parseFloat(item.pack_price || 0) * item.goods_number; // 配送费金额
  270. const itemTotal = item.price * item.goods_number;
  271. // total_goods_money += itemTotal;
  272. // total_num += item.goods_number;
  273. total_goods_money += itemGoodsMoney;
  274. total_pack_price += itemPackPrice;
  275. total_num += item.goods_number;
  276. });
  277. // 更新商品总额
  278. shopCart.total_goods_money = parseFloat(total_goods_money.toFixed(2));
  279. // 更新配送费总额
  280. shopCart.pack_price = parseFloat(total_pack_price.toFixed(2));
  281. // 更新商品总数量
  282. shopCart.total_num = total_num;
  283. // 计算总价:商品总额 + 配送费
  284. const total_price = shopCart.total_goods_money + (shopCart.pack_price || 0);
  285. shopCart.total_price = parseFloat(total_price.toFixed(2));
  286. // shopCart.goods_list.forEach(item => {
  287. // total_price += item.price * item.goods_number;
  288. // total_num += item.goods_number;
  289. // });
  290. // shopCart.total_price = parseFloat(total_price.toFixed(2));
  291. // shopCart.total_num = total_num;
  292. }
  293. // 获取商品在购物车中的数量
  294. getGoodsQuantity(goodsId, goodsSpec = []) {
  295. if (!this.currentShopId) return 0;
  296. const cart = this.getCart();
  297. const shopCart = cart[this.currentShopId];
  298. if (!shopCart) return 0;
  299. const specIdStr = goodsSpec.length > 0 ?
  300. goodsSpec.map(spec => `${spec.id}_${spec.number}`).sort().join('_') :
  301. 'no_spec';
  302. const goodsKey = `${goodsId}_${specIdStr}`;
  303. const goodsItem = shopCart.goods_list.find(
  304. item => this.getGoodsKey(item) === goodsKey
  305. );
  306. return goodsItem ? goodsItem.goods_number : 0;
  307. }
  308. // 获取指定店铺购物车中某商品的总数量(所有规格合并)
  309. getGoodsTotalQuantity(goodsId) {
  310. if (!this.currentShopId) return 0;
  311. const cart = this.getCart();
  312. const shopCart = cart[this.currentShopId];
  313. if (!shopCart) return 0;
  314. let total = 0;
  315. shopCart.goods_list.forEach(item => {
  316. if (item.goods_id === goodsId) {
  317. total += item.goods_number;
  318. }
  319. });
  320. return total;
  321. }
  322. // 获取购物车统计数据
  323. getCartStats(shopId = null) {
  324. const shopCart = this.getShopCart(shopId);
  325. if (!shopCart) {
  326. return {
  327. total_price: 0,
  328. total_num: 0,
  329. goods_list: [],
  330. pack_price: 0,
  331. total_goods_money: 0
  332. };
  333. }
  334. return {
  335. total_price: shopCart.total_price || 0,
  336. total_num: shopCart.total_num || 0,
  337. goods_list: shopCart.goods_list || [],
  338. pack_price: shopCart.pack_price || 0,
  339. total_goods_money: shopCart.total_goods_money || 0
  340. };
  341. }
  342. // 获取商品总额(不含配送费)
  343. getGoodsTotalMoney(shopId = null) {
  344. const shopCart = this.getShopCart(shopId);
  345. return shopCart ? (shopCart.total_goods_money || 0) : 0;
  346. }
  347. // 获取配送费
  348. getPackPrice(shopId = null) {
  349. const shopCart = this.getShopCart(shopId);
  350. return shopCart ? (shopCart.pack_price || 0) : 0;
  351. }
  352. // 获取总价(商品总额+配送费)
  353. getTotalPrice(shopId = null) {
  354. const shopCart = this.getShopCart(shopId);
  355. return shopCart ? (shopCart.total_price || 0) : 0;
  356. }
  357. // 获取单个商品在购物车中的信息
  358. getGoodsInfo(goodsId, goodsSpec = []) {
  359. if (!this.currentShopId) return null;
  360. const cart = this.getCart();
  361. const shopCart = cart[this.currentShopId];
  362. if (!shopCart) return null;
  363. const specIdStr = goodsSpec.length > 0 ?
  364. goodsSpec.map(spec => `${spec.id}_${spec.number}`).sort().join('_') :
  365. 'no_spec';
  366. const goodsKey = `${goodsId}_${specIdStr}`;
  367. return shopCart.goods_list.find(
  368. item => this.getGoodsKey(item) === goodsKey
  369. );
  370. }
  371. }
  372. // 创建单例
  373. const cartStore = new CartStore();
  374. export default cartStore;