category.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. // pages/category/category.js
  2. var http = require("../../utils/http.js");
  3. var util = require('../../utils/util.js');
  4. var config = require("../../utils/config.js");
  5. import eventBus from '../../utils/eventBus';
  6. Page({
  7. /**
  8. * 页面的初始数据
  9. */
  10. data: {
  11. showTabbar:true,
  12. showLoading:false,
  13. rightView:'',
  14. paramsObj:{
  15. sort:0,
  16. orderBy:0
  17. },
  18. type:'bottom',
  19. toViewId:'test1',
  20. topHeight:300,
  21. sort:0,
  22. imgUrl:'',
  23. testShopId:0,//109
  24. totalInfo:{"totalMoney":0,"finalMoney":0,"subtractMoney":0.0,"count":0},
  25. shopId:0,
  26. show:false,
  27. showCar:false,
  28. selIndex: 0,
  29. selCategory:0,
  30. subIndex:0,
  31. thridIndex:-1,
  32. subCategoryId:0,
  33. categoryList: [],
  34. categoryImg: '',
  35. subCategoryList: [],
  36. thridCategoryList:[],
  37. pageTopHeight: wx.getWindowInfo().statusBarHeight,
  38. hotList: [],
  39. topCurrentIndex: 0,
  40. productList:[],
  41. carData:[],//购物车数据
  42. animateInfo:{
  43. startX:99999,
  44. startY:0,
  45. endX:0,
  46. endY:0,
  47. },
  48. move:false
  49. },
  50. /**
  51. * 生命周期函数--监听页面加载
  52. */
  53. onLoad: function (options) {
  54. this.getRecommended()
  55. this.get_neighborShop()
  56. // this.get_categoryInfo()
  57. },
  58. scroll(){
  59. },
  60. scrollTop(){
  61. console.log('top',);
  62. if(this.data.subIndex==0||this.data.subCategoryList.length==0||this.data.productList.length == 0) return
  63. this.setData({
  64. type:'top'
  65. })
  66. let data = {currentTarget:{
  67. dataset:{
  68. index:this.data.subIndex-1
  69. }
  70. }}
  71. this.onleftMenuTab(data)
  72. // this.setData({
  73. // topHeight:0
  74. // })
  75. },
  76. scrollBottom(){
  77. // this.data.productList 新增判断 避免为空自动滚动
  78. if(this.data.subIndex==(this.data.subCategoryList.length-1)||this.data.subCategoryList.length==0||this.data.productList.length == 0) return
  79. this.setData({
  80. type:'bottom'
  81. })
  82. let data = {currentTarget:{
  83. dataset:{
  84. index:this.data.subIndex+1
  85. }
  86. }}
  87. this.setData({
  88. topHeight:15
  89. },() => {
  90. // 3. 延迟恢复样式(避免视觉闪烁)
  91. setTimeout(() => {
  92. this.onleftMenuTab(data)
  93. }, 0);
  94. })
  95. },
  96. handleSale(){
  97. this.setData({
  98. sort:1,
  99. paramsObj:{sort:1,orderBy:0}
  100. })
  101. this.getData(this.data.subCategoryList[this.data.subIndex])
  102. },
  103. handlePrice(){
  104. // 没点击价格
  105. if(this.data.sort !=2&&this.data.sort!=3){
  106. this.setData({
  107. sort:2,
  108. paramsObj:{sort:2,orderBy:0}
  109. })
  110. }else{
  111. let sort = this.data.sort ==2?3:2
  112. this.setData({
  113. sort,
  114. paramsObj:{sort:2,orderBy:this.data.sort ==2?0:1}
  115. })
  116. }
  117. this.getData(this.data.subCategoryList[this.data.subIndex])
  118. },
  119. resetData(){
  120. this.setData({
  121. subIndex:0,
  122. thridIndex:-1,
  123. subCategoryId:0,
  124. })
  125. },
  126. // 点击购物车内加减按钮
  127. handleNum(e){
  128. // 查看是否授权
  129. util.checkAuthInfo(()=>{
  130. let {num,item,type,index} = e.currentTarget.dataset
  131. let data = {
  132. "basketId": item.basketId||0,
  133. "count": num,
  134. "distributionCardNo": item.distributionCardNo||'',
  135. "prodId": item.prodId,
  136. "shopId": item.shopId,
  137. "skuId": item.skuId||item.skuList[0].skuId,
  138. channelId:wx.getStorageSync('channelId')||3
  139. }
  140. this.changeCar(data)
  141. if(type == 'add'){
  142. this.addAnimate(e)
  143. }
  144. })
  145. },
  146. addAnimate(e){
  147. let startX = e.touches[0].clientX-10
  148. let startY = e.touches[0].clientY-10
  149. const query = wx.createSelectorQuery().in(this);
  150. query.select('.bottom-box .left .icon').boundingClientRect(cartRect => {
  151. console.log(222222,cartRect);
  152. if (!cartRect) return;
  153. let animateInfo = {
  154. startX,
  155. startY,
  156. endX:cartRect.left,
  157. endY:cartRect.bottom,
  158. }
  159. this.setData({
  160. move:true,
  161. animateInfo
  162. })
  163. console.log(animateInfo);
  164. }).exec();
  165. },
  166. endAnimate(){
  167. console.log('ddddd');
  168. let animateInfo = {
  169. startX:9999,
  170. startY:0,
  171. endX:0,
  172. endY:0,
  173. }
  174. this.setData({
  175. move:false,
  176. animateInfo
  177. })
  178. },
  179. // 获取点击位置和购物车位置
  180. getNodePositions(index) {
  181. const query = wx.createSelectorQuery().in(this);
  182. // 1. 获取"加入购物车"按钮的位置(动画起始点)
  183. query.select(`.product-item:nth-child(${index + 1}) .info .price-box .test`).boundingClientRect(btnRect => {
  184. if (!btnRect) return; // 容错:防止节点未找到
  185. const startX = btnRect.left + btnRect.width / 2 - 20; // 20 = 40rpx/2(图标宽高)
  186. const startY = btnRect.top + btnRect.height / 2 - 20;
  187. // 2. 获取购物车位置(动画结束点)
  188. query.select('.bottom-box .left .icon').boundingClientRect(cartRect => {
  189. if (!cartRect) return;
  190. const endX = cartRect.left + cartRect.width / 2 - 20;
  191. const endY = cartRect.top + cartRect.height / 2 - 20;
  192. // 3. 计算抛物线中间点(控制弧度)
  193. const midX = (startX + endX) / 2;
  194. const midY = startY - 80; // 向上凸起80px,可调整弧度
  195. // 4. 创建动画图标
  196. this.createAnimationIcon(startX, startY, midX, midY, endX, endY);
  197. }).exec();
  198. }).exec();
  199. },
  200. // 创建抛物线动画(数据驱动,无DOM操作)
  201. createAnimationIcon(startX, startY, midX, midY, endX, endY) {
  202. // 生成唯一ID,避免key冲突
  203. const iconId = Date.now() + Math.floor(Math.random() * 1000);
  204. const newIcon = {
  205. id: iconId,
  206. startX,
  207. startY,
  208. midX,
  209. midY,
  210. endX,
  211. endY
  212. };
  213. // 添加动画图标到数组(自动渲染)
  214. this.setData({
  215. animationIcons: [...this.data.animationIcons, newIcon]
  216. });
  217. // 动画结束后移除图标+更新购物车
  218. setTimeout(() => {
  219. this.setData({
  220. animationIcons: this.data.animationIcons.filter(icon => icon.id !== iconId),
  221. });
  222. }, 700); // 与动画时长保持一致(0.7s)
  223. },
  224. handleAll(){
  225. this.setData({
  226. show:true
  227. })
  228. },
  229. onClose(){
  230. this.setData({
  231. show:false
  232. })
  233. },
  234. openCar(){
  235. console.log(111111);
  236. this.setData({
  237. showCar:true
  238. })
  239. },
  240. onCarClose(){
  241. this.setData({
  242. showCar:false
  243. })
  244. },
  245. /**
  246. * 获取距离最近店铺id
  247. * @param {*} e
  248. */
  249. get_neighborShop: function () {
  250. var params = {
  251. url: "/shop/neighborShop",
  252. method: "GET",
  253. data: {
  254. lat: wx.getStorageSync('LATITUDE'),
  255. lon: wx.getStorageSync('LONGITUDE'),
  256. channelId:wx.getStorageSync('channelId')||3
  257. },
  258. callBack: (res) => {
  259. // this.get_categoryInfo(res)
  260. wx.setStorageSync('shopInfo', res)
  261. this.setData({
  262. shopId:res.shopId
  263. })
  264. this.get_categoryInfo(res.shopId)
  265. this.getCarData(this.data.shopId)
  266. }
  267. };
  268. http.request(params);
  269. },
  270. get_categoryInfo: function (shopid) {
  271. var ths = this;
  272. let that = this
  273. //加载分类列表
  274. var params = {
  275. // url: "/category/categoryInfo",
  276. // url: "/category/listCategoryForUser/"+(this.data.testShopId||shopid),
  277. url: "/category/listCategoryForUser",
  278. method: "GET",
  279. data:{
  280. shopId:this.data.testShopId||shopid,
  281. channelId:wx.getStorageSync('channelId')||3,
  282. },
  283. callBack: function (res) {
  284. ths.setData({
  285. categoryList: res,
  286. subCategoryList: res[ths.data.selIndex].children
  287. });
  288. let categoryId =wx.getStorageSync('categoryId')
  289. if(categoryId){
  290. that.data.categoryList.map((item,index)=>{
  291. if(item.categoryId == categoryId){
  292. that.setData({
  293. selCategory:categoryId,
  294. selIndex:index,
  295. subCategoryList:res[index].children
  296. })
  297. }
  298. })
  299. wx.removeStorageSync('categoryId')
  300. }
  301. // eventBus.on('categoryId', (data) => {
  302. // eventBus.clear()
  303. // that.data.categoryList.map((item,index)=>{
  304. // if(item.categoryId == data){
  305. // that.setData({
  306. // selCategory:data,
  307. // selIndex:index,
  308. // subCategoryList:res[index].children
  309. // })
  310. // }
  311. // })
  312. // });
  313. ths.getData(ths.data.subCategoryList[0])
  314. }
  315. };
  316. http.request(params);
  317. },
  318. getData(data){
  319. console.log(data);
  320. if(!data){
  321. return this.setData({
  322. thridCategoryList:[],
  323. showLoading:false
  324. })
  325. }
  326. this.setData({
  327. thridCategoryList:[],
  328. showLoading:true
  329. })
  330. // 二级分类有商品
  331. if(data.productBeBound == 1){
  332. this.getAllProList(data.categoryId)
  333. // this.getProdList(data.categoryId)
  334. }else{//二级分类有三级分类
  335. this.getAllProList(data.categoryId)
  336. this.setData({
  337. thridCategoryList:data.children,
  338. subCategoryId:data.categoryId
  339. })
  340. }
  341. },
  342. /**
  343. * 选择定位后更新列表
  344. */
  345. go_update() {
  346. this.get_neighborShop()
  347. },
  348. /**
  349. * 生命周期函数--监听页面初次渲染完成
  350. */
  351. onReady: function () {
  352. },
  353. /**
  354. * 生命周期函数--监听页面显示
  355. */
  356. onShow: function () {
  357. console.log('show');
  358. if(this.data.shopId){
  359. this.getCarData(this.data.shopId)
  360. }
  361. // if (getApp().globalData.categoryId) {
  362. // let categoryId = getApp().globalData.categoryId
  363. // let index = getApp().globalData.index
  364. // let pic = getApp().globalData.pic
  365. // this.setData({
  366. // categoryImg: pic,
  367. // selIndex: index
  368. // });
  369. // }else{
  370. // this.get_neighborShop()
  371. // }
  372. // 之前逻辑 每次重新加载
  373. // this.resetData()
  374. // this.get_neighborShop()
  375. },
  376. /**
  377. * 生命周期函数--监听页面隐藏
  378. */
  379. onHide: function () {},
  380. /**
  381. * 生命周期函数--监听页面卸载
  382. */
  383. onUnload: function () {
  384. },
  385. /**
  386. * 页面相关事件处理函数--监听用户下拉动作
  387. */
  388. onPullDownRefresh: function () {
  389. },
  390. /**
  391. * 页面上拉触底事件的处理函数
  392. */
  393. onReachBottom: function () {
  394. },
  395. /**
  396. * 用户点击右上角分享
  397. */
  398. onShareAppMessage: function () {
  399. },
  400. /**
  401. * 分类点击事件,获取子分类
  402. */
  403. onMenuTab: function (e) {
  404. var id = e.currentTarget.dataset.id;
  405. var index = e.currentTarget.dataset.index;
  406. // if(this.data.categoryList[index].children.length == 0){
  407. // return
  408. // }
  409. this.setData({
  410. show:false,
  411. categoryImg: this.data.categoryList[index].pic,
  412. subCategoryList:this.data.categoryList[index].children,
  413. selIndex: index,
  414. selCategory:id,
  415. productList:[],
  416. subIndex:0,
  417. paramsObj:{sort:0,orderBy:0},
  418. sort:0
  419. });
  420. // this.getProdList(this.data.subCategoryList[0].categoryId)
  421. this.getData(this.data.subCategoryList[0])
  422. getApp().globalData.categoryId = ''
  423. getApp().globalData.index = ''
  424. getApp().globalData.pic = ''
  425. },
  426. /**
  427. * 推荐词,type:1关键词,2热门搜索词,3推荐搜索词
  428. */
  429. getRecommended: function () {
  430. var params = {
  431. url: "/keyword/list",
  432. method: "GET",
  433. data: {
  434. type: 2
  435. },
  436. callBack: (res) => {
  437. let reslut = res.filter(item => item.status !== 2) //过滤下线词
  438. let timeReslut = reslut.filter(e => util.dateToTimestamp(e.effectiveTime) < new Date().getTime()) //过滤未生效词
  439. this.setData({
  440. hotList: timeReslut
  441. })
  442. }
  443. };
  444. http.request(params);
  445. },
  446. /**
  447. * 推荐词搜索
  448. */
  449. topSwiperChange: function (e) {
  450. this.setData({
  451. topCurrentIndex: e.detail.current // 获取当前滚动到的swiper-item的索引并更新到data中
  452. })
  453. },
  454. topHotSearch: function () {
  455. const topname = this.data.hotList[this.data.topCurrentIndex].name
  456. wx.navigateTo({
  457. url: `/pages/search-prod-show/search-prod-show?prodName=${topname}&shopId=${this.data.shopId}`,
  458. })
  459. },
  460. // 跳转搜索页
  461. toSearchPage: function () {
  462. wx.navigateTo({
  463. url: `/pages/search-page/search-page?shopId=${this.data.shopId}`,
  464. })
  465. },
  466. /**
  467. * 跳转到定位页面
  468. */
  469. toLocationPage: function () {
  470. wx.navigateTo({
  471. url: '/pages/locationAdd/locationAdd',
  472. })
  473. },
  474. // 点击二级分类
  475. onleftMenuTab(e){
  476. const {
  477. index,
  478. id
  479. } = e.currentTarget.dataset
  480. if(id){
  481. this.setData({
  482. type:'click'
  483. })
  484. console.log('click');
  485. }
  486. this.setData({
  487. subIndex:index,
  488. paramsObj:{sort:0,orderBy:0},
  489. sort:0
  490. })
  491. // this.getProdList(this.data.subCategoryList[index].categoryId)
  492. this.getData(this.data.subCategoryList[index])
  493. },
  494. // 根据分类id获取商品数据
  495. getProdList(categoryId) {
  496. var params = {
  497. url: "/search/searchProdPage",
  498. method: "GET",
  499. data: {
  500. categoryId,
  501. current: 1,
  502. size: 999999,
  503. orderBy:this.data.paramsObj.orderBy,
  504. sort:this.data.paramsObj.sort,
  505. isAllProdType: true,
  506. channelId:wx.getStorageSync('channelId')||3,
  507. // lat: wx.getStorageSync('LATITUDE'),
  508. // lon: wx.getStorageSync('LONGITUDE'),
  509. // distance: wx.getStorageSync('DISTANCE') || 0
  510. },
  511. callBack: (res) => {
  512. setTimeout(() => {
  513. this.setData({
  514. showLoading:false
  515. })
  516. }, 500);
  517. console.log(res);
  518. let productList = res.records
  519. let img = ''
  520. productList.map(e => {
  521. img = e.pic.split(',')
  522. e.pic = img[0]
  523. })
  524. this.setData({
  525. productList,
  526. topHeight:15
  527. })
  528. if(productList.length == 0){
  529. if(this.data.type == 'top'){
  530. this.scrollTop()
  531. }else{
  532. this.scrollBottom()
  533. }
  534. }
  535. this.addParmasProduct()
  536. }
  537. };
  538. http.request(params);
  539. },
  540. // 根据分类id获取所有三级商品数据
  541. getAllProList(categoryId) {
  542. var params = {
  543. url: "/prod/listProdByCategoryIdAndShopId",
  544. method: "post",
  545. data: {
  546. orderBy:this.data.paramsObj.orderBy,
  547. sort:this.data.paramsObj.sort,
  548. categoryId,
  549. current: 1,
  550. size: 999999,
  551. channelId:wx.getStorageSync('channelId')||3,
  552. shopId:this.data.testShopId||this.data.shopId
  553. },
  554. callBack: (res) => {
  555. setTimeout(() => {
  556. this.setData({
  557. showLoading:false
  558. })
  559. }, 500);
  560. let productList = res.records
  561. let img = ''
  562. productList.map(e => {
  563. img = e.pic.split(',')
  564. e.pic = img[0]
  565. })
  566. this.setData({
  567. productList,
  568. topHeight:15
  569. })
  570. if(productList.length == 0){
  571. if(this.data.type == 'top'){
  572. this.scrollTop()
  573. }else if(this.data.type == 'bottom'){
  574. this.scrollBottom()
  575. }
  576. }
  577. this.addParmasProduct()
  578. }
  579. };
  580. http.request(params);
  581. },
  582. // 点击三级分类
  583. handleThrid(e){
  584. let {
  585. index,
  586. categoryid
  587. } = e.currentTarget.dataset
  588. console.log(33333333333,e.currentTarget.dataset);
  589. this.setData({
  590. thridIndex:index
  591. })
  592. if(index == -1){
  593. categoryid = this.data.subCategoryId
  594. }
  595. this.getAllProList(categoryid)
  596. },
  597. // 除了产品列表数据 给产品列表添加显示和数量 同步购物车数据
  598. addParmasProduct(){
  599. if(this.data.productList.length >0){
  600. let productList = JSON.parse(JSON.stringify( this.data.productList))
  601. productList.map(i=>{
  602. i.show = false
  603. this.data.carData.map(item=>{
  604. if(item.prodId == i.prodId){
  605. i.prodCount = item.prodCount
  606. i.show = true
  607. }
  608. })
  609. })
  610. this.setData({
  611. productList
  612. })
  613. }
  614. },
  615. // 获取购物车数据
  616. getCarData() {
  617. var params = {
  618. url: "/p/shopCart/info/1",
  619. method: "post",
  620. data: [{
  621. "basketId": 0,
  622. "discountId": 0,
  623. "shopId":this.data.testShopId||this.data.shopId
  624. }],
  625. callBack: (res) => {
  626. if(res.length){
  627. let carData = res[0].shopCartItemDiscounts[0].shopCartItems
  628. let img = ''
  629. carData.map(e => {
  630. img = e.pic.split(',')
  631. e.pic = img[0]
  632. })
  633. this.setData({
  634. carData
  635. },()=>{
  636. this.getCarTotal()
  637. })
  638. }else{
  639. this.setData({
  640. carData:[]
  641. },()=>{
  642. this.getCarTotal()
  643. })
  644. }
  645. // 给产品列表添加显示和数量 同步购物车数据
  646. this.addParmasProduct()
  647. }
  648. };
  649. http.request(params);
  650. },
  651. // 获取购物车数量和总价
  652. getCarTotal() {
  653. let basketIds = this.data.carData.map(item=>{
  654. return item.basketId
  655. })
  656. var params = {
  657. url: "/p/shopCart/totalPay?t="+new Date().getTime(),
  658. method: "post",
  659. data: basketIds,
  660. callBack: (res) => {
  661. this.setData({
  662. totalInfo:res
  663. })
  664. }
  665. };
  666. http.request(params);
  667. http.getCartCount(); //重新计算购物车总数量
  668. },
  669. // 添加修改购物车数量
  670. changeCar(data) {
  671. var params = {
  672. url: "/p/shopCart/changeItem?t="+new Date().getTime(),
  673. method: "post",
  674. data,
  675. callBack: (res) => {
  676. if(res.code == 500){
  677. wx.showToast({
  678. title: res.msg,
  679. icon:'none'
  680. })
  681. }else{
  682. this.getCarData()
  683. }
  684. }
  685. };
  686. http.request(params);
  687. },
  688. /**
  689. * 跳转到商品详情页
  690. */
  691. toProdPage: function (e) {
  692. var prodid = e.currentTarget.dataset.prodid;
  693. var shopid = e.currentTarget.dataset.shopid;
  694. console.log(22222222,e);
  695. if (prodid) {
  696. wx.navigateTo({
  697. url: `/pages/prod/prod?prodid=${prodid}&shopid=${shopid}`,
  698. })
  699. }
  700. },
  701. handleBuy(){
  702. if(this.data.carData.length == 0){
  703. return
  704. }
  705. let basketIds = this.data.carData.map(item=>{
  706. return item.basketId
  707. })
  708. wx.setStorageSync("basketIds", JSON.stringify(basketIds));
  709. wx.navigateTo({
  710. url: '/pages/submit-order/submit-order?orderEntry=0&shopId='+this.data.carData[0].shopId,
  711. })
  712. }
  713. })