Compare commits
14 Commits
e2fc723655
...
05a69374ea
Author | SHA1 | Date |
---|---|---|
zmj | 05a69374ea | |
zmj | 4220fd42ad | |
zmj | 6bfc0b0d48 | |
zmj | de66593e4a | |
zmj | 02faeccc96 | |
zmj | b6b5fbd790 | |
zmj | aa324b5ceb | |
weipengfei | acebf1a3ac | |
weipengfei | 83a8306ea4 | |
zmj | 8c33ae1516 | |
zmj | ca9c5bfbf1 | |
zmj | 2a1e112e57 | |
weipengfei | 6f6ceda684 | |
weipengfei | bdf4b08ef2 |
2
App.vue
2
App.vue
|
@ -4,7 +4,7 @@
|
||||||
console.log('App Launch');
|
console.log('App Launch');
|
||||||
},
|
},
|
||||||
onShow: function() {
|
onShow: function() {
|
||||||
console.log('App Show')
|
console.log('App Show');
|
||||||
},
|
},
|
||||||
onHide: function() {
|
onHide: function() {
|
||||||
console.log('App Hide');
|
console.log('App Hide');
|
||||||
|
|
|
@ -22,3 +22,11 @@ export const villageListApi = (data) => {
|
||||||
export const brigadeListApi = (data) => {
|
export const brigadeListApi = (data) => {
|
||||||
return request.get('/brigade', data);
|
return request.get('/brigade', data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getMassageCode = (data) => {
|
||||||
|
return request.post('/brigade', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const setPayPassword = (data) => {
|
||||||
|
return request.post('/brigade', data);
|
||||||
|
}
|
|
@ -86,7 +86,7 @@
|
||||||
|
|
||||||
const change = () => {
|
const change = () => {
|
||||||
if (+datas.value.cart_num < +datas.value.batch) return uni.$u.toast(
|
if (+datas.value.cart_num < +datas.value.batch) return uni.$u.toast(
|
||||||
`购买数量不能小于${datas.value.cart_num}${datas.value.unit_name}`);
|
`购买数量不能小于${datas.value.batch}${datas.value.unit_name}`);
|
||||||
if (subtotal.value <= 0) {
|
if (subtotal.value <= 0) {
|
||||||
uni.$u.toast('金额不可小于等于0');
|
uni.$u.toast('金额不可小于等于0');
|
||||||
datas.value.cart_num = '';
|
datas.value.cart_num = '';
|
||||||
|
@ -97,8 +97,8 @@
|
||||||
|
|
||||||
const subtotal = computed(() => {
|
const subtotal = computed(() => {
|
||||||
let num = +datas.value.cart_num || 0;
|
let num = +datas.value.cart_num || 0;
|
||||||
let sell = +datas.value.sell || datas.value.price;
|
let sell = +datas.value.sell || +datas.value.price;
|
||||||
return Math.ceil(num * sell * 100) / 100
|
return Number(num * sell * 100 / 100).toFixed(2)
|
||||||
})
|
})
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
<template>
|
||||||
|
<!-- <up-popup ref="popup" type="bottom" :mask-background-color="isPay?'rgba(0,0,0,.8)':'transparent'" safeArea
|
||||||
|
backgroundColor="transparent" :animation="true" @maskClick="maskClick">
|
||||||
|
<view class="popup-wrap" :style="{'border-radius':isPay?'': 0}">
|
||||||
|
<view class="paybox" v-if="isPay">
|
||||||
|
<view class="paybox-title">
|
||||||
|
<view class="paybox-title-left"></view>
|
||||||
|
<view class="paybox-title-middle">{{title}}</view>
|
||||||
|
<view class="paybox-titler-right" @click="handleClose">
|
||||||
|
<up-icon name="close" size="18" color="#666" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="paybox-input">
|
||||||
|
<u-code-input v-model="value" mode="box" dot readonly></u-code-input>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="keyboard">
|
||||||
|
<view class="keyboard-left" :style="{width:isPay?'100%':''}">
|
||||||
|
<block v-for="(item,indx) in keys" :key="indx">
|
||||||
|
<view class="keyboard-left-item active del" v-if="item=='del'" @click="handleClick(item)">
|
||||||
|
<image style="width: 48rpx;height: 48rpx;" src="@/static/del.webp" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="keyboard-left-item word active" :style="{width:isPay?'0%':'',border:isPay?'0':''}"
|
||||||
|
v-else-if="item == '.'" @click="handleClick(item)">
|
||||||
|
{{isPay?'':item}}
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="keyboard-left-item word active" :style="{width:(isPay && item == '0')?'66.66%':''}"
|
||||||
|
v-else @click="handleClick(item)">
|
||||||
|
{{item}}
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
<view class="keyboard-right" :style="{width:isPay?'0%':''}">
|
||||||
|
<view class="keyboard-right-clear word active" @click="handleClear">清空</view>
|
||||||
|
<view class="keyboard-right-pay word active-pay" @click="handlePay">{{txt}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</up-popup> -->
|
||||||
|
<view class="">
|
||||||
|
sds
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup></script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.popup-wrap {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 30rpx 30rpx 0 0;
|
||||||
|
|
||||||
|
.paybox {
|
||||||
|
.paybox-title {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 40rpx;
|
||||||
|
|
||||||
|
.paybox-title-left {}
|
||||||
|
|
||||||
|
.paybox-title-middle {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paybox-titler-right {}
|
||||||
|
}
|
||||||
|
|
||||||
|
.paybox-input {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
|
||||||
|
:deep(.u-code-input__item) {
|
||||||
|
background-color: #E6E6E6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
border: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.keyboard {
|
||||||
|
display: flex;
|
||||||
|
padding-bottom: 20rpx;
|
||||||
|
border-top: 2rpx solid #E6E6E6;
|
||||||
|
|
||||||
|
.keyboard-left {
|
||||||
|
width: 75%;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
.keyboard-left-item {
|
||||||
|
width: 33.3%;
|
||||||
|
height: 120rpx;
|
||||||
|
line-height: 102rpx;
|
||||||
|
border-bottom: 2rpx solid #E6E6E6;
|
||||||
|
border-right: 2rpx solid #E6E6E6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.del {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.keyboard-right {
|
||||||
|
width: 25%;
|
||||||
|
|
||||||
|
.keyboard-right-clear {
|
||||||
|
width: 100%;
|
||||||
|
height: 120rpx;
|
||||||
|
line-height: 120rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.keyboard-right-pay {
|
||||||
|
width: 100%;
|
||||||
|
height: 360rpx;
|
||||||
|
line-height: 360rpx;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #40AE36;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.word {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 34rpx;
|
||||||
|
color: #000000;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active:active {
|
||||||
|
background-color: rgba(232, 232, 232, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.active-pay:active {
|
||||||
|
opacity: .9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -10,7 +10,7 @@ switch (env) {
|
||||||
BASE_URL = 'https://test-multi-store.lihaink.cn';
|
BASE_URL = 'https://test-multi-store.lihaink.cn';
|
||||||
break;
|
break;
|
||||||
case 'liu':
|
case 'liu':
|
||||||
BASE_URL = 'http://192.168.1.22:8545';
|
BASE_URL = 'http://192.168.1.201:8545';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BASE_URL = 'https://multi-store.lihaink.cn';
|
BASE_URL = 'https://multi-store.lihaink.cn';
|
||||||
|
|
|
@ -89,6 +89,7 @@
|
||||||
|
|
||||||
// 门店选择
|
// 门店选择
|
||||||
const onChooseShop = (item) => {
|
const onChooseShop = (item) => {
|
||||||
|
return
|
||||||
currShop.value = item.id;
|
currShop.value = item.id;
|
||||||
uni.setStorageSync('STORE_INFO', JSON.stringify(item));
|
uni.setStorageSync('STORE_INFO', JSON.stringify(item));
|
||||||
// 如果选择了新店铺,删除之前的分享信息
|
// 如果选择了新店铺,删除之前的分享信息
|
||||||
|
@ -161,10 +162,8 @@
|
||||||
const getLocation = () => {
|
const getLocation = () => {
|
||||||
let location = uni.getStorageSync('location');
|
let location = uni.getStorageSync('location');
|
||||||
if (location) {
|
if (location) {
|
||||||
let [lng, lat] = location.split(',');
|
queryParams.longitude = location.lat
|
||||||
queryParams.longitude = lng;
|
queryParams.latitude = location.long
|
||||||
queryParams.latitude = lat;
|
|
||||||
|
|
||||||
// 加载店铺列表
|
// 加载店铺列表
|
||||||
getShopList();
|
getShopList();
|
||||||
} else {
|
} else {
|
||||||
|
@ -178,7 +177,10 @@
|
||||||
getShopList();
|
getShopList();
|
||||||
|
|
||||||
// 避免下次再获取
|
// 避免下次再获取
|
||||||
uni.setStorageSync('location', `${res.longitude},${res.latitude}`)
|
uni.setStorageSync('location', {
|
||||||
|
lat: queryParams.latitude,
|
||||||
|
long: queryParams.longitude
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,6 +161,13 @@
|
||||||
"navigationBarTitleText": "确认订单",
|
"navigationBarTitleText": "确认订单",
|
||||||
"enablePullDownRefresh": false
|
"enablePullDownRefresh": false
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "setPayPassword/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "设置密码",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -228,6 +235,8 @@
|
||||||
"enablePullDownRefresh": true
|
"enablePullDownRefresh": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
@ -109,8 +109,15 @@
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view style="width: 200rpx;">
|
<view style="width: 200rpx;">
|
||||||
<up-button color="#20b128" shape="circle" :disabled="!checkAll" @click="settleAccounts">去结算<text
|
<up-button color="#20b128" shape="circle" :disabled="!checkAll || c_price0<500 "
|
||||||
v-if="checkAll">({{checkAll}})</text></up-button>
|
@click="settleAccounts">
|
||||||
|
<view class="" v-if='c_price0>=500'>
|
||||||
|
去结算<text v-if="checkAll">({{checkAll}})</text>
|
||||||
|
</view>
|
||||||
|
<view class="" v-else>
|
||||||
|
¥500起订
|
||||||
|
</view>
|
||||||
|
</up-button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-else class="btn-boxs">
|
<view v-else class="btn-boxs">
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
<view class="store-info">
|
<view class="store-info">
|
||||||
<view style="display: flex;font-size: 30rpx;font-weight: bold;">
|
<view style="display: flex;font-size: 30rpx;font-weight: bold;">
|
||||||
<text v-if="userStore.userInfo.user_ship==1 || shareInfo.store_id"
|
<text v-if="userStore.userInfo.user_ship==1 || shareInfo.store_id"
|
||||||
style="max-width: 400rpx;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;">{{(shareInfo.real_name||userStore.userInfo.nickname) + '的供销个人门店' }}</text>
|
style="max-width: 400rpx;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;">{{(shareInfo.real_name||( userStore.userInfo.real_name|| userStore.userInfo.nickname)) + '的供销个人门店' }}</text>
|
||||||
<text v-else
|
<text v-else
|
||||||
style="max-width: 400rpx;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;">{{STORE_INFO.store_name}}</text>
|
style="max-width: 400rpx;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;">{{STORE_INFO.store_name}}</text>
|
||||||
<up-icon name="arrow-right"></up-icon>
|
<up-icon name="arrow-right"></up-icon>
|
||||||
|
@ -134,29 +134,29 @@
|
||||||
scroll-y @scrolltolower="loadMoreGood">
|
scroll-y @scrolltolower="loadMoreGood">
|
||||||
<view class="shop-item" v-for="(item, index) in goodList" :key="item.id"
|
<view class="shop-item" v-for="(item, index) in goodList" :key="item.id"
|
||||||
@click="openGoodPopup(item)">
|
@click="openGoodPopup(item)">
|
||||||
<view class="shop-img">
|
<view class="shop-img"
|
||||||
<up-image width="120rpx" height="120rpx" :src="item.image"></up-image>
|
:style="{backgroundImage: `url(${item.image}?x-oss-process=image/format,webp)`}">
|
||||||
</view>
|
</view>
|
||||||
<view class="shop-content">
|
<view class="shop-content">
|
||||||
<view class="title">
|
<view class="title">
|
||||||
<view class="name u-line-2">{{item.store_name}}</view>
|
<view class="name u-line-2">{{item.store_name}}</view>
|
||||||
<view class="tip u-line-1">
|
<view class="tip u-line-1">
|
||||||
<text>{{item.spec}}</text>
|
<text>{{item.spec}}</text>
|
||||||
<!-- <text>{{item.brand_name}}|</text> -->
|
|
||||||
<!-- <text>{{item.class_name}}|</text> -->
|
|
||||||
<!-- <text>{{item.unit_name}}</text> -->
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view style="display: flex;" v-if='userStore?.userInfo?.user_ship==1'>
|
||||||
|
<view class="price" style="margin-right: 10rpx;">¥{{item.vip_price}}</view>
|
||||||
|
<text class='price'>会员价</text>
|
||||||
|
</view>
|
||||||
<view class="price-btn">
|
<view class="price-btn">
|
||||||
<view class="price">¥{{item.price}}</view>
|
<view class="price" style="font-size: 24rpx;">¥{{item.price}}</view>
|
||||||
<view class="btn">
|
<view class="btn">
|
||||||
<u--icon name="plus-circle-fill" size="20" color="#20b128"></u--icon>
|
<u--icon name="plus-circle-fill" size="20" color="#20b128"></u--icon>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view style="width: 100%;height: 350rpx;"></view>
|
<view style="width: 100%;height: 470rpx;"></view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
@ -172,7 +172,8 @@
|
||||||
</view> -->
|
</view> -->
|
||||||
</view>
|
</view>
|
||||||
<view class="btn">
|
<view class="btn">
|
||||||
<up-button color="#20b128" :disabled="cartInfo.count==0" @click="settleAccounts">结算</up-button>
|
<up-button color="#20b128" :disabled="cartInfo.total_price<500" @click="settleAccounts">
|
||||||
|
{{cartInfo.total_price<500?"¥500起订":"结算" }} </up-button>
|
||||||
</view>
|
</view>
|
||||||
<view class="cart" @click="navTo('/pages/cart/cart')">
|
<view class="cart" @click="navTo('/pages/cart/cart')">
|
||||||
<image src="@/static/icon/cart.png"></image>
|
<image src="@/static/icon/cart.png"></image>
|
||||||
|
@ -222,8 +223,8 @@
|
||||||
import useUserStore from "@/store/user";
|
import useUserStore from "@/store/user";
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const STORE_INFO = reactive({
|
const STORE_INFO = reactive({
|
||||||
id: 5,
|
id: 4,
|
||||||
store_name: "测试"
|
store_name: "农(特)产品直营店"
|
||||||
})
|
})
|
||||||
|
|
||||||
const getStoreInfoFn = () => {
|
const getStoreInfoFn = () => {
|
||||||
|
@ -232,11 +233,14 @@
|
||||||
for (let key in data) {
|
for (let key in data) {
|
||||||
STORE_INFO[key] = data[key]
|
STORE_INFO[key] = data[key]
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
getStoreInfo().then(res => {
|
|
||||||
uni.setStorageSync("STORE_INFO", JSON.stringify(res.data))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
getStoreInfo().then(res => {
|
||||||
|
uni.setStorageSync("STORE_INFO", JSON.stringify(res.data));
|
||||||
|
let data = res.data;
|
||||||
|
for (let key in data) {
|
||||||
|
STORE_INFO[key] = data[key]
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
getStoreInfoFn()
|
getStoreInfoFn()
|
||||||
|
|
||||||
|
@ -249,7 +253,7 @@
|
||||||
.real_name || userStore.userInfo.nickname)
|
.real_name || userStore.userInfo.nickname)
|
||||||
}
|
}
|
||||||
let shareInfo = {
|
let shareInfo = {
|
||||||
title: userStore.userInfo.nickname,
|
title: (userStore.userInfo.real_name || userStore.userInfo.nickname) + '的供销个人门店',
|
||||||
path: '/pages/index/index' + shareStr,
|
path: '/pages/index/index' + shareStr,
|
||||||
imageUrl: STORE_INFO.image || '',
|
imageUrl: STORE_INFO.image || '',
|
||||||
success() {
|
success() {
|
||||||
|
@ -263,12 +267,14 @@
|
||||||
})
|
})
|
||||||
|
|
||||||
/*商品列表滚动隐藏头部导航 */
|
/*商品列表滚动隐藏头部导航 */
|
||||||
const instance = getCurrentInstance(); // 获取组件实例
|
|
||||||
const targetHeight = ref(0)
|
const targetHeight = ref(0)
|
||||||
|
let scoHeight = 0
|
||||||
const isScroll = ref(false)
|
const isScroll = ref(false)
|
||||||
let lastScollTop = 0
|
let lastScollTop = 0
|
||||||
const hideHeadView = (e) => {
|
const hideHeadView = (e) => {
|
||||||
if (e.detail.scrollTop <= 0 || e.detail.scrollTop >= targetHeight.value) return
|
if (e.detail.scrollTop < 100) return
|
||||||
|
if (e.detail.scrollTop <= 0 || e.detail.scrollTop > targetHeight.value)
|
||||||
|
return
|
||||||
isScroll.value = e.detail.scrollTop > lastScollTop
|
isScroll.value = e.detail.scrollTop > lastScollTop
|
||||||
lastScollTop = e.detail.scrollTop
|
lastScollTop = e.detail.scrollTop
|
||||||
}
|
}
|
||||||
|
@ -290,6 +296,8 @@
|
||||||
|
|
||||||
const leftActive = ref(0);
|
const leftActive = ref(0);
|
||||||
const changeTwo = (item, index) => {
|
const changeTwo = (item, index) => {
|
||||||
|
isScroll.value = false;
|
||||||
|
getWXDom(instance)
|
||||||
leftActive.value = item.id;
|
leftActive.value = item.id;
|
||||||
show.value = 0;
|
show.value = 0;
|
||||||
goodClassThree.value = item?.children || [];
|
goodClassThree.value = item?.children || [];
|
||||||
|
@ -334,7 +342,7 @@
|
||||||
|
|
||||||
const where = ref({
|
const where = ref({
|
||||||
page_no: 1,
|
page_no: 1,
|
||||||
page_size: 25,
|
page_size: 15,
|
||||||
name: '',
|
name: '',
|
||||||
order: '',
|
order: '',
|
||||||
store_name: '',
|
store_name: '',
|
||||||
|
@ -372,6 +380,8 @@
|
||||||
|
|
||||||
// 商品列表触底
|
// 商品列表触底
|
||||||
const loadMoreGood = () => {
|
const loadMoreGood = () => {
|
||||||
|
|
||||||
|
getWXDom(instance)
|
||||||
getGoodList(true);
|
getGoodList(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,6 +568,13 @@
|
||||||
store_id: ''
|
store_id: ''
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const getShareInfo = () => {
|
||||||
|
if (uni.getStorageSync('SHARE_INFO')) {
|
||||||
|
shareInfo.value = (uni.getStorageSync('SHARE_INFO'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getShareInfo()
|
||||||
|
|
||||||
onLoad(async (opt) => {
|
onLoad(async (opt) => {
|
||||||
where.value.store_id = opt.id || STORE_INFO.id;
|
where.value.store_id = opt.id || STORE_INFO.id;
|
||||||
// 店铺id
|
// 店铺id
|
||||||
|
@ -576,8 +593,10 @@
|
||||||
}
|
}
|
||||||
getgoodClassList(0);
|
getgoodClassList(0);
|
||||||
getGoodList();
|
getGoodList();
|
||||||
|
// #ifndef H5
|
||||||
// 胶囊布局信息
|
// 胶囊布局信息
|
||||||
btns.value = uni.getMenuButtonBoundingClientRect();
|
btns.value = uni.getMenuButtonBoundingClientRect();
|
||||||
|
// #endif
|
||||||
})
|
})
|
||||||
|
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
|
@ -597,8 +616,8 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
const instance = getCurrentInstance(); // 获取组件实例
|
let instance; // 获取组件实例
|
||||||
const getWXDom = () => {
|
const getWXDom = () => {
|
||||||
let query = uni.createSelectorQuery().in(instance).select("#drag_area");
|
let query = uni.createSelectorQuery().in(instance).select("#drag_area");
|
||||||
query.fields({
|
query.fields({
|
||||||
|
@ -606,12 +625,16 @@
|
||||||
scrollOffset: true,
|
scrollOffset: true,
|
||||||
},
|
},
|
||||||
(data) => {
|
(data) => {
|
||||||
|
scoHeight = data.scrollHeight
|
||||||
targetHeight.value = data.scrollHeight - data.height
|
targetHeight.value = data.scrollHeight - data.height
|
||||||
}
|
}
|
||||||
).exec();
|
).exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
instance = getCurrentInstance(); // 获取组件实例
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
getWXDom()
|
getWXDom(instance)
|
||||||
}, 500)
|
}, 500)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@ -919,6 +942,8 @@
|
||||||
margin-right: 20rpx;
|
margin-right: 20rpx;
|
||||||
border-radius: 14rpx;
|
border-radius: 14rpx;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
// background-image: url();
|
||||||
}
|
}
|
||||||
|
|
||||||
.shop-content {
|
.shop-content {
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<up-button @click="weixinLogin" color="#20B128" size="large"><up-icon name="weixin-fill"
|
<up-button @click="weixinLogin" color="#20B128" size="large"><up-icon name="weixin-fill"
|
||||||
color="#fff" size="28"></up-icon>微信快捷登录</up-button>
|
color="#fff" size="28"></up-icon>微信快捷登录</up-button>
|
||||||
</view>
|
</view>
|
||||||
<view class="btn">
|
<view class="btn" v-if="config.ENV=='dev'">
|
||||||
<up-button @click="navgo('/pages/login/test')" color="#20B128" size="large"><up-icon
|
<up-button @click="navgo('/pages/login/test')" color="#20B128" size="large"><up-icon
|
||||||
name="weixin-fill" color="#fff" size="28"></up-icon>账号登录</up-button>
|
name="weixin-fill" color="#fff" size="28"></up-icon>账号登录</up-button>
|
||||||
</view>
|
</view>
|
||||||
|
@ -96,6 +96,9 @@
|
||||||
import useUserStore from "@/store/user.js"
|
import useUserStore from "@/store/user.js"
|
||||||
import bindPhone from "@/components/bindPhone.vue"
|
import bindPhone from "@/components/bindPhone.vue"
|
||||||
import modal from "@/components/modal.vue"
|
import modal from "@/components/modal.vue"
|
||||||
|
import {
|
||||||
|
config
|
||||||
|
} from "@/config/app.js"
|
||||||
|
|
||||||
|
|
||||||
const showOfficial = ref(false);
|
const showOfficial = ref(false);
|
||||||
|
|
|
@ -44,20 +44,20 @@
|
||||||
|
|
||||||
<view class="rest">
|
<view class="rest">
|
||||||
<view class="rest-item">
|
<view class="rest-item">
|
||||||
<view class="rest-item-num">{{userInfo.now_money}}</view>
|
<view class="rest-item-num">{{userInfo.now_money||"0.00"}}</view>
|
||||||
<view class="rest-item-txt">余额</view>
|
<view class="rest-item-txt">余额</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="rest-item">
|
<view class="rest-item">
|
||||||
<view class="rest-item-num">{{userInfo.purchase_funds}}</view>
|
<view class="rest-item-num">{{userInfo.purchase_funds||'0.00'}}</view>
|
||||||
<view class="rest-item-txt">采购款</view>
|
<view class="rest-item-txt">采购款</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="rest-item">
|
<view class="rest-item">
|
||||||
<view class="rest-item-num">{{userInfo.return_money}}</view>
|
<view class="rest-item-num">{{userInfo.return_money||'0.00'}}</view>
|
||||||
<view class="rest-item-txt">返还金</view>
|
<view class="rest-item-txt">返还金</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="rest-item">
|
<view class="rest-item">
|
||||||
<view class="rest-item-num">{{userInfo.integral}}</view>
|
<view class="rest-item-num">{{userInfo.integral ||"0.00"}}</view>
|
||||||
<view class="rest-item-txt">礼品券</view>
|
<view class="rest-item-txt">礼品券</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
@ -107,8 +107,8 @@
|
||||||
|
|
||||||
<view class="card">
|
<view class="card">
|
||||||
<up-cell-group>
|
<up-cell-group>
|
||||||
<up-cell title="我的余额" :isLink="true" url="/pageQuota/Balance/index"></up-cell>
|
|
||||||
<up-cell title="我的地址" :isLink="true" url="/pagesOrder/addressList/addressList"></up-cell>
|
<up-cell title="我的地址" :isLink="true" url="/pagesOrder/addressList/addressList"></up-cell>
|
||||||
|
<up-cell title="支付密码" :isLink="true" url="/pagesOrder/setPayPassword/index"></up-cell>
|
||||||
</up-cell-group>
|
</up-cell-group>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|
|
@ -4,17 +4,17 @@
|
||||||
还剩<text>{{countDown}}</text>订单自动取消
|
还剩<text>{{countDown}}</text>订单自动取消
|
||||||
</view>
|
</view>
|
||||||
<view class="m-card m-address" style="margin-top: 20rpx;">
|
<view class="m-card m-address" style="margin-top: 20rpx;">
|
||||||
<view class="address-info" @click="callPhone(shopInfo.phone)">
|
<view class="address-info"
|
||||||
|
style='display: flex;justify-content: space-between;width: 690rpx;align-items: center;'
|
||||||
|
@click="callPhone(shopInfo.phone)">
|
||||||
<view class="top" style="align-items: flex-start;">
|
<view class="top" style="align-items: flex-start;">
|
||||||
<view style="color: #333;display: flex;align-items: center;">
|
<view style="color: #333;display: flex;align-items: center;flex-shrink: 0;">
|
||||||
<up-icon name="map"></up-icon>
|
<up-icon name="map"></up-icon>
|
||||||
<text style="margin: 0 10rpx;">自提点</text>
|
<text style="margin: 0 10rpx;">自提点</text>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="shopInfo.id">
|
<view v-if="shopInfo.id">
|
||||||
<view style="color: #333;">
|
<view style="color: #333;">
|
||||||
{{shopInfo.name}}
|
{{shopInfo.name}}
|
||||||
<!-- <text v-if="shopInfo.recommend"
|
|
||||||
style="font-size: 20rpx;color: #fff;background-color: #20b128;padding: 2rpx 5rpx;padding: 1rpx 4rpx;">推荐</text> -->
|
|
||||||
</view>
|
</view>
|
||||||
<view style="font-size: 24rpx;color: #333;">
|
<view style="font-size: 24rpx;color: #333;">
|
||||||
{{shopInfo.detailed_address}}
|
{{shopInfo.detailed_address}}
|
||||||
|
@ -24,16 +24,14 @@
|
||||||
<text style="margin-right: 10rpx;">{{shopInfo.name||shopInfo.mer_real_name}}</text>
|
<text style="margin-right: 10rpx;">{{shopInfo.name||shopInfo.mer_real_name}}</text>
|
||||||
<text>{{shopInfo.phone}}</text>
|
<text>{{shopInfo.phone}}</text>
|
||||||
</view>
|
</view>
|
||||||
<!-- <text v-if="shopInfo.distance"
|
|
||||||
style="color: #20b128;font-size: 22rpx;border: 1px solid #20b128;border-radius: 4rpx;">{{shopInfo.distance}}</text> -->
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view @click.stop="navgo('/multipleShop/index/index')"
|
||||||
|
style="padding: 20rpx;background-color:#20B128;color: white;border-radius: 40rpx;flex-shrink: 0;">
|
||||||
|
所有提货点
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- <view class="address-btn" v-if="datas.paid==0">
|
|
||||||
<view style="width: 80px;"><up-button @click="shopListShow=true" size="small" shape="circle"
|
|
||||||
color="#f6f6f6" :customStyle="{color:'#666666'}">修改</up-button></view>
|
|
||||||
</view> -->
|
|
||||||
</view>
|
</view>
|
||||||
<view class="m-card m-address" style="margin-top: 20rpx;" v-if="addressInfo && addressInfo.address_id">
|
<view class="m-card m-address" style="margin-top: 20rpx;" v-if="addressInfo && addressInfo.address_id">
|
||||||
<view class="address-info">
|
<view class="address-info">
|
||||||
|
@ -237,11 +235,12 @@
|
||||||
const datas = ref({})
|
const datas = ref({})
|
||||||
const getDetails = () => {
|
const getDetails = () => {
|
||||||
orderDetailApi({
|
orderDetailApi({
|
||||||
order_id: datas.value.id
|
order_id: datas.value.id,
|
||||||
|
...location
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
datas.value = res.data;
|
datas.value = res.data;
|
||||||
options.code = datas.value.verify_code; // 生成条形码的值
|
options.code = datas.value.verify_code; // 生成条形码的值
|
||||||
shopInfo.value = res.data.store_info;
|
shopInfo.value = res.data.near_store;
|
||||||
if (addressList.value.length > 0 && res.data.paid) {
|
if (addressList.value.length > 0 && res.data.paid) {
|
||||||
addressInfo.value = addressList.value.find(item => item.address_id == res.data.address_id);
|
addressInfo.value = addressList.value.find(item => item.address_id == res.data.address_id);
|
||||||
} else {
|
} else {
|
||||||
|
@ -456,13 +455,37 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取位置
|
||||||
|
let location = {
|
||||||
|
lat: "",
|
||||||
|
long: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
const getLocation = () => {
|
||||||
|
if (uni.getStorageSync('location')) {
|
||||||
|
location = uni.getStorageSync('location')
|
||||||
|
} else {
|
||||||
|
uni.getLocation({
|
||||||
|
type: "gcj02",
|
||||||
|
success(res) {
|
||||||
|
location.lat = res.latitude;
|
||||||
|
location.long = res.longitude;
|
||||||
|
uni.setStorageSync('location', location)
|
||||||
|
return getDetails()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
getDetails()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
onLoad((option) => {
|
onLoad((option) => {
|
||||||
uni.setNavigationBarTitle({
|
uni.setNavigationBarTitle({
|
||||||
title: option.type == 0 ? '等待付款' : '订单详情'
|
title: option.type == 0 ? '等待付款' : '订单详情'
|
||||||
});
|
});
|
||||||
if (option.id) {
|
if (option.id) {
|
||||||
datas.value.id = option.id;
|
datas.value.id = option.id;
|
||||||
getDetails()
|
getLocation()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -470,6 +493,12 @@
|
||||||
clearInterval(timer);
|
clearInterval(timer);
|
||||||
console.log("清除");
|
console.log("清除");
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const navgo = (url) => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
<template>
|
||||||
|
<view class='card'>
|
||||||
|
<up-input v-model="form.phone" placeholder="手机号" border="none"></up-input>
|
||||||
|
<up-line color="#D3E3FD" style="margin: 30rpx 0;"></up-line>
|
||||||
|
<view style="display: flex;justify-content: space-between;align-items: center;">
|
||||||
|
<up-input v-model="form.code" placeholder="验证码" border="none" type='number'></up-input>
|
||||||
|
<view class="code-btn">
|
||||||
|
<up-line color="grey" direction="col" length="30rpx" style="margin: 0 20rpx;"></up-line>
|
||||||
|
<text class='btn-text' style="color: grey;" v-if='cutDown'>重新获取({{cutDown}})</text>
|
||||||
|
<text @click="getCode" class='btn-text' v-else> {{flag?'获取验证码':'重新获取' }} </text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class='card'>
|
||||||
|
<!-- type='password' -->
|
||||||
|
<view @click="showKeyBorad=true,type=1">
|
||||||
|
<up-input style="pointer-events: none;" v-model="form.password" placeholder="请输入你的密码" border="none"
|
||||||
|
readonly></up-input>
|
||||||
|
</view>
|
||||||
|
<up-line color="#D3E3FD" style="margin: 30rpx 0;"></up-line>
|
||||||
|
<view @click="showKeyBorad=true,type=2">
|
||||||
|
<up-input style="pointer-events: none;" v-model="form.rePassword" placeholder="请再次输入你的密码" border="none"
|
||||||
|
readonly></up-input>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class='submit-btn'>
|
||||||
|
<up-button color="#20B128" shape="circle" @click="submit">确认</up-button>
|
||||||
|
</view>
|
||||||
|
<up-keyboard dotDisabled safeAreaInsetBottom ref="uKeyboard" @close="showKeyBorad=false" mode="number"
|
||||||
|
:tooltip="false" :show="showKeyBorad" @change='onKetDown' @backspace='backspaceFn' />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import useUserStore from "@/store/user";
|
||||||
|
import {
|
||||||
|
getMassageCode,
|
||||||
|
setPayPassword
|
||||||
|
} from "@/api/address.js"
|
||||||
|
import {
|
||||||
|
ref,
|
||||||
|
reactive
|
||||||
|
} from "vue"
|
||||||
|
|
||||||
|
const userInfo = useUserStore().userInfo;
|
||||||
|
const form = reactive({
|
||||||
|
phone: userInfo.mobile, //手机号
|
||||||
|
code: "", //验证码
|
||||||
|
password: "", //6位数密码
|
||||||
|
rePassword: "" //确认密码
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取验证码
|
||||||
|
const cutDown = ref(0)
|
||||||
|
const flag = ref(true)
|
||||||
|
const code = ref('')
|
||||||
|
const checkPhone = (phone) => {
|
||||||
|
const regex = /^1[3-9]\d{9}$/;
|
||||||
|
return regex.test(phone) ? true : false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const getCode = async () => {
|
||||||
|
if (!checkPhone(phone.value)) return uni.$u.toast('请输入正确的手机号')
|
||||||
|
await getMassageCode()
|
||||||
|
flag.value = false
|
||||||
|
cutDown.value = 10
|
||||||
|
let timer = setInterval(() => {
|
||||||
|
cutDown.value--
|
||||||
|
if (cutDown.value <= 0) clearInterval(timer)
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
// 获取验证码结束
|
||||||
|
|
||||||
|
// 键盘事件
|
||||||
|
const showKeyBorad = ref(false)
|
||||||
|
const type = ref(1) // 1 输入密码 2 再次输入密码
|
||||||
|
|
||||||
|
const onKetDown = (e) => {
|
||||||
|
if (type.value == 1) {
|
||||||
|
form.password.length < 6 ?
|
||||||
|
form.password += e :
|
||||||
|
showKeyBorad.value = false
|
||||||
|
} else {
|
||||||
|
form.rePassword.length < 6 ?
|
||||||
|
form.rePassword += e :
|
||||||
|
showKeyBorad.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const backspaceFn = () => {
|
||||||
|
if (type.value == 1) {
|
||||||
|
form.password = form.password.slice(0, -1);
|
||||||
|
} else {
|
||||||
|
form.rePassword = form.rePassword.slice(0, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 键盘事件结束
|
||||||
|
const submit = async () => {
|
||||||
|
if (!form.code) return uni.$u.toast('请输入验证码');
|
||||||
|
if (form.password !== form.rePassword) return uni.$u.toast('两次密码不一致');
|
||||||
|
await setPayPassword(...form)
|
||||||
|
uni.$u.toast('设置成功')
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.navigateBack()
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang='scss'>
|
||||||
|
.card {
|
||||||
|
padding: 50rpx;
|
||||||
|
background-color: white;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
padding-bottom: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-btn {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 100rpx;
|
||||||
|
width: 710rpx;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-text {
|
||||||
|
color: #20B128;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="">
|
<view class="">
|
||||||
<view class="m-card m-address">
|
<!-- <view class="m-card m-address">
|
||||||
<view class="address-info" @click="showAddress = true" v-if='orderInfo.shipping_type == 1'>
|
<view class="address-info" @click="showAddress = true" v-if='orderInfo.shipping_type == 1'>
|
||||||
<view class="top">
|
<view class="top">
|
||||||
<up-icon name="account"></up-icon>
|
<up-icon name="account"></up-icon>
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view> -->
|
||||||
<view class="m-card m-good" v-for="(item, index) in cartList" :key="index">
|
<view class="m-card m-good" v-for="(item, index) in cartList" :key="index">
|
||||||
<view class="image">
|
<view class="image">
|
||||||
<up-image width="160rpx" height="160rpx" :src="item.imgs"></up-image>
|
<up-image width="160rpx" height="160rpx" :src="item.imgs"></up-image>
|
||||||
|
@ -72,8 +72,8 @@
|
||||||
</view>
|
</view>
|
||||||
<view class="row" v-if="userInfo.user_ship==1 ">
|
<view class="row" v-if="userInfo.user_ship==1 ">
|
||||||
<view>消费返利</view>
|
<view>消费返利</view>
|
||||||
<view style="color: red;">
|
<view>
|
||||||
<text>-¥</text>{{ c_price(orderInfo.activities, 0) }}<text>.{{ c_price(orderInfo.activities, 1) }}</text>
|
<text>¥</text>{{ c_price(orderInfo.activity_price, 0) }}<text>.{{ c_price(orderInfo.activity_price, 1) }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
@ -93,9 +93,11 @@
|
||||||
|
|
||||||
<view class="row"
|
<view class="row"
|
||||||
v-if="userInfo.user_ship == 4 || userInfo.user_ship == 5 || userInfo.user_ship == 6 || userInfo.user_ship == 1">
|
v-if="userInfo.user_ship == 4 || userInfo.user_ship == 5 || userInfo.user_ship == 6 || userInfo.user_ship == 1">
|
||||||
|
<!-- <view class="row"> -->
|
||||||
<view class="icon-text">
|
<view class="icon-text">
|
||||||
<image src="@/static/icon/YEZF.png" style="width:40rpx;height: 40rpx;" />
|
<image src="@/static/icon/YEZF.png" style="width:40rpx;height: 40rpx;" />
|
||||||
<text style="margin-left: 20rpx;font-size: 26rpx;">余额支付</text>
|
<text style="margin-left: 20rpx;font-size: 26rpx;">余额支付</text>
|
||||||
|
<text style="margin-left: 20rpx;font-size: 22rpx;color: #FFB76D;">( 可用¥{{userInfo.now_money}} )</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="icon" @click="onChoosePaytype(3)">
|
<view class="icon" @click="onChoosePaytype(3)">
|
||||||
<image v-if="pay_type == 3" src="@/static/icon/check.png" />
|
<image v-if="pay_type == 3" src="@/static/icon/check.png" />
|
||||||
|
@ -108,6 +110,7 @@
|
||||||
<view class="icon-text">
|
<view class="icon-text">
|
||||||
<image src="@/static/icon/cgkzf.png" style="width:40rpx;height: 40rpx;" />
|
<image src="@/static/icon/cgkzf.png" style="width:40rpx;height: 40rpx;" />
|
||||||
<text style="margin-left: 20rpx;font-size: 26rpx;">采购款支付</text>
|
<text style="margin-left: 20rpx;font-size: 26rpx;">采购款支付</text>
|
||||||
|
<text style="margin-left: 20rpx;font-size: 22rpx;color: #1296DB;">( 可用¥{{userInfo.purchase_funds}} )</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="icon" @click="onChoosePaytype(18)">
|
<view class="icon" @click="onChoosePaytype(18)">
|
||||||
<image v-if="pay_type == 18" src="@/static/icon/check.png" />
|
<image v-if="pay_type == 18" src="@/static/icon/check.png" />
|
||||||
|
@ -352,7 +355,7 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const pay_type = ref('');
|
const pay_type = ref('7');
|
||||||
|
|
||||||
const createOrder = () => {
|
const createOrder = () => {
|
||||||
if (!pay_type.value) return uni.$u.toast('请选择支付方式');
|
if (!pay_type.value) return uni.$u.toast('请选择支付方式');
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,24 @@
|
||||||
|
## 1.3.3(2024-04-23)
|
||||||
|
- 修复 当元素会受变量影响自动隐藏的bug
|
||||||
|
## 1.3.2(2023-05-04)
|
||||||
|
- 修复 NVUE 平台报错的问题
|
||||||
|
## 1.3.1(2021-11-23)
|
||||||
|
- 修复 init 方法初始化问题
|
||||||
|
## 1.3.0(2021-11-19)
|
||||||
|
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
|
||||||
|
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-transition](https://uniapp.dcloud.io/component/uniui/uni-transition)
|
||||||
|
## 1.2.1(2021-09-27)
|
||||||
|
- 修复 init 方法不生效的 Bug
|
||||||
|
## 1.2.0(2021-07-30)
|
||||||
|
- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||||
|
## 1.1.1(2021-05-12)
|
||||||
|
- 新增 示例地址
|
||||||
|
- 修复 示例项目缺少组件的 Bug
|
||||||
|
## 1.1.0(2021-04-22)
|
||||||
|
- 新增 通过方法自定义动画
|
||||||
|
- 新增 custom-class 非 NVUE 平台支持自定义 class 定制样式
|
||||||
|
- 优化 动画触发逻辑,使动画更流畅
|
||||||
|
- 优化 支持单独的动画类型
|
||||||
|
- 优化 文档示例
|
||||||
|
## 1.0.2(2021-02-05)
|
||||||
|
- 调整为 uni_modules 目录规范
|
|
@ -0,0 +1,131 @@
|
||||||
|
// const defaultOption = {
|
||||||
|
// duration: 300,
|
||||||
|
// timingFunction: 'linear',
|
||||||
|
// delay: 0,
|
||||||
|
// transformOrigin: '50% 50% 0'
|
||||||
|
// }
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
const nvueAnimation = uni.requireNativePlugin('animation')
|
||||||
|
// #endif
|
||||||
|
class MPAnimation {
|
||||||
|
constructor(options, _this) {
|
||||||
|
this.options = options
|
||||||
|
// 在iOS10+QQ小程序平台下,传给原生的对象一定是个普通对象而不是Proxy对象,否则会报parameter should be Object instead of ProxyObject的错误
|
||||||
|
this.animation = uni.createAnimation({
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
this.currentStepAnimates = {}
|
||||||
|
this.next = 0
|
||||||
|
this.$ = _this
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_nvuePushAnimates(type, args) {
|
||||||
|
let aniObj = this.currentStepAnimates[this.next]
|
||||||
|
let styles = {}
|
||||||
|
if (!aniObj) {
|
||||||
|
styles = {
|
||||||
|
styles: {},
|
||||||
|
config: {}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
styles = aniObj
|
||||||
|
}
|
||||||
|
if (animateTypes1.includes(type)) {
|
||||||
|
if (!styles.styles.transform) {
|
||||||
|
styles.styles.transform = ''
|
||||||
|
}
|
||||||
|
let unit = ''
|
||||||
|
if(type === 'rotate'){
|
||||||
|
unit = 'deg'
|
||||||
|
}
|
||||||
|
styles.styles.transform += `${type}(${args+unit}) `
|
||||||
|
} else {
|
||||||
|
styles.styles[type] = `${args}`
|
||||||
|
}
|
||||||
|
this.currentStepAnimates[this.next] = styles
|
||||||
|
}
|
||||||
|
_animateRun(styles = {}, config = {}) {
|
||||||
|
let ref = this.$.$refs['ani'].ref
|
||||||
|
if (!ref) return
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
nvueAnimation.transition(ref, {
|
||||||
|
styles,
|
||||||
|
...config
|
||||||
|
}, res => {
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
_nvueNextAnimate(animates, step = 0, fn) {
|
||||||
|
let obj = animates[step]
|
||||||
|
if (obj) {
|
||||||
|
let {
|
||||||
|
styles,
|
||||||
|
config
|
||||||
|
} = obj
|
||||||
|
this._animateRun(styles, config).then(() => {
|
||||||
|
step += 1
|
||||||
|
this._nvueNextAnimate(animates, step, fn)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.currentStepAnimates = {}
|
||||||
|
typeof fn === 'function' && fn()
|
||||||
|
this.isEnd = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step(config = {}) {
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
this.animation.step(config)
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
|
||||||
|
this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
|
||||||
|
this.next++
|
||||||
|
// #endif
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
run(fn) {
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
this.$.animationData = this.animation.export()
|
||||||
|
this.$.timer = setTimeout(() => {
|
||||||
|
typeof fn === 'function' && fn()
|
||||||
|
}, this.$.durationTime)
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
this.isEnd = false
|
||||||
|
let ref = this.$.$refs['ani'] && this.$.$refs['ani'].ref
|
||||||
|
if(!ref) return
|
||||||
|
this._nvueNextAnimate(this.currentStepAnimates, 0, fn)
|
||||||
|
this.next = 0
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const animateTypes1 = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
|
||||||
|
'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
|
||||||
|
'translateZ'
|
||||||
|
]
|
||||||
|
const animateTypes2 = ['opacity', 'backgroundColor']
|
||||||
|
const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom']
|
||||||
|
animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
|
||||||
|
MPAnimation.prototype[type] = function(...args) {
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
this.animation[type](...args)
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
this._nvuePushAnimates(type, args)
|
||||||
|
// #endif
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export function createAnimation(option, _this) {
|
||||||
|
if(!_this) return
|
||||||
|
clearTimeout(_this.timer)
|
||||||
|
return new MPAnimation(option, _this)
|
||||||
|
}
|
|
@ -0,0 +1,286 @@
|
||||||
|
<template>
|
||||||
|
<!-- #ifndef APP-NVUE -->
|
||||||
|
<view v-show="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"><slot></slot></view>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifdef APP-NVUE -->
|
||||||
|
<view v-if="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"><slot></slot></view>
|
||||||
|
<!-- #endif -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { createAnimation } from './createAnimation'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transition 过渡动画
|
||||||
|
* @description 简单过渡动画组件
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=985
|
||||||
|
* @property {Boolean} show = [false|true] 控制组件显示或隐藏
|
||||||
|
* @property {Array|String} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型
|
||||||
|
* @value fade 渐隐渐出过渡
|
||||||
|
* @value slide-top 由上至下过渡
|
||||||
|
* @value slide-right 由右至左过渡
|
||||||
|
* @value slide-bottom 由下至上过渡
|
||||||
|
* @value slide-left 由左至右过渡
|
||||||
|
* @value zoom-in 由小到大过渡
|
||||||
|
* @value zoom-out 由大到小过渡
|
||||||
|
* @property {Number} duration 过渡动画持续时间
|
||||||
|
* @property {Object} styles 组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red`
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'uniTransition',
|
||||||
|
emits:['click','change'],
|
||||||
|
props: {
|
||||||
|
show: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
modeClass: {
|
||||||
|
type: [Array, String],
|
||||||
|
default() {
|
||||||
|
return 'fade'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
duration: {
|
||||||
|
type: Number,
|
||||||
|
default: 300
|
||||||
|
},
|
||||||
|
styles: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
customClass:{
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
onceRender:{
|
||||||
|
type:Boolean,
|
||||||
|
default:false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isShow: false,
|
||||||
|
transform: '',
|
||||||
|
opacity: 1,
|
||||||
|
animationData: {},
|
||||||
|
durationTime: 300,
|
||||||
|
config: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
show: {
|
||||||
|
handler(newVal) {
|
||||||
|
if (newVal) {
|
||||||
|
this.open()
|
||||||
|
} else {
|
||||||
|
// 避免上来就执行 close,导致动画错乱
|
||||||
|
if (this.isShow) {
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 生成样式数据
|
||||||
|
stylesObject() {
|
||||||
|
let styles = {
|
||||||
|
...this.styles,
|
||||||
|
'transition-duration': this.duration / 1000 + 's'
|
||||||
|
}
|
||||||
|
let transform = ''
|
||||||
|
for (let i in styles) {
|
||||||
|
let line = this.toLine(i)
|
||||||
|
transform += line + ':' + styles[i] + ';'
|
||||||
|
}
|
||||||
|
return transform
|
||||||
|
},
|
||||||
|
// 初始化动画条件
|
||||||
|
transformStyles() {
|
||||||
|
return 'transform:' + this.transform + ';' + 'opacity:' + this.opacity + ';' + this.stylesObject
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// 动画默认配置
|
||||||
|
this.config = {
|
||||||
|
duration: this.duration,
|
||||||
|
timingFunction: 'ease',
|
||||||
|
transformOrigin: '50% 50%',
|
||||||
|
delay: 0
|
||||||
|
}
|
||||||
|
this.durationTime = this.duration
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* ref 触发 初始化动画
|
||||||
|
*/
|
||||||
|
init(obj = {}) {
|
||||||
|
if (obj.duration) {
|
||||||
|
this.durationTime = obj.duration
|
||||||
|
}
|
||||||
|
this.animation = createAnimation(Object.assign(this.config, obj),this)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 点击组件触发回调
|
||||||
|
*/
|
||||||
|
onClick() {
|
||||||
|
this.$emit('click', {
|
||||||
|
detail: this.isShow
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* ref 触发 动画分组
|
||||||
|
* @param {Object} obj
|
||||||
|
*/
|
||||||
|
step(obj, config = {}) {
|
||||||
|
if (!this.animation) return
|
||||||
|
for (let i in obj) {
|
||||||
|
try {
|
||||||
|
if(typeof obj[i] === 'object'){
|
||||||
|
this.animation[i](...obj[i])
|
||||||
|
}else{
|
||||||
|
this.animation[i](obj[i])
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`方法 ${i} 不存在`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.animation.step(config)
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* ref 触发 执行动画
|
||||||
|
*/
|
||||||
|
run(fn) {
|
||||||
|
if (!this.animation) return
|
||||||
|
this.animation.run(fn)
|
||||||
|
},
|
||||||
|
// 开始过度动画
|
||||||
|
open() {
|
||||||
|
clearTimeout(this.timer)
|
||||||
|
this.transform = ''
|
||||||
|
this.isShow = true
|
||||||
|
let { opacity, transform } = this.styleInit(false)
|
||||||
|
if (typeof opacity !== 'undefined') {
|
||||||
|
this.opacity = opacity
|
||||||
|
}
|
||||||
|
this.transform = transform
|
||||||
|
// 确保动态样式已经生效后,执行动画,如果不加 nextTick ,会导致 wx 动画执行异常
|
||||||
|
this.$nextTick(() => {
|
||||||
|
// TODO 定时器保证动画完全执行,目前有些问题,后面会取消定时器
|
||||||
|
this.timer = setTimeout(() => {
|
||||||
|
this.animation = createAnimation(this.config, this)
|
||||||
|
this.tranfromInit(false).step()
|
||||||
|
this.animation.run()
|
||||||
|
this.$emit('change', {
|
||||||
|
detail: this.isShow
|
||||||
|
})
|
||||||
|
}, 20)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 关闭过度动画
|
||||||
|
close(type) {
|
||||||
|
if (!this.animation) return
|
||||||
|
this.tranfromInit(true)
|
||||||
|
.step()
|
||||||
|
.run(() => {
|
||||||
|
this.isShow = false
|
||||||
|
this.animationData = null
|
||||||
|
this.animation = null
|
||||||
|
let { opacity, transform } = this.styleInit(false)
|
||||||
|
this.opacity = opacity || 1
|
||||||
|
this.transform = transform
|
||||||
|
this.$emit('change', {
|
||||||
|
detail: this.isShow
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 处理动画开始前的默认样式
|
||||||
|
styleInit(type) {
|
||||||
|
let styles = {
|
||||||
|
transform: ''
|
||||||
|
}
|
||||||
|
let buildStyle = (type, mode) => {
|
||||||
|
if (mode === 'fade') {
|
||||||
|
styles.opacity = this.animationType(type)[mode]
|
||||||
|
} else {
|
||||||
|
styles.transform += this.animationType(type)[mode] + ' '
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (typeof this.modeClass === 'string') {
|
||||||
|
buildStyle(type, this.modeClass)
|
||||||
|
} else {
|
||||||
|
this.modeClass.forEach(mode => {
|
||||||
|
buildStyle(type, mode)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return styles
|
||||||
|
},
|
||||||
|
// 处理内置组合动画
|
||||||
|
tranfromInit(type) {
|
||||||
|
let buildTranfrom = (type, mode) => {
|
||||||
|
let aniNum = null
|
||||||
|
if (mode === 'fade') {
|
||||||
|
aniNum = type ? 0 : 1
|
||||||
|
} else {
|
||||||
|
aniNum = type ? '-100%' : '0'
|
||||||
|
if (mode === 'zoom-in') {
|
||||||
|
aniNum = type ? 0.8 : 1
|
||||||
|
}
|
||||||
|
if (mode === 'zoom-out') {
|
||||||
|
aniNum = type ? 1.2 : 1
|
||||||
|
}
|
||||||
|
if (mode === 'slide-right') {
|
||||||
|
aniNum = type ? '100%' : '0'
|
||||||
|
}
|
||||||
|
if (mode === 'slide-bottom') {
|
||||||
|
aniNum = type ? '100%' : '0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.animation[this.animationMode()[mode]](aniNum)
|
||||||
|
}
|
||||||
|
if (typeof this.modeClass === 'string') {
|
||||||
|
buildTranfrom(type, this.modeClass)
|
||||||
|
} else {
|
||||||
|
this.modeClass.forEach(mode => {
|
||||||
|
buildTranfrom(type, mode)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.animation
|
||||||
|
},
|
||||||
|
animationType(type) {
|
||||||
|
return {
|
||||||
|
fade: type ? 0 : 1,
|
||||||
|
'slide-top': `translateY(${type ? '0' : '-100%'})`,
|
||||||
|
'slide-right': `translateX(${type ? '0' : '100%'})`,
|
||||||
|
'slide-bottom': `translateY(${type ? '0' : '100%'})`,
|
||||||
|
'slide-left': `translateX(${type ? '0' : '-100%'})`,
|
||||||
|
'zoom-in': `scaleX(${type ? 1 : 0.8}) scaleY(${type ? 1 : 0.8})`,
|
||||||
|
'zoom-out': `scaleX(${type ? 1 : 1.2}) scaleY(${type ? 1 : 1.2})`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 内置动画类型与实际动画对应字典
|
||||||
|
animationMode() {
|
||||||
|
return {
|
||||||
|
fade: 'opacity',
|
||||||
|
'slide-top': 'translateY',
|
||||||
|
'slide-right': 'translateX',
|
||||||
|
'slide-bottom': 'translateY',
|
||||||
|
'slide-left': 'translateX',
|
||||||
|
'zoom-in': 'scale',
|
||||||
|
'zoom-out': 'scale'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 驼峰转中横线
|
||||||
|
toLine(name) {
|
||||||
|
return name.replace(/([A-Z])/g, '-$1').toLowerCase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
|
@ -0,0 +1,85 @@
|
||||||
|
{
|
||||||
|
"id": "uni-transition",
|
||||||
|
"displayName": "uni-transition 过渡动画",
|
||||||
|
"version": "1.3.3",
|
||||||
|
"description": "元素的简单过渡动画",
|
||||||
|
"keywords": [
|
||||||
|
"uni-ui",
|
||||||
|
"uniui",
|
||||||
|
"动画",
|
||||||
|
"过渡",
|
||||||
|
"过渡动画"
|
||||||
|
],
|
||||||
|
"repository": "https://github.com/dcloudio/uni-ui",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": ""
|
||||||
|
},
|
||||||
|
"directories": {
|
||||||
|
"example": "../../temps/example_temps"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "无",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
|
||||||
|
"type": "component-vue"
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": ["uni-scss"],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y",
|
||||||
|
"alipay": "n"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "y"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
},
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
|
||||||
|
## Transition 过渡动画
|
||||||
|
> **组件名:uni-transition**
|
||||||
|
> 代码块: `uTransition`
|
||||||
|
|
||||||
|
|
||||||
|
元素过渡动画
|
||||||
|
|
||||||
|
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-transition)
|
||||||
|
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
Loading…
Reference in New Issue