index.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. // nova-tourism/components/template2/shop/index.js
  2. let {
  3. statusBarHeight,
  4. screenHeight,
  5. safeArea: {
  6. bottom
  7. }
  8. } = wx.getSystemInfoSync();
  9. statusBarHeight = Math.abs(statusBarHeight)
  10. let custom = wx.getMenuButtonBoundingClientRect();
  11. let customBarHeight = custom.bottom + custom.top - statusBarHeight;
  12. customBarHeight = Math.abs(customBarHeight)
  13. const Parse = getApp().Parse;
  14. const company = getApp().globalData.company
  15. const compute = require("../../../../utils/compute.js");
  16. Component({
  17. /**
  18. * 组件的属性列表
  19. */
  20. properties: {
  21. },
  22. /**
  23. * 组件的初始数据
  24. */
  25. data: {
  26. latitude: 0,
  27. longitude: 0,
  28. statusBarHeight,
  29. customBarHeight,
  30. screenHeight,
  31. bottom,
  32. goods: [],
  33. shopCart: [],
  34. // activeItem: 'zS9XEd0Im1',
  35. activeItem: 'all',
  36. allCheck: true,
  37. value: '',
  38. imgUrls: [
  39. 'https://s1.ax1x.com/2023/04/10/ppqifvF.png',
  40. 'https://s1.ax1x.com/2023/04/10/ppqiWgU.png',
  41. 'https://s1.ax1x.com/2023/04/10/ppqiR3T.png'
  42. ],
  43. },
  44. lifetimes: {
  45. created() {},
  46. attached() {
  47. this.refresh()
  48. },
  49. },
  50. /**
  51. * 组件的方法列表
  52. */
  53. methods: {
  54. async refresh() {
  55. if (this.data.latitude == 0 && this.data.longitude == 0) {
  56. let {
  57. latitude,
  58. longitude
  59. } = await this.getLocation()
  60. this.setData({
  61. latitude,
  62. longitude
  63. })
  64. }
  65. this.getBanner()
  66. await this.getBindStore()
  67. this.getCategory()
  68. this.getGoods()
  69. },
  70. getLocation() {
  71. return new Promise((resolve, reject) => {
  72. wx.getLocation({
  73. type: 'gcj02',
  74. success: (res) => {
  75. resolve({
  76. latitude: res.latitude,
  77. longitude: res.longitude
  78. })
  79. },
  80. fail: () => {
  81. resolve({
  82. latitude: 0,
  83. longitude: 0
  84. })
  85. },
  86. complete: () => {}
  87. });
  88. })
  89. },
  90. async getBanner() {
  91. let Banner = new Parse.Query('Banner')
  92. Banner.notEqualTo('isDeleted', "true")
  93. Banner.equalTo('company', company)
  94. Banner.equalTo('isEnabled', "true")
  95. Banner.equalTo('type', 'shop')
  96. let banner = await Banner.find()
  97. if (banner && banner.length > 0) {
  98. let listJSON = []
  99. banner.forEach(c => {
  100. listJSON.push(c.toJSON())
  101. })
  102. this.setData({
  103. banner: listJSON
  104. })
  105. }
  106. },
  107. // 获取所有商品分类
  108. getCategory: async function () {
  109. let Category = new Parse.Query('Category')
  110. Category.notEqualTo('isDeleted', "true")
  111. Category.equalTo('company', company)
  112. Category.equalTo('type', 'shop')
  113. Category.descending('createdAt')
  114. let category = await Category.find()
  115. let list = []
  116. category.forEach(val => {
  117. val = val.toJSON()
  118. list.push(val)
  119. })
  120. this.setData({
  121. category: list
  122. })
  123. },
  124. // 获取商品
  125. getGoods: async function (value) {
  126. this.setData({
  127. goods:[]
  128. })
  129. let storeID = wx.getStorageSync('storeID');
  130. let Goods = new Parse.Query('ShopGoods')
  131. Goods.notEqualTo('isDeleted', "true")
  132. Goods.equalTo('company', company)
  133. if (this.data.activeItem !== 'all' && !value) {
  134. Goods.equalTo('category', this.data.activeItem)
  135. }
  136. Goods.equalTo('shopStore', storeID)
  137. Goods.equalTo('status', true)
  138. Goods.equalTo('type', 'shop')
  139. Goods.include('category')
  140. Goods.descending('createdAt')
  141. if (value) {
  142. Goods.contains('name', value)
  143. }
  144. Goods.limit(10)
  145. Goods.skip(this.data.goods.length)
  146. let goods = await Goods.find()
  147. let list = this.data.goods
  148. goods.forEach(val => {
  149. val = val.toJSON()
  150. list.push(val)
  151. })
  152. this.setData({
  153. loading: false,
  154. goods: list
  155. })
  156. },
  157. // 获取当前绑定的店铺
  158. getBindStore: async function () {
  159. let storeID = wx.getStorageSync('storeID');
  160. let Store = new Parse.Query('ShopStore')
  161. if (storeID) {
  162. console.log(storeID);
  163. let store = await Store.get(storeID)
  164. let storeJSON = store.toJSON()
  165. let distance = compute.computeDistance(
  166. this.data.latitude,
  167. this.data.longitude,
  168. storeJSON.location.latitude,
  169. storeJSON.location.longitude
  170. )
  171. storeJSON.distance = distance
  172. this.setData({
  173. store: storeJSON
  174. })
  175. } else {
  176. return wx.showToast({
  177. title: '快去选择一个店铺吧~',
  178. icon: 'none'
  179. })
  180. }
  181. },
  182. // 点击分类添加激活类名,以及显示分类下的商品
  183. changeCate: async function (e) {
  184. this.setData({
  185. loading: true,
  186. goods: []
  187. })
  188. let id = e.currentTarget.dataset.id
  189. this.setData({
  190. activeItem: id,
  191. })
  192. this.getGoods()
  193. },
  194. // 将商品添加至购物车,同时该商品显示的库存减少
  195. addCount(e) {
  196. let store = wx.getStorageSync('storeID');
  197. if (!store) {
  198. return wx.showToast({
  199. title: '请先绑定店铺后购买商品!',
  200. icon: 'none',
  201. duration: 1500,
  202. mask: false,
  203. });
  204. }
  205. let index = e.currentTarget.dataset.index
  206. let goods = this.data.goods[index]
  207. let shopCart = this.data.shopCart
  208. goods.total--
  209. shopCart.push(goods)
  210. let Goods = this.data.goods
  211. Goods[index] = goods
  212. this.setData({
  213. goods: Goods,
  214. shopCart: shopCart
  215. })
  216. this.checkCart('add')
  217. },
  218. // 库存不足
  219. onTips() {
  220. wx.showToast({
  221. title: '商品库存不足',
  222. icon: 'none',
  223. image: '',
  224. duration: 1500,
  225. mask: false,
  226. });
  227. },
  228. // 查看购物车
  229. checkCart(str) {
  230. let store = wx.getStorageSync('storeID');
  231. if (!store) {
  232. return wx.showToast({
  233. title: '请先绑定店铺后购买商品!',
  234. icon: 'none',
  235. duration: 1500,
  236. mask: false,
  237. });
  238. }
  239. if (str != 'add') {
  240. this.setData({
  241. show: true,
  242. })
  243. }
  244. let shopGoods = this.data.shopCart
  245. console.log(shopGoods);
  246. let list = []
  247. let result = shopGoods.reduce((init, current, index) => {
  248. list[current.objectId] ? '' : list[current.objectId] = true && init.push(current)
  249. return init
  250. }, [])
  251. console.log(result);
  252. let obj = {}
  253. for (let i = 0; i < shopGoods.length; i++) {
  254. if (shopGoods[i].objectId in obj) {
  255. obj[shopGoods[i].objectId] = obj[shopGoods[i].objectId] + 1
  256. } else {
  257. obj[shopGoods[i].objectId] = 1
  258. }
  259. }
  260. for (let k in obj) {
  261. let index = result.findIndex(val => {
  262. return val.objectId == k
  263. })
  264. result[index].check = false
  265. result[index].open = true
  266. result[index].count = obj[k]
  267. result[index].totalPrice = (obj[k] * result[index].price).toFixed(2)
  268. }
  269. console.log(result);
  270. this.setData({
  271. orderGoods: result
  272. })
  273. this.checkAll()
  274. },
  275. // 删除当前滑动的订单商品
  276. delete(e) {
  277. console.log("dalskd", e);
  278. wx.showModal({
  279. title: '删除商品',
  280. content: '确认删除该件商品吗',
  281. showCancel: true,
  282. cancelText: '取消',
  283. cancelColor: '#000000',
  284. confirmText: '确定',
  285. confirmColor: '#e42929',
  286. success: async (result) => {
  287. if (result.confirm) {
  288. let index = e.currentTarget.dataset.index
  289. let id = e.currentTarget.dataset.id
  290. let totalPrice = this.data.totalPrice
  291. let orderGoods = this.data.orderGoods
  292. let shopCart = this.data.shopCart
  293. let goods = this.data.goods
  294. shopCart = shopCart.filter(val => {
  295. return val.objectId !== id
  296. })
  297. let goodsIndex = goods.findIndex(val => {
  298. return val.objectId == id
  299. })
  300. goods[goodsIndex].total += orderGoods[index].count
  301. totalPrice = parseFloat(totalPrice) - parseFloat(orderGoods[index].totalPrice)
  302. totalPrice = parseFloat(totalPrice).toFixed(2)
  303. orderGoods.splice(index, 1)
  304. this.setData({
  305. totalPrice: totalPrice,
  306. goods: goods,
  307. shopCart: shopCart,
  308. orderGoods: orderGoods
  309. })
  310. this.checkAll()
  311. }
  312. },
  313. });
  314. },
  315. // 点击全选按钮
  316. checkAll(e) {
  317. // 1. 选中全部商品
  318. // 2. 计算总价
  319. let orderGoods = this.data.orderGoods
  320. if (e) {
  321. this.setData({
  322. allCheck: !this.data.allCheck
  323. })
  324. }
  325. if (this.data.allCheck) {
  326. let totalPrice = 0
  327. orderGoods.forEach(val => {
  328. val.check = true
  329. totalPrice += parseFloat(val.totalPrice)
  330. })
  331. this.setData({
  332. totalPrice: totalPrice,
  333. orderGoods: orderGoods
  334. })
  335. } else if (e && !this.data.allCheck) {
  336. orderGoods.forEach(val => {
  337. val.check = false
  338. })
  339. this.setData({
  340. totalPrice: 0,
  341. orderGoods: orderGoods
  342. })
  343. }
  344. },
  345. // 点击加号按钮触发
  346. plus(e) {
  347. let index = e.currentTarget.dataset.index
  348. let orderGoods = this.data.orderGoods
  349. orderGoods[index].total--
  350. // 复制一条与该商品相同的订单数据
  351. let shopCart = this.data.shopCart
  352. let cartIndex = shopCart.findIndex(val => {
  353. return val.objectId == orderGoods[index].objectId
  354. })
  355. let goods = shopCart[cartIndex]
  356. shopCart.push(goods)
  357. this.setData({
  358. shopCart: shopCart,
  359. orderGoods: orderGoods
  360. })
  361. },
  362. // 点击减号按钮触发
  363. minus(e) {
  364. // 将减少的商品数量加回显示的库存数量
  365. let index = e.currentTarget.dataset.index
  366. let orderGoods = this.data.orderGoods
  367. orderGoods[index].total++
  368. // 移除对应shopCart数组中一条数据
  369. let shopCart = this.data.shopCart
  370. let cartIndex = shopCart.findIndex(val => {
  371. return val.objectId == orderGoods[index].objectId
  372. })
  373. shopCart.splice(cartIndex, 1)
  374. this.setData({
  375. shopCart: shopCart,
  376. orderGoods: orderGoods
  377. })
  378. },
  379. // 点击删除按钮
  380. onDelete() {
  381. wx.showModal({
  382. title: '删除订单',
  383. content: '确认删除这些商品吗',
  384. showCancel: true,
  385. cancelText: '取消',
  386. cancelColor: '#000000',
  387. confirmText: '确定',
  388. confirmColor: '#e42929',
  389. success: (result) => {
  390. if (result.confirm) {
  391. if (this.data.allCheck) {
  392. // 全选之后的删除
  393. this.setData({
  394. totalPrice: 0,
  395. goods: [],
  396. shopCart: [],
  397. orderGoods: []
  398. })
  399. this.getGoods()
  400. } else {
  401. // 选中部分删除
  402. let totalPrice = this.data.totalPrice
  403. let shopCart = this.data.shopCart
  404. let orderGoods = this.data.orderGoods
  405. let goods = this.data.goods
  406. let list = orderGoods.filter(val => {
  407. return val.check == true
  408. })
  409. list.forEach(val => {
  410. shopCart = shopCart.filter(item => {
  411. return item.objectId !== val.objectId
  412. })
  413. let index = goods.findIndex(value => {
  414. return value.objectId == val.objectId
  415. })
  416. goods[index].total += val.count
  417. totalPrice = parseFloat(totalPrice) - parseFloat(val.totalPrice)
  418. totalPrice = parseFloat(totalPrice).toFixed(2)
  419. })
  420. orderGoods = orderGoods.filter(val => {
  421. return val.check !== true
  422. })
  423. this.setData({
  424. totalPrice: totalPrice,
  425. goods: goods,
  426. shopCart: shopCart,
  427. orderGoods: orderGoods
  428. })
  429. }
  430. }
  431. },
  432. });
  433. },
  434. // 根据商品objectId获取库存
  435. getTotal: async function (ID) {
  436. let Goods = new Parse.Query('ShopGoods')
  437. let goods = await Goods.get(ID)
  438. return goods.toJSON().total
  439. },
  440. // 点击结算按钮
  441. submit() {
  442. // 生成一条随机订单编号
  443. let orderNum = "C" +
  444. String(new Date().getFullYear()) +
  445. (new Date().getMonth() + 1) +
  446. new Date().getDate() +
  447. new Date().getHours() +
  448. new Date().getMinutes() +
  449. new Date().getSeconds() +
  450. Math.random().toString().slice(-6); //生成六位随机数
  451. // 创建specMap对象以及tagetObject数组
  452. let specMap = {}
  453. let targetObject = []
  454. let orderGoods = this.data.orderGoods
  455. orderGoods = orderGoods.filter(val => {
  456. return val.check == true
  457. })
  458. if (orderGoods.length == 0) {
  459. return
  460. }
  461. orderGoods.forEach(val => {
  462. specMap[val.objectId] = val.count
  463. let option = {
  464. '__type': 'Pointer',
  465. 'className': 'ShopGoods',
  466. 'objectId': val.objectId
  467. }
  468. targetObject.push(option)
  469. })
  470. // 生成一条Order记录
  471. let Order = Parse.Object.extend('Order')
  472. let order = new Order()
  473. order.set('orderNum', orderNum)
  474. order.set('company', {
  475. '__type': 'Pointer',
  476. 'className': 'Company',
  477. 'objectId': company
  478. })
  479. order.set('store', {
  480. '__type': 'Pointer',
  481. 'className': 'ShopStore',
  482. 'objectId': wx.getStorageSync('storeID')
  483. })
  484. order.set('specMap', specMap)
  485. order.set('totalPrice', this.data.totalPrice)
  486. order.set('user', {
  487. '__type': 'Pointer',
  488. 'className': '_User',
  489. 'objectId': Parse.User.current().id
  490. })
  491. order.set('targetObject', targetObject)
  492. order.set('status', '100')
  493. order.set('type', 'shop')
  494. order.set('isPay', false)
  495. order.save().then((res) => {
  496. let order = res.toJSON()
  497. wx.navigateTo({
  498. url: '/nova-tourism/pages/shop/order/index?id=' + order.objectId,
  499. success: () => {
  500. this.setData({
  501. totalPrice: 0,
  502. goods: [],
  503. shopCart: [],
  504. orderGoods: []
  505. })
  506. this.onClose()
  507. }
  508. });
  509. })
  510. // 跳转至订单支付页面
  511. },
  512. // 关闭购物车
  513. onClose() {
  514. this.setData({
  515. show: false,
  516. })
  517. this.getGoods()
  518. },
  519. // 步进器,单件商品的购买数量增减处理
  520. onChange: async function (e) {
  521. let num = e.detail
  522. let index = e.currentTarget.dataset.index
  523. let orderGoods = this.data.orderGoods
  524. let total = await this.getTotal(orderGoods[index].objectId)
  525. if ((total - num) < 0) {
  526. wx.showToast({
  527. title: '库存不足!',
  528. icon: 'none',
  529. duration: 1500,
  530. });
  531. orderGoods[index].open = false
  532. num--
  533. } else {
  534. orderGoods[index].open = true
  535. }
  536. orderGoods[index].count = num
  537. orderGoods[index].totalPrice = (orderGoods[index].count * orderGoods[index].price).toFixed(2)
  538. this.setData({
  539. orderGoods: orderGoods
  540. })
  541. this.checkAll()
  542. },
  543. // 点击勾选商品
  544. checkItem(e) {
  545. let index = e.currentTarget.dataset.index
  546. let orderGoods = this.data.orderGoods
  547. let totalPrice = this.data.totalPrice
  548. orderGoods[index].check = !orderGoods[index].check
  549. if (orderGoods[index].check) {
  550. totalPrice = parseFloat(totalPrice) + parseFloat(orderGoods[index].totalPrice)
  551. totalPrice = parseFloat(totalPrice).toFixed(2)
  552. } else {
  553. totalPrice = parseFloat(totalPrice) - parseFloat(orderGoods[index].totalPrice)
  554. totalPrice = parseFloat(totalPrice).toFixed(2)
  555. }
  556. let result = orderGoods.filter(val => {
  557. return val.check !== true
  558. })
  559. if (result.length > 0) {
  560. this.setData({
  561. allCheck: false
  562. })
  563. } else {
  564. this.setData({
  565. allCheck: true
  566. })
  567. }
  568. this.setData({
  569. totalPrice: totalPrice,
  570. orderGoods: orderGoods
  571. })
  572. },
  573. // 搜索
  574. search() {
  575. console.log(this.data.value)
  576. if (!this.data.value && this.data.value != '') {
  577. return
  578. }
  579. this.setData({
  580. loading: true,
  581. goods: []
  582. })
  583. this.getGoods(this.data.value)
  584. },
  585. // 当容器滑动至底部时,加载商品数据
  586. // scrolltolower: function () {
  587. // this.getGoods()
  588. // },
  589. // 跳转至选择店铺页面
  590. selectStore(e) {
  591. let store = e.target.dataset.store
  592. wx.navigateTo({
  593. url: '/nova-tourism/pages/shop/select-store/index?store=' + store,
  594. });
  595. },
  596. }
  597. })