quick-shop.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. <template>
  2. <app-layout>
  3. <view class="app-quick-shop dir-left-nowrap">
  4. <view class="app-left" :style="{height: `calc(100% - 136rpx - ${tabbarbool ? botHeight : 0}rpx)`}">
  5. <scroll-view scroll-y class="app-quick-scroll">
  6. <view class="app-text" v-for="(item, index) in classification" :class="{'app-active-bk': activeIndex === index}" :key="index">
  7. <app-form-id @click="active(item,index)">
  8. <text class="app-text-text">{{item.name}}</text>
  9. </app-form-id>
  10. </view>
  11. </scroll-view>
  12. <view class="app-cart">
  13. <view class="app-icon image-no-rep image-cover" @click="pushSelectProduct()">
  14. <app-jump-button form url="/pages/cart/cart">
  15. <text class="app-active-num" v-if="activeNum !== '0' || activeNum === 0">{{activeNum}}</text>
  16. </app-jump-button>
  17. </view>
  18. </view>
  19. </view>
  20. <view class="app-right" :style="{height: `calc(100% - ${tabbarbool ? botHeight : 0}rpx)`}">
  21. <text class="app-active-name">{{activeName}}</text>
  22. <scroll-view scroll-y class="app-scroll-right"
  23. :style="{height: `calc(100% - 102rpx)`}"
  24. :scroll-top="scrollTop" @scrolltolower="scrolltolower" >
  25. <view class="app-request">
  26. <view class="app-item-item" v-for="(item, index) in list" :key="index" >
  27. <app-form-id >
  28. <view class="app-item dir-left-nowrap cross-top" >
  29. <image class="app-image" lazy-load :src="item.cover_pic" @click.stop="jumpGo(item)"></image>
  30. <view class="out-dialog" v-if="item.goods_num == 0 && appSetting.is_show_stock == '1'">
  31. <image :src="appSetting.is_use_stock == '1' ? appImg.plugins_out : appSetting.sell_out_pic"></image>
  32. </view>
  33. <view class="app-content dir-top-nowrap main-left">
  34. <view class="app-top" @click.stop="jumpGo(item)">
  35. {{item.name}}
  36. </view>
  37. <view class="app-volume">
  38. 销量 {{item.virtual_sales}}
  39. </view>
  40. <view class="dir-top-nowrap" style="padding: 10rpx 0;">
  41. <view v-if="item.is_level == 1">
  42. <app-member-price :price="item.level_price"></app-member-price>
  43. </view>
  44. <app-sup-vip :is_vip_card_user="item.vip_card_appoint.is_vip_card_user" margin="4rpx 0 0" v-if="item.vip_card_appoint.discount > 0" :discount="item.vip_card_appoint.discount"></app-sup-vip>
  45. <view class="app-bottom dir-left-nowrap main-between">
  46. <view class="app-price">
  47. <text class="app-symbol">¥</text>
  48. {{item.price}}
  49. </view>
  50. <app-add-subtract :item="item" v-if="item.use_attr == '0' && item.goods_num > 0" @changeNum="changeNum" @subtract="subtract" @add="add" :total_num="item.total_num" ></app-add-subtract>
  51. <view class="app-button" v-if="item.use_attr == '1' && item.goods_num > 0">
  52. <app-button @click="specification(item)" padding="0 16rpx" type="important" roundSize="22rpx" fontSize="24" background="#ff4544" height="44" >选规格</app-button>
  53. </view>
  54. <view class="app-num" v-if="item.use_attr === '1' && item.total_num !== 0">{{item.total_num}}</view>
  55. </view>
  56. </view>
  57. </view>
  58. </view>
  59. </app-form-id>
  60. </view>
  61. </view>
  62. </scroll-view>
  63. </view>
  64. <app-attr ref="attr" v-if="item.use_attr == '1'" :goods="item" :select-attr="selectAttr" :attr-group-list="attrGroup" :show="show" @selectNumber="selectNumber" @attrtap="onAttr"></app-attr>
  65. </view>
  66. </app-layout>
  67. </template>
  68. <script>
  69. import { mapState, mapGetters } from 'vuex';
  70. import appAddSubtract from './components/app-add-subtract/app-add-subtract.vue';
  71. import appAttr from '../../components/page-component/app-attr/app-attr.vue';
  72. import appLoadText from '../../components/basic-component/app-load-text/app-load-text.vue';
  73. import appMemberPrice from "../../components/page-component/app-member-mark/app-member-price.vue";
  74. import appSupVip from "../../components/page-component/app-sup-vip/app-sup-vip.vue";
  75. export default {
  76. name: "quick-shop",
  77. components: {
  78. 'app-add-subtract': appAddSubtract,
  79. 'app-attr': appAttr,
  80. 'app-load-text': appLoadText,
  81. 'app-member-price': appMemberPrice,
  82. 'app-sup-vip': appSupVip,
  83. },
  84. computed: {
  85. ...mapState({
  86. tabBarNavs: state => state.mallConfig.navbar.navs,
  87. appSetting: state => state.mallConfig.mall.setting,
  88. appImg: state => state.mallConfig.__wxapp_img.mall,
  89. }),
  90. ...mapGetters('iPhoneX',{
  91. botHeight: 'getBotHeight',
  92. }),
  93. ...mapGetters('mallConfig',{
  94. getVideo: 'getVideo'
  95. }),
  96. },
  97. data() {
  98. return {
  99. activeNum: '',
  100. classification: [],
  101. activeIndex: 0,
  102. activeName: '',
  103. list: [],
  104. attrGroup: [],
  105. coverPic: '',
  106. spec: true,
  107. goodsNum: 0,
  108. item: null,
  109. selectAttr: {},
  110. show: 0,
  111. page: 1,
  112. over: false,
  113. tabbarbool: false,
  114. currentRoute: this.$platDiff.route(),
  115. activeId: '0',
  116. scrollTop: 0,
  117. old: {
  118. scrollTop: 0
  119. }
  120. }
  121. },
  122. methods: {
  123. request() {
  124. this.$request({
  125. url: `${this.$api.quick.goods_list}&page=${this.page}&cat_id=${this.activeId}is_sell_well=0 `,
  126. }).then(res => {
  127. if (res.code === 0) {
  128. if (res.data.list.length > 0) {
  129. this.list = [...this.list, ...res.data.list];
  130. } else {
  131. this.over = true;
  132. }
  133. }
  134. });
  135. },
  136. active(item, index) {
  137. this.scrollTop = 1;
  138. this.$nextTick(() => {
  139. this.scrollTop = 0
  140. });
  141. this.activeIndex = index;
  142. this.activeName = item.name;
  143. this.activeId = item.id;
  144. this.over = false;
  145. this.page = 1;
  146. this.pushSelectProduct().then(() => {
  147. this.$request({
  148. url: `${this.$api.quick.goods_list}&page=${this.page}&cat_id=${item.id}is_sell_well=0 `,
  149. }).then(res => {
  150. this.list = res.data.list;
  151. });
  152. });
  153. },
  154. specification(item) {
  155. this.attrGroup = item.attr_groups;
  156. this.item = item;
  157. this.show = Math.random();
  158. },
  159. selectNumber(data) {
  160. for (let i = 0; i < this.list.length; i++) {
  161. if (this.list[i].id === data.goods_id) {
  162. this.list[i].total_num += data.number;
  163. this.activeNum = Number(this.activeNum) + Number(data.number);
  164. }
  165. }
  166. },
  167. async pushSelectProduct() {
  168. let list = [];
  169. for (let key in this.selectAttr) {
  170. list.push(this.selectAttr[key]);
  171. }
  172. this.$request({
  173. url: this.$api.quick.cart,
  174. method: 'post',
  175. data: {
  176. list: JSON.stringify(list),
  177. }
  178. })
  179. },
  180. add(item) {
  181. for (let i = 0; i < this.list.length; i++) {
  182. if (this.list[i].id === item.id) {
  183. this.list[i].total_num += 1;
  184. this.activeNum = Number(this.activeNum) + 1;
  185. this.selectAttr[item.attr[0].id] = {
  186. attr: item.attr[0].id,
  187. num: this.list[i].total_num,
  188. goods_id: item.id,
  189. };
  190. }
  191. }
  192. },
  193. subtract(item) {
  194. for (let i = 0; i < this.list.length; i++) {
  195. if (this.list[i].id === item.id) {
  196. this.list[i].total_num -= 1;
  197. this.activeNum = Number(this.activeNum) - 1;
  198. this.selectAttr[item.attr[0].id] = {
  199. attr: item.attr[0].id,
  200. num: this.list[i].total_num,
  201. goods_id: item.id,
  202. };
  203. }
  204. }
  205. },
  206. changeNum(item, data) {
  207. for (let i = 0; i < this.list.length; i++) {
  208. if (this.list[i].id === item.id) {
  209. this.activeNum = Number(this.activeNum) - this.list[i].total_num;
  210. this.activeNum = Number(this.activeNum) + data;
  211. this.list[i].total_num = data;
  212. this.selectAttr[item.attr[0].id] = {
  213. attr: item.attr[0].id,
  214. num: this.list[i].total_num,
  215. goods_id: item.id,
  216. };
  217. }
  218. }
  219. },
  220. jumpGo(data) {
  221. console.log(data);
  222. // #ifndef MP-BAIDU
  223. if (data.video_url && this.getVideo == 1) {
  224. uni.navigateTo({
  225. url: `/pages/goods/video?goods_id=${data.id}`
  226. });
  227. } else {
  228. uni.navigateTo({
  229. url: `/pages/goods/goods?id=${data.id}`
  230. });
  231. }
  232. // #endif
  233. // #ifdef MP-BAIDU
  234. uni.navigateTo({
  235. url: `/pages/goods/goods?id=${data.id}`
  236. });
  237. // #endif
  238. },
  239. scrolltolower() {
  240. if (!this.over) {
  241. this.page++;
  242. this.request();
  243. }
  244. },
  245. b() {
  246. let currentRoute = this.currentRoute;
  247. for (let i = 0; i < this.tabBarNavs.length; i++) {
  248. if(currentRoute.includes(this.tabBarNavs[i].url.split('?')[0])) {
  249. return this.tabbarbool = true;
  250. }
  251. }
  252. return this.tabbarbool = false;
  253. },
  254. },
  255. onLoad() {
  256. this.$request({
  257. url: this.$api.quick.index
  258. }).then(response => {
  259. this.activeNum = `${response.data.count}`;
  260. let {name, id} = response.data.cats_list[this.activeIndex];
  261. this.activeName = name;
  262. this.activeId = id;
  263. this.classification = response.data.cats_list;
  264. this.$request({
  265. url: this.$api.quick.index,
  266. }).then(response => {
  267. this.activeNum = `${response.data.count}`;
  268. });
  269. this.$request({
  270. url: `${this.$api.quick.goods_list}&page=${this.page}&cat_id=${id}is_sell_well=0 `,
  271. }).then(response => {
  272. this.list = response.data.list;
  273. })
  274. })
  275. },
  276. onHide() {
  277. this.pushSelectProduct();
  278. },
  279. onUnload() {
  280. this.pushSelectProduct();
  281. },
  282. onShareAppMessage() {
  283. return this.$shareAppMessage({
  284. path: '/pages/quick-shop/quick-shop',
  285. title: this.$children[0].navigationBarTitle,
  286. });
  287. },
  288. watch: {
  289. tabBarNavs: {
  290. handler: function() {
  291. this.b();
  292. },
  293. immediate: true,
  294. }
  295. }
  296. }
  297. </script>
  298. <style scoped lang="scss">
  299. .app-quick-shop {
  300. position: absolute;
  301. height: 100%;
  302. width: $screen-width;
  303. .app-left {
  304. width: #{160rpx};
  305. .app-quick-scroll {
  306. width: 100%;
  307. height: 100%;
  308. background-color: #f3f3f3;
  309. .app-text {
  310. background-color: #f3f3f3;
  311. width: 100%;
  312. height: #{104rpx};
  313. line-height: #{104rpx};
  314. font-size: #{26rpx};
  315. color: #353535;
  316. .app-text-text {
  317. text-align: center;
  318. word-break: break-all;
  319. text-overflow: ellipsis;
  320. display: -webkit-box;
  321. -webkit-box-orient: vertical;
  322. -webkit-line-clamp: 1;
  323. overflow: hidden;
  324. }
  325. }
  326. .app-active-bk {
  327. background-color:white;
  328. }
  329. }
  330. .app-cart {
  331. width: #{160rpx};
  332. height: #{136rpx};
  333. background-color: #f3f3f3;
  334. .app-icon {
  335. width: #{96rpx};
  336. height: #{96rpx};
  337. margin: 0 #{32rpx} #{40rpx} #{32rpx};
  338. border-radius: 50%;
  339. box-shadow: #{0.1rpx} #{0.1rpx} #{5rpx} rgba(0,0,0,0.1);
  340. background-image: url("./image/cart-big.png");
  341. position: relative;
  342. }
  343. .app-active-num {
  344. position: absolute;
  345. top: #{26rpx};
  346. right: #{10rpx};
  347. background-color: #ff4544;
  348. border-radius: #{12rpx};
  349. font-size: #{18rpx};
  350. height: #{24rpx};
  351. line-height: #{24rpx};
  352. color: #FFFFFF;
  353. padding: 0 #{8rpx};
  354. }
  355. }
  356. }
  357. .app-right {
  358. width: calc(100% - #{160rpx});
  359. background-color: #ffffff;
  360. .app-active-name {
  361. display: inline-block;
  362. width: 100%;
  363. padding-top: #{40rpx};
  364. padding-bottom: #{36rpx};
  365. font-size: #{26rpx};
  366. color: #8c8c8c;
  367. padding-left: #{22rpx};
  368. }
  369. .app-scroll-right {
  370. .app-request {
  371. padding-top: #{1rpx};
  372. }
  373. .app-item-item {
  374. width: calc(100% - #{22rpx});
  375. margin-left: #{22rpx};
  376. margin-top: #{23rpx};
  377. }
  378. }
  379. .app-item {
  380. width: calc(100% - #{22rpx});
  381. border-bottom: #{1rpx} solid #e2e2e2;
  382. position: relative;
  383. .out-dialog {
  384. width: #{152rpx};
  385. height: #{152rpx};
  386. position: absolute;
  387. top: 0;
  388. left: 0;
  389. z-index: 10;
  390. background-color: rgba(0,0,0,.5);
  391. image {
  392. width: #{152rpx};
  393. height: #{152rpx};
  394. }
  395. }
  396. .app-image {
  397. height: #{152rpx};
  398. width: #{152rpx};
  399. margin-right: #{20rpx};
  400. }
  401. .app-content {
  402. width: calc(100% - #{192rpx} );
  403. min-height: #{152rpx};
  404. background-color: white;
  405. .app-top {
  406. width: 100%;
  407. padding-top: #{10rpx};
  408. font-size: #{28rpx};
  409. color: #353535;
  410. word-break: break-all;
  411. text-overflow: ellipsis;
  412. display: -webkit-box;
  413. -webkit-box-orient: vertical;
  414. -webkit-line-clamp: 2;
  415. overflow: hidden;
  416. }
  417. .app-volume {
  418. font-size: #{22rpx};
  419. color: #666666;
  420. margin-bottom: 2rpx;
  421. }
  422. .app-bottom {
  423. width: 100%;
  424. padding-bottom: #{16rpx};
  425. position: relative;
  426. .app-button {
  427. height: #{44rpx};
  428. }
  429. /deep/ button {
  430. text-align: center;
  431. width: #{104rpx};
  432. line-height: #{44rpx};
  433. }
  434. .app-price {
  435. font-size: #{28rpx};
  436. color: #f94748;
  437. .app-symbol {
  438. font-size: #{18rpx};
  439. }
  440. }
  441. .app-num {
  442. position: absolute;
  443. background-color: white;
  444. border: #{1rpx} solid #ff4544;
  445. border-radius: #{12rpx};
  446. height: #{24rpx};
  447. padding: 0 #{6rpx};
  448. top: #{-14rpx};
  449. right: #{15rpx};
  450. font-size: #{18rpx};
  451. line-height: #{24rpx};
  452. color: #ff4544;
  453. }
  454. }
  455. }
  456. }
  457. }
  458. }
  459. </style>