index.ts 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. //@ts-ignore
  2. import Toast from 'tdesign-miniprogram/toast/index'
  3. import GoodApi from '../../services/good'
  4. import checkauth from '../../utils/checkauth'
  5. import Navi from '../../utils/navi'
  6. import { backPage } from '../../utils/util'
  7. // pages/cart/index.ts
  8. Page({
  9. /**
  10. * 页面的初始数据
  11. */
  12. data: {
  13. // 猜你喜欢
  14. // 猜你喜欢
  15. favList: [] as WxGetCateAlbumOutput[],
  16. favTotal: 0,
  17. loadMoreStatus: 0,
  18. albumInput: {
  19. skipCount: 0,
  20. maxResultCount: 10,
  21. },
  22. cartData: {} as any,
  23. cartGoods: [] as any,
  24. wait: false,
  25. selgi: -1,
  26. isStock: false,
  27. isSpuSelectPopupShow: false,
  28. outEditStatus: true,
  29. details: {} as any,
  30. specImg: '',
  31. primaryImage: '',
  32. skuArray: [] as any[],
  33. unit: '',
  34. limitMaxCount: 999,
  35. limitMinCount: 1,
  36. limitBuyInfo: '',
  37. minSalePrice: 0,
  38. minLinePrice: 0,
  39. closed: true,
  40. _promotionGoods: [],
  41. _invalidGoods: [],
  42. selectItem: null as any,
  43. selectSkuSellPrice: 0,
  44. selectSkuLinePrice: 0,
  45. container: null as any,
  46. isChooseAddr: false,
  47. addr: {
  48. id: -1,
  49. name: '',
  50. },
  51. },
  52. behaviors: [checkauth],
  53. userAddr(addr: any) {
  54. this.setData({
  55. isChooseAddr: true,
  56. addr: {
  57. id: addr.id,
  58. name: addr.detailAddress,
  59. },
  60. })
  61. },
  62. load() {
  63. const apis = [GoodApi.GetCart()]
  64. if (!this.data.isChooseAddr) {
  65. apis.push(GoodApi.GetAddr())
  66. }
  67. Promise.all(apis)
  68. .then((rsps) => {
  69. if (rsps[0].result) {
  70. const cartData = rsps[0].result as any
  71. console.log(cartData)
  72. if (cartData && cartData.goods && cartData.goods.length > 0) {
  73. cartData.goods.forEach((o: any) => {
  74. o.skuTitle = o.specs.map((x: any) => x.title).join(' ')
  75. })
  76. } else {
  77. cartData.goods = []
  78. }
  79. const { goods, ...rest } = cartData
  80. this.setData(
  81. {
  82. cartData: rest,
  83. cartGoods: goods,
  84. },
  85. () => {
  86. console.log(this.data.cartGoods)
  87. },
  88. )
  89. }
  90. if (rsps[2] && rsps[2].result) {
  91. const addr = rsps[2].result
  92. this.setData({
  93. addr: {
  94. id: addr.id,
  95. name: addr.detailAddress,
  96. },
  97. })
  98. }
  99. })
  100. .finally(() => {
  101. this.setData({
  102. wait: false,
  103. authing: false,
  104. })
  105. })
  106. this.loadRecommend()
  107. },
  108. loadRecommend(rest = false) {
  109. console.log('next')
  110. this.setData({
  111. loadMoreStatus: 1,
  112. })
  113. GoodApi.GetHomeRecommend(this.data.albumInput as any).then((rsp) => {
  114. if (rsp.result) {
  115. const result = rsp.result as any
  116. const { items = [] } = result
  117. const nowItems = rest ? items : this.data.favList.concat(items)
  118. this.setData({
  119. favList: nowItems as any,
  120. favTotal: result.totalCount || 0,
  121. loadMoreStatus: nowItems.length === result.totalCount ? 2 : 0,
  122. })
  123. }
  124. })
  125. },
  126. handleReachBottom() {
  127. if (this.data.loadMoreStatus === 0 && this.data.favList.length < this.data.favTotal) {
  128. this.setData(
  129. {
  130. albumInput: {
  131. ...this.data.albumInput,
  132. skipCount: this.data.albumInput.skipCount + 10,
  133. },
  134. },
  135. () => {
  136. this.loadRecommend()
  137. },
  138. )
  139. }
  140. },
  141. /**
  142. * 生命周期函数--监听页面加载
  143. */
  144. onLoad() {},
  145. /**
  146. * 生命周期函数--监听页面初次渲染完成
  147. */
  148. onReady() {
  149. this.setData({
  150. container: () => this.createSelectorQuery().select('.cartwrap'),
  151. })
  152. },
  153. /**
  154. * 生命周期函数--监听页面显示
  155. */
  156. onShow() {
  157. const self = this
  158. this.getTabBar().init(() => {
  159. self.setData({
  160. authing: true,
  161. })
  162. })
  163. },
  164. /**
  165. * 生命周期函数--监听页面隐藏
  166. */
  167. onHide() {
  168. this.setData({
  169. authing: false,
  170. })
  171. },
  172. /**
  173. * 生命周期函数--监听页面卸载
  174. */
  175. onUnload() {},
  176. handleAuthDisagree() {
  177. backPage()
  178. },
  179. handleAuthOK() {
  180. this.load()
  181. },
  182. /**
  183. * 页面相关事件处理函数--监听用户下拉动作
  184. */
  185. onPullDownRefresh() {
  186. wx.stopPullDownRefresh()
  187. if (this.data.wait) return
  188. this.setData(
  189. {
  190. wait: true,
  191. },
  192. () => {
  193. setTimeout(() => {
  194. this.load()
  195. }, 100)
  196. },
  197. )
  198. },
  199. /**
  200. * 页面上拉触底事件的处理函数
  201. */
  202. onReachBottom() {},
  203. /**
  204. * 用户点击右上角分享
  205. */
  206. // onShareAppMessage() {
  207. // let pages = getCurrentPages(); //获取所有页面栈实例列表
  208. // let nowPage = pages[pages.length - 1]; //当前页页面实例
  209. // return {
  210. // title: share.title,
  211. // path: `/${nowPage.route}`,
  212. // imageUrl: share.imageUrl,
  213. // success(res) {
  214. // console.log('success(res)==', res);
  215. // },
  216. // fail(res) {
  217. // console.log('fail(res)==', res);
  218. // }
  219. // }
  220. // },
  221. reload() {
  222. this.setData({
  223. wait: true,
  224. })
  225. this.load()
  226. },
  227. gotoAddr() {
  228. const { id } = this.data.addr
  229. // wx.showModal({
  230. // content: JSON.stringify(this.data.addr),
  231. // success(res) {
  232. // if (res.confirm) {
  233. Navi.navigateTo({
  234. url: '/pages/mine/myaddr/list/index?mode=choose&id=' + id,
  235. })
  236. // }
  237. // },
  238. // })
  239. },
  240. gotoGoodsDetail(e: WechatMiniprogram.CustomEvent<{ goods: WxCateAlbumItemDto; index: number }>) {
  241. const { goods } = e.detail
  242. Navi.navigateTo({
  243. url: '/pages/goods/detail/index?id=' + goods.id + '&cateid=' + goods.cateId,
  244. })
  245. },
  246. gotoLogin() {
  247. Navi.navigateTo({
  248. url: '/pages/login/index',
  249. })
  250. },
  251. gotoList() {
  252. Navi.switchTab({
  253. url: '/pages/goods/category/index',
  254. })
  255. },
  256. onToSettle() {
  257. if (this.data.addr.id > 0) {
  258. Navi.navigateTo({
  259. url: '/pages/mine/myorder/confirm/index?addrId=' + this.data.addr.id,
  260. })
  261. } else {
  262. Toast({
  263. context: this,
  264. selector: '#t-toast',
  265. message: '请选择配送地址',
  266. icon: '',
  267. duration: 1000,
  268. })
  269. }
  270. },
  271. gotoFavGoods(
  272. e: WechatMiniprogram.BaseEvent<
  273. {},
  274. {
  275. goods: any
  276. }
  277. >,
  278. ) {
  279. const { goods } = e.currentTarget.dataset
  280. Navi.navigateTo({
  281. url: '/pages/goods/detail/index?id=' + goods.id + '&cateid=' + goods.cateId,
  282. })
  283. },
  284. gotoGoods(
  285. e: WechatMiniprogram.BaseEvent<
  286. {},
  287. {
  288. goods: any
  289. }
  290. >,
  291. ) {
  292. const { goods } = e.currentTarget.dataset
  293. Navi.navigateTo({
  294. url: '/pages/goods/detail/index?id=' + goods.goodId + '&cateid=' + goods.cateId,
  295. })
  296. },
  297. handlePopupHide() {
  298. this.setData({
  299. isSpuSelectPopupShow: false,
  300. selgi: -1,
  301. })
  302. },
  303. specsConfirm(e: WechatMiniprogram.CustomEvent<{ buy: number }>) {
  304. const { selectItem, cartGoods, selgi: gi } = this.data
  305. const goods = cartGoods[gi]
  306. const bag: WxAddCartInput = {
  307. id: goods.id,
  308. cateId: goods.cateId,
  309. goodId: goods.goodId,
  310. skuId: selectItem.skuId,
  311. info: selectItem.specInfo.map((o: any) => o.specValueId),
  312. } as any
  313. this.setData({
  314. wait: true,
  315. })
  316. GoodApi.AddCart(bag)
  317. .then((rsp) => {
  318. if (rsp.result === 'ok') {
  319. goods.skuTitle = selectItem.specInfo.map((o: any) => o.specValue).join(' ')
  320. goods.specs = selectItem.specInfo.map((o: any) => ({
  321. id: o.specValueId,
  322. title: o.specValue,
  323. }))
  324. goods.skuId = selectItem.skuId
  325. goods.price = selectItem.price
  326. goods.skuImage = selectItem.image
  327. } else if (Number(rsp.result) > 0) {
  328. const beforeNum = goods.buyNum
  329. const combineId = Number(rsp.result)
  330. cartGoods.splice(gi, 1)
  331. for (var g of cartGoods) {
  332. if (g.id === combineId) {
  333. g.buyNum += beforeNum
  334. break
  335. }
  336. }
  337. }
  338. this.setData({
  339. cartGoods: cartGoods,
  340. isSpuSelectPopupShow: false,
  341. wait: false,
  342. selgi: -1,
  343. })
  344. })
  345. .catch(() => {
  346. this.setData({
  347. wait: false,
  348. selgi: -1,
  349. })
  350. })
  351. },
  352. selectGoods(
  353. e: WechatMiniprogram.BaseEvent<
  354. {},
  355. {
  356. promoindex: number
  357. gi: number
  358. }
  359. >,
  360. ) {
  361. const { gi } = e.currentTarget.dataset
  362. const data = this.data.cartGoods as any[]
  363. const state = !data[gi].isSelected
  364. // data[gi].isSelected = !data[gi].isSelected
  365. this.setData({
  366. cartGoods: data,
  367. wait: true,
  368. })
  369. GoodApi.SelectCartItem({
  370. id: data[gi].id,
  371. state,
  372. })
  373. .then((rsp) => {
  374. if (rsp.result === 'ok') {
  375. data[gi].isSelected = !data[gi].isSelected
  376. this.calc(data)
  377. }
  378. })
  379. .catch(() => {
  380. this.setData({
  381. wait: false,
  382. })
  383. })
  384. },
  385. onSelectAll() {
  386. const unselected = this.data.cartData.isAllSelected
  387. const api = unselected ? GoodApi.UnSelectAllCartItem : GoodApi.SelectAllCartItem
  388. this.setData({
  389. wait: true,
  390. })
  391. api()
  392. .then((rsp) => {
  393. if (rsp.result === 'ok') {
  394. const data = this.data.cartGoods as any[]
  395. data.forEach((o) => {
  396. o.isSelected = !unselected
  397. })
  398. this.calc(data)
  399. }
  400. })
  401. .catch(() => {
  402. this.setData({
  403. wait: false,
  404. })
  405. })
  406. },
  407. onChangeStepper(
  408. e: WechatMiniprogram.CustomEvent<{ value: number }, {}, { gi: number; goods: any }>,
  409. ) {
  410. const { gi, goods } = e.currentTarget.dataset
  411. const val = e.detail.value
  412. const data = this.data.cartGoods as any[]
  413. if (data[gi].buyNum == val) {
  414. return
  415. }
  416. this.setData({
  417. wait: true,
  418. })
  419. GoodApi.NumCartItem({
  420. id: goods.id,
  421. buyNum: Number(val),
  422. })
  423. .then((rsp) => {
  424. if (rsp.result === 'ok') {
  425. data[gi].buyNum = val
  426. this.calc(data)
  427. }
  428. })
  429. .catch(() => {
  430. this.setData({
  431. wait: false,
  432. })
  433. })
  434. },
  435. onDeleteGoods(e: WechatMiniprogram.CustomEvent<{}, {}, { gi: number; goods: any }>) {
  436. const { gi, goods } = e.currentTarget.dataset
  437. const data = this.data.cartGoods as any[]
  438. this.setData({
  439. wait: true,
  440. })
  441. GoodApi.RemoveCartItem({
  442. id: goods.id,
  443. })
  444. .then((rsp) => {
  445. if (rsp.result === 'ok') {
  446. data.splice(gi, 1)
  447. this.calc(data)
  448. }
  449. })
  450. .catch(() => {
  451. this.setData({
  452. wait: false,
  453. })
  454. })
  455. },
  456. chooseSpecItem(
  457. e: WechatMiniprogram.CustomEvent<{
  458. selectedSku: Record<string, string>
  459. isAllSelectedSku: boolean
  460. }>,
  461. ) {
  462. const { specList } = this.data.details
  463. const { selectedSku, isAllSelectedSku } = e.detail
  464. console.log(specList, isAllSelectedSku, selectedSku)
  465. if (!isAllSelectedSku) {
  466. this.setData({
  467. selectSkuSellPrice: 0,
  468. })
  469. }
  470. this.setData({
  471. isAllSelectedSku,
  472. })
  473. this.getSkuItem(specList, selectedSku)
  474. },
  475. getSkuItem(specList: TmpSpec[] | undefined, selectedSku: Record<string, string>) {
  476. const { skuArray, primaryImage, unit } = this.data
  477. const selectedSkuValues = this.getSelectedSkuValues(specList, selectedSku)
  478. let selectedAttrStr = ` ${unit} `
  479. selectedSkuValues.forEach((item) => {
  480. selectedAttrStr += `,${item.specValue} `
  481. })
  482. // eslint-disable-next-line array-callback-return
  483. const findSkuItem = skuArray.filter((item) => {
  484. let status = true
  485. ;(item.specInfo || []).forEach((subItem: any) => {
  486. if (!selectedSku[subItem.specId] || selectedSku[subItem.specId] !== subItem.specValueId) {
  487. status = false
  488. }
  489. })
  490. if (status) return item
  491. })
  492. this.selectSpecsName(selectedSkuValues.length > 0 ? selectedAttrStr : '')
  493. console.log('find sku:', findSkuItem)
  494. if (findSkuItem && findSkuItem.length > 0) {
  495. const selectItem = findSkuItem[0]
  496. this.setData({
  497. specImg: selectItem.image,
  498. selectItem,
  499. selectSkuSellPrice: selectItem.price || 0,
  500. selectSkuLinePrice: selectItem.linePrice || 0,
  501. })
  502. } else {
  503. this.setData({
  504. specImg: primaryImage,
  505. selectItem: null,
  506. selectSkuSellPrice: 0,
  507. selectSkuLinePrice: 0,
  508. })
  509. }
  510. },
  511. getSelectedSkuValues(skuTree: any, selectedSku: any) {
  512. const normalizedTree = this.normalizeSkuTree(skuTree)
  513. return Object.keys(selectedSku).reduce((selectedValues: any[], skuKeyStr) => {
  514. const skuValues = normalizedTree[skuKeyStr] as any[]
  515. const skuValueId = selectedSku[skuKeyStr]
  516. if (skuValueId !== '') {
  517. const skuValue = skuValues.filter((value) => {
  518. return value.specValueId === skuValueId
  519. })[0]
  520. skuValue && selectedValues.push(skuValue)
  521. }
  522. return selectedValues
  523. }, [])
  524. },
  525. normalizeSkuTree(skuTree: any) {
  526. const normalizedTree = {} as any
  527. skuTree.forEach((treeItem: any) => {
  528. normalizedTree[treeItem.specId] = treeItem.specValueList
  529. })
  530. return normalizedTree
  531. },
  532. selectSpecsName(selectSpecsName: string) {
  533. if (selectSpecsName) {
  534. this.setData({
  535. selectedAttrStr: selectSpecsName,
  536. })
  537. } else {
  538. this.setData({
  539. selectedAttrStr: '',
  540. })
  541. }
  542. },
  543. onChangeSpec(e: WechatMiniprogram.CustomEvent<{}, {}, { gi: number; goods: any }>) {
  544. const { gi, goods } = e.currentTarget.dataset
  545. const data = this.data.cartGoods as any[]
  546. this.setData({
  547. wait: true,
  548. selgi: gi,
  549. })
  550. GoodApi.GetProduct({ id: goods.goodId } as any)
  551. .then((rsp) => {
  552. if (rsp.result) {
  553. const details = rsp.result
  554. const {
  555. imageUrl: primaryImage,
  556. limitMaxCount,
  557. limitMinCount,
  558. limitBuyInfo,
  559. unit,
  560. } = details
  561. const skuArray = [] as {
  562. skuId: number
  563. quantity: number
  564. image: string
  565. price: number
  566. linePrice: number
  567. specInfo: TmpSpecInfo[]
  568. }[]
  569. if (details.skuList) {
  570. details.skuList.forEach((item) => {
  571. const priceInfo = item.priceInfo || []
  572. const len = priceInfo.length
  573. skuArray.push({
  574. skuId: Number(item.skuId),
  575. image: item.skuImage || primaryImage || '',
  576. price: len > 0 ? priceInfo[0].price : 0,
  577. linePrice: len > 1 ? priceInfo[1].price : 0,
  578. quantity: item.stockInfo ? item.stockInfo.stockQuantity : 0,
  579. specInfo: item.specInfo || [],
  580. })
  581. })
  582. }
  583. console.log(rsp.result, skuArray)
  584. this.setData({
  585. details: rsp.result,
  586. wait: false,
  587. isAllSelectedSku: false,
  588. isSpuSelectPopupShow: true,
  589. primaryImage,
  590. isStock: details.spuStockQuantity > 0,
  591. skuArray: skuArray as any,
  592. soldout: details.isPutOnSale === 0,
  593. minSalePrice: details.minSalePrice,
  594. minLinePrice: details.minSalePrice,
  595. limitMaxCount,
  596. limitMinCount,
  597. limitBuyInfo,
  598. unit,
  599. })
  600. }
  601. })
  602. .catch(() => {
  603. this.setData({
  604. wait: false,
  605. selgi: -1,
  606. })
  607. })
  608. },
  609. calc(data: any[]) {
  610. const total = data.reduce(
  611. (
  612. re: {
  613. sum: number
  614. selected: number
  615. },
  616. o,
  617. ) => {
  618. if (o.isSelected) {
  619. re.sum += o.buyNum * o.price
  620. re.selected += 1
  621. }
  622. return re
  623. },
  624. {
  625. sum: 0,
  626. selected: 0,
  627. },
  628. )
  629. this.setData({
  630. cartGoods: data,
  631. wait: false,
  632. cartData: {
  633. ...this.data.cartData,
  634. totalAmount: total.sum,
  635. isAllSelected: data.length !== 0 && total.selected === data.length,
  636. selectedGoodsCount: total.selected,
  637. isNotEmpty: data.length !== 0,
  638. },
  639. })
  640. },
  641. changeAddress() {
  642. console.log('switch address')
  643. },
  644. })