index.vue 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. <template>
  2. <view class="rf-product-list">
  3. <view class="rf-product-list-container">
  4. <block v-for="(item, index) in list" :key="index">
  5. <!--礼品列表-->
  6. <view
  7. v-if="(index + 1) % 2 !== 0 || isList"
  8. class="rf-product-item"
  9. @tap.stop="navTo(`/pages/product/product?id=${item.id}`)"
  10. :class="[isList ? 'rf-product-flex-list' : '']"
  11. hover-class="hover"
  12. :hover-start-time="150"
  13. >
  14. <view class="rf-product-image-wrapper">
  15. <image :src="item.picture" mode="widthFix" :preview="false" :class="[isList?'rf-product-list-img':'rf-product-img']" ></image>
  16. <text class="sketch in1line">{{ item.sketch }}</text>
  17. <view class="triangle-wrapper">
  18. <image class="triangle-tag" :src="item | filterTagName"></image>
  19. </view>
  20. </view>
  21. <view class="rf-pro-content">
  22. <view class="rf-pro-tit">{{ item.name }}</view>
  23. <view v-if="item">
  24. <view class="rf-pro-price">
  25. <text class="rf-sale-price" :class="'text-'+themeColor.name">{{ moneySymbol }}{{ item.price }}</text>
  26. <text class="rf-factory-price" v-if="item.market_price > item.price">{{ moneySymbol }}{{ item.market_price }}</text>
  27. </view>
  28. <view class="rf-pro-pay">
  29. <text
  30. ><text :class="'text-'+themeColor.name">{{
  31. item.total_sales | filterTotalSales
  32. }}</text>
  33. 人付款</text
  34. >
  35. <text
  36. @tap.stop="toggleSpec(item)"
  37. class="iconfont icongouwuche2"
  38. :class="'text-'+themeColor.name"
  39. ></text>
  40. </view>
  41. </view>
  42. </view>
  43. </view>
  44. <!--礼品列表-->
  45. </block>
  46. </view>
  47. <view class="rf-product-list-container" v-if="!isList">
  48. <block v-for="(item, index) in list" :key="index">
  49. <!--礼品列表-->
  50. <view
  51. v-if="(index + 1) % 2 === 0"
  52. class="rf-product-item"
  53. @tap.stop="navTo(`/pages/product/product?id=${item.id}`)"
  54. :class="[isList ? 'rf-product-flex-list' : '']"
  55. hover-class="hover"
  56. :hover-start-time="150"
  57. >
  58. <view class="rf-product-image-wrapper">
  59. <image :src="item.picture" mode="widthFix" :preview="false" :class="[isList?'rf-product-list-img':'rf-product-img']" ></image>
  60. <text class="sketch in1line">{{ item.sketch }}</text>
  61. <view class="triangle-wrapper" v-if="item.shipping_type === '1' || item.is_virtual === '1' || item.commissionRate || item.is_open_presell === '1'">
  62. <image class="triangle-tag" :src="item | filterTagName"></image>
  63. </view>
  64. </view>
  65. <view class="rf-pro-content">
  66. <view class="rf-pro-tit">{{ item.name }}</view>
  67. <view v-if="item">
  68. <view class="rf-pro-price">
  69. <text class="rf-sale-price" :class="'text-'+themeColor.name">{{ moneySymbol }}{{ item.price }}</text>
  70. <text class="rf-factory-price" v-if="item.market_price > item.price">{{ moneySymbol }}{{ item.market_price }}</text>
  71. </view>
  72. <view class="rf-pro-pay">
  73. <text
  74. ><text :class="'text-'+themeColor.name">{{
  75. item.total_sales | filterTotalSales
  76. }}</text>
  77. 付款</text
  78. >
  79. <text
  80. @tap.stop="toggleSpec(item)"
  81. :class="'text-'+themeColor.name"
  82. class="iconfont icongouwuche2"
  83. ></text>
  84. </view>
  85. </view>
  86. </view>
  87. </view>
  88. <!--礼品列表-->
  89. </block>
  90. </view>
  91. <!-- 规格-模态层弹窗 -->
  92. <view
  93. class="popup spec show"
  94. v-if="specClass === 'show'"
  95. @touchmove.stop.prevent="stopPrevent"
  96. @tap="hideSpec"
  97. >
  98. <!-- 遮罩层 -->
  99. <view class="mask" @tap="hideSpec"></view>
  100. <view class="layer" :style="{bottom: bottom ? `${bottom}upx` : 0}" @tap.stop="stopPrevent">
  101. <rf-attr-content
  102. :product="productDetail"
  103. @toggle="toggleSpec"
  104. :showBuyBtn="true"
  105. ></rf-attr-content>
  106. </view>
  107. </view>
  108. </view>
  109. </template>
  110. <script>
  111. /**
  112. * @des 礼品列表
  113. *
  114. * @author stav stavyan@qq.com
  115. * @date 2020-05-15 10:49
  116. */
  117. import { productDetail, cartItemCount, cartItemCreate } from '@/api/product';
  118. import rfAttrContent from '@/components/rf-attr-content';
  119. import $mAssetsPath from '@/config/assets.config';
  120. import { mapMutations } from 'vuex';
  121. export default {
  122. name: 'rfProductList',
  123. props: {
  124. list: {
  125. type: Array,
  126. default() {
  127. return [];
  128. }
  129. },
  130. // 是否以列表展示 | 列表或大图
  131. isList: {
  132. type: Boolean,
  133. default: false
  134. },
  135. // 是否以列表展示 | 列表或大图
  136. bottom: {
  137. type: Number,
  138. default: 0
  139. }
  140. },
  141. components: {
  142. rfAttrContent
  143. },
  144. data() {
  145. return {
  146. specClass: 'none',
  147. moneySymbol: this.moneySymbol,
  148. productDetail: {}
  149. };
  150. },
  151. filters: {
  152. filterTotalSales(val) {
  153. if (val > 10000) {
  154. val = `${(val / 10000).toFixed(2)}w`;
  155. }
  156. return val;
  157. },
  158. filterTagName(val) {
  159. if (val.commissionRate) {
  160. // 分销礼品
  161. return $mAssetsPath.distribution;
  162. } else if (val.is_virtual === '1') {
  163. // 虚拟产品
  164. return $mAssetsPath.virtual;
  165. } else if (val.shipping_type === '1') {
  166. // 包邮产品
  167. return $mAssetsPath.pinkage;
  168. }
  169. }
  170. },
  171. methods: {
  172. ...mapMutations(['setCartNum']),
  173. // 跳转详情
  174. navTo(route) {
  175. this.$mRouter.push({ route });
  176. },
  177. // 获取产品详情
  178. async getProductDetail(row) {
  179. await this.$http
  180. .get(`${productDetail}`, {
  181. id: row.id
  182. })
  183. .then(async r => {
  184. this.productDetail = await r.data;
  185. this.productDetail.sku_name = row.sku_name;
  186. this.specClass = 'show';
  187. });
  188. },
  189. // 规格弹窗开关
  190. toggleSpec(row) {
  191. if (parseInt(row.status, 10) === 0) return;
  192. if (this.specClass === 'show') {
  193. this.specClass = 'hide';
  194. if (row.stock === 0) {
  195. this.$mHelper.toast('库存不足');
  196. return;
  197. }
  198. if (row.type.toString() === '1') {
  199. // 加入购物车
  200. this.handleCartItemCreate(row.skuId, row.cartCount);
  201. } else if (row.type.toString() === '2') {
  202. // 立即购买
  203. const list = {};
  204. const data = {};
  205. data.sku_id = row.skuId;
  206. data.num = row.cartCount;
  207. if (
  208. this.productDetail.point_exchange_type.toString() === '2' ||
  209. this.productDetail.point_exchange_type.toString() === '4' ||
  210. (this.productDetail.point_exchange_type.toString() === '3' &&
  211. this.isPointExchange)
  212. ) {
  213. list.type = 'point_exchange';
  214. } else {
  215. list.type = 'buy_now';
  216. }
  217. list.data = JSON.stringify(data);
  218. this.navTo(`/pages/order/create/order?data=${JSON.stringify(list)}`);
  219. }
  220. setTimeout(() => {
  221. this.specClass = 'none';
  222. }, 250);
  223. } else if (this.specClass === 'none') {
  224. this.getProductDetail(row);
  225. }
  226. },
  227. stopPrevent() {},
  228. hideSpec() {
  229. this.specClass = 'hide';
  230. setTimeout(() => {
  231. this.specClass = 'none';
  232. }, 250);
  233. },
  234. // 添加礼品至购物车
  235. async handleCartItemCreate(skuId, cartCount) {
  236. await this.$http
  237. .post(`${cartItemCreate}`, {
  238. sku_id: skuId,
  239. num: cartCount
  240. })
  241. .then(async () => {
  242. await this.$http.get(`${cartItemCount}`).then(async r => {
  243. this.setCartNum(r.data);
  244. });
  245. this.$mHelper.toast('添加购物车成功');
  246. });
  247. }
  248. }
  249. };
  250. </script>