index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. <template>
  2. <view>
  3. <view class='coupon-list-window animated' :class='coupon.status==true?"slideInUp":""'>
  4. <view class='title'>
  5. <view class="item">优惠券</view>
  6. </view>
  7. <block v-if="couponArr.length">
  8. <view class='coupon-list'>
  9. <view class='item acea-row row-center-wrapper' v-for="(item,index) in couponArr" @click="getCouponUser(index,item)"
  10. :key='index'>
  11. <view class='money acea-row row-column row-center-wrapper'>
  12. <view><text class='num'>{{item.coupon_price}}</text></view>
  13. <view class="pic-num">{{item.use_min_price}}元可用</view>
  14. </view>
  15. <view class='text'>
  16. <view class='condition line1'>
  17. <span class='line-title' v-if='item.coupon.type===0'>店铺券</span>
  18. <span class='line-title' v-else-if='item.coupon.type===1'>商品券</span>
  19. <span>{{item.coupon_title}}</span>
  20. </view>
  21. <view class='data acea-row row-between-wrapper'>
  22. <view>{{ item.start_time |timeYMD }} ~ {{ item.end_time |timeYMD}}</view>
  23. <view class="iconfont icon-weixuanzhong" v-if="!item.checked"></view>
  24. <view class='iconfont icon-xuanzhong1' v-else></view>
  25. </view>
  26. </view>
  27. </view>
  28. </view>
  29. <view class="foot-box">
  30. <view class="left">
  31. 已选择{{allNum}}张,可优惠<text>{{allCouponNum}}</text>
  32. </view>
  33. <view class="btn" @click="confirm">确定</view>
  34. </view>
  35. </block>
  36. <!-- 无优惠券 -->
  37. <view class='pictrue' v-else>
  38. <image :src="`${domain}/static/images/noCoupon.png`"></image>
  39. </view>
  40. </view>
  41. <view class='mask' catchtouchmove="true" :hidden='coupon.status==false' @click='close'></view>
  42. </view>
  43. </template>
  44. <script>
  45. // +----------------------------------------------------------------------
  46. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  47. // +----------------------------------------------------------------------
  48. // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
  49. // +----------------------------------------------------------------------
  50. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  51. // +----------------------------------------------------------------------
  52. // | Author: CRMEB Team <admin@crmeb.com>
  53. // +----------------------------------------------------------------------
  54. import { setCouponReceive } from '@/api/api.js';
  55. import { HTTP_REQUEST_URL } from '@/config/app'
  56. export default {
  57. props: {
  58. //打开状态 0=领取优惠券,1=使用优惠券
  59. openType: {
  60. type: Number,
  61. default: 0,
  62. },
  63. coupon: {
  64. type: Object,
  65. default: function() {
  66. return {};
  67. }
  68. },
  69. subCoupon: {
  70. type: Object
  71. }
  72. },
  73. filters: {
  74. timeYMD: function(value) {
  75. if(value){
  76. var newDate=/\d{4}-(\d{1,2}\d{1,2}-\d{1,2}\d{1,2})/g.exec(value)
  77. return newDate?.[1]||''
  78. }
  79. }
  80. },
  81. data() {
  82. return {
  83. domain: HTTP_REQUEST_URL,
  84. couponArr: [],
  85. couponData: {},
  86. // 选中的数据存放
  87. active: {},
  88. allNum: 0,
  89. allCouponNum: 0,
  90. // 选中店铺优惠券id
  91. use_store_coupon: 0,
  92. // 单个店铺总价
  93. pay_price: 0,
  94. // 商品有优惠订单
  95. goodsOrder: ''
  96. };
  97. },
  98. mounted() {
  99. this.couponData = this.coupon
  100. // 深拷贝数据 不影响原来数据使用
  101. this.couponArr = JSON.parse(JSON.stringify(this.coupon.coupon))
  102. // 深拷贝数据 不影响原来数据使用
  103. this.goodsOrder = JSON.parse(JSON.stringify(this.coupon.order))
  104. let tempObj = this.active[this.couponData.mer_id] = {}
  105. tempObj.product = []
  106. tempObj.store = ''
  107. this.allActive()
  108. },
  109. methods: {
  110. close: function() {
  111. this.$emit('ChangCouponsClose');
  112. },
  113. // 使用优惠券
  114. getCouponUser: function(index, item) {
  115. let self = this
  116. // 先判断是哪个券 1商品 0店铺
  117. if (item.coupon.type == 1) {
  118. let order = this.goodsOrder
  119. let orderToalPrice = 0
  120. if (item.checked) {
  121. /**
  122. * 取消选中 并且删除 use_coupon_product里的值
  123. * use_coupon_product 哪些商品可以用的券的id
  124. * */
  125. for (let key in order.use_coupon_product) {
  126. if (order.use_coupon_product[key] == item.coupon_user_id) {
  127. delete order.use_coupon_product[key]
  128. }
  129. }
  130. item.checked = false
  131. } else {
  132. /**
  133. * 选中
  134. * @item.product 该优惠券可以使用的商品
  135. * order.product_price 产品的价格 key是id
  136. * */
  137. for (let i = 0; i < item.product.length; i++) {
  138. if (order.product_price[item.product[i].product_id]) {
  139. orderToalPrice = order.product_price[item.product[i].product_id]
  140. //价格的值大于等于最小值就可以使用
  141. if (orderToalPrice >= parseFloat(item.use_min_price)) {
  142. // 可以用
  143. if (!order.use_coupon_product[item.product[i].product_id]) {
  144. item.checked = true
  145. order.use_coupon_product[item.product[i].product_id] = item.coupon_user_id
  146. } else {
  147. // 上个商品用了就取消选中,点击的这个添加选中
  148. this.couponArr.forEach(el => {
  149. if (el.coupon_user_id == order.use_coupon_product[item.product[i].product_id]) {
  150. el.checked = false
  151. }
  152. })
  153. item.checked = true
  154. order.use_coupon_product[item.product[i].product_id] = item.coupon_user_id
  155. }
  156. break
  157. }
  158. }
  159. }
  160. }
  161. } else {
  162. let order = this.couponData.order
  163. // 店铺券
  164. if (item.checked) {
  165. item.checked = false
  166. // this.pay_price = order.total_price
  167. } else {
  168. this.couponArr.forEach(el => {
  169. if (el.coupon.type == 0 && el.checked) {
  170. el.checked = false
  171. }
  172. })
  173. item.checked = true
  174. }
  175. this.pay_price = this.$util.$h.Sub(order.total_price, item.coupon_price)
  176. }
  177. this.allActive()
  178. },
  179. // 选中计算
  180. allActive() {
  181. let tempObj = this.active[this.couponData.mer_id]
  182. let sotreTotal = 0 //商铺券优惠
  183. let goodsTotal = 0 //商品券优惠
  184. tempObj.product = []
  185. tempObj.store = ''
  186. this.couponArr.forEach(el => {
  187. /**
  188. * @el.coupon.type 0店铺 1商品
  189. */
  190. if (el.coupon.type == 0 && el.checked) {
  191. tempObj.store = el.coupon_user_id
  192. sotreTotal = el.coupon_price
  193. this.use_store_coupon = el.coupon_user_id
  194. }
  195. if (el.coupon.type == 1 && el.checked) {
  196. tempObj.product.push(el.coupon_user_id)
  197. goodsTotal = this.$util.$h.Add(goodsTotal, el.coupon_price)
  198. }
  199. })
  200. if (tempObj.store) {
  201. this.allNum = this.$util.$h.Add(tempObj.product.length, 1)
  202. } else {
  203. this.allNum = tempObj.product.length
  204. }
  205. let tempAllCouponNum = this.$util.$h.Add(sotreTotal, goodsTotal)
  206. if (parseFloat(tempAllCouponNum) >= parseFloat(this.couponData.order.total_price)) {
  207. this.allCouponNum = this.couponData.order.total_price
  208. } else {
  209. if(this.allNum !== 0 ){
  210. if(sotreTotal || goodsTotal){
  211. this.allCouponNum = tempAllCouponNum
  212. }else{
  213. this.allCouponNum = this.couponData.order.total_price
  214. }
  215. }else{
  216. this.allCouponNum = tempAllCouponNum
  217. }
  218. }
  219. },
  220. // 确认
  221. confirm() {
  222. // 商品类
  223. this.couponData.order = this.goodsOrder
  224. // 店铺类
  225. // 支付价格
  226. let tempTotal = 0
  227. tempTotal = this.$util.$h.Sub(this.couponData.order.total_price, this.allCouponNum)
  228. if (tempTotal > 0) {
  229. this.couponData.order.pay_price = this.$util.$h.Add(tempTotal, this.couponData.order.postage_price)
  230. } else {
  231. // 如果没有用优惠券
  232. if(this.allNum == 0){
  233. this.couponData.order.pay_price = this.$util.$h.Add(this.couponData.order.total_price, this.couponData.order.postage_price)
  234. }else{
  235. this.couponData.order.pay_price = this.couponData.order.postage_price
  236. }
  237. }
  238. // 列表的优惠总金额
  239. this.couponData.order.coupon_price = this.allCouponNum
  240. this.couponData.order.use_store_coupon = this.use_store_coupon
  241. this.couponData.coupon = this.couponArr
  242. this.active[this.coupon.mer_id].product = this.goodsOrder.use_coupon_product
  243. this.subCoupon[this.coupon.mer_id] = this.active[this.coupon.mer_id]
  244. this.$emit('ChangCoupons',this.couponData);
  245. }
  246. }
  247. }
  248. </script>
  249. <style scoped lang="scss">
  250. .animated {
  251. animation-duration: .3s
  252. }
  253. .title {
  254. display: flex;
  255. .item {
  256. position: relative;
  257. flex: 1;
  258. font-size: 28rpx;
  259. color: #999999;
  260. &::after {
  261. content: ' ';
  262. position: absolute;
  263. left: 50%;
  264. bottom: 18rpx;
  265. width: 50rpx;
  266. height: 5rpx;
  267. background: transparent;
  268. border-radius: 3px;
  269. transform: translateX(-50%);
  270. }
  271. &.on {
  272. color: #282828;
  273. &::after {
  274. background: $theme-color;
  275. }
  276. }
  277. }
  278. }
  279. .coupon-list {
  280. padding: 30rpx;
  281. .item {
  282. box-shadow: 0px 2px 10px 0px rgba(0, 0, 0, 0.06);
  283. }
  284. }
  285. .coupon-list-window {
  286. position: fixed;
  287. bottom: 0;
  288. left: 0;
  289. width: 100%;
  290. background-color: #fff;
  291. border-radius: 16rpx 16rpx 0 0;
  292. z-index: 555;
  293. transform: translate3d(0, 100%, 0);
  294. transition: all .3s cubic-bezier(.25, .5, .5, .9);
  295. }
  296. .coupon-list-window.on {
  297. animation: aminup;
  298. }
  299. .coupon-list-window .title {
  300. height: 106rpx;
  301. width: 100%;
  302. text-align: center;
  303. line-height: 106rpx;
  304. font-size: 32rpx;
  305. font-weight: bold;
  306. position: relative;
  307. border: 1px solid #f5f5f5;
  308. }
  309. .coupon-list-window .title .iconfont {
  310. position: absolute;
  311. right: 30rpx;
  312. top: 50%;
  313. transform: translateY(-50%);
  314. font-size: 35rpx;
  315. color: #8a8a8a;
  316. font-weight: normal;
  317. }
  318. .coupon-list-window .coupon-list {
  319. margin: 0 0 0rpx 0;
  320. height: 550rpx;
  321. overflow: auto;
  322. }
  323. .coupon-list-window .pictrue {
  324. width: 414rpx;
  325. height: 336rpx;
  326. margin: 0 auto 50rpx auto;
  327. }
  328. .coupon-list-window .pictrue image {
  329. width: 100%;
  330. height: 100%;
  331. }
  332. .pic-num {
  333. color: #fff;
  334. font-size: 24rpx;
  335. }
  336. .line-title {
  337. width: 90rpx;
  338. padding: 0 10rpx;
  339. box-sizing: border-box;
  340. background: rgba(255, 247, 247, 1);
  341. border: 1px solid rgba(232, 51, 35, 1);
  342. opacity: 1;
  343. border-radius: 20rpx;
  344. font-size: 20rpx;
  345. color: #E83323;
  346. margin-right: 12rpx;
  347. }
  348. .line-title.gray {
  349. border-color: #BBB;
  350. color: #bbb;
  351. background-color: #F5F5F5;
  352. }
  353. .foot-box {
  354. display: flex;
  355. align-items: center;
  356. justify-content: space-between;
  357. height: 100rpx;
  358. padding: 0 30rpx;
  359. border-top: 1px solid #F5F5F5;
  360. .btn {
  361. width: 240rpx;
  362. height: 70rpx;
  363. line-height: 70rpx;
  364. text-align: center;
  365. background: $theme-color;
  366. border-radius: 35rpx;
  367. color: #fff;
  368. font-size: 30rpx;
  369. }
  370. .left {
  371. text {
  372. color: $theme-color;
  373. }
  374. }
  375. }
  376. .coupon-list .item .text .data .iconfont {
  377. font-size: 36rpx;
  378. &.icon-weixuanzhong {
  379. color: #BFBFBF;
  380. }
  381. &.icon-xuanzhong1 {
  382. color: $theme-color;
  383. }
  384. }
  385. </style>