index.ts 16 KB

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