cm-goods-nav.vue 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. <template>
  2. <view>
  3. <view class="cm-goods-nav" :class="{ hasBottom: isIphoneX }">
  4. <!-- 导航按钮 -->
  5. <uni-goods-nav
  6. :fill="true"
  7. :options="options"
  8. :buttonGroup="buttonGroup"
  9. @click="onClick"
  10. @buttonClick="buttonClick"
  11. :navType="navType"
  12. />
  13. </view>
  14. <cm-drawer :visible="countVisible" @close="drawerClose" position="bottom">
  15. <view class="count">
  16. <view class="top">
  17. <image :src="productInfo.mainImage" class="cover"></image>
  18. <view class="right">
  19. <view class="number">
  20. <text>数量:</text>
  21. <cm-number-box v-model="count" :min="1" :max="maxCount" :defaultVal="count"></cm-number-box>
  22. </view>
  23. <view class="single-price">
  24. <text>单价:¥</text> <text class="price">{{ buyRetailPrice | formatPrice }}</text>
  25. </view>
  26. </view>
  27. </view>
  28. <view class="btn" @click="confirm">确认</view>
  29. </view>
  30. </cm-drawer>
  31. </view>
  32. </template>
  33. <script>
  34. import CmDrawer from '@/components/cm-module/cm-drawer/cm-drawer.vue'
  35. import NumberBox from '@/components/cm-module/cm-cart-product/number-box.vue'
  36. import CmNumberBox from '@/components/cm-module/cm-number-box/cm-number-box.vue'
  37. import { mapGetters, mapActions, mapMutations } from 'vuex'
  38. export default {
  39. components: {
  40. NumberBox,
  41. CmDrawer,
  42. CmNumberBox
  43. },
  44. props: {
  45. productInfo: {
  46. type: Object,
  47. default: () => {}
  48. }
  49. },
  50. data() {
  51. return {
  52. count: 1,
  53. navType: 1,
  54. countVisible: false,
  55. // 购买类型: 0:正常价格购买 1:拼团价购买
  56. handleClickType : 0,
  57. options: [
  58. {
  59. icon: 'home',
  60. text: '首页'
  61. },
  62. {
  63. icon: 'headphones',
  64. text: '客服',
  65. type: 'contact'
  66. },
  67. {
  68. icon: 'cart',
  69. text: '购物车',
  70. info: 0,
  71. infoBackgroundColor: '#FC464C',
  72. infoColor: '#ffffff'
  73. }
  74. ],
  75. leftButton: {
  76. text: '加入购物车',
  77. price: 0,
  78. backgroundColor: '#FFEFF4',
  79. color: '#FF457B'
  80. },
  81. rightButton: {
  82. text: '立即购买',
  83. price: 0,
  84. backgroundColor: 'linear-gradient(90deg, #FC32B4 0%, #F83C6C 100%)',
  85. color: '#fff'
  86. }
  87. }
  88. },
  89. computed: {
  90. ...mapGetters(['isIphoneX', 'kindCount', 'hasLogin']),
  91. buttonGroup() {
  92. return [this.leftButton, this.rightButton]
  93. },
  94. // 最终购买价格
  95. buyRetailPrice() {
  96. return this.processPrice()
  97. },
  98. collageProduct(){
  99. return this.productInfo.collageProduct || {}
  100. },
  101. maxCount(){
  102. // unlimitedFlag 0 限购 1 不限购 handleClickType : 0 单独购买 1 拼团购买
  103. if(this.collageProduct.unlimitedFlag === 0 && this.handleClickType === 1){
  104. return this.collageProduct.limitedNum
  105. }else{
  106. return this.productInfo.stock
  107. }
  108. }
  109. },
  110. watch: {
  111. kindCount(newCount) {
  112. this.options[2].info = newCount
  113. },
  114. productInfo: {
  115. deep: true,
  116. handler: function(nVal) {
  117. this.navType = this.productInfo.collageStatus === 1 ? 2 : 1
  118. this.resetButtonInfo()
  119. }
  120. },
  121. count(nVal){
  122. console.log(nVal)
  123. }
  124. },
  125. created() {
  126. this.options[2].info = this.kindCount
  127. },
  128. methods: {
  129. ...mapActions('cart', ['addToCart', 'getCartNumber']),
  130. // 处理购买按钮信息
  131. resetButtonInfo() {
  132. // 导航类型1
  133. if (this.navType === 1) {
  134. this.leftButton.text = '加入购物车'
  135. this.rightButton.text = '立即购买'
  136. }
  137. // 导航类型2
  138. if (this.navType === 2) {
  139. this.leftButton.text = '单独购买'
  140. this.leftButton.price = this.productInfo.normalPrice
  141. this.rightButton.text = '拼团购买'
  142. this.rightButton.price = this.productInfo.price
  143. }
  144. },
  145. countChange(value) {
  146. this.count = value
  147. },
  148. drawerClose() {
  149. this.countVisible = false
  150. this.count = 1
  151. },
  152. // 左边按钮
  153. onClick(e) {
  154. const clickFns = {
  155. 0: this.toHome,
  156. 1: this.customer,
  157. 2: this.toCart
  158. }
  159. clickFns[e.index]()
  160. },
  161. // 右边按钮
  162. buttonClick(e) {
  163. this.countVisible = true
  164. this.handleClickType = e.index
  165. },
  166. // 确认操作
  167. confirm() {
  168. this.countVisible = false
  169. // 判断登录
  170. if (!this.hasLogin) return this.toLogin()
  171. // 导航类型1
  172. if(this.navType === 1){
  173. const clickFns = {
  174. 0: this.joinCart,
  175. 1: this.buyNow
  176. }
  177. clickFns[this.handleClickType]()
  178. }
  179. // 导航类型2
  180. if(this.navType === 2){
  181. const clickFns = {
  182. 0: this.buyNow,
  183. 1: this.buyGroupNow
  184. }
  185. clickFns[this.handleClickType]()
  186. }
  187. },
  188. // 立即购买
  189. buyNow() {
  190. let productStp = {
  191. allPrice: this.count * this.buyRetailPrice,
  192. allCount: this.count,
  193. productId: this.productInfo.productId,
  194. productCount: this.count,
  195. heUserId: this.productInfo.heUserId,
  196. collageFlag: 0
  197. }
  198. uni.setStorageSync('commitProductInfo', productStp)
  199. this.countVisible = false
  200. this.toCreateOrder()
  201. },
  202. // 拼团购买
  203. buyGroupNow(){
  204. console.log('拼团购买')
  205. let productStp = {
  206. allPrice: this.count * this.buyRetailPrice,
  207. allCount: this.count,
  208. productId: this.productInfo.productId,
  209. productCount: this.count,
  210. heUserId: this.productInfo.heUserId,
  211. collageFlag: 1
  212. }
  213. uni.setStorageSync('commitProductInfo', productStp)
  214. this.countVisible = false
  215. this.toCreateOrder()
  216. },
  217. // 跳转到创建订单
  218. toCreateOrder() {
  219. this.$api.navigateTo('/pages/order/order-create?type=prodcut')
  220. },
  221. // 跳转首页
  222. toHome() {
  223. uni.switchTab({ url: '/pages/tabBar/index/index' })
  224. },
  225. // 客服
  226. customer() {
  227. console.log(this)
  228. },
  229. // 去登陆
  230. toLogin() {
  231. uni.navigateTo({ url: '/pages/authorize/login' })
  232. },
  233. // 去购物车
  234. toCart() {
  235. uni.navigateTo({ url: '/pages/goods/cart' })
  236. },
  237. // 加入购物车
  238. joinCart() {
  239. this.addToCart({
  240. productId: this.productInfo.productId,
  241. productCount: this.count
  242. }).finally(() => {
  243. this.countVisible = false
  244. })
  245. },
  246. //处理最终的购买价格
  247. processPrice() {
  248. // 拼团价
  249. if(this.productInfo.collageStatus === 1){
  250. // 购买方式为拼团购买
  251. if(this.handleClickType === 1){
  252. return this.productInfo.price
  253. }
  254. // 购买方式为正常价购买
  255. if(this.handleClickType === 0){
  256. return this.productInfo.normalPrice
  257. }
  258. }
  259. // 活动价
  260. if (this.productInfo.activeStatus === 1 && this.productInfo.ladderList) {
  261. let buyPrice = this.productInfo.price
  262. // 过滤出符合的优惠价
  263. const findList = this.productInfo.ladderList.forEach(item=>{
  264. if(this.count >= item.buyNum) buyPrice = item.buyPrice
  265. })
  266. return buyPrice
  267. }
  268. // 其它价格
  269. return this.productInfo.price
  270. }
  271. }
  272. }
  273. </script>
  274. <style lang="scss" scoped>
  275. .cm-goods-nav {
  276. position: fixed;
  277. width: 100%;
  278. bottom: 0;
  279. left: 0;
  280. background: #fff;
  281. &.hasBottom {
  282. padding-bottom: 44rpx;
  283. }
  284. }
  285. .count {
  286. padding: 60rpx 0;
  287. .top {
  288. display: flex;
  289. justify-content: flex-start;
  290. align-items: center;
  291. padding: 0 60rpx;
  292. .cover {
  293. width: 104rpx;
  294. height: 104rpx;
  295. }
  296. .right {
  297. margin-left: 24rpx;
  298. font-size: 24rpx;
  299. color: #333;
  300. .single-price {
  301. color: #ff457b;
  302. margin-top: 24rpx;
  303. }
  304. .number {
  305. display: flex;
  306. justify-content: flex-start;
  307. align-items: center;
  308. }
  309. }
  310. }
  311. .btn {
  312. width: 100%;
  313. height: 88rpx;
  314. margin-top: 32px;
  315. background: #ff457b;
  316. line-height: 88rpx;
  317. text-align: center;
  318. color: #ffffff;
  319. font-size: 28rpx;
  320. border-radius: 44rpx;
  321. }
  322. }
  323. </style>