list.vue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. <template>
  2. <view class="container all-type-list-wrapper">
  3. <product-list ref="productList" @operationConfim="hanldOperationConfim"></product-list>
  4. <!--底部选择模态层弹窗组件 -->
  5. <view class="popup spec" :class="specClass" @tap="hideSpec">
  6. <!-- 遮罩层 -->
  7. <view class="mask"></view>
  8. <view class="layer">
  9. <view class="content">
  10. <view class="layer-smimg">
  11. <image :src="handleData.mainImage" mode=""></image>
  12. </view>
  13. <view class="layer-nunbox">
  14. <view class="layer-nunbox-b">
  15. <view class="text">
  16. <text class="p sm">¥</text>
  17. <text class="p bg">{{ buyRetailPrice.toFixed(2) }}</text>
  18. </view>
  19. </view>
  20. <view class="layer-nunbox-t">
  21. <view class="layer-nunbox-text">数量:</view>
  22. <view class="number-box">
  23. <view
  24. class="iconfont icon-jianhao"
  25. :class="[isQuantity == true ? 'disabled' : '']"
  26. @click="changeCountSub()"
  27. ></view>
  28. <input
  29. class="btn-input"
  30. type="number"
  31. v-model="number"
  32. maxlength="4"
  33. @blur="changeNumber($event)"
  34. />
  35. <view
  36. class="iconfont icon-jiahao"
  37. :class="[isStock == true ? 'disabled' : '']"
  38. @click="changeCountAdd()"
  39. ></view>
  40. </view>
  41. </view>
  42. </view>
  43. </view>
  44. <view class="btn">
  45. <view class="button add" @click="getAddProductCart">加入购物车</view>
  46. </view>
  47. </view>
  48. </view>
  49. </view>
  50. </template>
  51. <script>
  52. import productList from '@/components/cm-module/listTemplate/productList'
  53. export default {
  54. components: {
  55. productList
  56. },
  57. data() {
  58. return {
  59. userId: '',
  60. specClass: '', //规格弹窗css类,控制开关动画
  61. handleData: {},
  62. isQuantity: false,
  63. isStock: false,
  64. minBuyNumber: 0,
  65. number: 0,
  66. buyRetailPrice: 0,
  67. buyRetailPriceStep: 1
  68. }
  69. },
  70. onLoad() {
  71. // 获取机构id
  72. const clubInfo = uni.getStorageSync('clubInfo')
  73. this.userId = clubInfo.userId
  74. },
  75. methods: {
  76. //显示选择数量确认弹窗
  77. hanldOperationConfim(data) {
  78. this.specClass = 'show'
  79. this.handleData = data
  80. this.minBuyNumber = data.minBuyNumber
  81. this.buyRetailPrice = data.retailPrice
  82. this.buyRetailPriceStep = data.step
  83. if (this.handleData.ladderPriceFlag == '1') {
  84. this.number = data.maxBuyNumber
  85. } else {
  86. this.number = data.minBuyNumber
  87. }
  88. },
  89. //关闭选择数量确认弹窗
  90. hideSpec() {
  91. this.specClass = 'hide'
  92. setTimeout(() => {
  93. this.specClass = 'none'
  94. }, 200)
  95. },
  96. changeCountAdd() {
  97. //popup弹窗数量增加按钮
  98. if (this.buyRetailPriceStep == 2) {
  99. this.number += this.minBuyNumber
  100. } else {
  101. this.number++
  102. }
  103. this.calculatPerice()
  104. },
  105. changeCountSub() {
  106. //popup弹窗数量减按钮
  107. if (this.number <= this.minBuyNumber) {
  108. this.number = this.minBuyNumber
  109. this.isQuantity = true
  110. this.$util.msg(`该商品起订量为${this.minBuyNumber}`, 2000)
  111. return
  112. } else {
  113. if (this.buyRetailPriceStep == 2) {
  114. this.number -= this.minBuyNumber
  115. } else {
  116. this.number--
  117. }
  118. this.calculatPerice()
  119. this.isQuantity = false
  120. }
  121. },
  122. changeNumber(e) {
  123. let _value = e.detail.value
  124. if (!this.$api.isNumber(_value)) {
  125. this.number = this.minBuyNumber
  126. } else if (_value < this.minBuyNumber) {
  127. this.$util.msg(`该商品起订量为${this.minBuyNumber}`, 2000)
  128. this.number = this.minBuyNumber
  129. } else if (_value % this.minBuyNumber != 0) {
  130. this.$util.msg(`购买量必须为起订量的整数倍`, 2000)
  131. this.number = this.minBuyNumber
  132. } else {
  133. this.number = e.detail.value
  134. this.calculatPerice()
  135. }
  136. },
  137. //判断是否为阶梯价然后做计算价格处理
  138. calculatPerice() {
  139. if (this.handleData.ladderPriceFlag == '1') {
  140. this.handleData.ladderPriceList.forEach((item, index) => {
  141. if (this.number >= item.buyNum) {
  142. this.buyRetailPrice = item.buyPrice
  143. }
  144. })
  145. }
  146. },
  147. //增加购物车成功和toast弹窗提示成功
  148. getAddProductCart() {
  149. this.ProductService.shoppingAddCart({
  150. productId: this.handleData.productId,
  151. userId: this.userId,
  152. productCount: this.number
  153. })
  154. .then(response => {
  155. this.specClass = 'hide'
  156. this.$util.msg('加入购物车成功', 1500, true, 'success')
  157. setTimeout(() => {
  158. this.specClass = 'none'
  159. }, 500)
  160. this.$refs.productList.cartQuantity = response.data
  161. })
  162. .catch(error => {
  163. this.$util.msg(error.msg, 2000)
  164. })
  165. }
  166. }
  167. }
  168. </script>
  169. <style lang="scss">
  170. page {
  171. background: $sub-bg-color;
  172. .all-type-list-wrapper {
  173. display: flex;
  174. flex-direction: column;
  175. }
  176. }
  177. /* 加入购物模态层*/
  178. @keyframes showPopup {
  179. 0% {
  180. opacity: 0;
  181. }
  182. 100% {
  183. opacity: 1;
  184. }
  185. }
  186. @keyframes hidePopup {
  187. 0% {
  188. opacity: 1;
  189. }
  190. 100% {
  191. opacity: 0;
  192. }
  193. }
  194. @keyframes showLayer {
  195. 0% {
  196. transform: translateY(0);
  197. }
  198. 100% {
  199. transform: translateY(-100%);
  200. }
  201. }
  202. @keyframes hideLayer {
  203. 0% {
  204. transform: translateY(-100%);
  205. }
  206. 100% {
  207. transform: translateY(0);
  208. }
  209. }
  210. @keyframes showAmnation {
  211. 0% {
  212. top: -12rpx;
  213. opacity: 0;
  214. }
  215. 50% {
  216. top: -60rpx;
  217. opacity: 1;
  218. }
  219. 100% {
  220. top: -100rpx;
  221. opacity: 0;
  222. }
  223. }
  224. @keyframes hideAmnation {
  225. 0% {
  226. top: -100rpx;
  227. opacity: 0;
  228. }
  229. 100% {
  230. top: -12rpx;
  231. opacity: 0;
  232. }
  233. }
  234. .popup {
  235. position: fixed;
  236. top: 0;
  237. width: 100%;
  238. height: 100%;
  239. z-index: 999;
  240. display: none;
  241. .mask {
  242. position: fixed;
  243. top: 0;
  244. width: 100%;
  245. height: 100%;
  246. z-index: 21;
  247. background-color: rgba(0, 0, 0, 0.6);
  248. }
  249. .layer {
  250. position: fixed;
  251. z-index: 22;
  252. bottom: -420rpx;
  253. width: 702rpx;
  254. padding: 24rpx 24rpx 36rpx 24rpx;
  255. height: 360rpx;
  256. border-radius: 20rpx 20rpx 0 0;
  257. background-color: #fff;
  258. display: flex;
  259. flex-wrap: wrap;
  260. align-content: space-between;
  261. .content {
  262. width: 100%;
  263. margin-top: 40rpx;
  264. }
  265. .btn {
  266. width: 100%;
  267. height: 88rpx;
  268. display: flex;
  269. justify-content: center;
  270. .button {
  271. width: 600rpx;
  272. height: 90rpx;
  273. color: #fff;
  274. display: flex;
  275. align-items: center;
  276. justify-content: center;
  277. font-size: $font-size-28;
  278. border-radius: 45rpx;
  279. &.buy {
  280. background: $btn-confirm;
  281. }
  282. &.add {
  283. background: rgba(0, 0, 0, 1);
  284. }
  285. }
  286. }
  287. }
  288. &.show {
  289. display: block;
  290. .mask {
  291. animation: showPopup 0.2s linear both;
  292. }
  293. .layer {
  294. animation: showLayer 0.2s linear both;
  295. }
  296. }
  297. &.hide {
  298. display: block;
  299. .mask {
  300. animation: hidePopup 0.2s linear both;
  301. }
  302. .layer {
  303. animation: hideLayer 0.2s linear both;
  304. }
  305. }
  306. &.none {
  307. display: none;
  308. }
  309. &.service {
  310. .row {
  311. margin: 30upx 0;
  312. .title {
  313. font-size: 30upx;
  314. margin: 10upx 0;
  315. }
  316. .description {
  317. font-size: 28upx;
  318. color: #999;
  319. }
  320. }
  321. }
  322. .layer-smimg {
  323. border: 1px solid #eee;
  324. width: 136rpx;
  325. height: 136rpx;
  326. float: left;
  327. border-radius: 10rpx;
  328. margin-right: 24rpx;
  329. image {
  330. width: 136rpx;
  331. height: 136rpx;
  332. border-radius: 10rpx;
  333. }
  334. }
  335. .layer-nunbox {
  336. justify-content: space-between;
  337. align-items: center;
  338. width: 536rpx;
  339. height: 88rpx;
  340. padding: 13rpx 0 0 0;
  341. float: left;
  342. .layer-nunbox-t {
  343. width: 100%;
  344. height: 44rpx;
  345. position: relative;
  346. display: flex;
  347. .layer-nunbox-text {
  348. line-height: 44rpx;
  349. font-size: $font-size-28;
  350. }
  351. .number-box {
  352. display: flex;
  353. justify-content: center;
  354. align-items: center;
  355. border: 2rpx solid #e1e1e1;
  356. border-radius: 30rpx;
  357. height: 48rpx;
  358. margin-left: 20rpx;
  359. .iconfont {
  360. font-size: $font-size-24;
  361. padding: 0 18rpx;
  362. color: #333333;
  363. text-align: center;
  364. line-height: 48rpx;
  365. font-weight: bold;
  366. background: #ffffff;
  367. &.icon-jianhao {
  368. border-radius: 30rpx 0 0 30rpx;
  369. }
  370. &.icon-jiahao {
  371. border-radius: 0 30rpx 30rpx 0;
  372. }
  373. }
  374. .btn-input {
  375. width: 62rpx;
  376. height: 44rpx;
  377. line-height: 44rpx;
  378. border-radius: 4rpx;
  379. text-align: center;
  380. font-size: $font-size-24;
  381. border-bottom: 2rpx solid #e1e1e1;
  382. border-top: 2rpx solid #e1e1e1;
  383. color: #333333;
  384. background-color: #f7f7f7;
  385. }
  386. }
  387. .product-step {
  388. position: absolute;
  389. left: 45rpx;
  390. bottom: 0;
  391. height: 44rpx;
  392. background: #ffffff;
  393. }
  394. }
  395. .layer-nunbox-b {
  396. width: 100%;
  397. height: 44rpx;
  398. padding: 8rpx 0 16rpx;
  399. .text {
  400. font-weight: bold;
  401. }
  402. }
  403. .text {
  404. line-height: 44rpx;
  405. font-size: $font-size-32;
  406. .p {
  407. color: #ff2a2a;
  408. }
  409. // .p:first-child{
  410. // margin-left: 30rpx;
  411. // }
  412. .p.sm {
  413. font-size: $font-size-24;
  414. }
  415. }
  416. }
  417. }
  418. </style>