store_cate2.vue 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429
  1. <template>
  2. <view class="container">
  3. <view class="headerBg">
  4. <image :src="info.background_image" mode="aspectFill" class="image"></image>
  5. <view class="shade"></view>
  6. <!-- #ifdef MP || APP -->
  7. <view :style="{height: getHeight.barTop+'px'}"></view>
  8. <view :style="{height: getHeight.barHeight+'px'}"></view>
  9. <!-- #endif -->
  10. <view style="height: 224rpx;"></view>
  11. </view>
  12. <view class="page">
  13. <view class="search-box" :style="{height: headerHeight ? (headerHeight+'px') : 'auto'}">
  14. <view class="input-box" id="input-box" :class="{fixed: scrollTop > 0}">
  15. <!-- #ifdef MP || APP -->
  16. <view :style="{height: getHeight.barTop+'px'}"></view>
  17. <!-- #endif -->
  18. <!-- 顶部搜索框 -->
  19. <!-- #ifdef MP -->
  20. <view class="input-wrapper acea-row row-middle" :style="{height: getHeight.barHeight+'px'}">
  21. <view class="menu_box flex-center" @tap="moreNav">
  22. <text class="iconfont icon-a-icon_menu1x"></text>
  23. </view>
  24. <navigator url="/pages/goods/goods_search/index" class="input acea-row row-middle" hover-class="none">
  25. <text class="iconfont icon-ic_search"></text>搜索商品
  26. </navigator>
  27. <view v-if="info.store_splicing_switch" class="group-btn" @click="onCollage">
  28. <image :src="imgHost+'/statics/images/group-btn.png'" mode="aspectFit" class="img"></image>
  29. </view>
  30. <view :style="{width: getHeight.barWidth+'px'}"></view>
  31. </view>
  32. <!-- #endif -->
  33. <!-- #ifndef MP -->
  34. <view class="input-wrapper acea-row row-middle">
  35. <view class="menu_box flex-center" @tap="moreNav">
  36. <text class="iconfont icon-a-icon_menu1x"></text>
  37. </view>
  38. <navigator url="/pages/goods/goods_search/index" class="input acea-row row-middle" hover-class="none">
  39. <text class="iconfont icon-ic_search"></text>搜索商品
  40. </navigator>
  41. <!-- #ifdef H5 -->
  42. <view v-if="info.store_splicing_switch && $wechat.isWeixin()" class="group-btn" @click="onCollage">
  43. <image :src="imgHost+'/statics/images/group-btn.png'" mode="aspectFit" class="img"></image>
  44. </view>
  45. <!-- #endif -->
  46. </view>
  47. <!-- #endif -->
  48. </view>
  49. </view>
  50. <!-- <scroll-view scroll-y="true" class="scroll-view" @scroll="goodsListScroll" @scrolltolower="getProducts"> -->
  51. <!-- 门店地址 -->
  52. <view class="store-section">
  53. <view class="panel">
  54. <view class="acea-row row-middle store-name">
  55. <view class="name-wrap">
  56. <navigator :url="'/pages/store/info/index?store_id='+info.id" hover-class="none" class="acea-row row-middle name-inner">
  57. <text class="iconfont icon-ic_mall"></text>
  58. <view class="name line1">{{info.name}}</view>
  59. <text class="iconfont icon-ic_rightarrow"></text>
  60. </navigator>
  61. </view>
  62. <!-- <view class="tips">门店支持自提</view> -->
  63. <view class="switch acea-row" v-if="deliveryList.length > 1">
  64. <view v-for="(item, index) in deliveryList" :key="item.key" :class="{ on: switchNum == item.key }" class="btn" @click="swithFn(item.key)">{{item.name}}</view>
  65. </view>
  66. <view class="tips" v-else-if="deliveryList.length == 1">门店支持{{deliveryList[0].name}}</view>
  67. </view>
  68. <view class="acea-row row-bottom address-wrap">
  69. <view class="address-box">
  70. <view class="time">营业时间:{{info.day_time}}</view>
  71. <view class="address-info">
  72. <text class="distance">距您{{info.range}}km</text>
  73. {{info.address}}{{info.detailed_address}}
  74. </view>
  75. </view>
  76. <view class="acea-row btn-box">
  77. <view class="btn" @click="showMaoLocation">
  78. <text class="iconfont icon-ic_location5"></text>
  79. <view class="">地图</view>
  80. </view>
  81. <view class="btn" @click="goKefu">
  82. <text class="iconfont icon-ic_customerservice"></text>
  83. <view class="">客服</view>
  84. </view>
  85. </view>
  86. </view>
  87. </view>
  88. </view>
  89. <!-- 商品排序条件 -->
  90. <view class="nav-box" id="nav-box">
  91. <view class="nav acea-row row-middle" :class="{ fixed: scrollTop && conterTop <= headerHeight }" :style="{ top: headerHeight+'px' }">
  92. <view class="flex-1 acea-row row-around row-middle">
  93. <view @click="set_where(1)" :class="{'activeColor':active == 1}">
  94. 默认排序
  95. </view>
  96. <view @click='set_where(2)' :class="{'activeColor':active == 2}">
  97. 价格
  98. <text v-if="price==2" class="iconfont icon-ic_down2"></text>
  99. <text v-else class="iconfont icon-ic_up2"></text>
  100. </view>
  101. <view @click='set_where(3)' :class="{'activeColor':active == 3}">
  102. 销量
  103. <text v-if="stock==2" class="iconfont icon-ic_down2"></text>
  104. <text v-else class="iconfont icon-ic_up2"></text>
  105. </view>
  106. </view>
  107. <view @click="set_where(4)" class="filter-btn">
  108. <view class="line-left"></view>
  109. 筛选
  110. <text class="iconfont icon-ic_sort"></text>
  111. </view>
  112. </view>
  113. </view>
  114. <!-- 商品列表 -->
  115. <view class="list waterList">
  116. <WaterfallsFlow ref="waterfallsFlow" :wfList="productList" @itemTap="godDetail"></WaterfallsFlow>
  117. <view class='loadingicon acea-row row-center-wrapper' v-if='productList.length > 0'>
  118. <text class='loading iconfont icon-jiazai' :hidden='loading==false'></text>{{loadTitle}}
  119. </view>
  120. </view>
  121. <!-- 商品列表 -->
  122. <view class="default" v-if="productList.length==0 && where.page > 1">
  123. <emptyPage title="暂无商品,去看点别的吧~"></emptyPage>
  124. </view>
  125. <!-- </scroll-view> -->
  126. <view class="footer">
  127. <view class="inner-box" :class="{ open: footerOpen }">
  128. <view class="inner acea-row row-between row-middle">
  129. <view class="acea-row row-bottom" style="flex-wrap: nowrap;">
  130. <BaseMoney :money="totalPrice" symbolSize="32" integerSize="48" decimalSize="32" color="#FFFFFF"></BaseMoney>
  131. <view class="detail-btn" style="white-space: nowrap;" @click="getCartLists">查看明细<text class="iconfont icon-ic_uparrow"></text></view>
  132. </view>
  133. <view class="btn" @click="subOrder">去结算({{cartNum}})</view>
  134. </view>
  135. </view>
  136. <view class="cartIcon" @click="getCartLists">
  137. <uni-badge :text="cartNum" absolute="rightTop" :offset="[6, 4]" :custom-style="{background: 'var(--view-theme)'}">
  138. <view class="image-wrap">
  139. <image src="@/static/img/cart_pic.png" class="image"></image>
  140. </view>
  141. </uni-badge>
  142. </view>
  143. </view>
  144. </view>
  145. <!-- 筛选弹窗 -->
  146. <filterPopup ref="popup" :level="level" :storeCategory="storeCategory" :storeBrand="storeBrand" @brandChange="brandChange" @categoryChange="categoryChange" @submitFn="submitFn"></filterPopup>
  147. <!-- 客服弹窗 -->
  148. <Kefu ref="kefu" @closeKefu="closeKefu" :customerList="customerList" :customerType="customerType"></Kefu>
  149. <!-- #ifdef H5 || MP -->
  150. <tuiDrawer :visible="collageVisible" :zIndex="970" :maskZIndex="960" mode="bottom" backgroundColor="transparent" @close="onCollageClose">
  151. <view class="dialog">
  152. <view class="dialog-head acea-row row-between row-middle">
  153. <view>发起「一起拼」</view>
  154. <view class="btn" @click="onCollageClose">
  155. <text class="iconfont icon-ic_close"></text>
  156. </view>
  157. </view>
  158. <view class="dialog-body">
  159. <view class="navbar">
  160. <view class="navbar-bg"></view>
  161. <view class="active-bg acea-row row-bottom" :class="{'row-right':collageDelivery==1}">
  162. <image v-if="collageDelivery==1" class="image2" src="../static/navbar-right-2.png"></image>
  163. <image class="image1" src="../static/navbar-left-1.png"></image>
  164. <image v-if="collageDelivery==2" class="image2" src="../static/navbar-left-2.png"></image>
  165. </view>
  166. <view class="inner acea-row">
  167. <view v-for="(item, index) in deliveryList" :key="item.key" :class="{ on: collageDelivery == item.key }" class="item acea-row row-center-wrapper"
  168. @click="collageDeliveryChange(item, index)">
  169. <text :class="'iconfont '+item.icon"></text>
  170. {{item.name}}
  171. </view>
  172. </view>
  173. </view>
  174. <view class="dialog-content" :class="{
  175. btl:collageIndex==deliveryList.length-1,
  176. btr:!collageIndex
  177. }">
  178. <scroll-view v-if="collageDelivery == 1 && addressList.length" scroll-y="true" class="address-box">
  179. <view class="list">
  180. <view v-for="(item, index) in addressList" :key="item.id" :class="{ on: item.id == addressId }" class="item acea-row row-middle" @click="onAddressChange(item)">
  181. <view class="text">
  182. <view class="info">{{item.province}}{{item.city}}{{item.district}}{{item.street}}{{item.detail}}</view>
  183. <view class="name">{{item.real_name}} {{item.phone}}</view>
  184. </view>
  185. <text class="iconfont icon-ic_complete"></text>
  186. </view>
  187. </view>
  188. </scroll-view>
  189. <navigator v-if="collageDelivery == 1 && !addressList.length" class="link" url="/pages/users/user_address/index?fromType=1" hover-class="none">
  190. <view class="title acea-row row-between-wrapper">
  191. <view>添加配送地址</view>
  192. <text class="iconfont icon-ic_rightarrow"></text>
  193. </view>
  194. <view>您还未添加配送地址,先去添加地址再下单吧~</view>
  195. </navigator>
  196. <view v-if="collageDelivery == 2" class="store-box acea-row">
  197. <view class="text">
  198. <view class="name">{{collageStore.name}}</view>
  199. <view class="info acea-row">
  200. <text class="iconfont icon-ic_location51"></text>
  201. <view class="value">{{collageStore.address}}{{collageStore.detailed_address}}</view>
  202. </view>
  203. <view class="info acea-row">
  204. <text class="iconfont icon-icon_clock"></text>
  205. <view class="value">营业时间:{{collageStore.day_time}}</view>
  206. </view>
  207. </view>
  208. <view class="map-box">
  209. <image src="../static/map2.png" class="map"></image>
  210. <view class="img-box">
  211. <image :src="collageStore.image" class="img"></image>
  212. <view class="range">距您{{collageStore.range}}km</view>
  213. <view class="dot"></view>
  214. </view>
  215. </view>
  216. </view>
  217. <view class="btn-box acea-row row-center-wrapper" v-if="collageDelivery == 1 && addressList.length">
  218. <navigator url="/pages/users/user_address/index?fromType=1" hover-class="none">
  219. 添加地址
  220. <text class="iconfont icon-ic_rightarrow"></text>
  221. </navigator>
  222. </view>
  223. </view>
  224. </view>
  225. <view class="dialog-foot">
  226. <view class="btn" @click="initCollage">发起拼单</view>
  227. </view>
  228. </view>
  229. </tuiDrawer>
  230. <!-- 商品属性弹窗 -->
  231. <productWindow :attr="attr" :isShow="1" :iSplus="1" :iScart="1" :type="2" @myevent="onMyEvent" @attrVal="attrVal" @ChangeAttr="ChangeAttr" @ChangeCartNum="ChangeCartNumDuo"
  232. @iptCartNum="iptCartNum" @goCat="goCatNum">
  233. </productWindow>
  234. <!-- #endif -->
  235. <homeList :currentPage="currentPage" :navH="getHeight.barTop+40" :openNavList="diyProduct.navList"></homeList>
  236. <cartList :marginBottom="74" :cartData="cartData" @closeList="closeList" @ChangeCartNumDan="ChangeCartList" @ChangeSubDel="ChangeSubDel" @ChangeOneDel="ChangeOneDel"></cartList>
  237. </view>
  238. </template>
  239. <script>
  240. import filterPopup from "@/components/filterPopup/index.vue";
  241. import Kefu from "@/components/kefu/index.vue";
  242. import WaterfallsFlow from "@/components/WaterfallsFlow/WaterfallsFlow.vue";
  243. import productWindow from "@/components/productWindow/index.vue";
  244. import emptyPage from "@/components/emptyPage.vue";
  245. import homeList from "@/components/homeList/index.vue";
  246. import cartList from "@/components/cartList/index.vue";
  247. import tuiDrawer from "@/components/tui-drawer/tui-drawer.vue";
  248. import {
  249. mapState,
  250. mapGetters
  251. } from 'vuex';
  252. import {
  253. vcartList,
  254. getCartCounts,
  255. cartDel
  256. } from '@/api/order.js';
  257. import {
  258. getProducts,
  259. getCustomerList,
  260. getStoreCategory,
  261. getStoreBrand
  262. } from '@/api/new_store.js';
  263. import {
  264. goShopDetail
  265. } from '@/libs/order.js';
  266. import {
  267. HTTP_REQUEST_URL
  268. } from '@/config/app';
  269. import {
  270. // #ifdef MP || H5
  271. hasCollage,
  272. // #endif
  273. getAttr,
  274. initCollage,
  275. isWithin,
  276. } from '@/api/store.js';
  277. // #ifdef H5 || MP
  278. import {
  279. getAddressList,
  280. } from '@/api/user.js';
  281. // #endif
  282. // #ifdef H5
  283. import {
  284. toLogin
  285. } from '@/libs/login.js';
  286. // #endif
  287. import skuSelect from '@/mixins/skuSelect.js';
  288. export default {
  289. components: {
  290. filterPopup,
  291. Kefu,
  292. WaterfallsFlow,
  293. productWindow,
  294. emptyPage,
  295. homeList,
  296. cartList,
  297. tuiDrawer,
  298. },
  299. props: {
  300. info: {
  301. type: Object,
  302. default: {}
  303. },
  304. customerType: {
  305. type: Number,
  306. default: 1
  307. },
  308. cart_num: {
  309. type: Number,
  310. default: 0
  311. },
  312. },
  313. mixins: [skuSelect],
  314. computed: {
  315. ...mapState({
  316. // cartNum: state => state.indexData.cartNum
  317. }),
  318. ...mapGetters(['isLogin', 'uid', 'cartNum', 'diyProduct', 'diyCategory']),
  319. level() {
  320. return this.diyCategory.level
  321. },
  322. },
  323. provide: {
  324. parent: {}
  325. },
  326. data() {
  327. return {
  328. id: 0,
  329. getHeight: this.$util.getWXStatusHeight(),
  330. imgHost: HTTP_REQUEST_URL,
  331. price: 0,
  332. stock: 0,
  333. productList: [], // 商品数据
  334. customerList: [], // 客服数据
  335. storeCategory: [], // 分类数据
  336. storeBrand: [], // 品牌数据
  337. show: false,
  338. active: 1,
  339. where: {
  340. cid: 0,
  341. sid: 0,
  342. tid: 0,
  343. keyword: '',
  344. priceOrder: '',
  345. salesOrder: '',
  346. news: 0,
  347. page: 1,
  348. limit: 5,
  349. store_id: 0,
  350. brand_id: '',
  351. },
  352. loading: false,
  353. loadend: false,
  354. loadTitle: '加载更多',
  355. deliveryList: [{
  356. name: '自提',
  357. key: 2,
  358. icon: 'icon-icon_shop1'
  359. },
  360. {
  361. name: '配送',
  362. key: 1,
  363. icon: 'icon-icon_electromobile'
  364. },
  365. ],
  366. switchNum: 1,
  367. // #ifdef H5 || MP
  368. collageVisible: false,
  369. collageDelivery: 2,
  370. collageIndex: 0,
  371. collageAddress: {},
  372. collageStore: {},
  373. // #endif
  374. // #ifdef MP
  375. isSplicingPlatform: true,
  376. // #endif
  377. // #ifndef MP
  378. isSplicingPlatform: false,
  379. // #endif
  380. drawervisible: true,
  381. footerOpen: false,
  382. totalPrice: 0,
  383. cartData: {
  384. cartList: [],
  385. iScart: false
  386. },
  387. attr: {
  388. cartAttr: false,
  389. productAttr: [],
  390. productSelect: {},
  391. deliveryType: [],
  392. },
  393. is_vip: 0, //是否是会员
  394. storeInfo: {},
  395. attrValue: '', //已选属性
  396. currentPage: false,
  397. tempArr: [],
  398. headerHeight: 0,
  399. conterTop: 0,
  400. scrollTop: 0, //已滚动的距离
  401. addressId: 0, // 配送地址id
  402. addressList: [], // 配送地址列表
  403. }
  404. },
  405. mounted() {
  406. let default_delivery = this.info.default_delivery;
  407. for (let i = 0; i < this.deliveryList.length; i++) {
  408. if (this.deliveryList[i].key == 2 && (!this.info.store_self_mention || !this.info.is_store)) {
  409. this.deliveryList.splice(i, 1);
  410. i--;
  411. }
  412. }
  413. if (this.deliveryList.length == 1) {
  414. default_delivery = this.deliveryList[0].key;
  415. }
  416. this.collageStore = this.info;
  417. this.where.store_id = this.info.id;
  418. this.switchNumFun(default_delivery);
  419. // #ifdef H5
  420. this.isSplicingPlatform = this.$wechat.isWeixin();
  421. // #endif
  422. // #ifdef H5 || MP
  423. if (this.isSplicingPlatform && this.info.store_splicing_switch) {
  424. this.collageDelivery = this.info.is_store ? 2 : 1;
  425. uni.$on('activeFn', data => {
  426. this.collageStore = data;
  427. });
  428. }
  429. // #endif
  430. this.$eventHub.$on('onCartAddChange', (data) => {
  431. let index = -1;
  432. for (let i = 0; i < this.productList.length; i++) {
  433. if (this.productList[i].id == data.id) {
  434. index = i;
  435. break;
  436. }
  437. }
  438. if (data.spec_type) {
  439. this.goCartDuo(data);
  440. } else {
  441. this.goCartDan(data, index);
  442. }
  443. });
  444. let view = uni.createSelectorQuery().in(this).select("#nav-box");
  445. // 页面滚动
  446. uni.$on('onPageScroll', ({
  447. scrollTop
  448. }) => {
  449. this.scrollTop = scrollTop;
  450. this.footerOpen = false;
  451. view
  452. .boundingClientRect((data) => {
  453. this.conterTop = data.top;
  454. })
  455. .exec();
  456. });
  457. // 页面滚动到底部
  458. uni.$on('onReachBottom', () => {
  459. this.getProducts();
  460. });
  461. uni.$on('activeAddress', () => {
  462. this.getAddressList();
  463. });
  464. this.getProducts(true);
  465. this.getCartNum();
  466. this.getCartList(1);
  467. this.getAddressList();
  468. },
  469. methods: {
  470. productslist() {
  471. this.getProducts(true);
  472. },
  473. // #ifdef H5 || MP
  474. showMaoLocation() {
  475. let data = {
  476. latitude: Number(this.collageStore.latitude),
  477. longitude: Number(this.collageStore.longitude),
  478. name: this.collageStore.name,
  479. address: `${this.collageStore.address}`,
  480. };
  481. // #ifdef H5
  482. if (this.$wechat.isWeixin()) {
  483. data.scale = 13;
  484. return this.$wechat.seeLocation(data);
  485. }
  486. // #endif
  487. uni.openLocation(data);
  488. },
  489. // #endif
  490. // 选择品牌
  491. brandChange(val) {
  492. this.where.brand_id = val
  493. },
  494. // 选择分类
  495. categoryChange(val) {
  496. this.where.cid = val.cid
  497. this.where.sid = val.sid
  498. this.where.tid = val.tid
  499. },
  500. // 确认提交
  501. submitFn(val) {
  502. if (val == 1) {
  503. this.getProducts(true)
  504. this.$refs.popup.visible = false
  505. } else if (val == 2) {
  506. this.where.brand_id = ""
  507. this.where.cid = ""
  508. this.where.sid = ""
  509. this.getProducts(true)
  510. this.$refs.popup.visible = false
  511. }
  512. },
  513. // 打开附近门店
  514. goMap(val = 0) {
  515. uni.navigateTo({
  516. url: `/pages/store/store_list/index?storeFrom=1&type=1&storeId=${val ? this.collageStore.id : this.info.id}&isCollage=${val}`
  517. });
  518. },
  519. // 打开客服
  520. goKefu() {
  521. this.getCustomerList()
  522. this.$refs.kefu.show = true
  523. },
  524. // 购物车
  525. shoppCart() {
  526. uni.switchTab({
  527. url: "/pages/order_addcart/order_addcart"
  528. })
  529. },
  530. // 关闭客服
  531. closeKefu() {
  532. this.$refs.kefu.show = false
  533. },
  534. // 获取客服列表数据
  535. getCustomerList() {
  536. getCustomerList(this.where.store_id).then(res => {
  537. this.customerList = res.data
  538. })
  539. },
  540. // 去详情页
  541. godDetail(item) {
  542. this.currentPage = false
  543. if (this.promotions_type) {
  544. uni.navigateTo({
  545. url: `/pages/goods_details/index?id=${item.id}`
  546. })
  547. } else {
  548. goShopDetail(item, this.uid).catch(res => {
  549. uni.navigateTo({
  550. url: `/pages/goods_details/index?id=${item.id}`
  551. })
  552. })
  553. }
  554. },
  555. // 操作
  556. set_where: function(e) {
  557. switch (e) {
  558. case 1:
  559. this.active = 1
  560. this.where.priceOrder = ""
  561. this.where.salesOrder = ""
  562. this.where.brand_id = ""
  563. this.price = 0
  564. break;
  565. case 2:
  566. if (this.price == 0) this.price = 1;
  567. else if (this.price == 1) this.price = 2;
  568. else if (this.price == 2) this.price = 0;
  569. if (this.price == 1) {
  570. this.where.priceOrder = "asc"
  571. } else if (this.price == 2) {
  572. this.where.priceOrder = "desc"
  573. } else {
  574. this.where.priceOrder = ""
  575. }
  576. this.active = 2
  577. this.stock = 0;
  578. break;
  579. case 3:
  580. if (this.stock == 0) this.stock = 1;
  581. else if (this.stock == 1) this.stock = 2;
  582. else if (this.stock == 2) this.stock = 0;
  583. if (this.stock == 1) {
  584. this.where.priceOrder = ""
  585. this.where.salesOrder = "asc"
  586. } else if (this.stock == 2) {
  587. this.where.priceOrder = ""
  588. this.where.salesOrder = "desc"
  589. } else {
  590. this.where.salesOrder = ""
  591. }
  592. this.active = 3
  593. this.price = 0
  594. break;
  595. case 4:
  596. this.getStoreCategory()
  597. this.getStoreBrand()
  598. this.$refs.popup.visible = true
  599. this.loadend = false;
  600. this.loading = false;
  601. break;
  602. }
  603. if (e < 4) {
  604. this.loadend = false;
  605. this.$set(this.where, 'page', 1);
  606. this.getProducts(true)
  607. }
  608. },
  609. // 商品列表
  610. getProducts(isPage) {
  611. let that = this;
  612. if (that.loadend) return;
  613. if (that.loading) return;
  614. if (isPage === true) {
  615. // that.$refs.waterfallsFlow.refresh();
  616. that.where.page = 1;
  617. that.$set(that, 'productList', []);
  618. }
  619. that.loading = true;
  620. that.loadTitle = '';
  621. that.where.delivery_type = that.delivery_type;
  622. getProducts(this.where).then(res => {
  623. let list = res.data;
  624. let productList = that.$util.SplitArray(list, that.productList);
  625. let loadend = list.length < that.where.limit;
  626. that.loadend = loadend;
  627. that.loading = false;
  628. that.loadTitle = loadend ? '没有更多内容啦~' : '加载更多';
  629. that.$set(that, 'productList', productList);
  630. that.$set(that.where, 'page', that.where.page + 1);
  631. that.$set(that, 'tempArr', productList);
  632. this.$nextTick(() => {
  633. const query = uni.createSelectorQuery().in(this);
  634. query
  635. .select("#input-box")
  636. .boundingClientRect((data) => {
  637. this.headerHeight = data.height;
  638. })
  639. .exec();
  640. // query
  641. // .select("#nav-box")
  642. // .boundingClientRect((data) => {
  643. // this.conterTop = data.top;
  644. // })
  645. // .exec();
  646. })
  647. }).catch(err => {
  648. that.loading = false;
  649. that.loadTitle = '加载更多'
  650. });
  651. },
  652. // 切换自提方式
  653. swithFn(num) {
  654. this.switchNumFun(num);
  655. this.page = 1;
  656. this.loadend = false;
  657. this.tempArr = []
  658. this.getProducts(true)
  659. },
  660. switchNumFun(num) {
  661. switch (num) {
  662. case 1:
  663. this.switchNum = 1
  664. this.delivery_type = '3'
  665. break;
  666. case 2:
  667. this.switchNum = 2
  668. this.delivery_type = '2'
  669. break;
  670. }
  671. },
  672. // 筛选-分类数据
  673. getStoreCategory() {
  674. let data = {
  675. pid: 0
  676. }
  677. getStoreCategory(data).then(res => {
  678. res.data.map(item => {
  679. this.$set(item, 'disabled', false)
  680. this.$set(item, 'current', 0)
  681. // item.children.unshift({
  682. // 'id': 0,
  683. // 'cate_name': '全部'
  684. // })
  685. item.children.map(items => {
  686. this.$set(items, 'disabled', false)
  687. this.$set(items, 'current', 0)
  688. // item.children.unshift({
  689. // 'id': 0,
  690. // 'cate_name': '全部'
  691. // })
  692. })
  693. })
  694. this.storeCategory = res.data
  695. })
  696. },
  697. // 筛选-品牌数据
  698. getStoreBrand() {
  699. getStoreBrand(this.where).then(res => {
  700. this.storeBrand = res.data
  701. })
  702. },
  703. // #ifdef H5 || MP
  704. onCollage() {
  705. if (!this.isLogin) {
  706. return toLogin();
  707. }
  708. hasCollage().then(res => {
  709. const collageId = res.data.collageId;
  710. if (collageId) {
  711. uni.navigateTo({
  712. url: `/pages/store/group_buy/index?collage_id=${collageId}`
  713. });
  714. } else {
  715. this.collageVisible = true;
  716. }
  717. });
  718. },
  719. onCollageClose() {
  720. this.collageVisible = false;
  721. },
  722. initCollage() {
  723. let data = {
  724. store_id: this.collageStore.id,
  725. address_id: this.collageAddress.id || 0,
  726. shipping_type: this.collageDelivery == 1 ? 3 : 2
  727. };
  728. initCollage(data).then(res => {
  729. this.collageVisible = false;
  730. uni.navigateTo({
  731. url: `/pages/store/group_buy/index?collage_id=${res.data.collageId}`
  732. });
  733. }).catch(err => {
  734. this.$util.Tips({
  735. title: err
  736. });
  737. });
  738. },
  739. collageDeliveryChange(item, index) {
  740. if (item.key != 2 || this.info.is_store) {
  741. this.collageDelivery = item.key;
  742. this.collageIndex = index;
  743. }
  744. },
  745. onAddressChange(data) {
  746. isWithin({
  747. store_id: this.collageStore.id,
  748. address_id: data.id
  749. }).then(() => {
  750. this.addressId = data.id;
  751. }).catch(() => {
  752. this.$util.Tips({
  753. title: '您选择的地址超出门店配送范围,请重新选择'
  754. });
  755. });
  756. },
  757. // #endif
  758. // 生成订单;
  759. subOrder: function() {
  760. let that = this,
  761. list = that.cartData.cartList,
  762. ids = [];
  763. if (list.length) {
  764. list.forEach(item => {
  765. if (item.attrStatus && item.status) {
  766. ids.push(item.id)
  767. }
  768. });
  769. uni.navigateTo({
  770. url: '/pages/goods/order_confirm/index?is_store=1&cartId=' + ids.join(',') + '&delivery_type=' + that.delivery_type + '&store_id=' + that.info.id
  771. });
  772. that.cartData.iScart = false;
  773. } else {
  774. return that.$util.Tips({
  775. title: '请选择产品'
  776. });
  777. }
  778. },
  779. // 计算总价;
  780. getTotalPrice: function() {
  781. let that = this,
  782. list = that.cartData.cartList,
  783. totalPrice = 0.00;
  784. list.forEach(item => {
  785. if (item.attrStatus && item.status) {
  786. totalPrice = that.$util.$h.Add(totalPrice, that.$util.$h.Mul(item.cart_num, item
  787. .truePrice));
  788. }
  789. })
  790. // if(num){
  791. // data.forEach(item => {
  792. // totalPrice = that.$util.$h.Sub(totalPrice, that.$util.$h.Mul(item.cart_num, item.sum_price));
  793. // })
  794. // }
  795. that.$set(that, 'totalPrice', totalPrice);
  796. },
  797. getCartLists(iSshow) {
  798. if (this.footerOpen) {
  799. this.getCartList();
  800. } else {
  801. this.footerOpen = true;
  802. }
  803. },
  804. getCartList(iSshow) {
  805. let that = this;
  806. let data = {
  807. store_id: that.info.id
  808. };
  809. vcartList(data).then(res => {
  810. that.$set(that.cartData, 'cartList', res.data);
  811. if (res.data.length) {
  812. that.$set(that.cartData, 'iScart', iSshow ? false : !that.cartData.iScart);
  813. } else {
  814. that.$set(that.cartData, 'iScart', false);
  815. }
  816. that.getTotalPrice();
  817. })
  818. },
  819. // 商品详情接口;
  820. getAttrs(id) {
  821. let that = this;
  822. getAttr(id, 0).then(res => {
  823. // uni.hideLoading();
  824. that.$set(that.attr, 'productAttr', res.data.productAttr);
  825. that.$set(that, 'productValue', res.data.productValue);
  826. that.$set(that, 'is_vip', res.data.storeInfo.is_vip);
  827. that.$set(that, 'storeInfo', res.data.storeInfo);
  828. that.DefaultSelect();
  829. })
  830. },
  831. moreNav() {
  832. this.currentPage = !this.currentPage;
  833. },
  834. goodsListScroll() {
  835. this.footerOpen = false;
  836. this.currentPage = false;
  837. },
  838. getCartNum: function() {
  839. let that = this;
  840. getCartCounts(0, that.info.id).then(res => {
  841. this.$store.commit('indexData/setCartNum', res.data.count)
  842. });
  843. },
  844. closeList(e) {
  845. this.$set(this.cartData, 'iScart', e);
  846. },
  847. getAddressList() {
  848. getAddressList({
  849. page: 1,
  850. limit: 100
  851. }).then(res => {
  852. let addressList = res.data;
  853. this.addressList = addressList;
  854. })
  855. }
  856. }
  857. }
  858. </script>
  859. <style lang="scss">
  860. .container {}
  861. .activeColor {
  862. color: var(--view-theme) !important;
  863. }
  864. .headerBg {
  865. position: absolute;
  866. top: 0;
  867. left: 0;
  868. width: 100%;
  869. .image {
  870. position: absolute;
  871. top: 0;
  872. left: 0;
  873. width: 100%;
  874. height: 100%;
  875. }
  876. .shade {
  877. position: absolute;
  878. top: 0;
  879. left: 0;
  880. width: 100%;
  881. height: 100%;
  882. background: linear-gradient(180deg, rgba(0, 0, 0, 0.4047) 0%, #F5F5F5 100%);
  883. }
  884. }
  885. .nav-box {
  886. height: 98rpx;
  887. }
  888. .nav {
  889. top: 0;
  890. right: 0;
  891. left: 0;
  892. z-index: 10;
  893. height: 98rpx;
  894. font-size: 30rpx;
  895. color: #666666;
  896. background: #F5F5F5;
  897. &.fixed {
  898. background: #FFFFFF;
  899. }
  900. .iconfont {
  901. margin-left: 6rpx;
  902. vertical-align: middle;
  903. font-size: 14rpx;
  904. }
  905. .icon-ic_sort {
  906. margin-left: 8rpx;
  907. font-size: 28rpx;
  908. }
  909. }
  910. .list {
  911. padding: 0 20rpx;
  912. background: #F5F5F5;
  913. }
  914. .list .waterList {
  915. margin-bottom: 60rpx;
  916. }
  917. .default {
  918. padding: 0 20rpx;
  919. }
  920. .input-wrapper {
  921. position: relative;
  922. height: 78rpx;
  923. padding: 0 24rpx;
  924. .input {
  925. flex: 1;
  926. min-width: 0;
  927. height: 58rpx;
  928. padding-left: 24rpx;
  929. border-radius: 29rpx;
  930. background: rgba(255, 255, 255, 0.2);
  931. font-size: 24rpx;
  932. color: #FFFFFF;
  933. .iconfont {
  934. margin-right: 16rpx;
  935. font-size: 32rpx;
  936. }
  937. }
  938. .group-btn {
  939. width: 80rpx;
  940. height: 64rpx;
  941. border-radius: 50%;
  942. margin-left: 16rpx;
  943. .img {
  944. width: 100%;
  945. height: 100%;
  946. }
  947. }
  948. }
  949. /* #ifdef H5 || MP */
  950. .dialog {
  951. padding: 44rpx 20rpx 0;
  952. padding-bottom: constant(safe-area-inset-bottom);
  953. padding-bottom: env(safe-area-inset-bottom);
  954. border-radius: 40rpx 40rpx 0 0;
  955. background: linear-gradient(180deg, #F5F5F5 0%, #F5F5F5 0%, #FFFFFF 100%);
  956. }
  957. .dialog-head {
  958. padding: 0 24rpx;
  959. font-weight: 500;
  960. font-size: 32rpx;
  961. color: #333333;
  962. .btn {
  963. width: 40rpx;
  964. height: 40rpx;
  965. cursor: pointer;
  966. .iconfont {
  967. font-size: 40rpx;
  968. color: #BBBBBB;
  969. }
  970. }
  971. }
  972. .dialog-body {
  973. margin-top: 48rpx;
  974. .navbar {
  975. flex-shrink: 0;
  976. position: relative;
  977. height: 82rpx;
  978. .navbar-bg {
  979. position: absolute;
  980. top: 0;
  981. left: 0;
  982. width: 100%;
  983. height: 190rpx;
  984. border-radius: 16rpx 16rpx 0 0;
  985. background: #EEEEEE;
  986. }
  987. .active-bg {
  988. position: absolute;
  989. bottom: 0;
  990. left: 0;
  991. width: 100%;
  992. height: 96rpx;
  993. .image1 {
  994. width: 50%;
  995. height: 100%;
  996. }
  997. .image2 {
  998. width: 48rpx;
  999. height: 78rpx;
  1000. }
  1001. }
  1002. .inner {
  1003. position: absolute;
  1004. bottom: 0;
  1005. left: 0;
  1006. width: 100%;
  1007. height: 100%;
  1008. .item {
  1009. flex: 1;
  1010. min-width: 0;
  1011. font-size: 28rpx;
  1012. line-height: 44rpx;
  1013. color: #666666;
  1014. .iconfont {
  1015. display: none;
  1016. margin-right: 8rpx;
  1017. font-size: 36rpx;
  1018. }
  1019. &.on {
  1020. font-weight: 500;
  1021. font-size: 32rpx;
  1022. color: var(--view-theme);
  1023. .iconfont {
  1024. display: inline-block;
  1025. }
  1026. }
  1027. }
  1028. }
  1029. }
  1030. .dialog-content {
  1031. position: relative;
  1032. border-radius: 0 0 16rpx 16rpx;
  1033. background: #FFFFFF;
  1034. &.btl {
  1035. border-top-left-radius: 24rpx;
  1036. }
  1037. &.btr {
  1038. border-top-right-radius: 24rpx;
  1039. }
  1040. .link {
  1041. padding: 40rpx 32rpx;
  1042. font-size: 22rpx;
  1043. line-height: 30rpx;
  1044. color: #999999;
  1045. .title {
  1046. margin-bottom: 16rpx;
  1047. font-weight: 500;
  1048. font-size: 28rpx;
  1049. line-height: 40rpx;
  1050. color: #333333;
  1051. }
  1052. .iconfont {
  1053. font-size: 32rpx;
  1054. }
  1055. }
  1056. }
  1057. .address-box {
  1058. height: 388rpx;
  1059. .list {
  1060. padding: 36rpx 32rpx;
  1061. background-color: transparent;
  1062. }
  1063. .item {
  1064. margin-top: 32rpx;
  1065. color: #333333;
  1066. &:first-child {
  1067. margin-top: 0;
  1068. }
  1069. .text {
  1070. flex: 1;
  1071. }
  1072. .info {
  1073. font-weight: 500;
  1074. font-size: 28rpx;
  1075. line-height: 40rpx;
  1076. }
  1077. .name {
  1078. margin-top: 8rpx;
  1079. font-size: 22rpx;
  1080. line-height: 30rpx;
  1081. color: #999999;
  1082. }
  1083. .iconfont {
  1084. visibility: hidden;
  1085. font-size: 36rpx;
  1086. }
  1087. &.on {
  1088. color: var(--view-theme);
  1089. .name {
  1090. color: var(--view-theme);
  1091. }
  1092. .iconfont {
  1093. visibility: visible;
  1094. }
  1095. }
  1096. }
  1097. }
  1098. .btn-box {
  1099. height: 88rpx;
  1100. font-size: 24rpx;
  1101. line-height: 34rpx;
  1102. color: #666666;
  1103. .iconfont {
  1104. margin-left: 4rpx;
  1105. font-size: 24rpx;
  1106. }
  1107. }
  1108. .store-box {
  1109. padding: 40rpx 28rpx 40rpx 32rpx;
  1110. .text {
  1111. flex: 1;
  1112. }
  1113. .name {
  1114. font-weight: 500;
  1115. font-size: 28rpx;
  1116. line-height: 40rpx;
  1117. color: #333333;
  1118. }
  1119. .info {
  1120. margin-top: 16rpx;
  1121. font-size: 22rpx;
  1122. line-height: 30rpx;
  1123. color: #999999;
  1124. }
  1125. .value {
  1126. flex: 1;
  1127. }
  1128. .iconfont {
  1129. margin-right: 12rpx;
  1130. font-size: 22rpx;
  1131. }
  1132. .map-box {
  1133. position: relative;
  1134. width: 188rpx;
  1135. height: 104rpx;
  1136. margin-left: 32rpx;
  1137. .map {
  1138. width: 100%;
  1139. height: 100%;
  1140. }
  1141. .img-box {
  1142. position: absolute;
  1143. bottom: 16rpx;
  1144. left: 50%;
  1145. width: 52rpx;
  1146. height: 52rpx;
  1147. padding: 6rpx;
  1148. border-radius: 6rpx;
  1149. background: #FFFFFF;
  1150. box-shadow: 0rpx 0rpx 12rpx 0rpx rgba(0, 0, 0, 0.0784);
  1151. transform: translateX(-50%);
  1152. }
  1153. .img {
  1154. width: 100%;
  1155. height: 100%;
  1156. border-radius: 6rpx;
  1157. }
  1158. .range {
  1159. position: absolute;
  1160. top: -40rpx;
  1161. left: 50%;
  1162. height: 36rpx;
  1163. padding: 0 16rpx;
  1164. border-radius: 6rpx;
  1165. background: #FFFFFF;
  1166. box-shadow: 0rpx 0rpx 16rpx 0rpx rgba(0, 0, 0, 0.0784);
  1167. transform: translateX(-50%);
  1168. white-space: nowrap;
  1169. font-size: 20rpx;
  1170. line-height: 36rpx;
  1171. color: #333333;
  1172. &::after {
  1173. content: "";
  1174. position: absolute;
  1175. bottom: 0;
  1176. left: 50%;
  1177. width: 0;
  1178. height: 0;
  1179. border-width: 5rpx 9rpx;
  1180. border-style: solid;
  1181. border-color: #FFFFFF transparent transparent;
  1182. transform: translate(-50%, 100%);
  1183. }
  1184. }
  1185. .dot {
  1186. position: absolute;
  1187. bottom: -10rpx;
  1188. left: 50%;
  1189. width: 6rpx;
  1190. height: 6rpx;
  1191. border-radius: 50%;
  1192. background: var(--view-theme);
  1193. transform: translateX(-50%);
  1194. }
  1195. }
  1196. }
  1197. }
  1198. .dialog-foot {
  1199. padding: 20rpx 0;
  1200. .btn {
  1201. height: 72rpx;
  1202. border-radius: 36rpx;
  1203. background: var(--view-theme);
  1204. text-align: center;
  1205. font-weight: 500;
  1206. font-size: 26rpx;
  1207. line-height: 72rpx;
  1208. color: #FFFFFF;
  1209. }
  1210. }
  1211. /* #endif */
  1212. .page {
  1213. position: relative;
  1214. }
  1215. .store-section {
  1216. padding: 20rpx;
  1217. .panel {
  1218. padding: 0 32rpx 32rpx;
  1219. border-radius: 16rpx;
  1220. background: #FFFFFF;
  1221. }
  1222. .store-name {
  1223. height: 92rpx;
  1224. .name-wrap {
  1225. flex: 1;
  1226. min-width: 0;
  1227. }
  1228. .name-inner {
  1229. display: inline-flex;
  1230. max-width: 100%;
  1231. }
  1232. .name {
  1233. flex: 1;
  1234. min-width: 0;
  1235. margin: 0 8rpx 0 10rpx;
  1236. font-weight: 500;
  1237. font-size: 30rpx;
  1238. color: #333333;
  1239. }
  1240. .iconfont {
  1241. font-size: 32rpx;
  1242. color: #333333;
  1243. }
  1244. .tips {
  1245. font-size: 24rpx;
  1246. color: var(--view-theme);
  1247. }
  1248. }
  1249. .address-wrap {
  1250. .address-box {
  1251. flex: 1;
  1252. min-width: 0;
  1253. font-size: 22rpx;
  1254. color: #666666;
  1255. }
  1256. .address-info {
  1257. margin-top: 20rpx;
  1258. line-height: 34rpx;
  1259. }
  1260. .distance {
  1261. position: relative;
  1262. padding-right: 12rpx;
  1263. margin-right: 12rpx;
  1264. &::after {
  1265. content: "";
  1266. position: absolute;
  1267. top: 50%;
  1268. right: 0;
  1269. width: 1rpx;
  1270. height: 18rpx;
  1271. background: #CCCCCC;
  1272. transform: translateY(-50%);
  1273. }
  1274. }
  1275. .btn {
  1276. position: relative;
  1277. padding-left: 24rpx;
  1278. margin-left: 24rpx;
  1279. text-align: center;
  1280. font-size: 20rpx;
  1281. color: #333333;
  1282. &::before {
  1283. content: "";
  1284. position: absolute;
  1285. top: 50%;
  1286. left: 0;
  1287. width: 2rpx;
  1288. height: 24rpx;
  1289. background: #EEEEEE;
  1290. transform: translateY(-50%);
  1291. }
  1292. &:first-child::before {
  1293. display: none;
  1294. }
  1295. .iconfont {
  1296. display: inline-block;
  1297. margin-bottom: 8rpx;
  1298. font-size: 40rpx;
  1299. }
  1300. }
  1301. }
  1302. .switch {
  1303. width: 192rpx;
  1304. height: 48rpx;
  1305. background: #F5F5F5;
  1306. border-radius: 24rpx;
  1307. .btn {
  1308. width: 96rpx;
  1309. height: 48rpx;
  1310. border-radius: 24rpx;
  1311. text-align: center;
  1312. font-size: 24rpx;
  1313. line-height: 48rpx;
  1314. color: #999999;
  1315. &.on {
  1316. background: var(--view-theme);
  1317. color: #FFFFFF;
  1318. }
  1319. }
  1320. }
  1321. }
  1322. .line-left {
  1323. position: absolute;
  1324. top: 50%;
  1325. left: 0;
  1326. width: 1rpx;
  1327. height: 26rpx;
  1328. background: #CCCCCC;
  1329. transform: translateY(-50%);
  1330. }
  1331. .filter-btn {
  1332. position: relative;
  1333. padding: 0 32rpx;
  1334. }
  1335. </style>