cashier_app/pagesOrder/quan/quan.vue

580 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="u-p-l-30 u-p-r-30 u-p-t-30 u-font-28 ">
<up-sticky offset-top="0">
<my-tabs v-model="pageData.types.sel" @change="tabChange" :list="pageData.types.list"></my-tabs>
</up-sticky>
<view class="u-m-t-32">
<template v-if="pageData.types.sel==0">
<view class="" @click="changeFullReductionCouponSel(item)"
v-for="(item,index) in pageData.fullReductionCoupon" :class="{filtergray:!item.use}" :key="index">
<view class="quan u-row-between u-flex u-col-center u-m-b-32 border-r-10 ">
<view class="no-use" v-if="!item.use">
<image class="img" src="/pagesOrder/static/image/no-use.svg" mode=""></image>
</view>
<view class="sel u-abso" v-if="item.id == pageData.fullReductionCouponSel.id ">
<up-icon name="checkbox-mark" color="#fff"></up-icon>
</view>
<view class="u-p-t-32 u-p-b-32 u-p-l-24 u-p-r-24 left">
<view class="u-flex">
<view class="hui">减</view>
<view class="u-m-l-18">{{item.name}}</view>
</view>
<view class=" u-m-t-20 u-flex">
<view>有效期:</view>
<view class="u-font-24 u-m-l-6"> {{dayjs(item.endTime).format('YYYY-MM-DD HH:mm:ss') }}
</view>
</view>
<view class="u-m-t-10 color-999 u-font-24">
{{ formatStr(item.useRestrictions)}}
</view>
</view>
<view class="right u-flex u-flex-col u-row-between">
<view class="u-flex u-row-center u-font-36 ">
¥{{item.discountAmount}}
</view>
<view class="u-flex u-font-24">
满{{item.fullAmount}}可用
</view>
<view class="u-flex ">
<view class="use-btn" @click.stop="toEmitChooseQuan(item)">去使用</view>
</view>
</view>
</view>
</view>
<template v-if="pageData.fullReductionCoupon.length <= 0 && pageData.hasAjax">
<my-img-empty tips="暂无可用优惠券"></my-img-empty>
</template>
</template>
<template v-if="pageData.types.sel==1">
<view class="" @click="changeProductCoupon(item)" v-for="(item,index) in pageData.productCoupon"
:class="{filtergray:!item.use}" :key="index">
<view class="quan goods u-row-between u-flex u-col-center u-m-b-32 border-r-10 u-relative">
<view class="no-use" v-if="!item.use">
<image class="img" src="/pagesOrder/static/image/no-use.svg" mode=""></image>
</view>
<view class="sel u-abso" v-if="item.checked">
<up-icon name="checkbox-mark" color="#fff"></up-icon>
</view>
<view class="u-p-t-32 u-p-b-32 u-p-l-24 u-p-r-24">
<view class="u-flex">
<up-image width="80rpx" height="80rpx" :src="item.productCover"></up-image>
<view class="u-m-l-18">
<view class="u-m-l-18">{{item.name}}{{item.productName?' | '+item.productName : ''}}</view>
<!-- <view class="u-m-l-18 u-m-t-10 u-font-24 color-666">x{{item.num}}</view> -->
</view>
</view>
<view class=" u-m-t-14 u-flex">
<view>有效期:</view>
<view class="u-font-24 u-m-l-6"> {{dayjs(item.endTime).format('YYYY-MM-DD HH:mm:ss') }}
</view>
</view>
<view class="u-m-t-10 color-999 u-font-24">
{{ item.useRestrictions }}
</view>
</view>
<view class="right u-flex u-flex-col u-col-bottom u-row-center" style="flex-shrink: 1;">
<view class="use-btn" @click.stop="toEmitChooseQuan(item)" style="flex-shrink: 1;">去使用</view>
</view>
</view>
</view>
<template v-if="pageData.productCoupon.length <= 0 && pageData.hasAjax">
<my-img-empty tips="暂无可用优惠券"></my-img-empty>
</template>
</template>
</view>
<view :style="{height:safebottomHeight+'px'}"></view>
<view class="fixed-b bottom safe-bottom border-top">
<view class="u-m-b-32 u-flex u-row-between u-p-t-10">
<view class="u-flex">
<text>抵扣金额:</text>
<text class="color-red">¥</text>
<text class="color-red">{{discountAmount}}</text>
</view>
<view class="u-flex u-relative">
<text>支付金额:</text>
<text class="color-red">¥</text>
<text class="color-red">{{payPrice }}</text>
<view class="u-absolute u-flex u-row-between" style="bottom: 100%;right: 0;"
v-if="payPrice*1!=option.orderPrice*1">
<view class="u-flex line-th color-999">
<text class="">¥</text>
<text class="">{{option.orderPrice}}</text>
</view>
</view>
</view>
</view>
<view class="u-flex gap-20">
<up-button shape="circle" plain @click="back">
<view class="font-bold">取消</view>
</up-button>
<up-button shape="circle" type="primary" @click="toEmitChooseQuan()">
<view class="font-bold">确定</view>
</up-button>
</view>
</view>
<up-modal :title="modal.title" :content="modal.content" :show="modal.clear" :confirmText="modal.confirmText"
:cancelText="modal.cancelText" showCancelButton closeOnClickOverlay @confirm="confirmModelConfirm"
@cancel="confirmModelCancel" @close="setModalShow('clear',false)" width="300px" />
</view>
</template>
<script setup>
import { onLoad, onReady } from '@dcloudio/uni-app'
import { ref, reactive, watch, computed, onMounted } from 'vue';
import color from '@/commons/color.js'
import dayjs from 'dayjs';
import { getSafeBottomHeight } from '@/commons/utils/safe-bottom.js'
import go from '@/commons/utils/go.js'
import infoBox from '@/commons/utils/infoBox.js'
import {
returnNewGoodsList,
returnCoupCanUse,
returnCouponAllPrice,
returnProductCoupon,
returnCanUseFullReductionCoupon,
returnProductAllCoup
} from '../quan_util.js'
import { getHistoryOrder } from '@/http/api/order.js'
import { shopUserDetail } from '@/http/api/shopUser.js'
import { getFindCoupon } from '@/http/api/coupon.js'
const modal = reactive({
title: '提示',
cancelText: '取消',
confirmText: '确定',
content: '',
key: '',
clear: false,
data: ''
})
const option = reactive({
orderId: '',
shopUserId: '',
orderPrice: 0
})
const pageData = reactive({
order: null,
user: null,
types: {
list: ['满减券(单选)', '商品券(多选)'],
sel: 0
},
fullReductionCouponSel: {
id: ''
},
fullReductionCoupon: [],
productCoupon: [],
hasAjax: false
})
let canDikouGoodsArr = []
let safebottomHeight = ref(0)
onLoad((opt) => {
Object.assign(option, opt)
getQuan()
})
watch(() => pageData.types.sel, (newval) => {
if (newval == 0) {
pageData.fullReductionCoupon = returnCanUseFullReductionCoupon(pageData.fullReductionCoupon, payPrice.value,
pageData.fullReductionCouponSel)
}
if (newval == 1) {
}
})
onReady(() => {
getSafeBottomHeight('bottom', 0).then(height => {
safebottomHeight.value = height
})
})
function tabChange () {
getQuan()
}
/**
* 抵扣金额
*/
const discountAmount = computed(() => {
const goodsQuan = pageData.productCoupon.filter(v => v.checked)
const fullReductionCoupon = pageData.fullReductionCouponSel.id ? [pageData.fullReductionCouponSel] : []
let coupArr = [...fullReductionCoupon, ...goodsQuan]
return returnCouponAllPrice(coupArr, canDikouGoodsArr, pageData.user)
})
const payPrice = computed(() => {
const pay = option.orderPrice - discountAmount.value
return (pay < 0 ? 0 : pay).toFixed(2)
})
/**
* 获取优惠券
*/
async function getQuan() {
shopUserDetail({ id: option.shopUserId }).then(res=>{
pageData.user = res
})
pageData.order = await getHistoryOrder({orderId:option.orderId})
const res = await getFindCoupon({
shopUserId: option.shopUserId,
type: pageData.types.sel+1
})
let fullReductionCoupon = res ? res.filter(v => v.type == 1) : []
let productCoupon = res ? res.filter(v => v.type == 2) : []
canDikouGoodsArr = returnNewGoodsList(pageData.order.detailMap || [])
fullReductionCoupon = fullReductionCoupon.map((v) => {
if(option.orderPrice<=0){
return {...v,use:false}
}else{
return{
...v,
use:v.use && option.orderPrice * 1 >= v
.fullAmount * 1
}
}
})
productCoupon = productCoupon.map(v => {
const calcCoup = returnProductCoupon(v, pageData.order.detailMap, pageData.user)
return {
...calcCoup,
checked: false,
use: option.orderPrice<=0?false:v.use
}
})
// .filter((v) => v.use);
pageData.fullReductionCoupon = fullReductionCoupon
pageData.productCoupon = productCoupon
pageData.hasAjax = true;
}
function confirmModelCancel() {
setModalShow('clear', false, '')
}
/**
* 继续选择
*/
async function confirmModelConfirm() {
if (modal.key == 'clear') {
if( modal.data ){
pageData.fullReductionCouponSel = {
id: ''
}
const item = modal.data
item.checked = !item.checked
const CheckedArr = pageData.productCoupon.filter(v => v.checked)
const noCheckedArr = pageData.productCoupon.filter(v => !v.checked)
noCheckedArr.map(v => {
v.use = returnCoupCanUse(canDikouGoodsArr, v, CheckedArr)
})
}
setModalShow('clear', false, '')
}
}
function setModalShow(key = 'show', show = true, data) {
modal.key = key
modal[key] = show
modal.data = data
}
function back() {
uni.navigateBack()
}
/**
* 商品券选择
* @param {Object} item
*/
function changeProductCoupon(item) {
if (!item.use) { return }
if ( payPrice.value <= 0 ) {
modal.content = '当前支付金额不满足选择商品券的最低使用需求,无法选择'
modal.cancelText = '取消'
modal.confirmText = '确定'
setModalShow('clear', true)
return
}
if (!item.checked) {
const goodsQuan = pageData.productCoupon.filter(v => v.checked)
let coupArr = [...goodsQuan, item]
const payPrice = option.orderPrice - returnCouponAllPrice(coupArr, canDikouGoodsArr, pageData.user)
if (payPrice<=0) {
modal.content = '选择该商品券后支付金额将为0继续选择将取消选择的满减券'
modal.cancelText = '取消'
modal.confirmText = '继续选择'
setModalShow('clear', true, item)
return
}
if (pageData.fullReductionCouponSel.fullAmount > payPrice) {
modal.content = '选择该商品券后将不满足选择抵扣券的最低满减需求,继续选择将取消选择的满减券'
modal.cancelText = '取消'
modal.confirmText = '继续选择'
setModalShow('clear', true, item)
return
}
}
item.checked = !item.checked
const CheckedArr = pageData.productCoupon.filter(v => v.checked)
if (CheckedArr.length <= 0) {
return pageData.productCoupon.map(v => {
v.use = true
})
}
const noCheckedArr = pageData.productCoupon.filter(v => !v.checked)
noCheckedArr.map(v => {
v.use = returnCoupCanUse(canDikouGoodsArr, v, CheckedArr)
})
}
/**
* 优惠券选择
* @param {Object} item
*/
function changeFullReductionCouponSel(item) {
if (!item.use) {
return
}
if (item.id == pageData.fullReductionCouponSel.id) {
pageData.fullReductionCouponSel = {
id: ''
}
} else {
pageData.fullReductionCouponSel = item
}
pageData.fullReductionCoupon = returnCanUseFullReductionCoupon(pageData.fullReductionCoupon, payPrice.value, pageData
.fullReductionCouponSel)
}
function formatStr(str) {
// return str.replaceAll('"', '')
}
/**
* 优惠券选择确认
* @param {Object} item
*/
function toEmitChooseQuan(item) {
let arr = []
let discountAmount = 0;
if (item) {
arr = [item]
} else {
if (pageData.fullReductionCouponSel.id) {
arr.push(pageData.fullReductionCouponSel)
}
let goodsQuan = pageData.productCoupon.filter(v => v.checked)
arr.push(...goodsQuan)
}
arr.map(item=>{
discountAmount += item.discountAmount
})
if( discountAmount > option.orderPrice){
}
console.log(arr)
uni.$emit('choose-quan', arr)
back()
}
</script>
<style lang="scss" scoped>
// $quan-color:rgb(233, 77, 60);
$quan-color: #318AFE;
.no-use {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
display: flex;
justify-content: center;
align-items: center;
.img {
width: 200rpx;
height: 200rpx;
z-index: 10;
}
}
.fixed-b {
position: fixed;
bottom: 0;
background-color: #fff;
right: 0;
left: 0;
}
.bg-gray {
border-radius: 18rpx;
overflow: hidden;
}
.price1 {
color: rgb(255, 107, 0);
}
.payType {
.radio {
display: flex;
justify-content: center;
align-items: center;
background-color: rgb(255, 212, 0);
width: 40rpx;
height: 40rpx;
border-radius: 40rpx;
opacity: 0;
}
.active {
.radio {
opacity: 1;
}
}
}
.left-block {
position: relative;
&::after {
content: '';
position: absolute;
left: -30rpx;
display: block;
width: 12rpx;
top: 0;
background-color: rgb(255, 212, 0);
bottom: 0;
}
}
.filtergray {
filter: grayscale(1);
}
.radio {
display: flex;
justify-content: center;
align-items: center;
background-color: rgb(255, 255, 255);
width: 40rpx;
height: 40rpx;
border-radius: 40rpx;
&.active {}
}
.use-btn {
background-color: #fff;
border-radius: 100rpx;
padding: 4rpx 20rpx;
color: $quan-color;
}
.u-font-40 {
font-size: 40rpx;
}
.yilingqu {
position: absolute;
bottom: 20rpx;
right: 20rpx;
}
.lingqu {
position: absolute;
bottom: 20rpx;
right: 20rpx;
background-color: rgb(255, 207, 0);
padding: 10rpx 30rpx;
border-radius: 100rpx;
}
.btn {
background-color: $my-main-color;
color: #fff;
border: none;
padding: 10rpx 20rpx;
border-radius: 10rpx;
}
.hui {
// background-color: $quan-color;
background-image: linear-gradient(to right bottom, rgb(254, 103, 4), rgb(241, 50, 42));
padding: 4rpx 10rpx;
border-radius: 10rpx;
font-size: 24rpx;
color: #fff;
}
.quan {
border: 1px solid rgb(238, 238, 238);
position: relative;
border-radius: 10rpx;
box-shadow: 0 0 5px #eee;
overflow: hidden;
.left{
max-width: 80%;
}
.sel {
padding: 2rpx 4rpx;
position: absolute;
background-color: $quan-color;
left: 0;
top: 0;
border-radius: 0 0 24rpx 0;
}
.right {
position: absolute;
top: 0;
right: 0;
bottom: 0;
padding: 20rpx 24rpx;
color: #fff;
display: flex;
flex-direction: column;
background-color: $quan-color;
height: 100%;
}
&.goods {
.right {
background-color: #fff;
.use-btn {
padding: 10rpx 40rpx;
color: #fff;
background-color: $quan-color;
}
}
}
}
.bottom {
padding: 30rpx 30rpx 80rpx 30rpx;
}
</style>