2023-02-23
保存地址
This commit is contained in:
@@ -8,8 +8,8 @@
|
||||
<view class="demand">满{{ item.minPoint }} 减 {{ item.amount }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="get-btn" :style="{color:color, borderColor:color, background:solid}"
|
||||
@click="acceptCoupon(item)">立即领取</view>
|
||||
<view class="get-btn" :style="{color:color, borderColor:color, background:solid}" @click="acceptCoupon(item)">
|
||||
立即领取</view>
|
||||
<!-- <navigator class="get-btn" v-if="types" :style="{color:color, borderColor:color, background:solid}"
|
||||
:url='item.url' @click="useCoupon(item)">立即使用</navigator> -->
|
||||
</view>
|
||||
@@ -58,28 +58,42 @@
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapState(['hasLogin', 'userInfo']),
|
||||
...mapState(['hasLogin','hasVip', 'userInfo']),
|
||||
},
|
||||
methods: {
|
||||
async acceptCoupon(item) {
|
||||
if (this.hasLogin) {
|
||||
this.types = !this.types
|
||||
uni.showLoading({
|
||||
title: '请稍后'
|
||||
});
|
||||
|
||||
let params = {
|
||||
couponId: item.id
|
||||
};
|
||||
this.clickSubMethod(item)
|
||||
let data = await Api.apiCall('post', Api.index.acceptCoupon, params);
|
||||
// console.log("data?????", data);
|
||||
// if (data) {
|
||||
// // this.$api.msg(data);
|
||||
// this.clickSubMethod(item)
|
||||
|
||||
// }
|
||||
uni.hideLoading();
|
||||
if(this.hasVip){
|
||||
this.types = !this.types
|
||||
uni.showLoading({
|
||||
title: '请稍后'
|
||||
});
|
||||
|
||||
let params = {
|
||||
couponId: item.id
|
||||
};
|
||||
this.clickSubMethod(item)
|
||||
let data = await Api.apiCall('post', Api.index.acceptCoupon, params);
|
||||
// console.log("data?????", data);
|
||||
// if (data) {
|
||||
// // this.$api.msg(data);
|
||||
// this.clickSubMethod(item)
|
||||
|
||||
// }
|
||||
uni.hideLoading();
|
||||
}else{
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '您不属于惠农会员,暂不能领取此优惠券',
|
||||
showCancel:false,
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: '/pages/public/login'
|
||||
|
||||
70
mallplusui-uniapp-app/components/w-select/readme.md
Normal file
70
mallplusui-uniapp-app/components/w-select/readme.md
Normal file
@@ -0,0 +1,70 @@
|
||||
#### props
|
||||
|
||||
|名称 |类型 |默认值 |说明|
|
||||
|- |- |- |-|
|
||||
|width |string |'300rpx' |选择框宽度|
|
||||
|height |string |'60rpx' |选择框高度|
|
||||
|round |boolean |true |是否开启圆角|
|
||||
|bgColor|string |'#fff' |选择框的背景颜色|
|
||||
|color |string |'#606266' |字体颜色|
|
||||
|placeholderColor|string |'color:#bcbec4' |提示文字的字体颜色|
|
||||
|defaultValue |string |'请选择' |默认显示的名称 | |
|
||||
|valueName|string |'value' |显示的内容字段名,必传|
|
||||
|list |array |[] |展示的内容列表|
|
||||
|showClose|boolean |true |是否显示删除按钮|
|
||||
|multiple|boolean |false |是否开启多选|
|
||||
|filterable|boolean |false |是否开启搜索功能,开启后直接输入值不选择也可以保存内容|
|
||||
|
||||
|
||||
#### events
|
||||
|
||||
|事件名|说明|
|
||||
|-|-|
|
||||
|change|选择的内容改变时触发,返回的参数为列表的item|
|
||||
|
||||
|
||||
#### 使用举例
|
||||
|
||||
需要绑定的值通过`v-model`绑定,如下面的`chooseValue`,需要获取item的值可以监听`@change`事件
|
||||
|
||||
开启多选`multiple`时,双向绑定的值为数组类型,在change事件中根据自己需求进行处理。
|
||||
|
||||
`valueName`属性必须传,告知组件需要显示的是什么值
|
||||
|
||||
```html
|
||||
<template>
|
||||
<view class="login">
|
||||
<w-select style="margin-left: 20rpx;"
|
||||
v-model='chooseValue'
|
||||
defaultValue="所有审批人"
|
||||
:list='list'
|
||||
valueName='content'
|
||||
@change='change'>
|
||||
</w-select>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
chooseValue: "",
|
||||
list: [{
|
||||
id: 1,
|
||||
content: '张三'
|
||||
}, {
|
||||
id: 2,
|
||||
content: '李四'
|
||||
}, {
|
||||
id: 3,
|
||||
content: '王五'
|
||||
}],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
change(e) {
|
||||
console.log('chooseValue', this.chooseValue)
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
```
|
||||
395
mallplusui-uniapp-app/components/w-select/w-select.vue
Normal file
395
mallplusui-uniapp-app/components/w-select/w-select.vue
Normal file
@@ -0,0 +1,395 @@
|
||||
<template>
|
||||
<view class="wSelect" :class="show ? 'active' : ''" :style="{
|
||||
width: width,
|
||||
height: height,
|
||||
backgroundColor: bgColor,
|
||||
borderRadius: round ? '6rpx' : 'none'
|
||||
}">
|
||||
<view @click="openSelect" class="pickerSelect">
|
||||
<view :style="{ height: height }" v-if="multiple" class="multipleChoice">
|
||||
<view class="defaultValue" :style="{ color: color }" v-if="!inputData && multiSelectList.length < 1">
|
||||
{{ defaultValue }}
|
||||
</view>
|
||||
<view class="option" v-if="multiSelectList.length > 0">
|
||||
<view class="">{{ multiSelectList[0][valueName] }}</view>
|
||||
<image class="img" @click.stop="multiDelete" :src="refreshUrl" mode=""></image>
|
||||
</view>
|
||||
<view v-if="multiSelectList.length > 1" class="more">{{ multiLength }}</view>
|
||||
<input :disabled="!filterable"
|
||||
:style="{ height: height, paddingRight: '30rpx', fontSize: '28rpx', color: color }"
|
||||
@input="inputChange" type="text" v-model="inputData" />
|
||||
</view>
|
||||
<input v-else :disabled="!filterable"
|
||||
:style="{ height: height, paddingRight: '30rpx', fontSize: '30rpx', color:'#000' }" @input="inputChange"
|
||||
:placeholder="defaultValue" :placeholder-style="placeholderColor" type="text" v-model="inputData" />
|
||||
<view v-if="!inputData || !showClose" :class="show ? 'arrow-up' : 'arrow'"></view>
|
||||
<view class="showClose" v-if="showClose && inputData">
|
||||
<image @click.stop="refreshValue" :src="refreshUrl" mode=""></image>
|
||||
</view>
|
||||
<view v-show="show" :class="isShow ? 'animation-top' : 'animation-bottom'" class="tips"
|
||||
:style="{ top: tipsPositon }"></view>
|
||||
</view>
|
||||
<!-- 单选时的下拉框 -->
|
||||
<view v-if="!multiple" :style="{ width: '75%', color: '#737478' }" v-show="show"
|
||||
:class="isShow ? 'animation-top' : 'animation-bottom'" class="content">
|
||||
<view class="item" :class="value == item[valueName] ? 'choose' : ''" v-for="(item, index) in listData"
|
||||
:key="index" @click="clickSelect(item)">
|
||||
{{ item[valueName] }}
|
||||
</view>
|
||||
<view class="item" v-if="listData.length < 1">无匹配项</view>
|
||||
</view>
|
||||
<!-- 多选的下拉框 -->
|
||||
<view v-else :style="{ width: width }" v-show="show" :class="isShow ? 'animation-top' : 'animation-bottom'"
|
||||
class="content">
|
||||
<view class="item" :class="multiSelectList.find(res => res[valueName] == item[valueName]) ? 'choose' : ''"
|
||||
v-for="(item, index) in listData" :key="index" @click="multiSelect(item)">
|
||||
{{ item[valueName] }}
|
||||
</view>
|
||||
<view class="item" v-if="listData.length < 1">无匹配项</view>
|
||||
</view>
|
||||
<view v-if="show" @click="closeContentSelect" class="contentMask"></view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'wSelect',
|
||||
props: {
|
||||
//是否多选
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
//是否可搜索
|
||||
filterable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
//是否显示关闭按钮
|
||||
showClose: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '300rpx'
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#606266'
|
||||
},
|
||||
placeholderColor: {
|
||||
type: String,
|
||||
default: 'color:#bcbec4'
|
||||
},
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: '#fff'
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '60rpx'
|
||||
},
|
||||
//默认显示的内容
|
||||
defaultValue: {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
},
|
||||
//显示的内容
|
||||
valueName: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
required: true
|
||||
},
|
||||
//双向绑定的值
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
round: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
immediate: true,
|
||||
handler(newValueData) {
|
||||
if (!this.inputData) {
|
||||
this.inputData = newValueData
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
isShow: false,
|
||||
multiSelectList: [],
|
||||
inputData: '',
|
||||
listData: this.list,
|
||||
refreshUrl: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDQ4IDQ4IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxyZWN0IHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgZmlsbD0id2hpdGUiIGZpbGwtb3BhY2l0eT0iMC4wMSIvPjxwYXRoIGQ9Ik0yNCA0NEMzNS4wNDU3IDQ0IDQ0IDM1LjA0NTcgNDQgMjRDNDQgMTIuOTU0MyAzNS4wNDU3IDQgMjQgNEMxMi45NTQzIDQgNCAxMi45NTQzIDQgMjRDNCAzNS4wNDU3IDEyLjk1NDMgNDQgMjQgNDRaIiBmaWxsPSJub25lIiBzdHJva2U9IiM3YzZlNmUiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjxwYXRoIGQ9Ik0yOS42NTY5IDE4LjM0MzFMMTguMzQzMiAyOS42NTY4IiBzdHJva2U9IiM3YzZlNmUiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+PHBhdGggZD0iTTE4LjM0MzIgMTguMzQzMUwyOS42NTY5IDI5LjY1NjgiIHN0cm9rZT0iIzdjNmU2ZSIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48L3N2Zz4='
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
multiLength() {
|
||||
const length = this.multiSelectList.length - 1
|
||||
return '+' + length
|
||||
},
|
||||
tipsPositon() {
|
||||
let num = this.height.replace('rpx', '')
|
||||
let numAdd = Number(num) + Number(10)
|
||||
return numAdd + 'rpx'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openSelect() {
|
||||
this.listData = this.list
|
||||
console.log("listData>>>", this.listData)
|
||||
if (this.show === true) {
|
||||
this.isShow = false
|
||||
} else {
|
||||
this.isShow = true
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.show = !this.show
|
||||
}, 200)
|
||||
},
|
||||
clickSelect(item) {
|
||||
this.$emit('input', item[this.valueName])
|
||||
this.inputData = item[this.valueName]
|
||||
this.$emit('change', item)
|
||||
this.show = false
|
||||
},
|
||||
inputChange(e) {
|
||||
console.log(e.detail.value)
|
||||
let value = e.detail.value
|
||||
this.$emit('input', value)
|
||||
if (value) {
|
||||
this.listData = this.listData.filter(item => item[this.valueName].includes(value))
|
||||
} else {
|
||||
this.listData = this.list
|
||||
}
|
||||
},
|
||||
multiSelect(item) {
|
||||
let index = this.multiSelectList.findIndex(res => res[this.valueName] == item[this.valueName])
|
||||
if (index > -1) {
|
||||
this.multiSelectList.splice(index, 1)
|
||||
} else {
|
||||
this.multiSelectList.push(item)
|
||||
}
|
||||
this.inputData = ''
|
||||
this.listData = this.list
|
||||
this.$emit('input', this.multiSelectList)
|
||||
this.$emit('change', item)
|
||||
},
|
||||
refreshValue() {
|
||||
this.$emit('input', '')
|
||||
this.inputData = ''
|
||||
this.listData = this.list
|
||||
this.$emit('change', '')
|
||||
this.show = false
|
||||
},
|
||||
multiDelete() {
|
||||
this.multiSelectList.splice(0, 1)
|
||||
this.$emit('input', this.multiSelectList)
|
||||
if (this.multiSelectList.length < 1) {
|
||||
this.show = false
|
||||
}
|
||||
},
|
||||
closeContentSelect() {
|
||||
this.isShow = false
|
||||
setTimeout(() => {
|
||||
this.show = false
|
||||
}, 200)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.wSelect {
|
||||
// border: 2rpx solid #dcdfe6;
|
||||
transition: all 0.5s;
|
||||
|
||||
.pickerSelect {
|
||||
border-radius: 6rpx;
|
||||
padding: 0 20rpx;
|
||||
position: relative;
|
||||
transition: all 0.6s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.tips {
|
||||
position: absolute;
|
||||
margin-left: 30rpx;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-bottom: 12rpx solid #fff;
|
||||
border-left: 12rpx solid transparent;
|
||||
border-right: 12rpx solid transparent;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.showClose {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
position: absolute;
|
||||
right: 14rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.arrow {
|
||||
transition: all 0.3s;
|
||||
position: absolute;
|
||||
top: 44%;
|
||||
right: 20rpx;
|
||||
border-left: 2rpx solid #999999;
|
||||
border-bottom: 2rpx solid #999999;
|
||||
height: 16rpx;
|
||||
width: 16rpx;
|
||||
transform: translateY(-50%) rotate(-45deg);
|
||||
-webkit-transform: translateY(-50%) rotate(-45deg);
|
||||
border-right: 2rpx solid transparent;
|
||||
border-top: 2rpx solid transparent;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.arrow-up {
|
||||
@extend .arrow;
|
||||
transform: rotate(-235deg);
|
||||
}
|
||||
|
||||
.multipleChoice {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.defaultValue {
|
||||
position: absolute;
|
||||
left: 20rpx;
|
||||
}
|
||||
|
||||
.option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #f4f4f5;
|
||||
border-radius: 10rpx;
|
||||
font-size: 24rpx;
|
||||
color: #aa93b1;
|
||||
padding: 6rpx 12rpx;
|
||||
|
||||
.img {
|
||||
margin-left: 4rpx;
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.more {
|
||||
background-color: #f4f4f5;
|
||||
border-radius: 10rpx;
|
||||
font-size: 24rpx;
|
||||
color: #aa93b1;
|
||||
margin-left: 10rpx;
|
||||
padding: 6rpx 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
position: absolute;
|
||||
margin-top: 20rpx;
|
||||
padding: 20rpx;
|
||||
border-radius: 4px;
|
||||
background-color: #fff;
|
||||
box-shadow: rgba(0, 0, 0, 0.5) 0px 3px 8px;
|
||||
z-index: 999;
|
||||
max-height: 300rpx;
|
||||
overflow-y: auto;
|
||||
|
||||
.item {
|
||||
padding: 10rpx;
|
||||
height: 60rpx;
|
||||
line-height: 40rpx;
|
||||
margin-bottom: 10rpx;
|
||||
font-size: 28px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.choose {
|
||||
background-color: #f5f7fa;
|
||||
color: #409eff;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
.animation-top {
|
||||
animation-name: slide-top;
|
||||
animation-duration: 0.5s;
|
||||
animation-timing-function: ease-out;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.animation-bottom {
|
||||
animation-name: slide-bottom;
|
||||
animation-duration: 0.2s;
|
||||
animation-timing-function: ease-out;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
@keyframes slide-top {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(-20%);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slide-bottom {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translateY(-20%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
// border: 2rpx solid #409eff;
|
||||
}
|
||||
|
||||
.contentMask {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 998;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user