第一次提交
This commit is contained in:
289
package/MyArea/MyArea.vue
Normal file
289
package/MyArea/MyArea.vue
Normal file
@@ -0,0 +1,289 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- <u-navbar title-color="#fff" back-icon-color="#ffffff"
|
||||
:is-back="true"
|
||||
:background="background"
|
||||
:back-text-style="{color: '#fff'}"
|
||||
:title="title"
|
||||
:back-icon-name="backIconName"
|
||||
:back-text="backText">
|
||||
</u-navbar> -->
|
||||
<!-- <view class="areaPic">
|
||||
<image style="border-radius: 20rpx;" src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_match%2F0%2F10998212738%2F0.jpg&refer=http%3A%2F%2Finews.gtimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1638439546&t=37da2d714ac7228094c6f4179783b9e0"></image>
|
||||
</view> -->
|
||||
<view class="wrap">
|
||||
<view class="u-tabs-box">
|
||||
<u-tabs-swiper activeColor="#00aa00" ref="tabs" :list="list" :current="current" @change="change" :is-scroll="false" swiperWidth="750"></u-tabs-swiper>
|
||||
</view>
|
||||
<swiper class="swiper-box" :current="swiperCurrent" @transition="transition" @animationfinish="animationfinish">
|
||||
<swiper-item class="swiper-item">
|
||||
<view class="orderList">
|
||||
<view class="pic_of_Store">
|
||||
<image src="https://i6.mifile.cn/b2c-men/oms/5/64/59ccc2b175c7f.jpg"></image>
|
||||
</view>
|
||||
<view class="store">
|
||||
<view><text class="storename">好和家园菜鸟驿站</text></view>
|
||||
<view><text class="storeplace">门店地址:大学东路100号</text></view>
|
||||
<view><text class="order_num">门店总订单数:99单</text></view>
|
||||
<view>门店交易总额:<text class="commissonMoney">¥<text style="font-size: 18px;">2000</text></text></view>
|
||||
<view>提成金额:<text class="commissonMoney">¥<text style="font-size: 18px;">2000</text></text></view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<swiper-item class="swiper-item">
|
||||
<view class="orderList">
|
||||
<view class="pic_of_Store">
|
||||
<image src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg2.kybimg.com%2Fforum%2F202006%2F12%2F090943mlvyeifcrrphznvr.jpeg&refer=http%3A%2F%2Fimg2.kybimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1638439490&t=a9de43b4c243c4710b0a9815bd4a4ea4"></image>
|
||||
</view>
|
||||
<view class="store">
|
||||
<view><text class="storename">清华大学门店</text></view>
|
||||
<view><text class="storeplace">门店地址:大学东路100号</text></view>
|
||||
<view>门店交易总额:<text class="commissonMoney">¥<text style="font-size: 18px;">2000</text></text></view>
|
||||
<view>提成金额:<text class="commissonMoney">¥<text style="font-size: 18px;">2000</text></text></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="orderList">
|
||||
<view class="pic_of_Store">
|
||||
<image src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fnimg.ws.126.net%2F%3Furl%3Dhttp%253A%252F%252Fdingyue.ws.126.net%252F2021%252F1101%252F5e420da5j00r1w6fz002wc000hs00b9m.jpg%26thumbnail%3D650x2147483647%26quality%3D80%26type%3Djpg&refer=http%3A%2F%2Fnimg.ws.126.net&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1638439282&t=ef66cdd4c5bdf63bce1fadf1368df4ed"></image>
|
||||
</view>
|
||||
<view class="store">
|
||||
<view><text class="storename">CC杂货铺</text></view>
|
||||
<view><text class="storeplace">门店地址:大学东路100号</text></view>
|
||||
<view>门店交易总额:<text class="commissonMoney">¥<text style="font-size: 18px;">2000</text></text></view>
|
||||
<view>提成金额:<text class="commissonMoney">¥<text style="font-size: 18px;">2000</text></text></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="orderList">
|
||||
<view class="pic_of_Store">
|
||||
<image src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimage.zp365.com%2Fzygw%2Flpgl%2F107836404607330.jpg&refer=http%3A%2F%2Fimage.zp365.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1638091983&t=ef8474b167d75feb66208684f63461a4"></image>
|
||||
</view>
|
||||
<view class="store">
|
||||
<view><text class="storename">钱隆首府取货点</text></view>
|
||||
<view><text class="storeplace">门店地址:青秀区人民中路</text></view>
|
||||
<view>门店交易总额:<text class="commissonMoney">¥<text style="font-size: 18px;">2000</text></text></view>
|
||||
<view>提成金额:<text class="commissonMoney">¥<text style="font-size: 18px;">2000</text></text></view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<swiper-item class="swiper-item">
|
||||
<view>
|
||||
|
||||
</view>
|
||||
</swiper-item>
|
||||
<swiper-item class="swiper-item">
|
||||
<view class="orderList">
|
||||
<view class="pic_of_Store">
|
||||
<image src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimage.zp365.com%2Fzygw%2Flpgl%2F107836404607330.jpg&refer=http%3A%2F%2Fimage.zp365.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1638091983&t=ef8474b167d75feb66208684f63461a4"></image>
|
||||
</view>
|
||||
<view class="store2">
|
||||
<view><text class="storename">违规类型:偷吃店内食品</text></view>
|
||||
<view><text class="storeplace">违规内容:</text>
|
||||
</view>
|
||||
<view><text class="storeplace2">当你发现时间是贼了,他早已偷光你的选择。爱情更像是一场高烧,思念是紧跟着都好不了的咳。</text>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: '我的地区',
|
||||
backText: '返回',
|
||||
backIconName: 'nav-back',
|
||||
isBack: true,
|
||||
background: {
|
||||
backgroundImage: 'linear-gradient(to right, #146930 , #77b633)',
|
||||
|
||||
},
|
||||
orderList: [[], [], [], []],
|
||||
list: [
|
||||
{
|
||||
name: '我的地区'
|
||||
},
|
||||
{
|
||||
name: '订单统计'
|
||||
},
|
||||
{
|
||||
name: '提现明细'
|
||||
},
|
||||
{
|
||||
name: '违规记录',
|
||||
|
||||
}
|
||||
],
|
||||
current: 0,
|
||||
swiperCurrent: 0,
|
||||
tabsHeight: 0,
|
||||
dx: 0,
|
||||
loadStatus: ['loadmore','loadmore','loadmore','loadmore'],
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.getOrderList(0);
|
||||
this.getOrderList(1);
|
||||
this.getOrderList(3);
|
||||
},
|
||||
methods: {
|
||||
reachBottom() {
|
||||
// 此tab为空数据
|
||||
if(this.current != 2) {
|
||||
this.loadStatus.splice(this.current,1,"loading")
|
||||
setTimeout(() => {
|
||||
this.getOrderList(this.current);
|
||||
}, 1200);
|
||||
}
|
||||
},
|
||||
// 页面数据
|
||||
getOrderList(idx) {
|
||||
for(let i = 0; i < 5; i++) {
|
||||
let index = this.$u.random(0, this.dataList.length - 1);
|
||||
let data = JSON.parse(JSON.stringify(this.dataList[index]));
|
||||
data.id = this.$u.guid();
|
||||
this.orderList[idx].push(data);
|
||||
}
|
||||
this.loadStatus.splice(this.current,1,"loadmore")
|
||||
},
|
||||
// tab栏切换
|
||||
change(index) {
|
||||
this.swiperCurrent = index;
|
||||
this.getOrderList(index);
|
||||
},
|
||||
transition({ detail: { dx } }) {
|
||||
this.$refs.tabs.setDx(dx);
|
||||
},
|
||||
animationfinish({ detail: { current } }) {
|
||||
this.$refs.tabs.setFinishCurrent(current);
|
||||
this.swiperCurrent = current;
|
||||
this.current = current;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* #ifndef H5 */
|
||||
page {
|
||||
height: 100%;
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
/* #endif */
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.orderList{
|
||||
display: flex;
|
||||
background-color: #f3f3f3;
|
||||
width: 92%;
|
||||
height: 120px;
|
||||
border-radius: 20px;
|
||||
margin-top: 20px;
|
||||
margin-left: 4%;
|
||||
box-shadow: 2px 2px #DCDFE6;
|
||||
|
||||
}
|
||||
.addressAndDealsituation{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.pic_of_Store{
|
||||
width: 40%;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
|
||||
}
|
||||
.pic_of_Store image{
|
||||
width: 95%;
|
||||
height: 90%;
|
||||
margin-top: 6px;
|
||||
border-radius: 20px;
|
||||
|
||||
}
|
||||
.store{
|
||||
display: flex;
|
||||
width: 60%;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
line-height: 20px;
|
||||
justify-content: center;
|
||||
margin-left: 5px;
|
||||
}
|
||||
.store2{
|
||||
display: flex;
|
||||
width: 60%;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
line-height: 20px;
|
||||
margin-left: 5px;
|
||||
margin-top: 10rpx;
|
||||
align-content: center;
|
||||
margin-left: 15rpx
|
||||
}
|
||||
.TransactionAmount{
|
||||
margin: 10px;
|
||||
display: flex;
|
||||
height: 28px;
|
||||
width:100%;
|
||||
position:absolute;
|
||||
top: 150px;
|
||||
}
|
||||
.right{
|
||||
margin: 10px;
|
||||
margin-top: 20px;
|
||||
color: #F0AD4E;
|
||||
}
|
||||
.pickUpadress{
|
||||
margin-top: 20px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.areaPic{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
.areaPic image{
|
||||
width: 100%;
|
||||
margin: 5%;
|
||||
height: 200px;
|
||||
}
|
||||
.wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - var(--window-top));
|
||||
width: 100%;
|
||||
}
|
||||
.swiper-box {
|
||||
flex: 1;
|
||||
}
|
||||
.swiper-item {
|
||||
height: 100%;
|
||||
}
|
||||
.commissonMoney{
|
||||
|
||||
color: #ff0000
|
||||
}
|
||||
.order_num{
|
||||
color: #303030;
|
||||
font-size: 15px;
|
||||
}
|
||||
.storeplace{
|
||||
color: #303030;
|
||||
font-size: 15px;
|
||||
}
|
||||
.storeplace2{
|
||||
color: #303030;
|
||||
font-size: 13px;
|
||||
}
|
||||
.storename{
|
||||
color: #303030;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
378
package/MyStore/MyStore.vue
Normal file
378
package/MyStore/MyStore.vue
Normal file
@@ -0,0 +1,378 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="areaPic">
|
||||
<image style="border-radius: 20rpx;" src="https://img2.baidu.com/it/u=1945464906,1635022113&fm=26&fmt=auto"></image>
|
||||
</view>
|
||||
<view class="wrap">
|
||||
<view class="u-tabs-box">
|
||||
<u-tabs-swiper activeColor="#00aa00" ref="tabs" :list="list" :current="current" @change="change" :is-scroll="false" swiperWidth="750"></u-tabs-swiper>
|
||||
</view>
|
||||
<swiper class="swiper-box" :current="swiperCurrent" @transition="transition" @animationfinish="animationfinish">
|
||||
<swiper-item class="swiper-item">
|
||||
<view class="orderList">
|
||||
<view class="pic_of_Store">
|
||||
<image src="https://i6.mifile.cn/b2c-men/oms/5/64/59ccc2b175c7f.jpg"></image>
|
||||
</view>
|
||||
<view class="store">
|
||||
<view><text class="storename">好和家园菜鸟驿站</text></view>
|
||||
<view><text class="storeplace">门店地址:大学东路100号</text></view>
|
||||
<view><text class="order_num">门店总订单数:99单</text></view>
|
||||
<view><text class="storeplace">门店交易总额:</text><text style="color: #ED1C24;">¥<text class="commissonMoney">2000</text></text></view>
|
||||
<view><text class="storeplace">提成金额:</text><text style="color: #ED1C24;">¥<text class="commissonMoney">2000</text></text></view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<swiper-item class="swiper-item">
|
||||
<view class="orderList">
|
||||
<view class="pic_of_Store">
|
||||
<image src="https://img2.baidu.com/it/u=1945464906,1635022113&fm=26&fmt=auto"></image>
|
||||
</view>
|
||||
<view class="store">
|
||||
<view><text class="storename">钱隆首府取货点</text></view>
|
||||
<view><text class="storeplace">门店地址:青秀区人民中路</text></view>
|
||||
<view><text class="storeplace">门店交易总额:</text><text style="color: #ED1C24;">¥<text class="commissonMoney">2000</text></text></view>
|
||||
<view><text class="storeplace">提成金额:</text><text style="color: #ED1C24;">¥<text class="commissonMoney">2000</text></text></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="orderList">
|
||||
<view class="pic_of_Store">
|
||||
<image src="https://img2.baidu.com/it/u=1945464906,1635022113&fm=26&fmt=auto"></image>
|
||||
</view>
|
||||
<view class="store">
|
||||
<view><text class="storename">CC杂货铺</text></view>
|
||||
<view><text class="storeplace">门店地址:</text><text class="storeplace">大学东路100号</text></view>
|
||||
<view><text class="storeplace">门店交易总额:</text><text style="color: #ED1C24;">¥<text class="commissonMoney">2000</text></text></view>
|
||||
<view><text class="storeplace">提成金额:</text><text style="color: #ED1C24;">¥<text class="commissonMoney">2000</text></text></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="orderList">
|
||||
<view class="pic_of_Store">
|
||||
<image src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimage.zp365.com%2Fzygw%2Flpgl%2F107836404607330.jpg&refer=http%3A%2F%2Fimage.zp365.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1638091983&t=ef8474b167d75feb66208684f63461a4"></image>
|
||||
</view>
|
||||
<view class="store">
|
||||
<view><text class="storename">清华大学门店</text></view>
|
||||
<view><text class="storeplace">门店地址:大学东路100号</text></view>
|
||||
<view><text class="storeplace">门店交易总额:</text><text style="color: #ED1C24;">¥<text class="commissonMoney">2000</text></text></view>
|
||||
<view><text class="storeplace">提成金额:</text><text style="color: #ED1C24;">¥<text class="commissonMoney">2000</text></text></view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<swiper-item class="swiper-item">
|
||||
<view class="myriders">
|
||||
<view class="mysender">
|
||||
<view class="senderinfo">
|
||||
<view class="sendername">张大强</view>
|
||||
<view class="sendername2">骑手配送区域</view>
|
||||
<view class="sendingAddress">北京市清华园</view>
|
||||
</view>
|
||||
<view class="senderinfo">
|
||||
<view class="sendingAddress">已配送单数:<text class="commissonMoney">434</text></view>
|
||||
<view class="sendingAddress">累计提成:<text style="color:#ED1C24">¥<text class="commissonMoney">900</text></text></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mysender">
|
||||
<view class="senderinfo">
|
||||
<view class="sendername">李牛</view>
|
||||
<view class="sendername2">骑手配送区域</view>
|
||||
<view class="sendingAddress">南宁西乡塘</view>
|
||||
</view>
|
||||
<view class="senderinfo">
|
||||
<view class="sendingAddress">已配送单数:<text class="commissonMoney">123</text></view>
|
||||
<view class="sendingAddress">累计提成:<text style="color:#ED1C24">¥<text class="commissonMoney">6000</text></text></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mysender">
|
||||
<view class="senderinfo">
|
||||
<view class="sendername">丁紫雷</view>
|
||||
<view class="sendername2">骑手配送区域</view>
|
||||
<view class="sendingAddress">重庆山城</view>
|
||||
</view>
|
||||
<view class="senderinfo">
|
||||
<view class="sendingAddress">已配送单数:<text class="commissonMoney">323</text></view>
|
||||
<view class="sendingAddress">累计提成:<text style="color:#ED1C24">¥<text class="commissonMoney">9000</text></text></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<swiper-item class="swiper-item">
|
||||
<view class="orderList">
|
||||
<view class="pic_of_Store">
|
||||
<image src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimage.zp365.com%2Fzygw%2Flpgl%2F107836404607330.jpg&refer=http%3A%2F%2Fimage.zp365.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1638091983&t=ef8474b167d75feb66208684f63461a4"></image>
|
||||
</view>
|
||||
<view class="store2">
|
||||
<view><text class="storename">违规类型:偷吃店内食品</text></view>
|
||||
<view><text class="storeplace">违规内容:</text>
|
||||
</view>
|
||||
<view><text class="storeplace2">当你发现时间是贼了,他早已偷光你的选择。爱情更像是一场高烧,思念是紧跟着都好不了的咳。</text>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<swiper-item class="swiper-item">
|
||||
<view>
|
||||
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: '我的门店',
|
||||
backText: '返回',
|
||||
backIconName: 'nav-back',
|
||||
isBack: true,
|
||||
background: {
|
||||
backgroundImage: 'linear-gradient(to right, #146930 , #77b633)',
|
||||
|
||||
},
|
||||
orderList: [[], [], [], []],
|
||||
list: [
|
||||
{
|
||||
name: '门店详情'
|
||||
},
|
||||
{
|
||||
name: '订单数据'
|
||||
},
|
||||
{
|
||||
name: '我的骑手'
|
||||
},
|
||||
{
|
||||
name: '违规记录',
|
||||
|
||||
},
|
||||
{
|
||||
name: '提成明细',
|
||||
|
||||
}
|
||||
],
|
||||
current: 0,
|
||||
swiperCurrent: 0,
|
||||
tabsHeight: 0,
|
||||
dx: 0,
|
||||
loadStatus: ['loadmore','loadmore','loadmore','loadmore'],
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.getOrderList(0);
|
||||
this.getOrderList(1);
|
||||
this.getOrderList(3);
|
||||
},
|
||||
methods: {
|
||||
reachBottom() {
|
||||
// 此tab为空数据
|
||||
if(this.current != 2) {
|
||||
this.loadStatus.splice(this.current,1,"loading")
|
||||
setTimeout(() => {
|
||||
this.getOrderList(this.current);
|
||||
}, 1200);
|
||||
}
|
||||
},
|
||||
// 页面数据
|
||||
getOrderList(idx) {
|
||||
for(let i = 0; i < 5; i++) {
|
||||
let index = this.$u.random(0, this.dataList.length - 1);
|
||||
let data = JSON.parse(JSON.stringify(this.dataList[index]));
|
||||
data.id = this.$u.guid();
|
||||
this.orderList[idx].push(data);
|
||||
}
|
||||
this.loadStatus.splice(this.current,1,"loadmore")
|
||||
},
|
||||
// tab栏切换
|
||||
change(index) {
|
||||
this.swiperCurrent = index;
|
||||
this.getOrderList(index);
|
||||
},
|
||||
transition({ detail: { dx } }) {
|
||||
this.$refs.tabs.setDx(dx);
|
||||
},
|
||||
animationfinish({ detail: { current } }) {
|
||||
this.$refs.tabs.setFinishCurrent(current);
|
||||
this.swiperCurrent = current;
|
||||
this.current = current;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* #ifndef H5 */
|
||||
page {
|
||||
height: 100%;
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
/* #endif */
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.orderList{
|
||||
display: flex;
|
||||
background-color: #f3f3f3;
|
||||
width: 92%;
|
||||
height: 120px;
|
||||
border-radius: 20px;
|
||||
margin-top: 20px;
|
||||
margin-left: 4%;
|
||||
box-shadow: 2px 2px #DCDFE6;
|
||||
line-height: 60rpx;
|
||||
|
||||
}
|
||||
.addressAndDealsituation{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.pic_of_Store{
|
||||
width: 40%;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
|
||||
}
|
||||
.pic_of_Store image{
|
||||
width: 95%;
|
||||
height: 90%;
|
||||
border-radius: 20px;
|
||||
margin-top: 6px;
|
||||
|
||||
}
|
||||
.store{
|
||||
display: flex;
|
||||
width: 60%;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
line-height: 20px;
|
||||
justify-content: center;
|
||||
margin-left: 5px;
|
||||
|
||||
}
|
||||
.store2{
|
||||
display: flex;
|
||||
width: 60%;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
line-height: 20px;
|
||||
justify-content: center;
|
||||
margin-left: 15rpx
|
||||
;
|
||||
}
|
||||
.TransactionAmount{
|
||||
margin: 10px;
|
||||
display: flex;
|
||||
height: 28px;
|
||||
width:100%;
|
||||
position:absolute;
|
||||
top: 150px;
|
||||
}
|
||||
.right{
|
||||
margin: 10px;
|
||||
margin-top: 20px;
|
||||
color: #F0AD4E;
|
||||
}
|
||||
.pickUpadress{
|
||||
margin-top: 20px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.myriders{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
margin-left: 4%;}
|
||||
.mysender{
|
||||
width: 95%;
|
||||
display: flex;
|
||||
height: 80px;
|
||||
background-color: #ffffff;
|
||||
margin-top: 20px;
|
||||
flex-direction: column;
|
||||
border: solid 2px #18B566;
|
||||
border-radius: 10px;
|
||||
|
||||
}
|
||||
.senderinfo{
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
display: flex;
|
||||
border-radius: 10px;
|
||||
|
||||
}
|
||||
.sendername{
|
||||
height: 100%;
|
||||
width:25%;
|
||||
color: #000033;
|
||||
display: flex;
|
||||
background-color: #ffffff;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 10px;
|
||||
font-size: 16px;
|
||||
}
|
||||
.sendername2{
|
||||
height: 100%;
|
||||
width:25%;
|
||||
color: #000000;
|
||||
display: flex;
|
||||
background-color: #ffffff;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 10px;
|
||||
|
||||
}
|
||||
.sendingAddress{
|
||||
height: 100%;
|
||||
width: 50%;
|
||||
background-color: #ffffff;
|
||||
color: #000000;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.areaPic{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
.areaPic image{
|
||||
width: 100%;
|
||||
margin: 5%;
|
||||
height: 200px;
|
||||
}
|
||||
.wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - var(--window-top));
|
||||
width: 100%;
|
||||
}
|
||||
.swiper-box {
|
||||
flex: 1;
|
||||
}
|
||||
.swiper-item {
|
||||
height: 100%;
|
||||
}
|
||||
.commissonMoney{
|
||||
font-size: 17px;
|
||||
color: #ff0000
|
||||
}
|
||||
.order_num{
|
||||
color: #303030;
|
||||
font-size: 15px;
|
||||
}
|
||||
.storeplace{
|
||||
color: #303030;
|
||||
font-size: 15px;
|
||||
}
|
||||
.storeplace2{
|
||||
color: #303030;
|
||||
font-size: 13px;
|
||||
}
|
||||
.storename{
|
||||
color: #333333;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
282
package/apply/components/delivery.vue
Executable file
282
package/apply/components/delivery.vue
Executable file
@@ -0,0 +1,282 @@
|
||||
<template>
|
||||
<view :style="appThemeStyle">
|
||||
<u-form :model="form" ref="uForm" label-width="140rpx">
|
||||
<!-- {{JSON.stringify(setting)}} -->
|
||||
<u-form-item label="意向配送区域" prop="region">
|
||||
<select-region ref="sRegion" :disabled="disabled" v-model="form.region" />
|
||||
</u-form-item>
|
||||
<u-form-item label="姓名" prop="real_name">
|
||||
<u-input v-model="form.real_name" :disabled="disabled" placeholder="请输入商户姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="手机号码" prop="mobile">
|
||||
<u-input v-model="form.mobile" maxlength="11" :disabled="disabled" placeholder="请输入商户手机号" />
|
||||
</u-form-item>
|
||||
<Partner :form="form"></Partner>
|
||||
<u-form-item v-for="(item,imageIndex) in imageList" :key="imageIndex" :label="itemLabel[imageIndex]"
|
||||
:prop="itemProp[imageIndex]">
|
||||
<view class="image-preview">
|
||||
<image mode="widthFix" :src="item.path" class="sfz" @click="chooseImage(imageIndex)"></image>
|
||||
<text class="image-delete iconfont icon-shanchu" @click="deleteImage(imageIndex)"></text>
|
||||
</view>
|
||||
</u-form-item>
|
||||
<view class="form-license dis-flex flex-x-center flex-y-center">
|
||||
<view class="license-radio dis-flex flex-y-center" @click="isRead = !isRead">
|
||||
<text class="license-icon f-38 iconfont icon-radio"
|
||||
:class="[isRead ? 'c-violet' : 'col-bb']"></text>
|
||||
<text class="f-28 col-80">我已阅读并了解</text>
|
||||
</view>
|
||||
<text @click="handleShowLicense()" class="f-28 c-violet">【{{ setting.words.apply.words.license.value }}】</text>
|
||||
</view>
|
||||
</u-form>
|
||||
<!-- 入驻协议弹窗 -->
|
||||
<u-modal v-model="showLicense" title="入驻协议">
|
||||
<scroll-view class="pops-content" :scroll-y="true">
|
||||
<text>{{ setting.license }}</text>
|
||||
</scroll-view>
|
||||
</u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
import {
|
||||
isMobile
|
||||
} from '@/utils/verify'
|
||||
import Empty from '@/components/empty'
|
||||
import * as ApplyApi from '@/api/apply.js'
|
||||
import * as UploadApi from '@/api/upload'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
|
||||
// 图片上传类型
|
||||
const itemProp = ["sfz1", "sfz2", "yyzz"]
|
||||
// 图片上传名称
|
||||
const itemLabel = ["身份证(正)", "身份证(反)", "营业执照"]
|
||||
// 用户选择的图片列表
|
||||
const imageList = [{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/6b52b67ed9291757163c10ef96be1a54.png',
|
||||
size: 100
|
||||
},
|
||||
{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/55faad35f5ee30f3e8791bdfd2f75eb9.png',
|
||||
size: 100
|
||||
}
|
||||
]
|
||||
|
||||
// 表单字段元素
|
||||
const form = {
|
||||
// 入驻类型 (商家10001,配送员10002,社区门店10003,省代10004)
|
||||
grade_id: 10001,
|
||||
company: '',
|
||||
real_name: '',
|
||||
phone: '',
|
||||
mobile: '',
|
||||
region: [],
|
||||
detail: '',
|
||||
}
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
real_name: [{
|
||||
required: true,
|
||||
message: '请输入您的真实姓名',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
company: [{
|
||||
required: true,
|
||||
message: '请输入您的公司名称',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
phone: [{
|
||||
required: true,
|
||||
message: '请输入联系电话',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
mobile: [{
|
||||
required: true,
|
||||
message: '请输入手机号',
|
||||
trigger: ['blur', 'change']
|
||||
}, {
|
||||
// 自定义验证函数
|
||||
validator: (rule, value, callback) => {
|
||||
// 返回true表示校验通过,返回false表示不通过
|
||||
return isMobile(value)
|
||||
},
|
||||
message: '手机号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['blur'],
|
||||
}],
|
||||
region: [{
|
||||
required: true,
|
||||
message: '请选择省市区',
|
||||
trigger: ['blur', 'change'],
|
||||
type: 'array'
|
||||
}],
|
||||
detail: [{
|
||||
required: true,
|
||||
message: '请输入详细地址',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
}
|
||||
|
||||
const maxImageLength = 2
|
||||
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Empty
|
||||
},
|
||||
props: {
|
||||
record: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
setting: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
itemProp,
|
||||
itemLabel,
|
||||
imageList,
|
||||
form,
|
||||
rules,
|
||||
// 入驻协议阅读状态
|
||||
isRead: false,
|
||||
// 显示入驻协议弹窗
|
||||
showLicense: false,
|
||||
// 按钮禁用
|
||||
disabled: false,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 设置分类列表高度
|
||||
this.getSetting()
|
||||
},
|
||||
// onLoad(options) {
|
||||
// const app = this
|
||||
// this.getSetting()
|
||||
// // 获取用户坐标
|
||||
// app.getLocation((res) => {
|
||||
// app.getData(res.longitude, res.latitude)
|
||||
// })
|
||||
|
||||
// },
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules)
|
||||
},
|
||||
methods: {
|
||||
// 获取分销设置
|
||||
getSetting() {
|
||||
const app = this
|
||||
console.log("app.setting: ",this.setting);
|
||||
// SettingModel.data()
|
||||
// .then(setting => {
|
||||
// // 赋值属性
|
||||
// app.words = setting.words.apply.words
|
||||
// app.background = setting.background.apply
|
||||
// app.license = setting.license.license
|
||||
// // 设置当前页面标题
|
||||
// // app.setPageTitle(setting.words.apply.title)
|
||||
// })
|
||||
},
|
||||
// 显示入驻协议弹窗
|
||||
handleShowLicense() {
|
||||
this.showLicense = true
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.form-license {
|
||||
padding: 20rpx;
|
||||
}
|
||||
// 上传凭证
|
||||
.row-voucher {
|
||||
padding: 24rpx 20rpx;
|
||||
|
||||
.image-list {
|
||||
padding: 0 20rpx;
|
||||
margin-top: 20rpx;
|
||||
margin-bottom: -20rpx;
|
||||
|
||||
&:after {
|
||||
clear: both;
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.image-picker,
|
||||
.image-preview {
|
||||
width: 184rpx;
|
||||
height: 184rpx;
|
||||
margin-right: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
float: left;
|
||||
|
||||
&:nth-child(3n+0) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.image-picker {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 1rpx dashed #ccc;
|
||||
color: #ccc;
|
||||
|
||||
.choose-icon {
|
||||
font-size: 48rpx;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.choose-text {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
position: relative;
|
||||
|
||||
.image-delete {
|
||||
position: absolute;
|
||||
top: -15rpx;
|
||||
right: -15rpx;
|
||||
height: 42rpx;
|
||||
width: 42rpx;
|
||||
background: rgba(0, 0, 0, 0.64);
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
font-weight: bolder;
|
||||
font-size: 22rpx;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.pops-content{padding: 20rpx;}
|
||||
.sfz,
|
||||
.sfz1,
|
||||
.sfz2,
|
||||
.yyzz {
|
||||
width: 140rpx;
|
||||
padding-top: 20rpx;
|
||||
padding-right: 10rpx;
|
||||
}
|
||||
|
||||
</style>
|
||||
415
package/apply/components/index.vue
Normal file
415
package/apply/components/index.vue
Normal file
@@ -0,0 +1,415 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<!-- 标题 -->
|
||||
<view class="page-title">申请入驻</view>
|
||||
<!-- 合伙人 -->
|
||||
<Partner v-if=" currentType == 0 " :form="dataType[currentType]"
|
||||
@handleSubmit="handleSubmit" @chooseImage="chooseImage" @deleteImage="deleteImage" @showLicense="handleShowLicense" />
|
||||
<!-- 配送员 -->
|
||||
<Delivery v-if=" currentType == 1 " :form="dataType[currentType]"
|
||||
@handleSubmit="handleSubmit" @chooseImage="chooseImage" @deleteImage="deleteImage" />
|
||||
<!-- 团长 -->
|
||||
<Teamer v-if=" currentType == 2 " :form="dataType[currentType]"
|
||||
@handleSubmit="handleSubmit" @chooseImage="chooseImage" @deleteImage="deleteImage" />
|
||||
<!-- 个人商户 -->
|
||||
<Personal v-if=" currentType == 3 " :form="dataType[currentType]"
|
||||
@handleSubmit="handleSubmit" @chooseImage="chooseImage" @deleteImage="deleteImage" />
|
||||
|
||||
<!-- 入驻协议弹窗 -->
|
||||
<u-modal v-model="showLicense" title="入驻协议">
|
||||
<scroll-view class="pops-content" :scroll-y="true">
|
||||
<text>{{ dataType[currentType].license }}</text>
|
||||
</scroll-view>
|
||||
</u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as ApplyApi from '@/api/apply.js'
|
||||
import * as UploadApi from '@/api/upload'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
import Partner from './components/partner.vue'
|
||||
import Delivery from './components/delivery.vue'
|
||||
import Teamer from './components/teamer.vue'
|
||||
import Personal from './components/personal.vue'
|
||||
|
||||
// 数据类型
|
||||
const dataType = [
|
||||
{
|
||||
name: "商户",
|
||||
title: '申请成为商户',
|
||||
label: "partner",
|
||||
regionText: '所在地区',
|
||||
licenseTitle: '',
|
||||
license: '',
|
||||
submitText: '提交申请',
|
||||
disabled: false,
|
||||
longitude: '',
|
||||
latitude: '',
|
||||
imageProp: ["sfz1", "sfz2", "yyzz"],
|
||||
itemLabel: ["身份证(正)", "身份证(反)", "营业执照"],
|
||||
imageList: [{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/6b52b67ed9291757163c10ef96be1a54.png',
|
||||
size: 0
|
||||
},{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/6b52b67ed9291757163c10ef96be1a54.png',
|
||||
size: 0
|
||||
},
|
||||
{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/55faad35f5ee30f3e8791bdfd2f75eb9.png',
|
||||
size: 0
|
||||
}],
|
||||
|
||||
},
|
||||
{
|
||||
name: "配送员",
|
||||
title: '申请成为配送员',
|
||||
label: "delivery",
|
||||
regionText: '意向配送区域',
|
||||
licenseTitle: '',
|
||||
license: '',
|
||||
submitText: '提交申请',
|
||||
disabled: false,
|
||||
longitude: '',
|
||||
latitude: '',
|
||||
imageProp: ["sfz1", "sfz2", "yyzz"],
|
||||
itemLabel: ["身份证(正)", "身份证(反)", "营业执照"],
|
||||
imageList: [{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/6b52b67ed9291757163c10ef96be1a54.png',
|
||||
size: 0
|
||||
},{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/6b52b67ed9291757163c10ef96be1a54.png',
|
||||
size: 0
|
||||
},
|
||||
{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/55faad35f5ee30f3e8791bdfd2f75eb9.png',
|
||||
size: 0
|
||||
}],
|
||||
|
||||
},
|
||||
{
|
||||
name: "团长",
|
||||
title: '申请成为团长',
|
||||
label: "teamer",
|
||||
regionText: '所在地区',
|
||||
licenseTitle: '',
|
||||
license: '',
|
||||
submitText: '提交申请',
|
||||
disabled: false,
|
||||
longitude: '',
|
||||
latitude: '',
|
||||
imageProp: ["sfz1", "sfz2", "yyzz"],
|
||||
itemLabel: ["身份证(正)", "身份证(反)", "营业执照"],
|
||||
imageList: [{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/6b52b67ed9291757163c10ef96be1a54.png',
|
||||
size: 0
|
||||
},{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/6b52b67ed9291757163c10ef96be1a54.png',
|
||||
size: 0
|
||||
},
|
||||
{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/55faad35f5ee30f3e8791bdfd2f75eb9.png',
|
||||
size: 0
|
||||
}],
|
||||
|
||||
},
|
||||
{
|
||||
name: "个人商户",
|
||||
title: '申请成为个人商户',
|
||||
label: "personal",
|
||||
regionText: '所在地区',
|
||||
submitText: '提交申请',
|
||||
licenseTitle: '',
|
||||
license: '',
|
||||
disabled: false,
|
||||
longitude: '',
|
||||
latitude: '',
|
||||
imageProp: ["sfz1", "sfz2", "yyzz"],
|
||||
itemLabel: ["身份证(正)", "身份证(反)", "营业执照"],
|
||||
imageList: [{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/6b52b67ed9291757163c10ef96be1a54.png',
|
||||
size: 0
|
||||
},{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/6b52b67ed9291757163c10ef96be1a54.png',
|
||||
size: 0
|
||||
},
|
||||
{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/55faad35f5ee30f3e8791bdfd2f75eb9.png',
|
||||
size: 0
|
||||
}],
|
||||
|
||||
}
|
||||
]
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Partner,
|
||||
Delivery,
|
||||
Teamer,
|
||||
Personal
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 数据类型
|
||||
dataType,
|
||||
// 当前类型
|
||||
currentType: 0,
|
||||
// 文字设置
|
||||
words: undefined,
|
||||
// 显示入驻协议弹窗
|
||||
showLicense: false,
|
||||
// 入驻协议阅读状态
|
||||
isRead: false,
|
||||
// 当前记录
|
||||
form: {},
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
const app = this
|
||||
// 切换类型
|
||||
this.setDataType(options.dataType)
|
||||
// 获取设置信息
|
||||
this.getSetting()
|
||||
// 获取用户坐标及当前入驻申请记录
|
||||
app.getLocation((res) => {
|
||||
app.getData(res.longitude, res.latitude)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// 切换类型
|
||||
setDataType(dataType) {
|
||||
if (dataType == 'partner') {
|
||||
this.currentType = 0
|
||||
}
|
||||
if (dataType == 'delivery') {
|
||||
this.currentType = 1
|
||||
}
|
||||
if (dataType == 'teamer') {
|
||||
this.currentType = 2
|
||||
}
|
||||
if (dataType == 'personal') {
|
||||
this.currentType = 3
|
||||
}
|
||||
console.log("dataType: ",this.dataType[this.currentType]);
|
||||
},
|
||||
|
||||
// 获取用户坐标
|
||||
// 参考文档:https://uniapp.dcloud.io/api/location/location?id=getlocation
|
||||
getLocation(callback) {
|
||||
const app = this
|
||||
uni.getLocation({
|
||||
type: 'wgs84',
|
||||
success: callback,
|
||||
fail() {
|
||||
app.$toast('获取定位失败,请点击右下角按钮重新尝试定位')
|
||||
app.isAuthor = false
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 加载数据
|
||||
getData(longitude, latitude) {
|
||||
const app = this
|
||||
const { currentType, dataType } = this
|
||||
dataType[currentType].longitude = longitude
|
||||
dataType[currentType].latitude = latitude
|
||||
ApplyApi.detail().then(res => {
|
||||
const detail = res.data.detail
|
||||
console.log("detail: ",detail);
|
||||
// 编辑信息
|
||||
if (detail) {
|
||||
app.createFormData(detail)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 生成默认的表单数据
|
||||
createFormData(detail) {
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
form.region = this.createRegion(detail)
|
||||
// 是否可编辑
|
||||
this.disabled = true
|
||||
// 状态
|
||||
console.log("recore.apply_status: ", form.apply_status);
|
||||
if (form.apply_status == 10) {
|
||||
this.submitText = '待审核'
|
||||
}
|
||||
if (form.apply_status == 20) {
|
||||
this.submitText = '审核通过'
|
||||
}
|
||||
if (form.apply_status == 30) {
|
||||
this.submitText = '重新提交'
|
||||
this.disabled = false
|
||||
}
|
||||
|
||||
// 加载图片
|
||||
this.imageList = detail.images.map(d => {
|
||||
return {
|
||||
path: d.image_url,
|
||||
size: 101
|
||||
}
|
||||
})
|
||||
form.images = detail.images.map(d => {
|
||||
return d.image_id
|
||||
})
|
||||
},
|
||||
|
||||
// 地区
|
||||
createRegion(detail) {
|
||||
console.log("detail: ", detail);
|
||||
return [{
|
||||
label: detail.region.province,
|
||||
value: detail.province_id
|
||||
}, {
|
||||
label: detail.region.city,
|
||||
value: detail.city_id
|
||||
}, {
|
||||
label: detail.region.region,
|
||||
value: detail.region_id
|
||||
}]
|
||||
},
|
||||
|
||||
// 获取分销设置
|
||||
getSetting() {
|
||||
const app = this
|
||||
SettingModel.data()
|
||||
.then(setting => {
|
||||
app.dataType[app.currentType].licenseTitle = setting.words.apply.words.license.value
|
||||
// // 赋值属性
|
||||
app.dataType[app.currentType].license = setting.license.license
|
||||
// 设置当前页面标题
|
||||
app.setPageTitle()
|
||||
})
|
||||
},
|
||||
|
||||
// 设置当前页面标题
|
||||
setPageTitle() {
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.dataType[this.currentType].title
|
||||
})
|
||||
},
|
||||
|
||||
// 选择图片
|
||||
chooseImage(imageIndex,tempFiles){
|
||||
console.log("imageIndex: ",imageIndex);
|
||||
console.log("tempFiles: ",tempFiles);
|
||||
const {dataType, currentType} = this
|
||||
dataType[currentType].imageList.splice(imageIndex,1,tempFiles)
|
||||
},
|
||||
|
||||
// 删除图片
|
||||
deleteImage(imageIndex) {
|
||||
const { disabled } = this
|
||||
if (disabled == true) {
|
||||
return false
|
||||
}
|
||||
this.imageList[imageIndex].path = '/static/not-dealer.png'
|
||||
},
|
||||
|
||||
// 显示入驻协议弹窗
|
||||
handleShowLicense(e) {
|
||||
this.showLicense = e
|
||||
},
|
||||
|
||||
// 提交到后台
|
||||
handleSubmit(form,imageList){
|
||||
const app = this
|
||||
if (app.disabled) {
|
||||
return false
|
||||
}
|
||||
app.disabled = true
|
||||
app.form = form
|
||||
ApplyApi.checkAvailable(form).then(res => {
|
||||
if (imageList.length > 0 && imageList[0].size != 100) {
|
||||
app.uploadFile()
|
||||
.then(() => app.onSubmit())
|
||||
.catch(err => {
|
||||
app.disabled = false
|
||||
if (err.statusCode !== 0) {
|
||||
app.$toast(err.errMsg)
|
||||
}
|
||||
console.log('err', err)
|
||||
})
|
||||
} else {
|
||||
app.onSubmit()
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log("err: ", err);
|
||||
if (err.statusCode == 0) {
|
||||
app.disabled = false
|
||||
app.$toast(err.errMsg)
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
// 上传图片
|
||||
uploadFile() {
|
||||
const app = this
|
||||
const {
|
||||
imageList,
|
||||
form
|
||||
} = app
|
||||
// 批量上传
|
||||
return new Promise((resolve, reject) => {
|
||||
if (imageList.length > 0) {
|
||||
UploadApi.image(imageList)
|
||||
.then(fileIds => {
|
||||
form.images = fileIds
|
||||
resolve(fileIds)
|
||||
})
|
||||
.catch(reject)
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 提交到后端
|
||||
onSubmit() {
|
||||
const app = this
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
let req;
|
||||
if (form.apply_status == 30) {
|
||||
req = ApplyApi.edit(form.apply_id, form)
|
||||
} else {
|
||||
req = ApplyApi.add(form)
|
||||
}
|
||||
req.then(result => {
|
||||
console.log("result: ", result);
|
||||
app.$toast(result.message)
|
||||
setTimeout(function() {
|
||||
uni.navigateBack()
|
||||
}, 2000)
|
||||
|
||||
})
|
||||
.finally(() => app.disabled = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #f7f8fa;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.page-title {
|
||||
width: 94%;
|
||||
margin: 0 auto;
|
||||
padding-top: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(69, 90, 100, 0.6);
|
||||
}
|
||||
.pops-content {
|
||||
padding: 20rpx;
|
||||
}
|
||||
</style>
|
||||
566
package/apply/components/partner.2.vue
Normal file
566
package/apply/components/partner.2.vue
Normal file
@@ -0,0 +1,566 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper">
|
||||
<u-form :model="form" ref="uForm" label-width="140rpx">
|
||||
<u-form-item label="所在地区" prop="region">
|
||||
<select-region ref="sRegion" :disabled="disabled" v-model="form.region" />
|
||||
</u-form-item>
|
||||
<u-form-item label="公司名称" prop="company">
|
||||
<u-input v-model="form.company" :disabled="disabled" placeholder="请输入公司名称" />
|
||||
</u-form-item>
|
||||
<u-form-item label="联系电话" prop="phone">
|
||||
<u-input v-model="form.phone" :disabled="disabled" placeholder="请输入联系电话" />
|
||||
</u-form-item>
|
||||
<u-form-item label="姓名" prop="real_name">
|
||||
<u-input v-model="form.real_name" :disabled="disabled" placeholder="请输入商户姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="手机号码" prop="mobile">
|
||||
<u-input v-model="form.mobile" maxlength="11" :disabled="disabled" placeholder="请输入商户手机号" />
|
||||
</u-form-item>
|
||||
<u-form-item v-for="(item,imageIndex) in imageList" :key="imageIndex" :label="itemLabel[imageIndex]"
|
||||
:prop="itemProp[imageIndex]">
|
||||
<view class="image-preview">
|
||||
<image mode="widthFix" :src="item.path" class="sfz" @click="chooseImage(imageIndex)"></image>
|
||||
<text class="image-delete iconfont icon-shanchu" @click="deleteImage(imageIndex)"></text>
|
||||
</view>
|
||||
</u-form-item>
|
||||
<view class="form-license dis-flex flex-x-center flex-y-center">
|
||||
<view class="license-radio dis-flex flex-y-center" @click="isRead = !isRead">
|
||||
<text class="license-icon f-38 iconfont icon-radio"
|
||||
:class="[isRead ? 'c-violet' : 'col-bb']"></text>
|
||||
<text class="f-28 col-80">我已阅读并了解{{words}}</text>
|
||||
</view>
|
||||
<text @click="handleShowLicense()" class="f-28 c-violet">【{{ words.license.value }}】</text>
|
||||
</view>
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn-wrapper">
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">{{ submitText }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 入驻协议弹窗 -->
|
||||
<u-modal v-model="showLicense" title="申请协议">
|
||||
<scroll-view class="pops-content" :scroll-y="true">
|
||||
<text>{{ license }}</text>
|
||||
</scroll-view>
|
||||
</u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
import {
|
||||
isMobile
|
||||
} from '@/utils/verify'
|
||||
import * as ApplyApi from '@/api/apply.js'
|
||||
import * as UploadApi from '@/api/upload'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
// 入驻类型
|
||||
const dataType = [
|
||||
"partner", // 合伙人
|
||||
"teamer", // 团长
|
||||
"delivery", // 配送员
|
||||
"personal" // 个人商户
|
||||
]
|
||||
// 图片上传类型
|
||||
const itemProp = ["sfz", "yyzz"]
|
||||
// 图片上传名称
|
||||
const itemLabel = ["身份证", "营业执照"]
|
||||
|
||||
// 用户选择的图片列表
|
||||
const imageList = [{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/6b52b67ed9291757163c10ef96be1a54.png',
|
||||
size: 100
|
||||
},
|
||||
{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/55faad35f5ee30f3e8791bdfd2f75eb9.png',
|
||||
size: 100
|
||||
}
|
||||
]
|
||||
|
||||
// 表单字段元素
|
||||
const form = {
|
||||
// 入驻类型 (合伙人10001,配送员10002,社区门店10003,省代10004)
|
||||
grade_id: 10001,
|
||||
company: '',
|
||||
real_name: '',
|
||||
phone: '',
|
||||
mobile: '',
|
||||
region: [],
|
||||
detail: '',
|
||||
}
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
real_name: [{
|
||||
required: true,
|
||||
message: '请输入您的真实姓名',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
company: [{
|
||||
required: true,
|
||||
message: '请输入您的公司名称',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
phone: [{
|
||||
required: true,
|
||||
message: '请输入联系电话',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
mobile: [{
|
||||
required: true,
|
||||
message: '请输入手机号',
|
||||
trigger: ['blur', 'change']
|
||||
}, {
|
||||
// 自定义验证函数
|
||||
validator: (rule, value, callback) => {
|
||||
// 返回true表示校验通过,返回false表示不通过
|
||||
return isMobile(value)
|
||||
},
|
||||
message: '手机号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['blur'],
|
||||
}],
|
||||
region: [{
|
||||
required: true,
|
||||
message: '请选择省市区',
|
||||
trigger: ['blur', 'change'],
|
||||
type: 'array'
|
||||
}],
|
||||
detail: [{
|
||||
required: true,
|
||||
message: '请输入详细地址',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
}
|
||||
|
||||
const maxImageLength = 2
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataType,
|
||||
itemProp,
|
||||
itemLabel,
|
||||
imageList,
|
||||
form,
|
||||
rules,
|
||||
// 按钮禁用
|
||||
disabled: false,
|
||||
submitText: '提交申请',
|
||||
|
||||
// 文字设置
|
||||
words: undefined,
|
||||
// 显示入驻协议弹窗
|
||||
showLicense: false,
|
||||
// 入驻协议
|
||||
license: undefined,
|
||||
// 入驻协议阅读状态
|
||||
isRead: false,
|
||||
// 显示入驻协议弹窗
|
||||
showLicense: false,
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
this.getSetting()
|
||||
this.getData()
|
||||
},
|
||||
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules)
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 加载数据
|
||||
getData() {
|
||||
const app = this
|
||||
ApplyApi.detail().then(res => {
|
||||
const detail = res.data.detail
|
||||
// 编辑信息
|
||||
if (detail) {
|
||||
app.form = detail
|
||||
app.createFormData(detail)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 生成默认的表单数据
|
||||
createFormData(detail) {
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
form.company = detail.company
|
||||
form.phone = detail.phone
|
||||
form.region = this.createRegion(detail.shop)
|
||||
// 是否可编辑
|
||||
this.disabled = true
|
||||
// 状态
|
||||
if (form.apply_status == 10) {
|
||||
this.submitText = '待审核'
|
||||
}
|
||||
if (form.apply_status == 20) {
|
||||
this.submitText = '审核通过'
|
||||
}
|
||||
if (form.apply_status == 30) {
|
||||
this.submitText = '重新提交'
|
||||
this.disabled = false
|
||||
}
|
||||
|
||||
// 加载图片
|
||||
this.imageList = detail.images.map(d => {
|
||||
return {
|
||||
path: d.image_url,
|
||||
size: 101
|
||||
}
|
||||
})
|
||||
form.images = detail.images.map(d => {
|
||||
return d.image_id
|
||||
})
|
||||
},
|
||||
|
||||
createRegion(detail) {
|
||||
return [{
|
||||
label: detail.region.province,
|
||||
value: detail.province_id
|
||||
}, {
|
||||
label: detail.region.city,
|
||||
value: detail.city_id
|
||||
}, {
|
||||
label: detail.region.region,
|
||||
value: detail.region_id
|
||||
}]
|
||||
},
|
||||
|
||||
// 获取分销设置
|
||||
getSetting() {
|
||||
console.log("setting: ");
|
||||
const app = this
|
||||
SettingModel.data()
|
||||
.then(setting => {
|
||||
// 赋值属性
|
||||
app.words = setting.words.apply.words
|
||||
app.background = setting.background.apply
|
||||
app.license = setting.license.license
|
||||
})
|
||||
},
|
||||
|
||||
// 显示入驻协议弹窗
|
||||
handleShowLicense() {
|
||||
this.showLicense = true
|
||||
},
|
||||
|
||||
// 选择图片
|
||||
chooseImage(imageIndex) {
|
||||
const app = this
|
||||
const oldImageList = app.imageList
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
// 是否可编辑
|
||||
if (form.apply_status && form.apply_status != 30) {
|
||||
app.disabled = true
|
||||
return false
|
||||
}
|
||||
// 选择图片
|
||||
uni.chooseImage({
|
||||
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
|
||||
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
|
||||
success({
|
||||
tempFiles
|
||||
}) {
|
||||
// 删除第imageIndex个元素,并在数组的第imageIndex个位置添加新元素:
|
||||
app.imageList.splice(imageIndex, 1, tempFiles[0])
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 删除图片
|
||||
deleteImage(imageIndex) {
|
||||
const {
|
||||
disabled
|
||||
} = this
|
||||
if (disabled == true) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.imageList[imageIndex].path = '../../static/not-dealer.png'
|
||||
},
|
||||
|
||||
// 选择微信地址
|
||||
// #ifdef MP-WEIXIN
|
||||
chooseAddress() {
|
||||
const {
|
||||
form,
|
||||
$refs
|
||||
} = this
|
||||
uni.chooseAddress({
|
||||
success(res) {
|
||||
const names = $refs.sRegion.getOptionItemByNames(res)
|
||||
form.name = res.userName
|
||||
form.phone = res.telNumber
|
||||
form.detail = res.detailInfo
|
||||
form.region = names.length > 0 ? names : []
|
||||
}
|
||||
})
|
||||
},
|
||||
// #endif
|
||||
|
||||
// 表单提交
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
if (app.disabled) {
|
||||
return false
|
||||
}
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
const {
|
||||
imageList
|
||||
} = this
|
||||
app.$refs.uForm.validate(valid => {
|
||||
if (valid) {
|
||||
app.disabled = true
|
||||
ApplyApi.checkShop(form).then(res => {
|
||||
// 判断是否需要上传图片
|
||||
if (imageList[0].size == 100 || imageList[1].size == 100) {
|
||||
app.$toast('请上传图片!')
|
||||
app.disabled = false
|
||||
return false
|
||||
}
|
||||
if (imageList.length > 0 && imageList[0].size != 101) {
|
||||
app.uploadFile()
|
||||
.then(() => app.onSubmit())
|
||||
.catch(err => {
|
||||
app.disabled = false
|
||||
if (err.statusCode !== 0) {
|
||||
app.$toast(err.errMsg)
|
||||
}
|
||||
console.log('err', err)
|
||||
})
|
||||
} else {
|
||||
app.onSubmit()
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log("err: ", err);
|
||||
if (err.statusCode == 0) {
|
||||
app.disabled = false
|
||||
app.$toast(err.errMsg)
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 上传图片
|
||||
uploadFile() {
|
||||
const app = this
|
||||
const {
|
||||
imageList,
|
||||
form
|
||||
} = app
|
||||
// 批量上传
|
||||
return new Promise((resolve, reject) => {
|
||||
if (imageList.length > 0) {
|
||||
UploadApi.image(imageList)
|
||||
.then(fileIds => {
|
||||
form.images = fileIds
|
||||
resolve(fileIds)
|
||||
})
|
||||
.catch(reject)
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 提交到后端
|
||||
onSubmit() {
|
||||
const app = this
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
let req;
|
||||
if (form.apply_status == 30) {
|
||||
req = ApplyApi.edit(form.apply_id, form)
|
||||
} else {
|
||||
req = ApplyApi.add(form)
|
||||
}
|
||||
req.then(result => {
|
||||
console.log("result: ", result);
|
||||
app.$toast(result.message)
|
||||
setTimeout(function() {
|
||||
uni.navigateBack()
|
||||
}, 2000)
|
||||
|
||||
})
|
||||
.finally(() => app.disabled = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #f7f8fa;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.page-title {
|
||||
width: 94%;
|
||||
margin: 0 auto;
|
||||
padding-top: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(69, 90, 100, 0.6);
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
|
||||
.footer {
|
||||
margin-top: 80rpx;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-wechat {
|
||||
background: #0ba90b;
|
||||
margin-bottom: 26rpx;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 上传凭证
|
||||
.row-voucher {
|
||||
padding: 24rpx 20rpx;
|
||||
|
||||
.image-list {
|
||||
padding: 0 20rpx;
|
||||
margin-top: 20rpx;
|
||||
margin-bottom: -20rpx;
|
||||
|
||||
&:after {
|
||||
clear: both;
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.image-picker,
|
||||
.image-preview {
|
||||
width: 184rpx;
|
||||
height: 184rpx;
|
||||
margin-right: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
float: left;
|
||||
|
||||
&:nth-child(3n+0) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.image-picker {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 1rpx dashed #ccc;
|
||||
color: #ccc;
|
||||
|
||||
.choose-icon {
|
||||
font-size: 48rpx;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.choose-text {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
position: relative;
|
||||
|
||||
.image-delete {
|
||||
position: absolute;
|
||||
top: -15rpx;
|
||||
right: -15rpx;
|
||||
height: 42rpx;
|
||||
width: 42rpx;
|
||||
background: rgba(0, 0, 0, 0.64);
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
font-weight: bolder;
|
||||
font-size: 22rpx;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-license {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.sfz,
|
||||
.sfz1,
|
||||
.sfz2,
|
||||
.yyzz {
|
||||
width: 140rpx;
|
||||
padding-top: 20rpx;
|
||||
padding-right: 10rpx;
|
||||
}
|
||||
</style>
|
||||
327
package/apply/components/partner.vue
Executable file
327
package/apply/components/partner.vue
Executable file
@@ -0,0 +1,327 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper" :style="appThemeStyle">
|
||||
{{form.imageList}}{{form.license}}
|
||||
<u-form :model="form" ref="uForm" label-width="140rpx">
|
||||
<!-- {{JSON.stringify(setting)}} -->
|
||||
<u-form-item label="所在地区" prop="region">
|
||||
<select-region ref="sRegion" :disabled="disabled" v-model="form.region" />
|
||||
</u-form-item>
|
||||
<u-form-item label="公司名称" prop="company">
|
||||
<u-input v-model="form.company" :disabled="disabled" placeholder="请输入公司名称" />
|
||||
</u-form-item>
|
||||
<u-form-item label="联系电话" prop="phone">
|
||||
<u-input v-model="form.phone" :disabled="disabled" placeholder="请输入联系电话" />
|
||||
</u-form-item>
|
||||
<u-form-item label="姓名" prop="real_name">
|
||||
<u-input v-model="form.real_name" :disabled="disabled" placeholder="请输入商户姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="手机号码" prop="mobile">
|
||||
<u-input v-model="form.mobile" maxlength="11" :disabled="disabled" placeholder="请输入商户手机号" />
|
||||
</u-form-item>
|
||||
<u-form-item v-for="(item,imageIndex) in imageList" :key="imageIndex" :label="form.itemLabel[imageIndex]"
|
||||
:prop="form.imageProp[imageIndex]">
|
||||
<view class="image-preview">
|
||||
<image mode="widthFix" :src="item.path" class="sfz" @click="chooseImage(imageIndex)"></image>
|
||||
<text class="image-delete iconfont icon-shanchu" @click="deleteImage(imageIndex)"></text>
|
||||
</view>
|
||||
</u-form-item>
|
||||
<view class="form-license dis-flex flex-x-center flex-y-center">
|
||||
<view class="license-radio dis-flex flex-y-center" @click="isRead = !isRead">
|
||||
<text class="license-icon f-38 iconfont icon-radio"
|
||||
:class="[isRead ? 'c-violet' : 'col-bb']"></text>
|
||||
<text class="f-28 col-80">我已阅读并了解</text>
|
||||
</view>
|
||||
<text @click="handleShowLicense()"
|
||||
class="f-28 c-violet">【{{ form.licenseTitle }}】</text>
|
||||
</view>
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn-wrapper">
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">{{ form.submitText }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
import {
|
||||
isMobile
|
||||
} from '@/utils/verify'
|
||||
import Empty from '@/components/empty'
|
||||
import * as ApplyApi from '@/api/apply.js'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
real_name: [{
|
||||
required: true,
|
||||
message: '请输入您的真实姓名',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
company: [{
|
||||
required: true,
|
||||
message: '请输入您的公司名称',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
phone: [{
|
||||
required: true,
|
||||
message: '请输入联系电话',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
mobile: [{
|
||||
required: true,
|
||||
message: '请输入手机号',
|
||||
trigger: ['blur', 'change']
|
||||
}, {
|
||||
// 自定义验证函数
|
||||
validator: (rule, value, callback) => {
|
||||
// 返回true表示校验通过,返回false表示不通过
|
||||
return isMobile(value)
|
||||
},
|
||||
message: '手机号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['blur'],
|
||||
}],
|
||||
region: [{
|
||||
required: true,
|
||||
message: '请选择省市区',
|
||||
trigger: ['blur', 'change'],
|
||||
type: 'array'
|
||||
}],
|
||||
detail: [{
|
||||
required: true,
|
||||
message: '请输入详细地址',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
}
|
||||
|
||||
const maxImageLength = 2
|
||||
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Empty
|
||||
},
|
||||
props: {
|
||||
form: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
rules,
|
||||
// 入驻协议阅读状态
|
||||
isRead: false
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules)
|
||||
},
|
||||
methods: {
|
||||
// 选择图片
|
||||
chooseImage(imageIndex) {
|
||||
const app = this
|
||||
const oldImageList = app.imageList
|
||||
const { form } = this
|
||||
// 是否可编辑
|
||||
if (form.apply_status && form.apply_status != 30) {
|
||||
return false
|
||||
}
|
||||
// 选择图片
|
||||
uni.chooseImage({
|
||||
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
|
||||
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
|
||||
success({
|
||||
tempFiles
|
||||
}) {
|
||||
// 传递给父级
|
||||
app.$emit('chooseImage',imageIndex,tempFiles[0])
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
// 删除图片
|
||||
deleteImage(imageIndex) {
|
||||
// 传递给父级
|
||||
this.$emit('deleteImage', imageIndex)
|
||||
|
||||
},
|
||||
|
||||
// 显示入驻协议弹窗
|
||||
handleShowLicense() {
|
||||
this.$emit('showLicense',true)
|
||||
this.showLicense = true
|
||||
},
|
||||
|
||||
// 表单提交
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
const { form, imageList } = this
|
||||
// 判断是否需要上传图片
|
||||
if (imageList[0].size == 100 || imageList[1].size == 100 || imageList[2].size == 100) {
|
||||
app.$toast('请上传图片!')
|
||||
return false
|
||||
}
|
||||
app.$refs.uForm.validate(valid => {
|
||||
if (valid) {
|
||||
// 传递给父级
|
||||
app.$emit('handleSubmit', form, imageList)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
.form-license {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
// 上传凭证
|
||||
.row-voucher {
|
||||
padding: 24rpx 20rpx;
|
||||
|
||||
.image-list {
|
||||
padding: 0 20rpx;
|
||||
margin-top: 20rpx;
|
||||
margin-bottom: -20rpx;
|
||||
|
||||
&:after {
|
||||
clear: both;
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.image-picker,
|
||||
.image-preview {
|
||||
width: 184rpx;
|
||||
height: 184rpx;
|
||||
margin-right: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
float: left;
|
||||
|
||||
&:nth-child(3n+0) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.image-picker {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 1rpx dashed #ccc;
|
||||
color: #ccc;
|
||||
|
||||
.choose-icon {
|
||||
font-size: 48rpx;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.choose-text {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
position: relative;
|
||||
|
||||
.image-delete {
|
||||
position: absolute;
|
||||
top: -15rpx;
|
||||
right: -15rpx;
|
||||
height: 42rpx;
|
||||
width: 42rpx;
|
||||
background: rgba(0, 0, 0, 0.64);
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
font-weight: bolder;
|
||||
font-size: 22rpx;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pops-content {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.sfz,
|
||||
.sfz1,
|
||||
.sfz2,
|
||||
.yyzz {
|
||||
width: 140rpx;
|
||||
padding-top: 20rpx;
|
||||
padding-right: 10rpx;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
|
||||
.footer {
|
||||
margin-top: 80rpx;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-wechat {
|
||||
background: #0ba90b;
|
||||
margin-bottom: 26rpx;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
412
package/apply/components/personal.vue
Normal file
412
package/apply/components/personal.vue
Normal file
@@ -0,0 +1,412 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper" :style="appThemeStyle">
|
||||
<u-form :model="form" ref="uForm" label-width="140rpx">
|
||||
<!-- {{JSON.stringify(setting)}} -->
|
||||
<u-form-item label="所在地区" prop="region">
|
||||
<select-region ref="sRegion" :disabled="disabled" v-model="form.region" />
|
||||
</u-form-item>
|
||||
<u-form-item label="公司名称" prop="company">
|
||||
<u-input v-model="form.company" :disabled="disabled" placeholder="请输入公司名称" />
|
||||
</u-form-item>
|
||||
<u-form-item label="联系电话" prop="phone">
|
||||
<u-input v-model="form.phone" :disabled="disabled" placeholder="请输入联系电话" />
|
||||
</u-form-item>
|
||||
<u-form-item label="姓名" prop="real_name">
|
||||
<u-input v-model="form.real_name" :disabled="disabled" placeholder="请输入商户姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="手机号码" prop="mobile">
|
||||
<u-input v-model="form.mobile" maxlength="11" :disabled="disabled" placeholder="请输入商户手机号" />
|
||||
</u-form-item>
|
||||
<Partner :form="form"></Partner>
|
||||
<u-form-item v-for="(item,imageIndex) in imageList" :key="imageIndex" :label="itemLabel[imageIndex]"
|
||||
:prop="itemProp[imageIndex]">
|
||||
<view class="image-preview">
|
||||
<image mode="widthFix" :src="item.path" class="sfz" @click="chooseImage(imageIndex)"></image>
|
||||
<text class="image-delete iconfont icon-shanchu" @click="deleteImage(imageIndex)"></text>
|
||||
</view>
|
||||
</u-form-item>
|
||||
<view class="form-license dis-flex flex-x-center flex-y-center">
|
||||
<view class="license-radio dis-flex flex-y-center" @click="isRead = !isRead">
|
||||
<text class="license-icon f-38 iconfont icon-radio"
|
||||
:class="[isRead ? 'c-violet' : 'col-bb']"></text>
|
||||
<text class="f-28 col-80">我已阅读并了解</text>
|
||||
</view>
|
||||
<text @click="handleShowLicense()"
|
||||
class="f-28 c-violet">【{{ setting.words.apply.words.license.value }}】</text>
|
||||
</view>
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn-wrapper">
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">{{ submitText }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 入驻协议弹窗 -->
|
||||
<u-modal v-model="showLicense" title="入驻协议">
|
||||
<scroll-view class="pops-content" :scroll-y="true">
|
||||
<text>{{ setting.license }}</text>
|
||||
</scroll-view>
|
||||
</u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
import {
|
||||
isMobile
|
||||
} from '@/utils/verify'
|
||||
import Empty from '@/components/empty'
|
||||
import * as ApplyApi from '@/api/apply.js'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
|
||||
// 图片上传类型
|
||||
const itemProp = ["sfz1", "sfz2", "yyzz"]
|
||||
// 图片上传名称
|
||||
const itemLabel = ["身份证(正)", "身份证(反)", "营业执照"]
|
||||
// 用户选择的图片列表
|
||||
const imageList = [{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/6b52b67ed9291757163c10ef96be1a54.png',
|
||||
size: 100
|
||||
},
|
||||
{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/55faad35f5ee30f3e8791bdfd2f75eb9.png',
|
||||
size: 100
|
||||
}
|
||||
]
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
real_name: [{
|
||||
required: true,
|
||||
message: '请输入您的真实姓名',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
company: [{
|
||||
required: true,
|
||||
message: '请输入您的公司名称',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
phone: [{
|
||||
required: true,
|
||||
message: '请输入联系电话',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
mobile: [{
|
||||
required: true,
|
||||
message: '请输入手机号',
|
||||
trigger: ['blur', 'change']
|
||||
}, {
|
||||
// 自定义验证函数
|
||||
validator: (rule, value, callback) => {
|
||||
// 返回true表示校验通过,返回false表示不通过
|
||||
return isMobile(value)
|
||||
},
|
||||
message: '手机号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['blur'],
|
||||
}],
|
||||
region: [{
|
||||
required: true,
|
||||
message: '请选择省市区',
|
||||
trigger: ['blur', 'change'],
|
||||
type: 'array'
|
||||
}],
|
||||
detail: [{
|
||||
required: true,
|
||||
message: '请输入详细地址',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
}
|
||||
|
||||
const maxImageLength = 2
|
||||
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Empty
|
||||
},
|
||||
props: {
|
||||
form: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
setting: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
imageList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
submitText: {
|
||||
type: String,
|
||||
default: '提交申请'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
itemProp,
|
||||
itemLabel,
|
||||
rules,
|
||||
// 入驻协议阅读状态
|
||||
isRead: false,
|
||||
// 显示入驻协议弹窗
|
||||
showLicense: false,
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules)
|
||||
},
|
||||
methods: {
|
||||
// 选择图片
|
||||
chooseImage(imageIndex) {
|
||||
const app = this
|
||||
const oldImageList = app.imageList
|
||||
const { form } = this
|
||||
// 是否可编辑
|
||||
if (form.apply_status && form.apply_status != 30) {
|
||||
return false
|
||||
}
|
||||
// 选择图片
|
||||
uni.chooseImage({
|
||||
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
|
||||
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
|
||||
success({
|
||||
tempFiles
|
||||
}) {
|
||||
// 删除第imageIndex个元素,并在数组的第imageIndex个位置添加新元素:
|
||||
app.imageList.splice(imageIndex, 1, tempFiles[0])
|
||||
}
|
||||
});
|
||||
// 传递给父级
|
||||
this.$emit('chooseImage',app.imageList)
|
||||
},
|
||||
|
||||
// 删除图片
|
||||
deleteImage(imageIndex) {
|
||||
const { disabled } = this
|
||||
if (disabled == true) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.imageList[imageIndex].path = '../../static/not-dealer.png'
|
||||
},
|
||||
|
||||
// 显示入驻协议弹窗
|
||||
handleShowLicense() {
|
||||
this.showLicense = true
|
||||
},
|
||||
|
||||
|
||||
// 表单提交
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
const { form } = this
|
||||
app.$refs.uForm.validate(valid => {
|
||||
if (valid) {
|
||||
// 传递给父级
|
||||
app.$emit('handleSubmit', form)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 上传图片
|
||||
uploadFile() {
|
||||
const app = this
|
||||
const {
|
||||
imageList,
|
||||
form
|
||||
} = app
|
||||
// 批量上传
|
||||
return new Promise((resolve, reject) => {
|
||||
if (imageList.length > 0) {
|
||||
UploadApi.image(imageList)
|
||||
.then(fileIds => {
|
||||
form.images = fileIds
|
||||
resolve(fileIds)
|
||||
})
|
||||
.catch(reject)
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 提交到后端
|
||||
onSubmit() {
|
||||
const app = this
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
let req;
|
||||
if (form.apply_status == 30) {
|
||||
req = ApplyApi.edit(form.apply_id, form)
|
||||
} else {
|
||||
req = ApplyApi.add(form)
|
||||
}
|
||||
req.then(result => {
|
||||
console.log("result: ", result);
|
||||
app.$toast(result.message)
|
||||
setTimeout(function() {
|
||||
uni.navigateBack()
|
||||
}, 2000)
|
||||
|
||||
})
|
||||
.finally(() => app.disabled = false)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
.form-license {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
// 上传凭证
|
||||
.row-voucher {
|
||||
padding: 24rpx 20rpx;
|
||||
|
||||
.image-list {
|
||||
padding: 0 20rpx;
|
||||
margin-top: 20rpx;
|
||||
margin-bottom: -20rpx;
|
||||
|
||||
&:after {
|
||||
clear: both;
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.image-picker,
|
||||
.image-preview {
|
||||
width: 184rpx;
|
||||
height: 184rpx;
|
||||
margin-right: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
float: left;
|
||||
|
||||
&:nth-child(3n+0) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.image-picker {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 1rpx dashed #ccc;
|
||||
color: #ccc;
|
||||
|
||||
.choose-icon {
|
||||
font-size: 48rpx;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.choose-text {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
position: relative;
|
||||
|
||||
.image-delete {
|
||||
position: absolute;
|
||||
top: -15rpx;
|
||||
right: -15rpx;
|
||||
height: 42rpx;
|
||||
width: 42rpx;
|
||||
background: rgba(0, 0, 0, 0.64);
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
font-weight: bolder;
|
||||
font-size: 22rpx;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pops-content {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.sfz,
|
||||
.sfz1,
|
||||
.sfz2,
|
||||
.yyzz {
|
||||
width: 140rpx;
|
||||
padding-top: 20rpx;
|
||||
padding-right: 10rpx;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
|
||||
.footer {
|
||||
margin-top: 80rpx;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-wechat {
|
||||
background: #0ba90b;
|
||||
margin-bottom: 26rpx;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
412
package/apply/components/teamer.vue
Executable file
412
package/apply/components/teamer.vue
Executable file
@@ -0,0 +1,412 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper" :style="appThemeStyle">
|
||||
<u-form :model="form" ref="uForm" label-width="140rpx">
|
||||
<!-- {{JSON.stringify(setting)}} -->
|
||||
<u-form-item label="所在地区" prop="region">
|
||||
<select-region ref="sRegion" :disabled="disabled" v-model="form.region" />
|
||||
</u-form-item>
|
||||
<u-form-item label="公司名称" prop="company">
|
||||
<u-input v-model="form.company" :disabled="disabled" placeholder="请输入公司名称" />
|
||||
</u-form-item>
|
||||
<u-form-item label="联系电话" prop="phone">
|
||||
<u-input v-model="form.phone" :disabled="disabled" placeholder="请输入联系电话" />
|
||||
</u-form-item>
|
||||
<u-form-item label="姓名" prop="real_name">
|
||||
<u-input v-model="form.real_name" :disabled="disabled" placeholder="请输入商户姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="手机号码" prop="mobile">
|
||||
<u-input v-model="form.mobile" maxlength="11" :disabled="disabled" placeholder="请输入商户手机号" />
|
||||
</u-form-item>
|
||||
<Partner :form="form"></Partner>
|
||||
<u-form-item v-for="(item,imageIndex) in imageList" :key="imageIndex" :label="itemLabel[imageIndex]"
|
||||
:prop="itemProp[imageIndex]">
|
||||
<view class="image-preview">
|
||||
<image mode="widthFix" :src="item.path" class="sfz" @click="chooseImage(imageIndex)"></image>
|
||||
<text class="image-delete iconfont icon-shanchu" @click="deleteImage(imageIndex)"></text>
|
||||
</view>
|
||||
</u-form-item>
|
||||
<view class="form-license dis-flex flex-x-center flex-y-center">
|
||||
<view class="license-radio dis-flex flex-y-center" @click="isRead = !isRead">
|
||||
<text class="license-icon f-38 iconfont icon-radio"
|
||||
:class="[isRead ? 'c-violet' : 'col-bb']"></text>
|
||||
<text class="f-28 col-80">我已阅读并了解</text>
|
||||
</view>
|
||||
<text @click="handleShowLicense()"
|
||||
class="f-28 c-violet">【{{ setting.words.apply.words.license.value }}】</text>
|
||||
</view>
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn-wrapper">
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">{{ submitText }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 入驻协议弹窗 -->
|
||||
<u-modal v-model="showLicense" title="入驻协议">
|
||||
<scroll-view class="pops-content" :scroll-y="true">
|
||||
<text>{{ setting.license }}</text>
|
||||
</scroll-view>
|
||||
</u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
import {
|
||||
isMobile
|
||||
} from '@/utils/verify'
|
||||
import Empty from '@/components/empty'
|
||||
import * as ApplyApi from '@/api/apply.js'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
|
||||
// 图片上传类型
|
||||
const itemProp = ["sfz1", "sfz2", "yyzz"]
|
||||
// 图片上传名称
|
||||
const itemLabel = ["身份证(正)", "身份证(反)", "营业执照"]
|
||||
// 用户选择的图片列表
|
||||
const imageList = [{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/6b52b67ed9291757163c10ef96be1a54.png',
|
||||
size: 100
|
||||
},
|
||||
{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/55faad35f5ee30f3e8791bdfd2f75eb9.png',
|
||||
size: 100
|
||||
}
|
||||
]
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
real_name: [{
|
||||
required: true,
|
||||
message: '请输入您的真实姓名',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
company: [{
|
||||
required: true,
|
||||
message: '请输入您的公司名称',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
phone: [{
|
||||
required: true,
|
||||
message: '请输入联系电话',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
mobile: [{
|
||||
required: true,
|
||||
message: '请输入手机号',
|
||||
trigger: ['blur', 'change']
|
||||
}, {
|
||||
// 自定义验证函数
|
||||
validator: (rule, value, callback) => {
|
||||
// 返回true表示校验通过,返回false表示不通过
|
||||
return isMobile(value)
|
||||
},
|
||||
message: '手机号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['blur'],
|
||||
}],
|
||||
region: [{
|
||||
required: true,
|
||||
message: '请选择省市区',
|
||||
trigger: ['blur', 'change'],
|
||||
type: 'array'
|
||||
}],
|
||||
detail: [{
|
||||
required: true,
|
||||
message: '请输入详细地址',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
}
|
||||
|
||||
const maxImageLength = 2
|
||||
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Empty
|
||||
},
|
||||
props: {
|
||||
form: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
setting: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
imageList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
submitText: {
|
||||
type: String,
|
||||
default: '提交申请'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
itemProp,
|
||||
itemLabel,
|
||||
rules,
|
||||
// 入驻协议阅读状态
|
||||
isRead: false,
|
||||
// 显示入驻协议弹窗
|
||||
showLicense: false,
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules)
|
||||
},
|
||||
methods: {
|
||||
// 选择图片
|
||||
chooseImage(imageIndex) {
|
||||
const app = this
|
||||
const oldImageList = app.imageList
|
||||
const { form } = this
|
||||
// 是否可编辑
|
||||
if (form.apply_status && form.apply_status != 30) {
|
||||
return false
|
||||
}
|
||||
// 选择图片
|
||||
uni.chooseImage({
|
||||
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
|
||||
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
|
||||
success({
|
||||
tempFiles
|
||||
}) {
|
||||
// 删除第imageIndex个元素,并在数组的第imageIndex个位置添加新元素:
|
||||
app.imageList.splice(imageIndex, 1, tempFiles[0])
|
||||
}
|
||||
});
|
||||
// 传递给父级
|
||||
this.$emit('chooseImage',app.imageList)
|
||||
},
|
||||
|
||||
// 删除图片
|
||||
deleteImage(imageIndex) {
|
||||
const { disabled } = this
|
||||
if (disabled == true) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.imageList[imageIndex].path = '../../static/not-dealer.png'
|
||||
},
|
||||
|
||||
// 显示入驻协议弹窗
|
||||
handleShowLicense() {
|
||||
this.showLicense = true
|
||||
},
|
||||
|
||||
|
||||
// 表单提交
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
const { form } = this
|
||||
app.$refs.uForm.validate(valid => {
|
||||
if (valid) {
|
||||
// 传递给父级
|
||||
app.$emit('handleSubmit', form)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 上传图片
|
||||
uploadFile() {
|
||||
const app = this
|
||||
const {
|
||||
imageList,
|
||||
form
|
||||
} = app
|
||||
// 批量上传
|
||||
return new Promise((resolve, reject) => {
|
||||
if (imageList.length > 0) {
|
||||
UploadApi.image(imageList)
|
||||
.then(fileIds => {
|
||||
form.images = fileIds
|
||||
resolve(fileIds)
|
||||
})
|
||||
.catch(reject)
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 提交到后端
|
||||
onSubmit() {
|
||||
const app = this
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
let req;
|
||||
if (form.apply_status == 30) {
|
||||
req = ApplyApi.edit(form.apply_id, form)
|
||||
} else {
|
||||
req = ApplyApi.add(form)
|
||||
}
|
||||
req.then(result => {
|
||||
console.log("result: ", result);
|
||||
app.$toast(result.message)
|
||||
setTimeout(function() {
|
||||
uni.navigateBack()
|
||||
}, 2000)
|
||||
|
||||
})
|
||||
.finally(() => app.disabled = false)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
.form-license {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
// 上传凭证
|
||||
.row-voucher {
|
||||
padding: 24rpx 20rpx;
|
||||
|
||||
.image-list {
|
||||
padding: 0 20rpx;
|
||||
margin-top: 20rpx;
|
||||
margin-bottom: -20rpx;
|
||||
|
||||
&:after {
|
||||
clear: both;
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.image-picker,
|
||||
.image-preview {
|
||||
width: 184rpx;
|
||||
height: 184rpx;
|
||||
margin-right: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
float: left;
|
||||
|
||||
&:nth-child(3n+0) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.image-picker {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 1rpx dashed #ccc;
|
||||
color: #ccc;
|
||||
|
||||
.choose-icon {
|
||||
font-size: 48rpx;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.choose-text {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
position: relative;
|
||||
|
||||
.image-delete {
|
||||
position: absolute;
|
||||
top: -15rpx;
|
||||
right: -15rpx;
|
||||
height: 42rpx;
|
||||
width: 42rpx;
|
||||
background: rgba(0, 0, 0, 0.64);
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
font-weight: bolder;
|
||||
font-size: 22rpx;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pops-content {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.sfz,
|
||||
.sfz1,
|
||||
.sfz2,
|
||||
.yyzz {
|
||||
width: 140rpx;
|
||||
padding-top: 20rpx;
|
||||
padding-right: 10rpx;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
|
||||
.footer {
|
||||
margin-top: 80rpx;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-wechat {
|
||||
background: #0ba90b;
|
||||
margin-bottom: 26rpx;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
595
package/apply/delivery.vue
Normal file
595
package/apply/delivery.vue
Normal file
@@ -0,0 +1,595 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<!-- 标题 -->
|
||||
<view class="page-title">申请入驻</view>
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper">
|
||||
<u-form :model="form" ref="uForm" label-width="140rpx">
|
||||
<u-form-item label="意向配送区域" prop="region">
|
||||
<select-region ref="sRegion" :disabled="disabled" v-model="form.region" />
|
||||
</u-form-item>
|
||||
<u-form-item label="姓名" prop="real_name">
|
||||
<u-input v-model="form.real_name" :disabled="disabled" placeholder="请输入商户姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="手机号码" prop="mobile">
|
||||
<u-input v-model="form.mobile" maxlength="11" :disabled="disabled" placeholder="请输入商户手机号" />
|
||||
</u-form-item>
|
||||
<u-form-item v-for="(item,imageIndex) in imageList" :key="imageIndex" :label="itemLabel[imageIndex]"
|
||||
:prop="itemProp[imageIndex]">
|
||||
<view class="image-preview">
|
||||
<image mode="widthFix" :src="item.path" class="sfz" @click="chooseImage(imageIndex)"></image>
|
||||
<text class="image-delete iconfont icon-shanchu" @click="deleteImage(imageIndex)"></text>
|
||||
</view>
|
||||
</u-form-item>
|
||||
<view class="form-license dis-flex flex-x-center flex-y-center">
|
||||
<view class="license-radio dis-flex flex-y-center" @click="isRead = !isRead">
|
||||
<text class="license-icon f-38 iconfont icon-radio"
|
||||
:class="[isRead ? 'c-violet' : 'col-bb']"></text>
|
||||
<text class="f-28 col-80">我已阅读并了解</text>
|
||||
</view>
|
||||
<text @click="handleShowLicense()" class="f-28 c-violet">【{{ words.license.value }}】</text>
|
||||
</view>
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn-wrapper">
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">{{ submitText }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 入驻协议弹窗 -->
|
||||
<u-modal v-model="showLicense" title="申请协议">
|
||||
<scroll-view class="pops-content" :scroll-y="true">
|
||||
<text>{{ license }}</text>
|
||||
</scroll-view>
|
||||
</u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
import {
|
||||
isMobile
|
||||
} from '@/utils/verify'
|
||||
import * as ApplyApi from '@/api/apply.js'
|
||||
import * as UploadApi from '@/api/upload'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
// 入驻类型
|
||||
const dataType = [
|
||||
"partner", // 商家
|
||||
"teamer", // 团长
|
||||
"delivery", // 配送员
|
||||
"personal" // 个人商户
|
||||
]
|
||||
// 图片上传类型
|
||||
const itemProp = ["sfz1", "sfz2"]
|
||||
// 图片上传名称
|
||||
const itemLabel = ["身份证(正)", "身份证(反)"]
|
||||
|
||||
// 用户选择的图片列表
|
||||
const imageList = [{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/6b52b67ed9291757163c10ef96be1a54.png',
|
||||
size: 0
|
||||
},{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/6b52b67ed9291757163c10ef96be1a54.png',
|
||||
size: 0
|
||||
}
|
||||
]
|
||||
|
||||
// 表单字段元素
|
||||
const form = {
|
||||
// 入驻类型 (商家10001,配送员10002,社区门店10003,省代10004)
|
||||
grade_id: 10002,
|
||||
company: '',
|
||||
real_name: '',
|
||||
phone: '',
|
||||
mobile: '',
|
||||
region: [],
|
||||
detail: '',
|
||||
}
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
real_name: [{
|
||||
required: true,
|
||||
message: '请输入您的真实姓名',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
company: [{
|
||||
required: true,
|
||||
message: '请输入您的公司名称',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
phone: [{
|
||||
required: true,
|
||||
message: '请输入联系电话',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
mobile: [{
|
||||
required: true,
|
||||
message: '请输入手机号',
|
||||
trigger: ['blur', 'change']
|
||||
}, {
|
||||
// 自定义验证函数
|
||||
validator: (rule, value, callback) => {
|
||||
// 返回true表示校验通过,返回false表示不通过
|
||||
return isMobile(value)
|
||||
},
|
||||
message: '手机号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['blur'],
|
||||
}],
|
||||
region: [{
|
||||
required: true,
|
||||
message: '请选择省市区',
|
||||
trigger: ['blur', 'change'],
|
||||
type: 'array'
|
||||
}],
|
||||
detail: [{
|
||||
required: true,
|
||||
message: '请输入详细地址',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
}
|
||||
|
||||
const maxImageLength = 2
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataType,
|
||||
itemProp,
|
||||
itemLabel,
|
||||
imageList,
|
||||
form,
|
||||
rules,
|
||||
// 按钮禁用
|
||||
disabled: false,
|
||||
submitText: '提交申请',
|
||||
|
||||
// 文字设置
|
||||
words: undefined,
|
||||
// 显示入驻协议弹窗
|
||||
showLicense: false,
|
||||
// 入驻协议
|
||||
license: undefined,
|
||||
// 入驻协议阅读状态
|
||||
isRead: false,
|
||||
// 显示入驻协议弹窗
|
||||
showLicense: false,
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
const app = this
|
||||
app.getSetting()
|
||||
// 获取用户坐标及当前入驻申请记录
|
||||
app.getLocation((res) => {
|
||||
app.getData(res.longitude, res.latitude)
|
||||
})
|
||||
},
|
||||
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules)
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 获取用户坐标
|
||||
// 参考文档:https://uniapp.dcloud.io/api/location/location?id=getlocation
|
||||
getLocation(callback) {
|
||||
const app = this
|
||||
uni.getLocation({
|
||||
type: 'wgs84',
|
||||
success: callback,
|
||||
fail() {
|
||||
app.$toast('获取定位失败,请点击右下角按钮重新尝试定位')
|
||||
app.isAuthor = false
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 加载数据
|
||||
getData(longitude,latitude) {
|
||||
const app = this
|
||||
console.log("long: ",longitude);
|
||||
app.form.longitude = longitude
|
||||
app.form.latitude = latitude
|
||||
ApplyApi.detail().then(res => {
|
||||
const detail = res.data.detail
|
||||
console.log(detail);
|
||||
// 编辑信息
|
||||
if (detail) {
|
||||
app.form = detail
|
||||
app.createFormData(detail)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 生成默认的表单数据
|
||||
createFormData(detail) {
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
form.company = detail.company
|
||||
form.phone = detail.phone
|
||||
form.region = this.createRegion(detail.shop)
|
||||
// 是否可编辑
|
||||
this.disabled = true
|
||||
// 状态
|
||||
if (form.apply_status == 10) {
|
||||
this.submitText = '待审核'
|
||||
}
|
||||
if (form.apply_status == 20) {
|
||||
this.submitText = '审核通过'
|
||||
}
|
||||
if (form.apply_status == 30) {
|
||||
this.submitText = '重新提交'
|
||||
this.disabled = false
|
||||
}
|
||||
|
||||
// 加载图片
|
||||
this.imageList = detail.images.map(d => {
|
||||
return {
|
||||
path: d.image_url,
|
||||
size: 101
|
||||
}
|
||||
})
|
||||
form.images = detail.images.map(d => {
|
||||
return d.image_id
|
||||
})
|
||||
},
|
||||
|
||||
createRegion(detail) {
|
||||
return [{
|
||||
label: detail.region.province,
|
||||
value: detail.province_id
|
||||
}, {
|
||||
label: detail.region.city,
|
||||
value: detail.city_id
|
||||
}, {
|
||||
label: detail.region.region,
|
||||
value: detail.region_id
|
||||
}]
|
||||
},
|
||||
|
||||
// 获取分销设置
|
||||
getSetting() {
|
||||
const app = this
|
||||
SettingModel.data()
|
||||
.then(setting => {
|
||||
// 赋值属性
|
||||
app.words = setting.words.apply.words
|
||||
app.background = setting.background.apply
|
||||
app.license = setting.license.license
|
||||
// 设置当前页面标题
|
||||
app.setPageTitle(setting.words.apply.title)
|
||||
})
|
||||
},
|
||||
|
||||
// 显示入驻协议弹窗
|
||||
handleShowLicense() {
|
||||
this.showLicense = true
|
||||
},
|
||||
|
||||
// 设置当前页面标题
|
||||
setPageTitle(title) {
|
||||
uni.setNavigationBarTitle({
|
||||
title: '申请成为配送员'
|
||||
})
|
||||
},
|
||||
|
||||
// 选择图片
|
||||
chooseImage(imageIndex) {
|
||||
const app = this
|
||||
const oldImageList = app.imageList
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
// 是否可编辑
|
||||
if (form.apply_status && form.apply_status != 30) {
|
||||
app.disabled = true
|
||||
return false
|
||||
}
|
||||
// 选择图片
|
||||
uni.chooseImage({
|
||||
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
|
||||
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
|
||||
success({
|
||||
tempFiles
|
||||
}) {
|
||||
// 删除第imageIndex个元素,并在数组的第imageIndex个位置添加新元素:
|
||||
app.imageList.splice(imageIndex, 1, tempFiles[0])
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 删除图片
|
||||
deleteImage(imageIndex) {
|
||||
const {
|
||||
disabled
|
||||
} = this
|
||||
if (disabled == true) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.imageList[imageIndex].path = '../../static/not-dealer.png'
|
||||
},
|
||||
|
||||
// 选择微信地址
|
||||
// #ifdef MP-WEIXIN
|
||||
chooseAddress() {
|
||||
const {
|
||||
form,
|
||||
$refs
|
||||
} = this
|
||||
uni.chooseAddress({
|
||||
success(res) {
|
||||
const names = $refs.sRegion.getOptionItemByNames(res)
|
||||
form.name = res.userName
|
||||
form.phone = res.telNumber
|
||||
form.detail = res.detailInfo
|
||||
form.region = names.length > 0 ? names : []
|
||||
}
|
||||
})
|
||||
},
|
||||
// #endif
|
||||
|
||||
// 表单提交
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
console.log(app.disabled);
|
||||
if (app.disabled) {
|
||||
return false
|
||||
}
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
const {
|
||||
imageList
|
||||
} = this
|
||||
app.$refs.uForm.validate(valid => {
|
||||
if (valid) {
|
||||
app.disabled = true
|
||||
ApplyApi.checkAvailable(form).then(res => {
|
||||
// 判断是否需要上传图片
|
||||
if (imageList[0].size == 0 || imageList[1].size == 0) {
|
||||
app.$toast('请上传图片!')
|
||||
app.disabled = false
|
||||
return false
|
||||
}
|
||||
if (imageList.length > 0 && imageList[0].size > 0) {
|
||||
app.uploadFile()
|
||||
.then(() => app.onSubmit())
|
||||
.catch(err => {
|
||||
app.disabled = false
|
||||
if (err.statusCode !== 0) {
|
||||
app.$toast(err.errMsg)
|
||||
}
|
||||
console.log('err', err)
|
||||
})
|
||||
} else {
|
||||
app.onSubmit()
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log("err: ", err);
|
||||
if (err.statusCode == 0) {
|
||||
app.disabled = false
|
||||
app.$toast(err.errMsg)
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 上传图片
|
||||
uploadFile() {
|
||||
const app = this
|
||||
const {
|
||||
imageList,
|
||||
form
|
||||
} = app
|
||||
// 批量上传
|
||||
return new Promise((resolve, reject) => {
|
||||
if (imageList.length > 0) {
|
||||
UploadApi.image(imageList)
|
||||
.then(fileIds => {
|
||||
form.images = fileIds
|
||||
resolve(fileIds)
|
||||
})
|
||||
.catch(reject)
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 提交到后端
|
||||
onSubmit() {
|
||||
const app = this
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
let req;
|
||||
if (form.apply_status == 30) {
|
||||
req = ApplyApi.edit(form.apply_id, form)
|
||||
} else {
|
||||
req = ApplyApi.add(form)
|
||||
}
|
||||
req.then(result => {
|
||||
console.log("result: ", result);
|
||||
app.$toast(result.message)
|
||||
setTimeout(function() {
|
||||
uni.navigateBack()
|
||||
}, 2000)
|
||||
|
||||
})
|
||||
.finally(() => app.disabled = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #f7f8fa;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.page-title {
|
||||
width: 94%;
|
||||
margin: 0 auto;
|
||||
padding-top: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(69, 90, 100, 0.6);
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
|
||||
.footer {
|
||||
margin-top: 80rpx;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-wechat {
|
||||
background: #0ba90b;
|
||||
margin-bottom: 26rpx;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 上传凭证
|
||||
.row-voucher {
|
||||
padding: 24rpx 20rpx;
|
||||
|
||||
.image-list {
|
||||
padding: 0 20rpx;
|
||||
margin-top: 20rpx;
|
||||
margin-bottom: -20rpx;
|
||||
|
||||
&:after {
|
||||
clear: both;
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.image-picker,
|
||||
.image-preview {
|
||||
width: 184rpx;
|
||||
height: 184rpx;
|
||||
margin-right: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
float: left;
|
||||
|
||||
&:nth-child(3n+0) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.image-picker {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 1rpx dashed #ccc;
|
||||
color: #ccc;
|
||||
|
||||
.choose-icon {
|
||||
font-size: 48rpx;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.choose-text {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
position: relative;
|
||||
|
||||
.image-delete {
|
||||
position: absolute;
|
||||
top: -15rpx;
|
||||
right: -15rpx;
|
||||
height: 42rpx;
|
||||
width: 42rpx;
|
||||
background: rgba(0, 0, 0, 0.64);
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
font-weight: bolder;
|
||||
font-size: 22rpx;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-license {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.pops-content {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.sfz,
|
||||
.sfz1,
|
||||
.sfz2,
|
||||
.yyzz {
|
||||
width: 140rpx;
|
||||
padding-top: 20rpx;
|
||||
padding-right: 10rpx;
|
||||
}
|
||||
</style>
|
||||
625
package/apply/index.vue
Normal file
625
package/apply/index.vue
Normal file
@@ -0,0 +1,625 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<view class="reject" v-if="form.apply_status == 10">
|
||||
<u-alert-tips type="error" title="申请已提交:" description="请耐心等待工作人员的审核"></u-alert-tips>
|
||||
</view>
|
||||
<view class="reject" v-else-if="form.apply_status == 30">
|
||||
<u-alert-tips type="error" title="您的申请已被驳回:" :description="form.reject_reason"></u-alert-tips>
|
||||
</view>
|
||||
<u-form :model="form" ref="uForm" label-width="140rpx">
|
||||
<!-- 标题 -->
|
||||
<view class="page-title">基本信息</view>
|
||||
<view class="form-wrapper">
|
||||
<u-form-item label="站点名称" prop="company">
|
||||
<u-input v-model="form.company" :disabled="disabled" placeholder="请输入站点名称" />
|
||||
</u-form-item>
|
||||
<u-form-item label="门脸照" prop="shopImage">
|
||||
<u-upload ref="shopImage" :fileList="fileList1" :action="action" :header="headers"
|
||||
@delete="deletePic" index="1" name="file" :maxCount="1" @afterRead="afterRead">
|
||||
</u-upload>
|
||||
</u-form-item>
|
||||
</view>
|
||||
<!-- 标题 -->
|
||||
<view class="page-title">经营信息</view>
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper">
|
||||
<u-form-item label="所在地区" prop="region">
|
||||
<!-- {{form.region}}
|
||||
<u-select v-if="show" :disabled="disabled" :list="cityList" v-model="form.region"></u-select>
|
||||
<text @click="openSelect">{{ cityName }}</text> -->
|
||||
<select-region ref="sRegion" :disabled="disabled" v-model="form.region" />
|
||||
</u-form-item>
|
||||
<u-form-item label="站点地址" prop="address">
|
||||
<u-input v-model="form.address" :disabled="disabled" placeholder="请输入站点地址" />
|
||||
</u-form-item>
|
||||
<u-form-item label="食品经营许可证" prop="shipincard">
|
||||
<u-upload ref="shipinCardImage" :fileList="fileList2" :action="action" :header="headers"
|
||||
@delete="deletePic" index="2" name="file" :maxCount="1">
|
||||
</u-upload>
|
||||
</u-form-item>
|
||||
<u-form-item label="法定代表人身份证" prop="sfz">
|
||||
<u-upload ref="sfzImage" :fileList="fileList3" :action="action" :header="headers"
|
||||
@delete="deletePic" index="3" name="file" :maxCount="2">
|
||||
</u-upload>
|
||||
</u-form-item>
|
||||
<u-form-item label="营业执照" prop="yyzz">
|
||||
<u-upload ref="yyzzImage" :fileList="fileList4" :action="action" :header="headers"
|
||||
@delete="deletePic" index="4" name="file" :maxCount="1">
|
||||
</u-upload>
|
||||
</u-form-item>
|
||||
<u-form-item label="姓名" prop="real_name">
|
||||
<u-input v-model="form.real_name" :disabled="disabled" placeholder="请输入姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="手机号码" prop="mobile">
|
||||
<u-input v-model="form.mobile" maxlength="11" :disabled="disabled" placeholder="请输入手机号" />
|
||||
</u-form-item>
|
||||
<u-form-item label="微信号" prop="weixin">
|
||||
<u-input v-model="form.weixin" :disabled="disabled" placeholder="请输入微信号" />
|
||||
</u-form-item>
|
||||
</view>
|
||||
</u-form>
|
||||
<view class="btn">
|
||||
<u-button type="primary" shape="circle" @click="handleSubmit()">
|
||||
{{ submitText }}
|
||||
</u-button>
|
||||
</view>
|
||||
<view class="btn"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from '@/store'
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
import {
|
||||
isMobile
|
||||
} from '@/utils/verify'
|
||||
import * as ApplyApi from '@/api/apply.js'
|
||||
import * as UploadApi from '@/api/upload'
|
||||
import * as RegionApi from '@/api/region.js'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
// 入驻类型
|
||||
const dataType = [
|
||||
"partner", // 合伙人
|
||||
"teamer", // 团长
|
||||
"delivery", // 配送员
|
||||
"personal" // 个人商户
|
||||
]
|
||||
|
||||
// 表单字段元素
|
||||
const form = {
|
||||
// 入驻类型 (合伙人10001,配送员10002,社区门店10003,省代10004)
|
||||
grade_id: 10001,
|
||||
company: '',
|
||||
real_name: '',
|
||||
phone: '',
|
||||
mobile: '',
|
||||
region: [],
|
||||
detail: '',
|
||||
address: '',
|
||||
shop_image: '',
|
||||
shipin_card_image: '',
|
||||
sfz_image1: '',
|
||||
sfz_image2: '',
|
||||
yyzz_image: '',
|
||||
cityList: [],
|
||||
}
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
real_name: [{
|
||||
required: true,
|
||||
message: '请输入您的真实姓名',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
company: [{
|
||||
required: true,
|
||||
message: '请输入您的商户名称',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
address: [{
|
||||
required: true,
|
||||
message: '请输入站点地址',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
weixin: [{
|
||||
required: true,
|
||||
message: '请输入微信号',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
mobile: [{
|
||||
required: true,
|
||||
message: '请输入手机号',
|
||||
trigger: ['blur', 'change']
|
||||
}, {
|
||||
// 自定义验证函数
|
||||
validator: (rule, value, callback) => {
|
||||
// 返回true表示校验通过,返回false表示不通过
|
||||
return isMobile(value)
|
||||
},
|
||||
message: '手机号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['blur'],
|
||||
}],
|
||||
region: [{
|
||||
required: true,
|
||||
message: '请选择省市区',
|
||||
trigger: ['blur', 'change'],
|
||||
type: 'array'
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataType,
|
||||
fileList1: [],
|
||||
fileList2: [],
|
||||
fileList3: [],
|
||||
fileList4: [],
|
||||
form,
|
||||
rules,
|
||||
show: false,
|
||||
cityName: '选择所在城市',
|
||||
// 按钮禁用
|
||||
disabled: false,
|
||||
submitText: '申请创建商户',
|
||||
|
||||
// 文字设置
|
||||
words: undefined,
|
||||
// 显示入驻协议弹窗
|
||||
showLicense: false,
|
||||
// 入驻协议
|
||||
license: undefined,
|
||||
// 入驻协议阅读状态
|
||||
isRead: false,
|
||||
// 显示入驻协议弹窗
|
||||
showLicense: false,
|
||||
action: 'https://dev.gxwebsoft.com/ylx/api/upload/image',
|
||||
headers: {
|
||||
'storeId': 10001,
|
||||
'Access-Token': uni.getStorageSync('AccessToken'),
|
||||
'platform': store.getters.platform
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
const app = this
|
||||
app.getSetting()
|
||||
// 获取用户坐标及当前入驻申请记录
|
||||
app.getLocation((res) => {
|
||||
app.getData(res.longitude, res.latitude)
|
||||
})
|
||||
app.getRegion()
|
||||
},
|
||||
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules)
|
||||
},
|
||||
|
||||
methods: {
|
||||
openSelect() {
|
||||
this.show = !this.show
|
||||
},
|
||||
// 删除图片
|
||||
deletePic(event) {
|
||||
if (this.disabled) {
|
||||
return false
|
||||
}
|
||||
this[`fileList${event.name}`].splice(event.index, 1)
|
||||
},
|
||||
// 获取用户坐标
|
||||
// 参考文档:https://uniapp.dcloud.io/api/location/location?id=getlocation
|
||||
getLocation(callback) {
|
||||
const app = this
|
||||
uni.getLocation({
|
||||
type: 'wgs84',
|
||||
success: callback,
|
||||
fail(e) {
|
||||
app.$toast('获取定位失败,请点击右下角按钮重新尝试定位')
|
||||
app.isAuthor = false
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 加载数据
|
||||
getData(longitude, latitude) {
|
||||
const app = this
|
||||
app.form.longitude = longitude
|
||||
app.form.latitude = latitude
|
||||
ApplyApi.detail().then(res => {
|
||||
const detail = res.data.detail
|
||||
// 编辑信息
|
||||
if (detail) {
|
||||
app.form = detail
|
||||
if (detail.apply_status == 10) {
|
||||
app.submitText = '待审核'
|
||||
}
|
||||
if (detail.apply_status == 20) {
|
||||
app.submitText = '审核通过'
|
||||
}
|
||||
if (detail.apply_status == 30) {
|
||||
app.submitText = '重新提交'
|
||||
}
|
||||
app.createFormData(detail)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
onAfterRead(e){
|
||||
console.log("e: ",e);
|
||||
},
|
||||
|
||||
getRegion() {
|
||||
RegionApi.list({
|
||||
status: 20,
|
||||
level: 2
|
||||
}).then(res => {
|
||||
this.cityList = res.data.list.map(d => {
|
||||
return {
|
||||
label: d.name,
|
||||
value: d.id,
|
||||
code: d.code,
|
||||
id: d.id,
|
||||
name: d.name,
|
||||
pid: d.pid,
|
||||
status: d.status
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 生成默认的表单数据
|
||||
createFormData(detail) {
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
form.company = detail.company
|
||||
form.phone = detail.phone
|
||||
form.mobile = detail.mobile
|
||||
form.region = this.createRegion(detail)
|
||||
|
||||
// 加载图片
|
||||
this.fileList1.push({
|
||||
'url': detail.shop_image
|
||||
})
|
||||
this.fileList2.push({
|
||||
'url': detail.shipin_card_image
|
||||
})
|
||||
this.fileList3.push({
|
||||
'url': detail.sfz_image1
|
||||
})
|
||||
this.fileList3.push({
|
||||
'url': detail.sfz_image2
|
||||
})
|
||||
this.fileList4.push({
|
||||
'url': detail.yyzz_image
|
||||
})
|
||||
|
||||
// 是否可编辑
|
||||
this.disabled = true
|
||||
// 状态
|
||||
if (form.apply_status == 10) {
|
||||
this.submitText = '待审核'
|
||||
}
|
||||
if (form.apply_status == 20) {
|
||||
this.submitText = '审核通过'
|
||||
}
|
||||
if (form.apply_status == 30) {
|
||||
this.submitText = '重新提交'
|
||||
this.disabled = false
|
||||
}
|
||||
},
|
||||
|
||||
createRegion(detail) {
|
||||
return [{
|
||||
label: detail.region.province,
|
||||
value: detail.province_id
|
||||
}, {
|
||||
label: detail.region.city,
|
||||
value: detail.city_id
|
||||
}, {
|
||||
label: detail.region.region,
|
||||
value: detail.region_id
|
||||
}]
|
||||
},
|
||||
|
||||
// 获取分销设置
|
||||
getSetting() {
|
||||
const app = this
|
||||
SettingModel.data()
|
||||
.then(setting => {
|
||||
// 赋值属性
|
||||
app.words = setting.words.apply.words
|
||||
app.background = setting.background.apply
|
||||
app.license = setting.license.license
|
||||
// 设置当前页面标题
|
||||
app.setPageTitle(setting.words.apply.title)
|
||||
})
|
||||
},
|
||||
|
||||
// 显示入驻协议弹窗
|
||||
handleShowLicense() {
|
||||
this.showLicense = true
|
||||
},
|
||||
|
||||
// 设置当前页面标题
|
||||
setPageTitle(title) {
|
||||
uni.setNavigationBarTitle({
|
||||
title: '商户入驻'
|
||||
})
|
||||
},
|
||||
|
||||
// 选择微信地址
|
||||
// #ifdef MP-WEIXIN
|
||||
chooseAddress() {
|
||||
const {
|
||||
form,
|
||||
$refs
|
||||
} = this
|
||||
uni.chooseAddress({
|
||||
success(res) {
|
||||
const names = $refs.sRegion.getOptionItemByNames(res)
|
||||
form.name = res.userName
|
||||
form.phone = res.telNumber
|
||||
form.detail = res.detailInfo
|
||||
form.region = names.length > 0 ? names : []
|
||||
}
|
||||
})
|
||||
},
|
||||
// #endif
|
||||
|
||||
afterRead(e){
|
||||
console.log("e: ",e);
|
||||
},
|
||||
|
||||
// 表单提交
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
if (app.disabled) {
|
||||
return false
|
||||
}
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
if(app.$refs.shopImage.lists.length == 0){
|
||||
app.$toast('请上传门脸照')
|
||||
return false
|
||||
}
|
||||
if(app.$refs.shipinCardImage.lists.length == 0){
|
||||
app.$toast('请上传食品经营许可证')
|
||||
return false
|
||||
}
|
||||
if(app.$refs.sfzImage.lists.length != 2){
|
||||
app.$toast('请上传法定代表人身份证正反面')
|
||||
return false
|
||||
}
|
||||
if(app.$refs.yyzzImage.lists.length == 0){
|
||||
app.$toast('请上传营业执照')
|
||||
return false
|
||||
}
|
||||
app.$refs.uForm.validate(valid => {
|
||||
if (valid) {
|
||||
// 上传图片
|
||||
if (app.fileList1.length == 0) {
|
||||
form.shop_image = app.$refs.shopImage.lists[0].response.data.fileInfo.preview_url;
|
||||
}
|
||||
if (app.fileList2.length == 0) {
|
||||
form.shipin_card_image = app.$refs.shipinCardImage.lists[0].response.data.fileInfo.preview_url;
|
||||
}
|
||||
if (app.fileList3.length == 0) {
|
||||
form.sfz_image1 = app.$refs.sfzImage.lists[0].response.data.fileInfo.preview_url;
|
||||
form.sfz_image2 = app.$refs.sfzImage.lists[1].response.data.fileInfo.preview_url;
|
||||
}
|
||||
if (app.fileList4.length == 0) {
|
||||
form.yyzz_image = app.$refs.yyzzImage.lists[0].response.data.fileInfo.preview_url;
|
||||
}
|
||||
form.phone = form.mobile
|
||||
ApplyApi.checkAvailable(form).then(res => {
|
||||
app.disabled = true
|
||||
app.onSubmit()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 提交到后端
|
||||
onSubmit() {
|
||||
const app = this
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
let req;
|
||||
if (form.apply_status == 30) {
|
||||
req = ApplyApi.edit(form.apply_id, form)
|
||||
} else {
|
||||
console.log('add');
|
||||
req = ApplyApi.add(form)
|
||||
}
|
||||
req.then(result => {
|
||||
console.log("result: ", result);
|
||||
app.$toast(result.message)
|
||||
setTimeout(function() {
|
||||
uni.navigateBack()
|
||||
}, 2000)
|
||||
|
||||
})
|
||||
.finally(() => app.disabled = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #f7f8fa;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.page-title {
|
||||
width: 94%;
|
||||
margin: 0 auto;
|
||||
padding-top: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(69, 90, 100, 0.6);
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
|
||||
.footer {
|
||||
margin-top: 80rpx;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-wechat {
|
||||
background: #0ba90b;
|
||||
margin-bottom: 26rpx;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 上传凭证
|
||||
.row-voucher {
|
||||
padding: 24rpx 20rpx;
|
||||
|
||||
.image-list {
|
||||
padding: 0 20rpx;
|
||||
margin-top: 20rpx;
|
||||
margin-bottom: -20rpx;
|
||||
|
||||
&:after {
|
||||
clear: both;
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.image-picker,
|
||||
.image-preview {
|
||||
width: 184rpx;
|
||||
height: 184rpx;
|
||||
margin-right: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
float: left;
|
||||
|
||||
&:nth-child(3n+0) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.image-picker {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 1rpx dashed #ccc;
|
||||
color: #ccc;
|
||||
|
||||
.choose-icon {
|
||||
font-size: 48rpx;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.choose-text {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
position: relative;
|
||||
|
||||
.image-delete {
|
||||
position: absolute;
|
||||
top: -15rpx;
|
||||
right: -15rpx;
|
||||
height: 42rpx;
|
||||
width: 42rpx;
|
||||
background: rgba(0, 0, 0, 0.64);
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
font-weight: bolder;
|
||||
font-size: 22rpx;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-license {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.pops-content {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.sfz,
|
||||
.sfz1,
|
||||
.sfz2,
|
||||
.yyzz {
|
||||
width: 140rpx;
|
||||
padding-top: 20rpx;
|
||||
padding-right: 10rpx;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 700rpx;
|
||||
margin: 20rpx auto;
|
||||
height: 100rpx;
|
||||
}
|
||||
|
||||
.reject {
|
||||
width: 700rpx;
|
||||
margin: 20rpx auto;
|
||||
}
|
||||
</style>
|
||||
604
package/apply/personal.vue
Normal file
604
package/apply/personal.vue
Normal file
@@ -0,0 +1,604 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<!-- 标题 -->
|
||||
<view class="page-title">申请入驻</view>
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper">
|
||||
<u-form :model="form" ref="uForm" label-width="140rpx">
|
||||
<u-form-item label="所在地区" prop="region">
|
||||
<select-region ref="sRegion" :disabled="disabled" v-model="form.region" />
|
||||
</u-form-item>
|
||||
<u-form-item label="公司名称" prop="company">
|
||||
<u-input v-model="form.company" :disabled="disabled" placeholder="请输入公司名称" />
|
||||
</u-form-item>
|
||||
<u-form-item label="联系电话" prop="phone">
|
||||
<u-input v-model="form.phone" :disabled="disabled" placeholder="请输入联系电话" />
|
||||
</u-form-item>
|
||||
<u-form-item label="姓名" prop="real_name">
|
||||
<u-input v-model="form.real_name" :disabled="disabled" placeholder="请输入商户姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="手机号码" prop="mobile">
|
||||
<u-input v-model="form.mobile" maxlength="11" :disabled="disabled" placeholder="请输入商户手机号" />
|
||||
</u-form-item>
|
||||
<u-form-item v-for="(item,imageIndex) in imageList" :key="imageIndex" :label="itemLabel[imageIndex]"
|
||||
:prop="itemProp[imageIndex]">
|
||||
<view class="image-preview">
|
||||
<image mode="widthFix" :src="item.path" class="sfz" @click="chooseImage(imageIndex)"></image>
|
||||
<text class="image-delete iconfont icon-shanchu" @click="deleteImage(imageIndex)"></text>
|
||||
</view>
|
||||
</u-form-item>
|
||||
<view class="form-license dis-flex flex-x-center flex-y-center">
|
||||
<view class="license-radio dis-flex flex-y-center" @click="isRead = !isRead">
|
||||
<text class="license-icon f-38 iconfont icon-radio"
|
||||
:class="[isRead ? 'c-violet' : 'col-bb']"></text>
|
||||
<text class="f-28 col-80">我已阅读并了解</text>
|
||||
</view>
|
||||
<text @click="handleShowLicense()" class="f-28 c-violet">【{{ words.license.value }}】</text>
|
||||
</view>
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn-wrapper">
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">{{ submitText }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 入驻协议弹窗 -->
|
||||
<u-modal v-model="showLicense" title="申请协议">
|
||||
<scroll-view class="pops-content" :scroll-y="true">
|
||||
<text>{{ license }}</text>
|
||||
</scroll-view>
|
||||
</u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
import {
|
||||
isMobile
|
||||
} from '@/utils/verify'
|
||||
import * as ApplyApi from '@/api/apply.js'
|
||||
import * as UploadApi from '@/api/upload'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
// 入驻类型
|
||||
const dataType = [
|
||||
"partner", // 合伙人
|
||||
"teamer", // 团长
|
||||
"delivery", // 配送员
|
||||
"personal" // 个人商户
|
||||
]
|
||||
// 图片上传类型
|
||||
const itemProp = ["sfz1", "sfz2", "yyzz"]
|
||||
// 图片上传名称
|
||||
const itemLabel = ["身份证(正)", "身份证(反)", "营业执照"]
|
||||
|
||||
// 用户选择的图片列表
|
||||
const imageList = [{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/6b52b67ed9291757163c10ef96be1a54.png',
|
||||
size: 0
|
||||
},{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/6b52b67ed9291757163c10ef96be1a54.png',
|
||||
size: 0
|
||||
},
|
||||
{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/55faad35f5ee30f3e8791bdfd2f75eb9.png',
|
||||
size: 0
|
||||
}
|
||||
]
|
||||
|
||||
// 表单字段元素
|
||||
const form = {
|
||||
// 入驻类型 (合伙人10001,配送员10002,社区门店10003,省代10004)
|
||||
grade_id: 10004,
|
||||
company: '',
|
||||
real_name: '',
|
||||
phone: '',
|
||||
mobile: '',
|
||||
region: [],
|
||||
detail: '',
|
||||
}
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
real_name: [{
|
||||
required: true,
|
||||
message: '请输入您的真实姓名',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
company: [{
|
||||
required: true,
|
||||
message: '请输入您的公司名称',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
phone: [{
|
||||
required: true,
|
||||
message: '请输入联系电话',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
mobile: [{
|
||||
required: true,
|
||||
message: '请输入手机号',
|
||||
trigger: ['blur', 'change']
|
||||
}, {
|
||||
// 自定义验证函数
|
||||
validator: (rule, value, callback) => {
|
||||
// 返回true表示校验通过,返回false表示不通过
|
||||
return isMobile(value)
|
||||
},
|
||||
message: '手机号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['blur'],
|
||||
}],
|
||||
region: [{
|
||||
required: true,
|
||||
message: '请选择省市区',
|
||||
trigger: ['blur', 'change'],
|
||||
type: 'array'
|
||||
}],
|
||||
detail: [{
|
||||
required: true,
|
||||
message: '请输入详细地址',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
}
|
||||
|
||||
const maxImageLength = 2
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataType,
|
||||
itemProp,
|
||||
itemLabel,
|
||||
imageList,
|
||||
form,
|
||||
rules,
|
||||
// 按钮禁用
|
||||
disabled: false,
|
||||
submitText: '提交申请',
|
||||
|
||||
// 文字设置
|
||||
words: undefined,
|
||||
// 显示入驻协议弹窗
|
||||
showLicense: false,
|
||||
// 入驻协议
|
||||
license: undefined,
|
||||
// 入驻协议阅读状态
|
||||
isRead: false,
|
||||
// 显示入驻协议弹窗
|
||||
showLicense: false,
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
const app = this
|
||||
app.getSetting()
|
||||
// 获取用户坐标及当前入驻申请记录
|
||||
app.getLocation((res) => {
|
||||
app.getData(res.longitude, res.latitude)
|
||||
})
|
||||
},
|
||||
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules)
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 获取用户坐标
|
||||
// 参考文档:https://uniapp.dcloud.io/api/location/location?id=getlocation
|
||||
getLocation(callback) {
|
||||
const app = this
|
||||
uni.getLocation({
|
||||
type: 'wgs84',
|
||||
success: callback,
|
||||
fail() {
|
||||
app.$toast('获取定位失败,请点击右下角按钮重新尝试定位')
|
||||
app.isAuthor = false
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 加载数据
|
||||
getData(longitude,latitude) {
|
||||
const app = this
|
||||
app.form.longitude = longitude
|
||||
app.form.latitude = latitude
|
||||
ApplyApi.detail().then(res => {
|
||||
const detail = res.data.detail
|
||||
console.log(detail);
|
||||
// 编辑信息
|
||||
if (detail) {
|
||||
app.form = detail
|
||||
app.createFormData(detail)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 生成默认的表单数据
|
||||
createFormData(detail) {
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
form.company = detail.company
|
||||
form.phone = detail.phone
|
||||
form.region = this.createRegion(detail.shop)
|
||||
// 是否可编辑
|
||||
this.disabled = true
|
||||
// 状态
|
||||
if (form.apply_status == 10) {
|
||||
this.submitText = '待审核'
|
||||
}
|
||||
if (form.apply_status == 20) {
|
||||
this.submitText = '审核通过'
|
||||
}
|
||||
if (form.apply_status == 30) {
|
||||
this.submitText = '重新提交'
|
||||
this.disabled = false
|
||||
}
|
||||
|
||||
// 加载图片
|
||||
this.imageList = detail.images.map(d => {
|
||||
return {
|
||||
path: d.image_url,
|
||||
size: 101
|
||||
}
|
||||
})
|
||||
form.images = detail.images.map(d => {
|
||||
return d.image_id
|
||||
})
|
||||
},
|
||||
|
||||
createRegion(detail) {
|
||||
return [{
|
||||
label: detail.region.province,
|
||||
value: detail.province_id
|
||||
}, {
|
||||
label: detail.region.city,
|
||||
value: detail.city_id
|
||||
}, {
|
||||
label: detail.region.region,
|
||||
value: detail.region_id
|
||||
}]
|
||||
},
|
||||
|
||||
// 获取分销设置
|
||||
getSetting() {
|
||||
const app = this
|
||||
SettingModel.data()
|
||||
.then(setting => {
|
||||
// 赋值属性
|
||||
app.words = setting.words.apply.words
|
||||
app.background = setting.background.apply
|
||||
app.license = setting.license.license
|
||||
// 设置当前页面标题
|
||||
app.setPageTitle(setting.words.apply.title)
|
||||
})
|
||||
},
|
||||
|
||||
// 显示入驻协议弹窗
|
||||
handleShowLicense() {
|
||||
this.showLicense = true
|
||||
},
|
||||
|
||||
// 设置当前页面标题
|
||||
setPageTitle(title) {
|
||||
uni.setNavigationBarTitle({
|
||||
title: '申请成为商家'
|
||||
})
|
||||
},
|
||||
|
||||
// 选择图片
|
||||
chooseImage(imageIndex) {
|
||||
const app = this
|
||||
const oldImageList = app.imageList
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
// 是否可编辑
|
||||
if (form.apply_status && form.apply_status != 30) {
|
||||
app.disabled = true
|
||||
return false
|
||||
}
|
||||
// 选择图片
|
||||
uni.chooseImage({
|
||||
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
|
||||
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
|
||||
success({
|
||||
tempFiles
|
||||
}) {
|
||||
// 删除第imageIndex个元素,并在数组的第imageIndex个位置添加新元素:
|
||||
app.imageList.splice(imageIndex, 1, tempFiles[0])
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 删除图片
|
||||
deleteImage(imageIndex) {
|
||||
const {
|
||||
disabled
|
||||
} = this
|
||||
if (disabled == true) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.imageList[imageIndex].path = '../../static/not-dealer.png'
|
||||
},
|
||||
|
||||
// 选择微信地址
|
||||
// #ifdef MP-WEIXIN
|
||||
chooseAddress() {
|
||||
const {
|
||||
form,
|
||||
$refs
|
||||
} = this
|
||||
uni.chooseAddress({
|
||||
success(res) {
|
||||
const names = $refs.sRegion.getOptionItemByNames(res)
|
||||
form.name = res.userName
|
||||
form.phone = res.telNumber
|
||||
form.detail = res.detailInfo
|
||||
form.region = names.length > 0 ? names : []
|
||||
}
|
||||
})
|
||||
},
|
||||
// #endif
|
||||
|
||||
// 表单提交
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
console.log(app.disabled);
|
||||
if (app.disabled) {
|
||||
return false
|
||||
}
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
const {
|
||||
imageList
|
||||
} = this
|
||||
app.$refs.uForm.validate(valid => {
|
||||
if (valid) {
|
||||
app.disabled = true
|
||||
ApplyApi.checkAvailable(form).then(res => {
|
||||
// 判断是否需要上传图片
|
||||
if (imageList[0].size == 0 || imageList[1].size == 0 || imageList[2].size == 0) {
|
||||
app.$toast('请上传图片!')
|
||||
app.disabled = false
|
||||
return false
|
||||
}
|
||||
if (imageList.length > 0 && imageList[0].size > 0) {
|
||||
app.uploadFile()
|
||||
.then(() => app.onSubmit())
|
||||
.catch(err => {
|
||||
app.disabled = false
|
||||
if (err.statusCode !== 0) {
|
||||
app.$toast(err.errMsg)
|
||||
}
|
||||
console.log('err', err)
|
||||
})
|
||||
} else {
|
||||
app.onSubmit()
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log("err: ", err);
|
||||
if (err.statusCode == 0) {
|
||||
app.disabled = false
|
||||
app.$toast(err.errMsg)
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 上传图片
|
||||
uploadFile() {
|
||||
const app = this
|
||||
const {
|
||||
imageList,
|
||||
form
|
||||
} = app
|
||||
// 批量上传
|
||||
return new Promise((resolve, reject) => {
|
||||
if (imageList.length > 0) {
|
||||
UploadApi.image(imageList)
|
||||
.then(fileIds => {
|
||||
form.images = fileIds
|
||||
resolve(fileIds)
|
||||
})
|
||||
.catch(reject)
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 提交到后端
|
||||
onSubmit() {
|
||||
const app = this
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
let req;
|
||||
if (form.apply_status == 30) {
|
||||
req = ApplyApi.edit(form.apply_id, form)
|
||||
} else {
|
||||
req = ApplyApi.add(form)
|
||||
}
|
||||
req.then(result => {
|
||||
console.log("result: ", result);
|
||||
app.$toast(result.message)
|
||||
setTimeout(function() {
|
||||
uni.navigateBack()
|
||||
}, 2000)
|
||||
|
||||
})
|
||||
.finally(() => app.disabled = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #f7f8fa;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.page-title {
|
||||
width: 94%;
|
||||
margin: 0 auto;
|
||||
padding-top: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(69, 90, 100, 0.6);
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
|
||||
.footer {
|
||||
margin-top: 80rpx;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-wechat {
|
||||
background: #0ba90b;
|
||||
margin-bottom: 26rpx;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 上传凭证
|
||||
.row-voucher {
|
||||
padding: 24rpx 20rpx;
|
||||
|
||||
.image-list {
|
||||
padding: 0 20rpx;
|
||||
margin-top: 20rpx;
|
||||
margin-bottom: -20rpx;
|
||||
|
||||
&:after {
|
||||
clear: both;
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.image-picker,
|
||||
.image-preview {
|
||||
width: 184rpx;
|
||||
height: 184rpx;
|
||||
margin-right: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
float: left;
|
||||
|
||||
&:nth-child(3n+0) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.image-picker {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 1rpx dashed #ccc;
|
||||
color: #ccc;
|
||||
|
||||
.choose-icon {
|
||||
font-size: 48rpx;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.choose-text {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
position: relative;
|
||||
|
||||
.image-delete {
|
||||
position: absolute;
|
||||
top: -15rpx;
|
||||
right: -15rpx;
|
||||
height: 42rpx;
|
||||
width: 42rpx;
|
||||
background: rgba(0, 0, 0, 0.64);
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
font-weight: bolder;
|
||||
font-size: 22rpx;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-license {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.pops-content {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.sfz,
|
||||
.sfz1,
|
||||
.sfz2,
|
||||
.yyzz {
|
||||
width: 140rpx;
|
||||
padding-top: 20rpx;
|
||||
padding-right: 10rpx;
|
||||
}
|
||||
</style>
|
||||
80
package/apply/select.vue
Normal file
80
package/apply/select.vue
Normal file
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<view class="wrap" :style="appThemeStyle">
|
||||
<u-row gutter="16">
|
||||
<u-col span="6">
|
||||
<view class="wrap-item bg-purple-light" v-if="gradeId == 0 || gradeId == 10001" @click="navTo('package/apply/index')"><image src="http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/b437b0213516d446f2bbd2e4ca4aa1d3.png" class="wrap-avatar" mode="widthFix"></image><text class="item-text">商户入驻</text></view>
|
||||
</u-col>
|
||||
<!-- <u-col span="6">
|
||||
<view class="wrap-item bg-purple-light" v-if="gradeId == 0 || gradeId == 10002" @click="navTo('package/apply/delivery')"><image src="http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/92ba7cadfa6459034c3570e9141c49f5.png" class="wrap-avatar" mode="widthFix"></image><text class="item-text">配送员入驻</text></view>
|
||||
</u-col> -->
|
||||
<u-col span="6">
|
||||
<!-- <view class="wrap-item bg-purple-light" v-if="gradeId == 0 || gradeId == 10003" @click="navTo('package/apply/teamer')"><image src="http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/4df3d4d3a575467d9216b081ef23fe7a.png" class="wrap-avatar" mode="widthFix"></image><text class="item-text">团长入驻</text></view> -->
|
||||
</u-col>
|
||||
<!-- <u-col span="6">
|
||||
<view class="wrap-item bg-purple-light" v-if="gradeId == 0 || gradeId == 10004" @click="navTo('package/apply/personal')"><image src="http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/127c0a1f401a1119937eb3995235dc26.png" class="wrap-avatar" mode="widthFix"></image><text class="item-text">个人商户入驻</text></view>
|
||||
</u-col> -->
|
||||
</u-row>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as ApplyApi from '@/api/apply.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
gradeId: 0,
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
onLoad(){
|
||||
ApplyApi.detail().then(res => {
|
||||
let detail = res.data.detail
|
||||
if(detail){
|
||||
this.gradeId = detail.grade_id
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
navTo(url){
|
||||
this.$navTo(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.wrap {
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
.u-row {
|
||||
margin: 40rpx 0;
|
||||
}
|
||||
|
||||
.wrap-item {
|
||||
height: 120rpx;
|
||||
border-radius: 8rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.bg-purple {
|
||||
background: #d3dce6;
|
||||
}
|
||||
|
||||
.bg-purple-light {
|
||||
background: #e5e9f2;
|
||||
}
|
||||
|
||||
.bg-purple-dark {
|
||||
background: #99a9bf;
|
||||
}
|
||||
.wrap-avatar{
|
||||
width: 80rpx;
|
||||
}
|
||||
.item-text{
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
</style>
|
||||
605
package/apply/teamer.vue
Normal file
605
package/apply/teamer.vue
Normal file
@@ -0,0 +1,605 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<!-- 标题 -->
|
||||
<view class="page-title">申请入驻</view>
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper">
|
||||
<u-form :model="form" ref="uForm" label-width="140rpx">
|
||||
<u-form-item label="所在地区" prop="region">
|
||||
<select-region ref="sRegion" :disabled="disabled" v-model="form.region" />
|
||||
</u-form-item>
|
||||
<u-form-item label="公司名称" prop="company">
|
||||
<u-input v-model="form.company" :disabled="disabled" placeholder="请输入公司名称" />
|
||||
</u-form-item>
|
||||
<u-form-item label="联系电话" prop="phone">
|
||||
<u-input v-model="form.phone" :disabled="disabled" placeholder="请输入联系电话" />
|
||||
</u-form-item>
|
||||
<u-form-item label="姓名" prop="real_name">
|
||||
<u-input v-model="form.real_name" :disabled="disabled" placeholder="请输入商家姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="手机号码" prop="mobile">
|
||||
<u-input v-model="form.mobile" maxlength="11" :disabled="disabled" placeholder="请输入商家手机号" />
|
||||
</u-form-item>
|
||||
<u-form-item v-for="(item,imageIndex) in imageList" :key="imageIndex" :label="itemLabel[imageIndex]"
|
||||
:prop="itemProp[imageIndex]">
|
||||
<view class="image-preview">
|
||||
<image mode="widthFix" :src="item.path" class="sfz" @click="chooseImage(imageIndex)"></image>
|
||||
<text class="image-delete iconfont icon-shanchu" @click="deleteImage(imageIndex)"></text>
|
||||
</view>
|
||||
</u-form-item>
|
||||
<view class="form-license dis-flex flex-x-center flex-y-center">
|
||||
<view class="license-radio dis-flex flex-y-center" @click="isRead = !isRead">
|
||||
<text class="license-icon f-38 iconfont icon-radio"
|
||||
:class="[isRead ? 'c-violet' : 'col-bb']"></text>
|
||||
<text class="f-28 col-80">我已阅读并了解</text>
|
||||
</view>
|
||||
<text @click="handleShowLicense()" class="f-28 c-violet">【{{ words.license.value }}】</text>
|
||||
</view>
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn-wrapper">
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">{{ submitText }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 入驻协议弹窗 -->
|
||||
<u-modal v-model="showLicense" title="申请协议">
|
||||
<scroll-view class="pops-content" :scroll-y="true">
|
||||
<text>{{ license }}</text>
|
||||
</scroll-view>
|
||||
</u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
import {
|
||||
isMobile
|
||||
} from '@/utils/verify'
|
||||
import * as ApplyApi from '@/api/apply.js'
|
||||
import * as UploadApi from '@/api/upload'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
// 入驻类型
|
||||
const dataType = [
|
||||
"partner", // 合伙人
|
||||
"teamer", // 团长
|
||||
"delivery", // 配送员
|
||||
"personal" // 个人商户
|
||||
]
|
||||
// 图片上传类型
|
||||
const itemProp = ["sfz1", "sfz2", "yyzz"]
|
||||
// 图片上传名称
|
||||
const itemLabel = ["身份证(正)", "身份证(反)", "营业执照"]
|
||||
|
||||
// 用户选择的图片列表
|
||||
const imageList = [{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/6b52b67ed9291757163c10ef96be1a54.png',
|
||||
size: 0
|
||||
},{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/6b52b67ed9291757163c10ef96be1a54.png',
|
||||
size: 0
|
||||
},
|
||||
{
|
||||
path: 'http://dev.gxwebsoft.com/hainiu/uploads/10001/20220522/55faad35f5ee30f3e8791bdfd2f75eb9.png',
|
||||
size: 0
|
||||
}
|
||||
]
|
||||
|
||||
// 表单字段元素
|
||||
const form = {
|
||||
// 入驻类型 (合伙人10001,配送员10002,社区门店10003,省代10004)
|
||||
grade_id: 10003,
|
||||
company: '',
|
||||
real_name: '',
|
||||
phone: '',
|
||||
mobile: '',
|
||||
region: [],
|
||||
detail: '',
|
||||
}
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
real_name: [{
|
||||
required: true,
|
||||
message: '请输入您的真实姓名',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
company: [{
|
||||
required: true,
|
||||
message: '请输入您的公司名称',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
phone: [{
|
||||
required: true,
|
||||
message: '请输入联系电话',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
mobile: [{
|
||||
required: true,
|
||||
message: '请输入手机号',
|
||||
trigger: ['blur', 'change']
|
||||
}, {
|
||||
// 自定义验证函数
|
||||
validator: (rule, value, callback) => {
|
||||
// 返回true表示校验通过,返回false表示不通过
|
||||
return isMobile(value)
|
||||
},
|
||||
message: '手机号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['blur'],
|
||||
}],
|
||||
region: [{
|
||||
required: true,
|
||||
message: '请选择省市区',
|
||||
trigger: ['blur', 'change'],
|
||||
type: 'array'
|
||||
}],
|
||||
detail: [{
|
||||
required: true,
|
||||
message: '请输入详细地址',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
}
|
||||
|
||||
const maxImageLength = 2
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataType,
|
||||
itemProp,
|
||||
itemLabel,
|
||||
imageList,
|
||||
form,
|
||||
rules,
|
||||
// 按钮禁用
|
||||
disabled: false,
|
||||
submitText: '提交申请',
|
||||
|
||||
// 文字设置
|
||||
words: undefined,
|
||||
// 显示入驻协议弹窗
|
||||
showLicense: false,
|
||||
// 入驻协议
|
||||
license: undefined,
|
||||
// 入驻协议阅读状态
|
||||
isRead: false,
|
||||
// 显示入驻协议弹窗
|
||||
showLicense: false,
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
const app = this
|
||||
app.getSetting()
|
||||
// 获取用户坐标及当前入驻申请记录
|
||||
app.getLocation((res) => {
|
||||
app.getData(res.longitude, res.latitude)
|
||||
})
|
||||
},
|
||||
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules)
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 获取用户坐标
|
||||
// 参考文档:https://uniapp.dcloud.io/api/location/location?id=getlocation
|
||||
getLocation(callback) {
|
||||
const app = this
|
||||
uni.getLocation({
|
||||
type: 'wgs84',
|
||||
success: callback,
|
||||
fail() {
|
||||
app.$toast('获取定位失败,请点击右下角按钮重新尝试定位')
|
||||
app.isAuthor = false
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 加载数据
|
||||
getData(longitude,latitude) {
|
||||
const app = this
|
||||
app.form.longitude = longitude
|
||||
app.form.latitude = latitude
|
||||
ApplyApi.detail().then(res => {
|
||||
const detail = res.data.detail
|
||||
console.log(detail);
|
||||
// 编辑信息
|
||||
if (detail) {
|
||||
app.form = detail
|
||||
app.createFormData(detail)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
// 生成默认的表单数据
|
||||
createFormData(detail) {
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
form.company = detail.company
|
||||
form.phone = detail.phone
|
||||
form.region = this.createRegion(detail.shop)
|
||||
// 是否可编辑
|
||||
this.disabled = true
|
||||
// 状态
|
||||
if (form.apply_status == 10) {
|
||||
this.submitText = '待审核'
|
||||
}
|
||||
if (form.apply_status == 20) {
|
||||
this.submitText = '审核通过'
|
||||
}
|
||||
if (form.apply_status == 30) {
|
||||
this.submitText = '重新提交'
|
||||
this.disabled = false
|
||||
}
|
||||
|
||||
// 加载图片
|
||||
this.imageList = detail.images.map(d => {
|
||||
return {
|
||||
path: d.image_url,
|
||||
size: 101
|
||||
}
|
||||
})
|
||||
form.images = detail.images.map(d => {
|
||||
return d.image_id
|
||||
})
|
||||
},
|
||||
|
||||
createRegion(detail) {
|
||||
return [{
|
||||
label: detail.region.province,
|
||||
value: detail.province_id
|
||||
}, {
|
||||
label: detail.region.city,
|
||||
value: detail.city_id
|
||||
}, {
|
||||
label: detail.region.region,
|
||||
value: detail.region_id
|
||||
}]
|
||||
},
|
||||
|
||||
// 获取分销设置
|
||||
getSetting() {
|
||||
const app = this
|
||||
SettingModel.data()
|
||||
.then(setting => {
|
||||
// 赋值属性
|
||||
app.words = setting.words.apply.words
|
||||
app.background = setting.background.apply
|
||||
app.license = setting.license.license
|
||||
// 设置当前页面标题
|
||||
app.setPageTitle(setting.words.apply.title)
|
||||
})
|
||||
},
|
||||
|
||||
// 显示入驻协议弹窗
|
||||
handleShowLicense() {
|
||||
this.showLicense = true
|
||||
},
|
||||
|
||||
// 设置当前页面标题
|
||||
setPageTitle(title) {
|
||||
uni.setNavigationBarTitle({
|
||||
title: '申请成为团长'
|
||||
})
|
||||
},
|
||||
|
||||
// 选择图片
|
||||
chooseImage(imageIndex) {
|
||||
const app = this
|
||||
const oldImageList = app.imageList
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
// 是否可编辑
|
||||
if (form.apply_status && form.apply_status != 30) {
|
||||
app.disabled = true
|
||||
return false
|
||||
}
|
||||
// 选择图片
|
||||
uni.chooseImage({
|
||||
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
|
||||
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
|
||||
success({
|
||||
tempFiles
|
||||
}) {
|
||||
// 删除第imageIndex个元素,并在数组的第imageIndex个位置添加新元素:
|
||||
app.imageList.splice(imageIndex, 1, tempFiles[0])
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 删除图片
|
||||
deleteImage(imageIndex) {
|
||||
const {
|
||||
disabled
|
||||
} = this
|
||||
if (disabled == true) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.imageList[imageIndex].path = '../../static/not-dealer.png'
|
||||
},
|
||||
|
||||
// 选择微信地址
|
||||
// #ifdef MP-WEIXIN
|
||||
chooseAddress() {
|
||||
const {
|
||||
form,
|
||||
$refs
|
||||
} = this
|
||||
uni.chooseAddress({
|
||||
success(res) {
|
||||
const names = $refs.sRegion.getOptionItemByNames(res)
|
||||
form.name = res.userName
|
||||
form.phone = res.telNumber
|
||||
form.detail = res.detailInfo
|
||||
form.region = names.length > 0 ? names : []
|
||||
}
|
||||
})
|
||||
},
|
||||
// #endif
|
||||
|
||||
// 表单提交
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
console.log(app.disabled);
|
||||
if (app.disabled) {
|
||||
return false
|
||||
}
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
const {
|
||||
imageList
|
||||
} = this
|
||||
app.$refs.uForm.validate(valid => {
|
||||
if (valid) {
|
||||
app.disabled = true
|
||||
ApplyApi.checkAvailable(form).then(res => {
|
||||
// 判断是否需要上传图片
|
||||
if (imageList[0].size == 0 || imageList[1].size == 0 || imageList[2].size == 0) {
|
||||
app.$toast('请上传图片!')
|
||||
app.disabled = false
|
||||
return false
|
||||
}
|
||||
if (imageList.length > 0 && imageList[0].size > 0) {
|
||||
app.uploadFile()
|
||||
.then(() => app.onSubmit())
|
||||
.catch(err => {
|
||||
app.disabled = false
|
||||
if (err.statusCode !== 0) {
|
||||
app.$toast(err.errMsg)
|
||||
}
|
||||
console.log('err', err)
|
||||
})
|
||||
} else {
|
||||
app.onSubmit()
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log("err: ", err);
|
||||
if (err.statusCode == 0) {
|
||||
app.disabled = false
|
||||
app.$toast(err.errMsg)
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 上传图片
|
||||
uploadFile() {
|
||||
const app = this
|
||||
const {
|
||||
imageList,
|
||||
form
|
||||
} = app
|
||||
// 批量上传
|
||||
return new Promise((resolve, reject) => {
|
||||
if (imageList.length > 0) {
|
||||
UploadApi.image(imageList)
|
||||
.then(fileIds => {
|
||||
form.images = fileIds
|
||||
resolve(fileIds)
|
||||
})
|
||||
.catch(reject)
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 提交到后端
|
||||
onSubmit() {
|
||||
const app = this
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
let req;
|
||||
if (form.apply_status == 30) {
|
||||
req = ApplyApi.edit(form.apply_id, form)
|
||||
} else {
|
||||
req = ApplyApi.add(form)
|
||||
}
|
||||
req.then(result => {
|
||||
console.log("result: ", result);
|
||||
app.$toast(result.message)
|
||||
setTimeout(function() {
|
||||
uni.navigateBack()
|
||||
}, 2000)
|
||||
|
||||
})
|
||||
.finally(() => app.disabled = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #f7f8fa;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.page-title {
|
||||
width: 94%;
|
||||
margin: 0 auto;
|
||||
padding-top: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(69, 90, 100, 0.6);
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
|
||||
.footer {
|
||||
margin-top: 80rpx;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-wechat {
|
||||
background: #0ba90b;
|
||||
margin-bottom: 26rpx;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 上传凭证
|
||||
.row-voucher {
|
||||
padding: 24rpx 20rpx;
|
||||
|
||||
.image-list {
|
||||
padding: 0 20rpx;
|
||||
margin-top: 20rpx;
|
||||
margin-bottom: -20rpx;
|
||||
|
||||
&:after {
|
||||
clear: both;
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.image-picker,
|
||||
.image-preview {
|
||||
width: 184rpx;
|
||||
height: 184rpx;
|
||||
margin-right: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
float: left;
|
||||
|
||||
&:nth-child(3n+0) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.image-picker {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 1rpx dashed #ccc;
|
||||
color: #ccc;
|
||||
|
||||
.choose-icon {
|
||||
font-size: 48rpx;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.choose-text {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
position: relative;
|
||||
|
||||
.image-delete {
|
||||
position: absolute;
|
||||
top: -15rpx;
|
||||
right: -15rpx;
|
||||
height: 42rpx;
|
||||
width: 42rpx;
|
||||
background: rgba(0, 0, 0, 0.64);
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
font-weight: bolder;
|
||||
font-size: 22rpx;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-license {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.pops-content {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.sfz,
|
||||
.sfz1,
|
||||
.sfz2,
|
||||
.yyzz {
|
||||
width: 140rpx;
|
||||
padding-top: 20rpx;
|
||||
padding-right: 10rpx;
|
||||
}
|
||||
</style>
|
||||
67
package/brand/components/search.vue
Executable file
67
package/brand/components/search.vue
Executable file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<!-- 搜索框 -->
|
||||
<view class="search-wrapper">
|
||||
<view class="index-search" @click="onClick">
|
||||
<view class="index-cont-search t-c">
|
||||
<text class="search-icon iconfont icon-search"></text>
|
||||
<text class="search-text">{{ tips }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
tips: {
|
||||
type: String,
|
||||
default: '搜索关键词'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onClick() {
|
||||
this.$emit('event')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search-wrapper {
|
||||
padding: 13rpx;
|
||||
}
|
||||
|
||||
.index-search {
|
||||
border-bottom: 0;
|
||||
border-radius: 50rpx;
|
||||
overflow: hidden;
|
||||
font-size: 28rpx;
|
||||
color: #6d6d6d;
|
||||
box-sizing: border-box;
|
||||
line-height: 64rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.index-cont-search {
|
||||
width: 100%;
|
||||
font-size: 28rpx;
|
||||
background: #f7f7f7;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.index-cont-search .search-icon {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.index-cont-search .search-text {
|
||||
margin-left: 14rpx;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
228
package/brand/detail.vue
Normal file
228
package/brand/detail.vue
Normal file
@@ -0,0 +1,228 @@
|
||||
<template>
|
||||
<view class="partner">
|
||||
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper" v-if="detail">
|
||||
<u-form :model="form" ref="uForm" label-width="240rpx">
|
||||
<u-form-item>
|
||||
<image :src="detail.imageUrl" mode="widthFix" class="banner"></image>
|
||||
<view class="brand-name">{{detail.name}}</view>
|
||||
</u-form-item>
|
||||
<u-form-item>
|
||||
<view class="shop-box">
|
||||
<text class="shop-name">品牌介绍</text>
|
||||
<text>{{detail.describe}}</text>
|
||||
</view>
|
||||
</u-form-item>
|
||||
<view class="buy-desc">如果有意向,请填写以下信息给平台留言</view>
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper">
|
||||
<u-form :model="form" ref="uForm" label-width="140rpx">
|
||||
<u-form-item label="姓名" prop="real_name">
|
||||
<u-input v-model="form.real_name" :disabled="disabled" placeholder="请输入姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="电话" prop="phone">
|
||||
<u-input v-model="form.phone" maxlength="11" :disabled="disabled" placeholder="请输入联系电话" />
|
||||
</u-form-item>
|
||||
<u-form-item label="性别" prop="sex">
|
||||
<u-radio-group v-model="form.sex">
|
||||
<u-radio @change="groupChange" v-for="(item, index) in sex" :key="index"
|
||||
:name="item.name" :disabled="item.disabled">
|
||||
{{item.name}}
|
||||
</u-radio>
|
||||
</u-radio-group>
|
||||
</u-form-item>
|
||||
<u-form-item label="定制预算" prop="money">
|
||||
<u-input type="number" v-model="form.money" :disabled="disabled" placeholder="请输入定制预算" />
|
||||
</u-form-item>
|
||||
<u-form-item label="微信号" prop="weixin">
|
||||
<u-input v-model="form.weixin" :disabled="disabled" placeholder="请输入微信号" />
|
||||
</u-form-item>
|
||||
<u-form-item label="意向区域" prop="region">
|
||||
<select-region ref="sRegion" :disabled="disabled" v-model="form.region" />
|
||||
</u-form-item>
|
||||
<u-form-item label="整体需求" prop="comments">
|
||||
<u-input v-model="form.comments" :disabled="disabled" placeholder="请输入整体需求" />
|
||||
</u-form-item>
|
||||
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn">
|
||||
<u-button type="primary" shape="circle" @click="handleSubmit()">提交</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<!-- <view class="footer">
|
||||
<view class="btn">
|
||||
<u-button type="primary" shape="circle">更新资料</u-button>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 表单字段元素
|
||||
const form = {
|
||||
name: '',
|
||||
phone: '',
|
||||
sex: '',
|
||||
money: '',
|
||||
region: [],
|
||||
weixin: '',
|
||||
comments: '',
|
||||
}
|
||||
|
||||
const sex = [{
|
||||
name: '男',
|
||||
value: 1,
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
name: '女',
|
||||
value: 2,
|
||||
disabled: false
|
||||
}
|
||||
]
|
||||
|
||||
import * as Api from '@/api/brand/index.js'
|
||||
import * as ApplyApi from '@/api/brand/apply.js'
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form,
|
||||
disabled: false,
|
||||
detail: {},
|
||||
brandId: 0,
|
||||
sex
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.brandId = options.brandId
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
// 获取当前用户信息
|
||||
init() {
|
||||
const app = this
|
||||
const {
|
||||
brandId
|
||||
} = this
|
||||
console.log(brandId);
|
||||
Api.detail(brandId).then(result => {
|
||||
app.detail = result.data.detail
|
||||
})
|
||||
},
|
||||
groupChange(e) {
|
||||
this.form.sex = e
|
||||
},
|
||||
|
||||
// 表单提交
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
// if (app.disabled) {
|
||||
// return false
|
||||
// }
|
||||
const {
|
||||
form,
|
||||
brandId
|
||||
} = this
|
||||
form.brand_id = brandId
|
||||
app.$refs.uForm.validate(valid => {
|
||||
if (valid) {
|
||||
app.disabled = true
|
||||
app.onSubmit()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 提交到后端
|
||||
onSubmit() {
|
||||
const app = this
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
let req;
|
||||
if (form.apply_status == 30) {
|
||||
req = ApplyApi.edit(form.apply_id, form)
|
||||
} else {
|
||||
console.log('add');
|
||||
req = ApplyApi.add(form)
|
||||
}
|
||||
req.then(result => {
|
||||
console.log("result: ", result);
|
||||
app.$toast(result.message)
|
||||
setTimeout(function() {
|
||||
uni.navigateBack()
|
||||
}, 2000)
|
||||
|
||||
})
|
||||
.finally(() => app.disabled = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.partner {
|
||||
.banner {
|
||||
padding-top: 20rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
|
||||
.shop-box {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.shop-name {
|
||||
font-weight: bold;
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 100rpx;
|
||||
}
|
||||
|
||||
.shipin {
|
||||
width: 400rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: 500rpx;
|
||||
margin: 50rpx auto;
|
||||
padding-bottom: 50rpx !important;
|
||||
}
|
||||
}
|
||||
|
||||
.brand-name {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.buy-desc {
|
||||
text-align: center;
|
||||
color: #ff0000;
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
|
||||
.buy-text {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
68
package/brand/index.vue
Normal file
68
package/brand/index.vue
Normal file
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<view class="solution">
|
||||
<!-- <view class="search">
|
||||
<search class="search" :tips="options.search ? options.search : '搜索关键词'" @event="handleSearch" />
|
||||
</view> -->
|
||||
<view class="grid">
|
||||
<u-grid :border="false">
|
||||
<u-grid-item v-for="(item,index) in baseList" :key="index">
|
||||
<image :src="item.imageUrl" class="avatar" mode="widthFix" @click="navTo('package/brand/detail?brandId=' + item.brandId)"></image>
|
||||
<text class="grid-text" @click="navTo('package/brand/detail?brandId=' + item.brandId)">{{item.name}}</text>
|
||||
</u-grid-item>
|
||||
</u-grid>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Search from './components/search'
|
||||
import * as Api from '@/api/brand/index.js'
|
||||
export default {
|
||||
components: {
|
||||
Search
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
baseList: []
|
||||
}
|
||||
},
|
||||
onLoad(){
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
init(){
|
||||
const app = this
|
||||
Api.list().then(res => {
|
||||
app.baseList = res.data.list.data
|
||||
})
|
||||
},
|
||||
navTo(url){
|
||||
this.$navTo(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.solution {
|
||||
background-color: #ffffff;
|
||||
.search {
|
||||
padding: 10rpx 20rpx;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 700rpx;
|
||||
border-radius: 100%;
|
||||
margin: 25rpx auto;
|
||||
}
|
||||
|
||||
.grid {
|
||||
width: 700rpx;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 120rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
76
package/city/index.vue
Normal file
76
package/city/index.vue
Normal file
@@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<u-index-list :scrollTop="scrollTop">
|
||||
<view v-for="(item, index) in indexList" :key="index">
|
||||
<block v-for="(d,i) in cityList" :key="i" v-if="d.letter == item">
|
||||
<u-index-anchor :index="item" />
|
||||
<view class="list-cell" @click="selectCityId(d)">
|
||||
<text>{{ d.name }}</text>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</u-index-list>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as Api from '@/api/region.js'
|
||||
import storage from '@/utils/storage'
|
||||
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
scrollTop: 0,
|
||||
indexList: ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
|
||||
"T", "U",
|
||||
"V", "W", "X", "Y", "Z"
|
||||
],
|
||||
cityList: []
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.init()
|
||||
},
|
||||
onPageScroll(e) {
|
||||
this.scrollTop = e.scrollTop;
|
||||
},
|
||||
methods: {
|
||||
navTo(url) {
|
||||
this.$navTo(url)
|
||||
},
|
||||
init(){
|
||||
Api.list({status: 20}).then(res => {
|
||||
this.cityList = res.data.list
|
||||
console.log("res: ",res);
|
||||
})
|
||||
},
|
||||
selectCityId(city){
|
||||
storage.set('cityName', city.name)
|
||||
storage.set('cityId', city.id)
|
||||
uni.$emit('cityId', city.id)
|
||||
// 返回上级页面
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
},
|
||||
bindClick(e) {
|
||||
console.log('点击item,返回数据' + JSON.stringify(e))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.list-cell {
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
padding: 10px 24rpx;
|
||||
overflow: hidden;
|
||||
color: #323233;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
background-color: #fff;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
402
package/collection/components/goods.vue
Executable file
402
package/collection/components/goods.vue
Executable file
@@ -0,0 +1,402 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ use: false }" :up="upOption"
|
||||
:bottombar="false" @up="upCallback">
|
||||
<view class="cate-content">
|
||||
<!-- 商品列表 -->
|
||||
<view class="goods-list">
|
||||
<view class="goods-item--container" v-for="(item, index) in goodsList.data" :key="index">
|
||||
<view class="goods-item" @click="onTargetGoods(item.goods_id)">
|
||||
<!-- 商品图片 -->
|
||||
<view class="goods-item_left">
|
||||
<image class="image" :src="item.goods_image"></image>
|
||||
</view>
|
||||
<view class="goods-item_right">
|
||||
<!-- 商品标题 -->
|
||||
<view class="goods-name">
|
||||
<text class="twoline-hide">{{ item.goods_name }}</text>
|
||||
</view>
|
||||
<view class="item-prices oneline-hide">
|
||||
<text class="goods-sales">已售{{ item.goods_sales }}件</text>
|
||||
</view>
|
||||
<!-- 商品信息 -->
|
||||
<view class="goods-item_desc">
|
||||
<view class="desc_footer">
|
||||
<view class="item-prices oneline-hide">
|
||||
<text class="price_x">¥{{ item.goods_price_min }}</text>
|
||||
<!-- 商品销量 -->
|
||||
<text v-if="item.line_price_min > 0"
|
||||
class="price_y">¥{{ item.line_price_min }}</text>
|
||||
</view>
|
||||
<view class="buy-gouwuche">
|
||||
<u-button size="mini" @click="handleAddCart(item)">取消收藏
|
||||
</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 加入购物车组件 -->
|
||||
<AddCartPopup ref="AddCartPopup" @addCart="onUpdateCartTabBadge" />
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import {
|
||||
getEmptyPaginateObj,
|
||||
getMoreListData,
|
||||
setCartTabBadge
|
||||
} from '@/core/app'
|
||||
import {
|
||||
PageCategoryStyleEnum
|
||||
} from '@/common/enum/store/page/category'
|
||||
import Empty from '@/components/empty'
|
||||
import AddCartBtn from '@/components/add-cart-btn'
|
||||
import AddCartPopup from '@/components/add-cart-popup'
|
||||
import {
|
||||
rpx2px
|
||||
} from '@/utils/util'
|
||||
import * as GoodsApi from '@/api/goods'
|
||||
|
||||
const pageSize = 15
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody,
|
||||
Empty,
|
||||
AddCartBtn,
|
||||
AddCartPopup
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
props: {
|
||||
// 分类列表
|
||||
list: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
PageCategoryStyleEnum,
|
||||
// 列表高度
|
||||
scrollHeight: 0,
|
||||
// 一级分类:指针
|
||||
curIndex: -1,
|
||||
// 商品列表
|
||||
goodsList: getEmptyPaginateObj(),
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: {
|
||||
size: pageSize
|
||||
},
|
||||
// 数量要大于3条才显示无更多数据
|
||||
noMoreSize: 3,
|
||||
// 返回顶部
|
||||
toTop: {
|
||||
right: 30,
|
||||
bottom: 48,
|
||||
zIndex: 9
|
||||
}
|
||||
},
|
||||
|
||||
sortPrice: false, // 价格排序 (true高到低 false低到高)
|
||||
sortType: 'hot', // 排序类型
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 设置分类列表高度
|
||||
this.setListHeight()
|
||||
},
|
||||
methods: {
|
||||
|
||||
// 切换排序方式
|
||||
handleSortType(newSortType) {
|
||||
const app = this
|
||||
const newSortPrice = newSortType === 'price' ? !app.sortPrice : true
|
||||
app.sortType = newSortType
|
||||
app.sortPrice = newSortPrice
|
||||
// 刷新列表数据
|
||||
app.getGoodsList()
|
||||
},
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
console.log(page.num);
|
||||
app.getGoodsList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取商品列表
|
||||
* @param {Number} pageNo 页码
|
||||
*/
|
||||
getGoodsList(pageNo = 1) {
|
||||
const app = this
|
||||
const categoryId = app.curIndex > -1 ? app.list[app.curIndex].category_id : 0
|
||||
return new Promise((resolve, reject) => {
|
||||
GoodsApi.list({
|
||||
categoryId,
|
||||
page: pageNo,
|
||||
collection: true
|
||||
}, {
|
||||
load: false
|
||||
})
|
||||
.then(result => {
|
||||
const newList = result.data.list
|
||||
app.goodsList.data = getMoreListData(newList, app.goodsList, pageNo)
|
||||
app.goodsList.last_page = newList.last_page
|
||||
resolve(newList)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 设置列表内容的高度
|
||||
setListHeight() {
|
||||
const {
|
||||
windowHeight
|
||||
} = uni.getSystemInfoSync()
|
||||
this.scrollHeight = windowHeight - rpx2px(96)
|
||||
},
|
||||
|
||||
// 一级分类:选中分类
|
||||
handleSelectNav(index) {
|
||||
this.curIndex = index
|
||||
this.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新列表数据
|
||||
onRefreshList() {
|
||||
this.goodsList = getEmptyPaginateObj()
|
||||
setTimeout(() => this.mescroll.resetUpScroll(), 120)
|
||||
},
|
||||
|
||||
// 跳转至商品列表页
|
||||
onTargetGoods(goodsId) {
|
||||
this.$navTo('pages/goods/detail', {
|
||||
goodsId
|
||||
})
|
||||
},
|
||||
|
||||
// 点击加入购物车
|
||||
handleAddCart(item) {
|
||||
GoodsApi.collection({goodsId: item.})
|
||||
this.$emit('addCart')
|
||||
},
|
||||
|
||||
// 更新购物车角标
|
||||
onUpdateCartTabBadge() {
|
||||
console.log('onUpdateCartTabBadge')
|
||||
setCartTabBadge()
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
background-color: #F6F6F6 !important;
|
||||
}
|
||||
|
||||
// 分类内容
|
||||
.cate-content {
|
||||
z-index: 1;
|
||||
background-color: #F6F6F6 !important;
|
||||
padding-top: 0rpx;
|
||||
}
|
||||
|
||||
// 一级分类+二级分类 20
|
||||
.cate-left {
|
||||
width: 173rpx;
|
||||
height: 100%;
|
||||
background: #f8f8f8;
|
||||
color: #444;
|
||||
|
||||
position: fixed;
|
||||
top: calc(286rpx + var(--window-top));
|
||||
left: var(--window-left);
|
||||
bottom: var(--window-bottom);
|
||||
}
|
||||
|
||||
// 左侧一级分类
|
||||
.type-nav {
|
||||
position: relative;
|
||||
height: 90rpx;
|
||||
z-index: 10;
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&.selected {
|
||||
background: #fff;
|
||||
border-right: none;
|
||||
font-size: 28rpx;
|
||||
color: $main-bg
|
||||
}
|
||||
}
|
||||
|
||||
// 商品列表
|
||||
.goods-list {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.goods-item {
|
||||
padding: 28rpx 22rpx;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
padding: 20rpx;
|
||||
border: 1px solid #F6F6F6;
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.goods-item_left {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
margin-right: 20rpx;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 280rpx;
|
||||
height: 280rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_right {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
|
||||
.goods-name {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 68rpx;
|
||||
font-size: 34rpx;
|
||||
line-height: 1.3;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_desc {
|
||||
margin-top: 20rpx;
|
||||
|
||||
.people {
|
||||
margin-right: 14rpx;
|
||||
}
|
||||
|
||||
.desc_footer {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
position: absolute;
|
||||
right: 0rpx;
|
||||
bottom: 0rpx;
|
||||
min-height: 44rpx;
|
||||
|
||||
.item-prices {
|
||||
padding-right: 6rpx;
|
||||
|
||||
.price_x {
|
||||
margin-right: 14rpx;
|
||||
font-weight: 600;
|
||||
color: #ff0000;
|
||||
font-size: 38rpx;
|
||||
}
|
||||
|
||||
.price_y {
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.goods-sales {
|
||||
padding-top: 8rpx !important;
|
||||
color: #b3b3b3 !important;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
background: #fff;
|
||||
border-radius: 14rpx;
|
||||
padding: 20rpx 4rpx;
|
||||
box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.07);
|
||||
}
|
||||
|
||||
// 排序组件
|
||||
.store-sort {
|
||||
margin-top: 24rpx;
|
||||
position: sticky;
|
||||
top: var(--window-top);
|
||||
display: flex;
|
||||
padding: 20rpx 0;
|
||||
font-size: 28rpx;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
z-index: 99;
|
||||
|
||||
.sort-item {
|
||||
flex-basis: 33.3333%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 50rpx;
|
||||
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
}
|
||||
}
|
||||
|
||||
.sort-item-price .price-arrow {
|
||||
margin-left: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #000;
|
||||
|
||||
.icon {
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
}
|
||||
|
||||
&.up {
|
||||
margin-bottom: -16rpx;
|
||||
}
|
||||
|
||||
&.down {
|
||||
margin-top: -16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
394
package/collection/index.vue
Executable file
394
package/collection/index.vue
Executable file
@@ -0,0 +1,394 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ use: false }" :up="upOption"
|
||||
:bottombar="false" @up="upCallback">
|
||||
<view class="cate-content">
|
||||
<!-- 商品列表 -->
|
||||
<view class="goods-list">
|
||||
<view class="goods-item--container" v-for="(item, index) in goodsList.data" :key="index">
|
||||
<view class="goods-item" @click="onTargetGoods(item.goods_id)">
|
||||
<!-- 商品图片 -->
|
||||
<view class="goods-item_left">
|
||||
<image class="image" :src="item.goods_image"></image>
|
||||
</view>
|
||||
<view class="goods-item_right">
|
||||
<!-- 商品标题 -->
|
||||
<view class="goods-name">
|
||||
<text class="twoline-hide">{{ item.goods_name }}</text>
|
||||
</view>
|
||||
<view class="item-prices oneline-hide">
|
||||
<text class="goods-sales">已售{{ item.goods_sales }}件</text>
|
||||
</view>
|
||||
<!-- 商品信息 -->
|
||||
<view class="goods-item_desc">
|
||||
<view class="desc_footer">
|
||||
<view class="item-prices oneline-hide">
|
||||
<text class="price_x">¥{{ item.goods_price_min }}</text>
|
||||
<!-- 商品销量 -->
|
||||
<text v-if="item.line_price_min > 0"
|
||||
class="price_y">¥{{ item.line_price_min }}</text>
|
||||
</view>
|
||||
<view class="buy-gouwuche">
|
||||
<u-button size="mini" @click="handleAddCart(item)">取消收藏
|
||||
</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import {
|
||||
getEmptyPaginateObj,
|
||||
getMoreListData,
|
||||
setCartTabBadge
|
||||
} from '@/core/app'
|
||||
import {
|
||||
PageCategoryStyleEnum
|
||||
} from '@/common/enum/store/page/category'
|
||||
import Empty from '@/components/empty'
|
||||
import AddCartBtn from '@/components/add-cart-btn'
|
||||
import AddCartPopup from '@/components/add-cart-popup'
|
||||
import {
|
||||
rpx2px
|
||||
} from '@/utils/util'
|
||||
import * as GoodsApi from '@/api/goods'
|
||||
|
||||
const pageSize = 15
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody,
|
||||
Empty,
|
||||
AddCartBtn,
|
||||
AddCartPopup
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
PageCategoryStyleEnum,
|
||||
// 列表高度
|
||||
scrollHeight: 0,
|
||||
// 一级分类:指针
|
||||
curIndex: -1,
|
||||
// 商品列表
|
||||
goodsList: getEmptyPaginateObj(),
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: {
|
||||
size: pageSize
|
||||
},
|
||||
// 数量要大于3条才显示无更多数据
|
||||
noMoreSize: 3,
|
||||
// 返回顶部
|
||||
toTop: {
|
||||
right: 30,
|
||||
bottom: 48,
|
||||
zIndex: 9
|
||||
}
|
||||
},
|
||||
|
||||
sortPrice: false, // 价格排序 (true高到低 false低到高)
|
||||
sortType: 'hot', // 排序类型
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 设置分类列表高度
|
||||
this.setListHeight()
|
||||
},
|
||||
methods: {
|
||||
|
||||
// 切换排序方式
|
||||
handleSortType(newSortType) {
|
||||
const app = this
|
||||
const newSortPrice = newSortType === 'price' ? !app.sortPrice : true
|
||||
app.sortType = newSortType
|
||||
app.sortPrice = newSortPrice
|
||||
// 刷新列表数据
|
||||
app.getGoodsList()
|
||||
},
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
console.log(page.num);
|
||||
app.getGoodsList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取商品列表
|
||||
* @param {Number} pageNo 页码
|
||||
*/
|
||||
getGoodsList(pageNo = 1) {
|
||||
const app = this
|
||||
const categoryId = app.curIndex > -1 ? app.list[app.curIndex].category_id : 0
|
||||
return new Promise((resolve, reject) => {
|
||||
GoodsApi.list({
|
||||
categoryId,
|
||||
page: pageNo,
|
||||
collection: true
|
||||
}, {
|
||||
load: false
|
||||
})
|
||||
.then(result => {
|
||||
const newList = result.data.list
|
||||
app.goodsList.data = getMoreListData(newList, app.goodsList, pageNo)
|
||||
app.goodsList.last_page = newList.last_page
|
||||
resolve(newList)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 设置列表内容的高度
|
||||
setListHeight() {
|
||||
const {
|
||||
windowHeight
|
||||
} = uni.getSystemInfoSync()
|
||||
this.scrollHeight = windowHeight - rpx2px(96)
|
||||
},
|
||||
|
||||
// 一级分类:选中分类
|
||||
handleSelectNav(index) {
|
||||
this.curIndex = index
|
||||
this.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新列表数据
|
||||
onRefreshList() {
|
||||
this.goodsList = getEmptyPaginateObj()
|
||||
setTimeout(() => this.mescroll.resetUpScroll(), 120)
|
||||
},
|
||||
|
||||
// 跳转至商品列表页
|
||||
onTargetGoods(goodsId) {
|
||||
this.$navTo('pages/goods/detail', {
|
||||
goodsId
|
||||
})
|
||||
},
|
||||
|
||||
// 点击加入购物车
|
||||
handleAddCart(item) {
|
||||
GoodsApi.collection({goodsId: item.goods_id}).then(() => {
|
||||
this.getGoodsList()
|
||||
})
|
||||
},
|
||||
|
||||
// 更新购物车角标
|
||||
onUpdateCartTabBadge() {
|
||||
console.log('onUpdateCartTabBadge')
|
||||
setCartTabBadge()
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
background-color: #F6F6F6 !important;
|
||||
}
|
||||
|
||||
// 分类内容
|
||||
.cate-content {
|
||||
z-index: 1;
|
||||
background-color: #F6F6F6 !important;
|
||||
padding-top: 0rpx;
|
||||
}
|
||||
|
||||
// 一级分类+二级分类 20
|
||||
.cate-left {
|
||||
width: 173rpx;
|
||||
height: 100%;
|
||||
background: #f8f8f8;
|
||||
color: #444;
|
||||
|
||||
position: fixed;
|
||||
top: calc(286rpx + var(--window-top));
|
||||
left: var(--window-left);
|
||||
bottom: var(--window-bottom);
|
||||
}
|
||||
|
||||
// 左侧一级分类
|
||||
.type-nav {
|
||||
position: relative;
|
||||
height: 90rpx;
|
||||
z-index: 10;
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&.selected {
|
||||
background: #fff;
|
||||
border-right: none;
|
||||
font-size: 28rpx;
|
||||
color: $main-bg
|
||||
}
|
||||
}
|
||||
|
||||
// 商品列表
|
||||
.goods-list {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.goods-item {
|
||||
padding: 28rpx 22rpx;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
padding: 20rpx;
|
||||
border: 1px solid #F6F6F6;
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.goods-item_left {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
margin-right: 20rpx;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 280rpx;
|
||||
height: 280rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_right {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
|
||||
.goods-name {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 68rpx;
|
||||
font-size: 34rpx;
|
||||
line-height: 1.3;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_desc {
|
||||
margin-top: 20rpx;
|
||||
|
||||
.people {
|
||||
margin-right: 14rpx;
|
||||
}
|
||||
|
||||
.desc_footer {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
position: absolute;
|
||||
right: 0rpx;
|
||||
bottom: 0rpx;
|
||||
min-height: 44rpx;
|
||||
|
||||
.item-prices {
|
||||
padding-right: 6rpx;
|
||||
|
||||
.price_x {
|
||||
margin-right: 14rpx;
|
||||
font-weight: 600;
|
||||
color: #ff0000;
|
||||
font-size: 38rpx;
|
||||
}
|
||||
|
||||
.price_y {
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.goods-sales {
|
||||
padding-top: 8rpx !important;
|
||||
color: #b3b3b3 !important;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
background: #fff;
|
||||
border-radius: 14rpx;
|
||||
padding: 20rpx 4rpx;
|
||||
box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.07);
|
||||
}
|
||||
|
||||
// 排序组件
|
||||
.store-sort {
|
||||
margin-top: 24rpx;
|
||||
position: sticky;
|
||||
top: var(--window-top);
|
||||
display: flex;
|
||||
padding: 20rpx 0;
|
||||
font-size: 28rpx;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
z-index: 99;
|
||||
|
||||
.sort-item {
|
||||
flex-basis: 33.3333%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 50rpx;
|
||||
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
}
|
||||
}
|
||||
|
||||
.sort-item-price .price-arrow {
|
||||
margin-left: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #000;
|
||||
|
||||
.icon {
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
}
|
||||
|
||||
&.up {
|
||||
margin-bottom: -16rpx;
|
||||
}
|
||||
|
||||
&.down {
|
||||
margin-top: -16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
316
package/dealer/apply.vue
Executable file
316
package/dealer/apply.vue
Executable file
@@ -0,0 +1,316 @@
|
||||
<template>
|
||||
<view v-if="!isLoading" class="container b-f">
|
||||
|
||||
<!-- 头部背景图 -->
|
||||
<view class="dealer-bg">
|
||||
<image class="image" mode="widthFix" :src="background"></image>
|
||||
</view>
|
||||
|
||||
<!-- 等待审核 -->
|
||||
<view v-if="isApplying" class="dealer-boot dis-flex flex-dir-column flex-y-center">
|
||||
<view class="boot__msg f-30 dis-flex flex-dir-column flex-y-center">
|
||||
<text class="msg__icon iconfont icon-shenhezhong"></text>
|
||||
<text class="msg__content m-top20 f-29 col-80">{{ words.wait_audit.value }}</text>
|
||||
</view>
|
||||
<!-- 去商城逛逛 -->
|
||||
<view class="boot__submit form-submit dis-flex flex-x-center">
|
||||
<button class="button" @click="$navTo('pages/index/index')">{{ words.goto_mall.value }}</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 填写申请信息 -->
|
||||
<view v-else class="dis-flex flex-dir-column flex-y-center">
|
||||
<view class="widget-form b-f m-top20 dis-flex flex-dir-column">
|
||||
<view class="form-title f-30">{{ words.title.value }}</view>
|
||||
<view class="form-box dis-flex flex-dir-column">
|
||||
<form @submit="handleSubmit">
|
||||
<view class="form-field dis-flex flex-y-center">
|
||||
<view class="field-label">邀请人</view>
|
||||
<view class="field-input">
|
||||
<text>{{ refereeName }}(请核对)</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-field dis-flex flex-y-center">
|
||||
<view class="field-label">姓名</view>
|
||||
<view class="field-input flex-box">
|
||||
<input class="input" name="name" placeholder="请输入真实姓名"></input>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-field dis-flex flex-y-center">
|
||||
<view class="field-label">手机号</view>
|
||||
<view class="field-input flex-box">
|
||||
<input class="input" name="mobile" placeholder="请输入手机号"></input>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 申请协议 -->
|
||||
<view class="form-license dis-flex flex-x-center flex-y-center">
|
||||
<view class="license-radio dis-flex flex-y-center" @click="isRead = !isRead">
|
||||
<text class="license-icon f-38 iconfont icon-radio" :class="[isRead ? 'c-violet' : 'col-bb']"></text>
|
||||
<text class="f-28 col-80">我已阅读并了解</text>
|
||||
</view>
|
||||
<text @click="handleShowLicense()" class="f-28 c-violet">【{{ words.license.value }}】</text>
|
||||
</view>
|
||||
<!-- 立即申请 -->
|
||||
<view class="form-submit dis-flex flex-x-center">
|
||||
<button formType="submit" :disabled="disabled">{{ words.submit.value }}</button>
|
||||
</view>
|
||||
</form>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 入驻协议弹窗 -->
|
||||
<u-modal v-model="showLicense" title="申请协议">
|
||||
<scroll-view class="pops-content" :scroll-y="true">
|
||||
<text>{{ license }}</text>
|
||||
</scroll-view>
|
||||
</u-modal>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as ApplyApi from '@/api/dealer/apply'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 正在加载
|
||||
isLoading: true,
|
||||
// 当前是否为分销商
|
||||
isDealer: undefined,
|
||||
// 当前是否在申请中
|
||||
isApplying: undefined,
|
||||
// 推荐人昵称
|
||||
refereeName: undefined,
|
||||
// 文字设置
|
||||
words: undefined,
|
||||
// 背景图
|
||||
background: undefined,
|
||||
// 入驻协议
|
||||
license: undefined,
|
||||
// 入驻协议阅读状态
|
||||
isRead: false,
|
||||
// 显示入驻协议弹窗
|
||||
showLicense: false,
|
||||
// 按钮禁用
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
this.getSetting()
|
||||
this.getApplyStatus()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取分销设置
|
||||
getSetting() {
|
||||
const app = this
|
||||
SettingModel.data()
|
||||
.then(setting => {
|
||||
// 赋值属性
|
||||
app.words = setting.words.apply.words
|
||||
app.background = setting.background.apply
|
||||
app.license = setting.license.license
|
||||
// 设置当前页面标题
|
||||
app.setPageTitle(setting.words.apply.title)
|
||||
})
|
||||
},
|
||||
|
||||
// 分销商申请状态
|
||||
getApplyStatus() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
ApplyApi.status()
|
||||
.then(result => {
|
||||
const data = result.data
|
||||
app.isDealer = data.isDealer
|
||||
app.isApplying = data.isApplying
|
||||
app.refereeName = data.refereeName
|
||||
})
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 设置当前页面标题
|
||||
setPageTitle(title) {
|
||||
uni.setNavigationBarTitle({ title: title.value })
|
||||
},
|
||||
|
||||
// 切换支付选项
|
||||
handleChecked(value) {
|
||||
this.payment = value
|
||||
},
|
||||
|
||||
// 显示入驻协议弹窗
|
||||
handleShowLicense() {
|
||||
this.showLicense = true
|
||||
},
|
||||
|
||||
// 表单提交
|
||||
handleSubmit({ detail }) {
|
||||
const app = this
|
||||
// 表单验证
|
||||
if (!app.onValidation(detail.value)) {
|
||||
return false
|
||||
}
|
||||
// 确认提交
|
||||
app.disabled = true
|
||||
ApplyApi.submit({ form: detail.value })
|
||||
.then(result => {
|
||||
app.$toast(result.message)
|
||||
setTimeout(() => uni.navigateBack(), 1200)
|
||||
})
|
||||
.finally(() => app.disabled = false)
|
||||
},
|
||||
|
||||
// 表单验证
|
||||
onValidation(data) {
|
||||
const app = this
|
||||
// 验证可提现佣金
|
||||
if (!data.name) {
|
||||
app.$error('请填写姓名')
|
||||
return false
|
||||
}
|
||||
// 验证手机号
|
||||
if (!/^\+?\d[\d -]{8,12}\d/.test(data.mobile)) {
|
||||
app.$error('手机号格式不正确')
|
||||
return false
|
||||
}
|
||||
// 验证是否阅读协议
|
||||
if (!app.isRead) {
|
||||
app.$error('请先阅读分销商申请协议')
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.c-violet {
|
||||
color: #786cff;
|
||||
}
|
||||
|
||||
.col-80 {
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
.col-bb {
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.f-38 {
|
||||
font-size: 38rpx;
|
||||
}
|
||||
|
||||
.dealer-bg {
|
||||
.image {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.widget-form {
|
||||
position: relative;
|
||||
width: 700rpx;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 1rpx 20rpx rgba(0, 0, 0, 0.21);
|
||||
border-radius: 12rpx;
|
||||
margin-top: -80rpx;
|
||||
|
||||
.form-title {
|
||||
padding: 0 40rpx;
|
||||
height: 90rpx;
|
||||
border-bottom: 1rpx solid #e7e7e7;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.form-box {
|
||||
padding: 40rpx 35rpx;
|
||||
|
||||
.form-field {
|
||||
height: 80rpx;
|
||||
margin-bottom: 24rpx;
|
||||
padding: 10rpx 28rpx;
|
||||
background-color: #f9f9f9;
|
||||
box-sizing: border-box;
|
||||
font-size: 28rpx;
|
||||
|
||||
.field-label {
|
||||
width: 130rpx;
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
.input {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-license {
|
||||
.license-icon {
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.form-submit {
|
||||
margin-top: 40rpx;
|
||||
|
||||
button {
|
||||
font-size: 30rpx;
|
||||
background: #786cff;
|
||||
border: 1rpx solid #786cff;
|
||||
color: white;
|
||||
border-radius: 50rpx;
|
||||
padding: 0 120rpx;
|
||||
|
||||
&[disabled] {
|
||||
background: #8e84fc;
|
||||
border-color: #8e84fc;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 申请协议
|
||||
.pops-content {
|
||||
padding: 30rpx 48rpx;
|
||||
font-size: 28rpx;
|
||||
line-height: 50rpx;
|
||||
text-align: left;
|
||||
color: #606266;
|
||||
min-height: 320rpx;
|
||||
max-height: 640rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// 等待审核
|
||||
.dealer-boot {
|
||||
padding: 10rpx 30rpx;
|
||||
margin-top: 80rpx;
|
||||
|
||||
.msg__icon {
|
||||
font-size: 120rpx;
|
||||
color: #8e84fc;
|
||||
}
|
||||
|
||||
.boot__submit {
|
||||
margin-top: 60rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
237
package/dealer/driver.vue
Executable file
237
package/dealer/driver.vue
Executable file
@@ -0,0 +1,237 @@
|
||||
<template>
|
||||
<view class="container" v-if="!isLoading">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ use: false }" :up="upOption"
|
||||
@up="upCallback">
|
||||
|
||||
<!-- 团队总人数 -->
|
||||
<view class="widget-people f-28 col-9">
|
||||
<text>司机列表({{total}})</text>
|
||||
<u-button type="primary" size="mini">添加</u-button>
|
||||
</view>
|
||||
|
||||
<!-- 列表数据 -->
|
||||
<view class="widget-list b-f">
|
||||
<view class="widget__detail dis-flex flex-x-between" v-for="(item, index) in list" :key="index">
|
||||
<view class="detail__left dis-flex flex-y-center">
|
||||
<avatar-image class="user-avatar" :url="item.user.avatar_url" :width="100" :borderWidth="4"
|
||||
:borderColor="`#fff`" />
|
||||
<view class="user-info dis-flex flex-dir-column flex-x-center">
|
||||
<view class="user-nickName f-28">{{ item.real_name }}</view>
|
||||
<view class="user-time col-9 f-24">{{ item.mobile }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="detail__right dis-flex flex-dir-column flex-x-center flex-y-center">
|
||||
<view class="detail__money">
|
||||
</view>
|
||||
<view class="detail__member f-22">
|
||||
派单
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import AvatarImage from '@/components/avatar-image'
|
||||
import { getEmptyPaginateObj, getMoreListData } from '@/core/app'
|
||||
import * as Api from '@/api/shop/clerk'
|
||||
import * as DealerApi from '@/api/dealer'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
|
||||
const pageSize = 15
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody,
|
||||
AvatarImage
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
data() {
|
||||
return {
|
||||
// 选项卡列表
|
||||
tabList: [],
|
||||
// 当前选项
|
||||
curTab: 0,
|
||||
// 列表数据
|
||||
list: getEmptyPaginateObj(),
|
||||
total: 0,
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: { size: pageSize },
|
||||
// 数量要大于12条才显示无更多数据
|
||||
noMoreSize: 12,
|
||||
// 空布局
|
||||
empty: {
|
||||
tip: '亲,暂无相关数据'
|
||||
}
|
||||
},
|
||||
// 正在加载
|
||||
isLoading: true,
|
||||
// 文字设置
|
||||
words: undefined,
|
||||
// 团队总人数
|
||||
teamTotal: undefined,
|
||||
orderId: 0
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
const app = this
|
||||
console.log(options.orderId);
|
||||
app.orderId = options.orderId
|
||||
app.isLoading = true
|
||||
Promise.all([app.getSetting(), app.getDealerUser()])
|
||||
.then(result => {
|
||||
const setting = result[0]
|
||||
const dealer = result[1]
|
||||
// app.setTabList(setting, dealer)
|
||||
})
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取分销设置
|
||||
getSetting() {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
SettingModel.data()
|
||||
.then(setting => {
|
||||
app.words = setting.words.team.words
|
||||
resolve(setting)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取分销用户信息
|
||||
getDealerUser() {
|
||||
const app = this
|
||||
const { shopId } = uni.getStorageSync('shopInfo')
|
||||
Api.list({shopId}).then((result) => {
|
||||
app.list = result.data.list
|
||||
app.total = result.data.total
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
app.getList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
// 获取提现列表
|
||||
getList(pageNo = 1) {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
Api.list({ level: app.getTabValue(), page: pageNo })
|
||||
.then(result => {
|
||||
// 合并新数据
|
||||
const newList = result.data.list
|
||||
app.list.data = getMoreListData(newList, app.list, pageNo)
|
||||
resolve(newList)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 获取当前标签项的值
|
||||
getTabValue() {
|
||||
const app = this
|
||||
if (app.tabList.length) {
|
||||
return app.tabList[app.curTab].value
|
||||
}
|
||||
return 1
|
||||
},
|
||||
|
||||
// 切换标签项
|
||||
onChangeTab(index) {
|
||||
const app = this
|
||||
// 设置当前选中的标签
|
||||
app.curTab = index
|
||||
// 刷新订单列表
|
||||
app.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新列表数据
|
||||
onRefreshList() {
|
||||
this.list = getEmptyPaginateObj()
|
||||
setTimeout(() => {
|
||||
this.mescroll.resetUpScroll()
|
||||
}, 120)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
// 团队人数
|
||||
.widget-people {
|
||||
padding: 0 25rpx;
|
||||
height: 80rpx;
|
||||
line-height: 60rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: #f7f7f7;
|
||||
}
|
||||
|
||||
// 列表内容
|
||||
.widget-list {
|
||||
padding: 10rpx 20rpx 40rpx 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.widget__detail {
|
||||
padding: 20rpx 15rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 28rpx;
|
||||
border-bottom: 1rpx solid #e7e7e7;
|
||||
|
||||
.user-avatar {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.user-nickName {
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.detail__member {
|
||||
background-color: #786cff;
|
||||
color: #fff;
|
||||
padding: 2rpx 15rpx;
|
||||
border-radius: 6rpx;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
321
package/dealer/index.vue
Executable file
321
package/dealer/index.vue
Executable file
@@ -0,0 +1,321 @@
|
||||
<template>
|
||||
<view v-if="!isLoading" class="container b-f">
|
||||
|
||||
<!-- 分销商中心 -->
|
||||
<view class="center" v-if="isDealer">
|
||||
|
||||
<!-- 头部背景图 -->
|
||||
<view class="dealer-bg">
|
||||
<image class="image" mode="widthFix" :src="setting.background"></image>
|
||||
</view>
|
||||
|
||||
<!-- 内容区 -->
|
||||
<view class="widget-body b-f dis-flex flex-dir-column flex-y-center">
|
||||
<!-- 用户信息 -->
|
||||
<view class="widget widget__base m-top20 b-f dis-flex flex-dir-column">
|
||||
<view class="base__user f-30">
|
||||
<!-- 用户头像 -->
|
||||
<avatar-image class="user-avatar" :url="shopInfo.logoUrl" :width="150" :borderWidth="4"
|
||||
:borderColor="`#fff`" />
|
||||
<view class="user-nickName f-32">{{ shopInfo.shopName }}</view>
|
||||
<!-- <view class="user-referee f-24 col-9">
|
||||
{{ setting.words.index.words.referee.value }}:{{ refereeName }}
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="base__capital dis-flex flex-dir-column">
|
||||
<!-- 佣金卡片 -->
|
||||
<view class="capital-card dis-flex">
|
||||
<view class="card-left">
|
||||
<view class="f-28 col-f">
|
||||
<text space="ensp">{{ setting.words.index.words.money.value }} {{ dealer.money }}</text>
|
||||
<text class="m-l-10">元</text>
|
||||
</view>
|
||||
<view class="f-28 col-f">
|
||||
<text space="ensp">{{ setting.words.index.words.freeze_money.value }} {{ dealer.freeze_money }}</text>
|
||||
<text class="m-l-10">元</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="card-right flex-box dis-flex flex-x-end flex-y-center">
|
||||
<view class="withdraw-btn f-26" @click="$navTo('pages/dealer/withdraw/apply')">
|
||||
{{ setting.words.index.words.withdraw.value }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 已提现金额 -->
|
||||
<view class="capital-already clear">
|
||||
<view class="already-left f-26 fl">{{ setting.words.index.words.total_money.value }}</view>
|
||||
<view class="already-right f-26 fr">{{ dealer.total_money }}元</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 操作列表 -->
|
||||
<view class="widget widget__operat clear b-f">
|
||||
<view class="operat__item" @click="$navTo('pages/dealer/withdraw/list')">
|
||||
<view class="item__icon">
|
||||
<text class="iconfont icon-zhangben" style="color:#F9BA21;"></text>
|
||||
</view>
|
||||
<view class="item__text f-26">{{ setting.words.withdraw_list.title.value }}</view>
|
||||
</view>
|
||||
<view class="operat__item" @click="$navTo('pages/dealer/order')">
|
||||
<view class="item__icon">
|
||||
<text class="iconfont icon-dingdan" style="color:#FF7575;"></text>
|
||||
</view>
|
||||
<view class="item__text f-26">{{ setting.words.order.title.value }}</view>
|
||||
</view>
|
||||
<!-- <view class="operat__item" @click="$navTo('pages/dealer/team')">
|
||||
<view class="item__icon">
|
||||
<text class="iconfont icon-tuandui" style="color:#59C78E;"></text>
|
||||
</view>
|
||||
<view class="item__text f-26">{{ setting.words.team.title.value }}</view>
|
||||
</view> -->
|
||||
<view class="operat__item" @click="$navTo('pages/dealer/poster')">
|
||||
<view class="item__icon">
|
||||
<text class="iconfont icon-erweima" style="color:#5fa5ff;"></text>
|
||||
</view>
|
||||
<view class="item__text f-26">{{ setting.words.poster.title.value }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 当前不是分销商 -->
|
||||
<view class="container b-f" v-if="!isDealer">
|
||||
<view class="no-dealer">
|
||||
<view class="no-icon dis-flex flex-x-center">
|
||||
<image src="/static/not-dealer.png"></image>
|
||||
</view>
|
||||
<view class="no-msg dis-flex flex-x-center f-30">{{ setting.words.index.words.not_dealer.value }}
|
||||
</view>
|
||||
<!-- 立即申请 -->
|
||||
<view class="no-submit form-submit">
|
||||
<view class="button" @click="$navTo('pages/dealer/apply')">{{ setting.words.index.words.apply_now.value }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AvatarImage from '@/components/avatar-image'
|
||||
import * as Api from '@/api/dealer'
|
||||
import * as UserApi from '@/api/user'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AvatarImage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 正在加载
|
||||
isLoading: true,
|
||||
// 当前商户信息
|
||||
shopInfo: {},
|
||||
// 当前是否为分销商
|
||||
isDealer: false,
|
||||
// 当前分销商信息
|
||||
dealer: undefined,
|
||||
// 推荐人昵称
|
||||
refereeName: undefined,
|
||||
// 分销设置
|
||||
setting: {
|
||||
background: undefined,
|
||||
words: undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onShow(options) {
|
||||
this.getCenter()
|
||||
this.getUserInfo()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取当前用户信息
|
||||
getUserInfo() {
|
||||
const app = this
|
||||
UserApi.info().then(result => {
|
||||
app.shopInfo = result.data.shopInfo
|
||||
})
|
||||
},
|
||||
|
||||
// 获取分销商中心数据
|
||||
getCenter() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
Api.center()
|
||||
.then(result => {
|
||||
// api数据赋值
|
||||
const data = result.data
|
||||
app.isDealer = data.isDealer
|
||||
app.user = data.user
|
||||
app.dealer = data.dealer
|
||||
app.refereeName = data.refereeName
|
||||
app.setting = data.setting
|
||||
// 设置当前页面标题
|
||||
app.setPageTitle()
|
||||
app.isLoading = false
|
||||
})
|
||||
},
|
||||
|
||||
// 设置当前页面标题
|
||||
setPageTitle() {
|
||||
uni.setNavigationBarTitle({
|
||||
// title: this.setting.words.index.title.value,
|
||||
title: '我的商户'
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.dealer-bg {
|
||||
.image {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.widget-body {
|
||||
position: relative;
|
||||
|
||||
.widget {
|
||||
width: 88%;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.11);
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.widget__base {
|
||||
margin-top: -60rpx;
|
||||
|
||||
.base__user {
|
||||
position: relative;
|
||||
padding: 15rpx 40rpx;
|
||||
border-bottom: 1rpx solid #e7e7e7;
|
||||
|
||||
.user-avatar {
|
||||
position: absolute;
|
||||
top: -75rpx;
|
||||
right: 60rpx;
|
||||
}
|
||||
|
||||
.user-nickName {
|
||||
margin-top: 30rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.base__capital {
|
||||
padding: 35rpx;
|
||||
|
||||
.capital-card {
|
||||
height: 200rpx;
|
||||
padding: 36rpx 0;
|
||||
background-color: #8e84fc;
|
||||
border-radius: 10rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.card-left {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
padding-left: 32rpx;
|
||||
}
|
||||
|
||||
.card-right {
|
||||
.withdraw-btn {
|
||||
width: 130rpx;
|
||||
height: 50rpx;
|
||||
background: #fff;
|
||||
color: #8e84fc;
|
||||
border-radius: 24rpx;
|
||||
margin-right: 32rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.capital-already {
|
||||
padding: 20rpx;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 操作列表 */
|
||||
.widget__operat {
|
||||
padding: 50rpx;
|
||||
margin-top: 40rpx;
|
||||
|
||||
.operat__item {
|
||||
width: 33.33333%;
|
||||
float: left;
|
||||
margin-bottom: 50rpx;
|
||||
text-align: center;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.item__icon {
|
||||
margin-bottom: 8rpx;
|
||||
font-size: 58rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 当前不是分销商 */
|
||||
.no-dealer {
|
||||
padding-top: 150rpx;
|
||||
}
|
||||
|
||||
.no-icon {
|
||||
image {
|
||||
width: 420rpx;
|
||||
height: 240rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.no-msg {
|
||||
padding: 86rpx 0;
|
||||
}
|
||||
|
||||
.form-submit {
|
||||
.button {
|
||||
font-size: 30rpx;
|
||||
background: #786cff;
|
||||
border: 1rpx solid #786cff;
|
||||
color: white;
|
||||
border-radius: 50rpx;
|
||||
padding: 22rpx 0;
|
||||
width: 470rpx;
|
||||
box-sizing: border-box;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
223
package/dealer/order.vue
Executable file
223
package/dealer/order.vue
Executable file
@@ -0,0 +1,223 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ use: false }" :up="upOption"
|
||||
@up="upCallback">
|
||||
|
||||
<!-- tab栏 -->
|
||||
<u-tabs :list="tabList" :is-scroll="false" :current="curTab" active-color="#786cff" :duration="0.2"
|
||||
@change="onChangeTab" />
|
||||
|
||||
<!-- 列表数据 -->
|
||||
<view class="widget-list b-f">
|
||||
<view class="widget__detail" v-for="(item, index) in list.data" :key="index">
|
||||
<view class="detail__row dis-flex flex-x-between">
|
||||
<view class="detail__left f-24">订单号:{{ item.order.order_no }}</view>
|
||||
<view class="detail__right f-24 c-violet">
|
||||
{{ item.order.state_text }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="detail__row m-top10 dis-flex flex-x-between">
|
||||
<view class="detail__left dis-flex flex-y-center">
|
||||
<avatar-image class="user-avatar" :url="item.user.avatar_url" :width="100" :borderWidth="4"
|
||||
:borderColor="`#fff`" />
|
||||
<view class="user-info dis-flex flex-dir-column flex-x-center">
|
||||
<view class="user-nickName f-28">{{ item.user.nick_name }}</view>
|
||||
<view class="user-time f-24 c-80">消费金额:¥{{ item.order_price }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="detail__right dis-flex flex-dir-column flex-x-center flex-y-center">
|
||||
<view class="detail__money t-r col-m">
|
||||
<text class="f-26">+ </text>
|
||||
<text class="f-28">{{ item.my_money }}</text>
|
||||
</view>
|
||||
<view class="detail__time f-22 c-80">{{ item.create_time }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import AvatarImage from '@/components/avatar-image'
|
||||
import { getEmptyPaginateObj, getMoreListData } from '@/core/app'
|
||||
import * as Api from '@/api/dealer/order'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
|
||||
const pageSize = 15
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody,
|
||||
AvatarImage
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
data() {
|
||||
return {
|
||||
// 选项卡列表
|
||||
tabList: [],
|
||||
// 当前选项
|
||||
curTab: 0,
|
||||
// 列表数据
|
||||
list: getEmptyPaginateObj(),
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: { size: pageSize },
|
||||
// 数量要大于12条才显示无更多数据
|
||||
noMoreSize: 12,
|
||||
// 空布局
|
||||
empty: {
|
||||
tip: '亲,暂无相关数据'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
this.getSetting()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取分销设置
|
||||
getSetting() {
|
||||
const app = this
|
||||
SettingModel.data()
|
||||
.then(setting => {
|
||||
const words = setting.words.order
|
||||
app.setPageTitle(words.title)
|
||||
app.setTabList(words.words)
|
||||
})
|
||||
},
|
||||
|
||||
// 设置页面标题
|
||||
setPageTitle(title) {
|
||||
uni.setNavigationBarTitle({
|
||||
title: title.value
|
||||
})
|
||||
},
|
||||
|
||||
// 设置选项卡数据
|
||||
setTabList(words) {
|
||||
const app = this
|
||||
app.tabList = [
|
||||
{ value: -1, name: words.all.value },
|
||||
{ value: 0, name: words.unsettled.value },
|
||||
{ value: 1, name: words.settled.value }
|
||||
]
|
||||
},
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
app.getList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
// 获取提现列表
|
||||
getList(pageNo = 1) {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
Api.list({ settled: app.getTabValue(), page: pageNo })
|
||||
.then(result => {
|
||||
// 合并新数据
|
||||
const newList = result.data.list
|
||||
app.list.data = getMoreListData(newList, app.list, pageNo)
|
||||
resolve(newList)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 获取当前标签项的值
|
||||
getTabValue() {
|
||||
const app = this
|
||||
if (app.tabList.length) {
|
||||
return app.tabList[app.curTab].value
|
||||
}
|
||||
return -1
|
||||
},
|
||||
|
||||
// 切换标签项
|
||||
onChangeTab(index) {
|
||||
const app = this
|
||||
// 设置当前选中的标签
|
||||
app.curTab = index
|
||||
// 刷新订单列表
|
||||
app.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新列表数据
|
||||
onRefreshList() {
|
||||
this.list = getEmptyPaginateObj()
|
||||
setTimeout(() => {
|
||||
this.mescroll.resetUpScroll()
|
||||
}, 120)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.c-violet {
|
||||
color: #786cff;
|
||||
}
|
||||
|
||||
.c-80 {
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
// 订单列表
|
||||
.widget-list {
|
||||
padding: 10rpx 20rpx 40rpx 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.widget__detail {
|
||||
padding: 20rpx 15rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 28rpx;
|
||||
border-bottom: 1rpx solid #e7e7e7;
|
||||
|
||||
.user-avatar {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
height: 100%;
|
||||
|
||||
.user-nickName {
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.detail__money {
|
||||
width: 100%;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
80
package/dealer/poster.vue
Executable file
80
package/dealer/poster.vue
Executable file
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view v-if="imageUrl" class="poster">
|
||||
<image class="image" mode="widthFix" :src="imageUrl" @click="onPreviewImage"></image>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as Api from '@/api/dealer/poster'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 海报图url
|
||||
imageUrl: undefined
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
this.getSetting()
|
||||
this.getPoster()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取分销设置
|
||||
getSetting() {
|
||||
const app = this
|
||||
SettingModel.data()
|
||||
.then(setting => {
|
||||
const words = setting.words.poster
|
||||
app.setPageTitle(words.title)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取推广二维码
|
||||
getPoster() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
Api.qrcode({ channel: app.platform })
|
||||
.then(result => {
|
||||
// api数据赋值
|
||||
app.imageUrl = result.data.imageUrl
|
||||
})
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 设置当前页面标题
|
||||
setPageTitle(title) {
|
||||
uni.setNavigationBarTitle({ title: title.value })
|
||||
},
|
||||
|
||||
// 预览海报图
|
||||
onPreviewImage() {
|
||||
uni.previewImage({
|
||||
current: this.imageUrl,
|
||||
urls: [this.imageUrl]
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.poster .image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
236
package/dealer/team.vue
Executable file
236
package/dealer/team.vue
Executable file
@@ -0,0 +1,236 @@
|
||||
<template>
|
||||
<view class="container" v-if="!isLoading">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ use: false }" :up="upOption"
|
||||
@up="upCallback">
|
||||
|
||||
<!-- 团队总人数 -->
|
||||
<view class="widget-people f-28 col-9">
|
||||
<text>司机列表({{total}})</text>
|
||||
<!-- <u-button type="primary" size="mini">添加</u-button> -->
|
||||
</view>
|
||||
|
||||
<!-- 列表数据 -->
|
||||
<view class="widget-list b-f">
|
||||
<view class="widget__detail dis-flex flex-x-between" v-for="(item, index) in list" :key="index">
|
||||
<view class="detail__left dis-flex flex-y-center">
|
||||
<avatar-image class="user-avatar" :url="item.user.avatar_url" :width="100" :borderWidth="4"
|
||||
:borderColor="`#fff`" />
|
||||
<view class="user-info dis-flex flex-dir-column flex-x-center">
|
||||
<view class="user-nickName f-28">{{ item.real_name }}</view>
|
||||
<view class="user-time col-9 f-24">{{ item.mobile }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="detail__right dis-flex flex-dir-column flex-x-center flex-y-center">
|
||||
<view class="detail__money">
|
||||
<text class="f-24">¥</text>
|
||||
<text class="f-34">{{ item.user.expend_money }}</text>
|
||||
</view>
|
||||
<view class="detail__member f-22" v-if="item.subDealer">
|
||||
{{ item.subDealer.first_num + item.subDealer.second_num + item.subDealer.third_num }}个成员
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import AvatarImage from '@/components/avatar-image'
|
||||
import { getEmptyPaginateObj, getMoreListData } from '@/core/app'
|
||||
import * as Api from '@/api/shop/clerk'
|
||||
import * as DealerApi from '@/api/dealer'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
|
||||
const pageSize = 15
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody,
|
||||
AvatarImage
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
data() {
|
||||
return {
|
||||
// 选项卡列表
|
||||
tabList: [],
|
||||
// 当前选项
|
||||
curTab: 0,
|
||||
// 列表数据
|
||||
list: getEmptyPaginateObj(),
|
||||
total: 0,
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: { size: pageSize },
|
||||
// 数量要大于12条才显示无更多数据
|
||||
noMoreSize: 12,
|
||||
// 空布局
|
||||
empty: {
|
||||
tip: '亲,暂无相关数据'
|
||||
}
|
||||
},
|
||||
// 正在加载
|
||||
isLoading: true,
|
||||
// 文字设置
|
||||
words: undefined,
|
||||
// 团队总人数
|
||||
teamTotal: undefined
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
Promise.all([app.getSetting(), app.getDealerUser()])
|
||||
.then(result => {
|
||||
const setting = result[0]
|
||||
const dealer = result[1]
|
||||
// app.setTabList(setting, dealer)
|
||||
})
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取分销设置
|
||||
getSetting() {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
SettingModel.data()
|
||||
.then(setting => {
|
||||
app.words = setting.words.team.words
|
||||
resolve(setting)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取分销用户信息
|
||||
getDealerUser() {
|
||||
const app = this
|
||||
const { shopId } = uni.getStorageSync('shopInfo')
|
||||
Api.list({shopId}).then((result) => {
|
||||
app.list = result.data.list
|
||||
app.total = result.data.total
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
app.getList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
// 获取提现列表
|
||||
getList(pageNo = 1) {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
Api.list({ level: app.getTabValue(), page: pageNo })
|
||||
.then(result => {
|
||||
// 合并新数据
|
||||
const newList = result.data.list
|
||||
app.list.data = getMoreListData(newList, app.list, pageNo)
|
||||
resolve(newList)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 获取当前标签项的值
|
||||
getTabValue() {
|
||||
const app = this
|
||||
if (app.tabList.length) {
|
||||
return app.tabList[app.curTab].value
|
||||
}
|
||||
return 1
|
||||
},
|
||||
|
||||
// 切换标签项
|
||||
onChangeTab(index) {
|
||||
const app = this
|
||||
// 设置当前选中的标签
|
||||
app.curTab = index
|
||||
// 刷新订单列表
|
||||
app.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新列表数据
|
||||
onRefreshList() {
|
||||
this.list = getEmptyPaginateObj()
|
||||
setTimeout(() => {
|
||||
this.mescroll.resetUpScroll()
|
||||
}, 120)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
// 团队人数
|
||||
.widget-people {
|
||||
padding: 0 25rpx;
|
||||
height: 80rpx;
|
||||
line-height: 60rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: #f7f7f7;
|
||||
}
|
||||
|
||||
// 列表内容
|
||||
.widget-list {
|
||||
padding: 10rpx 20rpx 40rpx 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.widget__detail {
|
||||
padding: 20rpx 15rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 28rpx;
|
||||
border-bottom: 1rpx solid #e7e7e7;
|
||||
|
||||
.user-avatar {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.user-nickName {
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.detail__member {
|
||||
background-color: #786cff;
|
||||
color: #fff;
|
||||
padding: 2rpx 15rpx;
|
||||
border-radius: 6rpx;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
398
package/dealer/withdraw/apply.vue
Executable file
398
package/dealer/withdraw/apply.vue
Executable file
@@ -0,0 +1,398 @@
|
||||
<template>
|
||||
<view v-if="!isLoading" class="container b-f">
|
||||
|
||||
<!-- 头部背景图 -->
|
||||
<view class="dealer-bg">
|
||||
<image class="image" mode="widthFix" :src="background"></image>
|
||||
</view>
|
||||
|
||||
<view class="widget-body">
|
||||
<form @submit="handleSubmit">
|
||||
<!-- 提现佣金 -->
|
||||
<view class="widget widget__capital m-top20 b-f dis-flex flex-dir-column">
|
||||
<view class="capital__item dis-flex flex-x-between flex-y-center">
|
||||
<view class="item__left">{{ words.capital.value }}:</view>
|
||||
<view class="item__right c-violet">
|
||||
<text class="f-24">¥</text>
|
||||
<text class="f-34">{{ shopInfo.money }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="capital__item dis-flex flex-y-center">
|
||||
<view class="item__left">{{ words.money.value }}:</view>
|
||||
<view class="item__right flex-box">
|
||||
<input class="input" name="money" :placeholder="words.money_placeholder.value"></input>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 最低提现金额 -->
|
||||
<!-- <view class="capital__lowest m-top20 col-7 t-r">
|
||||
{{ words.min_money.value }}{{ settlement.min_money }}元
|
||||
</view> -->
|
||||
<view class="capital__lowest m-top20 col-7 t-r">
|
||||
<u-button size="mini" @click="navTo('package/dealer/withdraw/list')">查看明细</u-button>
|
||||
<text>提现手续费3%</text>
|
||||
</view>
|
||||
|
||||
<!-- 提现方式 -->
|
||||
<view class="widget widget__form m-top20 b-f dis-flex flex-dir-column">
|
||||
<view class="form__title f-28">提现方式</view>
|
||||
<view class="form__box">
|
||||
<block v-for="(item, index) in settlement.pay_type" :key="index">
|
||||
<block v-if="item == PayTypeEnum.WECHAT.value">
|
||||
<!-- 微信支付 -->
|
||||
<!-- <view class="form__field dis-flex flex-y-center">
|
||||
<view class="form__radio dis-flex flex-y-center"
|
||||
@click="handleChecked(PayTypeEnum.WECHAT.value)">
|
||||
<text class="radio__icon iconfont icon-radio"
|
||||
:class="[payment == PayTypeEnum.WECHAT.value ? 'c-violet' : 'col-bb']"></text>
|
||||
<text class="f-28">{{ PayTypeEnum.WECHAT.name }}</text>
|
||||
</view>
|
||||
</view> -->
|
||||
</block>
|
||||
<block v-if="item == PayTypeEnum.ALIPAY.value">
|
||||
<!-- 支付宝 -->
|
||||
<view class="form__field dis-flex flex-y-center">
|
||||
<view class="form__radio dis-flex flex-y-center"
|
||||
@click="handleChecked(PayTypeEnum.ALIPAY.value)">
|
||||
<text class="radio__icon iconfont icon-radio"
|
||||
:class="[payment == PayTypeEnum.ALIPAY.value ? 'c-violet' : 'col-bb']"></text>
|
||||
<text class="f-28">{{ PayTypeEnum.ALIPAY.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<block v-if="payment == PayTypeEnum.ALIPAY.value">
|
||||
<u-alert-tips v-if="!shopInfo.alipayAccount" type="warning" :title="title"
|
||||
:description="'首次提现将会保存,请填写正确的支付宝账号!'"></u-alert-tips>
|
||||
<view class="form__field dis-flex flex-y-center">
|
||||
<view class="field-input flex-box">
|
||||
<input class="input" name="alipay_name" :value="shopInfo.alipayName"
|
||||
:disabled="shopInfo.alipayName" placeholder="请输入真实姓名"></input>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form__field dis-flex flex-y-center">
|
||||
<view class="field-input flex-box">
|
||||
<input class="input" name="alipay_account" :value="shopInfo.alipayAccount"
|
||||
:disabled="shopInfo.alipayAccount" placeholder="请输入支付宝账号"></input>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</block>
|
||||
<block v-if="item == PayTypeEnum.BANK_CARD.value">
|
||||
<!-- 银行卡 -->
|
||||
<view class="form__field dis-flex flex-y-center">
|
||||
<view class="form__radio dis-flex flex-y-center"
|
||||
@click="handleChecked(PayTypeEnum.BANK_CARD.value)">
|
||||
<text class="radio__icon iconfont icon-radio"
|
||||
:class="[payment == PayTypeEnum.BANK_CARD.value ? 'c-violet' : 'col-bb']"></text>
|
||||
<text class="f-28">{{ PayTypeEnum.BANK_CARD.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<block v-if="payment == PayTypeEnum.BANK_CARD.value">
|
||||
<view class="form__field dis-flex flex-y-center">
|
||||
<view class="field-input flex-box">
|
||||
<input class="input" name="bank_name" placeholder="请输入真实姓名"></input>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form__field dis-flex flex-y-center">
|
||||
<view class="field-input flex-box">
|
||||
<input class="input" name="bank_account" placeholder="请输入开户行名称/地址"></input>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form__field dis-flex flex-y-center">
|
||||
<view class="field-input flex-box">
|
||||
<input class="input" name="bank_card" placeholder="请输入银行卡号"></input>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</block>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 提交申请 -->
|
||||
<view class="form-submit dis-flex flex-x-center">
|
||||
<button formType="submit" :disabled="disabled">{{ words.submit.value }}</button>
|
||||
</view>
|
||||
</form>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as DealerApi from '@/api/dealer'
|
||||
import * as ShopApi from '@/api/shop.js'
|
||||
import * as WithdrawApi from '@/api/dealer/withdraw'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
import {
|
||||
PayTypeEnum
|
||||
} from '@/common/enum/dealer/withdraw'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
PayTypeEnum,
|
||||
// 正在加载
|
||||
isLoading: true,
|
||||
shopInfo: {},
|
||||
shopId: 0,
|
||||
// 分销商用户信息
|
||||
dealer: undefined,
|
||||
// 当前提现方式(选中的)
|
||||
payment: undefined,
|
||||
// 分销结算设置
|
||||
settlement: undefined,
|
||||
// 文字设置
|
||||
words: undefined,
|
||||
// 背景图
|
||||
background: undefined,
|
||||
// 按钮禁用
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
this.getSetting()
|
||||
this.getDealer()
|
||||
this.getShopInfo()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
navTo(url) {
|
||||
this.$navTo(url)
|
||||
},
|
||||
getShopInfo() {
|
||||
const shopInfo = uni.getStorageSync('shopInfo')
|
||||
const {
|
||||
shopId
|
||||
} = shopInfo
|
||||
this.shopId = shopId
|
||||
ShopApi.detail(shopId).then(res => {
|
||||
this.shopInfo = res.data.detail
|
||||
})
|
||||
},
|
||||
|
||||
// 获取分销设置
|
||||
getSetting() {
|
||||
const app = this
|
||||
SettingModel.data()
|
||||
.then(setting => {
|
||||
// 赋值属性
|
||||
app.payment = setting.settlement.pay_type[0]
|
||||
app.settlement = setting.settlement
|
||||
app.words = setting.words.withdraw_apply.words
|
||||
app.background = setting.background.withdraw_apply
|
||||
// 设置当前页面标题
|
||||
app.setPageTitle(setting.words.withdraw_apply.title)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取分销商
|
||||
getDealer() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
DealerApi.user()
|
||||
.then(result => app.dealer = result.data.dealer)
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 设置当前页面标题
|
||||
setPageTitle(title) {
|
||||
uni.setNavigationBarTitle({
|
||||
title: title.value
|
||||
})
|
||||
},
|
||||
|
||||
// 切换支付选项
|
||||
handleChecked(value) {
|
||||
this.payment = value
|
||||
},
|
||||
|
||||
// 表单提交
|
||||
handleSubmit({
|
||||
detail
|
||||
}) {
|
||||
const app = this
|
||||
// 表单验证
|
||||
if (!app.onValidation(detail.value)) {
|
||||
return false
|
||||
}
|
||||
// 确认是否提交
|
||||
uni.showModal({
|
||||
title: '友情提示',
|
||||
content: '确定提交提现申请吗?请确认填写无误',
|
||||
showCancel: true,
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
app.onSubmit(detail.value)
|
||||
} else if (res.cancel) {
|
||||
app.disabled = false
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 提交提现申请
|
||||
onSubmit(data) {
|
||||
const app = this
|
||||
app.disabled = true
|
||||
data.pay_type = app.payment
|
||||
data.shopId = app.shopId
|
||||
ShopApi.submit({
|
||||
form: data
|
||||
})
|
||||
.then(result => {
|
||||
app.$toast(result.message)
|
||||
setTimeout(() => uni.navigateBack(), 1200)
|
||||
})
|
||||
.finally(() => app.disabled = false)
|
||||
},
|
||||
|
||||
// 表单验证
|
||||
onValidation(data) {
|
||||
const app = this
|
||||
const words = app.words
|
||||
// 验证可提现佣金
|
||||
if (app.dealer.money <= 0) {
|
||||
app.$error('当前没有' + words.capital.value)
|
||||
return false
|
||||
}
|
||||
// 验证提现金额
|
||||
if (!data.money || data.money.length < 1) {
|
||||
app.$error('请填写' + words.money.value)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.c-violet {
|
||||
color: #786cff;
|
||||
}
|
||||
|
||||
.col-bb {
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.dealer-bg {
|
||||
.image {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.widget-body {
|
||||
position: relative;
|
||||
width: 88%;
|
||||
margin: 0 auto;
|
||||
|
||||
.widget {
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.11);
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 提现金额
|
||||
.widget__capital {
|
||||
padding: 10rpx 0;
|
||||
margin-top: -60rpx;
|
||||
|
||||
.capital__item {
|
||||
height: 80rpx;
|
||||
padding: 10rpx 35rpx;
|
||||
font-size: 28rpx;
|
||||
border-bottom: 1rpx solid #e7e7e7;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.item__left {
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.item__right {
|
||||
.input {
|
||||
font-size: 28rpx;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.capital__lowest {
|
||||
padding-right: 20rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 26rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
// 提现方式
|
||||
.widget__form {
|
||||
padding: 10rpx 0 20rpx 0;
|
||||
|
||||
.form__title {
|
||||
padding: 16rpx 35rpx;
|
||||
border-bottom: 1rpx solid #f3f3f3;
|
||||
}
|
||||
|
||||
.form__box {
|
||||
padding: 20rpx 35rpx;
|
||||
}
|
||||
|
||||
.form__field {
|
||||
height: 80rpx;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-size: 28rpx;
|
||||
margin-bottom: 10rpx;
|
||||
|
||||
.radio__icon {
|
||||
font-size: 38rpx;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.field-input {
|
||||
.input {
|
||||
background-color: #f9f9f9;
|
||||
// height: 70rpx;
|
||||
padding: 16rpx 20rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 提交申请
|
||||
.form-submit {
|
||||
margin-top: 40rpx;
|
||||
|
||||
button {
|
||||
font-size: 30rpx;
|
||||
background: #786cff;
|
||||
border: 1rpx solid #786cff;
|
||||
color: white;
|
||||
border-radius: 50rpx;
|
||||
padding: 0 120rpx;
|
||||
}
|
||||
|
||||
button[disabled] {
|
||||
background: #8e84fc;
|
||||
border-color: #8e84fc;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
249
package/dealer/withdraw/list.vue
Executable file
249
package/dealer/withdraw/list.vue
Executable file
@@ -0,0 +1,249 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ use: false }" :up="upOption"
|
||||
@up="upCallback">
|
||||
|
||||
<!-- tab栏 -->
|
||||
<u-tabs :list="tabList" :is-scroll="false" :current="curTab" active-color="#786cff" :duration="0.2"
|
||||
@change="onChangeTab" />
|
||||
|
||||
<!-- 列表数据 -->
|
||||
<view class="widget-list">
|
||||
<view class="widget__detail dis-flex flex-x-between" v-for="(item, index) in list.data" :key="index">
|
||||
<view class="detail__left dis-flex flex-dir-column flex-x-around">
|
||||
<view class="detail__money f-30">
|
||||
<text>提现 {{ item.money }}元</text>
|
||||
<text v-if="item.pay_type == 10" class="iconfont icon-weixin"></text>
|
||||
<text v-if="item.pay_type == 20" class="iconfont icon-alipay"></text>
|
||||
<text v-if="item.pay_type == 30" class="iconfont icon-weixin"></text>
|
||||
</view>
|
||||
<view class="detail__time col-9 f-24">{{ item.create_time }}</view>
|
||||
</view>
|
||||
<view class="detail__right dis-flex flex-dir-column flex-x-center flex-y-center">
|
||||
<view class="detail__status f-28" :class="[ApplyStatusColor[item.apply_status]]">
|
||||
<text v-if="item.apply_status == 10">待审核</text>
|
||||
<text v-if="item.apply_status == 20">审核通过</text>
|
||||
<text v-if="item.apply_status == 30">驳回</text>
|
||||
<text v-if="item.apply_status == 40">已打款</text>
|
||||
</view>
|
||||
<block v-if="item.apply_status == 30">
|
||||
<view class="detail__reason f-24" @click="triggerReasonMsg">查看原因
|
||||
</view>
|
||||
<u-modal v-model="showReasonMsg" title="驳回原因">
|
||||
<view class="show-reason-msg">{{ item.reject_reason }}</view>
|
||||
</u-modal>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import { getEmptyPaginateObj, getMoreListData } from '@/core/app'
|
||||
import * as Api from '@/api/shop/withdraw'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
import { ApplyStatusEnum } from '@/common/enum/dealer/withdraw'
|
||||
|
||||
const pageSize = 15
|
||||
// 提现状态文字
|
||||
const ApplyStatusText = [10,20,30]
|
||||
|
||||
// 提现状态颜色
|
||||
const ApplyStatusColor = {
|
||||
[ApplyStatusEnum.WAIT.value]: 'col-m',
|
||||
[ApplyStatusEnum.PASSED.value]: 'col-green',
|
||||
[ApplyStatusEnum.REJECT.value]: 'col-m',
|
||||
[ApplyStatusEnum.PAYMENT.value]: 'col-green'
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
ApplyStatusEnum,
|
||||
ApplyStatusColor,
|
||||
ApplyStatusText,
|
||||
// 选项卡列表
|
||||
tabList: [],
|
||||
// 当前选项
|
||||
curTab: 0,
|
||||
// 列表数据
|
||||
list: getEmptyPaginateObj(),
|
||||
shopId: 0,
|
||||
showReasonMsg: false,
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: { size: pageSize },
|
||||
// 数量要大于12条才显示无更多数据
|
||||
noMoreSize: 12,
|
||||
// 空布局
|
||||
empty: {
|
||||
tip: '亲,暂无相关数据'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
this.getSetting()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取分销设置
|
||||
getSetting() {
|
||||
const app = this
|
||||
SettingModel.data()
|
||||
.then(setting => {
|
||||
const words = setting.words.withdraw_list
|
||||
app.setPageTitle(words.title)
|
||||
app.setTabList(words.words)
|
||||
})
|
||||
},
|
||||
|
||||
// 设置页面标题
|
||||
setPageTitle(title) {
|
||||
uni.setNavigationBarTitle({
|
||||
title: title.value
|
||||
})
|
||||
},
|
||||
|
||||
// 设置选项卡数据
|
||||
setTabList(words) {
|
||||
const app = this
|
||||
app.tabList = [
|
||||
{ value: -1, name: words.all.value },
|
||||
{ value: ApplyStatusEnum.WAIT.value, name: words.apply_10.value },
|
||||
{ value: ApplyStatusEnum.PASSED.value, name: words.apply_20.value },
|
||||
{ value: ApplyStatusEnum.PAYMENT.value, name: words.apply_40.value },
|
||||
{ value: ApplyStatusEnum.REJECT.value, name: words.apply_30.value }
|
||||
]
|
||||
},
|
||||
|
||||
triggerReasonMsg(){
|
||||
this.showReasonMsg = !this.showReasonMsg
|
||||
},
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
app.getList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
// 获取提现列表
|
||||
getList(pageNo = 1) {
|
||||
const app = this
|
||||
const { shopId } = uni.getStorageSync('shopInfo')
|
||||
return new Promise((resolve, reject) => {
|
||||
Api.list({ applyStatus: app.getTabValue(), page: pageNo, shopId })
|
||||
.then(result => {
|
||||
// 合并新数据
|
||||
const newList = result.data.list
|
||||
app.list.data = getMoreListData(newList, app.list, pageNo)
|
||||
resolve(newList)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 获取当前标签项的值
|
||||
getTabValue() {
|
||||
const app = this
|
||||
if (app.tabList.length) {
|
||||
return app.tabList[app.curTab].value
|
||||
}
|
||||
return -1
|
||||
},
|
||||
|
||||
// 切换标签项
|
||||
onChangeTab(index) {
|
||||
const app = this
|
||||
// 设置当前选中的标签
|
||||
app.curTab = index
|
||||
// 刷新订单列表
|
||||
app.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新列表数据
|
||||
onRefreshList() {
|
||||
this.list = getEmptyPaginateObj()
|
||||
setTimeout(() => {
|
||||
this.mescroll.resetUpScroll()
|
||||
}, 120)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
// 提现明细列表
|
||||
.widget-list {
|
||||
padding: 10rpx 20rpx 40rpx 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.widget__detail {
|
||||
padding: 20rpx 15rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 28rpx;
|
||||
border-bottom: 1rpx solid #e7e7e7;
|
||||
}
|
||||
|
||||
.widget__detail .detail__money {
|
||||
font-size: 30rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.widget__detail .detail__reason {
|
||||
margin-top: 15rpx;
|
||||
color: #8e84fc;
|
||||
}
|
||||
.show-reason-msg{
|
||||
padding: 20rpx;
|
||||
line-height: 2rem;
|
||||
color: #ff0000;
|
||||
}
|
||||
.detail__left{
|
||||
.iconfont{
|
||||
margin-left: 30rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.icon-weixin{
|
||||
color: #0eaf00;
|
||||
}
|
||||
.icon-alipay{
|
||||
color: #0f80ff;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
206
package/deliver/address/create.vue
Executable file
206
package/deliver/address/create.vue
Executable file
@@ -0,0 +1,206 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<!-- 标题 -->
|
||||
<view class="page-title">收货地址</view>
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper">
|
||||
<u-form :model="form" ref="uForm" label-width="140rpx">
|
||||
<u-form-item label="姓名" prop="name">
|
||||
<u-input v-model="form.name" placeholder="请输入收货人姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="电话" prop="phone">
|
||||
<u-input v-model="form.phone" placeholder="请输入收货人手机号" />
|
||||
</u-form-item>
|
||||
<u-form-item label="地区" prop="region">
|
||||
<select-region ref="sRegion" v-model="form.region" />
|
||||
</u-form-item>
|
||||
<u-form-item label="详细地址" prop="detail" :border-bottom="false">
|
||||
<u-input v-model="form.detail" placeholder="街道门牌、楼层等信息" />
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn-wrapper">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="btn-item btn-item-wechat" @click="chooseAddress()">选择微信收货地址</view>
|
||||
<!-- #endif -->
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">保存</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
import { isMobile } from '@/utils/verify'
|
||||
import * as AddressApi from '@/api/address'
|
||||
|
||||
// 表单字段元素
|
||||
const form = {
|
||||
name: '',
|
||||
phone: '',
|
||||
region: [],
|
||||
detail: ''
|
||||
}
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
name: [{
|
||||
required: true,
|
||||
message: '请输入姓名',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
phone: [{
|
||||
required: true,
|
||||
message: '请输入手机号',
|
||||
trigger: ['blur', 'change']
|
||||
}, {
|
||||
// 自定义验证函数
|
||||
validator: (rule, value, callback) => {
|
||||
// 返回true表示校验通过,返回false表示不通过
|
||||
return isMobile(value)
|
||||
},
|
||||
message: '手机号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['blur'],
|
||||
}],
|
||||
region: [{
|
||||
required: true,
|
||||
message: '请选择省市区',
|
||||
trigger: ['blur', 'change'],
|
||||
type: 'array'
|
||||
}],
|
||||
detail: [{
|
||||
required: true,
|
||||
message: '请输入详细地址',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form,
|
||||
rules,
|
||||
// 按钮禁用
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {},
|
||||
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules)
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 选择微信地址
|
||||
// #ifdef MP-WEIXIN
|
||||
chooseAddress() {
|
||||
const { form, $refs } = this
|
||||
uni.chooseAddress({
|
||||
success(res) {
|
||||
const names = $refs.sRegion.getOptionItemByNames(res)
|
||||
form.name = res.userName
|
||||
form.phone = res.telNumber
|
||||
form.detail = res.detailInfo
|
||||
form.region = names.length > 0 ? names : []
|
||||
}
|
||||
})
|
||||
},
|
||||
// #endif
|
||||
|
||||
// 表单提交
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
if (app.disabled) {
|
||||
return false
|
||||
}
|
||||
app.$refs.uForm.validate(valid => {
|
||||
if (valid) {
|
||||
app.disabled = true
|
||||
AddressApi.add(app.form)
|
||||
.then(result => {
|
||||
app.$toast(result.message)
|
||||
uni.navigateBack()
|
||||
})
|
||||
.finally(() => app.disabled = false)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #f7f8fa;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.page-title {
|
||||
width: 94%;
|
||||
margin: 0 auto;
|
||||
padding-top: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(69, 90, 100, 0.6);
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
|
||||
.footer {
|
||||
margin-top: 80rpx;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-wechat {
|
||||
background: #0ba90b;
|
||||
margin-bottom: 26rpx;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
305
package/deliver/address/index.vue
Executable file
305
package/deliver/address/index.vue
Executable file
@@ -0,0 +1,305 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<view class="addres-list">
|
||||
<view class="address-item" v-for="(item, index) in list" :key="index">
|
||||
<view class="contacts">
|
||||
<text class="name">{{ item.name }}</text>
|
||||
<text class="phone">{{ item.phone }}</text>
|
||||
</view>
|
||||
<view class="address">
|
||||
<text class="region" v-for="(region, idx) in item.region" :key="idx">{{ region }}</text>
|
||||
<text class="detail">{{ item.detail }}</text>
|
||||
</view>
|
||||
<view class="line"></view>
|
||||
<view class="item-option">
|
||||
<view class="_left">
|
||||
<label class="item-radio" @click.stop="handleSetDefault(item.address_id)">
|
||||
<radio class="radio" :color="appTheme.mainBg" :checked="item.address_id == defaultId"></radio>
|
||||
<text class="text">{{ item.address_id == defaultId ? '默认' : '选择' }}</text>
|
||||
</label>
|
||||
</view>
|
||||
<view class="_right">
|
||||
<view class="events">
|
||||
<view class="event-item" @click="handleUpdate(item.address_id)">
|
||||
<text class="iconfont icon-edit"></text>
|
||||
<text class="title">编辑</text>
|
||||
</view>
|
||||
<view class="event-item" @click="handleRemove(item.address_id)">
|
||||
<text class="iconfont icon-delete"></text>
|
||||
<text class="title">删除</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<empty v-if="!list.length" :isLoading="isLoading" tips="亲,暂无取货地址" />
|
||||
<!-- 底部操作按钮 -->
|
||||
<view class="footer-fixed">
|
||||
<view class="btn-wrapper">
|
||||
<view class="btn-item btn-item-main" @click="handleCreate()">添加新地址</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as AddressApi from '@/api/address'
|
||||
import Empty from '@/components/empty'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Empty
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
//当前页面参数
|
||||
options: {},
|
||||
// 正在加载
|
||||
isLoading: true,
|
||||
// 收货地址列表
|
||||
list: [],
|
||||
// 默认收货地址
|
||||
defaultId: null
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
// 当前页面参数
|
||||
this.options = options
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow() {
|
||||
// 获取页面数据
|
||||
this.getPageData()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取页面数据
|
||||
getPageData() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
Promise.all([app.getDefaultId(), app.getAddressList()])
|
||||
.then(() => {
|
||||
// 列表排序把默认收货地址放到最前
|
||||
app.onReorder()
|
||||
})
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 获取收货地址列表
|
||||
getAddressList() {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
AddressApi.list()
|
||||
.then(result => {
|
||||
app.list = result.data.list
|
||||
resolve(result)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取默认的收货地址
|
||||
getDefaultId() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const app = this
|
||||
AddressApi.defaultId()
|
||||
.then(result => {
|
||||
app.defaultId = result.data.defaultId
|
||||
resolve(result)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 列表排序把默认收货地址放到最前
|
||||
onReorder() {
|
||||
const app = this
|
||||
app.list.sort(item => {
|
||||
return item.address_id == app.defaultId ? -1 : 1
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 添加新地址
|
||||
*/
|
||||
handleCreate() {
|
||||
this.$navTo('pages/address/create')
|
||||
},
|
||||
|
||||
/**
|
||||
* 编辑地址
|
||||
* @param {int} addressId 收货地址ID
|
||||
*/
|
||||
handleUpdate(addressId) {
|
||||
this.$navTo('pages/address/update', { addressId })
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除收货地址
|
||||
* @param {int} addressId 收货地址ID
|
||||
*/
|
||||
handleRemove(addressId) {
|
||||
const app = this
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "您确定要删除当前收货地址吗?",
|
||||
success({ confirm }) {
|
||||
confirm && app.onRemove(addressId)
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 确认删除收货地址
|
||||
* @param {int} addressId 收货地址ID
|
||||
*/
|
||||
onRemove(addressId) {
|
||||
const app = this
|
||||
AddressApi.remove(addressId)
|
||||
.then(result => {
|
||||
app.getPageData()
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 设置为默认地址
|
||||
* @param {Object} addressId
|
||||
*/
|
||||
handleSetDefault(addressId) {
|
||||
const app = this
|
||||
AddressApi.setDefault(addressId)
|
||||
.then(result => {
|
||||
app.defaultId = addressId
|
||||
app.options.from === 'checkout' && uni.navigateBack()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.addres-list {
|
||||
padding-bottom: calc(constant(safe-area-inset-bottom) + 140rpx);
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 140rpx);
|
||||
padding-top: 20rpx;
|
||||
}
|
||||
|
||||
// 项目内容
|
||||
.address-item {
|
||||
margin: 0 auto 20rpx auto;
|
||||
padding: 30rpx 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0 rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.contacts {
|
||||
font-size: 30rpx;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
.name {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.address {
|
||||
font-size: 28rpx;
|
||||
|
||||
.region {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
margin: 20rpx 0;
|
||||
border-bottom: 1rpx solid #f3f3f3;
|
||||
}
|
||||
|
||||
.item-option {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 48rpx;
|
||||
|
||||
// 单选框
|
||||
.item-radio {
|
||||
font-size: 28rpx;
|
||||
|
||||
.radio {
|
||||
vertical-align: middle;
|
||||
transform: scale(0.76)
|
||||
}
|
||||
|
||||
.text {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
// 操作
|
||||
.events {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 48rpx;
|
||||
|
||||
.event-item {
|
||||
font-size: 28rpx;
|
||||
margin-right: 26rpx;
|
||||
color: #4c4c4c;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 底部操作栏
|
||||
.footer-fixed {
|
||||
position: fixed;
|
||||
bottom: var(--window-bottom);
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 11;
|
||||
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
|
||||
.btn-wrapper {
|
||||
height: 120rpx;
|
||||
padding: 0 40rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-shadow: 0 1rpx 5rpx 0 rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
244
package/deliver/address/update.vue
Executable file
244
package/deliver/address/update.vue
Executable file
@@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<!-- 标题 -->
|
||||
<view class="page-title">收货地址</view>
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper">
|
||||
<u-form :model="form" ref="uForm" label-width="140rpx">
|
||||
<u-form-item label="姓名" prop="name">
|
||||
<u-input v-model="form.name" placeholder="请输入收货人姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="电话" prop="phone">
|
||||
<u-input v-model="form.phone" placeholder="请输入收货人手机号" />
|
||||
</u-form-item>
|
||||
<u-form-item label="地区" prop="region">
|
||||
<select-region ref="sRegion" v-model="form.region" />
|
||||
</u-form-item>
|
||||
<u-form-item label="详细地址" prop="detail" :border-bottom="false">
|
||||
<u-input v-model="form.detail" placeholder="街道门牌、楼层等信息" />
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn-wrapper">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="btn-item btn-item-wechat" @click="chooseAddress()">选择微信收货地址</view>
|
||||
<!-- #endif -->
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">保存</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
import { isMobile } from '@/utils/verify'
|
||||
import * as AddressApi from '@/api/address'
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
name: [{
|
||||
required: true,
|
||||
message: '请输入姓名',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
phone: [{
|
||||
required: true,
|
||||
message: '请输入手机号',
|
||||
trigger: ['blur', 'change']
|
||||
}, {
|
||||
// 自定义验证函数
|
||||
validator: (rule, value, callback) => {
|
||||
// 返回true表示校验通过,返回false表示不通过
|
||||
return isMobile(value)
|
||||
},
|
||||
message: '手机号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['blur'],
|
||||
}],
|
||||
region: [{
|
||||
required: true,
|
||||
message: '请选择省市区',
|
||||
trigger: ['blur', 'change'],
|
||||
type: 'array'
|
||||
}],
|
||||
detail: [{
|
||||
required: true,
|
||||
message: '请输入详细地址',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
name: '',
|
||||
phone: '',
|
||||
region: [],
|
||||
detail: ''
|
||||
},
|
||||
rules,
|
||||
// 加载中
|
||||
isLoading: true,
|
||||
// 按钮禁用
|
||||
disabled: false,
|
||||
// 当前收货地址ID
|
||||
addressId: null
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad({ addressId }) {
|
||||
// 当前收货地址ID
|
||||
this.addressId = addressId
|
||||
// 获取当前记录详情
|
||||
this.getDetail()
|
||||
},
|
||||
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules)
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取当前记录详情
|
||||
getDetail() {
|
||||
const app = this
|
||||
AddressApi.detail(app.addressId)
|
||||
.then(result => {
|
||||
const detail = result.data.detail
|
||||
app.createFormData(detail)
|
||||
})
|
||||
},
|
||||
|
||||
// 选择微信地址
|
||||
// #ifdef MP-WEIXIN
|
||||
chooseAddress() {
|
||||
const { form, $refs } = this
|
||||
uni.chooseAddress({
|
||||
success(res) {
|
||||
const names = $refs.sRegion.getOptionItemByNames(res)
|
||||
form.name = res.userName
|
||||
form.phone = res.telNumber
|
||||
form.detail = res.detailInfo
|
||||
form.region = names.length > 0 ? names : []
|
||||
}
|
||||
})
|
||||
},
|
||||
// #endif
|
||||
|
||||
// 生成默认的表单数据
|
||||
createFormData(detail) {
|
||||
const { form } = this
|
||||
form.name = detail.name
|
||||
form.phone = detail.phone
|
||||
form.detail = detail.detail
|
||||
form.region = this.createRegion(detail)
|
||||
},
|
||||
|
||||
createRegion(detail) {
|
||||
return [{
|
||||
label: detail.region.province,
|
||||
value: detail.province_id
|
||||
}, {
|
||||
label: detail.region.city,
|
||||
value: detail.city_id
|
||||
}, {
|
||||
label: detail.region.region,
|
||||
value: detail.region_id
|
||||
}]
|
||||
},
|
||||
|
||||
// 表单提交
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
if (app.disabled) {
|
||||
return false
|
||||
}
|
||||
app.$refs.uForm.validate(valid => {
|
||||
if (valid) {
|
||||
app.disabled = true
|
||||
AddressApi.edit(app.addressId, app.form)
|
||||
.then(result => {
|
||||
app.$toast(result.message)
|
||||
uni.navigateBack()
|
||||
})
|
||||
.finally(() => app.disabled = false)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #f7f8fa;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.page-title {
|
||||
width: 94%;
|
||||
margin: 0 auto;
|
||||
padding-top: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(69, 90, 100, 0.6);
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
|
||||
.footer {
|
||||
margin-top: 80rpx;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-wechat {
|
||||
background: #0ba90b;
|
||||
margin-bottom: 26rpx;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
231
package/deliver/city-select.vue
Normal file
231
package/deliver/city-select.vue
Normal file
@@ -0,0 +1,231 @@
|
||||
<template>
|
||||
<u-popup v-model="value" mode="bottom" :popup="false" :mask="true" :closeable="true" :safe-area-inset-bottom="true"
|
||||
close-icon-color="#ffffff" :z-index="uZIndex" :maskCloseAble="maskCloseAble" @close="close">
|
||||
<u-tabs v-if="value" :list="genTabsList" :is-scroll="true" :current="tabsIndex" @change="tabsChange" ref="tabs"></u-tabs>
|
||||
<view class="area-box">
|
||||
<view class="u-flex" :class="{ 'change':isChange }">
|
||||
<view class="area-item">
|
||||
<view class="u-padding-10 u-bg-gray" style="height: 100%;">
|
||||
<scroll-view :scroll-y="true" style="height: 100%">
|
||||
<u-cell-group>
|
||||
<u-cell-item v-for="(item,index) in provinces" :title="item.label" :arrow="false" :index="index" :key="index"
|
||||
@click="provinceChange">
|
||||
<u-icon v-if="isChooseP&&province===index" slot="right-icon" size="34" name="checkbox-mark"></u-icon>
|
||||
</u-cell-item>
|
||||
</u-cell-group>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="area-item">
|
||||
<view class="u-padding-10 u-bg-gray" style="height: 100%;">
|
||||
<scroll-view :scroll-y="true" style="height: 100%">
|
||||
<u-cell-group v-if="isChooseP">
|
||||
<u-cell-item v-for="(item,index) in citys" :title="item.label" :arrow="false" :index="index" :key="index"
|
||||
@click="cityChange">
|
||||
<u-icon v-if="isChooseC&&city===index" slot="right-icon" size="34" name="checkbox-mark"></u-icon>
|
||||
</u-cell-item>
|
||||
</u-cell-group>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="area-item">
|
||||
<view class="u-padding-10 u-bg-gray" style="height: 100%;">
|
||||
<scroll-view :scroll-y="true" style="height: 100%">
|
||||
<u-cell-group v-if="isChooseC">
|
||||
<u-cell-item v-for="(item,index) in areas" :title="item.label" :arrow="false" :index="index" :key="index"
|
||||
@click="areaChange">
|
||||
<u-icon v-if="isChooseA&&area===index" slot="right-icon" size="34" name="checkbox-mark"></u-icon>
|
||||
</u-cell-item>
|
||||
</u-cell-group>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import provinces from "uview-ui/libs/util/province.js";
|
||||
import citys from "uview-ui/libs/util/city.js";
|
||||
import areas from "uview-ui/libs/util/area.js";
|
||||
/**
|
||||
* city-select 省市区级联选择器
|
||||
* @property {String Number} z-index 弹出时的z-index值(默认1075)
|
||||
* @property {Boolean} mask-close-able 是否允许通过点击遮罩关闭Picker(默认true)
|
||||
* @property {String} default-region 默认选中的地区,中文形式
|
||||
* @property {String} default-code 默认选中的地区,编号形式
|
||||
*/
|
||||
export default {
|
||||
name: 'u-city-select',
|
||||
props: {
|
||||
// 通过双向绑定控制组件的弹出与收起
|
||||
value: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 默认显示的地区,可传类似["河北省", "秦皇岛市", "北戴河区"]
|
||||
defaultRegion: {
|
||||
type: Array,
|
||||
default () {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
// 默认显示地区的编码,defaultRegion和areaCode同时存在,areaCode优先,可传类似["13", "1303", "130304"]
|
||||
areaCode: {
|
||||
type: Array,
|
||||
default () {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
// 是否允许通过点击遮罩关闭Picker
|
||||
maskCloseAble: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 弹出的z-index值
|
||||
zIndex: {
|
||||
type: [String, Number],
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
cityValue: "",
|
||||
isChooseP: false, //是否已经选择了省
|
||||
province: 0, //省级下标
|
||||
provinces: provinces,
|
||||
isChooseC: false, //是否已经选择了市
|
||||
city: 0, //市级下标
|
||||
citys: citys[0],
|
||||
isChooseA: false, //是否已经选择了区
|
||||
area: 0, //区级下标
|
||||
areas: areas[0][0],
|
||||
tabsIndex: 0,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
computed: {
|
||||
isChange() {
|
||||
return this.tabsIndex > 1;
|
||||
},
|
||||
genTabsList() {
|
||||
let tabsList = [{
|
||||
name: "请选择"
|
||||
}];
|
||||
if (this.isChooseP) {
|
||||
tabsList[0]['name'] = this.provinces[this.province]['label'];
|
||||
tabsList[1] = {
|
||||
name: "请选择"
|
||||
};
|
||||
}
|
||||
if (this.isChooseC) {
|
||||
tabsList[1]['name'] = this.citys[this.city]['label'];
|
||||
tabsList[2] = {
|
||||
name: "请选择"
|
||||
};
|
||||
}
|
||||
if (this.isChooseA) {
|
||||
tabsList[2]['name'] = this.areas[this.area]['label'];
|
||||
}
|
||||
return tabsList;
|
||||
},
|
||||
uZIndex() {
|
||||
// 如果用户有传递z-index值,优先使用
|
||||
return this.zIndex ? this.zIndex : this.$u.zIndex.popup;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
if (this.areaCode.length == 3) {
|
||||
this.setProvince("", this.areaCode[0]);
|
||||
this.setCity("", this.areaCode[1]);
|
||||
this.setArea("", this.areaCode[2]);
|
||||
} else if (this.defaultRegion.length == 3) {
|
||||
this.setProvince(this.defaultRegion[0], "");
|
||||
this.setCity(this.defaultRegion[1], "");
|
||||
this.setArea(this.defaultRegion[2], "");
|
||||
};
|
||||
},
|
||||
setProvince(label = "", value = "") {
|
||||
this.provinces.map((v, k) => {
|
||||
if (value ? v.value == value : v.label == label) {
|
||||
this.provinceChange(k);
|
||||
}
|
||||
})
|
||||
},
|
||||
setCity(label = "", value = "") {
|
||||
this.citys.map((v, k) => {
|
||||
if (value ? v.value == value : v.label == label) {
|
||||
this.cityChange(k);
|
||||
}
|
||||
})
|
||||
},
|
||||
setArea(label = "", value = "") {
|
||||
this.areas.map((v, k) => {
|
||||
if (value ? v.value == value : v.label == label) {
|
||||
this.isChooseA = true;
|
||||
this.area = k;
|
||||
}
|
||||
})
|
||||
},
|
||||
close() {
|
||||
this.$emit('input', false);
|
||||
},
|
||||
tabsChange(index) {
|
||||
this.tabsIndex = index;
|
||||
},
|
||||
provinceChange(index) {
|
||||
this.isChooseP = true;
|
||||
this.isChooseC = false;
|
||||
this.isChooseA = false;
|
||||
this.province = index;
|
||||
this.citys = citys[index];
|
||||
this.tabsIndex = 1;
|
||||
},
|
||||
cityChange(index) {
|
||||
this.isChooseC = true;
|
||||
this.isChooseA = false;
|
||||
this.city = index;
|
||||
this.areas = areas[this.province][index];
|
||||
this.tabsIndex = 2;
|
||||
},
|
||||
areaChange(index) {
|
||||
this.isChooseA = true;
|
||||
this.area = index;
|
||||
let result = {};
|
||||
result.province = this.provinces[this.province];
|
||||
result.city = this.citys[this.city];
|
||||
result.area = this.areas[this.area];
|
||||
this.$emit('city-change', result);
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.area-box {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
height: 800rpx;
|
||||
|
||||
>view {
|
||||
width: 150%;
|
||||
transition: transform 0.3s ease-in-out 0s;
|
||||
transform: translateX(0);
|
||||
|
||||
&.change {
|
||||
transform: translateX(-33.3333333%);
|
||||
}
|
||||
}
|
||||
|
||||
.area-item {
|
||||
width: 33.3333333%;
|
||||
height: 800rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
322
package/deliver/my-order.vue
Normal file
322
package/deliver/my-order.vue
Normal file
@@ -0,0 +1,322 @@
|
||||
<template>
|
||||
<view style="height: 90vh;">
|
||||
<u-navbar title-color="#fff" back-icon-color="#ffffff"
|
||||
:is-fixed="true"
|
||||
:is-back="true"
|
||||
:background="topBackground"
|
||||
:back-text-style="{color: '#fff'}"
|
||||
:title="title"
|
||||
:back-icon-name="backIconName"
|
||||
:back-text="backText"
|
||||
>
|
||||
</u-navbar>
|
||||
<view class="divison"></view>
|
||||
<view class="myData">
|
||||
<view class="datas">我的佣金:<text style="color: #ED1C24;font-size: 18px;margin: 5rpx;">¥{{ myMoney }}</text></view>
|
||||
<view class="datas">已配送单数:<text style="color: #ED1C24;font-size: 18px;margin: 5rpx;">{{ orderNum }}</text>单</view>
|
||||
</view>
|
||||
|
||||
<view class="pageContent">
|
||||
<view class="u-tabs-box">
|
||||
<u-tabs-swiper activeColor="#f29100" ref="tabs" :list="list" :current="current" @change="change" :is-scroll="false" ></u-tabs-swiper>
|
||||
</view>
|
||||
|
||||
<swiper class="swiper-box" :current="swiperCurrent" @transition="transition" @animationfinish="animationfinish">
|
||||
<!-- 待送达 -->
|
||||
|
||||
<swiper-item class="swiper-item">
|
||||
<scroll-view scroll-y style="height: 100%;width: 100%;" @scrolltolower="reachBottom">
|
||||
<view class="orderList" v-for="(item,index) in ongoinglist" :key="index">
|
||||
<view class="orderMassage">
|
||||
<view class="storePicture">
|
||||
<image :src="item.store_picture" border-radius="20px" style="width: 90%;height: 90%;"></image>
|
||||
</view>
|
||||
<view class="details">
|
||||
<view class="orderText">
|
||||
<text >取货地址:{{ item.take_addr }}</text>
|
||||
</view>
|
||||
<view class="orderText">
|
||||
<text>配送地址:{{ item.go_addr }}</text>
|
||||
</view>
|
||||
<view class="orderText">
|
||||
<text style="color: #ffaa00;">配送预计时间:{{ item.predict_time }}分钟</text>
|
||||
</view>
|
||||
<view class="orderText">
|
||||
<view>佣金:<text style="color: #ff0000">¥</text><text style="font-size: 18px;color: #ff0000;">{{ item.earn_money }}</text></view>
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<view class="giveUp">
|
||||
<u-button shape="square" type="success" size="mini" :plain="true">放弃订单</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</swiper-item>
|
||||
<!-- 已送达 -->
|
||||
<swiper-item class="swiper-item">
|
||||
<scroll-view scroll-y style="height: 100%;width: 100%;" @scrolltolower="reachBottom" >
|
||||
<view class="orderList2" v-for="(item,index) in completeorder" :key="index">
|
||||
<view class="orderMassage2">
|
||||
<view class="storePicture">
|
||||
<image :src="item.store_picture" border-radius="20px" style="width: 90%;height: 80%;border-radius: 10rpx;"></image>
|
||||
</view>
|
||||
<view class="details">
|
||||
<view>
|
||||
<view class="orderText">
|
||||
<text>取货地址:{{ item.take_addr }}</text>
|
||||
</view>
|
||||
<view class="orderText">
|
||||
<text>配送地址:{{ item.go_addr }}</text>
|
||||
</view>
|
||||
|
||||
<view class="orderText2">
|
||||
<view>佣金:<text style="color: #ff0000">¥</text><text style="font-size: 18px;color: #ff0000;">{{ item.earn_money }}</text></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 顶部标题
|
||||
title: '我的配送',
|
||||
backText: '返回',
|
||||
backIconName: 'nav-back',
|
||||
isBack: true,
|
||||
topBackground: {
|
||||
backgroundImage: 'linear-gradient(to right, #146930 , #77b633)'
|
||||
},
|
||||
|
||||
// 我的佣金和订单数
|
||||
myMoney:888,
|
||||
orderNum:55,
|
||||
|
||||
|
||||
|
||||
orderList: [[], []],
|
||||
list:[
|
||||
{
|
||||
name:'待送达',
|
||||
},
|
||||
{
|
||||
name:'已送达',
|
||||
}
|
||||
],
|
||||
// 因为内部的滑动机制限制,请将tabs组件和swiper组件的current用不同变量赋值
|
||||
current: 0,
|
||||
swiperCurrent: 0,
|
||||
tabsHeight: 0,
|
||||
dx: 0,
|
||||
loadStatus: ['loadmore','loadmore'],
|
||||
ongoinglist:[
|
||||
{
|
||||
store_id:1,
|
||||
store_picture:'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fwx4.sinaimg.cn%2Flarge%2F006CjT3ggy1gvbdntuo3fj60n40d0abv02.jpg&refer=http%3A%2F%2Fwx4.sinaimg.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1638519744&t=f9c70870945fb51eb9f4aa93ef5a3390',
|
||||
take_addr:'北京天安门广场一号广场楼',
|
||||
go_addr:'清华大学',
|
||||
predict_time:18,
|
||||
earn_money:18,
|
||||
},
|
||||
{
|
||||
store_id:2,
|
||||
store_picture:'https://pic.rmb.bdstatic.com/bjh/news/f8510dd27a49a7d30befaef266d0a9a5.png',
|
||||
take_addr:'南宁市良庆区总部基地',
|
||||
go_addr:'广西大学',
|
||||
predict_time:18,
|
||||
earn_money:18,
|
||||
}
|
||||
],
|
||||
completeorder:[
|
||||
{
|
||||
store_id:1,
|
||||
store_picture:'https://ns-strategy.cdn.bcebos.com/ns-strategy/upload/fc_big_pic/part-00555-2517.jpg',
|
||||
go_addr:'清华大学',
|
||||
predict_time:18,
|
||||
earn_money:18,
|
||||
take_addr:'南宁市良庆区总部基地',
|
||||
},
|
||||
{
|
||||
store_id:2,
|
||||
store_picture:'https://ns-strategy.cdn.bcebos.com/ns-strategy/upload/fc_big_pic/part-00555-2517.jpg',
|
||||
take_addr:'南宁市良庆区总部基地',
|
||||
go_addr:'广西大学',
|
||||
predict_time:18,
|
||||
earn_money:18,
|
||||
}
|
||||
],
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
// tab栏切换
|
||||
change(index) {
|
||||
this.swiperCurrent = index;
|
||||
this.getOrderList(index);
|
||||
},
|
||||
transition({ detail: { dx } }) {
|
||||
this.$refs.tabs.setDx(dx);
|
||||
},
|
||||
animationfinish({ detail: { current } }) {
|
||||
this.$refs.tabs.setFinishCurrent(current);
|
||||
this.swiperCurrent = current;
|
||||
this.current = current;
|
||||
},
|
||||
// 页面数据 foodMaterialList
|
||||
getOrderList(idx) {
|
||||
|
||||
if(idx==0){
|
||||
for(let i = 0; i < 5; i++) {
|
||||
let index = this.$u.random(0, this.ongoinglist.length - 1);
|
||||
let data = JSON.parse(JSON.stringify(this.ongoinglist[index]));
|
||||
data.id = this.$u.guid();
|
||||
this.orderList[idx].push(data);
|
||||
}
|
||||
this.loadStatus.splice(this.current,3,"loadmore")
|
||||
|
||||
}else if(idx==1){
|
||||
for(let i = 0; i < 5; i++) {
|
||||
let index = this.$u.random(0, this.completeorder.length - 1);
|
||||
let data = JSON.parse(JSON.stringify(this.completeorder[index]));
|
||||
data.id = this.$u.guid();
|
||||
this.orderList[idx].push(data);
|
||||
}
|
||||
this.loadStatus.splice(this.current,3,"loadmore")
|
||||
}
|
||||
},
|
||||
reachBottom() {
|
||||
// 此tab为空数据
|
||||
if(this.current != 2) {
|
||||
this.loadStatus.splice(this.current,10,"loading")
|
||||
setTimeout(() => {
|
||||
this.getOrderList(this.current);
|
||||
}, 1200);
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.myData{
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
background-color: #FFFFFF;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.datas{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 50%;
|
||||
height: 40px;
|
||||
font-size: 15px;
|
||||
|
||||
border-radius: 10px;
|
||||
margin: 20rpx 10rpx;
|
||||
}
|
||||
.pageContent{
|
||||
height: 100%;
|
||||
}
|
||||
.swiper-box {
|
||||
height: 100%;
|
||||
|
||||
}
|
||||
.swiper-item {
|
||||
height: 100%;
|
||||
}
|
||||
.orderList{
|
||||
margin-top: 20rpx;
|
||||
height: 140px;
|
||||
}
|
||||
.orderList2{
|
||||
margin-top: 20rpx;
|
||||
|
||||
}
|
||||
.divison{
|
||||
width: 100%;
|
||||
height: 10rpx;
|
||||
background-color: #e3e3e5;
|
||||
}
|
||||
|
||||
.orderMassage{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border: #f3f3f3 solid 1px;
|
||||
border-radius: 10px;
|
||||
height: 135px;
|
||||
align-items: center;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
.orderMassage2{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border: #f3f3f3 solid 1px;
|
||||
border-radius: 10px;
|
||||
height: 120px;
|
||||
align-items: center;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
.storePicture{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 45%;
|
||||
height: 260rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
.details{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: flex-end;
|
||||
width: 55%;
|
||||
}
|
||||
.orderText{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
margin-top: 10rpx;
|
||||
padding-left: 10rpx;
|
||||
|
||||
|
||||
}
|
||||
.orderText2{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
margin-top: 20rpx;
|
||||
padding-left: 10rpx;
|
||||
|
||||
|
||||
}
|
||||
.giveUp{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
align-items: flex-end;
|
||||
position: relative;
|
||||
top: -70rpx;
|
||||
margin-right: 15rpx;
|
||||
color: #FFFFFF;
|
||||
|
||||
}
|
||||
</style>
|
||||
271
package/deliver/notice/index.vue
Normal file
271
package/deliver/notice/index.vue
Normal file
@@ -0,0 +1,271 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ use: false }" :up="upOption"
|
||||
@up="upCallback">
|
||||
|
||||
<!-- tab栏 -->
|
||||
<u-tabs :list="tabList" :is-scroll="false" :current="curTab" active-color="#0f80ff" :duration="0.2"
|
||||
@change="onChangeTab" />
|
||||
|
||||
<!-- 列表数据 -->
|
||||
<view class="widget-list">
|
||||
<view class="widget__detail dis-flex flex-x-between" v-for="(item, index) in list.data" :key="index">
|
||||
<view class="detail__left dis-flex flex-dir-column flex-x-around">
|
||||
<view class="detail__money f-30" @click="onRead(item.id, item.content)">
|
||||
<u-avatar size="mini" mode="circle" v-if="item.sendUser" :src="item.sendUser.avatar_url">
|
||||
</u-avatar>
|
||||
<view class="content">
|
||||
<text>{{ item.content }}</text>
|
||||
<u-badge :is-dot="true" :offset="[0,0]" type="error" v-if="item.status == 0"></u-badge>
|
||||
</view>
|
||||
</view>
|
||||
<view class="detail__time col-9 f-24">{{ item.create_time }}</view>
|
||||
</view>
|
||||
<view class="detail__right dis-flex flex-dir-column flex-x-center flex-y-center">
|
||||
<view class="detail__status f-28">
|
||||
<u-tag v-if="item.status == 0" type="error" text="未读"></u-tag>
|
||||
<u-tag v-if="item.status == 1" type="success" text="已读"></u-tag>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import {
|
||||
getEmptyPaginateObj,
|
||||
getMoreListData
|
||||
} from '@/core/app'
|
||||
import * as Api from '@/api/user/notice.js'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
import {
|
||||
ApplyStatusEnum
|
||||
} from '@/common/enum/dealer/withdraw'
|
||||
|
||||
const pageSize = 15
|
||||
// 提现状态文字
|
||||
const ApplyStatusText = [0, 1]
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
ApplyStatusEnum,
|
||||
ApplyStatusText,
|
||||
// 选项卡列表
|
||||
tabList: [],
|
||||
// 当前选项
|
||||
curTab: 0,
|
||||
// 列表数据
|
||||
list: getEmptyPaginateObj(),
|
||||
shopId: 0,
|
||||
showReasonMsg: false,
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: {
|
||||
size: pageSize
|
||||
},
|
||||
// 数量要大于12条才显示无更多数据
|
||||
noMoreSize: 12,
|
||||
// 空布局
|
||||
empty: {
|
||||
tip: '亲,暂无未读消息'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
this.getSetting()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取分销设置
|
||||
getSetting() {
|
||||
const app = this
|
||||
SettingModel.data()
|
||||
.then(setting => {
|
||||
const words = setting.words.withdraw_list
|
||||
app.setTabList(words.words)
|
||||
})
|
||||
},
|
||||
|
||||
// 设置选项卡数据
|
||||
setTabList(words) {
|
||||
const app = this
|
||||
app.tabList = [
|
||||
{
|
||||
value: 0,
|
||||
name: '未读'
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
name: '已读'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
triggerReasonMsg() {
|
||||
this.showReasonMsg = !this.showReasonMsg
|
||||
},
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
app.getList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
// 获取提现列表
|
||||
getList(pageNo = 1) {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
Api.list({
|
||||
status: app.getTabValue(),
|
||||
page: pageNo
|
||||
})
|
||||
.then(result => {
|
||||
// 合并新数据
|
||||
const newList = result.data.list
|
||||
app.list.data = getMoreListData(newList, app.list, pageNo)
|
||||
resolve(newList)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 获取当前标签项的值
|
||||
getTabValue() {
|
||||
const app = this
|
||||
if (app.tabList.length) {
|
||||
return app.tabList[app.curTab].value
|
||||
}
|
||||
return 0
|
||||
},
|
||||
|
||||
// 切换标签项
|
||||
onChangeTab(index) {
|
||||
const app = this
|
||||
// 设置当前选中的标签
|
||||
app.curTab = index
|
||||
// 刷新订单列表
|
||||
app.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新列表数据
|
||||
onRefreshList() {
|
||||
this.list = getEmptyPaginateObj()
|
||||
setTimeout(() => {
|
||||
this.mescroll.resetUpScroll()
|
||||
}, 120)
|
||||
},
|
||||
|
||||
// 设为已读
|
||||
onRead(id, content) {
|
||||
const app = this
|
||||
uni.showModal({
|
||||
title: '查看消息',
|
||||
content,
|
||||
showCancel: false,
|
||||
success({ confirm }) {
|
||||
Api.status({id}).then(res => {
|
||||
app.getList()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
// 提现明细列表
|
||||
.widget-list {
|
||||
padding: 10rpx 20rpx 40rpx 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.widget__detail {
|
||||
padding: 20rpx 15rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 28rpx;
|
||||
border-bottom: 1rpx solid #e7e7e7;
|
||||
}
|
||||
|
||||
.widget__detail .detail__money {
|
||||
font-size: 30rpx;
|
||||
margin-bottom: 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.widget__detail .detail__reason {
|
||||
margin-top: 15rpx;
|
||||
color: #0f80ff;
|
||||
}
|
||||
|
||||
.show-reason-msg {
|
||||
padding: 20rpx;
|
||||
line-height: 2rem;
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
.detail__left {
|
||||
.iconfont {
|
||||
margin-left: 30rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.icon-weixin {
|
||||
color: #0eaf00;
|
||||
}
|
||||
|
||||
.icon-alipay {
|
||||
color: #0f80ff;
|
||||
}
|
||||
}
|
||||
|
||||
.detail__status {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.detail__money {
|
||||
.content {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
.modal-content{
|
||||
padding: 20rpx;
|
||||
}
|
||||
</style>
|
||||
750
package/deliver/order-center.vue
Normal file
750
package/deliver/order-center.vue
Normal file
@@ -0,0 +1,750 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ native: true }"
|
||||
@down="downCallback" :up="upOption" @up="upCallback">
|
||||
<!-- tab栏 -->
|
||||
<u-tabs :list="tabs" :is-scroll="false" :current="curTab" :active-color="appTheme.mainBg" :duration="0.2"
|
||||
@change="onChangeTab" />
|
||||
<!-- 订单列表 -->
|
||||
<view class="order-list">
|
||||
<block v-for="(item, index) in list.data" :key="index">
|
||||
<view class="shop-name" v-if="item.shopName">
|
||||
<image :src="item.logoUrl" class="shop-name-logo" mode="widthFix"></image>
|
||||
<text>{{ item.shopName }}</text>
|
||||
</view>
|
||||
<view class="order-item">
|
||||
<view class="item-top">
|
||||
<view class="item-top-left">
|
||||
<text class="order-time">{{item.create_time}}</text>
|
||||
</view>
|
||||
<view class="item-top-right">
|
||||
<text class="state-text">{{ item.state_text }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 商品列表 -->
|
||||
<view class="goods-list">
|
||||
<view class="goods-item" v-for="(goods, idx) in item.goods" :key="idx">
|
||||
<!-- 商品图片 -->
|
||||
<view class="goods-image" @click="onTargetDetail(goods.goods_id)">
|
||||
<image class="image" :src="goods.goods_image" mode="scaleToFill"></image>
|
||||
</view>
|
||||
<!-- 商品信息 -->
|
||||
<view class="goods-content">
|
||||
<view class="goods-title"><text class="twoline-hide">{{ goods.goods_name }}</text>
|
||||
</view>
|
||||
<view class="goods-props clearfix">
|
||||
<view class="goods-props-item" v-for="(props, idx) in goods.goods_props"
|
||||
:key="idx">
|
||||
<text>{{ props.value.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 交易信息 -->
|
||||
<view class="goods-trade">
|
||||
<view class="goods-price">
|
||||
<text class="unit">¥</text>
|
||||
<text
|
||||
class="value">{{ goods.is_user_grade ? goods.grade_goods_price : goods.goods_price }}</text>
|
||||
</view>
|
||||
<view class="goods-num">
|
||||
<text>×{{ goods.total_num }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 订单合计 -->
|
||||
<view class="order-total">
|
||||
<!-- <text class="create-time">{{ item.create_time }}</text> -->
|
||||
<!-- <text>共{{ item.total_num }}件商品,总金额</text> -->
|
||||
<!-- <text class="unit">¥</text> -->
|
||||
<text class="money">合计:¥{{ item.pay_price }}</text>
|
||||
</view>
|
||||
<!-- 订单操作 -->
|
||||
<view v-if="item.order_status != OrderStatusEnum.CANCELLED.value" class="order-handle">
|
||||
<view class="btn-group clearfix">
|
||||
<!-- 未接单 -->
|
||||
<block v-if="item.delivery_status == DeliveryStatusEnum.NOT_RECEIVING.value">
|
||||
<view class="btn-box">
|
||||
<u-button size="mini" @click="expressInfo(item.address)">配送地址</u-button>
|
||||
<view style="margin-left: 15rpx;">
|
||||
<u-button type="primary" size="mini" @click="onDelivery(item.order_id)">接单
|
||||
</u-button>
|
||||
</view>
|
||||
<view style="margin-left: 15rpx;">
|
||||
<u-button type="warning" size="mini"
|
||||
@click="offDelivery(item.order_id, item.storePhone)">拒单</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 待签收 -->
|
||||
<block
|
||||
v-if="item.delivery_status == DeliveryStatusEnum.DELIVERED.value && item.receipt_status == ReceiptStatusEnum.NOT_RECEIVED.value">
|
||||
<view class="btn-box2">
|
||||
<view style="margin-left: 15rpx;">
|
||||
<u-button type="primary" size="mini" @click="expressInfo(item.address)">配送地址</u-button>
|
||||
</view>
|
||||
<!-- <view style="margin-left: 15rpx;">
|
||||
<u-button size="mini" @click="offDelivery(item.order_id)">退单</u-button>
|
||||
</view> -->
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!-- 未支付取消订单 -->
|
||||
<!-- <block v-if="item.pay_status == PayStatusEnum.PENDING.value">
|
||||
<view class="btn-item" @click="onCancel(item.order_id)">取消</view>
|
||||
</block> -->
|
||||
<!-- 已支付进行中的订单 -->
|
||||
<!-- <block v-if="item.order_status != OrderStatusEnum.APPLY_CANCEL.value"> -->
|
||||
<!-- <block v-if="item.pay_status == PayStatusEnum.SUCCESS.value && item.delivery_status == DeliveryStatusEnum.NOT_DELIVERED.value">
|
||||
<u-button type="primary" size="mini" class="btn-item" @click="onDelivery(item.order_id)">配送</u-button>
|
||||
</block> -->
|
||||
<!-- 订单核销码 -->
|
||||
<!-- <block v-if="item.pay_status == PayStatusEnum.SUCCESS.value && item.delivery_type == DeliveryTypeEnum.EXTRACT.value
|
||||
&& item.delivery_status == DeliveryStatusEnum.NOT_DELIVERED.value">
|
||||
<view class="btn-item active" @click="onExtractQRCode(item.order_id)">
|
||||
<text class="iconfont icon-qr-extract"></text>
|
||||
<text class="m-l-10">核销码</text>
|
||||
</view>
|
||||
</block> -->
|
||||
<!-- </block> -->
|
||||
<!-- 已申请取消 -->
|
||||
<!-- <view v-else class="f-28 col-8">取消申请中</view> -->
|
||||
<!-- 未支付的订单 -->
|
||||
<!-- <block v-if="item.pay_status == PayStatusEnum.PENDING.value">
|
||||
<view class="btn-item active" @click="onPay(item.order_id)">去支付</view>
|
||||
</block> -->
|
||||
<!-- 确认收货 -->
|
||||
<!-- <block v-if="item.delivery_status == DeliveryStatusEnum.DELIVERED.value && item.receipt_status == ReceiptStatusEnum.NOT_RECEIVED.value">
|
||||
<view class="btn-item active" @click="onReceipt(item.order_id)">确认收货</view>
|
||||
</block> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
<!-- 核销二维码弹窗 -->
|
||||
<u-popup v-model="showQRCodePopup" mode="center" border-radius="26" :closeable="true">
|
||||
<view class="qrcode-popup">
|
||||
<view class="title">自提核销二维码</view>
|
||||
<view class="pop-content">
|
||||
<image v-if="qrcodeImage" class="image" :src="qrcodeImage"></image>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
<!-- 配送信息弹窗 -->
|
||||
<u-popup v-model="showExpressInfo" mode="center" border-radius="26" :closeable="true">
|
||||
<view class="qrcode-popup">
|
||||
<view class="title">配送信息</view>
|
||||
<view class="pop-content2">
|
||||
<text>收货人姓名:{{ address.name }}</text>
|
||||
<text>收货人电话:{{ address.phone }}</text>
|
||||
<text>详细地址:{{ address.detail }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
<!-- 拒单弹窗 -->
|
||||
<u-popup v-model="showOffDeliver" mode="center" border-radius="26" :closeable="true">
|
||||
<view class="qrcode-popup">
|
||||
<view class="title">拒单理由</view>
|
||||
<view class="pop-content2">
|
||||
<u-input v-model="offDeliverInfo" />
|
||||
</view>
|
||||
<view class="btn-box-off-deliver">
|
||||
<u-button type="success" size="mini" @click="callShop">联系商家</u-button>
|
||||
<u-button type="warning" size="mini" @click="onSubmit">确定提交</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
DeliveryStatusEnum,
|
||||
DeliveryTypeEnum,
|
||||
OrderStatusEnum,
|
||||
PayStatusEnum,
|
||||
PayTypeEnum,
|
||||
ReceiptStatusEnum
|
||||
} from '@/common/enum/order'
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import {
|
||||
getEmptyPaginateObj,
|
||||
getMoreListData
|
||||
} from '@/core/app'
|
||||
import * as OrderApi from '@/api/order'
|
||||
import * as UserApi from '@/api/user'
|
||||
import {
|
||||
wxPayment
|
||||
} from '@/core/app'
|
||||
|
||||
// 每页记录数量
|
||||
const pageSize = 15
|
||||
|
||||
// tab栏数据
|
||||
const tabs = [{
|
||||
name: `全部`,
|
||||
value: 'driver'
|
||||
}, {
|
||||
name: `使用中`,
|
||||
value: 'driverDaiJieDan'
|
||||
},
|
||||
// {
|
||||
// name: `待配送`,
|
||||
// value: 'delivery'
|
||||
// },
|
||||
{
|
||||
name: `已过期`,
|
||||
value: 'driverDaiShouHuo'
|
||||
}, {
|
||||
name: `已结束`,
|
||||
value: 'driverOk'
|
||||
}
|
||||
]
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
DeliveryStatusEnum,
|
||||
DeliveryTypeEnum,
|
||||
OrderStatusEnum,
|
||||
PayStatusEnum,
|
||||
PayTypeEnum,
|
||||
ReceiptStatusEnum,
|
||||
|
||||
// 当前页面参数
|
||||
options: {
|
||||
dataType: 'all'
|
||||
},
|
||||
// tab栏数据
|
||||
tabs,
|
||||
// 当前标签索引
|
||||
curTab: 0,
|
||||
// 订单列表数据
|
||||
list: getEmptyPaginateObj(),
|
||||
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: {
|
||||
size: pageSize
|
||||
},
|
||||
// 数量要大于4条才显示无更多数据
|
||||
noMoreSize: 4,
|
||||
// 空布局
|
||||
empty: {
|
||||
tip: '亲,暂无订单记录'
|
||||
}
|
||||
},
|
||||
// 控制首次触发onShow事件时不刷新列表
|
||||
canReset: false,
|
||||
// 核销二维码弹窗
|
||||
showQRCodePopup: false,
|
||||
showExpressInfo: false,
|
||||
showOffDeliver: false,
|
||||
// 核销二维码图片url (通过后端获取)
|
||||
qrcodeImage: '',
|
||||
shopInfo: {},
|
||||
address: {},
|
||||
offDeliverInfo: undefined,
|
||||
storePhone: null
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
// 初始化当前选中的标签
|
||||
this.initCurTab(options)
|
||||
this.getOrderList()
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow() {
|
||||
this.canReset && this.onRefreshList()
|
||||
this.canReset = true
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 初始化当前选中的标签
|
||||
initCurTab(options) {
|
||||
const app = this
|
||||
if (options.dataType) {
|
||||
const index = app.tabs.findIndex(item => item.value == options.dataType)
|
||||
app.curTab = index > -1 ? index : 0
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
app.getOrderList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
// 获取订单列表
|
||||
getOrderList(pageNo = 1) {
|
||||
const app = this
|
||||
const {
|
||||
clerk_id
|
||||
} = uni.getStorageSync('clerkInfo')
|
||||
return new Promise((resolve, reject) => {
|
||||
OrderApi.list({
|
||||
dataType: app.getTabValue(),
|
||||
page: pageNo,
|
||||
driverOrder: true,
|
||||
clerk_id
|
||||
}, {
|
||||
load: false
|
||||
})
|
||||
.then(result => {
|
||||
// 合并新数据
|
||||
const newList = app.initList(result.data.list)
|
||||
app.list.data = getMoreListData(newList, app.list, pageNo)
|
||||
resolve(newList)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 初始化订单列表数据
|
||||
initList(newList) {
|
||||
newList.data.forEach(item => {
|
||||
item.total_num = 0
|
||||
item.goods.forEach(goods => {
|
||||
item.total_num += goods.total_num
|
||||
})
|
||||
})
|
||||
return newList
|
||||
},
|
||||
|
||||
// 获取当前标签项的值
|
||||
getTabValue() {
|
||||
return this.tabs[this.curTab].value
|
||||
},
|
||||
|
||||
// 切换标签项
|
||||
onChangeTab(index) {
|
||||
const app = this
|
||||
// 设置当前选中的标签
|
||||
app.curTab = index
|
||||
// 刷新订单列表
|
||||
app.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新订单列表
|
||||
onRefreshList() {
|
||||
this.list = getEmptyPaginateObj()
|
||||
setTimeout(() => {
|
||||
this.mescroll.resetUpScroll()
|
||||
}, 120)
|
||||
},
|
||||
|
||||
// 取消订单
|
||||
onCancel(orderId) {
|
||||
const app = this
|
||||
uni.showModal({
|
||||
title: '友情提示',
|
||||
content: '确认要取消该订单吗?',
|
||||
success(o) {
|
||||
if (o.confirm) {
|
||||
OrderApi.cancel(orderId)
|
||||
.then(result => {
|
||||
// 显示成功信息
|
||||
app.$toast(result.message)
|
||||
// 刷新订单列表
|
||||
app.onRefreshList()
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onDelivery(orderId) {
|
||||
const app = this
|
||||
OrderApi.onDeliver(orderId).then(result => {
|
||||
// 显示成功信息
|
||||
app.$success(result.message)
|
||||
// 刷新订单列表
|
||||
app.onRefreshList()
|
||||
})
|
||||
},
|
||||
|
||||
offDelivery(orderId, storePhone) {
|
||||
this.showOffDeliver = true
|
||||
this.orderId = orderId
|
||||
this.storePhone = storePhone
|
||||
},
|
||||
|
||||
callShop() {
|
||||
const {
|
||||
storePhone
|
||||
} = this
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: storePhone
|
||||
})
|
||||
},
|
||||
|
||||
onSubmit() {
|
||||
const app = this
|
||||
const {
|
||||
orderId,
|
||||
offDeliverInfo
|
||||
} = this
|
||||
OrderApi.offDeliver(orderId, {
|
||||
offDeliverInfo
|
||||
}).then(result => {
|
||||
app.showOffDeliver = false
|
||||
// 显示成功信息
|
||||
app.$success(result.message)
|
||||
// 刷新订单列表
|
||||
app.onRefreshList()
|
||||
})
|
||||
},
|
||||
|
||||
doOffDelivery() {
|
||||
OrderApi.offDeliver(orderId).then(result => {
|
||||
// 显示成功信息
|
||||
app.$success(result.message)
|
||||
// 刷新订单列表
|
||||
app.onRefreshList()
|
||||
})
|
||||
// uni.showModal({
|
||||
// title: '拒单理由',
|
||||
// content: '退单后将返回商家后台重新派单!',
|
||||
// success(o) {
|
||||
// if (o.confirm) {
|
||||
// OrderApi.offDeliver(orderId).then(result => {
|
||||
// // 显示成功信息
|
||||
// app.$success(result.message)
|
||||
// // 刷新订单列表
|
||||
// app.onRefreshList()
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
},
|
||||
|
||||
expressInfo(address) {
|
||||
this.showExpressInfo = true
|
||||
this.address = address
|
||||
console.log(address);
|
||||
},
|
||||
|
||||
// 确认收货
|
||||
onReceipt(orderId) {
|
||||
const app = this
|
||||
uni.showModal({
|
||||
title: '友情提示',
|
||||
content: '确认收到商品了吗?',
|
||||
success(o) {
|
||||
if (o.confirm) {
|
||||
OrderApi.receipt(orderId)
|
||||
.then(result => {
|
||||
// 显示成功信息
|
||||
app.$success(result.message)
|
||||
// 刷新订单列表
|
||||
app.onRefreshList()
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 获取核销二维码
|
||||
onExtractQRCode(orderId) {
|
||||
const app = this
|
||||
OrderApi.extractQrcode(orderId, {
|
||||
channel: app.platform
|
||||
})
|
||||
.then(result => {
|
||||
app.qrcodeImage = result.data.qrcode
|
||||
app.showQRCodePopup = true
|
||||
})
|
||||
},
|
||||
|
||||
// 点击去支付
|
||||
onPay(orderId) {
|
||||
this.$navTo('pages/checkout/cashier/index', {
|
||||
orderId
|
||||
})
|
||||
},
|
||||
|
||||
// 跳转到订单详情页
|
||||
handleTargetDetail(orderId) {
|
||||
this.$navTo('pages/order/detail', {
|
||||
orderId
|
||||
})
|
||||
},
|
||||
|
||||
// 跳转到订单评价页
|
||||
handleTargetComment(orderId) {
|
||||
this.$navTo('pages/order/comment/index', {
|
||||
orderId
|
||||
})
|
||||
},
|
||||
|
||||
// 跳转商品详情页
|
||||
onTargetDetail(goodsId) {
|
||||
this.$navTo('pages/goods/detail', {
|
||||
goodsId
|
||||
})
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.shop-name {
|
||||
width: 720rpx;
|
||||
margin: auto;
|
||||
height: 50rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
font-weight: bold;
|
||||
|
||||
.shop-name-logo {
|
||||
width: 36rpx !important;
|
||||
height: 36rpx !important;
|
||||
border: 1rpx solid #ffffff;
|
||||
border-radius: 100%;
|
||||
margin: 0 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 项目内容
|
||||
.order-item {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 30rpx 30rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
// 项目顶部
|
||||
.item-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 26rpx;
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
.store-house {
|
||||
font-weight: bold;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.order-time {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.state-text {
|
||||
color: $main-bg;
|
||||
}
|
||||
}
|
||||
|
||||
// 商品列表
|
||||
.goods-list {
|
||||
|
||||
// 商品项
|
||||
.goods-item {
|
||||
display: flex;
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
// 商品图片
|
||||
.goods-image {
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 商品内容
|
||||
.goods-content {
|
||||
flex: 1;
|
||||
padding-left: 16rpx;
|
||||
padding-top: 16rpx;
|
||||
|
||||
.goods-title {
|
||||
font-size: 26rpx;
|
||||
max-height: 76rpx;
|
||||
}
|
||||
|
||||
.goods-props {
|
||||
margin-top: 14rpx;
|
||||
height: 40rpx;
|
||||
color: #ababab;
|
||||
font-size: 24rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.goods-props-item {
|
||||
display: inline-block;
|
||||
margin-right: 14rpx;
|
||||
padding: 4rpx 16rpx;
|
||||
border-radius: 12rpx;
|
||||
background-color: #F5F5F5;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 交易信息
|
||||
.goods-trade {
|
||||
padding-top: 16rpx;
|
||||
width: 150rpx;
|
||||
text-align: right;
|
||||
color: $uni-text-color-grey;
|
||||
font-size: 26rpx;
|
||||
|
||||
.goods-price {
|
||||
vertical-align: bottom;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
.unit {
|
||||
margin-right: -2rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 订单合计
|
||||
.order-total {
|
||||
font-size: 26rpx;
|
||||
vertical-align: bottom;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 40rpx;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.create-time {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.unit {
|
||||
margin-left: 8rpx;
|
||||
margin-right: -2rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.money {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 订单操作
|
||||
.order-handle {
|
||||
.btn-group {
|
||||
.btn-box {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 12rpx 0;
|
||||
}
|
||||
|
||||
.btn-box2 {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
border-radius: 10rpx;
|
||||
padding: 6rpx 20rpx;
|
||||
margin-left: 15rpx;
|
||||
font-size: 28rpx;
|
||||
float: right;
|
||||
|
||||
&:last-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
border: 1rpx solid $main-bg;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 弹出层 - 核销二维码
|
||||
.qrcode-popup {
|
||||
width: 700rpx;
|
||||
padding: 36rpx 30rpx;
|
||||
|
||||
.btn-box-off-deliver {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 10rpx !important;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 30rpx;
|
||||
margin-bottom: 26rpx;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pop-content {
|
||||
min-height: 260rpx;
|
||||
padding: 0 10rpx;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 510rpx;
|
||||
height: 510rpx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.pop-content2 {
|
||||
min-height: 120rpx;
|
||||
padding: 0 10rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #f3f3f3;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 510rpx;
|
||||
height: 510rpx;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
460
package/equipment/cashier/index.vue
Executable file
460
package/equipment/cashier/index.vue
Executable file
@@ -0,0 +1,460 @@
|
||||
<template>
|
||||
<view v-if="!isLoading" class="container" :style="appThemeStyle">
|
||||
<!-- 订单信息 -->
|
||||
<view class="order-info">
|
||||
<!-- 支付剩余时间 -->
|
||||
<view class="order-countdown">
|
||||
<text class="m-r-6">剩余时间</text>
|
||||
<count-down :date="order.expirationTime" separator="zh" theme="text" />
|
||||
</view>
|
||||
<!-- 付款金额 -->
|
||||
<view class="order-amount">
|
||||
<text class="unit">¥</text>
|
||||
<text class="amount">{{ order.pay_price }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付方式 -->
|
||||
<view class="payment-method">
|
||||
<view v-for="(item, index) in methods" :key="index" class="pay-item dis-flex flex-x-between" @click="handleSelectPayType(index)">
|
||||
<view class="item-left dis-flex flex-y-center">
|
||||
<view class="item-left_icon" :class="[item.method]">
|
||||
<text class="iconfont" :class="[PayMethodIconEnum[item.method]]"></text>
|
||||
</view>
|
||||
<view class="item-left_text">
|
||||
<text>{{ PayMethodEnum[item.method].name }}</text>
|
||||
</view>
|
||||
<view v-if="item.method === PayMethodEnum.BALANCE.value" class="user-balance">
|
||||
<text>(可用¥{{ personal.balance }}元)</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-right col-m" v-if="curPaymentItem && curPaymentItem.method == item.method">
|
||||
<text class="iconfont icon-check"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 确认按钮 -->
|
||||
<view class="footer-fixed">
|
||||
<view class="btn-wrapper">
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">确认支付</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付确认弹窗 -->
|
||||
<!-- #ifdef H5 -->
|
||||
<u-modal v-if="tempUnifyData" v-model="showConfirmModal" title="支付确认" show-cancel-button confirm-text="已完成支付"
|
||||
:confirm-color="appTheme.mainBg" negative-top="100" :asyncClose="true"
|
||||
@confirm="onTradeQuery(tempUnifyData.outTradeNo, tempUnifyData.method)">
|
||||
<view class="modal-content">
|
||||
<text>请在{{ PayMethodClientNameEnum[tempUnifyData.method] }}内完成支付,如果您已经支付成功,请点击“已完成支付”按钮</text>
|
||||
</view>
|
||||
</u-modal>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from '@/utils/storage'
|
||||
import { inArray, urlEncode } from '@/utils/util'
|
||||
import { Alipay, Wechat } from '@/core/payment'
|
||||
import CountDown from '@/components/countdown'
|
||||
import { PayMethodEnum } from '@/common/enum/payment'
|
||||
import { PayStatusEnum } from '@/common/enum/order'
|
||||
import * as Api from '@/api/solution/cashier.js'
|
||||
|
||||
// 支付方式对应的图标
|
||||
const PayMethodIconEnum = {
|
||||
[PayMethodEnum.WECHAT.value]: 'icon-wechat-pay',
|
||||
[PayMethodEnum.ALIPAY.value]: 'icon-alipay',
|
||||
[PayMethodEnum.BALANCE.value]: 'icon-balance-pay'
|
||||
}
|
||||
|
||||
// 支付方式的终端名称
|
||||
const PayMethodClientNameEnum = {
|
||||
[PayMethodEnum.WECHAT.value]: '微信',
|
||||
[PayMethodEnum.ALIPAY.value]: '支付宝'
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CountDown
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 加载中
|
||||
isLoading: true,
|
||||
// 确认按钮禁用
|
||||
disabled: false,
|
||||
// 枚举类
|
||||
PayMethodEnum,
|
||||
PayMethodIconEnum,
|
||||
PayMethodClientNameEnum,
|
||||
// 当前选中的支付方式
|
||||
curPaymentItem: null,
|
||||
// 当前订单ID
|
||||
orderId: null,
|
||||
// 当前结算订单信息
|
||||
order: {},
|
||||
// 个人信息
|
||||
personal: { balance: '0.00' },
|
||||
// 当前客户端的支付方式列表(后端根据platform判断)
|
||||
methods: [],
|
||||
// 支付确认弹窗
|
||||
showConfirmModal: false,
|
||||
// #ifdef H5
|
||||
// 当前微信支付信息 (临时数据, 仅用于H5端)
|
||||
tempUnifyData: { outTradeNo: '', method: '' },
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad({ orderId }) {
|
||||
// 记录订单ID
|
||||
this.orderId = Number(orderId)
|
||||
// 获取收银台信息
|
||||
this.getCashierInfo()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取收银台信息
|
||||
getCashierInfo() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
Api.orderInfo()
|
||||
.then(result => {
|
||||
app.order = result.data.order
|
||||
app.personal = result.data.personal
|
||||
app.methods = result.data.paymentMethods
|
||||
app.isLoading = false
|
||||
app.setDefaultPayType()
|
||||
app.checkOrderPayStatus()
|
||||
// #ifdef H5
|
||||
// 判断当前页面来源于浏览器返回
|
||||
this.performance()
|
||||
// #endif
|
||||
})
|
||||
},
|
||||
|
||||
// 设置默认的支付方式
|
||||
setDefaultPayType() {
|
||||
const app = this
|
||||
if (app.disabled) return
|
||||
const defaultIndex = app.methods.findIndex(item => item.is_default == true)
|
||||
defaultIndex > -1 && app.handleSelectPayType(defaultIndex)
|
||||
},
|
||||
|
||||
// 判断当前订单是否为已支付
|
||||
checkOrderPayStatus() {
|
||||
const app = this
|
||||
if (app.order.pay_status == PayStatusEnum.SUCCESS.value) {
|
||||
app.$toast('恭喜您,订单已付款成功')
|
||||
app.onSuccessNav()
|
||||
}
|
||||
},
|
||||
|
||||
// 选择支付方式
|
||||
handleSelectPayType(index) {
|
||||
this.curPaymentItem = this.methods[index]
|
||||
},
|
||||
|
||||
// 判断当前页面来源于浏览器返回
|
||||
// #ifdef H5
|
||||
performance() {
|
||||
const app = this
|
||||
// 判断订单状态, 异步回调会将订单状态变为已支付, 那么就不需要让用户手动查单了
|
||||
if (app.order.pay_status == PayStatusEnum.PENDING.value) {
|
||||
app.alipayPerformance()
|
||||
app.wechatPerformance()
|
||||
}
|
||||
},
|
||||
|
||||
// H5端支付宝支付完成跳转回当前页面时触发
|
||||
alipayPerformance() {
|
||||
const app = this
|
||||
app.tempUnifyData = Alipay.performance()
|
||||
if (app.tempUnifyData) {
|
||||
app.onTradeQuery(app.tempUnifyData.outTradeNo, app.tempUnifyData.method)
|
||||
}
|
||||
},
|
||||
|
||||
// H5端微信支付完成或返回时触发
|
||||
wechatPerformance() {
|
||||
const app = this
|
||||
app.tempUnifyData = Wechat.performance(app.orderId)
|
||||
if (app.tempUnifyData) {
|
||||
app.showConfirmModal = true
|
||||
}
|
||||
},
|
||||
// #endif
|
||||
|
||||
// 确认支付
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
// 判断是否选择了支付方式
|
||||
if (!app.curPaymentItem) {
|
||||
app.$toast('您还没有选择支付方式')
|
||||
return
|
||||
}
|
||||
// 按钮禁用
|
||||
if (app.disabled) return
|
||||
app.disabled = true
|
||||
// 提交到后端API
|
||||
Api.orderPay(app.orderId, {
|
||||
method: app.curPaymentItem.method,
|
||||
client: app.platform,
|
||||
extra: app.getExtraAsUnify(app.curPaymentItem.method)
|
||||
})
|
||||
.then(result => app.onSubmitCallback(result))
|
||||
.finally(err => {
|
||||
setTimeout(() => app.disabled = false, 10)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取第三方支付的扩展参数
|
||||
getExtraAsUnify(method) {
|
||||
if (method === PayMethodEnum.ALIPAY.value) {
|
||||
return Alipay.extraAsUnify()
|
||||
}
|
||||
if (method === PayMethodEnum.WECHAT.value) {
|
||||
return Wechat.extraAsUnify()
|
||||
}
|
||||
return {}
|
||||
},
|
||||
|
||||
// 订单提交成功后回调
|
||||
onSubmitCallback(result) {
|
||||
const app = this
|
||||
const method = app.curPaymentItem.method
|
||||
const paymentData = result.data.payment
|
||||
// 余额支付
|
||||
if (method === PayMethodEnum.BALANCE.value) {
|
||||
app.onShowSuccess(result)
|
||||
}
|
||||
// 发起支付宝支付
|
||||
if (method === PayMethodEnum.ALIPAY.value) {
|
||||
console.log('paymentData', paymentData)
|
||||
Alipay.payment(paymentData)
|
||||
.then(res => app.onPaySuccess(res))
|
||||
.catch(err => app.onPayFail(err))
|
||||
}
|
||||
// 发起微信支付
|
||||
if (method === PayMethodEnum.WECHAT.value) {
|
||||
console.log('paymentData', paymentData)
|
||||
Wechat.payment({ orderKey: app.orderId, ...paymentData })
|
||||
.then(res => app.onPaySuccess(res))
|
||||
.catch(err => app.onPayFail(err))
|
||||
}
|
||||
},
|
||||
|
||||
// 订单支付成功的回调方法
|
||||
// 这里只是前端支付api返回结果success,实际订单是否支付成功 以后端的查单和异步通知为准
|
||||
onPaySuccess({ res, option: { isRequireQuery, outTradeNo, method } }) {
|
||||
const app = this
|
||||
// 判断是否需要主动查单
|
||||
// isRequireQuery为true代表需要主动查单
|
||||
if (isRequireQuery) {
|
||||
app.onTradeQuery(outTradeNo, method)
|
||||
return true
|
||||
}
|
||||
this.onShowSuccess(res)
|
||||
},
|
||||
|
||||
// 显示支付成功信息并页面跳转
|
||||
onShowSuccess({ message }) {
|
||||
this.$toast(message || '订单支付成功')
|
||||
this.onSuccessNav()
|
||||
},
|
||||
|
||||
// 订单支付失败
|
||||
onPayFail(err) {
|
||||
console.log('onPayFail', err)
|
||||
const errMsg = err.message || '订单未支付'
|
||||
this.$error(errMsg)
|
||||
},
|
||||
|
||||
// 已完成支付按钮事件: 请求后端查单
|
||||
onTradeQuery(outTradeNo, method) {
|
||||
const app = this
|
||||
// 交易查询
|
||||
// 查询第三方支付订单是否付款成功
|
||||
Api.tradeQuery({ outTradeNo, method, client: app.platform })
|
||||
.then(result => result.data.isPay ? app.onShowSuccess(result) : app.onPayFail(result))
|
||||
.finally(() => app.showConfirmModal = false)
|
||||
},
|
||||
|
||||
// 支付成功后的跳转
|
||||
onSuccessNav() {
|
||||
const pages = getCurrentPages()
|
||||
const lastPage = pages.length < 2 ? null : pages[pages.length - 2]
|
||||
const backRoutes = [
|
||||
// 'package/equipment/index',
|
||||
'package/equipment/detail'
|
||||
]
|
||||
if (lastPage && inArray(lastPage.route, backRoutes)) {
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1000)
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
this.$navTo('pages/order/index', {}, 'redirectTo')
|
||||
}, 1200)
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #F4F4F4;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
background-color: #F4F4F4;
|
||||
}
|
||||
|
||||
// 订单信息
|
||||
.order-info {
|
||||
padding: 80rpx 0;
|
||||
text-align: center;
|
||||
|
||||
.order-countdown {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.order-amount {
|
||||
margin: 0 auto;
|
||||
max-width: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #111111;
|
||||
|
||||
.unit {
|
||||
font-size: 30rpx;
|
||||
margin-bottom: -18rpx;
|
||||
}
|
||||
|
||||
.amount {
|
||||
font-size: 56rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 支付方式
|
||||
.payment-method {
|
||||
width: 94%;
|
||||
margin: 0 auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 20rpx;
|
||||
|
||||
.pay-item {
|
||||
padding: 26rpx 0;
|
||||
font-size: 28rpx;
|
||||
border-bottom: 1rpx solid rgb(248, 248, 248);
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.item-left_icon {
|
||||
margin-right: 20rpx;
|
||||
font-size: 44rpx;
|
||||
|
||||
&.wechat {
|
||||
color: #00c800;
|
||||
}
|
||||
|
||||
&.alipay {
|
||||
color: #009fe8;
|
||||
}
|
||||
|
||||
&.balance {
|
||||
color: #ff9700;
|
||||
}
|
||||
}
|
||||
|
||||
.item-left_text {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.item-right {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.user-balance {
|
||||
margin-left: 20rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 支付确认弹窗
|
||||
.modal-content {
|
||||
padding: 40rpx 48rpx;
|
||||
font-size: 30rpx;
|
||||
line-height: 50rpx;
|
||||
text-align: left;
|
||||
color: #606266;
|
||||
// height: 620rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
// 底部操作栏
|
||||
.footer-fixed {
|
||||
position: fixed;
|
||||
bottom: var(--window-bottom);
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 11;
|
||||
box-shadow: 0 -4rpx 40rpx 0 rgba(151, 151, 151, 0.24);
|
||||
background: #fff;
|
||||
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
|
||||
.btn-wrapper {
|
||||
height: 120rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 40rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 80rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
718
package/equipment/checkout/index.vue
Executable file
718
package/equipment/checkout/index.vue
Executable file
@@ -0,0 +1,718 @@
|
||||
<template>
|
||||
<view v-if="!isLoading" class="container" :style="appThemeStyle">
|
||||
|
||||
<!-- 订单信息 -->
|
||||
<view class="order-info">
|
||||
<!-- 支付剩余时间 -->
|
||||
<view class="order-countdown">
|
||||
<text class="m-r-6">剩余时间</text>
|
||||
<count-down :date="order.expirationTime" separator="zh" theme="text" />
|
||||
</view>
|
||||
<!-- 付款金额 -->
|
||||
<view class="order-amount">
|
||||
<text class="unit">¥</text>
|
||||
<text class="amount">{{ 300 + Number(order.pay_price) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="checkout-item">
|
||||
<view class="head-info">
|
||||
<view class="title">订单信息</view>
|
||||
</view>
|
||||
<view class="line"></view>
|
||||
<view class="goods-info">
|
||||
<image class="image" src="../../../static/order/status/wait_deliver.png" mode="widthFix"></image>
|
||||
<view class="goods-info-box">
|
||||
<view class="title">云芯威72v50AH锂电池</view>
|
||||
<view class="desc">归属门店:白沙店</view>
|
||||
<view class="desc">租赁时长:3个月</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="line"></view>
|
||||
<view class="contacts">
|
||||
<view class="bms-info">
|
||||
<view class="item">
|
||||
<text>电池租金:</text>
|
||||
<text>300元</text>
|
||||
</view>
|
||||
<view class="item">
|
||||
<text>电池押金:</text>
|
||||
<text>300元</text>
|
||||
</view>
|
||||
<view class="item">
|
||||
<text>电池保险:</text>
|
||||
<text>30元</text>
|
||||
</view>
|
||||
<view class="item">
|
||||
<text>合计:</text>
|
||||
<text class="totao-price">¥{{ 300 + Number(order.pay_price) }}元</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="line"></view>
|
||||
<view class="form-license dis-flex flex-x-center flex-y-center">
|
||||
<view class="license-radio dis-flex flex-y-center" @click="setIsRead">
|
||||
<text class="license-icon f-38 iconfont icon-radio"
|
||||
:class="[isRead ? 'c-violet' : 'col-bb']"></text>
|
||||
<text class="f-28 col-80">我已阅读并同意</text>
|
||||
</view>
|
||||
<text @click="handleShowLicense(0)" class="f-28 c-violet f-blue">{{ xieyiText[0] }}</text>
|
||||
<text class="f-28 c-violet">与</text>
|
||||
<text @click="handleShowLicense(1)" class="f-28 c-violet f-blue">{{ xieyiText[1] }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付方式 -->
|
||||
<view class="payment-method">
|
||||
<view v-for="(item, index) in methods" :key="index" class="pay-item dis-flex flex-x-between"
|
||||
@click="handleSelectPayType(index)">
|
||||
<view class="item-left dis-flex flex-y-center">
|
||||
<view class="item-left_icon" :class="[item.method]">
|
||||
<text class="iconfont" :class="[PayMethodIconEnum[item.method]]"></text>
|
||||
</view>
|
||||
<view class="item-left_text">
|
||||
<text>{{ PayMethodEnum[item.method].name }}</text>
|
||||
</view>
|
||||
<view v-if="item.method === PayMethodEnum.BALANCE.value" class="user-balance">
|
||||
<text>(可用¥{{ personal.balance }}元)</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-right col-m" v-if="curPaymentItem && curPaymentItem.method == item.method">
|
||||
<text class="iconfont icon-check"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 确认按钮 -->
|
||||
<view class="footer-fixed">
|
||||
<view class="btn-wrapper">
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">确认支付</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付确认弹窗 -->
|
||||
<!-- #ifdef H5 -->
|
||||
<u-modal v-if="tempUnifyData" v-model="showConfirmModal" title="支付确认" show-cancel-button confirm-text="已完成支付"
|
||||
:confirm-color="appTheme.mainBg" negative-top="100" :asyncClose="true"
|
||||
@confirm="onTradeQuery(tempUnifyData.outTradeNo, tempUnifyData.method)">
|
||||
<view class="modal-content">
|
||||
<text>请在{{ PayMethodClientNameEnum[tempUnifyData.method] }}内完成支付,如果您已经支付成功,请点击“已完成支付”按钮</text>
|
||||
</view>
|
||||
</u-modal>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- 入驻协议弹窗 -->
|
||||
<u-modal v-model="showLicense" :title="xieyiText[showConfirmIndex]">
|
||||
<scroll-view class="pops-content" :scroll-y="true">
|
||||
<text v-if="showConfirmIndex == 0">{{ license }}</text>
|
||||
<text v-if="showConfirmIndex == 1">{{ license1 }}</text>
|
||||
</scroll-view>
|
||||
</u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from '@/utils/storage'
|
||||
import {
|
||||
inArray,
|
||||
urlEncode
|
||||
} from '@/utils/util'
|
||||
import {
|
||||
Alipay,
|
||||
Wechat
|
||||
} from '@/core/payment'
|
||||
import CountDown from '@/components/countdown'
|
||||
import {
|
||||
PayMethodEnum
|
||||
} from '@/common/enum/payment'
|
||||
import {
|
||||
PayStatusEnum
|
||||
} from '@/common/enum/order'
|
||||
import * as Api from '@/api/solution/cashier.js'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
|
||||
// 支付方式对应的图标
|
||||
const PayMethodIconEnum = {
|
||||
[PayMethodEnum.WECHAT.value]: 'icon-wechat-pay',
|
||||
[PayMethodEnum.ALIPAY.value]: 'icon-alipay',
|
||||
[PayMethodEnum.BALANCE.value]: 'icon-balance-pay'
|
||||
}
|
||||
|
||||
// 支付方式的终端名称
|
||||
const PayMethodClientNameEnum = {
|
||||
[PayMethodEnum.WECHAT.value]: '微信',
|
||||
[PayMethodEnum.ALIPAY.value]: '支付宝'
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CountDown
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 加载中
|
||||
isLoading: true,
|
||||
// 确认按钮禁用
|
||||
disabled: true,
|
||||
// 枚举类
|
||||
PayMethodEnum,
|
||||
PayMethodIconEnum,
|
||||
PayMethodClientNameEnum,
|
||||
// 当前选中的支付方式
|
||||
curPaymentItem: null,
|
||||
// 当前订单ID
|
||||
orderId: null,
|
||||
// 当前结算订单信息
|
||||
order: {},
|
||||
// 显示入驻协议弹窗
|
||||
showLicense: false,
|
||||
// 个人信息
|
||||
personal: {
|
||||
balance: '0.00'
|
||||
},
|
||||
// 入驻协议阅读状态
|
||||
isRead: false,
|
||||
// 当前客户端的支付方式列表(后端根据platform判断)
|
||||
methods: [],
|
||||
setting: {},
|
||||
// 文字设置
|
||||
words: undefined,
|
||||
// 显示入驻协议弹窗
|
||||
// 租赁服务协议
|
||||
license: undefined,
|
||||
// 隐私协议
|
||||
license1: undefined,
|
||||
// 支付确认弹窗
|
||||
showConfirmModal: false,
|
||||
showConfirmIndex: 0,
|
||||
xieyiText: ["《租赁协议》", "《隐私协议》"],
|
||||
// #ifdef H5
|
||||
// 当前微信支付信息 (临时数据, 仅用于H5端)
|
||||
tempUnifyData: {
|
||||
outTradeNo: '',
|
||||
method: ''
|
||||
},
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad({
|
||||
orderId
|
||||
}) {
|
||||
// 记录订单ID
|
||||
this.orderId = Number(orderId)
|
||||
// 获取收银台信息
|
||||
this.getCashierInfo()
|
||||
// 获取设置信息
|
||||
this.getSetting()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取分销设置
|
||||
getSetting() {
|
||||
const app = this
|
||||
SettingModel.data()
|
||||
.then(setting => {
|
||||
// 赋值属性
|
||||
app.words = setting.words.apply.words
|
||||
app.background = setting.background.apply
|
||||
app.license = setting.license.license
|
||||
app.license1 = setting.license.license1
|
||||
// 设置当前页面标题
|
||||
app.setPageTitle(setting.words.apply.title)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取收银台信息
|
||||
getCashierInfo() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
Api.orderInfo()
|
||||
.then(result => {
|
||||
app.order = result.data.order
|
||||
app.personal = result.data.personal
|
||||
app.methods = result.data.paymentMethods
|
||||
app.isLoading = false
|
||||
app.setDefaultPayType()
|
||||
app.checkOrderPayStatus()
|
||||
// #ifdef H5
|
||||
// 判断当前页面来源于浏览器返回
|
||||
this.performance()
|
||||
// #endif
|
||||
})
|
||||
},
|
||||
|
||||
// 设置默认的支付方式
|
||||
setDefaultPayType() {
|
||||
const app = this
|
||||
if (app.disabled) return
|
||||
const defaultIndex = app.methods.findIndex(item => item.is_default == true)
|
||||
defaultIndex > -1 && app.handleSelectPayType(defaultIndex)
|
||||
},
|
||||
|
||||
// 判断当前订单是否为已支付
|
||||
checkOrderPayStatus() {
|
||||
const app = this
|
||||
if (app.order.pay_status == PayStatusEnum.SUCCESS.value) {
|
||||
app.$toast('恭喜您,订单已付款成功')
|
||||
app.onSuccessNav()
|
||||
}
|
||||
},
|
||||
|
||||
// 显示入驻协议弹窗
|
||||
handleShowLicense(index) {
|
||||
this.showLicense = true
|
||||
this.showConfirmIndex = index
|
||||
},
|
||||
|
||||
// 选择支付方式
|
||||
handleSelectPayType(index) {
|
||||
this.curPaymentItem = this.methods[index]
|
||||
},
|
||||
|
||||
// 判断当前页面来源于浏览器返回
|
||||
// #ifdef H5
|
||||
performance() {
|
||||
const app = this
|
||||
// 判断订单状态, 异步回调会将订单状态变为已支付, 那么就不需要让用户手动查单了
|
||||
if (app.order.pay_status == PayStatusEnum.PENDING.value) {
|
||||
app.alipayPerformance()
|
||||
app.wechatPerformance()
|
||||
}
|
||||
},
|
||||
|
||||
// H5端支付宝支付完成跳转回当前页面时触发
|
||||
alipayPerformance() {
|
||||
const app = this
|
||||
app.tempUnifyData = Alipay.performance()
|
||||
if (app.tempUnifyData) {
|
||||
app.onTradeQuery(app.tempUnifyData.outTradeNo, app.tempUnifyData.method)
|
||||
}
|
||||
},
|
||||
|
||||
// H5端微信支付完成或返回时触发
|
||||
wechatPerformance() {
|
||||
const app = this
|
||||
app.tempUnifyData = Wechat.performance(app.orderId)
|
||||
if (app.tempUnifyData) {
|
||||
app.showConfirmModal = true
|
||||
}
|
||||
},
|
||||
// #endif
|
||||
|
||||
// 确认支付
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
// 判断是否选择了支付方式
|
||||
if (!app.curPaymentItem) {
|
||||
app.$toast('您还没有同意租赁协议或选择支付方式')
|
||||
return
|
||||
}
|
||||
// 按钮禁用
|
||||
if (app.disabled) return
|
||||
app.disabled = true
|
||||
// 提交到后端API
|
||||
Api.orderPay(app.orderId, {
|
||||
method: app.curPaymentItem.method,
|
||||
client: app.platform,
|
||||
extra: app.getExtraAsUnify(app.curPaymentItem.method)
|
||||
})
|
||||
.then(result => app.onSubmitCallback(result))
|
||||
.finally(err => {
|
||||
setTimeout(() => app.disabled = false, 10)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取第三方支付的扩展参数
|
||||
getExtraAsUnify(method) {
|
||||
if (method === PayMethodEnum.ALIPAY.value) {
|
||||
return Alipay.extraAsUnify()
|
||||
}
|
||||
if (method === PayMethodEnum.WECHAT.value) {
|
||||
return Wechat.extraAsUnify()
|
||||
}
|
||||
return {}
|
||||
},
|
||||
|
||||
// 订单提交成功后回调
|
||||
onSubmitCallback(result) {
|
||||
const app = this
|
||||
const method = app.curPaymentItem.method
|
||||
const paymentData = result.data.payment
|
||||
// 余额支付
|
||||
if (method === PayMethodEnum.BALANCE.value) {
|
||||
app.onShowSuccess(result)
|
||||
}
|
||||
// 发起支付宝支付
|
||||
if (method === PayMethodEnum.ALIPAY.value) {
|
||||
console.log('paymentData', paymentData)
|
||||
Alipay.payment(paymentData)
|
||||
.then(res => app.onPaySuccess(res))
|
||||
.catch(err => app.onPayFail(err))
|
||||
}
|
||||
// 发起微信支付
|
||||
if (method === PayMethodEnum.WECHAT.value) {
|
||||
console.log('paymentData', paymentData)
|
||||
Wechat.payment({
|
||||
orderKey: app.orderId,
|
||||
...paymentData
|
||||
})
|
||||
.then(res => app.onPaySuccess(res))
|
||||
.catch(err => app.onPayFail(err))
|
||||
}
|
||||
},
|
||||
|
||||
// 订单支付成功的回调方法
|
||||
// 这里只是前端支付api返回结果success,实际订单是否支付成功 以后端的查单和异步通知为准
|
||||
onPaySuccess({
|
||||
res,
|
||||
option: {
|
||||
isRequireQuery,
|
||||
outTradeNo,
|
||||
method
|
||||
}
|
||||
}) {
|
||||
const app = this
|
||||
// 判断是否需要主动查单
|
||||
// isRequireQuery为true代表需要主动查单
|
||||
if (isRequireQuery) {
|
||||
app.onTradeQuery(outTradeNo, method)
|
||||
return true
|
||||
}
|
||||
this.onShowSuccess(res)
|
||||
},
|
||||
|
||||
// 显示支付成功信息并页面跳转
|
||||
onShowSuccess({
|
||||
message
|
||||
}) {
|
||||
this.$toast(message || '订单支付成功')
|
||||
this.onSuccessNav()
|
||||
},
|
||||
|
||||
setIsRead(){
|
||||
this.isRead = true
|
||||
this.disabled = false
|
||||
},
|
||||
|
||||
// 订单支付失败
|
||||
onPayFail(err) {
|
||||
console.log('onPayFail', err)
|
||||
const errMsg = err.message || '订单未支付'
|
||||
this.$error(errMsg)
|
||||
},
|
||||
|
||||
// 已完成支付按钮事件: 请求后端查单
|
||||
onTradeQuery(outTradeNo, method) {
|
||||
const app = this
|
||||
// 交易查询
|
||||
// 查询第三方支付订单是否付款成功
|
||||
Api.tradeQuery({
|
||||
outTradeNo,
|
||||
method,
|
||||
client: app.platform
|
||||
})
|
||||
.then(result => result.data.isPay ? app.onShowSuccess(result) : app.onPayFail(result))
|
||||
.finally(() => app.showConfirmModal = false)
|
||||
},
|
||||
|
||||
// 支付成功后的跳转
|
||||
onSuccessNav() {
|
||||
const pages = getCurrentPages()
|
||||
const lastPage = pages.length < 2 ? null : pages[pages.length - 2]
|
||||
const backRoutes = [
|
||||
// 'package/equipment/index',
|
||||
'package/equipment/detail'
|
||||
]
|
||||
if (lastPage && inArray(lastPage.route, backRoutes)) {
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1000)
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
this.$navTo('pages/order/index', {}, 'redirectTo')
|
||||
}, 1200)
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #F4F4F4;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
background-color: #F4F4F4;
|
||||
}
|
||||
|
||||
// 订单信息
|
||||
.order-info {
|
||||
padding: 80rpx 0;
|
||||
text-align: center;
|
||||
|
||||
.order-countdown {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.order-amount {
|
||||
margin: 0 auto;
|
||||
max-width: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #111111;
|
||||
|
||||
.unit {
|
||||
font-size: 30rpx;
|
||||
margin-bottom: -18rpx;
|
||||
}
|
||||
|
||||
.amount {
|
||||
font-size: 56rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 支付方式
|
||||
.payment-method {
|
||||
width: 94%;
|
||||
margin: 0 auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 20rpx;
|
||||
|
||||
.pay-item {
|
||||
padding: 26rpx 0;
|
||||
font-size: 28rpx;
|
||||
border-bottom: 1rpx solid rgb(248, 248, 248);
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.item-left_icon {
|
||||
margin-right: 20rpx;
|
||||
font-size: 44rpx;
|
||||
|
||||
&.wechat {
|
||||
color: #00c800;
|
||||
}
|
||||
|
||||
&.alipay {
|
||||
color: #009fe8;
|
||||
}
|
||||
|
||||
&.balance {
|
||||
color: #ff9700;
|
||||
}
|
||||
}
|
||||
|
||||
.item-left_text {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.item-right {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.user-balance {
|
||||
margin-left: 20rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 支付确认弹窗
|
||||
.modal-content {
|
||||
padding: 40rpx 48rpx;
|
||||
font-size: 30rpx;
|
||||
line-height: 50rpx;
|
||||
text-align: left;
|
||||
color: #606266;
|
||||
// height: 620rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
// 底部操作栏
|
||||
.footer-fixed {
|
||||
position: fixed;
|
||||
bottom: var(--window-bottom);
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 11;
|
||||
box-shadow: 0 -4rpx 40rpx 0 rgba(151, 151, 151, 0.24);
|
||||
background: #fff;
|
||||
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
|
||||
.btn-wrapper {
|
||||
height: 120rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 40rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 80rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 项目内容
|
||||
.checkout-item {
|
||||
margin: 0 auto 20rpx auto;
|
||||
padding: 30rpx 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0 rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.head-info {
|
||||
width: 750rpx;
|
||||
margin: auto;
|
||||
display: felx;
|
||||
flex-direction: column;
|
||||
|
||||
.title {
|
||||
font-weight: bold;
|
||||
font-size: 34rpx;
|
||||
}
|
||||
|
||||
.description {
|
||||
padding: 10rpx 0;
|
||||
font-size: 30rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
margin: 20rpx 0;
|
||||
border-bottom: 1rpx solid #f3f3f3;
|
||||
}
|
||||
|
||||
.goods-info {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
.image {
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
padding: 10rpx;
|
||||
}
|
||||
|
||||
.goods-info-box{
|
||||
margin-left: 20rpx;
|
||||
.title{
|
||||
font-weight: bold;
|
||||
font-size: 38rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
.desc{
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.contacts {
|
||||
margin-bottom: 16rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
|
||||
.bms-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 96%;
|
||||
|
||||
.item {
|
||||
margin-bottom: 10rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.name {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.totao-price {
|
||||
color: #ff0000;
|
||||
}
|
||||
}
|
||||
|
||||
.bms-image {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
width: 120rpx;
|
||||
|
||||
.bms-image-box {
|
||||
display: flex;
|
||||
font-size: 22rpx;
|
||||
margin-bottom: 18rpx;
|
||||
color: #00af00;
|
||||
|
||||
.bms-image-fbf {
|
||||
margin-top: 22rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 50rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.f-blue {
|
||||
color: #3f6fc1;
|
||||
}
|
||||
|
||||
.c-violet {
|
||||
color: #786cff;
|
||||
}
|
||||
|
||||
.col-bb {
|
||||
color: #bbb;
|
||||
}
|
||||
</style>
|
||||
159
package/equipment/components/Comment.vue
Executable file
159
package/equipment/components/Comment.vue
Executable file
@@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<!-- 设备评价 -->
|
||||
<view v-if="!isLoading && list.length" class="equipment-comment m-top20">
|
||||
<view class="item-title dis-flex">
|
||||
<view class="block-left flex-box">
|
||||
设备评价 (<text class="total">{{ total }}条</text>)
|
||||
</view>
|
||||
<view class="block-right">
|
||||
<text @click="onTargetToComment" class="show-more col-9">查看更多</text>
|
||||
<text class="iconfont icon-arrow-right col-9"></text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 评论列表 -->
|
||||
<view class="comment-list">
|
||||
<view class="comment-item" v-for="(item, index) in list" :key="index">
|
||||
<view class="comment-item_row dis-flex flex-y-center">
|
||||
<view class="user-info dis-flex flex-y-center">
|
||||
<avatar-image class="user-avatar" :url="item.user.avatar_url" :width="50" />
|
||||
<text class="user-name">{{ item.user.nick_name }}</text>
|
||||
</view>
|
||||
<!-- 评星 -->
|
||||
<view class="star-rating">
|
||||
<u-rate active-color="#f4a213" :current="rates[item.score]" :disabled="true" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-content m-top20">
|
||||
<text class="f-26 twoline-hide">{{ item.content }}</text>
|
||||
</view>
|
||||
<view class="comment-time">{{ item.create_time }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AvatarImage from '@/components/avatar-image'
|
||||
import * as CommentApi from '@/api/comment'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AvatarImage
|
||||
},
|
||||
props: {
|
||||
// 设备ID
|
||||
equipmentId: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
// 加载多少条记录 默认2条
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 2
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 正在加载
|
||||
isLoading: true,
|
||||
// 评星数据转换
|
||||
rates: { 10: 5, 20: 3, 30: 1 },
|
||||
// 评价列表数据
|
||||
list: [],
|
||||
// 评价总数量
|
||||
total: 0
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
// 加载评价列表数据
|
||||
this.getCommentList()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 加载评价列表数据
|
||||
getCommentList() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
CommentApi.listRows(app.equipmentId, app.limit)
|
||||
.then(result => {
|
||||
app.list = result.data.list
|
||||
app.total = result.data.total
|
||||
})
|
||||
.catch(err => err)
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 跳转到评论列表页
|
||||
onTargetToComment() {
|
||||
const app = this
|
||||
app.$navTo('pages/comment/index', { equipmentId: app.equipmentId })
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.equipment-comment {
|
||||
padding: 20rpx 30rpx;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
font-size: 28rpx;
|
||||
margin-bottom: 25rpx;
|
||||
|
||||
.total {
|
||||
margin: 0 4rpx;
|
||||
}
|
||||
|
||||
.show-more {
|
||||
margin-right: 8rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.comment-item {
|
||||
padding: 15rpx 5rpx;
|
||||
margin-bottom: 10rpx;
|
||||
border-bottom: 1rpx solid #f5f5f5;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.comment-item_row {
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.user-info {
|
||||
margin-right: 15rpx;
|
||||
|
||||
.user-avatar {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.item-content {
|
||||
color: #333;
|
||||
margin: 16rpx 0;
|
||||
max-height: 76rpx;
|
||||
line-height: 38rpx;
|
||||
}
|
||||
|
||||
.comment-time {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
</style>
|
||||
158
package/equipment/components/Service.vue
Executable file
158
package/equipment/components/Service.vue
Executable file
@@ -0,0 +1,158 @@
|
||||
<template>
|
||||
<view v-if="list.length" class="service-wrapper" :style="appThemeStyle">
|
||||
<!-- 服务简述 -->
|
||||
<view class="service-simple" @click="handlePopup">
|
||||
<view class="s-list">
|
||||
<view class="s-item" v-for="(item, index) in list" :key="index">
|
||||
<text class="item-icon iconfont icon-fuwu"></text>
|
||||
<text class="item-val">{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 扩展箭头 -->
|
||||
<view class="s-arrow f-26 col-9 t-r">
|
||||
<text class="iconfont icon-arrow-right"></text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 详情内容弹窗 -->
|
||||
<u-popup v-model="showPopup" mode="bottom" :closeable="true" :border-radius="26">
|
||||
<view class="service-content">
|
||||
<view class="title">服务</view>
|
||||
<scroll-view class="content-scroll" :scroll-y="true">
|
||||
<view class="s-list clearfix">
|
||||
<view class="s-item" v-for="(item, index) in list" :key="index">
|
||||
<text class="item-icon iconfont icon-fuwu"></text>
|
||||
<view class="item-val">{{ item.name }}</view>
|
||||
<view class="item-summary">{{ item.summary }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as ServiceApi from '@/api/equipment/service'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
// 设备ID
|
||||
equipmentId: {
|
||||
type: Number,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 正在加载
|
||||
isLoading: true,
|
||||
// 显示详情内容弹窗
|
||||
showPopup: false,
|
||||
// 服务列表数据
|
||||
list: []
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
// 获取设备服务列表
|
||||
this.getServiceList()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取设备服务列表
|
||||
getServiceList() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
ServiceApi.list(app.equipmentId)
|
||||
.then(result => app.list = result.data.list)
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 显示弹窗
|
||||
handlePopup() {
|
||||
this.showPopup = !this.showPopup
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.service-wrapper {
|
||||
min-height: 24rpx;
|
||||
margin-bottom: -24rpx;
|
||||
}
|
||||
|
||||
// 服务简述
|
||||
.service-simple {
|
||||
padding: 24rpx 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.s-list {
|
||||
flex: 1;
|
||||
margin-left: -15rpx;
|
||||
}
|
||||
|
||||
.s-item {
|
||||
float: left;
|
||||
font-size: 26rpx;
|
||||
margin: 8rpx 15rpx;
|
||||
|
||||
.item-icon {
|
||||
color: $main-bg;
|
||||
}
|
||||
|
||||
.item-val {
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 服务详细内容
|
||||
.service-content {
|
||||
padding: 24rpx;
|
||||
|
||||
.title {
|
||||
font-size: 30rpx;
|
||||
margin-bottom: 50rpx;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.content-scroll {
|
||||
min-height: 400rpx;
|
||||
max-height: 760rpx;
|
||||
}
|
||||
|
||||
.s-list {
|
||||
padding: 0 30rpx 0 80rpx;
|
||||
}
|
||||
|
||||
.s-item {
|
||||
position: relative;
|
||||
margin-bottom: 60rpx;
|
||||
|
||||
.item-icon {
|
||||
position: absolute;
|
||||
top: 6rpx;
|
||||
left: -50rpx;
|
||||
color: $main-bg;
|
||||
}
|
||||
|
||||
.item-val {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.item-summary {
|
||||
font-size: 26rpx;
|
||||
margin-top: 20rpx;
|
||||
color: #6d6d6d;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
179
package/equipment/components/SkuPopup.vue
Executable file
179
package/equipment/components/SkuPopup.vue
Executable file
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<equipment-sku-popup :value="value" @input="onChangeValue" border-radius="20" :localdata="equipmentInfo" :mode="skuMode" :maskCloseAble="true"
|
||||
:priceColor="appTheme.mainBg" :buyNowBackgroundColor="appTheme.mainBg" :addCartColor="appTheme.viceText" :addCartBackgroundColor="appTheme.viceBg"
|
||||
:activedStyle="{ color: appTheme.mainBg, borderColor: appTheme.mainBg, backgroundColor: activedBtnBackgroundColor }"
|
||||
@open="openSkuPopup" @close="closeSkuPopup" @add-cart="addCart" @buy-now="buyNow" buyNowText="立即租用" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { setCartTotalNum } from '@/core/app'
|
||||
import { hex2rgba } from '@/utils/color'
|
||||
import * as CartApi from '@/api/cart'
|
||||
import EquipmentSkuPopup from '@/components/equipment-sku-popup'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EquipmentSkuPopup
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'input'
|
||||
},
|
||||
props: {
|
||||
// true 组件显示 false 组件隐藏
|
||||
value: {
|
||||
Type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 模式 1:都显示 2:只显示购物车 3:只显示立即购买
|
||||
skuMode: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
// 商品详情信息
|
||||
equipment: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
equipmentInfo: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 规格按钮选中时的背景色
|
||||
activedBtnBackgroundColor() {
|
||||
return hex2rgba(this.appTheme.mainBg, 0.1)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const app = this
|
||||
const { equipment } = app
|
||||
app.equipmentInfo = {
|
||||
_id: equipment.equipment_id,
|
||||
name: equipment.equipment_name,
|
||||
equipment_thumb: equipment.equipment_image,
|
||||
sku_list: app.getSkuList(),
|
||||
spec_list: app.getSpecList()
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 监听组件显示隐藏
|
||||
onChangeValue(val) {
|
||||
this.$emit('input', val)
|
||||
},
|
||||
|
||||
// 整理商品SKU列表
|
||||
getSkuList() {
|
||||
const app = this
|
||||
const { equipment: { equipment_name, equipment_image, skuList } } = app
|
||||
const skuData = []
|
||||
skuList.forEach(item => {
|
||||
skuData.push({
|
||||
_id: item.id,
|
||||
equipment_sku_id: item.equipment_sku_id,
|
||||
equipment_id: item.equipment_id,
|
||||
equipment_name: equipment_name,
|
||||
image: item.image_url ? item.image_url : equipment_image,
|
||||
price: item.equipment_price * 100,
|
||||
stock: item.stock_num,
|
||||
spec_value_ids: item.spec_value_ids,
|
||||
sku_name_arr: app.getSkuNameArr(item.spec_value_ids)
|
||||
})
|
||||
})
|
||||
return skuData
|
||||
},
|
||||
|
||||
// 获取sku记录的规格值列表
|
||||
getSkuNameArr(specValueIds) {
|
||||
const app = this
|
||||
const defaultData = ['默认']
|
||||
const skuNameArr = []
|
||||
if (specValueIds) {
|
||||
specValueIds.forEach((valueId, groupIndex) => {
|
||||
const specValueName = app.getSpecValueName(valueId, groupIndex)
|
||||
skuNameArr.push(specValueName)
|
||||
})
|
||||
}
|
||||
return skuNameArr.length ? skuNameArr : defaultData
|
||||
},
|
||||
|
||||
// 获取指定的规格值名称
|
||||
getSpecValueName(valueId, groupIndex) {
|
||||
const app = this
|
||||
const { equipment: { specList } } = app
|
||||
const res = specList[groupIndex].valueList.find(specValue => {
|
||||
return specValue.spec_value_id == valueId
|
||||
})
|
||||
return res.spec_value
|
||||
},
|
||||
|
||||
// 整理规格数据
|
||||
getSpecList() {
|
||||
const { equipment: { specList } } = this
|
||||
const defaultData = [{ name: '默认', list: [{ name: '默认' }] }]
|
||||
const specData = []
|
||||
specList.forEach(group => {
|
||||
const children = []
|
||||
group.valueList.forEach(specValue => {
|
||||
children.push({ name: specValue.spec_value })
|
||||
})
|
||||
specData.push({
|
||||
name: group.spec_name,
|
||||
list: children
|
||||
})
|
||||
})
|
||||
return specData.length ? specData : defaultData
|
||||
},
|
||||
|
||||
// sku组件 开始-----------------------------------------------------------
|
||||
openSkuPopup() {
|
||||
// console.log("监听 - 打开sku组件")
|
||||
},
|
||||
|
||||
closeSkuPopup() {
|
||||
// console.log("监听 - 关闭sku组件")
|
||||
},
|
||||
|
||||
// 加入购物车按钮
|
||||
addCart(selectShop) {
|
||||
const app = this
|
||||
const { equipment_id, equipment_sku_id, buy_num } = selectShop
|
||||
CartApi.add(equipment_id, equipment_sku_id, buy_num)
|
||||
.then(result => {
|
||||
// 显示成功
|
||||
app.$toast(result.message)
|
||||
// 隐藏当前弹窗
|
||||
app.onChangeValue(false)
|
||||
// 购物车商品总数量
|
||||
const cartTotal = result.data.cartTotal
|
||||
// 缓存购物车数量
|
||||
setCartTotalNum(cartTotal)
|
||||
// 传递给父级
|
||||
app.$emit('addCart', cartTotal)
|
||||
})
|
||||
},
|
||||
|
||||
// 立即购买
|
||||
buyNow(selectShop) {
|
||||
// 跳转到订单结算页
|
||||
this.$navTo('package/equipment/cashier/index', {
|
||||
mode: 'buyNow',
|
||||
equipmentId: selectShop.equipment_id,
|
||||
equipmentSkuId: selectShop.equipment_sku_id,
|
||||
equipmentNum: selectShop.buy_num
|
||||
})
|
||||
// 隐藏当前弹窗
|
||||
this.onChangeValue(false)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
146
package/equipment/components/SlideImage.vue
Executable file
146
package/equipment/components/SlideImage.vue
Executable file
@@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<!-- 商品图片 -->
|
||||
<view class="images-swiper">
|
||||
<swiper class="swiper-box" :autoplay="autoplay" :duration="duration" :indicator-dots="indicatorDots"
|
||||
:interval="interval" :circular="true" @change="setCurrent">
|
||||
<!-- 主图视频 -->
|
||||
<swiper-item v-if="video">
|
||||
<view class="slide-video">
|
||||
<video id="myVideo" class="video" :poster="videoCover.preview_url" :src="video.external_url" controls
|
||||
x5-playsinline playsinline webkit-playsinline webkit-playsinline x5-video-player-type="h5"
|
||||
x5-video-player-fullscreen x5-video-orientation="portrait" :enable-progress-gesture="false"
|
||||
@play="onVideoPlay"></video>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<!-- 轮播图片 -->
|
||||
<swiper-item v-for="(item, index) in images" :key="index" @click="onPreviewImages(index)">
|
||||
<view class="slide-image">
|
||||
<image class="image" :draggable="false" :src="item.preview_url"></image>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<view class="swiper-count">
|
||||
<text>{{ currentIndex }}</text>
|
||||
<text>/</text>
|
||||
<text>{{ images.length + (video ? 1 : 0) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
// 主图视频
|
||||
video: {
|
||||
type: Object,
|
||||
default () {
|
||||
return null
|
||||
}
|
||||
},
|
||||
// 主图视频封面
|
||||
videoCover: {
|
||||
type: Object,
|
||||
default () {
|
||||
return null
|
||||
}
|
||||
},
|
||||
// 图片轮播
|
||||
images: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
indicatorDots: true, // 是否显示面板指示点
|
||||
autoplay: true, // 是否自动切换
|
||||
interval: 4000, // 自动切换时间间隔
|
||||
duration: 800, // 滑动动画时长
|
||||
currentIndex: 1, // 轮播图指针
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 事件:视频开始播放
|
||||
onVideoPlay(e) {
|
||||
this.autoplay = false
|
||||
},
|
||||
|
||||
// 设置轮播图当前指针 数字
|
||||
setCurrent({ detail }) {
|
||||
const app = this
|
||||
app.currentIndex = detail.current + 1
|
||||
},
|
||||
|
||||
// 浏览商品图片
|
||||
onPreviewImages(index) {
|
||||
const app = this
|
||||
const imageUrls = []
|
||||
app.images.forEach(item => {
|
||||
imageUrls.push(item.preview_url);
|
||||
});
|
||||
uni.previewImage({
|
||||
current: imageUrls[index],
|
||||
urls: imageUrls
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// swiper组件
|
||||
.images-swiper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.swiper-box {
|
||||
width: 100%;
|
||||
height: 100vw;
|
||||
|
||||
/* #ifdef H5 */
|
||||
max-width: 480px;
|
||||
max-height: 480px;
|
||||
margin: 0 auto;
|
||||
/* #endif */
|
||||
|
||||
// 主图视频
|
||||
.slide-video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.video {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
// 图片轮播
|
||||
.slide-image {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// swiper计数
|
||||
.swiper-count {
|
||||
position: absolute;
|
||||
right: 36rpx;
|
||||
bottom: 72rpx;
|
||||
padding: 2rpx 18rpx;
|
||||
background: rgba(0, 0, 0, 0.363);
|
||||
border-radius: 50rpx;
|
||||
color: #fff;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
</style>
|
||||
69
package/equipment/components/search.vue
Executable file
69
package/equipment/components/search.vue
Executable file
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<!-- 搜索框 -->
|
||||
<view class="search-wrapper">
|
||||
<view class="index-search" @click="onClick">
|
||||
<view class="index-cont-search t-c">
|
||||
<text class="search-icon iconfont icon-search"></text>
|
||||
<text class="search-text">{{ tips }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
tips: {
|
||||
type: String,
|
||||
default: '搜索商品'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onClick() {
|
||||
this.$emit('event')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search-wrapper {
|
||||
background: #fff;
|
||||
padding: 13rpx;
|
||||
}
|
||||
|
||||
.index-search {
|
||||
border-bottom: 0;
|
||||
background: #fff;
|
||||
border-radius: 50rpx;
|
||||
overflow: hidden;
|
||||
font-size: 28rpx;
|
||||
color: #6d6d6d;
|
||||
box-sizing: border-box;
|
||||
line-height: 64rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.index-cont-search {
|
||||
width: 100%;
|
||||
font-size: 28rpx;
|
||||
background: #f7f7f7;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.index-cont-search .search-icon {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.index-cont-search .search-text {
|
||||
margin-left: 14rpx;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
229
package/equipment/detail.scss
Executable file
229
package/equipment/detail.scss
Executable file
@@ -0,0 +1,229 @@
|
||||
.container {
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
// 110 - 18 + 4
|
||||
padding-bottom: calc(constant(safe-area-inset-bottom) + 106rpx + 6rpx);
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 106rpx + 6rpx);
|
||||
}
|
||||
|
||||
// 商品信息
|
||||
.equipment-info {
|
||||
background: #fff;
|
||||
padding: 25rpx 30rpx;
|
||||
}
|
||||
|
||||
.info-item__top {
|
||||
min-height: 40rpx;
|
||||
margin-bottom: 20rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.floor-price__samll {
|
||||
font-size: 26rpx;
|
||||
line-height: 1;
|
||||
color: #ff0000;
|
||||
margin-bottom: -10rpx;
|
||||
}
|
||||
|
||||
// 商品价
|
||||
.floor-price {
|
||||
color: #ff0000;
|
||||
margin-right: 15rpx;
|
||||
font-size: 42rpx;
|
||||
}
|
||||
|
||||
.original-price {
|
||||
font-size: 26rpx;
|
||||
text-decoration: line-through;
|
||||
color: #959595;
|
||||
margin-right: 15rpx;
|
||||
margin-bottom: -6rpx;
|
||||
}
|
||||
|
||||
// 会员价标签
|
||||
.user-grade {
|
||||
background: #3c3c3c;
|
||||
border-radius: 6rpx;
|
||||
padding: 8rpx 14rpx;
|
||||
margin-right: 15rpx;
|
||||
font-size: 24rpx;
|
||||
color: #EEE0C3;
|
||||
}
|
||||
|
||||
.equipment-sales {
|
||||
font-size: 24rpx;
|
||||
color: #959595;
|
||||
}
|
||||
|
||||
.info-item__name .equipment-name {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* 商品分享 */
|
||||
|
||||
.equipment-share__line {
|
||||
border-left: 1rpx solid #f4f4f4;
|
||||
height: 60rpx;
|
||||
margin: 0 30rpx;
|
||||
}
|
||||
|
||||
.equipment-share .share-btn {
|
||||
line-height: normal;
|
||||
padding: 0;
|
||||
background: none;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
font-size: 8pt;
|
||||
border: none;
|
||||
color: #191919;
|
||||
}
|
||||
|
||||
.equipment-share .share-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.equipment-share .share__icon {
|
||||
font-size: 40rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
|
||||
// 商品卖点
|
||||
.info-item_selling-point {
|
||||
margin-top: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
// 选择商品规格
|
||||
.equipment-choice {
|
||||
padding: 26rpx 30rpx;
|
||||
font-size: 28rpx;
|
||||
|
||||
.spec-list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.spec-name {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 商品详情
|
||||
.equipment-content .item-title {
|
||||
padding: 26rpx 30rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
// 底部操作栏
|
||||
.footer-fixed {
|
||||
position: fixed;
|
||||
bottom: var(--window-bottom);
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
z-index: 11;
|
||||
box-shadow: 0 -4rpx 40rpx 0 rgba(151, 151, 151, 0.24);
|
||||
background: #fff;
|
||||
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
.footer-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
height: 106rpx;
|
||||
}
|
||||
|
||||
// 快捷菜单
|
||||
.foo-item-fast {
|
||||
box-sizing: border-box;
|
||||
min-width: 214rpx;
|
||||
line-height: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
margin-right: 12rpx;
|
||||
|
||||
.fast-item {
|
||||
position: relative;
|
||||
padding: 4rpx 0;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
width: 84rpx;
|
||||
|
||||
&--cart {
|
||||
margin-left: 6rpx;
|
||||
.fast-icon { margin-left: -12rpx; }
|
||||
}
|
||||
|
||||
// 角标
|
||||
.fast-badge {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
min-width: 16px;
|
||||
padding: 0 3px;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
font-size: 12px;
|
||||
font-family: -apple-system-font, Helvetica Neue, Arial, sans-serif;
|
||||
line-height: 1.2;
|
||||
text-align: center;
|
||||
background-color: #ee0a24;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.fast-badge--fixed {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
transform-origin: 100%
|
||||
}
|
||||
|
||||
.fast-icon {
|
||||
font-size: 44rpx;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.fast-text {
|
||||
font-size: 22rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 操作按钮
|
||||
.foo-item-btn {
|
||||
flex: 1;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 72rpx;
|
||||
margin-right: 16rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
// 立即购买按钮
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
}
|
||||
|
||||
// 购物车按钮
|
||||
.btn-item-deputy {
|
||||
background: linear-gradient(to right, $vice-bg, $vice-bg2);
|
||||
color: $vice-text;
|
||||
}
|
||||
}
|
||||
348
package/equipment/detail.vue
Executable file
348
package/equipment/detail.vue
Executable file
@@ -0,0 +1,348 @@
|
||||
<template>
|
||||
<view v-show="!isLoading" class="container" :style="appThemeStyle">
|
||||
<!-- 设备图片轮播 -->
|
||||
<SlideImage v-if="!isLoading" :video="equipment.video" :videoCover="equipment.videoCover" :images="equipment.equipment_images" />
|
||||
|
||||
<!-- 设备信息 -->
|
||||
<view v-if="!isLoading" class="equipment-info m-top20">
|
||||
<!-- 价格、销量 -->
|
||||
<view class="info-item info-item__top dis-flex flex-x-between flex-y-end">
|
||||
<view class="block-left dis-flex flex-y-center">
|
||||
<!-- 设备售价 -->
|
||||
<text class="floor-price__samll">¥</text>
|
||||
<text class="floor-price">{{ equipment.equipment_price_min }}</text>
|
||||
<!-- 会员价标签 -->
|
||||
<view v-if="equipment.is_user_grade" class="user-grade">
|
||||
<text>会员价</text>
|
||||
</view>
|
||||
<!-- 划线价 -->
|
||||
<text v-if="equipment.line_price_min > 0" class="original-price">¥{{ equipment.line_price_min }}</text>
|
||||
</view>
|
||||
<view class="block-right dis-flex">
|
||||
<!-- 销量 -->
|
||||
<view class="equipment-sales">
|
||||
<text>已售{{ equipment.equipment_sales }}件</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 标题、分享 -->
|
||||
<view class="info-item info-item__name dis-flex flex-y-center">
|
||||
<view class="equipment-name flex-box">
|
||||
<text class="twoline-hide">{{ equipment.equipment_name }}</text>
|
||||
</view>
|
||||
<view class="equipment-share__line"></view>
|
||||
<view class="equipment-share">
|
||||
<button class="share-btn dis-flex flex-dir-column" @click="onShowShareSheet()">
|
||||
<text class="share__icon iconfont icon-fenxiang"></text>
|
||||
<text class="f-24">分享</text>
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 设备卖点 -->
|
||||
<view v-if="equipment.selling_point" class="info-item info-item_selling-point">
|
||||
<text>{{ equipment.selling_point }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 选择设备规格 -->
|
||||
<view v-if="equipment.spec_type == 20" class="equipment-choice m-top20 b-f" @click="onShowSkuPopup(1)">
|
||||
<view class="spec-list">
|
||||
<view class="flex-box">
|
||||
<text class="col-8">选择:</text>
|
||||
<text class="spec-name" v-for="(item, index) in equipment.specList" :key="index">{{ item.spec_name }}</text>
|
||||
</view>
|
||||
<view class="f-26 col-9 t-r">
|
||||
<text class="iconfont icon-arrow-right"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 设备服务 -->
|
||||
<Service v-if="!isLoading" :equipment-id="equipmentId" />
|
||||
|
||||
<!-- 设备SKU弹窗 -->
|
||||
<SkuPopup v-if="!isLoading" v-model="showSkuPopup" :skuMode="skuMode" :equipment="equipment" @addCart="onAddCart" />
|
||||
|
||||
<!-- 设备评价 -->
|
||||
<Comment v-if="!isLoading" :equipment-id="equipmentId" :limit="2" />
|
||||
|
||||
<!-- 设备描述 -->
|
||||
<view v-if="!isLoading" class="equipment-content m-top20">
|
||||
<view class="item-title b-f">
|
||||
<text>设备描述</text>
|
||||
</view>
|
||||
<block v-if="equipment.content != ''">
|
||||
<view class="equipment-content__detail b-f">
|
||||
<mp-html :content="equipment.content" />
|
||||
</view>
|
||||
</block>
|
||||
<empty v-else tips="亲,暂无设备描述" />
|
||||
</view>
|
||||
|
||||
<!-- 设备推荐 -->
|
||||
<recommended />
|
||||
|
||||
<!-- 底部选项卡 -->
|
||||
<view class="footer-fixed">
|
||||
<view class="footer-container">
|
||||
<!-- 导航图标 -->
|
||||
<view class="foo-item-fast">
|
||||
<!-- 首页 -->
|
||||
<!-- <view class="fast-item fast-item--home" @click="onTargetHome">
|
||||
<view class="fast-icon">
|
||||
<text class="iconfont icon-shouye"></text>
|
||||
</view>
|
||||
<view class="fast-text">
|
||||
<text>站点</text>
|
||||
</view>
|
||||
</view> -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<button class="btn-normal" @click="onCollection(equipment.equipment_id)">
|
||||
<view class="fast-item">
|
||||
<view class="fast-icon">
|
||||
<u-icon name="star-fill" color="#fd8008" v-if="equipment.is_collection"></u-icon>
|
||||
<u-icon name="star" v-else></u-icon>
|
||||
</view>
|
||||
<view class="fast-text">
|
||||
<text>收藏</text>
|
||||
</view>
|
||||
</view>
|
||||
</button>
|
||||
<!-- #endif -->
|
||||
<!-- 客服 (仅微信小程序端显示) -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<!-- <button class="btn-normal" open-type="contact">
|
||||
<view class="fast-item">
|
||||
<view class="fast-icon">
|
||||
<text class="iconfont icon-kefu1"></text>
|
||||
</view>
|
||||
<view class="fast-text">
|
||||
<text>客服</text>
|
||||
</view>
|
||||
</view>
|
||||
</button> -->
|
||||
<!-- #endif -->
|
||||
<!-- 购物车 -->
|
||||
<!-- <view class="fast-item fast-item--cart" @click="onTargetCart">
|
||||
<view v-if="cartTotal > 0" class="fast-badge fast-badge--fixed">{{ cartTotal > 99 ? '99+' : cartTotal }}
|
||||
</view>
|
||||
<view class="fast-icon">
|
||||
<text class="iconfont icon-gouwuche"></text>
|
||||
</view>
|
||||
<view class="fast-text">
|
||||
<text>购物车</text>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="foo-item-btn">
|
||||
<view class="btn-wrapper">
|
||||
<!-- <view class="btn-item btn-item-deputy" @click="onShowSkuPopup(2)">
|
||||
<text>加入购物车</text>
|
||||
</view> -->
|
||||
<view class="btn-item btn-item-main" @click="onShowSkuPopup(3)">
|
||||
<text>立即租用</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 快捷导航 -->
|
||||
<!-- <shortcut bottom="120rpx" /> -->
|
||||
|
||||
<!-- 分享菜单 -->
|
||||
<share-sheet v-model="showShareSheet" :shareTitle="equipment.equipment_name" :shareImageUrl="equipment.equipment_image"
|
||||
:posterApiCall="posterApiCall" :posterApiParam="{ equipmentId }" />
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getSceneData } from '@/core/app'
|
||||
import * as EquipmentApi from '@/api/equipment'
|
||||
import * as CartApi from '@/api/cart'
|
||||
import Recommended from '@/components/recommended'
|
||||
import ShareSheet from '@/components/share-sheet'
|
||||
import SlideImage from './components/SlideImage'
|
||||
import SkuPopup from './components/SkuPopup'
|
||||
import Comment from './components/Comment'
|
||||
import Service from './components/Service'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Recommended,
|
||||
ShareSheet,
|
||||
SlideImage,
|
||||
SkuPopup,
|
||||
Comment,
|
||||
Service
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 正在加载
|
||||
isLoading: true,
|
||||
// 当前设备ID
|
||||
equipmentId: null,
|
||||
// 设备详情
|
||||
equipment: {},
|
||||
// 购物车总数量
|
||||
cartTotal: 0,
|
||||
// 显示/隐藏SKU弹窗
|
||||
showSkuPopup: false,
|
||||
// 模式 1:都显示 2:只显示购物车 3:只显示立即购买
|
||||
skuMode: 1,
|
||||
// 显示/隐藏分享菜单
|
||||
showShareSheet: false,
|
||||
// 获取设备海报图api方法
|
||||
posterApiCall: EquipmentApi.poster
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
// 记录query参数
|
||||
this.onRecordQuery(options)
|
||||
// 加载页面数据
|
||||
this.onRefreshPage()
|
||||
// 浏览历史
|
||||
this.saveFootMarkList(options.equipmentId)
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 浏览历史记录
|
||||
saveFootMarkList(equipmentId){
|
||||
const userId = uni.getStorageSync('userId')
|
||||
const arr = uni.getStorageSync(`FOOTMARKLIST_${userId}`) || []
|
||||
arr.unshift(Number(equipmentId))
|
||||
return uni.setStorageSync(`FOOTMARKLIST_${userId}`,arr)
|
||||
},
|
||||
// 记录query参数
|
||||
onRecordQuery(query) {
|
||||
const scene = getSceneData(query)
|
||||
this.equipmentId = query.equipmentId ? parseInt(query.equipmentId) : parseInt(scene.gid)
|
||||
},
|
||||
|
||||
// 刷新页面数据
|
||||
onRefreshPage() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
Promise.all([app.getEquipmentDetail(), app.getCartTotal()])
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 获取设备信息
|
||||
getEquipmentDetail() {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
EquipmentApi.detail(app.equipmentId)
|
||||
.then(result => {
|
||||
app.equipment = result.data.detail
|
||||
resolve(result)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取购物车总数量
|
||||
getCartTotal() {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
CartApi.total()
|
||||
.then(result => {
|
||||
app.cartTotal = result.data.cartTotal
|
||||
resolve(result)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 更新购物车数量
|
||||
onAddCart(total) {
|
||||
this.cartTotal = total
|
||||
},
|
||||
|
||||
/**
|
||||
* 显示/隐藏SKU弹窗
|
||||
* @param {skuMode} 模式 1:都显示 2:只显示购物车 3:只显示立即购买
|
||||
*/
|
||||
onShowSkuPopup(skuMode = 1) {
|
||||
const shopInfo = uni.getStorageSync('shopInfo')
|
||||
const clerkInfo = uni.getStorageSync('clerkInfo')
|
||||
if(shopInfo || clerkInfo){
|
||||
return this.$error('请使用会员账号购买')
|
||||
}
|
||||
this.skuMode = skuMode
|
||||
this.showSkuPopup = !this.showSkuPopup
|
||||
},
|
||||
|
||||
// 显示隐藏分享菜单
|
||||
onShowShareSheet() {
|
||||
this.showShareSheet = !this.showShareSheet
|
||||
},
|
||||
|
||||
// 跳转到首页
|
||||
onTargetHome(e) {
|
||||
const { equipment } = this
|
||||
console.log("this.equipment: ",equipment);
|
||||
this.$navTo('package/shops/detail/index',equipment)
|
||||
},
|
||||
|
||||
// 加入收藏
|
||||
onCollection(equipmentId){
|
||||
EquipmentApi.collection({equipmentId})
|
||||
this.equipment.is_collection = !this.equipment.is_collection
|
||||
},
|
||||
|
||||
// 跳转到购物车页
|
||||
onTargetCart() {
|
||||
this.$navTo('pages/cart/index')
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享当前页面
|
||||
*/
|
||||
onShareAppMessage() {
|
||||
const app = this
|
||||
// 构建页面参数
|
||||
const params = app.$getShareUrlParams({
|
||||
equipmentId: app.equipmentId,
|
||||
})
|
||||
return {
|
||||
title: app.equipment.equipment_name,
|
||||
path: `/pages/equipment/detail?${params}`
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享到朋友圈
|
||||
* 本接口为 Beta 版本,暂只在 Android 平台支持,详见分享到朋友圈 (Beta)
|
||||
* https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html
|
||||
*/
|
||||
onShareTimeline() {
|
||||
const app = this
|
||||
// 构建页面参数
|
||||
const params = app.$getShareUrlParams({
|
||||
equipmentId: app.equipmentId,
|
||||
})
|
||||
return {
|
||||
title: app.equipment.equipment_name,
|
||||
path: `/pages/equipment/detail?${params}`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
@import "./detail.scss";
|
||||
</style>
|
||||
|
||||
465
package/equipment/list.vue
Executable file
465
package/equipment/list.vue
Executable file
@@ -0,0 +1,465 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ native: true }" @down="downCallback" :up="upOption"
|
||||
@up="upCallback">
|
||||
<!-- 页面头部 -->
|
||||
<view class="header">
|
||||
<search class="search" :tips="options.search ? options.search : '搜索商品'" @event="handleSearch" />
|
||||
<!-- 切换列表显示方式 -->
|
||||
<view class="show-view" @click="handleShowView">
|
||||
<text class="iconfont icon-view-tile" v-if="showView"></text>
|
||||
<text class="iconfont icon-view-list" v-else></text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 排序标签 -->
|
||||
<view class="store-sort">
|
||||
<view class="sort-item" :class="{ active: sortType === 'all' }" @click="handleSortType('all')">
|
||||
<text>综合</text>
|
||||
</view>
|
||||
<view class="sort-item" :class="{ active: sortType === 'sales' }" @click="handleSortType('sales')">
|
||||
<text>销量</text>
|
||||
</view>
|
||||
<view class="sort-item sort-item-price" :class="{ active: sortType === 'price' }" @click="handleSortType('price')">
|
||||
<text>价格</text>
|
||||
<view class="price-arrow">
|
||||
<view class="icon up" :class="{ active: sortType === 'price' && !sortPrice }">
|
||||
<text class="iconfont icon-arrow-up"></text>
|
||||
</view>
|
||||
<view class="icon down" :class="{ active: sortType === 'price' && sortPrice }">
|
||||
<text class="iconfont icon-arrow-down"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 商品列表 -->
|
||||
<view class="goods-list clearfix" :class="['column-' + (showView ? '1' : '2')]">
|
||||
<view class="goods-item" v-for="(item, index) in list.data" :key="index" @click="onTargetDetail(item.goods_id)">
|
||||
<!-- 单列显示 -->
|
||||
<view v-if="showView" class="dis-flex">
|
||||
<!-- 商品图片 -->
|
||||
<view class="goods-item_left">
|
||||
<image class="image" :src="item.goods_image"></image>
|
||||
</view>
|
||||
<view class="goods-item_right">
|
||||
<!-- 商品名称 -->
|
||||
<view class="goods-name">
|
||||
<text class="twoline-hide">{{ item.goods_name }}</text>
|
||||
</view>
|
||||
<view class="goods-item_desc">
|
||||
<!-- 商品卖点 -->
|
||||
<view class="desc-selling_point dis-flex">
|
||||
<text class="oneline-hide">{{ item.selling_point }}</text>
|
||||
</view>
|
||||
<!-- 商品销量 -->
|
||||
<view class="desc-goods_sales dis-flex">
|
||||
<text>已售{{ item.goods_sales }}件</text>
|
||||
</view>
|
||||
<!-- 商品价格 -->
|
||||
<view class="desc_footer">
|
||||
<text class="price_x">¥{{ item.goods_price_min }}</text>
|
||||
<text class="price_y col-9" v-if="item.line_price_min > 0">¥{{ item.line_price_min }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 多列显示 -->
|
||||
<view v-else class="">
|
||||
<!-- 商品图片 -->
|
||||
<view class="goods-image">
|
||||
<image class="image" mode="aspectFill" :src="item.goods_image"></image>
|
||||
</view>
|
||||
<view class="detail">
|
||||
<!-- 商品名称 -->
|
||||
<view class="goods-name">
|
||||
<text class="twoline-hide">{{ item.goods_name }}</text>
|
||||
</view>
|
||||
<!-- 商品价格 -->
|
||||
<view class="detail-price oneline-hide">
|
||||
<text class="goods-price f-30 col-m">¥{{ item.goods_price_min }}</text>
|
||||
<text v-if="item.line_price_min > 0" class="line-price col-9 f-24">¥{{ item.line_price_min }}</text>
|
||||
</view>
|
||||
<!-- 商品销量 -->
|
||||
<text class="col-9 f-24 u-text-right">已售{{ item.goods_sales }}件</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import * as GoodsApi from '@/api/goods'
|
||||
import { getEmptyPaginateObj, getMoreListData } from '@/core/app'
|
||||
import Search from './components/search.vue'
|
||||
|
||||
const pageSize = 15
|
||||
const showViewKey = 'GoodsList-ShowView';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody,
|
||||
Search
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
data() {
|
||||
return {
|
||||
showView: false, // 列表显示方式 (true列表、false平铺)
|
||||
sortType: 'all', // 排序类型
|
||||
sortPrice: false, // 价格排序 (true高到低 false低到高)
|
||||
options: {}, // 当前页面参数
|
||||
list: getEmptyPaginateObj(), // 商品列表数据
|
||||
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: { size: pageSize },
|
||||
// 数量要大于4条才显示无更多数据
|
||||
noMoreSize: 4,
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
// 记录options
|
||||
this.options = options
|
||||
// 设置默认列表显示方式
|
||||
this.setShowView()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
app.getGoodsList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
// 设置默认列表显示方式
|
||||
setShowView() {
|
||||
this.showView = uni.getStorageSync(showViewKey) || false
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取商品列表
|
||||
* @param {number} pageNo 页码
|
||||
*/
|
||||
getGoodsList(pageNo = 1) {
|
||||
const app = this
|
||||
console.log(app.options)
|
||||
const param = {
|
||||
sortType: app.sortType,
|
||||
sortPrice: Number(app.sortPrice),
|
||||
categoryId: app.options.categoryId || 0,
|
||||
goodsName: app.options.search || '',
|
||||
page: pageNo
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
GoodsApi.list(param)
|
||||
.then(result => {
|
||||
// 合并新数据
|
||||
const newList = result.data.list
|
||||
app.list.data = getMoreListData(newList, app.list, pageNo)
|
||||
resolve(newList)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 切换排序方式
|
||||
handleSortType(newSortType) {
|
||||
const app = this
|
||||
const newSortPrice = newSortType === 'price' ? !app.sortPrice : true
|
||||
app.sortType = newSortType
|
||||
app.sortPrice = newSortPrice
|
||||
// 刷新列表数据
|
||||
app.list = getEmptyPaginateObj()
|
||||
app.mescroll.resetUpScroll()
|
||||
},
|
||||
|
||||
// 切换列表显示方式
|
||||
handleShowView() {
|
||||
const app = this
|
||||
app.showView = !app.showView
|
||||
uni.setStorageSync(showViewKey, app.showView)
|
||||
},
|
||||
|
||||
// 跳转商品详情页
|
||||
onTargetDetail(goodsId) {
|
||||
this.$navTo('pages/goods/detail', { goodsId })
|
||||
},
|
||||
|
||||
/**
|
||||
* 商品搜索
|
||||
*/
|
||||
handleSearch() {
|
||||
const searchPageUrl = 'pages/search/index'
|
||||
// 判断来源页面
|
||||
let pages = getCurrentPages()
|
||||
if (pages.length > 1 &&
|
||||
pages[pages.length - 2].route === searchPageUrl) {
|
||||
uni.navigateBack()
|
||||
return
|
||||
}
|
||||
// 跳转到商品搜索页
|
||||
this.$navTo(searchPageUrl)
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 设置分享内容
|
||||
*/
|
||||
onShareAppMessage() {
|
||||
// 构建分享参数
|
||||
return {
|
||||
title: "全部分类",
|
||||
path: "/pages/category/index?" + this.$getShareUrlParams()
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享到朋友圈
|
||||
* 本接口为 Beta 版本,暂只在 Android 平台支持,详见分享到朋友圈 (Beta)
|
||||
* https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html
|
||||
*/
|
||||
onShareTimeline() {
|
||||
// 构建分享参数
|
||||
return {
|
||||
title: "全部分类",
|
||||
path: "/pages/category/index?" + this.$getShareUrlParams()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 页面头部
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
|
||||
// 搜索框
|
||||
.search {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
// 切换显示方式
|
||||
.show-view {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
font-size: 36rpx;
|
||||
color: #505050;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
// 排序组件
|
||||
.store-sort {
|
||||
position: sticky;
|
||||
top: var(--window-top);
|
||||
display: flex;
|
||||
padding: 20rpx 0;
|
||||
font-size: 28rpx;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
z-index: 99;
|
||||
|
||||
.sort-item {
|
||||
flex-basis: 33.3333%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 50rpx;
|
||||
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
}
|
||||
}
|
||||
|
||||
.sort-item-price .price-arrow {
|
||||
margin-left: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #000;
|
||||
|
||||
.icon {
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
}
|
||||
|
||||
&.up {
|
||||
margin-bottom: -16rpx;
|
||||
}
|
||||
|
||||
&.down {
|
||||
margin-top: -16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 商品列表
|
||||
.goods-list {
|
||||
padding: 4rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// 单列显示
|
||||
.goods-list.column-1 {
|
||||
.goods-item {
|
||||
width: 100%;
|
||||
height: 280rpx;
|
||||
margin-bottom: 12rpx;
|
||||
padding: 20rpx;
|
||||
box-sizing: border-box;
|
||||
background: #fff;
|
||||
line-height: 1.6;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_left {
|
||||
display: flex;
|
||||
width: 300rpx;
|
||||
background: #fff;
|
||||
align-items: center;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 240rpx;
|
||||
height: 240rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_right {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
|
||||
.goods-name {
|
||||
margin-top: 10rpx;
|
||||
min-height: 68rpx;
|
||||
line-height: 1.3;
|
||||
white-space: normal;
|
||||
color: #484848;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_desc {
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.desc-selling_point {
|
||||
width: 400rpx;
|
||||
font-size: 24rpx;
|
||||
color: #e49a3d;
|
||||
}
|
||||
|
||||
.desc-goods_sales {
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.desc_footer {
|
||||
font-size: 24rpx;
|
||||
|
||||
.price_x {
|
||||
margin-right: 16rpx;
|
||||
color: $main-bg;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.price_y {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 平铺显示
|
||||
.goods-list.column-2 {
|
||||
.goods-item {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item {
|
||||
float: left;
|
||||
box-sizing: border-box;
|
||||
padding: 6rpx;
|
||||
|
||||
.goods-image {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
padding-bottom: 100%;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
display: block;
|
||||
margin-top: 100%;
|
||||
}
|
||||
|
||||
.image {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
-o-object-fit: cover;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.detail {
|
||||
padding: 8rpx;
|
||||
background: #fff;
|
||||
|
||||
.goods-name {
|
||||
min-height: 68rpx;
|
||||
line-height: 1.3;
|
||||
white-space: normal;
|
||||
color: #484848;
|
||||
font-size: 26rpx;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.detail-price {
|
||||
.goods-price {
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.line-price {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
278
package/follow/index.vue
Normal file
278
package/follow/index.vue
Normal file
@@ -0,0 +1,278 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- 门店列表 -->
|
||||
<view class="shop-list">
|
||||
<u-card v-for="(item, index) in shopList" :key="index" @click="onSelectedShop(item)"
|
||||
class="shop-item dis-flex flex-y-center" :border="false" :box-shadow="true" :show-head="false"
|
||||
:head-border-bottom="false">
|
||||
<view class="" slot="body">
|
||||
<view class="shop-item__content flex-box">
|
||||
<view class="u-body-item u-flex u-col-between u-p-t-0">
|
||||
<u-avatar :src="item.logoUrl" :size="120" mode="square" :show-level="true" ></u-avatar>
|
||||
<view class="shop-info">
|
||||
<view class="title">{{item.shopName}}</view>
|
||||
<view class="about">联系电话:{{item.phone}}</view>
|
||||
<view class="address">地址:{{ item.region.province }}{{ item.region.city }}{{ item.region.region }}{{ item.address }}</view>
|
||||
<view v-if="item.distance" class="shop-item__distance">
|
||||
<text class="iconfont icon-dingwei"></text>
|
||||
<text class="f-24">{{ item.distanceUnit }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 选中状态 -->
|
||||
<!-- <view v-if="item.shop_id == selectedId" class="shop-item__right">
|
||||
<text class="iconfont icon-check1"></text>
|
||||
</view> -->
|
||||
</view>
|
||||
</u-card>
|
||||
</view>
|
||||
<!-- 定位按钮 -->
|
||||
<view v-if="!isAuthor" class="widget-location dis-flex flex-x-center flex-y-center" @click="onAuthorize()">
|
||||
<text class="iconfont icon-locate"></text>
|
||||
</view>
|
||||
<empty v-if="!shopList.length" :isLoading="isLoading" tips="亲,暂无关注的站点哦" />
|
||||
|
||||
<!-- <view class="shop-list">
|
||||
<u-card v-for="(item,index) in list" :key="index" :border="false" :box-shadow="true" :show-head="false"
|
||||
:head-border-bottom="false">
|
||||
<view class="" slot="body">
|
||||
<view class="u-body-item u-flex u-col-between u-p-t-0">
|
||||
<image class="shop-avatar"
|
||||
:src="item.logo_url"
|
||||
mode="widthFix"></image>
|
||||
<view class="shop-info">
|
||||
<view class="title">{{item.shop_name}}</view>
|
||||
<view class="about">{{item.summary}}</view>
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</u-card>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Search from '@/components/page/diyComponents/search/index.vue'
|
||||
import {
|
||||
getMoreListData
|
||||
} from '@/core/app'
|
||||
import * as ShopApi from '@/api/shop.js'
|
||||
import Empty from '@/components/empty'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Search,
|
||||
Empty
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: '国内馆',
|
||||
// 正在加载中
|
||||
isLoading: true,
|
||||
// 是否授权了定位权限
|
||||
isAuthor: true,
|
||||
// 当前选择的门店ID
|
||||
selectedId: null,
|
||||
// 订单列表数据
|
||||
shopList: [],
|
||||
|
||||
}
|
||||
},
|
||||
onLoad({
|
||||
selectedId
|
||||
}) {
|
||||
const app = this
|
||||
// 记录当前选择的门店ID
|
||||
app.selectedId = selectedId ? selectedId : null
|
||||
// 获取默认门店列表
|
||||
app.getShopList()
|
||||
// 获取用户坐标
|
||||
app.getLocation(res => {
|
||||
app.getShopList(res.longitude, res.latitude)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// 获取门店列表
|
||||
getShopList(longitude, latitude) {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
ShopApi.list({
|
||||
isCheck: 1,
|
||||
longitude,
|
||||
latitude,
|
||||
follow: true
|
||||
})
|
||||
.then(result => app.shopList = result.data.list)
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 获取用户坐标
|
||||
// 参考文档:https://uniapp.dcloud.io/api/location/location?id=getlocation
|
||||
getLocation(callback) {
|
||||
const app = this
|
||||
uni.getLocation({
|
||||
type: 'wgs84',
|
||||
success: callback,
|
||||
fail() {
|
||||
app.$toast('获取定位失败,请点击右下角按钮重新尝试定位')
|
||||
app.isAuthor = false
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 授权启用定位权限
|
||||
onAuthorize() {
|
||||
const app = this
|
||||
// #ifdef MP
|
||||
uni.openSetting({
|
||||
success(res) {
|
||||
if (res.authSetting['scope.userLocation']) {
|
||||
console.log('定位权限授权成功')
|
||||
app.isAuthor = true
|
||||
setTimeout(() => {
|
||||
// 获取用户坐标
|
||||
app.getLocation((res) => {
|
||||
app.getShopList(res.longitude, res.latitude)
|
||||
})
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
// 获取用户坐标
|
||||
app.getLocation((res) => {
|
||||
app.getShopList(res.longitude, res.latitude)
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
|
||||
/**
|
||||
* 选择门店
|
||||
*/
|
||||
onSelectedShop(item) {
|
||||
this.$navTo('package/shops/detail/index',item)
|
||||
},
|
||||
|
||||
changeCity() {
|
||||
this.$toast('切换区域')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bg {
|
||||
background-color: #F5F5F8
|
||||
}
|
||||
|
||||
.shop-list {
|
||||
.shop-item {
|
||||
}
|
||||
}
|
||||
|
||||
.header-box {
|
||||
padding: 20rpx 36rpx 0 36rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.location {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
width: 60rpx;
|
||||
height: 60rpx
|
||||
}
|
||||
}
|
||||
|
||||
.u-subsection {
|
||||
width: 260rpx;
|
||||
margin-top: 7rpx
|
||||
}
|
||||
}
|
||||
|
||||
.search-wrapper {
|
||||
display: flex;
|
||||
width: 80%;
|
||||
height: 64rpx
|
||||
}
|
||||
|
||||
// 搜索输入框
|
||||
.search-input {
|
||||
width: 90%;
|
||||
background: #fff;
|
||||
border-radius: 10rpx 0 0 10rpx;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
|
||||
.search-input-wrapper {
|
||||
display: flex;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
width: 60rpx;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.search-icon {
|
||||
display: block;
|
||||
color: #b4b4b4;
|
||||
font-size: 28rpx
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
|
||||
input {
|
||||
font-size: 28rpx;
|
||||
height: 64rpx;
|
||||
display: flex;
|
||||
|
||||
.input-placeholder {
|
||||
color: #aba9a9
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.shop-avatar {
|
||||
width: 200rpx;
|
||||
margin-right: 24rpx
|
||||
}
|
||||
|
||||
// 搜索按钮
|
||||
.search-button {
|
||||
width: 25%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.button {
|
||||
height: 64rpx;
|
||||
font-size: 28rpx;
|
||||
border-radius: 0 5px 5px 0;
|
||||
background: #2C71C7
|
||||
}
|
||||
}
|
||||
|
||||
.shop-info {
|
||||
width: 100%;
|
||||
margin-left: 20rpx;
|
||||
|
||||
.title {
|
||||
font-size: 38rpx;
|
||||
font-weight: bold;
|
||||
padding-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.u-body-item {
|
||||
align-items: stretch !important
|
||||
}
|
||||
</style>
|
||||
402
package/footmark/components/goods.vue
Executable file
402
package/footmark/components/goods.vue
Executable file
@@ -0,0 +1,402 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ use: false }" :up="upOption"
|
||||
:bottombar="false" @up="upCallback">
|
||||
<view class="cate-content">
|
||||
<!-- 商品列表 -->
|
||||
<view class="goods-list">
|
||||
<view class="goods-item--container" v-for="(item, index) in goodsList.data" :key="index">
|
||||
<view class="goods-item" @click="onTargetGoods(item.goods_id)">
|
||||
<!-- 商品图片 -->
|
||||
<view class="goods-item_left">
|
||||
<image class="image" :src="item.goods_image"></image>
|
||||
</view>
|
||||
<view class="goods-item_right">
|
||||
<!-- 商品标题 -->
|
||||
<view class="goods-name">
|
||||
<text class="twoline-hide">{{ item.goods_name }}</text>
|
||||
</view>
|
||||
<view class="item-prices oneline-hide">
|
||||
<text class="goods-sales">已售{{ item.goods_sales }}件</text>
|
||||
</view>
|
||||
<!-- 商品信息 -->
|
||||
<view class="goods-item_desc">
|
||||
<view class="desc_footer">
|
||||
<view class="item-prices oneline-hide">
|
||||
<text class="price_x">¥{{ item.goods_price_min }}</text>
|
||||
<!-- 商品销量 -->
|
||||
<text v-if="item.line_price_min > 0"
|
||||
class="price_y">¥{{ item.line_price_min }}</text>
|
||||
</view>
|
||||
<view class="buy-gouwuche">
|
||||
<u-button size="mini" @click="handleAddCart(item)">取消收藏
|
||||
</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 加入购物车组件 -->
|
||||
<AddCartPopup ref="AddCartPopup" @addCart="onUpdateCartTabBadge" />
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import {
|
||||
getEmptyPaginateObj,
|
||||
getMoreListData,
|
||||
setCartTabBadge
|
||||
} from '@/core/app'
|
||||
import {
|
||||
PageCategoryStyleEnum
|
||||
} from '@/common/enum/store/page/category'
|
||||
import Empty from '@/components/empty'
|
||||
import AddCartBtn from '@/components/add-cart-btn'
|
||||
import AddCartPopup from '@/components/add-cart-popup'
|
||||
import {
|
||||
rpx2px
|
||||
} from '@/utils/util'
|
||||
import * as GoodsApi from '@/api/goods'
|
||||
|
||||
const pageSize = 15
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody,
|
||||
Empty,
|
||||
AddCartBtn,
|
||||
AddCartPopup
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
props: {
|
||||
// 分类列表
|
||||
list: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
PageCategoryStyleEnum,
|
||||
// 列表高度
|
||||
scrollHeight: 0,
|
||||
// 一级分类:指针
|
||||
curIndex: -1,
|
||||
// 商品列表
|
||||
goodsList: getEmptyPaginateObj(),
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: {
|
||||
size: pageSize
|
||||
},
|
||||
// 数量要大于3条才显示无更多数据
|
||||
noMoreSize: 3,
|
||||
// 返回顶部
|
||||
toTop: {
|
||||
right: 30,
|
||||
bottom: 48,
|
||||
zIndex: 9
|
||||
}
|
||||
},
|
||||
|
||||
sortPrice: false, // 价格排序 (true高到低 false低到高)
|
||||
sortType: 'hot', // 排序类型
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 设置分类列表高度
|
||||
this.setListHeight()
|
||||
},
|
||||
methods: {
|
||||
|
||||
// 切换排序方式
|
||||
handleSortType(newSortType) {
|
||||
const app = this
|
||||
const newSortPrice = newSortType === 'price' ? !app.sortPrice : true
|
||||
app.sortType = newSortType
|
||||
app.sortPrice = newSortPrice
|
||||
// 刷新列表数据
|
||||
app.getGoodsList()
|
||||
},
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
console.log(page.num);
|
||||
app.getGoodsList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取商品列表
|
||||
* @param {Number} pageNo 页码
|
||||
*/
|
||||
getGoodsList(pageNo = 1) {
|
||||
const app = this
|
||||
const categoryId = app.curIndex > -1 ? app.list[app.curIndex].category_id : 0
|
||||
return new Promise((resolve, reject) => {
|
||||
GoodsApi.list({
|
||||
categoryId,
|
||||
page: pageNo,
|
||||
collection: true
|
||||
}, {
|
||||
load: false
|
||||
})
|
||||
.then(result => {
|
||||
const newList = result.data.list
|
||||
app.goodsList.data = getMoreListData(newList, app.goodsList, pageNo)
|
||||
app.goodsList.last_page = newList.last_page
|
||||
resolve(newList)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 设置列表内容的高度
|
||||
setListHeight() {
|
||||
const {
|
||||
windowHeight
|
||||
} = uni.getSystemInfoSync()
|
||||
this.scrollHeight = windowHeight - rpx2px(96)
|
||||
},
|
||||
|
||||
// 一级分类:选中分类
|
||||
handleSelectNav(index) {
|
||||
this.curIndex = index
|
||||
this.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新列表数据
|
||||
onRefreshList() {
|
||||
this.goodsList = getEmptyPaginateObj()
|
||||
setTimeout(() => this.mescroll.resetUpScroll(), 120)
|
||||
},
|
||||
|
||||
// 跳转至商品列表页
|
||||
onTargetGoods(goodsId) {
|
||||
this.$navTo('pages/goods/detail', {
|
||||
goodsId
|
||||
})
|
||||
},
|
||||
|
||||
// 点击加入购物车
|
||||
handleAddCart(item) {
|
||||
GoodsApi.collection({goodsId: item.})
|
||||
this.$emit('addCart')
|
||||
},
|
||||
|
||||
// 更新购物车角标
|
||||
onUpdateCartTabBadge() {
|
||||
console.log('onUpdateCartTabBadge')
|
||||
setCartTabBadge()
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
background-color: #F6F6F6 !important;
|
||||
}
|
||||
|
||||
// 分类内容
|
||||
.cate-content {
|
||||
z-index: 1;
|
||||
background-color: #F6F6F6 !important;
|
||||
padding-top: 0rpx;
|
||||
}
|
||||
|
||||
// 一级分类+二级分类 20
|
||||
.cate-left {
|
||||
width: 173rpx;
|
||||
height: 100%;
|
||||
background: #f8f8f8;
|
||||
color: #444;
|
||||
|
||||
position: fixed;
|
||||
top: calc(286rpx + var(--window-top));
|
||||
left: var(--window-left);
|
||||
bottom: var(--window-bottom);
|
||||
}
|
||||
|
||||
// 左侧一级分类
|
||||
.type-nav {
|
||||
position: relative;
|
||||
height: 90rpx;
|
||||
z-index: 10;
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&.selected {
|
||||
background: #fff;
|
||||
border-right: none;
|
||||
font-size: 28rpx;
|
||||
color: $main-bg
|
||||
}
|
||||
}
|
||||
|
||||
// 商品列表
|
||||
.goods-list {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.goods-item {
|
||||
padding: 28rpx 22rpx;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
padding: 20rpx;
|
||||
border: 1px solid #F6F6F6;
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.goods-item_left {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
margin-right: 20rpx;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 280rpx;
|
||||
height: 280rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_right {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
|
||||
.goods-name {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 68rpx;
|
||||
font-size: 34rpx;
|
||||
line-height: 1.3;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_desc {
|
||||
margin-top: 20rpx;
|
||||
|
||||
.people {
|
||||
margin-right: 14rpx;
|
||||
}
|
||||
|
||||
.desc_footer {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
position: absolute;
|
||||
right: 0rpx;
|
||||
bottom: 0rpx;
|
||||
min-height: 44rpx;
|
||||
|
||||
.item-prices {
|
||||
padding-right: 6rpx;
|
||||
|
||||
.price_x {
|
||||
margin-right: 14rpx;
|
||||
font-weight: 600;
|
||||
color: #ff0000;
|
||||
font-size: 38rpx;
|
||||
}
|
||||
|
||||
.price_y {
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.goods-sales {
|
||||
padding-top: 8rpx !important;
|
||||
color: #b3b3b3 !important;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
background: #fff;
|
||||
border-radius: 14rpx;
|
||||
padding: 20rpx 4rpx;
|
||||
box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.07);
|
||||
}
|
||||
|
||||
// 排序组件
|
||||
.store-sort {
|
||||
margin-top: 24rpx;
|
||||
position: sticky;
|
||||
top: var(--window-top);
|
||||
display: flex;
|
||||
padding: 20rpx 0;
|
||||
font-size: 28rpx;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
z-index: 99;
|
||||
|
||||
.sort-item {
|
||||
flex-basis: 33.3333%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 50rpx;
|
||||
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
}
|
||||
}
|
||||
|
||||
.sort-item-price .price-arrow {
|
||||
margin-left: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #000;
|
||||
|
||||
.icon {
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
}
|
||||
|
||||
&.up {
|
||||
margin-bottom: -16rpx;
|
||||
}
|
||||
|
||||
&.down {
|
||||
margin-top: -16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
398
package/footmark/index.vue
Executable file
398
package/footmark/index.vue
Executable file
@@ -0,0 +1,398 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ use: false }" :up="upOption"
|
||||
:bottombar="false" @up="upCallback">
|
||||
<view class="cate-content">
|
||||
<!-- 商品列表 -->
|
||||
<view class="goods-list">
|
||||
<view class="goods-item--container" v-for="(item, index) in goodsList.data" :key="index">
|
||||
<view class="goods-item" @click="onTargetGoods(item.goods_id)">
|
||||
<!-- 商品图片 -->
|
||||
<view class="goods-item_left">
|
||||
<image class="image" :src="item.goods_image"></image>
|
||||
</view>
|
||||
<view class="goods-item_right">
|
||||
<!-- 商品标题 -->
|
||||
<view class="goods-name">
|
||||
<text class="twoline-hide">{{ item.goods_name }}</text>
|
||||
</view>
|
||||
<view class="item-prices oneline-hide">
|
||||
<text class="goods-sales">已售{{ item.goods_sales }}件</text>
|
||||
</view>
|
||||
<!-- 商品信息 -->
|
||||
<view class="goods-item_desc">
|
||||
<view class="desc_footer">
|
||||
<view class="item-prices oneline-hide">
|
||||
<text class="price_x">¥{{ item.goods_price_min }}</text>
|
||||
<!-- 商品销量 -->
|
||||
<text v-if="item.line_price_min > 0"
|
||||
class="price_y">¥{{ item.line_price_min }}</text>
|
||||
</view>
|
||||
<!-- <view class="buy-gouwuche">
|
||||
<u-button size="mini" @click="handleAddCart(item)">取消收藏
|
||||
</u-button>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import {
|
||||
getEmptyPaginateObj,
|
||||
getMoreListData,
|
||||
setCartTabBadge
|
||||
} from '@/core/app'
|
||||
import {
|
||||
PageCategoryStyleEnum
|
||||
} from '@/common/enum/store/page/category'
|
||||
import Empty from '@/components/empty'
|
||||
import AddCartBtn from '@/components/add-cart-btn'
|
||||
import AddCartPopup from '@/components/add-cart-popup'
|
||||
import {
|
||||
rpx2px
|
||||
} from '@/utils/util'
|
||||
import * as GoodsApi from '@/api/goods'
|
||||
|
||||
const pageSize = 15
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody,
|
||||
Empty,
|
||||
AddCartBtn,
|
||||
AddCartPopup
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
PageCategoryStyleEnum,
|
||||
// 列表高度
|
||||
scrollHeight: 0,
|
||||
// 一级分类:指针
|
||||
curIndex: -1,
|
||||
// 商品列表
|
||||
goodsList: getEmptyPaginateObj(),
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: {
|
||||
size: pageSize
|
||||
},
|
||||
// 数量要大于3条才显示无更多数据
|
||||
noMoreSize: 3,
|
||||
// 返回顶部
|
||||
toTop: {
|
||||
right: 30,
|
||||
bottom: 48,
|
||||
zIndex: 9
|
||||
}
|
||||
},
|
||||
|
||||
sortPrice: false, // 价格排序 (true高到低 false低到高)
|
||||
sortType: 'hot', // 排序类型
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 设置分类列表高度
|
||||
this.setListHeight()
|
||||
},
|
||||
methods: {
|
||||
|
||||
// 切换排序方式
|
||||
handleSortType(newSortType) {
|
||||
const app = this
|
||||
const newSortPrice = newSortType === 'price' ? !app.sortPrice : true
|
||||
app.sortType = newSortType
|
||||
app.sortPrice = newSortPrice
|
||||
// 刷新列表数据
|
||||
app.getGoodsList()
|
||||
},
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
console.log(page.num);
|
||||
app.getGoodsList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取商品列表
|
||||
* @param {Number} pageNo 页码
|
||||
*/
|
||||
getGoodsList(pageNo = 1) {
|
||||
const app = this
|
||||
const categoryId = app.curIndex > -1 ? app.list[app.curIndex].category_id : 0
|
||||
const userId = uni.getStorageSync('userId')
|
||||
const arr = uni.getStorageSync(`FOOTMARKLIST_${userId}`) || []
|
||||
console.log(arr);
|
||||
return new Promise((resolve, reject) => {
|
||||
GoodsApi.list({
|
||||
categoryId,
|
||||
page: pageNo,
|
||||
footMark: true,
|
||||
goodsIds: JSON.stringify(arr)
|
||||
}, {
|
||||
load: false
|
||||
})
|
||||
.then(result => {
|
||||
const newList = result.data.list
|
||||
app.goodsList.data = getMoreListData(newList, app.goodsList, pageNo)
|
||||
app.goodsList.last_page = newList.last_page
|
||||
resolve(newList)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 设置列表内容的高度
|
||||
setListHeight() {
|
||||
const {
|
||||
windowHeight
|
||||
} = uni.getSystemInfoSync()
|
||||
this.scrollHeight = windowHeight - rpx2px(96)
|
||||
},
|
||||
|
||||
// 一级分类:选中分类
|
||||
handleSelectNav(index) {
|
||||
this.curIndex = index
|
||||
this.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新列表数据
|
||||
onRefreshList() {
|
||||
this.goodsList = getEmptyPaginateObj()
|
||||
setTimeout(() => this.mescroll.resetUpScroll(), 120)
|
||||
},
|
||||
|
||||
// 跳转至商品列表页
|
||||
onTargetGoods(goodsId) {
|
||||
this.$navTo('pages/goods/detail', {
|
||||
goodsId
|
||||
})
|
||||
},
|
||||
|
||||
// 点击加入购物车
|
||||
handleAddCart(item) {
|
||||
GoodsApi.collection({goodsId: item.goods_id}).then(() => {
|
||||
this.getGoodsList()
|
||||
})
|
||||
},
|
||||
|
||||
// 更新购物车角标
|
||||
onUpdateCartTabBadge() {
|
||||
console.log('onUpdateCartTabBadge')
|
||||
setCartTabBadge()
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
background-color: #F6F6F6 !important;
|
||||
}
|
||||
|
||||
// 分类内容
|
||||
.cate-content {
|
||||
z-index: 1;
|
||||
background-color: #F6F6F6 !important;
|
||||
padding-top: 0rpx;
|
||||
}
|
||||
|
||||
// 一级分类+二级分类 20
|
||||
.cate-left {
|
||||
width: 173rpx;
|
||||
height: 100%;
|
||||
background: #f8f8f8;
|
||||
color: #444;
|
||||
|
||||
position: fixed;
|
||||
top: calc(286rpx + var(--window-top));
|
||||
left: var(--window-left);
|
||||
bottom: var(--window-bottom);
|
||||
}
|
||||
|
||||
// 左侧一级分类
|
||||
.type-nav {
|
||||
position: relative;
|
||||
height: 90rpx;
|
||||
z-index: 10;
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&.selected {
|
||||
background: #fff;
|
||||
border-right: none;
|
||||
font-size: 28rpx;
|
||||
color: $main-bg
|
||||
}
|
||||
}
|
||||
|
||||
// 商品列表
|
||||
.goods-list {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.goods-item {
|
||||
padding: 28rpx 22rpx;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
padding: 20rpx;
|
||||
border: 1px solid #F6F6F6;
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.goods-item_left {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
margin-right: 20rpx;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 280rpx;
|
||||
height: 280rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_right {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
|
||||
.goods-name {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 68rpx;
|
||||
font-size: 34rpx;
|
||||
line-height: 1.3;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_desc {
|
||||
margin-top: 20rpx;
|
||||
|
||||
.people {
|
||||
margin-right: 14rpx;
|
||||
}
|
||||
|
||||
.desc_footer {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
position: absolute;
|
||||
right: 0rpx;
|
||||
bottom: 0rpx;
|
||||
min-height: 44rpx;
|
||||
|
||||
.item-prices {
|
||||
padding-right: 6rpx;
|
||||
|
||||
.price_x {
|
||||
margin-right: 14rpx;
|
||||
font-weight: 600;
|
||||
color: #ff0000;
|
||||
font-size: 38rpx;
|
||||
}
|
||||
|
||||
.price_y {
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.goods-sales {
|
||||
padding-top: 8rpx !important;
|
||||
color: #b3b3b3 !important;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
background: #fff;
|
||||
border-radius: 14rpx;
|
||||
padding: 20rpx 4rpx;
|
||||
box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.07);
|
||||
}
|
||||
|
||||
// 排序组件
|
||||
.store-sort {
|
||||
margin-top: 24rpx;
|
||||
position: sticky;
|
||||
top: var(--window-top);
|
||||
display: flex;
|
||||
padding: 20rpx 0;
|
||||
font-size: 28rpx;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
z-index: 99;
|
||||
|
||||
.sort-item {
|
||||
flex-basis: 33.3333%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 50rpx;
|
||||
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
}
|
||||
}
|
||||
|
||||
.sort-item-price .price-arrow {
|
||||
margin-left: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #000;
|
||||
|
||||
.icon {
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
}
|
||||
|
||||
&.up {
|
||||
margin-bottom: -16rpx;
|
||||
}
|
||||
|
||||
&.down {
|
||||
margin-top: -16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
98
package/partner/partner.vue
Normal file
98
package/partner/partner.vue
Normal file
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<view class="partner">
|
||||
<view class="banner">
|
||||
<image src="https://dev.gxwebsoft.com/ylx/uploads/10001/20220815/d494a73f94f5e0a4b8562c77e5ec9ec3.jpg" class="banner" mode="widthFix"></image>
|
||||
</view>
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper">
|
||||
<u-form :model="form" ref="uForm" label-width="140rpx">
|
||||
<u-form-item label="姓名" prop="name">
|
||||
<u-input v-model="form.name" :disabled="disabled" placeholder="请输入姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="电话" prop="mobile">
|
||||
<u-input v-model="form.mobile" maxlength="11" :disabled="disabled" placeholder="请输入联系电话" />
|
||||
</u-form-item>
|
||||
<u-form-item label="性别" prop="sex">
|
||||
<u-radio-group v-model="form.sex" @change="groupChange">
|
||||
<u-radio label="1">男</u-radio>
|
||||
<u-radio label="2">女</u-radio>
|
||||
</u-radio-group>
|
||||
</u-form-item>
|
||||
<u-form-item label="投资预算" prop="weixin">
|
||||
<u-input type="number" v-model="form.yusuan" :disabled="disabled" placeholder="请输入投资预算" />
|
||||
</u-form-item>
|
||||
<u-form-item label="微信号" prop="weixin">
|
||||
<u-input v-model="form.weixin" :disabled="disabled" placeholder="请输入微信号" />
|
||||
</u-form-item>
|
||||
<u-form-item label="意向地区" prop="region">
|
||||
<select-region ref="sRegion" :disabled="disabled" v-model="form.region" />
|
||||
</u-form-item>
|
||||
<u-form-item label="整体需求" prop="comments">
|
||||
<u-input v-model="form.comments" :disabled="disabled" placeholder="请输入整体需求" />
|
||||
</u-form-item>
|
||||
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn">
|
||||
<u-button type="primary" shape="circle">提交申请</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 表单字段元素
|
||||
const form = {
|
||||
// 入驻类型 (合伙人10001,配送员10002,社区门店10003,省代10004)
|
||||
grade_id: 10004,
|
||||
company: '',
|
||||
real_name: '',
|
||||
phone: '',
|
||||
mobile: '',
|
||||
region: [],
|
||||
detail: '',
|
||||
}
|
||||
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form,
|
||||
disabled: false,
|
||||
imageList: []
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
groupChange(){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.partner {
|
||||
|
||||
.banner {
|
||||
width: 100%;
|
||||
}
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
.footer{
|
||||
width: 500rpx;
|
||||
margin: 20rpx auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
275
package/salesman/profit/index.vue
Normal file
275
package/salesman/profit/index.vue
Normal file
@@ -0,0 +1,275 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ use: false }" :up="upOption"
|
||||
@up="upCallback">
|
||||
|
||||
<!-- tab栏 -->
|
||||
<u-tabs :list="tabList" :is-scroll="false" :current="curTab" active-color="#0f80ff" :duration="0.2"
|
||||
@change="onChangeTab" />
|
||||
|
||||
<!-- 列表数据 -->
|
||||
<view class="widget-list">
|
||||
<view class="widget__detail dis-flex flex-x-between" v-for="(item, index) in list.data" :key="index">
|
||||
<view class="detail__left dis-flex flex-dir-column flex-x-around">
|
||||
<view class="detail__time col-9 f-24 order-no">订单号:2022092457995352</view>
|
||||
<view class="detail__money f-30">
|
||||
<u-avatar size="mini" mode="circle" v-if="item.sendUser" :src="item.sendUser.avatar_url">
|
||||
</u-avatar>
|
||||
<view class="content">
|
||||
<text>{{ item.sendUser.nick_name }}</text>
|
||||
<text class="detail__time col-9 f-24">消费金额:¥268.00</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="detail__right dis-flex flex-dir-column flex-x-center flex-y-center">
|
||||
<view class="detail__status f-28">
|
||||
<text>已完成</text>
|
||||
<view>+ 56.00</view>
|
||||
<!-- <u-tag v-if="item.status == 0" type="error" text="未结算"></u-tag>
|
||||
<u-tag v-if="item.status == 1" type="success" text="已结算"></u-tag> -->
|
||||
</view>
|
||||
<view class="detail__time col-9 f-24">{{ item.create_time }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import {
|
||||
getEmptyPaginateObj,
|
||||
getMoreListData
|
||||
} from '@/core/app'
|
||||
import * as Api from '@/api/user/notice.js'
|
||||
import SettingModel from '@/common/model/dealer/Setting'
|
||||
import {
|
||||
ApplyStatusEnum
|
||||
} from '@/common/enum/dealer/withdraw'
|
||||
|
||||
const pageSize = 15
|
||||
// 提现状态文字
|
||||
const ApplyStatusText = [0, 1]
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
ApplyStatusEnum,
|
||||
ApplyStatusText,
|
||||
// 选项卡列表
|
||||
tabList: [],
|
||||
// 当前选项
|
||||
curTab: 0,
|
||||
// 列表数据
|
||||
list: getEmptyPaginateObj(),
|
||||
shopId: 0,
|
||||
showReasonMsg: false,
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: {
|
||||
size: pageSize
|
||||
},
|
||||
// 数量要大于12条才显示无更多数据
|
||||
noMoreSize: 12,
|
||||
// 空布局
|
||||
empty: {
|
||||
tip: '亲,暂无收益数据'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
this.getSetting()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取分销设置
|
||||
getSetting() {
|
||||
const app = this
|
||||
SettingModel.data()
|
||||
.then(setting => {
|
||||
const words = setting.words.withdraw_list
|
||||
app.setTabList(words.words)
|
||||
})
|
||||
},
|
||||
|
||||
// 设置选项卡数据
|
||||
setTabList(words) {
|
||||
const app = this
|
||||
app.tabList = [
|
||||
{
|
||||
value: 0,
|
||||
name: '全部'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
triggerReasonMsg() {
|
||||
this.showReasonMsg = !this.showReasonMsg
|
||||
},
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
app.getList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
// 获取提现列表
|
||||
getList(pageNo = 1) {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
Api.list({
|
||||
page: pageNo
|
||||
})
|
||||
.then(result => {
|
||||
// 合并新数据
|
||||
const newList = result.data.list
|
||||
app.list.data = getMoreListData(newList, app.list, pageNo)
|
||||
resolve(newList)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 获取当前标签项的值
|
||||
getTabValue() {
|
||||
const app = this
|
||||
if (app.tabList.length) {
|
||||
return app.tabList[app.curTab].value
|
||||
}
|
||||
return 1
|
||||
},
|
||||
|
||||
// 切换标签项
|
||||
onChangeTab(index) {
|
||||
const app = this
|
||||
// 设置当前选中的标签
|
||||
app.curTab = index
|
||||
// 刷新订单列表
|
||||
app.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新列表数据
|
||||
onRefreshList() {
|
||||
this.list = getEmptyPaginateObj()
|
||||
setTimeout(() => {
|
||||
this.mescroll.resetUpScroll()
|
||||
}, 120)
|
||||
},
|
||||
|
||||
// 设为已读
|
||||
onRead(id, content) {
|
||||
const app = this
|
||||
uni.showModal({
|
||||
title: '查看消息',
|
||||
content,
|
||||
showCancel: false,
|
||||
success({ confirm }) {
|
||||
Api.status({id}).then(res => {
|
||||
app.getList()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
// 提现明细列表
|
||||
.widget-list {
|
||||
padding: 10rpx 20rpx 40rpx 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.widget__detail {
|
||||
padding: 20rpx 15rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 28rpx;
|
||||
border-bottom: 1rpx solid #e7e7e7;
|
||||
}
|
||||
|
||||
.widget__detail .detail__money {
|
||||
font-size: 30rpx;
|
||||
margin-bottom: 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.widget__detail .detail__reason {
|
||||
margin-top: 15rpx;
|
||||
color: #0f80ff;
|
||||
}
|
||||
|
||||
.show-reason-msg {
|
||||
padding: 20rpx;
|
||||
line-height: 2rem;
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
.detail__left {
|
||||
.iconfont {
|
||||
margin-left: 30rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.icon-weixin {
|
||||
color: #0eaf00;
|
||||
}
|
||||
|
||||
.icon-alipay {
|
||||
color: #0f80ff;
|
||||
}
|
||||
}
|
||||
|
||||
.detail__status {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.detail__money {
|
||||
.content {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-left: 10rpx;
|
||||
}
|
||||
}
|
||||
.modal-content{
|
||||
padding: 20rpx;
|
||||
}
|
||||
.order-no{
|
||||
line-height: 2rem;
|
||||
}
|
||||
</style>
|
||||
84
package/salesman/qrcode/index.vue
Normal file
84
package/salesman/qrcode/index.vue
Normal file
@@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<view class="partner">
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper">
|
||||
<view class="item-list">
|
||||
<image :src="shopPosterUrl" mode="widthFix"></image>
|
||||
<text>推广商户二维码</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-wrapper">
|
||||
<view class="item-list">
|
||||
<image :src="userPosterUrl" mode="widthFix"></image>
|
||||
<text>推广用户二维码</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as Api from '@/api/dealer/poster'
|
||||
export default {
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
shopPosterUrl: undefined,
|
||||
userPosterUrl: undefined
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.getPoster()
|
||||
},
|
||||
methods: {
|
||||
// 获取推广二维码
|
||||
getPoster() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
Api.qrcode({ channel: app.platform })
|
||||
.then(result => {
|
||||
// api数据赋值
|
||||
app.shopPosterUrl = result.data.shopPosterUrl
|
||||
app.userPosterUrl = result.data.userPosterUrl
|
||||
})
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.partner {
|
||||
|
||||
.banner {
|
||||
width: 100%;
|
||||
}
|
||||
.form-wrapper {
|
||||
margin: 30rpx auto 50rpx auto;
|
||||
padding: 30rpx 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
.item-list{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
image{
|
||||
width: 70%;
|
||||
margin: auto;
|
||||
}
|
||||
text{
|
||||
line-height: 2rem;
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
.footer{
|
||||
width: 500rpx;
|
||||
margin: 20rpx auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
303
package/salesman/storehouse/index.vue
Normal file
303
package/salesman/storehouse/index.vue
Normal file
@@ -0,0 +1,303 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- 展馆图标 -->
|
||||
<!-- <view class="header-box">
|
||||
<view class="location" @click="changeCity">
|
||||
<image src="../../static/postion.svg"></image><text>南宁</text>
|
||||
</view>
|
||||
<view class="search-wrapper">
|
||||
<view class="search-input">
|
||||
<view class="search-input-wrapper">
|
||||
<view class="left">
|
||||
<text class="search-icon iconfont icon-search"></text>
|
||||
</view>
|
||||
<view class="right">
|
||||
<input v-model="searchValue" class="input" focus="true" placeholder="请输入您搜索的商品"
|
||||
type="text"></input>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="search-button">
|
||||
<button class="button" @click="onSearch" type="warn">搜索</button>
|
||||
</view>
|
||||
</view>
|
||||
</view> -->
|
||||
<!-- 门店列表 -->
|
||||
<view class="shop-list">
|
||||
<u-card v-for="(item, index) in shopList" :key="index" @click="onSelectedShop(item)"
|
||||
class="shop-item dis-flex flex-y-center" :border="false" :box-shadow="true" :show-head="false"
|
||||
:head-border-bottom="false">
|
||||
<view class="" slot="body">
|
||||
<view class="shop-item__content flex-box">
|
||||
<view class="u-body-item u-flex u-col-between u-p-t-0">
|
||||
<u-avatar :src="item.logoUrl" :size="120" mode="square" :show-level="true" ></u-avatar>
|
||||
<view class="shop-info">
|
||||
<view class="title">{{item.shopName}}</view>
|
||||
<view class="address">站点地址:{{ item.region.province }}{{ item.region.city }}{{ item.region.region }}{{ item.address }}</view>
|
||||
<view class="address">获得收益:<text class="first-commission-money">¥{{ item.firstCommissionMoney }}</text></view>
|
||||
<!-- <view v-if="item.distance" class="shop-item__distance">
|
||||
<text class="iconfont icon-dingwei"></text>
|
||||
<text class="f-24">{{ item.distance_unit }}</text>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 选中状态 -->
|
||||
<!-- <view v-if="item.shop_id == selectedId" class="shop-item__right">
|
||||
<text class="iconfont icon-check1"></text>
|
||||
</view> -->
|
||||
</view>
|
||||
</u-card>
|
||||
</view>
|
||||
<!-- 定位按钮 -->
|
||||
<view v-if="!isAuthor" class="widget-location dis-flex flex-x-center flex-y-center" @click="onAuthorize()">
|
||||
<text class="iconfont icon-locate"></text>
|
||||
</view>
|
||||
<empty v-if="!shopList.length" :isLoading="isLoading" tips="亲,暂无自提门店哦" />
|
||||
|
||||
<!-- <view class="shop-list">
|
||||
<u-card v-for="(item,index) in list" :key="index" :border="false" :box-shadow="true" :show-head="false"
|
||||
:head-border-bottom="false">
|
||||
<view class="" slot="body">
|
||||
<view class="u-body-item u-flex u-col-between u-p-t-0">
|
||||
<image class="shop-avatar"
|
||||
:src="item.logo_url"
|
||||
mode="widthFix"></image>
|
||||
<view class="shop-info">
|
||||
<view class="title">{{item.shop_name}}</view>
|
||||
<view class="about">{{item.summary}}</view>
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</u-card>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Search from '@/components/page/diyComponents/search/index.vue'
|
||||
import {
|
||||
getMoreListData
|
||||
} from '@/core/app'
|
||||
import * as ShopApi from '@/api/shop.js'
|
||||
import Empty from '@/components/empty'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Search,
|
||||
Empty
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: '国内馆',
|
||||
// 正在加载中
|
||||
isLoading: true,
|
||||
// 是否授权了定位权限
|
||||
isAuthor: true,
|
||||
// 当前选择的门店ID
|
||||
selectedId: null,
|
||||
// 订单列表数据
|
||||
shopList: [],
|
||||
|
||||
}
|
||||
},
|
||||
onLoad({
|
||||
selectedId
|
||||
}) {
|
||||
const app = this
|
||||
// 记录当前选择的门店ID
|
||||
app.selectedId = selectedId ? selectedId : null
|
||||
// 获取默认门店列表
|
||||
app.getShopList()
|
||||
// 获取用户坐标
|
||||
app.getLocation(res => {
|
||||
app.getShopList(res.longitude, res.latitude)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// 获取门店列表
|
||||
getShopList(longitude, latitude) {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
ShopApi.list({
|
||||
isCheck: 1,
|
||||
longitude,
|
||||
latitude,
|
||||
dealerReferee: true
|
||||
})
|
||||
.then(result => app.shopList = result.data.list)
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 获取用户坐标
|
||||
// 参考文档:https://uniapp.dcloud.io/api/location/location?id=getlocation
|
||||
getLocation(callback) {
|
||||
const app = this
|
||||
uni.getLocation({
|
||||
type: 'wgs84',
|
||||
success: callback,
|
||||
fail() {
|
||||
app.$toast('获取定位失败,请点击右下角按钮重新尝试定位')
|
||||
app.isAuthor = false
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 授权启用定位权限
|
||||
onAuthorize() {
|
||||
const app = this
|
||||
// #ifdef MP
|
||||
uni.openSetting({
|
||||
success(res) {
|
||||
if (res.authSetting['scope.userLocation']) {
|
||||
console.log('定位权限授权成功')
|
||||
app.isAuthor = true
|
||||
setTimeout(() => {
|
||||
// 获取用户坐标
|
||||
app.getLocation((res) => {
|
||||
app.getShopList(res.longitude, res.latitude)
|
||||
})
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
// 获取用户坐标
|
||||
app.getLocation((res) => {
|
||||
app.getShopList(res.longitude, res.latitude)
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
|
||||
/**
|
||||
* 选择门店
|
||||
*/
|
||||
onSelectedShop(item) {
|
||||
this.$navTo('package/shops/detail/index',item)
|
||||
},
|
||||
|
||||
changeCity() {
|
||||
this.$toast('切换区域')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bg {
|
||||
background-color: #F5F5F8
|
||||
}
|
||||
|
||||
.shop-list {
|
||||
.shop-item {
|
||||
}
|
||||
}
|
||||
|
||||
.header-box {
|
||||
padding: 20rpx 36rpx 0 36rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.location {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
width: 60rpx;
|
||||
height: 60rpx
|
||||
}
|
||||
}
|
||||
|
||||
.u-subsection {
|
||||
width: 260rpx;
|
||||
margin-top: 7rpx
|
||||
}
|
||||
}
|
||||
|
||||
.search-wrapper {
|
||||
display: flex;
|
||||
width: 80%;
|
||||
height: 64rpx
|
||||
}
|
||||
|
||||
// 搜索输入框
|
||||
.search-input {
|
||||
width: 90%;
|
||||
background: #fff;
|
||||
border-radius: 10rpx 0 0 10rpx;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
|
||||
.search-input-wrapper {
|
||||
display: flex;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
width: 60rpx;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.search-icon {
|
||||
display: block;
|
||||
color: #b4b4b4;
|
||||
font-size: 28rpx
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
|
||||
input {
|
||||
font-size: 28rpx;
|
||||
height: 64rpx;
|
||||
display: flex;
|
||||
|
||||
.input-placeholder {
|
||||
color: #aba9a9
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.shop-avatar {
|
||||
width: 200rpx;
|
||||
margin-right: 24rpx
|
||||
}
|
||||
|
||||
// 搜索按钮
|
||||
.search-button {
|
||||
width: 25%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.button {
|
||||
height: 64rpx;
|
||||
font-size: 28rpx;
|
||||
border-radius: 0 5px 5px 0;
|
||||
background: #2C71C7
|
||||
}
|
||||
}
|
||||
|
||||
.shop-info {
|
||||
width: 100%;
|
||||
margin-left: 20rpx;
|
||||
|
||||
.title {
|
||||
font-size: 38rpx;
|
||||
font-weight: bold;
|
||||
padding-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.u-body-item {
|
||||
align-items: stretch !important
|
||||
}
|
||||
.first-commission-money{
|
||||
color: #ff0000;
|
||||
}
|
||||
</style>
|
||||
321
package/shops/detail/components/commodity.vue
Executable file
321
package/shops/detail/components/commodity.vue
Executable file
@@ -0,0 +1,321 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<!-- 一级分类 -->
|
||||
<scroll-view class="cate-left" :scroll-y="true" :style="{ height: `${scrollHeight}px` }">
|
||||
<text class="type-nav" :class="{ selected: curIndex == -1 }" @click="handleSelectNav(-1)">全部</text>
|
||||
<text class="type-nav" :class="{ selected: curIndex == index }" v-for="(item, index) in list" :key="index"
|
||||
@click="handleSelectNav(index)">{{ item.name }}</text>
|
||||
</scroll-view>
|
||||
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ use: false }" :up="upOption" :bottombar="false" @up="upCallback">
|
||||
<view class="cate-content">
|
||||
<!-- 设备列表 -->
|
||||
<view class="equipment-list">
|
||||
<view class="equipment-item--container" v-for="(item, index) in equipmentList.data" :key="index">
|
||||
<view class="equipment-item" @click="onTargetEquipment(item.equipment_id)">
|
||||
<!-- 设备图片 -->
|
||||
<view class="equipment-item_left">
|
||||
<image class="image" :src="item.equipment_image"></image>
|
||||
</view>
|
||||
<view class="equipment-item_right">
|
||||
<!-- 设备标题 -->
|
||||
<view class="equipment-name">
|
||||
<text class="title">{{ item.equipment_name }}</text>
|
||||
<text class="desc">可租 {{ item.stock_total }} 个</text>
|
||||
</view>
|
||||
<!-- 设备信息 -->
|
||||
<view class="equipment-item_desc">
|
||||
<view class="desc_footer">
|
||||
<view class="item-prices oneline-hide">
|
||||
<text class="price_x">¥{{ item.equipment_price_min }}/月</text>
|
||||
<!-- <text v-if="item.line_price_min > 0" class="price_y">¥{{ item.line_price_min }}</text> -->
|
||||
</view>
|
||||
<u-button size="mini" type="warning" @click="onTargetEquipment(item.equipment_id)">立即租用</u-button>
|
||||
<!-- <add-cart-btn v-if="setting.showAddCart" :btnStyle="setting.cartStyle" @click="handleAddCart(item)" /> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 加入购物车组件 -->
|
||||
<AddCartPopup ref="AddCartPopup" @addCart="onUpdateCartTabBadge" />
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import { getEmptyPaginateObj, getMoreListData, setCartTabBadge } from '@/core/app'
|
||||
import { PageCategoryStyleEnum } from '@/common/enum/store/page/category'
|
||||
import Empty from '@/components/empty'
|
||||
import AddCartBtn from '@/components/add-cart-btn'
|
||||
import AddCartPopup from '@/components/add-cart-popup'
|
||||
import { rpx2px } from '@/utils/util'
|
||||
import * as EquipmentApi from '@/api/equipment'
|
||||
import storage from '@/utils/storage'
|
||||
|
||||
const pageSize = 15
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody,
|
||||
Empty,
|
||||
AddCartBtn,
|
||||
AddCartPopup
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
props: {
|
||||
// 分类列表
|
||||
list: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
// 分类设置
|
||||
setting: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
// 店铺ID
|
||||
shopId:{
|
||||
type: Number,
|
||||
default: 10001
|
||||
},
|
||||
// 设备名称搜索
|
||||
equipmentName:{
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
PageCategoryStyleEnum,
|
||||
// 列表高度
|
||||
scrollHeight: 0,
|
||||
// 一级分类:指针
|
||||
curIndex: -1,
|
||||
// 设备列表
|
||||
equipmentList: getEmptyPaginateObj(),
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: { size: pageSize },
|
||||
// 数量要大于3条才显示无更多数据
|
||||
noMoreSize: 3,
|
||||
// 返回顶部
|
||||
toTop: { right: 30, bottom: 48, zIndex: 9 }
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 设置分类列表高度
|
||||
this.setListHeight()
|
||||
},
|
||||
methods: {
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
app.getEquipmentList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取设备列表
|
||||
* @param {Number} pageNo 页码
|
||||
*/
|
||||
getEquipmentList(pageNo = 1) {
|
||||
const app = this
|
||||
const categoryId = app.curIndex > -1 ? app.list[app.curIndex].category_id : 0
|
||||
const { shopId, equipmentName } = this
|
||||
return new Promise((resolve, reject) => {
|
||||
EquipmentApi.list({ categoryId, page: pageNo, shopId, equipmentName, storeHouseEquipment: true }, { load: false })
|
||||
.then(result => {
|
||||
const newList = result.data.list
|
||||
app.equipmentList.data = getMoreListData(newList, app.equipmentList, pageNo)
|
||||
app.equipmentList.last_page = newList.last_page
|
||||
resolve(newList)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 设置列表内容的高度
|
||||
setListHeight() {
|
||||
const { windowHeight } = uni.getSystemInfoSync()
|
||||
this.scrollHeight = windowHeight - rpx2px(96)
|
||||
},
|
||||
|
||||
// 一级分类:选中分类
|
||||
handleSelectNav(index) {
|
||||
this.curIndex = index
|
||||
this.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新列表数据
|
||||
onRefreshList() {
|
||||
this.equipmentList = getEmptyPaginateObj()
|
||||
setTimeout(() => this.mescroll.resetUpScroll(), 120)
|
||||
},
|
||||
|
||||
// 跳转设备详情
|
||||
onTargetEquipment(equipmentId) {
|
||||
this.$navTo('package/equipment/detail', { equipmentId })
|
||||
},
|
||||
|
||||
// 点击加入购物车
|
||||
handleAddCart(item) {
|
||||
this.$refs.AddCartPopup.handle(item)
|
||||
this.$emit('addCart')
|
||||
},
|
||||
|
||||
// 更新购物车角标
|
||||
onUpdateCartTabBadge() {
|
||||
console.log('onUpdateCartTabBadge')
|
||||
setCartTabBadge()
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
padding-left: 173rpx;
|
||||
}
|
||||
|
||||
// 分类内容
|
||||
.cate-content {
|
||||
z-index: 1;
|
||||
background: #fff;
|
||||
padding-top: 286rpx;
|
||||
}
|
||||
|
||||
// 一级分类+二级分类 20
|
||||
.cate-left {
|
||||
width: 173rpx;
|
||||
height: 100%;
|
||||
background: #f8f8f8;
|
||||
color: #444;
|
||||
|
||||
position: fixed;
|
||||
top: calc(286rpx + var(--window-top));
|
||||
left: var(--window-left);
|
||||
bottom: var(--window-bottom);
|
||||
}
|
||||
|
||||
// 左侧一级分类
|
||||
.type-nav {
|
||||
position: relative;
|
||||
height: 90rpx;
|
||||
z-index: 10;
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&.selected {
|
||||
background: #fff;
|
||||
border-right: none;
|
||||
font-size: 28rpx;
|
||||
color: $main-bg
|
||||
}
|
||||
}
|
||||
|
||||
// 设备列表
|
||||
.equipment-list {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.equipment-item {
|
||||
padding: 28rpx 22rpx;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.equipment-item_left {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
margin-right: 20rpx;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.equipment-item_right {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
|
||||
.equipment-name {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
min-height: 68rpx;
|
||||
font-size: 28rpx;
|
||||
line-height: 1.3;
|
||||
color: #333;
|
||||
.title{
|
||||
font-weight: bold;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
.desc{
|
||||
color: #666;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.equipment-item_desc {
|
||||
margin-top: 20rpx;
|
||||
|
||||
.people {
|
||||
margin-right: 14rpx;
|
||||
}
|
||||
|
||||
.desc_footer {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
right: 0rpx;
|
||||
bottom: 0rpx;
|
||||
min-height: 44rpx;
|
||||
|
||||
.item-prices {
|
||||
padding-right: 6rpx;
|
||||
|
||||
.price_x {
|
||||
margin-right: 14rpx;
|
||||
color: #ff0000;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.price_y {
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
110
package/shops/detail/components/primary.vue
Executable file
110
package/shops/detail/components/primary.vue
Executable file
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<view class="primary">
|
||||
<!-- 一级分类(大图) 10 -->
|
||||
<view v-if="list.length > 0 && display == PageCategoryStyleEnum.ONE_LEVEL_BIG.value" class="cate-content">
|
||||
<view class="cate-wrapper cate_style__10">
|
||||
<view class="cate-item" v-for="(item, index) in list" :key="index" @click="onTargetGoodsList(item.category_id)">
|
||||
<image v-if="item.image" class="image" mode="widthFix" :src="item.image.preview_url"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 一级分类(小图) 11 -->
|
||||
<view v-if="list.length > 0 && display == PageCategoryStyleEnum.ONE_LEVEL_SMALL.value" class="cate-content">
|
||||
<view class="cate-wrapper cate_style__11">
|
||||
<view class="cate-item" v-for="(item, index) in list" :key="index" @click="onTargetGoodsList(item.category_id)">
|
||||
<image v-if="item.image" class="image" mode="widthFix" :src="item.image.preview_url"></image>
|
||||
<view class="cate-name">{{ item.name }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<empty v-if="!list.length" :tips="'亲,暂无商品分类' + display" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { PageCategoryStyleEnum } from '@/common/enum/store/page/category'
|
||||
import Empty from '@/components/empty'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Empty
|
||||
},
|
||||
props: {
|
||||
// 分类页样式
|
||||
display: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
// 分类列表
|
||||
list: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
PageCategoryStyleEnum,
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 跳转至商品列表页
|
||||
onTargetGoodsList(categoryId) {
|
||||
this.$navTo('pages/goods/list', { categoryId })
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 分类内容
|
||||
.cate-content {
|
||||
z-index: 1;
|
||||
background: #fff;
|
||||
padding-top: 396rpx;
|
||||
|
||||
.cate-wrapper {
|
||||
padding: 0 20rpx 20rpx 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
// 一级分类(大图) 10
|
||||
.cate_style__10 .cate-item {
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
// 一级分类(小图) 11
|
||||
.cate_style__11 .cate-item {
|
||||
float: left;
|
||||
padding: 25rpx;
|
||||
width: 33.3333%;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 33vw;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.cate-name {
|
||||
font-size: 28rpx;
|
||||
color: #555;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
94
package/shops/detail/components/search.vue
Executable file
94
package/shops/detail/components/search.vue
Executable file
@@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<view class="diy-search">
|
||||
<view class="inner" :class="itemStyle.searchStyle" @click="onTargetSearch">
|
||||
<view class="search-input" :style="{ textAlign: itemStyle.textAlign }">
|
||||
<text class="search-icon iconfont icon-search"></text>
|
||||
<input v-model="searchValue" class="input" @confirm="onSearch" focus="true" placeholder="请输入关键词"
|
||||
type="text"></input>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
searchValue: ''
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* 搜索提交
|
||||
*/
|
||||
onSearch() {
|
||||
const {
|
||||
searchValue
|
||||
} = this
|
||||
if (searchValue) {
|
||||
// 记录历史搜索
|
||||
this.setHistory(searchValue)
|
||||
// 跳转到商品列表页
|
||||
this.$navTo('pages/goods/list', {
|
||||
search: searchValue
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.diy-search {
|
||||
background: #e2f2fb;
|
||||
padding: 20rpx 40rpx;
|
||||
font-size: 26rpx;
|
||||
.inner {
|
||||
width: 360rpx;
|
||||
height: 60rpx;
|
||||
background: #fff;
|
||||
border-radius: 100rpx;
|
||||
overflow: hidden;
|
||||
|
||||
&.radius {
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
&.round {
|
||||
border-radius: 60rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.search-input {
|
||||
height: 60rpx;
|
||||
color: #999;
|
||||
padding: 0 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.search-icon {
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.flow-delivery {
|
||||
background-color: #2C71C7;
|
||||
padding: 10rpx 26rpx;
|
||||
color: #FFFFFF;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.col-title {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.my-order {
|
||||
border: 1px solid #fff;
|
||||
border-radius: 20rpx;
|
||||
padding: 0rpx 20rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
180
package/shops/detail/components/secondary.vue
Executable file
180
package/shops/detail/components/secondary.vue
Executable file
@@ -0,0 +1,180 @@
|
||||
<template>
|
||||
<view v-if="list.length > 0" class="secondary" :style="appThemeStyle">
|
||||
<!-- 二级分类 20 -->
|
||||
<view class="cate-content">
|
||||
<!-- 左侧 一级分类 -->
|
||||
<scroll-view class="cate-left" :scroll-y="true" :style="{ height: `${scrollHeight}px` }">
|
||||
<text class="type-nav" :class="{ selected: curIndex == index }" v-for="(item, index) in list" :key="index"
|
||||
@click="handleSelectNav(index)">{{ item.name }}</text>
|
||||
</scroll-view>
|
||||
<!-- 右侧 二级分类 -->
|
||||
<scroll-view class="cate-right" :scroll-top="scrollTop" :scroll-y="true" :style="{ height: `${scrollHeight}px` }">
|
||||
<view v-if="list[curIndex]" class="cate-right-cont">
|
||||
<view class="cate-two-box">
|
||||
<view class="cate-cont-box">
|
||||
<view class="flex-three" v-for="(item, idx) in list[curIndex].children" :key="idx" @click="onTargetGoodsList(item.category_id)">
|
||||
<view class="cate-img-padding">
|
||||
<view v-if="item.image" class="cate-img">
|
||||
<image class="image" mode="scaleToFill" :src="item.image.preview_url"></image>
|
||||
</view>
|
||||
</view>
|
||||
<text class="name oneline-hide">{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<empty v-if="!list.length" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { PageCategoryStyleEnum } from '@/common/enum/store/page/category'
|
||||
import Empty from '@/components/empty'
|
||||
import { rpx2px } from '@/utils/util'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Empty
|
||||
},
|
||||
props: {
|
||||
// 分类列表
|
||||
list: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
PageCategoryStyleEnum,
|
||||
// 列表高度
|
||||
scrollHeight: 0,
|
||||
// 一级分类:指针
|
||||
curIndex: 0,
|
||||
// 内容区竖向滚动条位置
|
||||
scrollTop: 0,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 设置分类列表高度
|
||||
this.setListHeight()
|
||||
},
|
||||
methods: {
|
||||
|
||||
// 设置列表内容的高度
|
||||
setListHeight() {
|
||||
const { windowHeight } = uni.getSystemInfoSync()
|
||||
this.scrollHeight = windowHeight - rpx2px(96)
|
||||
},
|
||||
|
||||
// 一级分类:选中分类
|
||||
handleSelectNav(index) {
|
||||
this.curIndex = index
|
||||
this.scrollTop = 0
|
||||
},
|
||||
|
||||
// 跳转至商品列表页
|
||||
onTargetGoodsList(categoryId) {
|
||||
this.$navTo('pages/goods/list', { categoryId })
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 分类内容
|
||||
.cate-content {
|
||||
display: flex;
|
||||
z-index: 1;
|
||||
background: #fff;
|
||||
padding-top: 96rpx;
|
||||
}
|
||||
|
||||
// 一级分类+二级分类 20
|
||||
.cate-left {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 0 0 23%;
|
||||
background: #f8f8f8;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.cate-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
.cate-right-cont {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
align-content: flex-start;
|
||||
padding-top: 15rpx;
|
||||
|
||||
.cate-two-box {
|
||||
width: 100%;
|
||||
padding: 0 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 左侧一级分类
|
||||
.type-nav {
|
||||
position: relative;
|
||||
height: 90rpx;
|
||||
z-index: 10;
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&.selected {
|
||||
background: #fff;
|
||||
color: $main-bg;
|
||||
border-right: none;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 右侧二级分类
|
||||
.cate-cont-box {
|
||||
margin-bottom: 30rpx;
|
||||
padding-bottom: 10rpx;
|
||||
background: #fff;
|
||||
overflow: hidden;
|
||||
|
||||
.name {
|
||||
display: block;
|
||||
padding-bottom: 30rpx;
|
||||
text-align: center;
|
||||
font-size: 26rpx;
|
||||
color: #444444;
|
||||
}
|
||||
|
||||
.cate-img-padding {
|
||||
padding: 16rpx 16rpx 4rpx 16rpx;
|
||||
}
|
||||
|
||||
.cate-img {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding-top: 100%;
|
||||
|
||||
.image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
177
package/shops/detail/components/shop-banner.vue
Executable file
177
package/shops/detail/components/shop-banner.vue
Executable file
@@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<view>
|
||||
<block v-if="shop.shopName">
|
||||
<!-- 搜索框 -->
|
||||
<view class="shop-banner" v-if="shop.backgroundUrl" :style="'background-image: url('+ shop.backgroundUrl +');background-size: 100%;'">
|
||||
<view class="shop-logo">
|
||||
<u-avatar :src="shop.logoUrl" :size="120" mode="square" :show-level="true"></u-avatar>
|
||||
</view>
|
||||
<view class="shop-info">
|
||||
<view class="title">{{shop.shopName}}
|
||||
<u-icon name="star-fill" color="#fd8008" v-if="shop.follow" @click="onFollow(shop.shopId)"></u-icon>
|
||||
<u-icon name="star" v-else @click="onFollow(shop.shopId)"></u-icon>
|
||||
</view>
|
||||
<!-- <view class="about">联系电话:{{ shop.phone }}</view> -->
|
||||
<view class="address">地址:{{ shop.fullAddress }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="shop-banner" v-else>
|
||||
<view class="shop-logo">
|
||||
<u-avatar :src="shop.logoUrl" :size="120" mode="square" :show-level="true"></u-avatar>
|
||||
</view>
|
||||
<view class="shop-info">
|
||||
<view class="title">{{shop.shopName}} 关注</view>
|
||||
<!-- <view class="about">联系电话:{{ shop.phone }}</view> -->
|
||||
<view class="address">地址:{{ shop.fullAddress }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="diy-search">
|
||||
<view class="inner">
|
||||
<view class="search-input">
|
||||
<text class="search-icon iconfont icon-search"></text>
|
||||
<input v-model="searchValue" class="input" @confirm="onSearch" focus="true" placeholder="请输入关键词"
|
||||
type="text"></input>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
tips: {
|
||||
type: String,
|
||||
default: '搜索商品'
|
||||
},
|
||||
shop: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
searchValue: ''
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onClick() {
|
||||
this.$emit('event')
|
||||
},
|
||||
onFollow(shopId){
|
||||
this.$emit('onFollow',shopId)
|
||||
},
|
||||
/**
|
||||
* 搜索提交
|
||||
*/
|
||||
onSearch() {
|
||||
const {
|
||||
searchValue
|
||||
} = this
|
||||
if (searchValue) {
|
||||
this.$emit('event', searchValue)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.shop-banner {
|
||||
background-color: #2C71C7;
|
||||
height: 200rpx;
|
||||
position: fixed;
|
||||
top: var(--window-top);
|
||||
left: var(--window-left);
|
||||
right: var(--window-right);
|
||||
z-index: 9;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.shop-logo {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 24rpx;
|
||||
}
|
||||
|
||||
.shop-logo image {
|
||||
width: 140rpx;
|
||||
height: 140rpx;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
.shop-info {
|
||||
width: 100%;
|
||||
margin-left: 20rpx;
|
||||
height: 140rpx;
|
||||
z-index: 10;
|
||||
color: #FFFFFF;
|
||||
|
||||
.title {
|
||||
font-size: 38rpx;
|
||||
font-weight: bold;
|
||||
padding-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.diy-search {
|
||||
width: 750rpx;
|
||||
background: #e2f2fb;
|
||||
padding: 20rpx 40rpx;
|
||||
font-size: 26rpx;
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
top: 200rpx;
|
||||
left: var(--window-left);
|
||||
right: var(--window-right);
|
||||
.inner {
|
||||
width: 360rpx;
|
||||
height: 60rpx;
|
||||
background: #fff;
|
||||
border-radius: 100rpx;
|
||||
overflow: hidden;
|
||||
|
||||
&.radius {
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
&.round {
|
||||
border-radius: 60rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.search-input {
|
||||
height: 60rpx;
|
||||
color: #999;
|
||||
padding: 0 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.search-icon {
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.flow-delivery {
|
||||
background-color: #2C71C7;
|
||||
padding: 10rpx 26rpx;
|
||||
color: #FFFFFF;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.col-title {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.my-order {
|
||||
border: 1px solid #fff;
|
||||
border-radius: 20rpx;
|
||||
padding: 0rpx 20rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
228
package/shops/detail/index.scss
Executable file
228
package/shops/detail/index.scss
Executable file
@@ -0,0 +1,228 @@
|
||||
.container {
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
// 110 - 18 + 4
|
||||
padding-bottom: calc(constant(safe-area-inset-bottom) + 106rpx + 6rpx);
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 106rpx + 6rpx);
|
||||
}
|
||||
|
||||
// 商品信息
|
||||
.goods-info {
|
||||
background: #fff;
|
||||
padding: 25rpx 30rpx;
|
||||
}
|
||||
|
||||
.info-item__top {
|
||||
min-height: 40rpx;
|
||||
margin-bottom: 20rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.floor-price__samll {
|
||||
font-size: 26rpx;
|
||||
line-height: 1;
|
||||
color: #ff0000;
|
||||
margin-bottom: -10rpx;
|
||||
}
|
||||
|
||||
// 商品价
|
||||
.floor-price {
|
||||
color: #ff0000;
|
||||
margin-right: 15rpx;
|
||||
font-size: 42rpx;
|
||||
}
|
||||
|
||||
.original-price {
|
||||
font-size: 26rpx;
|
||||
text-decoration: line-through;
|
||||
color: #959595;
|
||||
margin-right: 15rpx;
|
||||
margin-bottom: -6rpx;
|
||||
}
|
||||
|
||||
// 会员价标签
|
||||
.user-grade {
|
||||
background: #3c3c3c;
|
||||
border-radius: 6rpx;
|
||||
padding: 8rpx 14rpx;
|
||||
margin-right: 15rpx;
|
||||
font-size: 24rpx;
|
||||
color: #EEE0C3;
|
||||
}
|
||||
|
||||
.goods-sales {
|
||||
font-size: 24rpx;
|
||||
color: #959595;
|
||||
}
|
||||
|
||||
.info-item__name .goods-name {
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
/* 商品分享 */
|
||||
|
||||
.goods-share__line {
|
||||
border-left: 1rpx solid #f4f4f4;
|
||||
height: 60rpx;
|
||||
margin: 0 30rpx;
|
||||
}
|
||||
|
||||
.goods-share .share-btn {
|
||||
line-height: normal;
|
||||
padding: 0;
|
||||
background: none;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
font-size: 8pt;
|
||||
border: none;
|
||||
color: #191919;
|
||||
}
|
||||
|
||||
.goods-share .share-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.goods-share .share__icon {
|
||||
font-size: 40rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
|
||||
// 商品卖点
|
||||
.info-item_selling-point {
|
||||
margin-top: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
// 选择商品规格
|
||||
.goods-choice {
|
||||
padding: 26rpx 30rpx;
|
||||
font-size: 28rpx;
|
||||
|
||||
.spec-list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.spec-name {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 商品详情
|
||||
.goods-content .item-title {
|
||||
padding: 26rpx 30rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
// 底部操作栏
|
||||
.footer-fixed {
|
||||
position: fixed;
|
||||
bottom: var(--window-bottom);
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
z-index: 11;
|
||||
box-shadow: 0 -4rpx 40rpx 0 rgba(151, 151, 151, 0.24);
|
||||
background: #fff;
|
||||
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
.footer-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
height: 106rpx;
|
||||
}
|
||||
|
||||
// 快捷菜单
|
||||
.foo-item-fast {
|
||||
box-sizing: border-box;
|
||||
min-width: 214rpx;
|
||||
line-height: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
margin-right: 12rpx;
|
||||
|
||||
.fast-item {
|
||||
position: relative;
|
||||
padding: 4rpx 0;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
width: 84rpx;
|
||||
|
||||
&--cart {
|
||||
margin-left: 6rpx;
|
||||
.fast-icon { margin-left: -12rpx; }
|
||||
}
|
||||
|
||||
// 角标
|
||||
.fast-badge {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
min-width: 16px;
|
||||
padding: 0 3px;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
font-size: 12px;
|
||||
font-family: -apple-system-font, Helvetica Neue, Arial, sans-serif;
|
||||
line-height: 1.2;
|
||||
text-align: center;
|
||||
background-color: #ee0a24;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.fast-badge--fixed {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
transform-origin: 100%
|
||||
}
|
||||
|
||||
.fast-icon {
|
||||
font-size: 44rpx;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.fast-text {
|
||||
font-size: 22rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 操作按钮
|
||||
.foo-item-btn {
|
||||
flex: 1;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 72rpx;
|
||||
margin-right: 16rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
// 立即购买按钮
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
}
|
||||
|
||||
// 购物车按钮
|
||||
.btn-item-deputy {
|
||||
background: linear-gradient(to right, $vice-bg, $vice-bg2);
|
||||
color: $vice-text;
|
||||
}
|
||||
}
|
||||
316
package/shops/detail/index.vue
Executable file
316
package/shops/detail/index.vue
Executable file
@@ -0,0 +1,316 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<!-- 店招 -->
|
||||
<shop-banner :shop="shop" @onFollow="onFollow" @event="onSearch" />
|
||||
<!-- 一级分类 -->
|
||||
<primary v-if="setting.style == PageCategoryStyleEnum.ONE_LEVEL_BIG.value || setting.style == PageCategoryStyleEnum.ONE_LEVEL_SMALL.value"
|
||||
:display="setting.style" :list="list" />
|
||||
|
||||
<!-- 二级分类 -->
|
||||
<secondary v-if="setting.style == PageCategoryStyleEnum.TWO_LEVEL.value" :list="list" />
|
||||
|
||||
<!-- 分类+商品 -->
|
||||
<commodity v-if="setting.style == PageCategoryStyleEnum.COMMODITY.value" ref="mescrollItem" :equipmentName="searchValue" :list="list" :shopId="shopId" :setting="setting" @addCart="onRefreshPage"/>
|
||||
|
||||
<!-- 底部选项卡 -->
|
||||
<view class="footer-fixed" style="display: none;">
|
||||
<view class="footer-container">
|
||||
<!-- 导航图标 -->
|
||||
<view class="foo-item-fast">
|
||||
<!-- 首页 -->
|
||||
<view class="fast-item fast-item--home" @click="onTargetHome">
|
||||
<view class="fast-icon">
|
||||
<text class="iconfont icon-shouye"></text>
|
||||
</view>
|
||||
<view class="fast-text">
|
||||
<text>首页</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 客服 (仅微信小程序端显示) -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<button class="btn-normal" open-type="contact">
|
||||
<view class="fast-item">
|
||||
<view class="fast-icon">
|
||||
<text class="iconfont icon-kefu1"></text>
|
||||
</view>
|
||||
<view class="fast-text">
|
||||
<text>客服</text>
|
||||
</view>
|
||||
</view>
|
||||
</button>
|
||||
<!-- #endif -->
|
||||
<!-- 购物车 -->
|
||||
<view class="fast-item fast-item--cart" @click="onTargetCart">
|
||||
<view v-if="cartTotal > 0" class="fast-badge fast-badge--fixed">{{ cartTotal > 99 ? '99+' : cartTotal }}
|
||||
</view>
|
||||
<view class="fast-icon">
|
||||
<text class="iconfont icon-gouwuche"></text>
|
||||
</view>
|
||||
<view class="fast-text">
|
||||
<text>购物车</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="foo-item-btn">
|
||||
<view class="btn-wrapper">
|
||||
<view class="btn-item btn-item-main" @click="onTargetCart(3)">
|
||||
<text>去结算</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollCompMixin from '@/components/mescroll-uni/mixins/mescroll-comp'
|
||||
import { setCartTabBadge } from '@/core/app'
|
||||
import SettingKeyEnum from '@/common/enum/setting/Key'
|
||||
import { PageCategoryStyleEnum } from '@/common/enum/store/page/category'
|
||||
import SettingModel from '@/common/model/Setting'
|
||||
import * as CategoryApi from '@/api/category'
|
||||
import * as EquipmentApi from '@/api/equipment'
|
||||
import * as CartApi from '@/api/cart'
|
||||
import * as ShopApi from '@/api/shop.js'
|
||||
import Empty from '@/components/empty'
|
||||
import Search from './components/search'
|
||||
import ShopBanner from './components/shop-banner'
|
||||
import Primary from './components/primary'
|
||||
import Secondary from './components/secondary'
|
||||
import Commodity from './components/commodity'
|
||||
import storage from '@/utils/storage'
|
||||
|
||||
// 最后一次刷新时间
|
||||
let lastRefreshTime;
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Search,
|
||||
Empty,
|
||||
Primary,
|
||||
Secondary,
|
||||
Commodity,
|
||||
ShopBanner
|
||||
},
|
||||
mixins: [MescrollCompMixin],
|
||||
data() {
|
||||
return {
|
||||
// 店铺信息
|
||||
shop: {},
|
||||
// 店铺ID
|
||||
shopId: null,
|
||||
// 枚举类
|
||||
PageCategoryStyleEnum,
|
||||
// 分类列表
|
||||
list: [],
|
||||
// 分类模板设置
|
||||
setting: {},
|
||||
// 正在加载中
|
||||
isLoading: true,
|
||||
|
||||
// 购物车总数量
|
||||
cartTotal: 0,
|
||||
// 显示/隐藏SKU弹窗
|
||||
showSkuPopup: false,
|
||||
// 模式 1:都显示 2:只显示购物车 3:只显示立即购买
|
||||
skuMode: 1,
|
||||
// 显示/隐藏分享菜单
|
||||
showShareSheet: false,
|
||||
// 获取商品海报图api方法
|
||||
posterApiCall: EquipmentApi.poster,
|
||||
// 搜索关键词
|
||||
searchValue: '',
|
||||
// 刷新组件
|
||||
isRefresh: true
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad({ shopId }) {
|
||||
// 店铺ID
|
||||
this.shopId = parseInt(shopId),
|
||||
// 加载页面数据
|
||||
this.onRefreshPage()
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow() {
|
||||
// 每间隔5分钟自动刷新一次页面数据
|
||||
const curTime = new Date().getTime()
|
||||
if ((curTime - lastRefreshTime) > 5 * 60 * 1000) {
|
||||
this.onRefreshPage()
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
searchValue(val){
|
||||
this.searchValue = val
|
||||
this.$navTo('pages/search/index')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
// 刷新页面
|
||||
onRefreshPage() {
|
||||
// 记录刷新时间
|
||||
lastRefreshTime = new Date().getTime()
|
||||
// 获取页面数据
|
||||
this.getPageData()
|
||||
// 更新购物车角标
|
||||
setCartTabBadge()
|
||||
},
|
||||
|
||||
// 关注
|
||||
onFollow(shopId){
|
||||
ShopApi.setFollow({shopId}).then(res => {
|
||||
this.getPageData()
|
||||
})
|
||||
},
|
||||
|
||||
// 获取页面数据
|
||||
getPageData() {
|
||||
const app = this
|
||||
const equipmentName = storage.get('shopSearchValue')
|
||||
app.isLoading = true
|
||||
Promise.all([
|
||||
// 获取分类模板设置
|
||||
// 优化建议: 可以将此处的false改为true 启用缓存
|
||||
SettingModel.data(true),
|
||||
// 获取分类列表
|
||||
CategoryApi.list({shopId:app.shopId,equipmentName}),
|
||||
// 店铺信息
|
||||
ShopApi.detail(app.shopId)
|
||||
])
|
||||
.then(result => {
|
||||
// 初始化分类模板设置
|
||||
app.initSetting(result[0])
|
||||
// 初始化分类列表数据
|
||||
app.initCategory(result[1])
|
||||
// 更新购物车角标
|
||||
app.getCartTotal()
|
||||
// 初始化店铺信息
|
||||
app.initShop(result[2])
|
||||
// 刷新子组件
|
||||
app.isRefresh = true
|
||||
})
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
/**
|
||||
* 初始化分类模板设置
|
||||
* @param {Object} result
|
||||
*/
|
||||
initSetting(setting) {
|
||||
this.setting = setting[SettingKeyEnum.PAGE_CATEGORY_TEMPLATE.value]
|
||||
},
|
||||
|
||||
/**
|
||||
* 初始化分类列表数据
|
||||
* @param {Object} result
|
||||
*/
|
||||
initCategory(result) {
|
||||
this.list = result.data.list
|
||||
},
|
||||
|
||||
/**
|
||||
* 初始化店铺信息
|
||||
* @param {Object} result
|
||||
*/
|
||||
initShop(result){
|
||||
this.shop = result.data.detail
|
||||
},
|
||||
|
||||
// 获取购物车总数量
|
||||
getCartTotal() {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
CartApi.total()
|
||||
.then(result => {
|
||||
app.cartTotal = result.data.cartTotal
|
||||
resolve(result)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 更新购物车数量
|
||||
onAddCart(total) {
|
||||
this.cartTotal = total
|
||||
},
|
||||
|
||||
/**
|
||||
* 显示/隐藏SKU弹窗
|
||||
* @param {skuMode} 模式 1:都显示 2:只显示购物车 3:只显示立即购买
|
||||
*/
|
||||
onShowSkuPopup(skuMode = 1) {
|
||||
this.skuMode = skuMode
|
||||
this.showSkuPopup = !this.showSkuPopup
|
||||
},
|
||||
|
||||
// 搜索
|
||||
onSearch(searchValue){
|
||||
this.searchValue = searchValue
|
||||
},
|
||||
|
||||
// 跳转到首页
|
||||
onTargetHome(e) {
|
||||
this.$navTo('pages/index/index')
|
||||
},
|
||||
|
||||
// 跳转到购物车页
|
||||
onTargetCart() {
|
||||
this.$navTo('pages/cart/index')
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 设置分享内容
|
||||
*/
|
||||
onShareAppMessage() {
|
||||
const app = this
|
||||
return {
|
||||
title: _this.templet.shareTitle,
|
||||
path: '/pages/category/index?' + app.$getShareUrlParams()
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享到朋友圈
|
||||
* 本接口为 Beta 版本,暂只在 Android 平台支持,详见分享到朋友圈 (Beta)
|
||||
* https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html
|
||||
*/
|
||||
onShareTimeline() {
|
||||
const app = this
|
||||
return {
|
||||
title: _this.templet.shareTitle,
|
||||
path: '/pages/category/index?' + app.$getShareUrlParams()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
@import "./index.scss";
|
||||
// 搜索框
|
||||
.search {
|
||||
position: fixed;
|
||||
top: var(--window-top);
|
||||
left: var(--window-left);
|
||||
right: var(--window-right);
|
||||
z-index: 9;
|
||||
top: 200rpx;
|
||||
padding-bottom: 20rpx;
|
||||
}
|
||||
|
||||
</style>
|
||||
299
package/shops/index.vue
Normal file
299
package/shops/index.vue
Normal file
@@ -0,0 +1,299 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- 展馆图标 -->
|
||||
<view class="header-box">
|
||||
<view class="location" @click="changeCity">
|
||||
<image src="../../static/postion.svg"></image><text>南宁</text>
|
||||
</view>
|
||||
<view class="search-wrapper">
|
||||
<view class="search-input">
|
||||
<view class="search-input-wrapper">
|
||||
<view class="left">
|
||||
<text class="search-icon iconfont icon-search"></text>
|
||||
</view>
|
||||
<view class="right">
|
||||
<input v-model="searchValue" class="input" focus="true" placeholder="请输入您搜索的商品"
|
||||
type="text"></input>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="search-button">
|
||||
<button class="button" @click="onSearch" type="warn">搜索</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 门店列表 -->
|
||||
<view class="shop-list">
|
||||
<u-card v-for="(item, index) in shopList" :key="index" @click="onSelectedShop(item)"
|
||||
class="shop-item dis-flex flex-y-center" :border="false" :box-shadow="true" :show-head="false"
|
||||
:head-border-bottom="false">
|
||||
<view class="" slot="body">
|
||||
<view class="shop-item__content flex-box">
|
||||
<view class="u-body-item u-flex u-col-between u-p-t-0">
|
||||
<u-avatar :src="item.logo_url" :size="120" mode="square" :show-level="true" ></u-avatar>
|
||||
<view class="shop-info">
|
||||
<view class="title">{{item.shop_name}}</view>
|
||||
<view class="about">联系电话:{{item.phone}}</view>
|
||||
<view class="address">地址:{{ item.region.province }}{{ item.region.city }}{{ item.region.region }}{{ item.address }}</view>
|
||||
<view v-if="item.distance" class="shop-item__distance">
|
||||
<text class="iconfont icon-dingwei"></text>
|
||||
<text class="f-24">{{ item.distance_unit }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 选中状态 -->
|
||||
<!-- <view v-if="item.shop_id == selectedId" class="shop-item__right">
|
||||
<text class="iconfont icon-check1"></text>
|
||||
</view> -->
|
||||
</view>
|
||||
</u-card>
|
||||
</view>
|
||||
<!-- 定位按钮 -->
|
||||
<view v-if="!isAuthor" class="widget-location dis-flex flex-x-center flex-y-center" @click="onAuthorize()">
|
||||
<text class="iconfont icon-locate"></text>
|
||||
</view>
|
||||
<empty v-if="!shopList.length" :isLoading="isLoading" tips="亲,暂无自提门店哦" />
|
||||
|
||||
<!-- <view class="shop-list">
|
||||
<u-card v-for="(item,index) in list" :key="index" :border="false" :box-shadow="true" :show-head="false"
|
||||
:head-border-bottom="false">
|
||||
<view class="" slot="body">
|
||||
<view class="u-body-item u-flex u-col-between u-p-t-0">
|
||||
<image class="shop-avatar"
|
||||
:src="item.logo_url"
|
||||
mode="widthFix"></image>
|
||||
<view class="shop-info">
|
||||
<view class="title">{{item.shop_name}}</view>
|
||||
<view class="about">{{item.summary}}</view>
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</u-card>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Search from '@/components/page/diyComponents/search/index.vue'
|
||||
import {
|
||||
getMoreListData
|
||||
} from '@/core/app'
|
||||
import * as ShopApi from '@/api/shop.js'
|
||||
import Empty from '@/components/empty'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Search,
|
||||
Empty
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: '国内馆',
|
||||
// 正在加载中
|
||||
isLoading: true,
|
||||
// 是否授权了定位权限
|
||||
isAuthor: true,
|
||||
// 当前选择的门店ID
|
||||
selectedId: null,
|
||||
// 订单列表数据
|
||||
shopList: [],
|
||||
|
||||
}
|
||||
},
|
||||
onLoad({
|
||||
selectedId
|
||||
}) {
|
||||
const app = this
|
||||
// 记录当前选择的门店ID
|
||||
app.selectedId = selectedId ? selectedId : null
|
||||
// 获取默认门店列表
|
||||
app.getShopList()
|
||||
// 获取用户坐标
|
||||
app.getLocation(res => {
|
||||
app.getShopList(res.longitude, res.latitude)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// 获取门店列表
|
||||
getShopList(longitude, latitude) {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
ShopApi.list({
|
||||
isCheck: 1,
|
||||
longitude,
|
||||
latitude
|
||||
})
|
||||
.then(result => app.shopList = result.data.list)
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 获取用户坐标
|
||||
// 参考文档:https://uniapp.dcloud.io/api/location/location?id=getlocation
|
||||
getLocation(callback) {
|
||||
const app = this
|
||||
uni.getLocation({
|
||||
type: 'wgs84',
|
||||
success: callback,
|
||||
fail() {
|
||||
app.$toast('获取定位失败,请点击右下角按钮重新尝试定位')
|
||||
app.isAuthor = false
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 授权启用定位权限
|
||||
onAuthorize() {
|
||||
const app = this
|
||||
// #ifdef MP
|
||||
uni.openSetting({
|
||||
success(res) {
|
||||
if (res.authSetting['scope.userLocation']) {
|
||||
console.log('定位权限授权成功')
|
||||
app.isAuthor = true
|
||||
setTimeout(() => {
|
||||
// 获取用户坐标
|
||||
app.getLocation((res) => {
|
||||
app.getShopList(res.longitude, res.latitude)
|
||||
})
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
// 获取用户坐标
|
||||
app.getLocation((res) => {
|
||||
app.getShopList(res.longitude, res.latitude)
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
|
||||
/**
|
||||
* 选择门店
|
||||
*/
|
||||
onSelectedShop(item) {
|
||||
this.$navTo('package/shops/detail/index',item)
|
||||
},
|
||||
|
||||
changeCity() {
|
||||
this.$toast('切换区域')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bg {
|
||||
background-color: #F5F5F8
|
||||
}
|
||||
|
||||
.shop-list {
|
||||
.shop-item {
|
||||
}
|
||||
}
|
||||
|
||||
.header-box {
|
||||
padding: 20rpx 36rpx 0 36rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.location {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
width: 60rpx;
|
||||
height: 60rpx
|
||||
}
|
||||
}
|
||||
|
||||
.u-subsection {
|
||||
width: 260rpx;
|
||||
margin-top: 7rpx
|
||||
}
|
||||
}
|
||||
|
||||
.search-wrapper {
|
||||
display: flex;
|
||||
width: 80%;
|
||||
height: 64rpx
|
||||
}
|
||||
|
||||
// 搜索输入框
|
||||
.search-input {
|
||||
width: 90%;
|
||||
background: #fff;
|
||||
border-radius: 10rpx 0 0 10rpx;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
|
||||
.search-input-wrapper {
|
||||
display: flex;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
width: 60rpx;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.search-icon {
|
||||
display: block;
|
||||
color: #b4b4b4;
|
||||
font-size: 28rpx
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
|
||||
input {
|
||||
font-size: 28rpx;
|
||||
height: 64rpx;
|
||||
display: flex;
|
||||
|
||||
.input-placeholder {
|
||||
color: #aba9a9
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.shop-avatar {
|
||||
width: 200rpx;
|
||||
margin-right: 24rpx
|
||||
}
|
||||
|
||||
// 搜索按钮
|
||||
.search-button {
|
||||
width: 25%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.button {
|
||||
height: 64rpx;
|
||||
font-size: 28rpx;
|
||||
border-radius: 0 5px 5px 0;
|
||||
background: #2C71C7
|
||||
}
|
||||
}
|
||||
|
||||
.shop-info {
|
||||
width: 100%;
|
||||
margin-left: 20rpx;
|
||||
|
||||
.title {
|
||||
font-size: 38rpx;
|
||||
font-weight: bold;
|
||||
padding-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.u-body-item {
|
||||
align-items: stretch !important
|
||||
}
|
||||
</style>
|
||||
232
package/solution/apply.vue
Normal file
232
package/solution/apply.vue
Normal file
@@ -0,0 +1,232 @@
|
||||
<template>
|
||||
<view class="partner">
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper" v-if="setting">
|
||||
<u-form :model="form" ref="uForm" label-width="240rpx">
|
||||
<view class="brand-poster">
|
||||
<image :src="setting.background" mode="widthFix" class="banner"></image>
|
||||
<view class="brand-name" v-html="setting.content"></view>
|
||||
</view>
|
||||
<view class="buy-desc">如果有意向,请填写以下信息给平台留言</view>
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper">
|
||||
<u-form :model="form" ref="uForm" label-width="140rpx">
|
||||
<u-form-item label="姓名" prop="real_name">
|
||||
<u-input v-model="form.real_name" :disabled="disabled" placeholder="请输入姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="电话" prop="phone">
|
||||
<u-input v-model="form.phone" maxlength="11" :disabled="disabled" placeholder="请输入联系电话" />
|
||||
</u-form-item>
|
||||
<u-form-item label="性别" prop="sex">
|
||||
<u-radio-group v-model="form.sex">
|
||||
<u-radio @change="groupChange" v-for="(item, index) in sex" :key="index"
|
||||
:name="item.name" :disabled="item.disabled">
|
||||
{{item.name}}
|
||||
</u-radio>
|
||||
</u-radio-group>
|
||||
</u-form-item>
|
||||
<u-form-item label="定制预算" prop="money">
|
||||
<u-input type="number" v-model="form.money" :disabled="disabled" maxlength="11" placeholder="请输入定制预算" />
|
||||
</u-form-item>
|
||||
<u-form-item label="微信号" prop="weixin">
|
||||
<u-input v-model="form.weixin" :disabled="disabled" placeholder="请输入微信号" />
|
||||
</u-form-item>
|
||||
<u-form-item label="意向区域" prop="region">
|
||||
<select-region ref="sRegion" :disabled="disabled" v-model="form.region" />
|
||||
</u-form-item>
|
||||
<u-form-item label="整体需求" prop="comments">
|
||||
<u-input v-model="form.comments" :disabled="disabled" placeholder="请输入整体需求" />
|
||||
</u-form-item>
|
||||
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn">
|
||||
<u-button type="primary" shape="circle" @click="handleSubmit()">提交</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<!-- <view class="footer">
|
||||
<view class="btn">
|
||||
<u-button type="primary" shape="circle">更新资料</u-button>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 表单字段元素
|
||||
const form = {
|
||||
name: '',
|
||||
phone: '',
|
||||
sex: '',
|
||||
money: '',
|
||||
region: [],
|
||||
weixin: '',
|
||||
comments: '',
|
||||
}
|
||||
|
||||
const sex = [{
|
||||
name: '男',
|
||||
value: 1,
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
name: '女',
|
||||
value: 2,
|
||||
disabled: false
|
||||
}
|
||||
]
|
||||
|
||||
import * as Api from '@/api/solution/index.js'
|
||||
import * as ApplyApi from '@/api/solution/apply.js'
|
||||
import * as SettingApi from '@/api/solution/setting.js'
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form,
|
||||
disabled: false,
|
||||
detail: {},
|
||||
solutionId: 0,
|
||||
sex,
|
||||
setting: {}
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
// 获取当前用户信息
|
||||
init() {
|
||||
const app = this
|
||||
SettingApi.data().then(result => {
|
||||
app.setting = result.data.setting
|
||||
// 设置当前页面标题
|
||||
app.setPageTitle()
|
||||
})
|
||||
},
|
||||
|
||||
// 设置当前页面标题
|
||||
setPageTitle() {
|
||||
uni.setNavigationBarTitle({ title: this.setting.title })
|
||||
},
|
||||
|
||||
groupChange(e) {
|
||||
this.form.sex = e
|
||||
},
|
||||
|
||||
// 表单提交
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
// if (app.disabled) {
|
||||
// return false
|
||||
// }
|
||||
const {
|
||||
form,
|
||||
solutionId
|
||||
} = this
|
||||
form.brand_id = solutionId
|
||||
app.$refs.uForm.validate(valid => {
|
||||
if (valid) {
|
||||
app.disabled = true
|
||||
app.onSubmit()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 提交到后端
|
||||
onSubmit() {
|
||||
const app = this
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
let req;
|
||||
if (form.apply_status == 30) {
|
||||
req = ApplyApi.edit(form.apply_id, form)
|
||||
} else {
|
||||
console.log('add');
|
||||
req = ApplyApi.add(form)
|
||||
}
|
||||
req.then(result => {
|
||||
console.log("result: ", result);
|
||||
app.$toast(result.message)
|
||||
setTimeout(function() {
|
||||
uni.navigateBack()
|
||||
}, 2000)
|
||||
|
||||
})
|
||||
.finally(() => app.disabled = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.partner {
|
||||
.banner {
|
||||
padding-top: 20rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
|
||||
.shop-box {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.shop-name {
|
||||
font-weight: bold;
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.brand-poster{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 100rpx;
|
||||
}
|
||||
|
||||
.shipin {
|
||||
width: 400rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: 500rpx;
|
||||
margin: 50rpx auto;
|
||||
padding-bottom: 50rpx !important;
|
||||
}
|
||||
}
|
||||
|
||||
.brand-name {
|
||||
padding: 10rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.buy-desc {
|
||||
text-align: center;
|
||||
color: #ff0000;
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
|
||||
.buy-text {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
238
package/solution/article/index.vue
Normal file
238
package/solution/article/index.vue
Normal file
@@ -0,0 +1,238 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ use: false }" :up="upOption" @up="upCallback">
|
||||
|
||||
<!-- 文章列表 -->
|
||||
<view class="article-list">
|
||||
<view class="article-item" :class="[`show-type__${item.show_type}`]" v-for="(item, index) in articleList.data" :key="index"
|
||||
@click="onTargetDetail(item.solution_id)">
|
||||
<!-- 小图模式 -->
|
||||
<block v-if="item.show_type == 10">
|
||||
<view class="article-item__image article-item__left">
|
||||
<image class="image" mode="widthFix" :src="item.image_url"></image>
|
||||
</view>
|
||||
<view class="flex-box">
|
||||
<view class="article-item__title">
|
||||
<text class="twoline-hide">{{ item.title }}</text>
|
||||
</view>
|
||||
<!-- <view class="article-item__footer m-top10">
|
||||
<text class="article-views f-24 col-8">{{ item.show_views }}次浏览</text>
|
||||
</view> -->
|
||||
</view>
|
||||
</block>
|
||||
<!-- 大图模式 -->
|
||||
<block v-if="item.show_type == 20">
|
||||
<view class="article-item__title">
|
||||
<text class="twoline-hide">{{ item.title }}</text>
|
||||
</view>
|
||||
<view class="article-item__image m-top20">
|
||||
<image class="image" mode="widthFix" :src="item.image_url"></image>
|
||||
</view>
|
||||
<!-- <view class="article-item__footer m-top10">
|
||||
<text class="article-views f-24 col-8">{{ item.show_views }}次浏览</text>
|
||||
</view> -->
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import * as Api from '@/api/solution/index.js'
|
||||
import * as UserApi from '@/api/user'
|
||||
import * as CategoryApi from '@/api/solution/category'
|
||||
import { getEmptyPaginateObj, getMoreListData } from '@/core/app'
|
||||
|
||||
const pageSize = 15
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
data() {
|
||||
return {
|
||||
CategoryId: 0,
|
||||
// 文章列表
|
||||
articleList: getEmptyPaginateObj(),
|
||||
userInfo: {},
|
||||
// 订单类型
|
||||
orderType: false,
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: { size: pageSize },
|
||||
// 数量要大于3条才显示无更多数据
|
||||
noMoreSize: 3,
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
const app = this
|
||||
console.log("options: ",options);
|
||||
app.CategoryId = options.categoryId
|
||||
app.orderType = options.orderType
|
||||
// 获取文章分类数据
|
||||
app.getArticleList()
|
||||
app.getUserInfo()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
app.getArticleList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取文章列表
|
||||
* @param {Number} pageNo 页码
|
||||
*/
|
||||
getArticleList(pageNo = 1) {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
Api.list({ categoryId: app.CategoryId, page: pageNo }, { load: false })
|
||||
.then(result => {
|
||||
// 合并新数据
|
||||
const newList = result.data.list
|
||||
app.articleList.data = getMoreListData(newList, app.articleList, pageNo)
|
||||
resolve(newList)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取当前用户信息
|
||||
getUserInfo() {
|
||||
const app = this
|
||||
UserApi.info()
|
||||
.then(result => {
|
||||
app.userInfo = result.data.userInfo
|
||||
})
|
||||
},
|
||||
|
||||
// 获取当前标签项的值
|
||||
getTabValue() {
|
||||
const app = this
|
||||
return app.tabList.length ? app.tabList[app.curTab].value : 0
|
||||
},
|
||||
|
||||
// 刷新列表数据
|
||||
onRefreshList() {
|
||||
this.articleList = getEmptyPaginateObj()
|
||||
setTimeout(() => this.mescroll.resetUpScroll(), 120)
|
||||
},
|
||||
|
||||
// 跳转文章详情页
|
||||
onTargetDetail(articleId) {
|
||||
const { orderType } = this
|
||||
if( orderType ){
|
||||
return this.$navTo('package/solution/detail', { articleId })
|
||||
}
|
||||
return this.$navTo('package/solution/buy/index')
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享当前页面
|
||||
*/
|
||||
onShareAppMessage() {
|
||||
return {
|
||||
title: '文章首页',
|
||||
path: "/pages/article/index?" + this.$getShareUrlParams()
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享到朋友圈
|
||||
* 本接口为 Beta 版本,暂只在 Android 平台支持,详见分享到朋友圈 (Beta)
|
||||
* https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html
|
||||
*/
|
||||
onShareTimeline() {
|
||||
return {
|
||||
title: '文章首页',
|
||||
path: "/pages/article/index?" + this.$getShareUrlParams()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
// 文章列表
|
||||
.article-list {
|
||||
padding-top: 20rpx;
|
||||
line-height: 1;
|
||||
background: #f7f7f7;
|
||||
}
|
||||
|
||||
|
||||
.article-item {
|
||||
margin-bottom: 20rpx;
|
||||
padding: 30rpx;
|
||||
background: #fff;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.article-item__title {
|
||||
max-height: 74rpx;
|
||||
font-size: 28rpx;
|
||||
line-height: 38rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.article-item__image .image {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
// 小图模式
|
||||
.show-type__10 {
|
||||
display: flex;
|
||||
|
||||
.article-item__left {
|
||||
padding-right: 20rpx;
|
||||
}
|
||||
|
||||
.article-item__title {
|
||||
// min-height: 72rpx;
|
||||
}
|
||||
|
||||
.article-item__image .image {
|
||||
width: 240rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 大图模式
|
||||
.show-type__20 .article-item__image .image {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
225
package/solution/buy/index.vue
Normal file
225
package/solution/buy/index.vue
Normal file
@@ -0,0 +1,225 @@
|
||||
<template>
|
||||
<view class="partner">
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper" v-if="setting">
|
||||
<u-form :model="form" ref="uForm" label-width="240rpx">
|
||||
<view class="brand-poster">
|
||||
<image :src="setting.background" mode="widthFix" class="banner"></image>
|
||||
<view class="brand-name" v-html="setting.content"></view>
|
||||
</view>
|
||||
<view class="buy-info">
|
||||
<u-radio-group v-model="agree" placement="column">
|
||||
<u-radio name="购买协议" @change="radioChange">同意<text class="show-agreement">《购买协议》</text></u-radio>
|
||||
</u-radio-group>
|
||||
<text class="price">¥{{ setting.money }}</text>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn">
|
||||
<u-button :disabled="!agree" type="primary" shape="circle" @click="handleSubmit()">立即购买</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</u-form>
|
||||
</view>
|
||||
<u-modal v-model="show" ref="uModal" title="购买协议" @confirm="confirm">
|
||||
<view v-html="setting.agreement" class="agreement-content"></view>
|
||||
</u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 表单字段元素
|
||||
const form = {
|
||||
name: '',
|
||||
phone: '',
|
||||
sex: '',
|
||||
money: '',
|
||||
region: [],
|
||||
weixin: '',
|
||||
comments: '',
|
||||
}
|
||||
|
||||
const sex = [{
|
||||
name: '男',
|
||||
value: 1,
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
name: '女',
|
||||
value: 2,
|
||||
disabled: false
|
||||
}
|
||||
]
|
||||
|
||||
import * as Api from '@/api/solution/index.js'
|
||||
import * as ApplyApi from '@/api/solution/apply.js'
|
||||
import * as SettingApi from '@/api/solution/setting.js'
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form,
|
||||
disabled: false,
|
||||
detail: {},
|
||||
solutionId: 0,
|
||||
sex,
|
||||
setting: {
|
||||
money: 0
|
||||
},
|
||||
agree: 0,
|
||||
// 是否显示协议内容
|
||||
show: false
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
// 获取当前用户信息
|
||||
init() {
|
||||
const app = this
|
||||
SettingApi.data().then(result => {
|
||||
app.setting = result.data.setting
|
||||
// 设置当前页面标题
|
||||
app.setPageTitle()
|
||||
})
|
||||
},
|
||||
|
||||
// 设置当前页面标题
|
||||
setPageTitle() {
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.setting.title
|
||||
})
|
||||
},
|
||||
|
||||
radioChange() {
|
||||
this.show = true
|
||||
},
|
||||
|
||||
groupChange(e) {
|
||||
this.form.sex = e
|
||||
},
|
||||
|
||||
confirm(e){
|
||||
let app = this
|
||||
},
|
||||
|
||||
// 表单提交
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
const {
|
||||
form
|
||||
} = this
|
||||
app.onSubmit()
|
||||
},
|
||||
|
||||
// 提交到后端
|
||||
onSubmit() {
|
||||
const app = this
|
||||
return this.$navTo('package/solution/cashier/index')
|
||||
// const {
|
||||
// form
|
||||
// } = this
|
||||
// let req;
|
||||
// if (form.apply_status == 30) {
|
||||
// req = ApplyApi.edit(form.apply_id, form)
|
||||
// } else {
|
||||
// console.log('add');
|
||||
// req = ApplyApi.add(form)
|
||||
// }
|
||||
// req.then(result => {
|
||||
// console.log("result: ", result);
|
||||
// app.$toast(result.message)
|
||||
// setTimeout(function() {
|
||||
// uni.navigateBack()
|
||||
// }, 2000)
|
||||
|
||||
// })
|
||||
// .finally(() => app.disabled = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.partner {
|
||||
.banner {
|
||||
padding-top: 20rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
|
||||
.shop-box {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.shop-name {
|
||||
font-weight: bold;
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.brand-poster{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
|
||||
.logo {
|
||||
width: 100rpx;
|
||||
}
|
||||
|
||||
.shipin {
|
||||
width: 400rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: 500rpx;
|
||||
margin: 50rpx auto;
|
||||
padding-bottom: 50rpx !important;
|
||||
}
|
||||
}
|
||||
|
||||
.brand-name {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.buy-desc {
|
||||
text-align: center;
|
||||
color: #ff0000;
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
|
||||
.buy-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 40rpx;
|
||||
|
||||
.price {
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
.show-agreement{
|
||||
color: #0000ff;
|
||||
}
|
||||
}
|
||||
|
||||
.buy-text {
|
||||
text-align: center;
|
||||
}
|
||||
.agreement-content{
|
||||
padding: 20rpx;
|
||||
}
|
||||
</style>
|
||||
460
package/solution/cashier/index.vue
Executable file
460
package/solution/cashier/index.vue
Executable file
@@ -0,0 +1,460 @@
|
||||
<template>
|
||||
<view v-if="!isLoading" class="container" :style="appThemeStyle">
|
||||
<!-- 订单信息 -->
|
||||
<view class="order-info">
|
||||
<!-- 支付剩余时间 -->
|
||||
<view class="order-countdown">
|
||||
<text class="m-r-6">剩余时间</text>
|
||||
<count-down :date="order.expirationTime" separator="zh" theme="text" />
|
||||
</view>
|
||||
<!-- 付款金额 -->
|
||||
<view class="order-amount">
|
||||
<text class="unit">¥</text>
|
||||
<text class="amount">{{ order.pay_price }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付方式 -->
|
||||
<view class="payment-method">
|
||||
<view v-for="(item, index) in methods" :key="index" class="pay-item dis-flex flex-x-between" @click="handleSelectPayType(index)">
|
||||
<view class="item-left dis-flex flex-y-center">
|
||||
<view class="item-left_icon" :class="[item.method]">
|
||||
<text class="iconfont" :class="[PayMethodIconEnum[item.method]]"></text>
|
||||
</view>
|
||||
<view class="item-left_text">
|
||||
<text>{{ PayMethodEnum[item.method].name }}</text>
|
||||
</view>
|
||||
<view v-if="item.method === PayMethodEnum.BALANCE.value" class="user-balance">
|
||||
<text>(可用¥{{ personal.balance }}元)</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-right col-m" v-if="curPaymentItem && curPaymentItem.method == item.method">
|
||||
<text class="iconfont icon-check"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 确认按钮 -->
|
||||
<view class="footer-fixed">
|
||||
<view class="btn-wrapper">
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">确认支付</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付确认弹窗 -->
|
||||
<!-- #ifdef H5 -->
|
||||
<u-modal v-if="tempUnifyData" v-model="showConfirmModal" title="支付确认" show-cancel-button confirm-text="已完成支付"
|
||||
:confirm-color="appTheme.mainBg" negative-top="100" :asyncClose="true"
|
||||
@confirm="onTradeQuery(tempUnifyData.outTradeNo, tempUnifyData.method)">
|
||||
<view class="modal-content">
|
||||
<text>请在{{ PayMethodClientNameEnum[tempUnifyData.method] }}内完成支付,如果您已经支付成功,请点击“已完成支付”按钮</text>
|
||||
</view>
|
||||
</u-modal>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from '@/utils/storage'
|
||||
import { inArray, urlEncode } from '@/utils/util'
|
||||
import { Alipay, Wechat } from '@/core/payment'
|
||||
import CountDown from '@/components/countdown'
|
||||
import { PayMethodEnum } from '@/common/enum/payment'
|
||||
import { PayStatusEnum } from '@/common/enum/order'
|
||||
import * as Api from '@/api/solution/cashier.js'
|
||||
|
||||
// 支付方式对应的图标
|
||||
const PayMethodIconEnum = {
|
||||
[PayMethodEnum.WECHAT.value]: 'icon-wechat-pay',
|
||||
[PayMethodEnum.ALIPAY.value]: 'icon-alipay',
|
||||
[PayMethodEnum.BALANCE.value]: 'icon-balance-pay'
|
||||
}
|
||||
|
||||
// 支付方式的终端名称
|
||||
const PayMethodClientNameEnum = {
|
||||
[PayMethodEnum.WECHAT.value]: '微信',
|
||||
[PayMethodEnum.ALIPAY.value]: '支付宝'
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CountDown
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 加载中
|
||||
isLoading: true,
|
||||
// 确认按钮禁用
|
||||
disabled: false,
|
||||
// 枚举类
|
||||
PayMethodEnum,
|
||||
PayMethodIconEnum,
|
||||
PayMethodClientNameEnum,
|
||||
// 当前选中的支付方式
|
||||
curPaymentItem: null,
|
||||
// 当前订单ID
|
||||
orderId: null,
|
||||
// 当前结算订单信息
|
||||
order: {},
|
||||
// 个人信息
|
||||
personal: { balance: '0.00' },
|
||||
// 当前客户端的支付方式列表(后端根据platform判断)
|
||||
methods: [],
|
||||
// 支付确认弹窗
|
||||
showConfirmModal: false,
|
||||
// #ifdef H5
|
||||
// 当前微信支付信息 (临时数据, 仅用于H5端)
|
||||
tempUnifyData: { outTradeNo: '', method: '' },
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad({ orderId }) {
|
||||
// 记录订单ID
|
||||
this.orderId = Number(orderId)
|
||||
// 获取收银台信息
|
||||
this.getCashierInfo()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取收银台信息
|
||||
getCashierInfo() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
Api.orderInfo()
|
||||
.then(result => {
|
||||
app.order = result.data.order
|
||||
app.personal = result.data.personal
|
||||
app.methods = result.data.paymentMethods
|
||||
app.isLoading = false
|
||||
app.setDefaultPayType()
|
||||
app.checkOrderPayStatus()
|
||||
// #ifdef H5
|
||||
// 判断当前页面来源于浏览器返回
|
||||
this.performance()
|
||||
// #endif
|
||||
})
|
||||
},
|
||||
|
||||
// 设置默认的支付方式
|
||||
setDefaultPayType() {
|
||||
const app = this
|
||||
if (app.disabled) return
|
||||
const defaultIndex = app.methods.findIndex(item => item.is_default == true)
|
||||
defaultIndex > -1 && app.handleSelectPayType(defaultIndex)
|
||||
},
|
||||
|
||||
// 判断当前订单是否为已支付
|
||||
checkOrderPayStatus() {
|
||||
const app = this
|
||||
if (app.order.pay_status == PayStatusEnum.SUCCESS.value) {
|
||||
app.$toast('恭喜您,订单已付款成功')
|
||||
app.onSuccessNav()
|
||||
}
|
||||
},
|
||||
|
||||
// 选择支付方式
|
||||
handleSelectPayType(index) {
|
||||
this.curPaymentItem = this.methods[index]
|
||||
},
|
||||
|
||||
// 判断当前页面来源于浏览器返回
|
||||
// #ifdef H5
|
||||
performance() {
|
||||
const app = this
|
||||
// 判断订单状态, 异步回调会将订单状态变为已支付, 那么就不需要让用户手动查单了
|
||||
if (app.order.pay_status == PayStatusEnum.PENDING.value) {
|
||||
app.alipayPerformance()
|
||||
app.wechatPerformance()
|
||||
}
|
||||
},
|
||||
|
||||
// H5端支付宝支付完成跳转回当前页面时触发
|
||||
alipayPerformance() {
|
||||
const app = this
|
||||
app.tempUnifyData = Alipay.performance()
|
||||
if (app.tempUnifyData) {
|
||||
app.onTradeQuery(app.tempUnifyData.outTradeNo, app.tempUnifyData.method)
|
||||
}
|
||||
},
|
||||
|
||||
// H5端微信支付完成或返回时触发
|
||||
wechatPerformance() {
|
||||
const app = this
|
||||
app.tempUnifyData = Wechat.performance(app.orderId)
|
||||
if (app.tempUnifyData) {
|
||||
app.showConfirmModal = true
|
||||
}
|
||||
},
|
||||
// #endif
|
||||
|
||||
// 确认支付
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
// 判断是否选择了支付方式
|
||||
if (!app.curPaymentItem) {
|
||||
app.$toast('您还没有选择支付方式')
|
||||
return
|
||||
}
|
||||
// 按钮禁用
|
||||
if (app.disabled) return
|
||||
app.disabled = true
|
||||
// 提交到后端API
|
||||
Api.orderPay(app.orderId, {
|
||||
method: app.curPaymentItem.method,
|
||||
client: app.platform,
|
||||
extra: app.getExtraAsUnify(app.curPaymentItem.method)
|
||||
})
|
||||
.then(result => app.onSubmitCallback(result))
|
||||
.finally(err => {
|
||||
setTimeout(() => app.disabled = false, 10)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取第三方支付的扩展参数
|
||||
getExtraAsUnify(method) {
|
||||
if (method === PayMethodEnum.ALIPAY.value) {
|
||||
return Alipay.extraAsUnify()
|
||||
}
|
||||
if (method === PayMethodEnum.WECHAT.value) {
|
||||
return Wechat.extraAsUnify()
|
||||
}
|
||||
return {}
|
||||
},
|
||||
|
||||
// 订单提交成功后回调
|
||||
onSubmitCallback(result) {
|
||||
const app = this
|
||||
const method = app.curPaymentItem.method
|
||||
const paymentData = result.data.payment
|
||||
// 余额支付
|
||||
if (method === PayMethodEnum.BALANCE.value) {
|
||||
app.onShowSuccess(result)
|
||||
}
|
||||
// 发起支付宝支付
|
||||
if (method === PayMethodEnum.ALIPAY.value) {
|
||||
console.log('paymentData', paymentData)
|
||||
Alipay.payment(paymentData)
|
||||
.then(res => app.onPaySuccess(res))
|
||||
.catch(err => app.onPayFail(err))
|
||||
}
|
||||
// 发起微信支付
|
||||
if (method === PayMethodEnum.WECHAT.value) {
|
||||
console.log('paymentData', paymentData)
|
||||
Wechat.payment({ orderKey: app.orderId, ...paymentData })
|
||||
.then(res => app.onPaySuccess(res))
|
||||
.catch(err => app.onPayFail(err))
|
||||
}
|
||||
},
|
||||
|
||||
// 订单支付成功的回调方法
|
||||
// 这里只是前端支付api返回结果success,实际订单是否支付成功 以后端的查单和异步通知为准
|
||||
onPaySuccess({ res, option: { isRequireQuery, outTradeNo, method } }) {
|
||||
const app = this
|
||||
// 判断是否需要主动查单
|
||||
// isRequireQuery为true代表需要主动查单
|
||||
if (isRequireQuery) {
|
||||
app.onTradeQuery(outTradeNo, method)
|
||||
return true
|
||||
}
|
||||
this.onShowSuccess(res)
|
||||
},
|
||||
|
||||
// 显示支付成功信息并页面跳转
|
||||
onShowSuccess({ message }) {
|
||||
this.$toast(message || '订单支付成功')
|
||||
this.onSuccessNav()
|
||||
},
|
||||
|
||||
// 订单支付失败
|
||||
onPayFail(err) {
|
||||
console.log('onPayFail', err)
|
||||
const errMsg = err.message || '订单未支付'
|
||||
this.$error(errMsg)
|
||||
},
|
||||
|
||||
// 已完成支付按钮事件: 请求后端查单
|
||||
onTradeQuery(outTradeNo, method) {
|
||||
const app = this
|
||||
// 交易查询
|
||||
// 查询第三方支付订单是否付款成功
|
||||
Api.tradeQuery({ outTradeNo, method, client: app.platform })
|
||||
.then(result => result.data.isPay ? app.onShowSuccess(result) : app.onPayFail(result))
|
||||
.finally(() => app.showConfirmModal = false)
|
||||
},
|
||||
|
||||
// 支付成功后的跳转
|
||||
onSuccessNav() {
|
||||
const pages = getCurrentPages()
|
||||
const lastPage = pages.length < 2 ? null : pages[pages.length - 2]
|
||||
const backRoutes = [
|
||||
'package/solution/index',
|
||||
'package/solution/detail'
|
||||
]
|
||||
if (lastPage && inArray(lastPage.route, backRoutes)) {
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1000)
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
this.$navTo('package/solution/index', {}, 'redirectTo')
|
||||
}, 1200)
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #F4F4F4;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
background-color: #F4F4F4;
|
||||
}
|
||||
|
||||
// 订单信息
|
||||
.order-info {
|
||||
padding: 80rpx 0;
|
||||
text-align: center;
|
||||
|
||||
.order-countdown {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.order-amount {
|
||||
margin: 0 auto;
|
||||
max-width: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #111111;
|
||||
|
||||
.unit {
|
||||
font-size: 30rpx;
|
||||
margin-bottom: -18rpx;
|
||||
}
|
||||
|
||||
.amount {
|
||||
font-size: 56rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 支付方式
|
||||
.payment-method {
|
||||
width: 94%;
|
||||
margin: 0 auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 20rpx;
|
||||
|
||||
.pay-item {
|
||||
padding: 26rpx 0;
|
||||
font-size: 28rpx;
|
||||
border-bottom: 1rpx solid rgb(248, 248, 248);
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.item-left_icon {
|
||||
margin-right: 20rpx;
|
||||
font-size: 44rpx;
|
||||
|
||||
&.wechat {
|
||||
color: #00c800;
|
||||
}
|
||||
|
||||
&.alipay {
|
||||
color: #009fe8;
|
||||
}
|
||||
|
||||
&.balance {
|
||||
color: #ff9700;
|
||||
}
|
||||
}
|
||||
|
||||
.item-left_text {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.item-right {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.user-balance {
|
||||
margin-left: 20rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 支付确认弹窗
|
||||
.modal-content {
|
||||
padding: 40rpx 48rpx;
|
||||
font-size: 30rpx;
|
||||
line-height: 50rpx;
|
||||
text-align: left;
|
||||
color: #606266;
|
||||
// height: 620rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
// 底部操作栏
|
||||
.footer-fixed {
|
||||
position: fixed;
|
||||
bottom: var(--window-bottom);
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 11;
|
||||
box-shadow: 0 -4rpx 40rpx 0 rgba(151, 151, 151, 0.24);
|
||||
background: #fff;
|
||||
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
|
||||
.btn-wrapper {
|
||||
height: 120rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 40rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 80rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
67
package/solution/components/search.vue
Executable file
67
package/solution/components/search.vue
Executable file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<!-- 搜索框 -->
|
||||
<view class="search-wrapper">
|
||||
<view class="index-search" @click="onClick">
|
||||
<view class="index-cont-search t-c">
|
||||
<text class="search-icon iconfont icon-search"></text>
|
||||
<text class="search-text">{{ tips }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
tips: {
|
||||
type: String,
|
||||
default: '搜索关键词'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onClick() {
|
||||
this.$emit('event')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search-wrapper {
|
||||
padding: 13rpx;
|
||||
}
|
||||
|
||||
.index-search {
|
||||
border-bottom: 0;
|
||||
border-radius: 50rpx;
|
||||
overflow: hidden;
|
||||
font-size: 28rpx;
|
||||
color: #6d6d6d;
|
||||
box-sizing: border-box;
|
||||
line-height: 64rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.index-cont-search {
|
||||
width: 100%;
|
||||
font-size: 28rpx;
|
||||
background: #f7f7f7;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.index-cont-search .search-icon {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.index-cont-search .search-text {
|
||||
margin-left: 14rpx;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
107
package/solution/detail.vue
Executable file
107
package/solution/detail.vue
Executable file
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<view v-if="!isLoading" class="container b-f p-b">
|
||||
<view class="article-title">
|
||||
<text class="f-32">{{ detail.title }}</text>
|
||||
</view>
|
||||
<view class="article-little dis-flex flex-x-between m-top10">
|
||||
<view class="article-little__left">
|
||||
<text class="article-views f-24 col-8">{{ detail.show_views }}次浏览</text>
|
||||
</view>
|
||||
<view class="article-little__right">
|
||||
<text class="article-views f-24 col-8">{{ detail.view_time }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="article-content m-top20">
|
||||
<mp-html :content="detail.content" />
|
||||
</view>
|
||||
<!-- 快捷导航 -->
|
||||
<shortcut />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Shortcut from '@/components/shortcut'
|
||||
import * as ArticleApi from '@/api/article'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Shortcut
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 当前文章ID
|
||||
articleId: null,
|
||||
// 加载中
|
||||
isLoading: true,
|
||||
// 当前文章详情
|
||||
detail: null
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
// 记录文章ID
|
||||
this.articleId = options.articleId
|
||||
// 获取文章详情
|
||||
this.getArticleDetail()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取文章详情
|
||||
getArticleDetail() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
ArticleApi.detail(app.articleId)
|
||||
.then(result => {
|
||||
app.detail = result.data.detail
|
||||
})
|
||||
.finally(() => app.isLoading = false)
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享当前页面
|
||||
*/
|
||||
onShareAppMessage() {
|
||||
const app = this
|
||||
// 构建页面参数
|
||||
const params = app.$getShareUrlParams({ articleId: app.articleId });
|
||||
return {
|
||||
title: app.detail.title,
|
||||
path: "/pages/article/detail?" + params
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享到朋友圈
|
||||
* 本接口为 Beta 版本,暂只在 Android 平台支持,详见分享到朋友圈 (Beta)
|
||||
* https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html
|
||||
*/
|
||||
onShareTimeline() {
|
||||
const app = this
|
||||
// 构建页面参数
|
||||
const params = app.$getShareUrlParams({ articleId: app.articleId });
|
||||
return {
|
||||
title: app.detail.title,
|
||||
path: "/pages/article/detail?" + params
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
padding: 20rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.article-content {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
</style>
|
||||
109
package/solution/index.vue
Normal file
109
package/solution/index.vue
Normal file
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<view class="solution">
|
||||
<view class="search">
|
||||
<search class="search" :tips="options.search ? options.search : '搜索关键词'" @event="onTargetDetail(2)" />
|
||||
</view>
|
||||
<view class="btn">
|
||||
<u-button type="primary" shape="circle" text="门店定制解决方案预定" @click="onApply">门店定制解决方案预定</u-button>
|
||||
</view>
|
||||
<view class="grid">
|
||||
<u-grid :border="false">
|
||||
<u-grid-item v-for="(item,index) in baseList" :key="index" @click="onTargetDetail(item.category_id)">
|
||||
<image
|
||||
:src="item.image ? item.image.preview_url : 'https://file.gxwebsoft.com/20220820/5794a3c1ed9b4d6b94737e4ebc36ce90.png'"
|
||||
class="avatar" mode="widthFix"></image>
|
||||
<text class="grid-text">{{item.name}}</text>
|
||||
</u-grid-item>
|
||||
</u-grid>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as CategoryApi from '@/api/solution/category.js'
|
||||
import * as SolutionOrderApi from '@/api/order.js'
|
||||
import Search from './components/search'
|
||||
export default {
|
||||
components: {
|
||||
Search
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
baseList: [],
|
||||
// 是否已购买门店解决方案
|
||||
orderType: false
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
const app = this
|
||||
// 获取文章分类数据
|
||||
app.getCategoryList(options.categoryId)
|
||||
// 门店解决方案订单
|
||||
app.getSolutionOrder()
|
||||
},
|
||||
methods: {
|
||||
// 获取文章分类数据
|
||||
getCategoryList(categoryId) {
|
||||
CategoryApi.list({
|
||||
type: 'solution'
|
||||
}).then(result => {
|
||||
this.baseList = result.data.list
|
||||
})
|
||||
},
|
||||
// 门店解决方案订单
|
||||
getSolutionOrder() {
|
||||
const app = this
|
||||
SolutionOrderApi.list({
|
||||
dataType: 'all',
|
||||
page: 1,
|
||||
orderType: 1
|
||||
}, {
|
||||
load: false
|
||||
}).then(result => {
|
||||
if (result.data.list.total > 0) {
|
||||
app.orderType = true
|
||||
}
|
||||
})
|
||||
},
|
||||
// 跳转文章详情页
|
||||
onTargetDetail(categoryId) {
|
||||
const app = this
|
||||
const { orderType } = this
|
||||
// 已付款
|
||||
if (orderType) {
|
||||
return this.$navTo('package/solution/article/index', {
|
||||
categoryId, orderType
|
||||
})
|
||||
}
|
||||
return this.$navTo('package/solution/buy/index')
|
||||
},
|
||||
onApply() {
|
||||
this.$navTo('package/solution/apply')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.solution {
|
||||
.search {
|
||||
padding: 10rpx 20rpx;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 700rpx;
|
||||
border-radius: 100%;
|
||||
margin: 25rpx auto;
|
||||
}
|
||||
|
||||
.grid {
|
||||
width: 700rpx;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 120rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
122
package/user/account/index.vue
Normal file
122
package/user/account/index.vue
Normal file
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<view class="partner">
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper" v-if="shopInfo">
|
||||
<u-form :model="form" ref="uForm" label-width="240rpx">
|
||||
<u-form-item label="商户名称" prop="name">
|
||||
{{shopInfo.shopName}}
|
||||
</u-form-item>
|
||||
<u-form-item label="联系人" prop="name">
|
||||
{{shopInfo.linkman}}
|
||||
</u-form-item>
|
||||
<u-form-item label="联系方式" prop="name">
|
||||
{{shopInfo.phone}}
|
||||
</u-form-item>
|
||||
<u-form-item label="站点地址" prop="name">
|
||||
{{shopInfo.address}}
|
||||
</u-form-item>
|
||||
<u-form-item label="法定代表人身份" prop="name">
|
||||
<image :src="applyInfo.sfz_image1" mode="widthFix" class="shipin"></image>
|
||||
<image :src="applyInfo.sfz_image2" mode="widthFix" class="shipin"></image>
|
||||
</u-form-item>
|
||||
<u-form-item label="门脸照" prop="name">
|
||||
<image :src="applyInfo.shop_image" mode="widthFix" class="shipin"></image>
|
||||
</u-form-item>
|
||||
<u-form-item label="微信号" prop="name">
|
||||
{{applyInfo.weixin}}
|
||||
</u-form-item>
|
||||
<u-form-item label="食品经营许可证" prop="name">
|
||||
<image :src="applyInfo.shipin_card_image" mode="widthFix" class="shipin"></image>
|
||||
</u-form-item>
|
||||
<u-form-item label="支付宝姓名" prop="name" v-if="shopInfo.alipayName">
|
||||
{{shopInfo.alipayName}}
|
||||
</u-form-item>
|
||||
<u-form-item label="支付宝账号" prop="name" v-if="shopInfo.alipayAccount">
|
||||
{{shopInfo.alipayAccount}}
|
||||
</u-form-item>
|
||||
|
||||
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<!-- <view class="footer">
|
||||
<view class="btn">
|
||||
<u-button type="primary" shape="circle">更新资料</u-button>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 表单字段元素
|
||||
const form = {
|
||||
// 入驻类型 (合伙人10001,配送员10002,社区门店10003,省代10004)
|
||||
gradeId: 10004,
|
||||
company: '',
|
||||
realName: '',
|
||||
phone: '',
|
||||
mobile: '',
|
||||
region: [],
|
||||
detail: '',
|
||||
}
|
||||
|
||||
import * as UserApi from '@/api/user'
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form,
|
||||
disabled: false,
|
||||
imageList: [],
|
||||
shopInfo: null,
|
||||
applyInfo: null
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.getUserInfo()
|
||||
},
|
||||
methods: {
|
||||
// 获取当前用户信息
|
||||
getUserInfo() {
|
||||
const app = this
|
||||
UserApi.info().then(result => {
|
||||
app.shopInfo = result.data.shopInfo
|
||||
app.applyInfo = result.data.applyInfo
|
||||
})
|
||||
},
|
||||
groupChange(){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.partner {
|
||||
|
||||
.banner {
|
||||
width: 100%;
|
||||
}
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
.logo{
|
||||
width: 100rpx;
|
||||
}
|
||||
.shipin{
|
||||
width: 200rpx;
|
||||
}
|
||||
}
|
||||
.footer{
|
||||
width: 500rpx;
|
||||
margin: 20rpx auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
206
package/user/address/create.vue
Executable file
206
package/user/address/create.vue
Executable file
@@ -0,0 +1,206 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<!-- 标题 -->
|
||||
<view class="page-title">收货地址</view>
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper">
|
||||
<u-form :model="form" ref="uForm" label-width="140rpx">
|
||||
<u-form-item label="姓名" prop="name">
|
||||
<u-input v-model="form.name" placeholder="请输入收货人姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="电话" prop="phone">
|
||||
<u-input v-model="form.phone" placeholder="请输入收货人手机号" />
|
||||
</u-form-item>
|
||||
<u-form-item label="地区" prop="region">
|
||||
<select-region ref="sRegion" v-model="form.region" />
|
||||
</u-form-item>
|
||||
<u-form-item label="详细地址" prop="detail" :border-bottom="false">
|
||||
<u-input v-model="form.detail" placeholder="街道门牌、楼层等信息" />
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn-wrapper">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="btn-item btn-item-wechat" @click="chooseAddress()">选择微信收货地址</view>
|
||||
<!-- #endif -->
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">保存</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
import { isMobile } from '@/utils/verify'
|
||||
import * as AddressApi from '@/api/address'
|
||||
|
||||
// 表单字段元素
|
||||
const form = {
|
||||
name: '',
|
||||
phone: '',
|
||||
region: [],
|
||||
detail: ''
|
||||
}
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
name: [{
|
||||
required: true,
|
||||
message: '请输入姓名',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
phone: [{
|
||||
required: true,
|
||||
message: '请输入手机号',
|
||||
trigger: ['blur', 'change']
|
||||
}, {
|
||||
// 自定义验证函数
|
||||
validator: (rule, value, callback) => {
|
||||
// 返回true表示校验通过,返回false表示不通过
|
||||
return isMobile(value)
|
||||
},
|
||||
message: '手机号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['blur'],
|
||||
}],
|
||||
region: [{
|
||||
required: true,
|
||||
message: '请选择省市区',
|
||||
trigger: ['blur', 'change'],
|
||||
type: 'array'
|
||||
}],
|
||||
detail: [{
|
||||
required: true,
|
||||
message: '请输入详细地址',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form,
|
||||
rules,
|
||||
// 按钮禁用
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {},
|
||||
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules)
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 选择微信地址
|
||||
// #ifdef MP-WEIXIN
|
||||
chooseAddress() {
|
||||
const { form, $refs } = this
|
||||
uni.chooseAddress({
|
||||
success(res) {
|
||||
const names = $refs.sRegion.getOptionItemByNames(res)
|
||||
form.name = res.userName
|
||||
form.phone = res.telNumber
|
||||
form.detail = res.detailInfo
|
||||
form.region = names.length > 0 ? names : []
|
||||
}
|
||||
})
|
||||
},
|
||||
// #endif
|
||||
|
||||
// 表单提交
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
if (app.disabled) {
|
||||
return false
|
||||
}
|
||||
app.$refs.uForm.validate(valid => {
|
||||
if (valid) {
|
||||
app.disabled = true
|
||||
AddressApi.add(app.form)
|
||||
.then(result => {
|
||||
app.$toast(result.message)
|
||||
uni.navigateBack()
|
||||
})
|
||||
.finally(() => app.disabled = false)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #f7f8fa;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.page-title {
|
||||
width: 94%;
|
||||
margin: 0 auto;
|
||||
padding-top: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(69, 90, 100, 0.6);
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
|
||||
.footer {
|
||||
margin-top: 80rpx;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-wechat {
|
||||
background: #0ba90b;
|
||||
margin-bottom: 26rpx;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
305
package/user/address/index.vue
Executable file
305
package/user/address/index.vue
Executable file
@@ -0,0 +1,305 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<view class="addres-list">
|
||||
<view class="address-item" v-for="(item, index) in list" :key="index">
|
||||
<view class="contacts">
|
||||
<text class="name">{{ item.name }}</text>
|
||||
<text class="phone">{{ item.phone }}</text>
|
||||
</view>
|
||||
<view class="address">
|
||||
<text class="region" v-for="(region, idx) in item.region" :key="idx">{{ region }}</text>
|
||||
<text class="detail">{{ item.detail }}</text>
|
||||
</view>
|
||||
<view class="line"></view>
|
||||
<view class="item-option">
|
||||
<view class="_left">
|
||||
<label class="item-radio" @click.stop="handleSetDefault(item.address_id)">
|
||||
<radio class="radio" :color="appTheme.mainBg" :checked="item.address_id == defaultId"></radio>
|
||||
<text class="text">{{ item.address_id == defaultId ? '默认' : '选择' }}</text>
|
||||
</label>
|
||||
</view>
|
||||
<view class="_right">
|
||||
<view class="events">
|
||||
<view class="event-item" @click="handleUpdate(item.address_id)">
|
||||
<text class="iconfont icon-edit"></text>
|
||||
<text class="title">编辑</text>
|
||||
</view>
|
||||
<view class="event-item" @click="handleRemove(item.address_id)">
|
||||
<text class="iconfont icon-delete"></text>
|
||||
<text class="title">删除</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<empty v-if="!list.length" :isLoading="isLoading" tips="亲,暂无收货地址" />
|
||||
<!-- 底部操作按钮 -->
|
||||
<view class="footer-fixed">
|
||||
<view class="btn-wrapper">
|
||||
<view class="btn-item btn-item-main" @click="handleCreate()">添加新地址</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as AddressApi from '@/api/address'
|
||||
import Empty from '@/components/empty'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Empty
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
//当前页面参数
|
||||
options: {},
|
||||
// 正在加载
|
||||
isLoading: true,
|
||||
// 收货地址列表
|
||||
list: [],
|
||||
// 默认收货地址
|
||||
defaultId: null
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
// 当前页面参数
|
||||
this.options = options
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow() {
|
||||
// 获取页面数据
|
||||
this.getPageData()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取页面数据
|
||||
getPageData() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
Promise.all([app.getDefaultId(), app.getAddressList()])
|
||||
.then(() => {
|
||||
// 列表排序把默认收货地址放到最前
|
||||
app.onReorder()
|
||||
})
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 获取收货地址列表
|
||||
getAddressList() {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
AddressApi.list()
|
||||
.then(result => {
|
||||
app.list = result.data.list
|
||||
resolve(result)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取默认的收货地址
|
||||
getDefaultId() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const app = this
|
||||
AddressApi.defaultId()
|
||||
.then(result => {
|
||||
app.defaultId = result.data.defaultId
|
||||
resolve(result)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 列表排序把默认收货地址放到最前
|
||||
onReorder() {
|
||||
const app = this
|
||||
app.list.sort(item => {
|
||||
return item.address_id == app.defaultId ? -1 : 1
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 添加新地址
|
||||
*/
|
||||
handleCreate() {
|
||||
this.$navTo('pages/address/create')
|
||||
},
|
||||
|
||||
/**
|
||||
* 编辑地址
|
||||
* @param {int} addressId 收货地址ID
|
||||
*/
|
||||
handleUpdate(addressId) {
|
||||
this.$navTo('pages/address/update', { addressId })
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除收货地址
|
||||
* @param {int} addressId 收货地址ID
|
||||
*/
|
||||
handleRemove(addressId) {
|
||||
const app = this
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "您确定要删除当前收货地址吗?",
|
||||
success({ confirm }) {
|
||||
confirm && app.onRemove(addressId)
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 确认删除收货地址
|
||||
* @param {int} addressId 收货地址ID
|
||||
*/
|
||||
onRemove(addressId) {
|
||||
const app = this
|
||||
AddressApi.remove(addressId)
|
||||
.then(result => {
|
||||
app.getPageData()
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 设置为默认地址
|
||||
* @param {Object} addressId
|
||||
*/
|
||||
handleSetDefault(addressId) {
|
||||
const app = this
|
||||
AddressApi.setDefault(addressId)
|
||||
.then(result => {
|
||||
app.defaultId = addressId
|
||||
app.options.from === 'checkout' && uni.navigateBack()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.addres-list {
|
||||
padding-bottom: calc(constant(safe-area-inset-bottom) + 140rpx);
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 140rpx);
|
||||
padding-top: 20rpx;
|
||||
}
|
||||
|
||||
// 项目内容
|
||||
.address-item {
|
||||
margin: 0 auto 20rpx auto;
|
||||
padding: 30rpx 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0 rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.contacts {
|
||||
font-size: 30rpx;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
.name {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.address {
|
||||
font-size: 28rpx;
|
||||
|
||||
.region {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
margin: 20rpx 0;
|
||||
border-bottom: 1rpx solid #f3f3f3;
|
||||
}
|
||||
|
||||
.item-option {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 48rpx;
|
||||
|
||||
// 单选框
|
||||
.item-radio {
|
||||
font-size: 28rpx;
|
||||
|
||||
.radio {
|
||||
vertical-align: middle;
|
||||
transform: scale(0.76)
|
||||
}
|
||||
|
||||
.text {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
// 操作
|
||||
.events {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 48rpx;
|
||||
|
||||
.event-item {
|
||||
font-size: 28rpx;
|
||||
margin-right: 26rpx;
|
||||
color: #4c4c4c;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 底部操作栏
|
||||
.footer-fixed {
|
||||
position: fixed;
|
||||
bottom: var(--window-bottom);
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 11;
|
||||
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
|
||||
.btn-wrapper {
|
||||
height: 120rpx;
|
||||
padding: 0 40rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-shadow: 0 1rpx 5rpx 0 rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
244
package/user/address/update.vue
Executable file
244
package/user/address/update.vue
Executable file
@@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<!-- 标题 -->
|
||||
<view class="page-title">收货地址</view>
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper">
|
||||
<u-form :model="form" ref="uForm" label-width="140rpx">
|
||||
<u-form-item label="姓名" prop="name">
|
||||
<u-input v-model="form.name" placeholder="请输入收货人姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="电话" prop="phone">
|
||||
<u-input v-model="form.phone" placeholder="请输入收货人手机号" />
|
||||
</u-form-item>
|
||||
<u-form-item label="地区" prop="region">
|
||||
<select-region ref="sRegion" v-model="form.region" />
|
||||
</u-form-item>
|
||||
<u-form-item label="详细地址" prop="detail" :border-bottom="false">
|
||||
<u-input v-model="form.detail" placeholder="街道门牌、楼层等信息" />
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn-wrapper">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="btn-item btn-item-wechat" @click="chooseAddress()">选择微信收货地址</view>
|
||||
<!-- #endif -->
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">保存</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
import { isMobile } from '@/utils/verify'
|
||||
import * as AddressApi from '@/api/address'
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
name: [{
|
||||
required: true,
|
||||
message: '请输入姓名',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
phone: [{
|
||||
required: true,
|
||||
message: '请输入手机号',
|
||||
trigger: ['blur', 'change']
|
||||
}, {
|
||||
// 自定义验证函数
|
||||
validator: (rule, value, callback) => {
|
||||
// 返回true表示校验通过,返回false表示不通过
|
||||
return isMobile(value)
|
||||
},
|
||||
message: '手机号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['blur'],
|
||||
}],
|
||||
region: [{
|
||||
required: true,
|
||||
message: '请选择省市区',
|
||||
trigger: ['blur', 'change'],
|
||||
type: 'array'
|
||||
}],
|
||||
detail: [{
|
||||
required: true,
|
||||
message: '请输入详细地址',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
name: '',
|
||||
phone: '',
|
||||
region: [],
|
||||
detail: ''
|
||||
},
|
||||
rules,
|
||||
// 加载中
|
||||
isLoading: true,
|
||||
// 按钮禁用
|
||||
disabled: false,
|
||||
// 当前收货地址ID
|
||||
addressId: null
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad({ addressId }) {
|
||||
// 当前收货地址ID
|
||||
this.addressId = addressId
|
||||
// 获取当前记录详情
|
||||
this.getDetail()
|
||||
},
|
||||
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules)
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取当前记录详情
|
||||
getDetail() {
|
||||
const app = this
|
||||
AddressApi.detail(app.addressId)
|
||||
.then(result => {
|
||||
const detail = result.data.detail
|
||||
app.createFormData(detail)
|
||||
})
|
||||
},
|
||||
|
||||
// 选择微信地址
|
||||
// #ifdef MP-WEIXIN
|
||||
chooseAddress() {
|
||||
const { form, $refs } = this
|
||||
uni.chooseAddress({
|
||||
success(res) {
|
||||
const names = $refs.sRegion.getOptionItemByNames(res)
|
||||
form.name = res.userName
|
||||
form.phone = res.telNumber
|
||||
form.detail = res.detailInfo
|
||||
form.region = names.length > 0 ? names : []
|
||||
}
|
||||
})
|
||||
},
|
||||
// #endif
|
||||
|
||||
// 生成默认的表单数据
|
||||
createFormData(detail) {
|
||||
const { form } = this
|
||||
form.name = detail.name
|
||||
form.phone = detail.phone
|
||||
form.detail = detail.detail
|
||||
form.region = this.createRegion(detail)
|
||||
},
|
||||
|
||||
createRegion(detail) {
|
||||
return [{
|
||||
label: detail.region.province,
|
||||
value: detail.province_id
|
||||
}, {
|
||||
label: detail.region.city,
|
||||
value: detail.city_id
|
||||
}, {
|
||||
label: detail.region.region,
|
||||
value: detail.region_id
|
||||
}]
|
||||
},
|
||||
|
||||
// 表单提交
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
if (app.disabled) {
|
||||
return false
|
||||
}
|
||||
app.$refs.uForm.validate(valid => {
|
||||
if (valid) {
|
||||
app.disabled = true
|
||||
AddressApi.edit(app.addressId, app.form)
|
||||
.then(result => {
|
||||
app.$toast(result.message)
|
||||
uni.navigateBack()
|
||||
})
|
||||
.finally(() => app.disabled = false)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #f7f8fa;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.page-title {
|
||||
width: 94%;
|
||||
margin: 0 auto;
|
||||
padding-top: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(69, 90, 100, 0.6);
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
|
||||
.footer {
|
||||
margin-top: 80rpx;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-wechat {
|
||||
background: #0ba90b;
|
||||
margin-bottom: 26rpx;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
109
package/user/admin/index.vue
Normal file
109
package/user/admin/index.vue
Normal file
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<view class="partner">
|
||||
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper" v-if="shopInfo">
|
||||
<u-form :model="form" ref="uForm" label-width="240rpx">
|
||||
<u-form-item>
|
||||
<view class="shop-box">
|
||||
<text class="shop-name">后台管理</text>
|
||||
<text>地址:https://dev.gxwebsoft.com/ylx-admin/</text>
|
||||
<text>账号:{{applyInfo.phone}}</text>
|
||||
<text>密码:默认为手机号码后6位</text>
|
||||
</view>
|
||||
</u-form-item>
|
||||
|
||||
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<!-- <view class="footer">
|
||||
<view class="btn">
|
||||
<u-button type="primary" shape="circle">更新资料</u-button>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 表单字段元素
|
||||
const form = {
|
||||
// 入驻类型 (合伙人10001,配送员10002,社区门店10003,省代10004)
|
||||
grade_id: 10004,
|
||||
company: '',
|
||||
real_name: '',
|
||||
phone: '',
|
||||
mobile: '',
|
||||
region: [],
|
||||
detail: '',
|
||||
}
|
||||
|
||||
import * as UserApi from '@/api/user'
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form,
|
||||
disabled: false,
|
||||
imageList: [],
|
||||
shopInfo: {},
|
||||
applyInfo: {}
|
||||
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.getUserInfo()
|
||||
},
|
||||
methods: {
|
||||
// 获取当前用户信息
|
||||
getUserInfo() {
|
||||
const app = this
|
||||
UserApi.info().then(result => {
|
||||
app.shopInfo = result.data.shopInfo
|
||||
app.applyInfo = result.data.applyInfo
|
||||
})
|
||||
},
|
||||
groupChange(){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.partner {
|
||||
.banner {
|
||||
padding-top: 20rpx;
|
||||
width: 100%;
|
||||
}
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
.shop-box{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.shop-name{
|
||||
font-weight: bold;
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
.logo{
|
||||
width: 100rpx;
|
||||
}
|
||||
.shipin{
|
||||
width: 400rpx;
|
||||
}
|
||||
}
|
||||
.footer{
|
||||
width: 500rpx;
|
||||
margin: 20rpx auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
206
package/user/equipment/create.vue
Executable file
206
package/user/equipment/create.vue
Executable file
@@ -0,0 +1,206 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<!-- 标题 -->
|
||||
<view class="page-title">收货地址</view>
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper">
|
||||
<u-form :model="form" ref="uForm" label-width="140rpx">
|
||||
<u-form-item label="姓名" prop="name">
|
||||
<u-input v-model="form.name" placeholder="请输入收货人姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="电话" prop="phone">
|
||||
<u-input v-model="form.phone" placeholder="请输入收货人手机号" />
|
||||
</u-form-item>
|
||||
<u-form-item label="地区" prop="region">
|
||||
<select-region ref="sRegion" v-model="form.region" />
|
||||
</u-form-item>
|
||||
<u-form-item label="详细地址" prop="detail" :border-bottom="false">
|
||||
<u-input v-model="form.detail" placeholder="街道门牌、楼层等信息" />
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn-wrapper">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="btn-item btn-item-wechat" @click="chooseAddress()">选择微信收货地址</view>
|
||||
<!-- #endif -->
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">保存</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
import { isMobile } from '@/utils/verify'
|
||||
import * as AddressApi from '@/api/address'
|
||||
|
||||
// 表单字段元素
|
||||
const form = {
|
||||
name: '',
|
||||
phone: '',
|
||||
region: [],
|
||||
detail: ''
|
||||
}
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
name: [{
|
||||
required: true,
|
||||
message: '请输入姓名',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
phone: [{
|
||||
required: true,
|
||||
message: '请输入手机号',
|
||||
trigger: ['blur', 'change']
|
||||
}, {
|
||||
// 自定义验证函数
|
||||
validator: (rule, value, callback) => {
|
||||
// 返回true表示校验通过,返回false表示不通过
|
||||
return isMobile(value)
|
||||
},
|
||||
message: '手机号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['blur'],
|
||||
}],
|
||||
region: [{
|
||||
required: true,
|
||||
message: '请选择省市区',
|
||||
trigger: ['blur', 'change'],
|
||||
type: 'array'
|
||||
}],
|
||||
detail: [{
|
||||
required: true,
|
||||
message: '请输入详细地址',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form,
|
||||
rules,
|
||||
// 按钮禁用
|
||||
disabled: false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {},
|
||||
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules)
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 选择微信地址
|
||||
// #ifdef MP-WEIXIN
|
||||
chooseAddress() {
|
||||
const { form, $refs } = this
|
||||
uni.chooseAddress({
|
||||
success(res) {
|
||||
const names = $refs.sRegion.getOptionItemByNames(res)
|
||||
form.name = res.userName
|
||||
form.phone = res.telNumber
|
||||
form.detail = res.detailInfo
|
||||
form.region = names.length > 0 ? names : []
|
||||
}
|
||||
})
|
||||
},
|
||||
// #endif
|
||||
|
||||
// 表单提交
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
if (app.disabled) {
|
||||
return false
|
||||
}
|
||||
app.$refs.uForm.validate(valid => {
|
||||
if (valid) {
|
||||
app.disabled = true
|
||||
AddressApi.add(app.form)
|
||||
.then(result => {
|
||||
app.$toast(result.message)
|
||||
uni.navigateBack()
|
||||
})
|
||||
.finally(() => app.disabled = false)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #f7f8fa;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.page-title {
|
||||
width: 94%;
|
||||
margin: 0 auto;
|
||||
padding-top: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(69, 90, 100, 0.6);
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
|
||||
.footer {
|
||||
margin-top: 80rpx;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-wechat {
|
||||
background: #0ba90b;
|
||||
margin-bottom: 26rpx;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
441
package/user/equipment/detail.vue
Executable file
441
package/user/equipment/detail.vue
Executable file
@@ -0,0 +1,441 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<view class="addres-list">
|
||||
<view class="address-item">
|
||||
<view class="head-info">
|
||||
<view class="title">{{ title }}</view>
|
||||
<view class="description">{{ description }}</view>
|
||||
|
||||
</view>
|
||||
<u-form :label-width="200" :model="form" ref="uForm">
|
||||
<u-form-item left-icon="info-circle" label="剩余电量">
|
||||
<view class="item-right">{{ form.surplusPower }}</view>
|
||||
</u-form-item>
|
||||
<u-form-item left-icon="info-circle" label="设备电压">
|
||||
<view class="item-right">{{ form.equipmentVoltage }}</view>
|
||||
</u-form-item>
|
||||
<u-form-item left-icon="info-circle" label="GPS信号">
|
||||
<view class="item-right">{{ form.gps }}</view>
|
||||
</u-form-item>
|
||||
<u-form-item left-icon="info-circle" label="GSM信号">
|
||||
<view class="item-right">{{ form.gsm }}</view>
|
||||
</u-form-item>
|
||||
<u-form-item left-icon="info-circle" label="设备电流">
|
||||
<view class="item-right">{{ form.equipmentCurrent }}</view>
|
||||
</u-form-item>
|
||||
<u-form-item left-icon="info-circle" label="标称容量">
|
||||
<view class="item-right">{{ form.nominalCapacity }}</view>
|
||||
</u-form-item>
|
||||
<u-form-item left-icon="info-circle" label="设备温度">
|
||||
<view class="item-right">{{ form.equipmentTemperature }}</view>
|
||||
</u-form-item>
|
||||
<u-form-item left-icon="info-circle" label="电池温度">
|
||||
<view class="item-right">{{ form.batteryTemperature }}</view>
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
</view>
|
||||
<view class="address-item">
|
||||
<u-row gutter="16" justify="center">
|
||||
<u-col span="4">
|
||||
<view class="demo-layout bg-purple">
|
||||
<text class="desc">最高电压</text>
|
||||
<text class="value1">3.168V</text>
|
||||
</view>
|
||||
</u-col>
|
||||
<u-col span="4">
|
||||
<view class="demo-layout bg-purple-light">
|
||||
<text class="desc">最低电压</text>
|
||||
<text class="value2">3.166V</text>
|
||||
</view>
|
||||
</u-col>
|
||||
<u-col span="4">
|
||||
<view class="demo-layout bg-purple-dark">
|
||||
<text class="desc">相差压值</text>
|
||||
<text class="value3">0.002V</text>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
<view class="address-item">
|
||||
<view class="head-info">
|
||||
<view class="title">电芯电压</view>
|
||||
</view>
|
||||
<view class="content">
|
||||
<image class="image" src="/static/battery.png"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as AddressApi from '@/api/address'
|
||||
import Empty from '@/components/empty'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Empty
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
//当前页面参数
|
||||
options: {},
|
||||
form: {
|
||||
surplusPower: '98%',
|
||||
equipmentVoltage: '82.6V',
|
||||
gps: '',
|
||||
gsm: '',
|
||||
equipmentCurrent: '12AH',
|
||||
nominalCapacity: '50AH',
|
||||
equipmentTemperature: '2℃',
|
||||
batteryTemperature: '35℃'
|
||||
},
|
||||
// 正在加载
|
||||
isLoading: true,
|
||||
// 收货地址列表
|
||||
list: [],
|
||||
// 默认收货地址
|
||||
defaultId: null,
|
||||
title: '设备信息',
|
||||
description: '要查看设备的相关参数信息'
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
// 当前页面参数
|
||||
this.options = options
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow() {
|
||||
// 获取页面数据
|
||||
this.getPageData()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取页面数据
|
||||
getPageData() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
Promise.all([app.getDefaultId(), app.getAddressList()])
|
||||
.then(() => {
|
||||
// 列表排序把默认收货地址放到最前
|
||||
app.onReorder()
|
||||
})
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 获取收货地址列表
|
||||
getAddressList() {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
AddressApi.list()
|
||||
.then(result => {
|
||||
app.list = result.data.list
|
||||
resolve(result)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取默认的收货地址
|
||||
getDefaultId() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const app = this
|
||||
AddressApi.defaultId()
|
||||
.then(result => {
|
||||
app.defaultId = result.data.defaultId
|
||||
resolve(result)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 列表排序把默认收货地址放到最前
|
||||
onReorder() {
|
||||
const app = this
|
||||
app.list.sort(item => {
|
||||
return item.address_id == app.defaultId ? -1 : 1
|
||||
})
|
||||
},
|
||||
|
||||
navTo(url) {
|
||||
this.$navTo(url)
|
||||
},
|
||||
|
||||
/**
|
||||
* 添加新地址
|
||||
*/
|
||||
handleCreate() {
|
||||
this.$navTo('pages/address/create')
|
||||
},
|
||||
|
||||
/**
|
||||
* 编辑地址
|
||||
* @param {int} addressId 收货地址ID
|
||||
*/
|
||||
handleUpdate(addressId) {
|
||||
this.$navTo('pages/address/update', {
|
||||
addressId
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除收货地址
|
||||
* @param {int} addressId 收货地址ID
|
||||
*/
|
||||
handleRemove(addressId) {
|
||||
const app = this
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "您确定要删除当前收货地址吗?",
|
||||
success({
|
||||
confirm
|
||||
}) {
|
||||
confirm && app.onRemove(addressId)
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 确认删除收货地址
|
||||
* @param {int} addressId 收货地址ID
|
||||
*/
|
||||
onRemove(addressId) {
|
||||
const app = this
|
||||
AddressApi.remove(addressId)
|
||||
.then(result => {
|
||||
app.getPageData()
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 设置为默认地址
|
||||
* @param {Object} addressId
|
||||
*/
|
||||
handleSetDefault(addressId) {
|
||||
const app = this
|
||||
AddressApi.setDefault(addressId)
|
||||
.then(result => {
|
||||
app.defaultId = addressId
|
||||
app.options.from === 'checkout' && uni.navigateBack()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.addres-list {
|
||||
padding-bottom: calc(constant(safe-area-inset-bottom) + 140rpx);
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 140rpx);
|
||||
padding-top: 20rpx;
|
||||
|
||||
.head-info {
|
||||
width: 750rpx;
|
||||
margin: auto;
|
||||
display: felx;
|
||||
flex-direction: column;
|
||||
|
||||
.title {
|
||||
font-weight: bold;
|
||||
font-size: 34rpx;
|
||||
}
|
||||
|
||||
.description {
|
||||
padding: 10rpx 0;
|
||||
font-size: 30rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 项目内容
|
||||
.address-item {
|
||||
margin: 0 auto 20rpx auto;
|
||||
padding: 30rpx 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0 rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.item-right {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.demo-layout {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.value1 {
|
||||
color: #de4e02;
|
||||
}
|
||||
|
||||
.value2 {
|
||||
color: #ff0089;
|
||||
}
|
||||
|
||||
.value3 {
|
||||
color: #0c10f5;
|
||||
}
|
||||
}
|
||||
|
||||
.image{
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.contacts {
|
||||
margin-bottom: 16rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.bms-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.item {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.name {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.bms-image {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
width: 120rpx;
|
||||
|
||||
.bms-image-box {
|
||||
display: flex;
|
||||
font-size: 22rpx;
|
||||
margin-bottom: 18rpx;
|
||||
color: #00af00;
|
||||
|
||||
.bms-image-fbf {
|
||||
margin-top: 22rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 50rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.address {
|
||||
font-size: 28rpx;
|
||||
|
||||
.region {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
margin: 20rpx 0;
|
||||
border-bottom: 1rpx solid #f3f3f3;
|
||||
}
|
||||
|
||||
.line-align {
|
||||
width: 6rpx;
|
||||
height: 48rpx;
|
||||
border-right: 1rpx solid #f3f3f3;
|
||||
}
|
||||
|
||||
.item-option {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
height: 48rpx;
|
||||
|
||||
// 单选框
|
||||
.item-radio {
|
||||
font-size: 28rpx;
|
||||
|
||||
.radio {
|
||||
vertical-align: middle;
|
||||
transform: scale(0.76)
|
||||
}
|
||||
|
||||
.text {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
// 操作
|
||||
.events {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 48rpx;
|
||||
|
||||
.event-item {
|
||||
font-size: 28rpx;
|
||||
margin-right: 26rpx;
|
||||
color: #4c4c4c;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 底部操作栏
|
||||
.footer-fixed {
|
||||
position: fixed;
|
||||
bottom: var(--window-bottom);
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 11;
|
||||
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
|
||||
.btn-wrapper {
|
||||
height: 120rpx;
|
||||
padding: 0 40rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-shadow: 0 1rpx 5rpx 0 rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
358
package/user/equipment/index.vue
Executable file
358
package/user/equipment/index.vue
Executable file
@@ -0,0 +1,358 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<view class="addres-list">
|
||||
<view class="address-item" v-for="(item, index) in list" :key="index">
|
||||
<view class="title">
|
||||
<text>设备编号:{{ item.phone }}</text>
|
||||
<u-tag text="已激活" plain size="mini" type="success"></u-tag>
|
||||
</view>
|
||||
<view class="line"></view>
|
||||
<view class="contacts">
|
||||
<view class="bms-info">
|
||||
<text class="item">电池型号:</text>
|
||||
<text class="item">BMS模块:硬件版</text>
|
||||
<text class="item">工作状态:正常</text>
|
||||
<text class="item">电池状态:健康</text>
|
||||
</view>
|
||||
<view class="bms-image">
|
||||
<view class="bms-image-box">
|
||||
<image class="image" src="../../../static/battery.png"></image>
|
||||
<text class="bms-image-fbf">67%</text>
|
||||
</view>
|
||||
<u-tag text="离线" plain size="mini" type="info"></u-tag>
|
||||
</view>
|
||||
</view>
|
||||
<view class="line"></view>
|
||||
<view class="item-option">
|
||||
<view class="_left">
|
||||
<u-icon label="操作" size="40" name="map" @click="navTo('package/user/equipment/operation')"></u-icon>
|
||||
</view>
|
||||
<view class="line-align"></view>
|
||||
<view class="_right">
|
||||
<view class="events">
|
||||
<u-icon label="详情" size="40" name="file-text" @click="navTo('package/user/equipment/detail')"></u-icon>
|
||||
<!-- <view class="event-item" @click="handleUpdate(item.address_id)">
|
||||
<text class="iconfont icon-edit"></text>
|
||||
<text class="title">编辑</text>
|
||||
</view>
|
||||
<view class="event-item" @click="handleRemove(item.address_id)">
|
||||
<text class="iconfont icon-delete"></text>
|
||||
<text class="title">删除</text>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<empty v-if="!list.length" :isLoading="isLoading" tips="亲,暂无取货地址" />
|
||||
<!-- 底部操作按钮 -->
|
||||
<view class="footer-fixed">
|
||||
<view class="btn-wrapper">
|
||||
<view class="btn-item btn-item-main" @click="handleCreate()">添加新地址</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as AddressApi from '@/api/address'
|
||||
import Empty from '@/components/empty'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Empty
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
//当前页面参数
|
||||
options: {},
|
||||
// 正在加载
|
||||
isLoading: true,
|
||||
// 收货地址列表
|
||||
list: [],
|
||||
// 默认收货地址
|
||||
defaultId: null
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
// 当前页面参数
|
||||
this.options = options
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow() {
|
||||
// 获取页面数据
|
||||
this.getPageData()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取页面数据
|
||||
getPageData() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
Promise.all([app.getDefaultId(), app.getAddressList()])
|
||||
.then(() => {
|
||||
// 列表排序把默认收货地址放到最前
|
||||
app.onReorder()
|
||||
})
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 获取收货地址列表
|
||||
getAddressList() {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
AddressApi.list()
|
||||
.then(result => {
|
||||
app.list = result.data.list
|
||||
resolve(result)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取默认的收货地址
|
||||
getDefaultId() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const app = this
|
||||
AddressApi.defaultId()
|
||||
.then(result => {
|
||||
app.defaultId = result.data.defaultId
|
||||
resolve(result)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 列表排序把默认收货地址放到最前
|
||||
onReorder() {
|
||||
const app = this
|
||||
app.list.sort(item => {
|
||||
return item.address_id == app.defaultId ? -1 : 1
|
||||
})
|
||||
},
|
||||
|
||||
navTo(url){
|
||||
this.$navTo(url)
|
||||
},
|
||||
|
||||
/**
|
||||
* 添加新地址
|
||||
*/
|
||||
handleCreate() {
|
||||
this.$navTo('pages/address/create')
|
||||
},
|
||||
|
||||
/**
|
||||
* 编辑地址
|
||||
* @param {int} addressId 收货地址ID
|
||||
*/
|
||||
handleUpdate(addressId) {
|
||||
this.$navTo('pages/address/update', { addressId })
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除收货地址
|
||||
* @param {int} addressId 收货地址ID
|
||||
*/
|
||||
handleRemove(addressId) {
|
||||
const app = this
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "您确定要删除当前收货地址吗?",
|
||||
success({ confirm }) {
|
||||
confirm && app.onRemove(addressId)
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 确认删除收货地址
|
||||
* @param {int} addressId 收货地址ID
|
||||
*/
|
||||
onRemove(addressId) {
|
||||
const app = this
|
||||
AddressApi.remove(addressId)
|
||||
.then(result => {
|
||||
app.getPageData()
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 设置为默认地址
|
||||
* @param {Object} addressId
|
||||
*/
|
||||
handleSetDefault(addressId) {
|
||||
const app = this
|
||||
AddressApi.setDefault(addressId)
|
||||
.then(result => {
|
||||
app.defaultId = addressId
|
||||
app.options.from === 'checkout' && uni.navigateBack()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.addres-list {
|
||||
padding-bottom: calc(constant(safe-area-inset-bottom) + 140rpx);
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 140rpx);
|
||||
padding-top: 20rpx;
|
||||
}
|
||||
|
||||
// 项目内容
|
||||
.address-item {
|
||||
margin: 0 auto 20rpx auto;
|
||||
padding: 30rpx 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0 rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
.title{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
.contacts {
|
||||
margin-bottom: 16rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.bms-info{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: #666666;
|
||||
.item{
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
.name {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
}
|
||||
.bms-image{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
width: 120rpx;
|
||||
.bms-image-box{
|
||||
display: flex;
|
||||
font-size: 22rpx;
|
||||
margin-bottom: 18rpx;
|
||||
color: #00af00;
|
||||
.bms-image-fbf{
|
||||
margin-top: 22rpx;
|
||||
}
|
||||
}
|
||||
.image{
|
||||
width: 50rpx; height: 60rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.address {
|
||||
font-size: 28rpx;
|
||||
|
||||
.region {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
margin: 20rpx 0;
|
||||
border-bottom: 1rpx solid #f3f3f3;
|
||||
}
|
||||
|
||||
.line-align{
|
||||
width: 6rpx;
|
||||
height: 48rpx;
|
||||
border-right: 1rpx solid #f3f3f3;
|
||||
}
|
||||
|
||||
.item-option {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
height: 48rpx;
|
||||
|
||||
// 单选框
|
||||
.item-radio {
|
||||
font-size: 28rpx;
|
||||
|
||||
.radio {
|
||||
vertical-align: middle;
|
||||
transform: scale(0.76)
|
||||
}
|
||||
|
||||
.text {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
// 操作
|
||||
.events {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 48rpx;
|
||||
|
||||
.event-item {
|
||||
font-size: 28rpx;
|
||||
margin-right: 26rpx;
|
||||
color: #4c4c4c;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 底部操作栏
|
||||
.footer-fixed {
|
||||
position: fixed;
|
||||
bottom: var(--window-bottom);
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 11;
|
||||
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
|
||||
.btn-wrapper {
|
||||
height: 120rpx;
|
||||
padding: 0 40rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-shadow: 0 1rpx 5rpx 0 rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
440
package/user/equipment/operation.vue
Executable file
440
package/user/equipment/operation.vue
Executable file
@@ -0,0 +1,440 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<view class="addres-list">
|
||||
<view class="address-item">
|
||||
<view class="head-info">
|
||||
<view class="title">{{ title }}</view>
|
||||
<view class="description">{{ description }}</view>
|
||||
</view>
|
||||
<u-form :label-width="200" :model="form" ref="uForm">
|
||||
<u-form-item left-icon="pause-circle" label="放电开关">
|
||||
<u-switch slot="right" v-model="form.switchVal1"></u-switch>
|
||||
</u-form-item>
|
||||
<u-form-item left-icon="lock-open" label="放电开关">
|
||||
<u-switch slot="right" v-model="form.switchVal2"></u-switch>
|
||||
</u-form-item>
|
||||
<u-form-item left-icon="reload" label="更换电池">
|
||||
<u-tag text="更换" slot="right" plain type="error" @click="handleChangeEquipment"></u-tag>
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 换电 -->
|
||||
<u-popup v-model="showQRCodeBind" mode="center" border-radius="26" :closeable="true">
|
||||
<view class="qrcode-bind">
|
||||
<view class="title">请输入更换的新电池编号</view>
|
||||
<view class="bind-content">
|
||||
<input v-model="bindValue" class="input" @confirm="onSearch" focus="true" placeholder="请输入设备编号"
|
||||
type="text"></input>
|
||||
</view>
|
||||
<view class="submit">
|
||||
<u-button type="error" @click="doEquipment(true)">确定更换电池</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as AddressApi from '@/api/address'
|
||||
import Empty from '@/components/empty'
|
||||
import * as EquipmentApi from '@/websoft/api/equipment.js'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Empty
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
//当前页面参数
|
||||
options: {},
|
||||
equipmentId: {},
|
||||
equipment: {},
|
||||
form: {
|
||||
switchVal1: false,
|
||||
switchVal2: false,
|
||||
},
|
||||
// 正在加载
|
||||
isLoading: true,
|
||||
// 收货地址列表
|
||||
list: [],
|
||||
// 默认收货地址
|
||||
defaultId: null,
|
||||
title: '设备操作',
|
||||
showQRCodeBind: false,
|
||||
bindValue: '',
|
||||
orderId: null,
|
||||
description: '用户可控制设备的控制开关'
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
// 当前页面参数
|
||||
this.options = options
|
||||
this.equipmentId = options.equipmentId
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow() {
|
||||
// 获取页面数据
|
||||
this.getPageData()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取页面数据
|
||||
getPageData() {
|
||||
const app = this
|
||||
EquipmentApi.getEquipment(app.equipmentId).then(result => {
|
||||
app.equipment = result.data
|
||||
app.orderId = result.data.orderId
|
||||
})
|
||||
// app.isLoading = true
|
||||
// Promise.all([app.getDefaultId(), app.getAddressList()])
|
||||
// .then(() => {
|
||||
// // 列表排序把默认收货地址放到最前
|
||||
// app.onReorder()
|
||||
// })
|
||||
// .finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 获取收货地址列表
|
||||
getAddressList() {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
AddressApi.list()
|
||||
.then(result => {
|
||||
app.list = result.data.list
|
||||
resolve(result)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
handleChangeEquipment() {
|
||||
const app = this
|
||||
app.showQRCodeBind = true
|
||||
},
|
||||
doEquipment(canReset = false) {
|
||||
const app = this
|
||||
const {
|
||||
equipmentId,
|
||||
bindValue,
|
||||
orderId
|
||||
} = this
|
||||
EquipmentApi.changeEquipment({
|
||||
equipmentCode: bindValue,
|
||||
equipmentId,
|
||||
orderId
|
||||
}).then(result => {
|
||||
app.$success(result.message)
|
||||
app.showQRCodeBind = false
|
||||
app.getPageData()
|
||||
}).catch(err => {
|
||||
app.$error(err.message)
|
||||
})
|
||||
console.log("this.bindValue: ", this.bindValue);
|
||||
},
|
||||
|
||||
// 获取默认的收货地址
|
||||
getDefaultId() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const app = this
|
||||
AddressApi.defaultId()
|
||||
.then(result => {
|
||||
app.defaultId = result.data.defaultId
|
||||
resolve(result)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 列表排序把默认收货地址放到最前
|
||||
onReorder() {
|
||||
const app = this
|
||||
app.list.sort(item => {
|
||||
return item.address_id == app.defaultId ? -1 : 1
|
||||
})
|
||||
},
|
||||
|
||||
navTo(url) {
|
||||
this.$navTo(url)
|
||||
},
|
||||
|
||||
/**
|
||||
* 添加新地址
|
||||
*/
|
||||
handleCreate() {
|
||||
this.$navTo('pages/address/create')
|
||||
},
|
||||
|
||||
/**
|
||||
* 编辑地址
|
||||
* @param {int} addressId 收货地址ID
|
||||
*/
|
||||
handleUpdate(addressId) {
|
||||
this.$navTo('pages/address/update', {
|
||||
addressId
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除收货地址
|
||||
* @param {int} addressId 收货地址ID
|
||||
*/
|
||||
handleRemove(addressId) {
|
||||
const app = this
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "您确定要删除当前收货地址吗?",
|
||||
success({
|
||||
confirm
|
||||
}) {
|
||||
confirm && app.onRemove(addressId)
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 确认删除收货地址
|
||||
* @param {int} addressId 收货地址ID
|
||||
*/
|
||||
onRemove(addressId) {
|
||||
const app = this
|
||||
AddressApi.remove(addressId)
|
||||
.then(result => {
|
||||
app.getPageData()
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 设置为默认地址
|
||||
* @param {Object} addressId
|
||||
*/
|
||||
handleSetDefault(addressId) {
|
||||
const app = this
|
||||
AddressApi.setDefault(addressId)
|
||||
.then(result => {
|
||||
app.defaultId = addressId
|
||||
app.options.from === 'checkout' && uni.navigateBack()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.addres-list {
|
||||
padding-bottom: calc(constant(safe-area-inset-bottom) + 140rpx);
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 140rpx);
|
||||
padding-top: 20rpx;
|
||||
|
||||
.head-info {
|
||||
width: 750rpx;
|
||||
margin: auto;
|
||||
display: felx;
|
||||
flex-direction: column;
|
||||
|
||||
.title {
|
||||
font-weight: bold;
|
||||
font-size: 34rpx;
|
||||
}
|
||||
|
||||
.description {
|
||||
padding: 10rpx 0;
|
||||
font-size: 30rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 项目内容
|
||||
.address-item {
|
||||
margin: 0 auto 20rpx auto;
|
||||
padding: 30rpx 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0 rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
.contacts {
|
||||
margin-bottom: 16rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.bms-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.item {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.name {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.bms-image {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
width: 120rpx;
|
||||
|
||||
.bms-image-box {
|
||||
display: flex;
|
||||
font-size: 22rpx;
|
||||
margin-bottom: 18rpx;
|
||||
color: #00af00;
|
||||
|
||||
.bms-image-fbf {
|
||||
margin-top: 22rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 50rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.address {
|
||||
font-size: 28rpx;
|
||||
|
||||
.region {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
margin: 20rpx 0;
|
||||
border-bottom: 1rpx solid #f3f3f3;
|
||||
}
|
||||
|
||||
.line-align {
|
||||
width: 6rpx;
|
||||
height: 48rpx;
|
||||
border-right: 1rpx solid #f3f3f3;
|
||||
}
|
||||
|
||||
.item-option {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
height: 48rpx;
|
||||
|
||||
// 单选框
|
||||
.item-radio {
|
||||
font-size: 28rpx;
|
||||
|
||||
.radio {
|
||||
vertical-align: middle;
|
||||
transform: scale(0.76)
|
||||
}
|
||||
|
||||
.text {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
// 操作
|
||||
.events {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 48rpx;
|
||||
|
||||
.event-item {
|
||||
font-size: 28rpx;
|
||||
margin-right: 26rpx;
|
||||
color: #4c4c4c;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 底部操作栏
|
||||
.footer-fixed {
|
||||
position: fixed;
|
||||
bottom: var(--window-bottom);
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 11;
|
||||
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
|
||||
.btn-wrapper {
|
||||
height: 120rpx;
|
||||
padding: 0 40rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-shadow: 0 1rpx 5rpx 0 rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
}
|
||||
|
||||
}
|
||||
// 弹出层 - 绑定设备码
|
||||
.qrcode-bind{
|
||||
width: 550rpx;
|
||||
height: 300rpx;
|
||||
padding: 36rpx 30rpx;
|
||||
|
||||
.title {
|
||||
font-size: 30rpx;
|
||||
margin-bottom: 26rpx;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.bind-content {
|
||||
padding: 0 10rpx;
|
||||
border: 1rpx solid #eee;
|
||||
font-size: 24rpx;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 510rpx;
|
||||
height: 510rpx;
|
||||
}
|
||||
|
||||
}
|
||||
.submit{
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
244
package/user/equipment/update.vue
Executable file
244
package/user/equipment/update.vue
Executable file
@@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<!-- 标题 -->
|
||||
<view class="page-title">收货地址</view>
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper">
|
||||
<u-form :model="form" ref="uForm" label-width="140rpx">
|
||||
<u-form-item label="姓名" prop="name">
|
||||
<u-input v-model="form.name" placeholder="请输入收货人姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="电话" prop="phone">
|
||||
<u-input v-model="form.phone" placeholder="请输入收货人手机号" />
|
||||
</u-form-item>
|
||||
<u-form-item label="地区" prop="region">
|
||||
<select-region ref="sRegion" v-model="form.region" />
|
||||
</u-form-item>
|
||||
<u-form-item label="详细地址" prop="detail" :border-bottom="false">
|
||||
<u-input v-model="form.detail" placeholder="街道门牌、楼层等信息" />
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="footer">
|
||||
<view class="btn-wrapper">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="btn-item btn-item-wechat" @click="chooseAddress()">选择微信收货地址</view>
|
||||
<!-- #endif -->
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">保存</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
import { isMobile } from '@/utils/verify'
|
||||
import * as AddressApi from '@/api/address'
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
name: [{
|
||||
required: true,
|
||||
message: '请输入姓名',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
phone: [{
|
||||
required: true,
|
||||
message: '请输入手机号',
|
||||
trigger: ['blur', 'change']
|
||||
}, {
|
||||
// 自定义验证函数
|
||||
validator: (rule, value, callback) => {
|
||||
// 返回true表示校验通过,返回false表示不通过
|
||||
return isMobile(value)
|
||||
},
|
||||
message: '手机号码不正确',
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ['blur'],
|
||||
}],
|
||||
region: [{
|
||||
required: true,
|
||||
message: '请选择省市区',
|
||||
trigger: ['blur', 'change'],
|
||||
type: 'array'
|
||||
}],
|
||||
detail: [{
|
||||
required: true,
|
||||
message: '请输入详细地址',
|
||||
trigger: ['blur', 'change']
|
||||
}],
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
name: '',
|
||||
phone: '',
|
||||
region: [],
|
||||
detail: ''
|
||||
},
|
||||
rules,
|
||||
// 加载中
|
||||
isLoading: true,
|
||||
// 按钮禁用
|
||||
disabled: false,
|
||||
// 当前收货地址ID
|
||||
addressId: null
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad({ addressId }) {
|
||||
// 当前收货地址ID
|
||||
this.addressId = addressId
|
||||
// 获取当前记录详情
|
||||
this.getDetail()
|
||||
},
|
||||
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules)
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取当前记录详情
|
||||
getDetail() {
|
||||
const app = this
|
||||
AddressApi.detail(app.addressId)
|
||||
.then(result => {
|
||||
const detail = result.data.detail
|
||||
app.createFormData(detail)
|
||||
})
|
||||
},
|
||||
|
||||
// 选择微信地址
|
||||
// #ifdef MP-WEIXIN
|
||||
chooseAddress() {
|
||||
const { form, $refs } = this
|
||||
uni.chooseAddress({
|
||||
success(res) {
|
||||
const names = $refs.sRegion.getOptionItemByNames(res)
|
||||
form.name = res.userName
|
||||
form.phone = res.telNumber
|
||||
form.detail = res.detailInfo
|
||||
form.region = names.length > 0 ? names : []
|
||||
}
|
||||
})
|
||||
},
|
||||
// #endif
|
||||
|
||||
// 生成默认的表单数据
|
||||
createFormData(detail) {
|
||||
const { form } = this
|
||||
form.name = detail.name
|
||||
form.phone = detail.phone
|
||||
form.detail = detail.detail
|
||||
form.region = this.createRegion(detail)
|
||||
},
|
||||
|
||||
createRegion(detail) {
|
||||
return [{
|
||||
label: detail.region.province,
|
||||
value: detail.province_id
|
||||
}, {
|
||||
label: detail.region.city,
|
||||
value: detail.city_id
|
||||
}, {
|
||||
label: detail.region.region,
|
||||
value: detail.region_id
|
||||
}]
|
||||
},
|
||||
|
||||
// 表单提交
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
if (app.disabled) {
|
||||
return false
|
||||
}
|
||||
app.$refs.uForm.validate(valid => {
|
||||
if (valid) {
|
||||
app.disabled = true
|
||||
AddressApi.edit(app.addressId, app.form)
|
||||
.then(result => {
|
||||
app.$toast(result.message)
|
||||
uni.navigateBack()
|
||||
})
|
||||
.finally(() => app.disabled = false)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #f7f8fa;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.page-title {
|
||||
width: 94%;
|
||||
margin: 0 auto;
|
||||
padding-top: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(69, 90, 100, 0.6);
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
|
||||
.footer {
|
||||
margin-top: 80rpx;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 86rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-wechat {
|
||||
background: #0ba90b;
|
||||
margin-bottom: 26rpx;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
618
package/user/goods/cashier.vue
Executable file
618
package/user/goods/cashier.vue
Executable file
@@ -0,0 +1,618 @@
|
||||
<template>
|
||||
<view v-if="!isLoading" class="container" :style="appThemeStyle">
|
||||
|
||||
|
||||
<!-- 订单信息 -->
|
||||
<view class="order-info">
|
||||
<!-- 支付剩余时间 -->
|
||||
<view class="order-countdown">
|
||||
<text class="m-r-6">剩余时间</text>
|
||||
<count-down :date="order.expirationTime" separator="zh" theme="text" />
|
||||
</view>
|
||||
<!-- 付款金额 -->
|
||||
<view class="order-amount">
|
||||
<text class="unit">¥</text>
|
||||
<text class="amount">{{ order.pay_price }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 购买时长 -->
|
||||
<u-card title="订单信息">
|
||||
<view class="duration-method" slot="body">
|
||||
<view class="pay-item dis-flex flex-x-between">
|
||||
<view class="item-left dis-flex flex-y-center">
|
||||
<view class="item-left_text">
|
||||
<text>购买时长</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-right col-m" @click="onShowDuration">
|
||||
<text class="duration-title">{{ duration[planId].label }}</text>
|
||||
<text class="iconfont icon-arrow-down"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pay-item dis-flex flex-x-between">
|
||||
<view class="item-left dis-flex flex-y-center">
|
||||
<view class="item-left_text">
|
||||
<text>购买数量</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-right col-m">
|
||||
<text>{{ length }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<u-select v-model="showDuration" :list="duration" @confirm="onConfirm"></u-select>
|
||||
</view>
|
||||
</u-card>
|
||||
|
||||
<!-- 支付方式 -->
|
||||
<u-card title="付款方式">
|
||||
<view class="payment-method" slot="body">
|
||||
<view v-for="(item, index) in methods" :key="index" class="pay-item dis-flex flex-x-between"
|
||||
@click="handleSelectPayType(index)">
|
||||
<view class="item-left dis-flex flex-y-center">
|
||||
<view class="item-left_icon" :class="[item.method]">
|
||||
<text class="iconfont" :class="[PayMethodIconEnum[item.method]]"></text>
|
||||
</view>
|
||||
<view class="item-left_text">
|
||||
<text>{{ PayMethodEnum[item.method].name }}</text>
|
||||
</view>
|
||||
<view v-if="item.method === PayMethodEnum.BALANCE.value" class="user-balance">
|
||||
<text>(可用¥{{ personal.balance }}元)</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-right col-m" v-if="curPaymentItem && curPaymentItem.method == item.method">
|
||||
<text class="iconfont icon-check"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-card>
|
||||
|
||||
<!-- 确认按钮 -->
|
||||
<view class="footer-fixed">
|
||||
<view class="btn-wrapper">
|
||||
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">确认支付</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付确认弹窗 -->
|
||||
<!-- #ifdef H5 -->
|
||||
<u-modal v-if="tempUnifyData" v-model="showConfirmModal" title="支付确认" show-cancel-button confirm-text="已完成支付"
|
||||
:confirm-color="appTheme.mainBg" negative-top="100" :asyncClose="true"
|
||||
@confirm="onTradeQuery(tempUnifyData.outTradeNo, tempUnifyData.method)">
|
||||
<view class="modal-content">
|
||||
<text>请在{{ PayMethodClientNameEnum[tempUnifyData.method] }}内完成支付,如果您已经支付成功,请点击“已完成支付”按钮</text>
|
||||
</view>
|
||||
</u-modal>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from '@/utils/storage'
|
||||
import {
|
||||
inArray,
|
||||
urlEncode
|
||||
} from '@/utils/util'
|
||||
import {
|
||||
Alipay,
|
||||
Wechat
|
||||
} from '@/core/payment'
|
||||
import CountDown from '@/components/countdown'
|
||||
import {
|
||||
PayMethodEnum
|
||||
} from '@/common/enum/payment'
|
||||
import {
|
||||
PayStatusEnum
|
||||
} from '@/common/enum/order'
|
||||
import * as Api from '@/api/order/popularize.js'
|
||||
|
||||
// 支付方式对应的图标
|
||||
const PayMethodIconEnum = {
|
||||
[PayMethodEnum.WECHAT.value]: 'icon-wechat-pay',
|
||||
[PayMethodEnum.ALIPAY.value]: 'icon-alipay',
|
||||
[PayMethodEnum.BALANCE.value]: 'icon-balance-pay'
|
||||
}
|
||||
|
||||
// 支付方式的终端名称
|
||||
const PayMethodClientNameEnum = {
|
||||
[PayMethodEnum.WECHAT.value]: '微信',
|
||||
[PayMethodEnum.ALIPAY.value]: '支付宝'
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CountDown
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 加载中
|
||||
isLoading: true,
|
||||
// 确认按钮禁用
|
||||
disabled: false,
|
||||
// 枚举类
|
||||
PayMethodEnum,
|
||||
PayMethodIconEnum,
|
||||
PayMethodClientNameEnum,
|
||||
// 当前选中的支付方式
|
||||
curPaymentItem: null,
|
||||
// 当前订单ID
|
||||
orderId: null,
|
||||
// 当前结算订单信息
|
||||
order: {},
|
||||
// 个人信息
|
||||
personal: {
|
||||
balance: '0.00'
|
||||
},
|
||||
// 当前客户端的支付方式列表(后端根据platform判断)
|
||||
methods: [],
|
||||
// 支付确认弹窗
|
||||
showConfirmModal: false,
|
||||
// #ifdef H5
|
||||
// 当前微信支付信息 (临时数据, 仅用于H5端)
|
||||
tempUnifyData: {
|
||||
outTradeNo: '',
|
||||
method: ''
|
||||
},
|
||||
// #endif
|
||||
// 购买商品数量
|
||||
length: 0,
|
||||
// 购买的商品ID
|
||||
goodsIds: [],
|
||||
|
||||
// 购买时长
|
||||
duration: [],
|
||||
// 套餐ID
|
||||
planId: 0,
|
||||
showDuration: false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
// 读取缓存数据
|
||||
const goodsIds = storage.get('selectGoodsIdsByPopularize')
|
||||
this.goodsIds = goodsIds
|
||||
// 购买数量
|
||||
this.length = goodsIds.length
|
||||
// 获取收银台信息
|
||||
this.getCashierInfo()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取收银台信息
|
||||
getCashierInfo() {
|
||||
const app = this
|
||||
const { goodsIds, planId, length } = this
|
||||
app.isLoading = true
|
||||
// 读取缓存数据
|
||||
Api.orderInfo({form: {planId,goodsIds,length}})
|
||||
.then(result => {
|
||||
app.order = result.data.order
|
||||
app.personal = result.data.personal
|
||||
app.methods = result.data.paymentMethods
|
||||
app.duration = result.data.planList.map((d,index) => {
|
||||
return {
|
||||
value: index,
|
||||
label: d.plan_name + '¥(' + d.money + ')'
|
||||
}
|
||||
})
|
||||
app.isLoading = false
|
||||
app.setDefaultPayType()
|
||||
app.checkOrderPayStatus()
|
||||
// #ifdef H5
|
||||
// 判断当前页面来源于浏览器返回
|
||||
this.performance()
|
||||
// #endif
|
||||
})
|
||||
},
|
||||
|
||||
// 设置默认的支付方式
|
||||
setDefaultPayType() {
|
||||
const app = this
|
||||
if (app.disabled) return
|
||||
const defaultIndex = app.methods.findIndex(item => item.is_default == true)
|
||||
defaultIndex > -1 && app.handleSelectPayType(defaultIndex)
|
||||
},
|
||||
|
||||
// 判断当前订单是否为已支付
|
||||
checkOrderPayStatus() {
|
||||
const app = this
|
||||
if (app.order.pay_status == PayStatusEnum.SUCCESS.value) {
|
||||
app.$toast('恭喜您,订单已付款成功')
|
||||
app.onSuccessNav()
|
||||
}
|
||||
},
|
||||
|
||||
onShowDuration(index){
|
||||
this.showDuration = true
|
||||
},
|
||||
|
||||
onConfirm(item){
|
||||
this.planId = item[0].value
|
||||
this.getCashierInfo()
|
||||
},
|
||||
|
||||
bindPickerChange: function(e) {
|
||||
console.log('picker发送选择改变,携带值为', e.detail.value)
|
||||
this.index = e.detail.value
|
||||
},
|
||||
// 选择支付方式
|
||||
handleSelectPayType(index) {
|
||||
this.curPaymentItem = this.methods[index]
|
||||
},
|
||||
|
||||
// 选择时长类型
|
||||
handleSelectDurationType(key){
|
||||
this.selectDuration = key
|
||||
},
|
||||
|
||||
// 判断当前页面来源于浏览器返回
|
||||
// #ifdef H5
|
||||
performance() {
|
||||
const app = this
|
||||
// 判断订单状态, 异步回调会将订单状态变为已支付, 那么就不需要让用户手动查单了
|
||||
if (app.order.pay_status == PayStatusEnum.PENDING.value) {
|
||||
app.alipayPerformance()
|
||||
app.wechatPerformance()
|
||||
}
|
||||
},
|
||||
|
||||
// H5端支付宝支付完成跳转回当前页面时触发
|
||||
alipayPerformance() {
|
||||
const app = this
|
||||
app.tempUnifyData = Alipay.performance()
|
||||
if (app.tempUnifyData) {
|
||||
app.onTradeQuery(app.tempUnifyData.outTradeNo, app.tempUnifyData.method)
|
||||
}
|
||||
},
|
||||
|
||||
// H5端微信支付完成或返回时触发
|
||||
wechatPerformance() {
|
||||
const app = this
|
||||
app.tempUnifyData = Wechat.performance(app.orderId)
|
||||
if (app.tempUnifyData) {
|
||||
app.showConfirmModal = true
|
||||
}
|
||||
},
|
||||
// #endif
|
||||
|
||||
// 确认支付
|
||||
handleSubmit() {
|
||||
const app = this
|
||||
const { goodsIds, planId, length } = this
|
||||
// 判断是否选择了支付方式
|
||||
if (!app.curPaymentItem) {
|
||||
app.$toast('您还没有选择支付方式')
|
||||
return
|
||||
}
|
||||
// 按钮禁用
|
||||
if (app.disabled) return
|
||||
app.disabled = true
|
||||
// 提交到后端API
|
||||
Api.orderPay({
|
||||
form: {
|
||||
method: app.curPaymentItem.method,
|
||||
client: app.platform,
|
||||
extra: app.getExtraAsUnify(app.curPaymentItem.method),
|
||||
goodsIds,
|
||||
planId,
|
||||
length
|
||||
}
|
||||
})
|
||||
.then(result => app.onSubmitCallback(result))
|
||||
.finally(err => {
|
||||
setTimeout(() => app.disabled = false, 10)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取第三方支付的扩展参数
|
||||
getExtraAsUnify(method) {
|
||||
if (method === PayMethodEnum.ALIPAY.value) {
|
||||
return Alipay.extraAsUnify()
|
||||
}
|
||||
if (method === PayMethodEnum.WECHAT.value) {
|
||||
return Wechat.extraAsUnify()
|
||||
}
|
||||
return {}
|
||||
},
|
||||
|
||||
// 订单提交成功后回调
|
||||
onSubmitCallback(result) {
|
||||
const app = this
|
||||
const method = app.curPaymentItem.method
|
||||
const paymentData = result.data.payment
|
||||
// 余额支付
|
||||
if (method === PayMethodEnum.BALANCE.value) {
|
||||
app.onShowSuccess(result)
|
||||
}
|
||||
// 发起支付宝支付
|
||||
if (method === PayMethodEnum.ALIPAY.value) {
|
||||
console.log('paymentData', paymentData)
|
||||
Alipay.payment(paymentData)
|
||||
.then(res => app.onPaySuccess(res))
|
||||
.catch(err => app.onPayFail(err))
|
||||
}
|
||||
// 发起微信支付
|
||||
if (method === PayMethodEnum.WECHAT.value) {
|
||||
console.log('paymentData', paymentData)
|
||||
Wechat.payment({
|
||||
orderKey: app.orderId,
|
||||
...paymentData
|
||||
})
|
||||
.then(res => app.onPaySuccess(res))
|
||||
.catch(err => app.onPayFail(err))
|
||||
}
|
||||
},
|
||||
|
||||
// 订单支付成功的回调方法
|
||||
// 这里只是前端支付api返回结果success,实际订单是否支付成功 以后端的查单和异步通知为准
|
||||
onPaySuccess({
|
||||
res,
|
||||
option: {
|
||||
isRequireQuery,
|
||||
outTradeNo,
|
||||
method
|
||||
}
|
||||
}) {
|
||||
const app = this
|
||||
// 判断是否需要主动查单
|
||||
// isRequireQuery为true代表需要主动查单
|
||||
if (isRequireQuery) {
|
||||
app.onTradeQuery(outTradeNo, method)
|
||||
return true
|
||||
}
|
||||
this.onShowSuccess(res)
|
||||
},
|
||||
|
||||
// 显示支付成功信息并页面跳转
|
||||
onShowSuccess({
|
||||
message
|
||||
}) {
|
||||
this.$toast(message || '订单支付成功')
|
||||
this.onSuccessNav()
|
||||
},
|
||||
|
||||
// 订单支付失败
|
||||
onPayFail(err) {
|
||||
console.log('onPayFail', err)
|
||||
const errMsg = err.message || '订单未支付'
|
||||
this.$error(errMsg)
|
||||
},
|
||||
|
||||
// 已完成支付按钮事件: 请求后端查单
|
||||
onTradeQuery(outTradeNo, method) {
|
||||
const app = this
|
||||
// 交易查询
|
||||
// 查询第三方支付订单是否付款成功
|
||||
Api.tradeQuery({
|
||||
outTradeNo,
|
||||
method,
|
||||
client: app.platform
|
||||
})
|
||||
.then(result => result.data.isPay ? app.onShowSuccess(result) : app.onPayFail(result))
|
||||
.finally(() => app.showConfirmModal = false)
|
||||
},
|
||||
|
||||
// 支付成功后的跳转
|
||||
onSuccessNav() {
|
||||
const pages = getCurrentPages()
|
||||
const lastPage = pages.length < 2 ? null : pages[pages.length - 2]
|
||||
const backRoutes = [
|
||||
'package/solution/index',
|
||||
'package/solution/detail'
|
||||
]
|
||||
if (lastPage && inArray(lastPage.route, backRoutes)) {
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1000)
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
this.$navTo('package/user/goods/list', {}, 'redirectTo')
|
||||
}, 1200)
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #F4F4F4;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
background-color: #F4F4F4;
|
||||
}
|
||||
|
||||
// 订单信息
|
||||
.order-info {
|
||||
padding: 80rpx 0;
|
||||
text-align: center;
|
||||
|
||||
.order-countdown {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.order-amount {
|
||||
margin: 0 auto;
|
||||
max-width: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #111111;
|
||||
|
||||
.unit {
|
||||
font-size: 30rpx;
|
||||
margin-bottom: -18rpx;
|
||||
}
|
||||
|
||||
.amount {
|
||||
font-size: 56rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.duration-title {
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.duration-method {
|
||||
width: 94%;
|
||||
background-color: #ffffff;
|
||||
border-radius: 20rpx;
|
||||
|
||||
.pay-item {
|
||||
padding: 26rpx 0;
|
||||
font-size: 28rpx;
|
||||
border-bottom: 1rpx solid rgb(248, 248, 248);
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.item-left_icon {
|
||||
margin-right: 20rpx;
|
||||
font-size: 44rpx;
|
||||
|
||||
&.wechat {
|
||||
color: #00c800;
|
||||
}
|
||||
|
||||
&.alipay {
|
||||
color: #009fe8;
|
||||
}
|
||||
|
||||
&.balance {
|
||||
color: #ff9700;
|
||||
}
|
||||
}
|
||||
|
||||
.item-left_text {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.item-right {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.user-balance {
|
||||
margin-left: 20rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 支付方式
|
||||
.payment-method {
|
||||
width: 94%;
|
||||
background-color: #ffffff;
|
||||
border-radius: 20rpx;
|
||||
|
||||
.pay-item {
|
||||
padding: 26rpx 0;
|
||||
font-size: 28rpx;
|
||||
border-bottom: 1rpx solid rgb(248, 248, 248);
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.item-left_icon {
|
||||
margin-right: 20rpx;
|
||||
font-size: 44rpx;
|
||||
|
||||
&.wechat {
|
||||
color: #00c800;
|
||||
}
|
||||
|
||||
&.alipay {
|
||||
color: #009fe8;
|
||||
}
|
||||
|
||||
&.balance {
|
||||
color: #ff9700;
|
||||
}
|
||||
}
|
||||
|
||||
.item-left_text {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.item-right {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.user-balance {
|
||||
margin-left: 20rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 支付确认弹窗
|
||||
.modal-content {
|
||||
padding: 40rpx 48rpx;
|
||||
font-size: 30rpx;
|
||||
line-height: 50rpx;
|
||||
text-align: left;
|
||||
color: #606266;
|
||||
// height: 620rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
// 底部操作栏
|
||||
.footer-fixed {
|
||||
position: fixed;
|
||||
bottom: var(--window-bottom);
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 11;
|
||||
box-shadow: 0 -4rpx 40rpx 0 rgba(151, 151, 151, 0.24);
|
||||
background: #fff;
|
||||
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
|
||||
.btn-wrapper {
|
||||
height: 120rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 40rpx;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 80rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
|
||||
// 禁用按钮
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
159
package/user/goods/components/Comment.vue
Executable file
159
package/user/goods/components/Comment.vue
Executable file
@@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<!-- 商品评价 -->
|
||||
<view v-if="!isLoading && list.length" class="goods-comment m-top20">
|
||||
<view class="item-title dis-flex">
|
||||
<view class="block-left flex-box">
|
||||
商品评价 (<text class="total">{{ total }}条</text>)
|
||||
</view>
|
||||
<view class="block-right">
|
||||
<text @click="onTargetToComment" class="show-more col-9">查看更多</text>
|
||||
<text class="iconfont icon-arrow-right col-9"></text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 评论列表 -->
|
||||
<view class="comment-list">
|
||||
<view class="comment-item" v-for="(item, index) in list" :key="index">
|
||||
<view class="comment-item_row dis-flex flex-y-center">
|
||||
<view class="user-info dis-flex flex-y-center">
|
||||
<avatar-image class="user-avatar" :url="item.user.avatar_url" :width="50" />
|
||||
<text class="user-name">{{ item.user.nick_name }}</text>
|
||||
</view>
|
||||
<!-- 评星 -->
|
||||
<view class="star-rating">
|
||||
<u-rate active-color="#f4a213" :current="rates[item.score]" :disabled="true" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-content m-top20">
|
||||
<text class="f-26 twoline-hide">{{ item.content }}</text>
|
||||
</view>
|
||||
<view class="comment-time">{{ item.create_time }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AvatarImage from '@/components/avatar-image'
|
||||
import * as CommentApi from '@/api/comment'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AvatarImage
|
||||
},
|
||||
props: {
|
||||
// 商品ID
|
||||
goodsId: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
// 加载多少条记录 默认2条
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 2
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 正在加载
|
||||
isLoading: true,
|
||||
// 评星数据转换
|
||||
rates: { 10: 5, 20: 3, 30: 1 },
|
||||
// 评价列表数据
|
||||
list: [],
|
||||
// 评价总数量
|
||||
total: 0
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
// 加载评价列表数据
|
||||
this.getCommentList()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 加载评价列表数据
|
||||
getCommentList() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
CommentApi.listRows(app.goodsId, app.limit)
|
||||
.then(result => {
|
||||
app.list = result.data.list
|
||||
app.total = result.data.total
|
||||
})
|
||||
.catch(err => err)
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 跳转到评论列表页
|
||||
onTargetToComment() {
|
||||
const app = this
|
||||
app.$navTo('pages/comment/index', { goodsId: app.goodsId })
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.goods-comment {
|
||||
padding: 20rpx 30rpx;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
font-size: 28rpx;
|
||||
margin-bottom: 25rpx;
|
||||
|
||||
.total {
|
||||
margin: 0 4rpx;
|
||||
}
|
||||
|
||||
.show-more {
|
||||
margin-right: 8rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.comment-item {
|
||||
padding: 15rpx 5rpx;
|
||||
margin-bottom: 10rpx;
|
||||
border-bottom: 1rpx solid #f5f5f5;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.comment-item_row {
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.user-info {
|
||||
margin-right: 15rpx;
|
||||
|
||||
.user-avatar {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.item-content {
|
||||
color: #333;
|
||||
margin: 16rpx 0;
|
||||
max-height: 76rpx;
|
||||
line-height: 38rpx;
|
||||
}
|
||||
|
||||
.comment-time {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
</style>
|
||||
158
package/user/goods/components/Service.vue
Executable file
158
package/user/goods/components/Service.vue
Executable file
@@ -0,0 +1,158 @@
|
||||
<template>
|
||||
<view v-if="list.length" class="service-wrapper" :style="appThemeStyle">
|
||||
<!-- 服务简述 -->
|
||||
<view class="service-simple" @click="handlePopup">
|
||||
<view class="s-list">
|
||||
<view class="s-item" v-for="(item, index) in list" :key="index">
|
||||
<text class="item-icon iconfont icon-fuwu"></text>
|
||||
<text class="item-val">{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 扩展箭头 -->
|
||||
<view class="s-arrow f-26 col-9 t-r">
|
||||
<text class="iconfont icon-arrow-right"></text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 详情内容弹窗 -->
|
||||
<u-popup v-model="showPopup" mode="bottom" :closeable="true" :border-radius="26">
|
||||
<view class="service-content">
|
||||
<view class="title">服务</view>
|
||||
<scroll-view class="content-scroll" :scroll-y="true">
|
||||
<view class="s-list clearfix">
|
||||
<view class="s-item" v-for="(item, index) in list" :key="index">
|
||||
<text class="item-icon iconfont icon-fuwu"></text>
|
||||
<view class="item-val">{{ item.name }}</view>
|
||||
<view class="item-summary">{{ item.summary }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as ServiceApi from '@/api/goods/service'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
// 商品ID
|
||||
goodsId: {
|
||||
type: Number,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 正在加载
|
||||
isLoading: true,
|
||||
// 显示详情内容弹窗
|
||||
showPopup: false,
|
||||
// 服务列表数据
|
||||
list: []
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
// 获取商品服务列表
|
||||
this.getServiceList()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 获取商品服务列表
|
||||
getServiceList() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
ServiceApi.list(app.goodsId)
|
||||
.then(result => app.list = result.data.list)
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 显示弹窗
|
||||
handlePopup() {
|
||||
this.showPopup = !this.showPopup
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.service-wrapper {
|
||||
min-height: 24rpx;
|
||||
margin-bottom: -24rpx;
|
||||
}
|
||||
|
||||
// 服务简述
|
||||
.service-simple {
|
||||
padding: 24rpx 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.s-list {
|
||||
flex: 1;
|
||||
margin-left: -15rpx;
|
||||
}
|
||||
|
||||
.s-item {
|
||||
float: left;
|
||||
font-size: 26rpx;
|
||||
margin: 8rpx 15rpx;
|
||||
|
||||
.item-icon {
|
||||
color: $main-bg;
|
||||
}
|
||||
|
||||
.item-val {
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 服务详细内容
|
||||
.service-content {
|
||||
padding: 24rpx;
|
||||
|
||||
.title {
|
||||
font-size: 30rpx;
|
||||
margin-bottom: 50rpx;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.content-scroll {
|
||||
min-height: 400rpx;
|
||||
max-height: 760rpx;
|
||||
}
|
||||
|
||||
.s-list {
|
||||
padding: 0 30rpx 0 80rpx;
|
||||
}
|
||||
|
||||
.s-item {
|
||||
position: relative;
|
||||
margin-bottom: 60rpx;
|
||||
|
||||
.item-icon {
|
||||
position: absolute;
|
||||
top: 6rpx;
|
||||
left: -50rpx;
|
||||
color: $main-bg;
|
||||
}
|
||||
|
||||
.item-val {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.item-summary {
|
||||
font-size: 26rpx;
|
||||
margin-top: 20rpx;
|
||||
color: #6d6d6d;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
179
package/user/goods/components/SkuPopup.vue
Executable file
179
package/user/goods/components/SkuPopup.vue
Executable file
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<goods-sku-popup :value="value" @input="onChangeValue" border-radius="20" :localdata="goodsInfo" :mode="skuMode" :maskCloseAble="true"
|
||||
:priceColor="appTheme.mainBg" :buyNowBackgroundColor="appTheme.mainBg" :addCartColor="appTheme.viceText" :addCartBackgroundColor="appTheme.viceBg"
|
||||
:activedStyle="{ color: appTheme.mainBg, borderColor: appTheme.mainBg, backgroundColor: activedBtnBackgroundColor }"
|
||||
@open="openSkuPopup" @close="closeSkuPopup" @add-cart="addCart" @buy-now="buyNow" buyNowText="立即购买" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { setCartTotalNum } from '@/core/app'
|
||||
import { hex2rgba } from '@/utils/color'
|
||||
import * as CartApi from '@/api/cart'
|
||||
import GoodsSkuPopup from '@/components/goods-sku-popup'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GoodsSkuPopup
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'input'
|
||||
},
|
||||
props: {
|
||||
// true 组件显示 false 组件隐藏
|
||||
value: {
|
||||
Type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 模式 1:都显示 2:只显示购物车 3:只显示立即购买
|
||||
skuMode: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
// 商品详情信息
|
||||
goods: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
goodsInfo: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 规格按钮选中时的背景色
|
||||
activedBtnBackgroundColor() {
|
||||
return hex2rgba(this.appTheme.mainBg, 0.1)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const app = this
|
||||
const { goods } = app
|
||||
app.goodsInfo = {
|
||||
_id: goods.goods_id,
|
||||
name: goods.goods_name,
|
||||
goods_thumb: goods.goods_image,
|
||||
sku_list: app.getSkuList(),
|
||||
spec_list: app.getSpecList()
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 监听组件显示隐藏
|
||||
onChangeValue(val) {
|
||||
this.$emit('input', val)
|
||||
},
|
||||
|
||||
// 整理商品SKU列表
|
||||
getSkuList() {
|
||||
const app = this
|
||||
const { goods: { goods_name, goods_image, skuList } } = app
|
||||
const skuData = []
|
||||
skuList.forEach(item => {
|
||||
skuData.push({
|
||||
_id: item.id,
|
||||
goods_sku_id: item.goods_sku_id,
|
||||
goods_id: item.goods_id,
|
||||
goods_name: goods_name,
|
||||
image: item.image_url ? item.image_url : goods_image,
|
||||
price: item.goods_price * 100,
|
||||
stock: item.stock_num,
|
||||
spec_value_ids: item.spec_value_ids,
|
||||
sku_name_arr: app.getSkuNameArr(item.spec_value_ids)
|
||||
})
|
||||
})
|
||||
return skuData
|
||||
},
|
||||
|
||||
// 获取sku记录的规格值列表
|
||||
getSkuNameArr(specValueIds) {
|
||||
const app = this
|
||||
const defaultData = ['默认']
|
||||
const skuNameArr = []
|
||||
if (specValueIds) {
|
||||
specValueIds.forEach((valueId, groupIndex) => {
|
||||
const specValueName = app.getSpecValueName(valueId, groupIndex)
|
||||
skuNameArr.push(specValueName)
|
||||
})
|
||||
}
|
||||
return skuNameArr.length ? skuNameArr : defaultData
|
||||
},
|
||||
|
||||
// 获取指定的规格值名称
|
||||
getSpecValueName(valueId, groupIndex) {
|
||||
const app = this
|
||||
const { goods: { specList } } = app
|
||||
const res = specList[groupIndex].valueList.find(specValue => {
|
||||
return specValue.spec_value_id == valueId
|
||||
})
|
||||
return res.spec_value
|
||||
},
|
||||
|
||||
// 整理规格数据
|
||||
getSpecList() {
|
||||
const { goods: { specList } } = this
|
||||
const defaultData = [{ name: '默认', list: [{ name: '默认' }] }]
|
||||
const specData = []
|
||||
specList.forEach(group => {
|
||||
const children = []
|
||||
group.valueList.forEach(specValue => {
|
||||
children.push({ name: specValue.spec_value })
|
||||
})
|
||||
specData.push({
|
||||
name: group.spec_name,
|
||||
list: children
|
||||
})
|
||||
})
|
||||
return specData.length ? specData : defaultData
|
||||
},
|
||||
|
||||
// sku组件 开始-----------------------------------------------------------
|
||||
openSkuPopup() {
|
||||
// console.log("监听 - 打开sku组件")
|
||||
},
|
||||
|
||||
closeSkuPopup() {
|
||||
// console.log("监听 - 关闭sku组件")
|
||||
},
|
||||
|
||||
// 加入购物车按钮
|
||||
addCart(selectShop) {
|
||||
const app = this
|
||||
const { goods_id, goods_sku_id, buy_num } = selectShop
|
||||
CartApi.add(goods_id, goods_sku_id, buy_num)
|
||||
.then(result => {
|
||||
// 显示成功
|
||||
app.$toast(result.message)
|
||||
// 隐藏当前弹窗
|
||||
app.onChangeValue(false)
|
||||
// 购物车商品总数量
|
||||
const cartTotal = result.data.cartTotal
|
||||
// 缓存购物车数量
|
||||
setCartTotalNum(cartTotal)
|
||||
// 传递给父级
|
||||
app.$emit('addCart', cartTotal)
|
||||
})
|
||||
},
|
||||
|
||||
// 立即购买
|
||||
buyNow(selectShop) {
|
||||
// 跳转到订单结算页
|
||||
this.$navTo('pages/checkout/index', {
|
||||
mode: 'buyNow',
|
||||
goodsId: selectShop.goods_id,
|
||||
goodsSkuId: selectShop.goods_sku_id,
|
||||
goodsNum: selectShop.buy_num
|
||||
})
|
||||
// 隐藏当前弹窗
|
||||
this.onChangeValue(false)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
146
package/user/goods/components/SlideImage.vue
Executable file
146
package/user/goods/components/SlideImage.vue
Executable file
@@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<!-- 商品图片 -->
|
||||
<view class="images-swiper">
|
||||
<swiper class="swiper-box" :autoplay="autoplay" :duration="duration" :indicator-dots="indicatorDots"
|
||||
:interval="interval" :circular="true" @change="setCurrent">
|
||||
<!-- 主图视频 -->
|
||||
<swiper-item v-if="video">
|
||||
<view class="slide-video">
|
||||
<video id="myVideo" class="video" :poster="videoCover.preview_url" :src="video.external_url" controls
|
||||
x5-playsinline playsinline webkit-playsinline webkit-playsinline x5-video-player-type="h5"
|
||||
x5-video-player-fullscreen x5-video-orientation="portrait" :enable-progress-gesture="false"
|
||||
@play="onVideoPlay"></video>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<!-- 轮播图片 -->
|
||||
<swiper-item v-for="(item, index) in images" :key="index" @click="onPreviewImages(index)">
|
||||
<view class="slide-image">
|
||||
<image class="image" :draggable="false" :src="item.preview_url"></image>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<view class="swiper-count">
|
||||
<text>{{ currentIndex }}</text>
|
||||
<text>/</text>
|
||||
<text>{{ images.length + (video ? 1 : 0) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
// 主图视频
|
||||
video: {
|
||||
type: Object,
|
||||
default () {
|
||||
return null
|
||||
}
|
||||
},
|
||||
// 主图视频封面
|
||||
videoCover: {
|
||||
type: Object,
|
||||
default () {
|
||||
return null
|
||||
}
|
||||
},
|
||||
// 图片轮播
|
||||
images: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
indicatorDots: true, // 是否显示面板指示点
|
||||
autoplay: true, // 是否自动切换
|
||||
interval: 4000, // 自动切换时间间隔
|
||||
duration: 800, // 滑动动画时长
|
||||
currentIndex: 1, // 轮播图指针
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 事件:视频开始播放
|
||||
onVideoPlay(e) {
|
||||
this.autoplay = false
|
||||
},
|
||||
|
||||
// 设置轮播图当前指针 数字
|
||||
setCurrent({ detail }) {
|
||||
const app = this
|
||||
app.currentIndex = detail.current + 1
|
||||
},
|
||||
|
||||
// 浏览商品图片
|
||||
onPreviewImages(index) {
|
||||
const app = this
|
||||
const imageUrls = []
|
||||
app.images.forEach(item => {
|
||||
imageUrls.push(item.preview_url);
|
||||
});
|
||||
uni.previewImage({
|
||||
current: imageUrls[index],
|
||||
urls: imageUrls
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// swiper组件
|
||||
.images-swiper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.swiper-box {
|
||||
width: 100%;
|
||||
height: 100vw;
|
||||
|
||||
/* #ifdef H5 */
|
||||
max-width: 480px;
|
||||
max-height: 480px;
|
||||
margin: 0 auto;
|
||||
/* #endif */
|
||||
|
||||
// 主图视频
|
||||
.slide-video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.video {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
// 图片轮播
|
||||
.slide-image {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// swiper计数
|
||||
.swiper-count {
|
||||
position: absolute;
|
||||
right: 36rpx;
|
||||
bottom: 72rpx;
|
||||
padding: 2rpx 18rpx;
|
||||
background: rgba(0, 0, 0, 0.363);
|
||||
border-radius: 50rpx;
|
||||
color: #fff;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
</style>
|
||||
69
package/user/goods/components/search.vue
Executable file
69
package/user/goods/components/search.vue
Executable file
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<!-- 搜索框 -->
|
||||
<view class="search-wrapper">
|
||||
<view class="index-search" @click="onClick">
|
||||
<view class="index-cont-search t-c">
|
||||
<text class="search-icon iconfont icon-search"></text>
|
||||
<text class="search-text">{{ tips }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
tips: {
|
||||
type: String,
|
||||
default: '搜索商品'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onClick() {
|
||||
this.$emit('event')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search-wrapper {
|
||||
background: #fff;
|
||||
padding: 13rpx;
|
||||
}
|
||||
|
||||
.index-search {
|
||||
border-bottom: 0;
|
||||
background: #fff;
|
||||
border-radius: 50rpx;
|
||||
overflow: hidden;
|
||||
font-size: 28rpx;
|
||||
color: #6d6d6d;
|
||||
box-sizing: border-box;
|
||||
line-height: 64rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.index-cont-search {
|
||||
width: 100%;
|
||||
font-size: 28rpx;
|
||||
background: #f7f7f7;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.index-cont-search .search-icon {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.index-cont-search .search-text {
|
||||
margin-left: 14rpx;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
228
package/user/goods/detail.scss
Executable file
228
package/user/goods/detail.scss
Executable file
@@ -0,0 +1,228 @@
|
||||
.container {
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
// 110 - 18 + 4
|
||||
padding-bottom: calc(constant(safe-area-inset-bottom) + 106rpx + 6rpx);
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 106rpx + 6rpx);
|
||||
}
|
||||
|
||||
// 商品信息
|
||||
.goods-info {
|
||||
background: #fff;
|
||||
padding: 25rpx 30rpx;
|
||||
}
|
||||
|
||||
.info-item__top {
|
||||
min-height: 40rpx;
|
||||
margin-bottom: 20rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.floor-price__samll {
|
||||
font-size: 26rpx;
|
||||
line-height: 1;
|
||||
color: #ff0000;
|
||||
margin-bottom: -10rpx;
|
||||
}
|
||||
|
||||
// 商品价
|
||||
.floor-price {
|
||||
color: #ff0000;
|
||||
margin-right: 15rpx;
|
||||
font-size: 42rpx;
|
||||
}
|
||||
|
||||
.original-price {
|
||||
font-size: 26rpx;
|
||||
text-decoration: line-through;
|
||||
color: #959595;
|
||||
margin-right: 15rpx;
|
||||
margin-bottom: -6rpx;
|
||||
}
|
||||
|
||||
// 会员价标签
|
||||
.user-grade {
|
||||
background: #3c3c3c;
|
||||
border-radius: 6rpx;
|
||||
padding: 8rpx 14rpx;
|
||||
margin-right: 15rpx;
|
||||
font-size: 24rpx;
|
||||
color: #EEE0C3;
|
||||
}
|
||||
|
||||
.goods-sales {
|
||||
font-size: 24rpx;
|
||||
color: #959595;
|
||||
}
|
||||
|
||||
.info-item__name .goods-name {
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
/* 商品分享 */
|
||||
|
||||
.goods-share__line {
|
||||
border-left: 1rpx solid #f4f4f4;
|
||||
height: 60rpx;
|
||||
margin: 0 30rpx;
|
||||
}
|
||||
|
||||
.goods-share .share-btn {
|
||||
line-height: normal;
|
||||
padding: 0;
|
||||
background: none;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
font-size: 8pt;
|
||||
border: none;
|
||||
color: #191919;
|
||||
}
|
||||
|
||||
.goods-share .share-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.goods-share .share__icon {
|
||||
font-size: 40rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
|
||||
// 商品卖点
|
||||
.info-item_selling-point {
|
||||
margin-top: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
// 选择商品规格
|
||||
.goods-choice {
|
||||
padding: 26rpx 30rpx;
|
||||
font-size: 28rpx;
|
||||
|
||||
.spec-list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.spec-name {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 商品详情
|
||||
.goods-content .item-title {
|
||||
padding: 26rpx 30rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
// 底部操作栏
|
||||
.footer-fixed {
|
||||
position: fixed;
|
||||
bottom: var(--window-bottom);
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
z-index: 11;
|
||||
box-shadow: 0 -4rpx 40rpx 0 rgba(151, 151, 151, 0.24);
|
||||
background: #fff;
|
||||
|
||||
// 设置ios刘海屏底部横线安全区域
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
.footer-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
height: 106rpx;
|
||||
}
|
||||
|
||||
// 快捷菜单
|
||||
.foo-item-fast {
|
||||
box-sizing: border-box;
|
||||
min-width: 214rpx;
|
||||
line-height: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
margin-right: 12rpx;
|
||||
|
||||
.fast-item {
|
||||
position: relative;
|
||||
padding: 4rpx 0;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
width: 84rpx;
|
||||
|
||||
&--cart {
|
||||
margin-left: 6rpx;
|
||||
.fast-icon { margin-left: -12rpx; }
|
||||
}
|
||||
|
||||
// 角标
|
||||
.fast-badge {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
min-width: 16px;
|
||||
padding: 0 3px;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
font-size: 12px;
|
||||
font-family: -apple-system-font, Helvetica Neue, Arial, sans-serif;
|
||||
line-height: 1.2;
|
||||
text-align: center;
|
||||
background-color: #ee0a24;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.fast-badge--fixed {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
transform-origin: 100%
|
||||
}
|
||||
|
||||
.fast-icon {
|
||||
font-size: 44rpx;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.fast-text {
|
||||
font-size: 22rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 操作按钮
|
||||
.foo-item-btn {
|
||||
flex: 1;
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn-item {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
height: 72rpx;
|
||||
margin-right: 16rpx;
|
||||
color: #fff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
// 立即购买按钮
|
||||
.btn-item-main {
|
||||
background: linear-gradient(to right, $main-bg, $main-bg2);
|
||||
}
|
||||
|
||||
// 购物车按钮
|
||||
.btn-item-deputy {
|
||||
background: linear-gradient(to right, $vice-bg, $vice-bg2);
|
||||
color: $vice-text;
|
||||
}
|
||||
}
|
||||
347
package/user/goods/detail.vue
Executable file
347
package/user/goods/detail.vue
Executable file
@@ -0,0 +1,347 @@
|
||||
<template>
|
||||
<view v-show="!isLoading" class="container" :style="appThemeStyle">
|
||||
<!-- 商品图片轮播 -->
|
||||
<SlideImage v-if="!isLoading" :video="goods.video" :videoCover="goods.videoCover" :images="goods.goods_images" />
|
||||
|
||||
<!-- 商品信息 -->
|
||||
<view v-if="!isLoading" class="goods-info m-top20">
|
||||
<!-- 价格、销量 -->
|
||||
<view class="info-item info-item__top dis-flex flex-x-between flex-y-end">
|
||||
<view class="block-left dis-flex flex-y-center">
|
||||
<!-- 商品售价 -->
|
||||
<text class="floor-price__samll">¥</text>
|
||||
<text class="floor-price">{{ goods.goods_price_min }}</text>
|
||||
<!-- 会员价标签 -->
|
||||
<view v-if="goods.is_user_grade" class="user-grade">
|
||||
<text>会员价</text>
|
||||
</view>
|
||||
<!-- 划线价 -->
|
||||
<text v-if="goods.line_price_min > 0" class="original-price">¥{{ goods.line_price_min }}</text>
|
||||
</view>
|
||||
<view class="block-right dis-flex">
|
||||
<!-- 销量 -->
|
||||
<view class="goods-sales">
|
||||
<text>已售{{ goods.goods_sales }}件</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 标题、分享 -->
|
||||
<view class="info-item info-item__name dis-flex flex-y-center">
|
||||
<view class="goods-name flex-box">
|
||||
<text class="twoline-hide">{{ goods.goods_name }}</text>
|
||||
</view>
|
||||
<view class="goods-share__line"></view>
|
||||
<view class="goods-share">
|
||||
<button class="share-btn dis-flex flex-dir-column" @click="onShowShareSheet()">
|
||||
<text class="share__icon iconfont icon-fenxiang"></text>
|
||||
<text class="f-24">分享</text>
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 商品卖点 -->
|
||||
<view v-if="goods.selling_point" class="info-item info-item_selling-point">
|
||||
<text>{{ goods.selling_point }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 选择商品规格 -->
|
||||
<view v-if="goods.spec_type == 20" class="goods-choice m-top20 b-f" @click="onShowSkuPopup(1)">
|
||||
<view class="spec-list">
|
||||
<view class="flex-box">
|
||||
<text class="col-8">选择:</text>
|
||||
<text class="spec-name" v-for="(item, index) in goods.specList" :key="index">{{ item.spec_name }}</text>
|
||||
</view>
|
||||
<view class="f-26 col-9 t-r">
|
||||
<text class="iconfont icon-arrow-right"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品服务 -->
|
||||
<Service v-if="!isLoading" :goods-id="goodsId" />
|
||||
|
||||
<!-- 商品SKU弹窗 -->
|
||||
<SkuPopup v-if="!isLoading" v-model="showSkuPopup" :skuMode="skuMode" :goods="goods" @addCart="onAddCart" />
|
||||
|
||||
<!-- 商品评价 -->
|
||||
<Comment v-if="!isLoading" :goods-id="goodsId" :limit="2" />
|
||||
|
||||
<!-- 商品描述 -->
|
||||
<view v-if="!isLoading" class="goods-content m-top20">
|
||||
<view class="item-title b-f">
|
||||
<text>商品描述</text>
|
||||
</view>
|
||||
<block v-if="goods.content != ''">
|
||||
<view class="goods-content__detail b-f">
|
||||
<mp-html :content="goods.content" />
|
||||
</view>
|
||||
</block>
|
||||
<empty v-else tips="亲,暂无商品描述" />
|
||||
</view>
|
||||
|
||||
<!-- 商品推荐 -->
|
||||
<recommended />
|
||||
|
||||
<!-- 底部选项卡 -->
|
||||
<view class="footer-fixed">
|
||||
<view class="footer-container">
|
||||
<!-- 导航图标 -->
|
||||
<view class="foo-item-fast">
|
||||
<!-- 首页 -->
|
||||
<view class="fast-item fast-item--home" @click="onTargetHome">
|
||||
<view class="fast-icon">
|
||||
<text class="iconfont icon-shouye"></text>
|
||||
</view>
|
||||
<view class="fast-text">
|
||||
<text>站点</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<button class="btn-normal" @click="onCollection(goods.goods_id)">
|
||||
<view class="fast-item">
|
||||
<view class="fast-icon">
|
||||
<u-icon name="star-fill" color="#fd8008" v-if="goods.is_collection"></u-icon>
|
||||
<u-icon name="star" v-else></u-icon>
|
||||
</view>
|
||||
<view class="fast-text">
|
||||
<text>收藏</text>
|
||||
</view>
|
||||
</view>
|
||||
</button>
|
||||
<!-- #endif -->
|
||||
<!-- 客服 (仅微信小程序端显示) -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<!-- <button class="btn-normal" open-type="contact">
|
||||
<view class="fast-item">
|
||||
<view class="fast-icon">
|
||||
<text class="iconfont icon-kefu1"></text>
|
||||
</view>
|
||||
<view class="fast-text">
|
||||
<text>客服</text>
|
||||
</view>
|
||||
</view>
|
||||
</button> -->
|
||||
<!-- #endif -->
|
||||
<!-- 购物车 -->
|
||||
<view class="fast-item fast-item--cart" @click="onTargetCart">
|
||||
<view v-if="cartTotal > 0" class="fast-badge fast-badge--fixed">{{ cartTotal > 99 ? '99+' : cartTotal }}
|
||||
</view>
|
||||
<view class="fast-icon">
|
||||
<text class="iconfont icon-gouwuche"></text>
|
||||
</view>
|
||||
<view class="fast-text">
|
||||
<text>购物车</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<view class="foo-item-btn">
|
||||
<view class="btn-wrapper">
|
||||
<view class="btn-item btn-item-deputy" @click="onShowSkuPopup(2)">
|
||||
<text>加入购物车</text>
|
||||
</view>
|
||||
<view class="btn-item btn-item-main" @click="onShowSkuPopup(3)">
|
||||
<text>立即购买</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 快捷导航 -->
|
||||
<!-- <shortcut bottom="120rpx" /> -->
|
||||
|
||||
<!-- 分享菜单 -->
|
||||
<share-sheet v-model="showShareSheet" :shareTitle="goods.goods_name" :shareImageUrl="goods.goods_image"
|
||||
:posterApiCall="posterApiCall" :posterApiParam="{ goodsId }" />
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getSceneData } from '@/core/app'
|
||||
import * as GoodsApi from '@/api/goods'
|
||||
import * as CartApi from '@/api/cart'
|
||||
import Recommended from '@/components/recommended'
|
||||
import ShareSheet from '@/components/share-sheet'
|
||||
import SlideImage from './components/SlideImage'
|
||||
import SkuPopup from './components/SkuPopup'
|
||||
import Comment from './components/Comment'
|
||||
import Service from './components/Service'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Recommended,
|
||||
ShareSheet,
|
||||
SlideImage,
|
||||
SkuPopup,
|
||||
Comment,
|
||||
Service
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 正在加载
|
||||
isLoading: true,
|
||||
// 当前商品ID
|
||||
goodsId: null,
|
||||
// 商品详情
|
||||
goods: {},
|
||||
// 购物车总数量
|
||||
cartTotal: 0,
|
||||
// 显示/隐藏SKU弹窗
|
||||
showSkuPopup: false,
|
||||
// 模式 1:都显示 2:只显示购物车 3:只显示立即购买
|
||||
skuMode: 1,
|
||||
// 显示/隐藏分享菜单
|
||||
showShareSheet: false,
|
||||
// 获取商品海报图api方法
|
||||
posterApiCall: GoodsApi.poster
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
// 记录query参数
|
||||
this.onRecordQuery(options)
|
||||
// 加载页面数据
|
||||
this.onRefreshPage()
|
||||
// 浏览历史
|
||||
this.saveFootMarkList(options.goodsId)
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 浏览历史记录
|
||||
saveFootMarkList(goodsId){
|
||||
const userId = uni.getStorageSync('userId')
|
||||
const arr = uni.getStorageSync(`FOOTMARKLIST_${userId}`) || []
|
||||
arr.unshift(Number(goodsId))
|
||||
return uni.setStorageSync(`FOOTMARKLIST_${userId}`,arr)
|
||||
},
|
||||
// 记录query参数
|
||||
onRecordQuery(query) {
|
||||
const scene = getSceneData(query)
|
||||
this.goodsId = query.goodsId ? parseInt(query.goodsId) : parseInt(scene.gid)
|
||||
},
|
||||
|
||||
// 刷新页面数据
|
||||
onRefreshPage() {
|
||||
const app = this
|
||||
app.isLoading = true
|
||||
Promise.all([app.getGoodsDetail(), app.getCartTotal()])
|
||||
.finally(() => app.isLoading = false)
|
||||
},
|
||||
|
||||
// 获取商品信息
|
||||
getGoodsDetail() {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
GoodsApi.detail(app.goodsId)
|
||||
.then(result => {
|
||||
app.goods = result.data.detail
|
||||
resolve(result)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取购物车总数量
|
||||
getCartTotal() {
|
||||
const app = this
|
||||
return new Promise((resolve, reject) => {
|
||||
CartApi.total()
|
||||
.then(result => {
|
||||
app.cartTotal = result.data.cartTotal
|
||||
resolve(result)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 更新购物车数量
|
||||
onAddCart(total) {
|
||||
this.cartTotal = total
|
||||
},
|
||||
|
||||
/**
|
||||
* 显示/隐藏SKU弹窗
|
||||
* @param {skuMode} 模式 1:都显示 2:只显示购物车 3:只显示立即购买
|
||||
*/
|
||||
onShowSkuPopup(skuMode = 1) {
|
||||
const shopInfo = uni.getStorageSync('shopInfo')
|
||||
const clerkInfo = uni.getStorageSync('clerkInfo')
|
||||
if(shopInfo || clerkInfo){
|
||||
return this.$error('请使用会员账号购买')
|
||||
}
|
||||
this.skuMode = skuMode
|
||||
this.showSkuPopup = !this.showSkuPopup
|
||||
},
|
||||
|
||||
// 显示隐藏分享菜单
|
||||
onShowShareSheet() {
|
||||
this.showShareSheet = !this.showShareSheet
|
||||
},
|
||||
|
||||
// 跳转到首页
|
||||
onTargetHome(e) {
|
||||
const { goods } = this
|
||||
console.log("this.goods: ",goods);
|
||||
this.$navTo('package/shops/detail/index',goods)
|
||||
},
|
||||
|
||||
// 加入收藏
|
||||
onCollection(goodsId){
|
||||
GoodsApi.collection({goodsId})
|
||||
this.goods.is_collection = !this.goods.is_collection
|
||||
},
|
||||
|
||||
// 跳转到购物车页
|
||||
onTargetCart() {
|
||||
this.$navTo('pages/cart/index')
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享当前页面
|
||||
*/
|
||||
onShareAppMessage() {
|
||||
const app = this
|
||||
// 构建页面参数
|
||||
const params = app.$getShareUrlParams({
|
||||
goodsId: app.goodsId,
|
||||
})
|
||||
return {
|
||||
title: app.goods.goods_name,
|
||||
path: `/pages/goods/detail?${params}`
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享到朋友圈
|
||||
* 本接口为 Beta 版本,暂只在 Android 平台支持,详见分享到朋友圈 (Beta)
|
||||
* https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html
|
||||
*/
|
||||
onShareTimeline() {
|
||||
const app = this
|
||||
// 构建页面参数
|
||||
const params = app.$getShareUrlParams({
|
||||
goodsId: app.goodsId,
|
||||
})
|
||||
return {
|
||||
title: app.goods.goods_name,
|
||||
path: `/pages/goods/detail?${params}`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
@import "./detail.scss";
|
||||
</style>
|
||||
659
package/user/goods/list.vue
Executable file
659
package/user/goods/list.vue
Executable file
@@ -0,0 +1,659 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ native: true }"
|
||||
@down="downCallback" :up="upOption" @up="upCallback">
|
||||
<!-- 页面头部 -->
|
||||
<view class="header">
|
||||
<view class="search">
|
||||
<input v-model="searchValue" class="input" focus="true" placeholder="请输入您搜索的商品" type="text" @input="onInput" @confirm="onSearch"></input>
|
||||
</view>
|
||||
<u-dropdown>
|
||||
<u-dropdown-item v-model="parentId" :title="parentName" :options="parentList"></u-dropdown-item>
|
||||
<u-dropdown-item v-if="childrenList.length > 0" v-model="categoryId" :title="categoryName" :options="childrenList"></u-dropdown-item>
|
||||
<u-dropdown-item v-if="thirdList.length > 0" v-model="thirdId" :title="thirdName" :options="thirdList"></u-dropdown-item>
|
||||
</u-dropdown>
|
||||
</view>
|
||||
<!-- {{parentId}}
|
||||
{{categoryId}}
|
||||
{{thirdId}}
|
||||
{{JSON.stringify(childrenList)}}
|
||||
{{JSON.stringify(thirdList)}} -->
|
||||
<!-- 排序标签 -->
|
||||
<!-- <view class="store-sort">
|
||||
<view class="sort-item" :class="{ active: sortType === 'all' }" @click="handleSortType('all')">
|
||||
<text>综合</text>
|
||||
</view>
|
||||
<view class="sort-item" :class="{ active: sortType === 'sales' }" @click="handleSortType('sales')">
|
||||
<text>销量</text>
|
||||
</view>
|
||||
<view class="sort-item sort-item-price" :class="{ active: sortType === 'price' }" @click="handleSortType('price')">
|
||||
<text>价格</text>
|
||||
<view class="price-arrow">
|
||||
<view class="icon up" :class="{ active: sortType === 'price' && !sortPrice }">
|
||||
<text class="iconfont icon-arrow-up"></text>
|
||||
</view>
|
||||
<view class="icon down" :class="{ active: sortType === 'price' && sortPrice }">
|
||||
<text class="iconfont icon-arrow-down"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view> -->
|
||||
<!-- 商品列表 -->
|
||||
<view class="goods-list clearfix" :class="['column-' + (showView ? '1' : '2')]">
|
||||
<view class="goods-item" v-for="(item, index) in list.data" :key="index">
|
||||
<!-- 单列显示 -->
|
||||
<view v-if="showView" class="dis-flex">
|
||||
<!-- 商品图片 -->
|
||||
<view class="goods-item_left" @click="onTargetDetail(item.goods_id)">
|
||||
<image class="image" :src="item.goods_image"></image>
|
||||
</view>
|
||||
<view class="goods-item_right">
|
||||
<!-- 商品名称 -->
|
||||
<view class="goods-name">
|
||||
<text class="twoline-hide" @click="onTargetDetail(item.goods_id)">{{ item.goods_name }}</text>
|
||||
</view>
|
||||
<view class="goods-item_desc">
|
||||
<!-- 商品卖点 -->
|
||||
<view class="desc-selling_point dis-flex">
|
||||
<text class="oneline-hide">{{ item.selling_point }}</text>
|
||||
</view>
|
||||
<!-- 商品销量 -->
|
||||
<view class="desc-goods_sales dis-flex">
|
||||
<text>已售{{ item.goods_sales }}件</text>
|
||||
</view>
|
||||
<!-- 商品价格 -->
|
||||
<view class="desc_footer">
|
||||
<text class="price_x">¥{{ item.goods_price_min }}</text>
|
||||
<text class="price_y col-9"
|
||||
v-if="item.line_price_min > 0">¥{{ item.line_price_min }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="buy-gouwuche" v-if="item.top_time == 0">
|
||||
<u-checkbox v-model="item.checked" @change="checkboxChange(item.goods_id)">置顶</u-checkbox>
|
||||
<!-- <u-button size="mini">置顶</u-button> -->
|
||||
</view>
|
||||
<view class="buy-gouwuche" v-else>
|
||||
<u-tag text="投放中"></u-tag>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 多列显示 -->
|
||||
<view v-else class="">
|
||||
<!-- 商品图片 -->
|
||||
<view class="goods-image">
|
||||
<image class="image" mode="aspectFill" :src="item.goods_image"></image>
|
||||
</view>
|
||||
<view class="detail">
|
||||
<!-- 商品名称 -->
|
||||
<view class="goods-name">
|
||||
<text class="twoline-hide">{{ item.goods_name }}</text>
|
||||
</view>
|
||||
<!-- 商品价格 -->
|
||||
<view class="detail-price oneline-hide">
|
||||
<text class="goods-price f-30 col-m">¥{{ item.goods_price_min }}</text>
|
||||
<text v-if="item.line_price_min > 0"
|
||||
class="line-price col-9 f-24">¥{{ item.line_price_min }}</text>
|
||||
</view>
|
||||
<!-- 商品销量 -->
|
||||
<text class="col-9 f-24 u-text-right">已售{{ item.goods_sales }}件</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="gotobuy">
|
||||
<u-button v-if="checked.length > 0" type="primary" @click="goToBuy">去付款</u-button>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import * as GoodsApi from '@/api/goods'
|
||||
import * as CategoryApi from '@/api/category'
|
||||
import {
|
||||
getEmptyPaginateObj,
|
||||
getMoreListData
|
||||
} from '@/core/app'
|
||||
import Search from './components/search.vue'
|
||||
import storage from '@/utils/storage'
|
||||
|
||||
const pageSize = 15
|
||||
const showViewKey = 'GoodsList-ShowView';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody,
|
||||
Search
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
data() {
|
||||
return {
|
||||
showView: true, // 列表显示方式 (true列表、false平铺)
|
||||
sortType: 'all', // 排序类型
|
||||
sortPrice: false, // 价格排序 (true高到低 false低到高)
|
||||
options: {}, // 当前页面参数
|
||||
list: getEmptyPaginateObj(), // 商品列表数据
|
||||
searchValue: '',
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: {
|
||||
size: pageSize
|
||||
},
|
||||
// 数量要大于4条才显示无更多数据
|
||||
noMoreSize: 4,
|
||||
},
|
||||
parentId: 0,
|
||||
parentName: '商品分类',
|
||||
categoryId: 0,
|
||||
categoryName: '请选择',
|
||||
category: [],
|
||||
parentList: [],
|
||||
childrenList: [],
|
||||
// 三级分类
|
||||
thirdId: 0,
|
||||
thirdName: '请选择',
|
||||
thirdList: [],
|
||||
checked: [],
|
||||
time: ''
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
// 记录options
|
||||
this.options = options
|
||||
// 设置默认列表显示方式
|
||||
this.setShowView()
|
||||
// 加载商品分类
|
||||
this.getCategory()
|
||||
// 检查商品支付状态并设置置顶时间
|
||||
// this.time = this.$u.timeFrom(1665049088);
|
||||
// console.log("this.time: ",this.time);
|
||||
|
||||
},
|
||||
|
||||
watch: {
|
||||
parentId(val) {
|
||||
// 设置一级分类名称
|
||||
this.parentList.map(d => {
|
||||
if(d.value == val){
|
||||
this.parentName = d.label
|
||||
this.parentId = d.value
|
||||
this.categoryId = 0
|
||||
this.categoryName = '请选择'
|
||||
this.thirdId = 0
|
||||
d.children && this.getChildrenList(d.value)
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
categoryId(val){
|
||||
this.childrenList.map(d => {
|
||||
if(d.value == val){
|
||||
this.categoryName = d.label
|
||||
this.categoryId = d.value
|
||||
this.thirdId = 0
|
||||
d.children && this.getThirdList(d.value)
|
||||
}
|
||||
})
|
||||
this.getGoodsList()
|
||||
},
|
||||
thirdId(val){
|
||||
this.thirdList.map(d => {
|
||||
if(d.value == val){
|
||||
this.thirdName = d.label
|
||||
this.thirdId = d.value
|
||||
}
|
||||
})
|
||||
this.getGoodsList()
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
app.getGoodsList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
// 选择一级分类后刷新左侧菜单
|
||||
getChildrenList(parentId){
|
||||
const app = this
|
||||
app.parentId = parentId
|
||||
app.category.map(d => {
|
||||
if(d.category_id == parentId){
|
||||
app.childrenList = d.children.map(item => {
|
||||
return {
|
||||
value: item.category_id,
|
||||
label: item.name,
|
||||
children: item.children
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// 三级分类
|
||||
getThirdList(categoryId){
|
||||
const app = this
|
||||
app.categoryId = categoryId
|
||||
app.childrenList.map(d => {
|
||||
console.log(categoryId + "====",d.value);
|
||||
if(d.value == categoryId){
|
||||
app.thirdList = d.children.map(d => {
|
||||
return {
|
||||
value: d.category_id,
|
||||
label: d.name,
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 设置默认列表显示方式
|
||||
setShowView() {
|
||||
this.showView = uni.getStorageSync(showViewKey) || true
|
||||
},
|
||||
|
||||
onInput(e){
|
||||
this.searchValue = e.detail.value
|
||||
this.options.search = e.detail.value
|
||||
},
|
||||
|
||||
onSearch(){
|
||||
this.getGoodsList()
|
||||
},
|
||||
// 收集选中的goodsId
|
||||
checkboxChange(goodsId){
|
||||
const app = this
|
||||
// 查找数组是否含该元素并返回下标位置
|
||||
var index = app.checked.indexOf(goodsId)
|
||||
// 存在则删除不存在则插入
|
||||
if( index > -1){
|
||||
app.checked.splice(index,1)
|
||||
}else{
|
||||
app.checked.push(goodsId)
|
||||
}
|
||||
storage.set('selectGoodsIdsByPopularize', app.checked)
|
||||
},
|
||||
goToBuy(){
|
||||
this.$navTo('package/user/goods/cashier')
|
||||
},
|
||||
|
||||
getCategory(){
|
||||
CategoryApi.list().then(result => {
|
||||
this.category = result.data.list
|
||||
// 抽取一级分类
|
||||
this.parentList = result.data.list.map(d => {
|
||||
if(d.parent_id == 0){
|
||||
return {
|
||||
value: d.category_id,
|
||||
label: d.name,
|
||||
children: d.children
|
||||
}
|
||||
}
|
||||
})
|
||||
// console.log('顶部一级分类:',this.parentList);
|
||||
// 左侧二级分类
|
||||
// result.data.list.map(d => {
|
||||
// if(d.category_id == this.parentId){
|
||||
// this.childrenList = d.children
|
||||
// }
|
||||
// })
|
||||
// console.log(": ",this.childrenList);
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取商品列表
|
||||
* @param {number} pageNo 页码
|
||||
*/
|
||||
getGoodsList(pageNo = 1) {
|
||||
const app = this
|
||||
const { thirdId, categoryId, parentId } = this
|
||||
const { shopId } = uni.getStorageSync('shopInfo')
|
||||
let lastId = 0;
|
||||
if(parentId > 0) {
|
||||
lastId = parentId
|
||||
}
|
||||
if(categoryId > 0) {
|
||||
lastId = categoryId
|
||||
}
|
||||
if(thirdId > 0){
|
||||
lastId = thirdId
|
||||
}
|
||||
const param = {
|
||||
sortType: app.sortType,
|
||||
sortPrice: Number(app.sortPrice),
|
||||
categoryId: lastId || 0,
|
||||
goodsName: app.options.search || '',
|
||||
page: pageNo,
|
||||
shopId,
|
||||
// storeHouseGoods: true,
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
GoodsApi.list(param)
|
||||
.then(result => {
|
||||
// 合并新数据
|
||||
const newList = result.data.list
|
||||
app.list.data = getMoreListData(newList, app.list, pageNo)
|
||||
resolve(newList)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 切换排序方式
|
||||
handleSortType(newSortType) {
|
||||
const app = this
|
||||
const newSortPrice = newSortType === 'price' ? !app.sortPrice : true
|
||||
app.sortType = newSortType
|
||||
app.sortPrice = newSortPrice
|
||||
// 刷新列表数据
|
||||
app.list = getEmptyPaginateObj()
|
||||
app.mescroll.resetUpScroll()
|
||||
},
|
||||
|
||||
// 切换列表显示方式
|
||||
handleShowView() {
|
||||
const app = this
|
||||
app.showView = !app.showView
|
||||
uni.setStorageSync(showViewKey, app.showView)
|
||||
},
|
||||
|
||||
// 跳转商品详情页
|
||||
onTargetDetail(goodsId) {
|
||||
this.$navTo('pages/goods/detail', {
|
||||
goodsId
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 商品搜索
|
||||
*/
|
||||
handleSearch() {
|
||||
const searchPageUrl = 'pages/search/index'
|
||||
// 判断来源页面
|
||||
let pages = getCurrentPages()
|
||||
if (pages.length > 1 &&
|
||||
pages[pages.length - 2].route === searchPageUrl) {
|
||||
uni.navigateBack()
|
||||
return
|
||||
}
|
||||
// 跳转到商品搜索页
|
||||
this.$navTo(searchPageUrl)
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 设置分享内容
|
||||
*/
|
||||
onShareAppMessage() {
|
||||
// 构建分享参数
|
||||
return {
|
||||
title: "全部分类",
|
||||
path: "/pages/category/index?" + this.$getShareUrlParams()
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享到朋友圈
|
||||
* 本接口为 Beta 版本,暂只在 Android 平台支持,详见分享到朋友圈 (Beta)
|
||||
* https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html
|
||||
*/
|
||||
onShareTimeline() {
|
||||
// 构建分享参数
|
||||
return {
|
||||
title: "全部分类",
|
||||
path: "/pages/category/index?" + this.$getShareUrlParams()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 页面头部
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
flex: 1;
|
||||
// 搜索框
|
||||
.search {
|
||||
flex: 1;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
// 切换显示方式
|
||||
.show-view {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
font-size: 36rpx;
|
||||
color: #505050;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
// 排序组件
|
||||
.store-sort {
|
||||
position: sticky;
|
||||
top: var(--window-top);
|
||||
display: flex;
|
||||
padding: 20rpx 0;
|
||||
font-size: 28rpx;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
z-index: 99;
|
||||
|
||||
.sort-item {
|
||||
flex-basis: 33.3333%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 50rpx;
|
||||
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
}
|
||||
}
|
||||
|
||||
.sort-item-price .price-arrow {
|
||||
margin-left: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #000;
|
||||
|
||||
.icon {
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
}
|
||||
|
||||
&.up {
|
||||
margin-bottom: -16rpx;
|
||||
}
|
||||
|
||||
&.down {
|
||||
margin-top: -16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 商品列表
|
||||
.goods-list {
|
||||
padding: 4rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// 单列显示
|
||||
.goods-list.column-1 {
|
||||
.goods-item {
|
||||
width: 100%;
|
||||
height: 280rpx;
|
||||
margin-bottom: 12rpx;
|
||||
padding: 20rpx;
|
||||
box-sizing: border-box;
|
||||
background: #fff;
|
||||
line-height: 1.6;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_left {
|
||||
display: flex;
|
||||
width: 300rpx;
|
||||
background: #fff;
|
||||
align-items: center;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 240rpx;
|
||||
height: 240rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_right {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
|
||||
.goods-name {
|
||||
margin-top: 10rpx;
|
||||
min-height: 68rpx;
|
||||
line-height: 1.3;
|
||||
white-space: normal;
|
||||
color: #484848;
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
.buy-gouwuche{
|
||||
position: absolute;
|
||||
right: 10rpx;
|
||||
bottom: 10rpx;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_desc {
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.desc-selling_point {
|
||||
width: 400rpx;
|
||||
font-size: 24rpx;
|
||||
color: #e49a3d;
|
||||
}
|
||||
|
||||
.desc-goods_sales {
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.desc_footer {
|
||||
font-size: 24rpx;
|
||||
|
||||
.price_x {
|
||||
margin-right: 16rpx;
|
||||
color: $main-bg;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.price_y {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 平铺显示
|
||||
.goods-list.column-2 {
|
||||
.goods-item {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item {
|
||||
float: left;
|
||||
box-sizing: border-box;
|
||||
padding: 6rpx;
|
||||
|
||||
.goods-image {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
padding-bottom: 100%;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
display: block;
|
||||
margin-top: 100%;
|
||||
}
|
||||
|
||||
.image {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
-o-object-fit: cover;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.detail {
|
||||
padding: 8rpx;
|
||||
background: #fff;
|
||||
|
||||
.goods-name {
|
||||
min-height: 68rpx;
|
||||
line-height: 1.3;
|
||||
white-space: normal;
|
||||
color: #484848;
|
||||
font-size: 26rpx;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.detail-price {
|
||||
.goods-price {
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.line-price {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.gotobuy{
|
||||
position: fixed;
|
||||
width: 700rpx;
|
||||
margin-left: 25rpx;
|
||||
bottom: 50rpx;
|
||||
}
|
||||
</style>
|
||||
109
package/user/notice/index.vue
Normal file
109
package/user/notice/index.vue
Normal file
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<view class="partner">
|
||||
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper" v-if="shopInfo">
|
||||
<!-- <u-form :model="form" ref="uForm" label-width="240rpx">
|
||||
<u-form-item>
|
||||
<view class="shop-box">
|
||||
<text class="shop-name">后台管理</text>
|
||||
<text>地址:https://dev.gxwebsoft.com/ylx-admin/</text>
|
||||
<text>账号:{{applyInfo.phone}}</text>
|
||||
<text>密码:默认为手机号码后6位</text>
|
||||
</view>
|
||||
</u-form-item>
|
||||
|
||||
|
||||
</u-form> -->
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<!-- <view class="footer">
|
||||
<view class="btn">
|
||||
<u-button type="primary" shape="circle">更新资料</u-button>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 表单字段元素
|
||||
const form = {
|
||||
// 入驻类型 (合伙人10001,配送员10002,社区门店10003,省代10004)
|
||||
grade_id: 10004,
|
||||
company: '',
|
||||
real_name: '',
|
||||
phone: '',
|
||||
mobile: '',
|
||||
region: [],
|
||||
detail: '',
|
||||
}
|
||||
|
||||
import * as UserApi from '@/api/user'
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form,
|
||||
disabled: false,
|
||||
imageList: [],
|
||||
shopInfo: {},
|
||||
applyInfo: {}
|
||||
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.getUserInfo()
|
||||
},
|
||||
methods: {
|
||||
// 获取当前用户信息
|
||||
getUserInfo() {
|
||||
const app = this
|
||||
UserApi.info().then(result => {
|
||||
app.shopInfo = result.data.shopInfo
|
||||
app.applyInfo = result.data.applyInfo
|
||||
})
|
||||
},
|
||||
groupChange(){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.partner {
|
||||
.banner {
|
||||
padding-top: 20rpx;
|
||||
width: 100%;
|
||||
}
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
.shop-box{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.shop-name{
|
||||
font-weight: bold;
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
.logo{
|
||||
width: 100rpx;
|
||||
}
|
||||
.shipin{
|
||||
width: 400rpx;
|
||||
}
|
||||
}
|
||||
.footer{
|
||||
width: 500rpx;
|
||||
margin: 20rpx auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
521
package/user/order/index.vue
Executable file
521
package/user/order/index.vue
Executable file
@@ -0,0 +1,521 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ native: true }" @down="downCallback" :up="upOption"
|
||||
@up="upCallback">
|
||||
<!-- tab栏 -->
|
||||
<u-tabs :list="tabs" :is-scroll="false" :current="curTab" :active-color="appTheme.mainBg" :duration="0.2" @change="onChangeTab" />
|
||||
<!-- 订单列表 -->
|
||||
<view class="order-list">
|
||||
<view class="order-item" v-for="(item, index) in list.data" :key="index">
|
||||
<view class="item-top">
|
||||
<view class="item-top-left">
|
||||
<text class="order-time">{{ item.create_time }}</text>
|
||||
</view>
|
||||
<view class="item-top-right">
|
||||
<text class="state-text">{{ item.state_text }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 商品列表 -->
|
||||
<view class="goods-list">
|
||||
<view class="goods-item" v-for="(goods, idx) in item.goods" :key="idx">
|
||||
<!-- 商品图片 -->
|
||||
<view class="goods-image">
|
||||
<image class="image" :src="goods.goods_image" mode="scaleToFill"></image>
|
||||
</view>
|
||||
<!-- 商品信息 -->
|
||||
<view class="goods-content">
|
||||
<view class="goods-title"><text class="twoline-hide">{{ goods.goods_name }}</text></view>
|
||||
<view class="goods-props clearfix">
|
||||
<view class="goods-props-item" v-for="(props, idx) in goods.goods_props" :key="idx">
|
||||
<text>{{ props.value.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 交易信息 -->
|
||||
<view class="goods-trade">
|
||||
<view class="goods-price">
|
||||
<text class="unit">¥</text>
|
||||
<text class="value">{{ goods.is_user_grade ? goods.grade_goods_price : goods.goods_price }}</text>
|
||||
</view>
|
||||
<view class="goods-num">
|
||||
<text>×{{ goods.total_num }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 订单合计 -->
|
||||
<view class="order-total">
|
||||
<text>共{{ item.total_num }}件商品,总金额</text>
|
||||
<text class="unit">¥</text>
|
||||
<text class="money">{{ item.pay_price }}</text>
|
||||
</view>
|
||||
<!-- 订单操作 -->
|
||||
<view v-if="item.order_status != OrderStatusEnum.CANCELLED.value" class="order-handle">
|
||||
<view class="btn-group clearfix">
|
||||
<!-- 未支付取消订单 -->
|
||||
<!-- <block v-if="item.pay_status == PayStatusEnum.PENDING.value">
|
||||
<view class="btn-item" @click="onCancel(item.order_id)">取消</view>
|
||||
</block> -->
|
||||
<!-- 已支付进行中的订单 -->
|
||||
<!-- <block v-if="item.order_status != OrderStatusEnum.APPLY_CANCEL.value"> -->
|
||||
<!-- <block v-if="item.pay_status == PayStatusEnum.SUCCESS.value && item.delivery_status == DeliveryStatusEnum.NOT_DELIVERED.value">
|
||||
<u-button type="primary" size="mini" class="btn-item" @click="onDelivery(item.order_id)">配送</u-button>
|
||||
</block> -->
|
||||
<!-- 订单核销码 -->
|
||||
<!-- <block v-if="item.pay_status == PayStatusEnum.SUCCESS.value && item.delivery_type == DeliveryTypeEnum.EXTRACT.value
|
||||
&& item.delivery_status == DeliveryStatusEnum.NOT_DELIVERED.value">
|
||||
<view class="btn-item active" @click="onExtractQRCode(item.order_id)">
|
||||
<text class="iconfont icon-qr-extract"></text>
|
||||
<text class="m-l-10">核销码</text>
|
||||
</view>
|
||||
</block> -->
|
||||
<!-- </block> -->
|
||||
<!-- 已申请取消 -->
|
||||
<!-- <view v-else class="f-28 col-8">取消申请中</view> -->
|
||||
<!-- 未支付的订单 -->
|
||||
<!-- <block v-if="item.pay_status == PayStatusEnum.PENDING.value">
|
||||
<view class="btn-item active" @click="onPay(item.order_id)">去支付</view>
|
||||
</block> -->
|
||||
<!-- 确认收货 -->
|
||||
<!-- <block v-if="item.delivery_status == DeliveryStatusEnum.DELIVERED.value && item.receipt_status == ReceiptStatusEnum.NOT_RECEIVED.value">
|
||||
<view class="btn-item active" @click="onReceipt(item.order_id)">确认收货</view>
|
||||
</block> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
<!-- 核销二维码弹窗 -->
|
||||
<u-popup v-model="showQRCodePopup" mode="center" border-radius="26" :closeable="true">
|
||||
<view class="qrcode-popup">
|
||||
<view class="title">自提核销二维码</view>
|
||||
<view class="pop-content">
|
||||
<image v-if="qrcodeImage" class="image" :src="qrcodeImage"></image>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
DeliveryStatusEnum,
|
||||
DeliveryTypeEnum,
|
||||
OrderStatusEnum,
|
||||
PayStatusEnum,
|
||||
PayTypeEnum,
|
||||
ReceiptStatusEnum
|
||||
} from '@/common/enum/order'
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import { getEmptyPaginateObj, getMoreListData } from '@/core/app'
|
||||
import * as OrderApi from '@/api/order'
|
||||
import * as UserApi from '@/api/user'
|
||||
import { wxPayment } from '@/core/app'
|
||||
|
||||
// 每页记录数量
|
||||
const pageSize = 15
|
||||
|
||||
// tab栏数据
|
||||
const tabs = [{
|
||||
name: `全部`,
|
||||
value: 'all'
|
||||
}, {
|
||||
name: `待支付`,
|
||||
value: 'payment'
|
||||
}, {
|
||||
name: `待发货`,
|
||||
value: 'delivery'
|
||||
}, {
|
||||
name: `待收货`,
|
||||
value: 'received'
|
||||
}, {
|
||||
name: `待评价`,
|
||||
value: 'comment'
|
||||
}]
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
DeliveryStatusEnum,
|
||||
DeliveryTypeEnum,
|
||||
OrderStatusEnum,
|
||||
PayStatusEnum,
|
||||
PayTypeEnum,
|
||||
ReceiptStatusEnum,
|
||||
|
||||
// 当前页面参数
|
||||
options: { dataType: 'all' },
|
||||
// tab栏数据
|
||||
tabs,
|
||||
// 当前标签索引
|
||||
curTab: 0,
|
||||
// 订单列表数据
|
||||
list: getEmptyPaginateObj(),
|
||||
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: { size: pageSize },
|
||||
// 数量要大于4条才显示无更多数据
|
||||
noMoreSize: 4,
|
||||
// 空布局
|
||||
empty: {
|
||||
tip: '亲,暂无订单记录'
|
||||
}
|
||||
},
|
||||
// 控制首次触发onShow事件时不刷新列表
|
||||
canReset: false,
|
||||
// 核销二维码弹窗
|
||||
showQRCodePopup: false,
|
||||
// 核销二维码图片url (通过后端获取)
|
||||
qrcodeImage: '',
|
||||
shopInfo: {},
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
// 初始化当前选中的标签
|
||||
this.initCurTab(options)
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow() {
|
||||
this.canReset && this.onRefreshList()
|
||||
this.canReset = true
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// 初始化当前选中的标签
|
||||
initCurTab(options) {
|
||||
const app = this
|
||||
if (options.dataType) {
|
||||
const index = app.tabs.findIndex(item => item.value == options.dataType)
|
||||
app.curTab = index > -1 ? index : 0
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
app.getOrderList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
// 获取订单列表
|
||||
getOrderList(pageNo = 1) {
|
||||
const app = this
|
||||
const shopInfo = uni.getStorageSync('shopInfo')
|
||||
return new Promise((resolve, reject) => {
|
||||
OrderApi.list({ dataType: app.getTabValue(), page: pageNo, byShopId: shopInfo.shopId }, { load: false })
|
||||
.then(result => {
|
||||
// 合并新数据
|
||||
const newList = app.initList(result.data.list)
|
||||
app.list.data = getMoreListData(newList, app.list, pageNo)
|
||||
resolve(newList)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 初始化订单列表数据
|
||||
initList(newList) {
|
||||
newList.data.forEach(item => {
|
||||
item.total_num = 0
|
||||
item.goods.forEach(goods => {
|
||||
item.total_num += goods.total_num
|
||||
})
|
||||
})
|
||||
return newList
|
||||
},
|
||||
|
||||
// 获取当前标签项的值
|
||||
getTabValue() {
|
||||
return this.tabs[this.curTab].value
|
||||
},
|
||||
|
||||
// 切换标签项
|
||||
onChangeTab(index) {
|
||||
const app = this
|
||||
// 设置当前选中的标签
|
||||
app.curTab = index
|
||||
// 刷新订单列表
|
||||
app.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新订单列表
|
||||
onRefreshList() {
|
||||
this.list = getEmptyPaginateObj()
|
||||
setTimeout(() => {
|
||||
this.mescroll.resetUpScroll()
|
||||
}, 120)
|
||||
},
|
||||
|
||||
// 取消订单
|
||||
onCancel(orderId) {
|
||||
const app = this
|
||||
uni.showModal({
|
||||
title: '友情提示',
|
||||
content: '确认要取消该订单吗?',
|
||||
success(o) {
|
||||
if (o.confirm) {
|
||||
OrderApi.cancel(orderId)
|
||||
.then(result => {
|
||||
// 显示成功信息
|
||||
app.$toast(result.message)
|
||||
// 刷新订单列表
|
||||
app.onRefreshList()
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onDelivery(orderId){
|
||||
return this.$navTo('package/dealer/driver', { orderId })
|
||||
console.log(orderId);
|
||||
return false
|
||||
},
|
||||
|
||||
// 确认收货
|
||||
onReceipt(orderId) {
|
||||
const app = this
|
||||
uni.showModal({
|
||||
title: '友情提示',
|
||||
content: '确认收到商品了吗?',
|
||||
success(o) {
|
||||
if (o.confirm) {
|
||||
OrderApi.receipt(orderId)
|
||||
.then(result => {
|
||||
// 显示成功信息
|
||||
app.$success(result.message)
|
||||
// 刷新订单列表
|
||||
app.onRefreshList()
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 获取核销二维码
|
||||
onExtractQRCode(orderId) {
|
||||
const app = this
|
||||
OrderApi.extractQrcode(orderId, { channel: app.platform })
|
||||
.then(result => {
|
||||
app.qrcodeImage = result.data.qrcode
|
||||
app.showQRCodePopup = true
|
||||
})
|
||||
},
|
||||
|
||||
// 点击去支付
|
||||
onPay(orderId) {
|
||||
this.$navTo('pages/checkout/cashier/index', { orderId })
|
||||
},
|
||||
|
||||
// 跳转到订单详情页
|
||||
handleTargetDetail(orderId) {
|
||||
this.$navTo('pages/order/detail', { orderId })
|
||||
},
|
||||
|
||||
// 跳转到订单评价页
|
||||
handleTargetComment(orderId) {
|
||||
this.$navTo('pages/order/comment/index', { orderId })
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 项目内容
|
||||
.order-item {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 30rpx 30rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
// 项目顶部
|
||||
.item-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 26rpx;
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
.order-time {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.state-text {
|
||||
color: $main-bg;
|
||||
}
|
||||
}
|
||||
|
||||
// 商品列表
|
||||
.goods-list {
|
||||
|
||||
// 商品项
|
||||
.goods-item {
|
||||
display: flex;
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
// 商品图片
|
||||
.goods-image {
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 商品内容
|
||||
.goods-content {
|
||||
flex: 1;
|
||||
padding-left: 16rpx;
|
||||
padding-top: 16rpx;
|
||||
|
||||
.goods-title {
|
||||
font-size: 26rpx;
|
||||
max-height: 76rpx;
|
||||
}
|
||||
|
||||
.goods-props {
|
||||
margin-top: 14rpx;
|
||||
height: 40rpx;
|
||||
color: #ababab;
|
||||
font-size: 24rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.goods-props-item {
|
||||
display: inline-block;
|
||||
margin-right: 14rpx;
|
||||
padding: 4rpx 16rpx;
|
||||
border-radius: 12rpx;
|
||||
background-color: #F5F5F5;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 交易信息
|
||||
.goods-trade {
|
||||
padding-top: 16rpx;
|
||||
width: 150rpx;
|
||||
text-align: right;
|
||||
color: $uni-text-color-grey;
|
||||
font-size: 26rpx;
|
||||
|
||||
.goods-price {
|
||||
vertical-align: bottom;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
.unit {
|
||||
margin-right: -2rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 订单合计
|
||||
.order-total {
|
||||
font-size: 26rpx;
|
||||
vertical-align: bottom;
|
||||
text-align: right;
|
||||
height: 40rpx;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.unit {
|
||||
margin-left: 8rpx;
|
||||
margin-right: -2rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.money {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 订单操作
|
||||
.order-handle {
|
||||
.btn-group {
|
||||
|
||||
.btn-item {
|
||||
border-radius: 10rpx;
|
||||
padding: 6rpx 20rpx;
|
||||
margin-left: 15rpx;
|
||||
font-size: 28rpx;
|
||||
float: right;
|
||||
|
||||
&:last-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
border: 1rpx solid $main-bg;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 弹出层 - 核销二维码
|
||||
.qrcode-popup {
|
||||
padding: 36rpx 30rpx;
|
||||
|
||||
.title {
|
||||
font-size: 30rpx;
|
||||
margin-bottom: 26rpx;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pop-content {
|
||||
min-height: 260rpx;
|
||||
padding: 0 10rpx;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 510rpx;
|
||||
height: 510rpx;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
402
package/user/popularize/components/goods.vue
Executable file
402
package/user/popularize/components/goods.vue
Executable file
@@ -0,0 +1,402 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ use: false }" :up="upOption"
|
||||
:bottombar="false" @up="upCallback">
|
||||
<view class="cate-content">
|
||||
<!-- 商品列表 -->
|
||||
<view class="goods-list">
|
||||
<view class="goods-item--container" v-for="(item, index) in goodsList.data" :key="index">
|
||||
<view class="goods-item" @click="onTargetGoods(item.goods_id)">
|
||||
<!-- 商品图片 -->
|
||||
<view class="goods-item_left">
|
||||
<image class="image" :src="item.goods_image"></image>
|
||||
</view>
|
||||
<view class="goods-item_right">
|
||||
<!-- 商品标题 -->
|
||||
<view class="goods-name">
|
||||
<text class="twoline-hide">{{ item.goods_name }}</text>
|
||||
</view>
|
||||
<view class="item-prices oneline-hide">
|
||||
<text class="goods-sales">已售{{ item.goods_sales }}件</text>
|
||||
</view>
|
||||
<!-- 商品信息 -->
|
||||
<view class="goods-item_desc">
|
||||
<view class="desc_footer">
|
||||
<view class="item-prices oneline-hide">
|
||||
<text class="price_x">¥{{ item.goods_price_min }}</text>
|
||||
<!-- 商品销量 -->
|
||||
<text v-if="item.line_price_min > 0"
|
||||
class="price_y">¥{{ item.line_price_min }}</text>
|
||||
</view>
|
||||
<view class="buy-gouwuche">
|
||||
<u-button size="mini" @click="handleAddCart(item)">取消收藏
|
||||
</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 加入购物车组件 -->
|
||||
<AddCartPopup ref="AddCartPopup" @addCart="onUpdateCartTabBadge" />
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import {
|
||||
getEmptyPaginateObj,
|
||||
getMoreListData,
|
||||
setCartTabBadge
|
||||
} from '@/core/app'
|
||||
import {
|
||||
PageCategoryStyleEnum
|
||||
} from '@/common/enum/store/page/category'
|
||||
import Empty from '@/components/empty'
|
||||
import AddCartBtn from '@/components/add-cart-btn'
|
||||
import AddCartPopup from '@/components/add-cart-popup'
|
||||
import {
|
||||
rpx2px
|
||||
} from '@/utils/util'
|
||||
import * as GoodsApi from '@/api/goods'
|
||||
|
||||
const pageSize = 15
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody,
|
||||
Empty,
|
||||
AddCartBtn,
|
||||
AddCartPopup
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
props: {
|
||||
// 分类列表
|
||||
list: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
PageCategoryStyleEnum,
|
||||
// 列表高度
|
||||
scrollHeight: 0,
|
||||
// 一级分类:指针
|
||||
curIndex: -1,
|
||||
// 商品列表
|
||||
goodsList: getEmptyPaginateObj(),
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: {
|
||||
size: pageSize
|
||||
},
|
||||
// 数量要大于3条才显示无更多数据
|
||||
noMoreSize: 3,
|
||||
// 返回顶部
|
||||
toTop: {
|
||||
right: 30,
|
||||
bottom: 48,
|
||||
zIndex: 9
|
||||
}
|
||||
},
|
||||
|
||||
sortPrice: false, // 价格排序 (true高到低 false低到高)
|
||||
sortType: 'hot', // 排序类型
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 设置分类列表高度
|
||||
this.setListHeight()
|
||||
},
|
||||
methods: {
|
||||
|
||||
// 切换排序方式
|
||||
handleSortType(newSortType) {
|
||||
const app = this
|
||||
const newSortPrice = newSortType === 'price' ? !app.sortPrice : true
|
||||
app.sortType = newSortType
|
||||
app.sortPrice = newSortPrice
|
||||
// 刷新列表数据
|
||||
app.getGoodsList()
|
||||
},
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
console.log(page.num);
|
||||
app.getGoodsList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取商品列表
|
||||
* @param {Number} pageNo 页码
|
||||
*/
|
||||
getGoodsList(pageNo = 1) {
|
||||
const app = this
|
||||
const categoryId = app.curIndex > -1 ? app.list[app.curIndex].category_id : 0
|
||||
return new Promise((resolve, reject) => {
|
||||
GoodsApi.list({
|
||||
categoryId,
|
||||
page: pageNo,
|
||||
collection: true
|
||||
}, {
|
||||
load: false
|
||||
})
|
||||
.then(result => {
|
||||
const newList = result.data.list
|
||||
app.goodsList.data = getMoreListData(newList, app.goodsList, pageNo)
|
||||
app.goodsList.last_page = newList.last_page
|
||||
resolve(newList)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 设置列表内容的高度
|
||||
setListHeight() {
|
||||
const {
|
||||
windowHeight
|
||||
} = uni.getSystemInfoSync()
|
||||
this.scrollHeight = windowHeight - rpx2px(96)
|
||||
},
|
||||
|
||||
// 一级分类:选中分类
|
||||
handleSelectNav(index) {
|
||||
this.curIndex = index
|
||||
this.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新列表数据
|
||||
onRefreshList() {
|
||||
this.goodsList = getEmptyPaginateObj()
|
||||
setTimeout(() => this.mescroll.resetUpScroll(), 120)
|
||||
},
|
||||
|
||||
// 跳转至商品列表页
|
||||
onTargetGoods(goodsId) {
|
||||
this.$navTo('pages/goods/detail', {
|
||||
goodsId
|
||||
})
|
||||
},
|
||||
|
||||
// 点击加入购物车
|
||||
handleAddCart(item) {
|
||||
GoodsApi.collection({goodsId: item.})
|
||||
this.$emit('addCart')
|
||||
},
|
||||
|
||||
// 更新购物车角标
|
||||
onUpdateCartTabBadge() {
|
||||
console.log('onUpdateCartTabBadge')
|
||||
setCartTabBadge()
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
background-color: #F6F6F6 !important;
|
||||
}
|
||||
|
||||
// 分类内容
|
||||
.cate-content {
|
||||
z-index: 1;
|
||||
background-color: #F6F6F6 !important;
|
||||
padding-top: 0rpx;
|
||||
}
|
||||
|
||||
// 一级分类+二级分类 20
|
||||
.cate-left {
|
||||
width: 173rpx;
|
||||
height: 100%;
|
||||
background: #f8f8f8;
|
||||
color: #444;
|
||||
|
||||
position: fixed;
|
||||
top: calc(286rpx + var(--window-top));
|
||||
left: var(--window-left);
|
||||
bottom: var(--window-bottom);
|
||||
}
|
||||
|
||||
// 左侧一级分类
|
||||
.type-nav {
|
||||
position: relative;
|
||||
height: 90rpx;
|
||||
z-index: 10;
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&.selected {
|
||||
background: #fff;
|
||||
border-right: none;
|
||||
font-size: 28rpx;
|
||||
color: $main-bg
|
||||
}
|
||||
}
|
||||
|
||||
// 商品列表
|
||||
.goods-list {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.goods-item {
|
||||
padding: 28rpx 22rpx;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
padding: 20rpx;
|
||||
border: 1px solid #F6F6F6;
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.goods-item_left {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
margin-right: 20rpx;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 280rpx;
|
||||
height: 280rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_right {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
|
||||
.goods-name {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 68rpx;
|
||||
font-size: 34rpx;
|
||||
line-height: 1.3;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_desc {
|
||||
margin-top: 20rpx;
|
||||
|
||||
.people {
|
||||
margin-right: 14rpx;
|
||||
}
|
||||
|
||||
.desc_footer {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
position: absolute;
|
||||
right: 0rpx;
|
||||
bottom: 0rpx;
|
||||
min-height: 44rpx;
|
||||
|
||||
.item-prices {
|
||||
padding-right: 6rpx;
|
||||
|
||||
.price_x {
|
||||
margin-right: 14rpx;
|
||||
font-weight: 600;
|
||||
color: #ff0000;
|
||||
font-size: 38rpx;
|
||||
}
|
||||
|
||||
.price_y {
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.goods-sales {
|
||||
padding-top: 8rpx !important;
|
||||
color: #b3b3b3 !important;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
background: #fff;
|
||||
border-radius: 14rpx;
|
||||
padding: 20rpx 4rpx;
|
||||
box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.07);
|
||||
}
|
||||
|
||||
// 排序组件
|
||||
.store-sort {
|
||||
margin-top: 24rpx;
|
||||
position: sticky;
|
||||
top: var(--window-top);
|
||||
display: flex;
|
||||
padding: 20rpx 0;
|
||||
font-size: 28rpx;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
z-index: 99;
|
||||
|
||||
.sort-item {
|
||||
flex-basis: 33.3333%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 50rpx;
|
||||
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
}
|
||||
}
|
||||
|
||||
.sort-item-price .price-arrow {
|
||||
margin-left: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #000;
|
||||
|
||||
.icon {
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
}
|
||||
|
||||
&.up {
|
||||
margin-bottom: -16rpx;
|
||||
}
|
||||
|
||||
&.down {
|
||||
margin-top: -16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
404
package/user/popularize/components/goods1.vue
Executable file
404
package/user/popularize/components/goods1.vue
Executable file
@@ -0,0 +1,404 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ use: false }" :up="upOption"
|
||||
:bottombar="false" @up="upCallback">
|
||||
<view class="cate-content">
|
||||
<!-- 商品列表 -->
|
||||
<view class="goods-list">
|
||||
<view class="goods-item--container" v-for="(item, index) in goodsList.data" :key="index">
|
||||
<view class="goods-item" @click="onTargetGoods(item.goods_id)">
|
||||
<!-- 商品图片 -->
|
||||
<view class="goods-item_left">
|
||||
<image class="image" :src="item.goods_image"></image>
|
||||
</view>
|
||||
<view class="goods-item_right">
|
||||
<!-- 商品标题 -->
|
||||
<view class="goods-name">
|
||||
<text class="twoline-hide">{{ item.goods_name }}</text>
|
||||
</view>
|
||||
<view class="item-prices oneline-hide">
|
||||
<text class="goods-sales">已售{{ item.goods_sales }}件</text>
|
||||
</view>
|
||||
<!-- 商品信息 -->
|
||||
<view class="goods-item_desc">
|
||||
<view class="desc_footer">
|
||||
<view class="item-prices oneline-hide">
|
||||
<text class="price_x">¥{{ item.goods_price_min }}</text>
|
||||
<!-- 商品销量 -->
|
||||
<text v-if="item.line_price_min > 0"
|
||||
class="price_y">¥{{ item.line_price_min }}</text>
|
||||
</view>
|
||||
<view class="buy-gouwuche">
|
||||
<u-button type="primary" size="mini">置顶</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 加入购物车组件 -->
|
||||
<AddCartPopup ref="AddCartPopup" @addCart="onUpdateCartTabBadge" />
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import {
|
||||
getEmptyPaginateObj,
|
||||
getMoreListData,
|
||||
setCartTabBadge
|
||||
} from '@/core/app'
|
||||
import {
|
||||
PageCategoryStyleEnum
|
||||
} from '@/common/enum/store/page/category'
|
||||
import Empty from '@/components/empty'
|
||||
import AddCartBtn from '@/components/add-cart-btn'
|
||||
import AddCartPopup from '@/components/add-cart-popup'
|
||||
import {
|
||||
rpx2px
|
||||
} from '@/utils/util'
|
||||
import * as GoodsApi from '@/api/goods'
|
||||
|
||||
const pageSize = 15
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody,
|
||||
Empty,
|
||||
AddCartBtn,
|
||||
AddCartPopup
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
props: {
|
||||
// 分类列表
|
||||
list: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
PageCategoryStyleEnum,
|
||||
// 列表高度
|
||||
scrollHeight: 0,
|
||||
// 一级分类:指针
|
||||
curIndex: -1,
|
||||
// 商品列表
|
||||
goodsList: getEmptyPaginateObj(),
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: {
|
||||
size: pageSize
|
||||
},
|
||||
// 数量要大于3条才显示无更多数据
|
||||
noMoreSize: 3,
|
||||
// 返回顶部
|
||||
toTop: {
|
||||
right: 30,
|
||||
bottom: 48,
|
||||
zIndex: 9
|
||||
}
|
||||
},
|
||||
|
||||
sortPrice: false, // 价格排序 (true高到低 false低到高)
|
||||
sortType: 'hot', // 排序类型
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 设置分类列表高度
|
||||
this.setListHeight()
|
||||
},
|
||||
methods: {
|
||||
|
||||
// 切换排序方式
|
||||
handleSortType(newSortType) {
|
||||
const app = this
|
||||
const newSortPrice = newSortType === 'price' ? !app.sortPrice : true
|
||||
app.sortType = newSortType
|
||||
app.sortPrice = newSortPrice
|
||||
// 刷新列表数据
|
||||
app.getGoodsList()
|
||||
},
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
console.log(page.num);
|
||||
app.getGoodsList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取商品列表
|
||||
* @param {Number} pageNo 页码
|
||||
*/
|
||||
getGoodsList(pageNo = 1) {
|
||||
const app = this
|
||||
const categoryId = app.curIndex > -1 ? app.list[app.curIndex].category_id : 0
|
||||
const { sortType } = this
|
||||
const { shopId } = uni.getStorageSync('shopInfo')
|
||||
return new Promise((resolve, reject) => {
|
||||
GoodsApi.list({
|
||||
categoryId,
|
||||
page: pageNo,
|
||||
sortType,
|
||||
shopId
|
||||
}, {
|
||||
load: false
|
||||
})
|
||||
.then(result => {
|
||||
const newList = result.data.list
|
||||
app.goodsList.data = getMoreListData(newList, app.goodsList, pageNo)
|
||||
app.goodsList.last_page = newList.last_page
|
||||
resolve(newList)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 设置列表内容的高度
|
||||
setListHeight() {
|
||||
const {
|
||||
windowHeight
|
||||
} = uni.getSystemInfoSync()
|
||||
this.scrollHeight = windowHeight - rpx2px(96)
|
||||
},
|
||||
|
||||
// 一级分类:选中分类
|
||||
handleSelectNav(index) {
|
||||
this.curIndex = index
|
||||
this.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新列表数据
|
||||
onRefreshList() {
|
||||
this.goodsList = getEmptyPaginateObj()
|
||||
setTimeout(() => this.mescroll.resetUpScroll(), 120)
|
||||
},
|
||||
|
||||
// 跳转至商品列表页
|
||||
onTargetGoods(goodsId) {
|
||||
this.$navTo('pages/goods/detail', {
|
||||
goodsId
|
||||
})
|
||||
},
|
||||
|
||||
// 点击加入购物车
|
||||
handleAddCart(item) {
|
||||
this.$refs.AddCartPopup.handle(item)
|
||||
this.$emit('addCart')
|
||||
},
|
||||
|
||||
// 更新购物车角标
|
||||
onUpdateCartTabBadge() {
|
||||
console.log('onUpdateCartTabBadge')
|
||||
setCartTabBadge()
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
background-color: #F6F6F6 !important;
|
||||
}
|
||||
|
||||
// 分类内容
|
||||
.cate-content {
|
||||
z-index: 1;
|
||||
background-color: #F6F6F6 !important;
|
||||
padding-top: 0rpx;
|
||||
}
|
||||
|
||||
// 一级分类+二级分类 20
|
||||
.cate-left {
|
||||
width: 173rpx;
|
||||
height: 100%;
|
||||
background: #f8f8f8;
|
||||
color: #444;
|
||||
|
||||
position: fixed;
|
||||
top: calc(286rpx + var(--window-top));
|
||||
left: var(--window-left);
|
||||
bottom: var(--window-bottom);
|
||||
}
|
||||
|
||||
// 左侧一级分类
|
||||
.type-nav {
|
||||
position: relative;
|
||||
height: 90rpx;
|
||||
z-index: 10;
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&.selected {
|
||||
background: #fff;
|
||||
border-right: none;
|
||||
font-size: 28rpx;
|
||||
color: $main-bg
|
||||
}
|
||||
}
|
||||
|
||||
// 商品列表
|
||||
.goods-list {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.goods-item {
|
||||
padding: 28rpx 22rpx;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
padding: 20rpx;
|
||||
border: 1px solid #F6F6F6;
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.goods-item_left {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
margin-right: 20rpx;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 280rpx;
|
||||
height: 280rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_right {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
|
||||
.goods-name {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 68rpx;
|
||||
font-size: 34rpx;
|
||||
line-height: 1.3;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_desc {
|
||||
margin-top: 20rpx;
|
||||
|
||||
.people {
|
||||
margin-right: 14rpx;
|
||||
}
|
||||
|
||||
.desc_footer {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
position: absolute;
|
||||
right: 0rpx;
|
||||
bottom: 0rpx;
|
||||
min-height: 44rpx;
|
||||
|
||||
.item-prices {
|
||||
padding-right: 6rpx;
|
||||
|
||||
.price_x {
|
||||
margin-right: 14rpx;
|
||||
font-weight: 600;
|
||||
color: #ff0000;
|
||||
font-size: 38rpx;
|
||||
}
|
||||
|
||||
.price_y {
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.goods-sales {
|
||||
padding-top: 8rpx !important;
|
||||
color: #b3b3b3 !important;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
background: #fff;
|
||||
border-radius: 14rpx;
|
||||
padding: 20rpx 4rpx;
|
||||
box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.07);
|
||||
}
|
||||
|
||||
// 排序组件
|
||||
.store-sort {
|
||||
margin-top: 24rpx;
|
||||
position: sticky;
|
||||
top: var(--window-top);
|
||||
display: flex;
|
||||
padding: 20rpx 0;
|
||||
font-size: 28rpx;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
z-index: 99;
|
||||
|
||||
.sort-item {
|
||||
flex-basis: 33.3333%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 50rpx;
|
||||
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
}
|
||||
}
|
||||
|
||||
.sort-item-price .price-arrow {
|
||||
margin-left: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #000;
|
||||
|
||||
.icon {
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
}
|
||||
|
||||
&.up {
|
||||
margin-bottom: -16rpx;
|
||||
}
|
||||
|
||||
&.down {
|
||||
margin-top: -16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
395
package/user/popularize/index.vue
Executable file
395
package/user/popularize/index.vue
Executable file
@@ -0,0 +1,395 @@
|
||||
<template>
|
||||
<view class="container" :style="appThemeStyle">
|
||||
<mescroll-body ref="mescrollRef" :sticky="true" @init="mescrollInit" :down="{ use: false }" :up="upOption"
|
||||
:bottombar="false" @up="upCallback">
|
||||
<view class="cate-content">
|
||||
<!-- 商品列表 -->
|
||||
<view class="goods-list">
|
||||
<view class="goods-item--container" v-for="(item, index) in goodsList.data" :key="index">
|
||||
<view class="goods-item" @click="onTargetGoods(item.goods_id)">
|
||||
<!-- 商品图片 -->
|
||||
<view class="goods-item_left">
|
||||
<image class="image" :src="item.goods_image"></image>
|
||||
</view>
|
||||
<view class="goods-item_right">
|
||||
<!-- 商品标题 -->
|
||||
<view class="goods-name">
|
||||
<text class="twoline-hide">{{ item.goods_name }}</text>
|
||||
</view>
|
||||
<view class="item-prices oneline-hide">
|
||||
<text class="goods-sales">已售{{ item.goods_sales }}件</text>
|
||||
</view>
|
||||
<!-- 商品信息 -->
|
||||
<view class="goods-item_desc">
|
||||
<view class="desc_footer">
|
||||
<view class="item-prices oneline-hide">
|
||||
<text class="price_x">¥{{ item.goods_price_min }}</text>
|
||||
<!-- 商品销量 -->
|
||||
<text v-if="item.line_price_min > 0"
|
||||
class="price_y">¥{{ item.line_price_min }}</text>
|
||||
</view>
|
||||
<view class="buy-gouwuche">
|
||||
<u-button type="primary" size="mini">置顶</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
|
||||
import MescrollMixin from '@/components/mescroll-uni/mescroll-mixins'
|
||||
import {
|
||||
getEmptyPaginateObj,
|
||||
getMoreListData,
|
||||
setCartTabBadge
|
||||
} from '@/core/app'
|
||||
import {
|
||||
PageCategoryStyleEnum
|
||||
} from '@/common/enum/store/page/category'
|
||||
import Empty from '@/components/empty'
|
||||
import AddCartBtn from '@/components/add-cart-btn'
|
||||
import AddCartPopup from '@/components/add-cart-popup'
|
||||
import {
|
||||
rpx2px
|
||||
} from '@/utils/util'
|
||||
import * as GoodsApi from '@/api/goods'
|
||||
|
||||
const pageSize = 15
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MescrollBody,
|
||||
Empty,
|
||||
AddCartBtn,
|
||||
AddCartPopup
|
||||
},
|
||||
mixins: [MescrollMixin],
|
||||
data() {
|
||||
return {
|
||||
// 枚举类
|
||||
PageCategoryStyleEnum,
|
||||
// 列表高度
|
||||
scrollHeight: 0,
|
||||
// 一级分类:指针
|
||||
curIndex: -1,
|
||||
// 商品列表
|
||||
goodsList: getEmptyPaginateObj(),
|
||||
// 上拉加载配置
|
||||
upOption: {
|
||||
// 首次自动执行
|
||||
auto: true,
|
||||
// 每页数据的数量; 默认10
|
||||
page: {
|
||||
size: pageSize
|
||||
},
|
||||
// 数量要大于3条才显示无更多数据
|
||||
noMoreSize: 3,
|
||||
// 返回顶部
|
||||
toTop: {
|
||||
right: 30,
|
||||
bottom: 48,
|
||||
zIndex: 9
|
||||
}
|
||||
},
|
||||
|
||||
sortPrice: false, // 价格排序 (true高到低 false低到高)
|
||||
sortType: 'hot', // 排序类型
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 设置分类列表高度
|
||||
this.setListHeight()
|
||||
},
|
||||
methods: {
|
||||
|
||||
// 切换排序方式
|
||||
handleSortType(newSortType) {
|
||||
const app = this
|
||||
const newSortPrice = newSortType === 'price' ? !app.sortPrice : true
|
||||
app.sortType = newSortType
|
||||
app.sortPrice = newSortPrice
|
||||
// 刷新列表数据
|
||||
app.getGoodsList()
|
||||
},
|
||||
|
||||
/**
|
||||
* 上拉加载的回调 (页面初始化时也会执行一次)
|
||||
* 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10
|
||||
* @param {Object} page
|
||||
*/
|
||||
upCallback(page) {
|
||||
const app = this
|
||||
// 设置列表数据
|
||||
console.log(page.num);
|
||||
app.getGoodsList(page.num)
|
||||
.then(list => {
|
||||
const curPageLen = list.data.length
|
||||
const totalSize = list.data.total
|
||||
app.mescroll.endBySize(curPageLen, totalSize)
|
||||
})
|
||||
.catch(() => app.mescroll.endErr())
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取商品列表
|
||||
* @param {Number} pageNo 页码
|
||||
*/
|
||||
getGoodsList(pageNo = 1) {
|
||||
const app = this
|
||||
const categoryId = app.curIndex > -1 ? app.list[app.curIndex].category_id : 0
|
||||
const { shopId } = uni.getStorageSync('shopInfo')
|
||||
return new Promise((resolve, reject) => {
|
||||
GoodsApi.list({
|
||||
categoryId,
|
||||
page: pageNo,
|
||||
topGoods: true,
|
||||
shopId
|
||||
}, {
|
||||
load: false
|
||||
})
|
||||
.then(result => {
|
||||
const newList = result.data.list
|
||||
app.goodsList.data = getMoreListData(newList, app.goodsList, pageNo)
|
||||
app.goodsList.last_page = newList.last_page
|
||||
resolve(newList)
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
},
|
||||
|
||||
// 设置列表内容的高度
|
||||
setListHeight() {
|
||||
const {
|
||||
windowHeight
|
||||
} = uni.getSystemInfoSync()
|
||||
this.scrollHeight = windowHeight - rpx2px(96)
|
||||
},
|
||||
|
||||
// 一级分类:选中分类
|
||||
handleSelectNav(index) {
|
||||
this.curIndex = index
|
||||
this.onRefreshList()
|
||||
},
|
||||
|
||||
// 刷新列表数据
|
||||
onRefreshList() {
|
||||
this.goodsList = getEmptyPaginateObj()
|
||||
setTimeout(() => this.mescroll.resetUpScroll(), 120)
|
||||
},
|
||||
|
||||
// 跳转至商品列表页
|
||||
onTargetGoods(goodsId) {
|
||||
this.$navTo('pages/goods/detail', {
|
||||
goodsId
|
||||
})
|
||||
},
|
||||
|
||||
// 点击加入购物车
|
||||
handleAddCart(item) {
|
||||
GoodsApi.collection({goodsId: item.goods_id}).then(() => {
|
||||
this.getGoodsList()
|
||||
})
|
||||
},
|
||||
|
||||
// 更新购物车角标
|
||||
onUpdateCartTabBadge() {
|
||||
console.log('onUpdateCartTabBadge')
|
||||
setCartTabBadge()
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
background-color: #F6F6F6 !important;
|
||||
}
|
||||
|
||||
// 分类内容
|
||||
.cate-content {
|
||||
z-index: 1;
|
||||
background-color: #F6F6F6 !important;
|
||||
padding-top: 0rpx;
|
||||
}
|
||||
|
||||
// 一级分类+二级分类 20
|
||||
.cate-left {
|
||||
width: 173rpx;
|
||||
height: 100%;
|
||||
background: #f8f8f8;
|
||||
color: #444;
|
||||
|
||||
position: fixed;
|
||||
top: calc(286rpx + var(--window-top));
|
||||
left: var(--window-left);
|
||||
bottom: var(--window-bottom);
|
||||
}
|
||||
|
||||
// 左侧一级分类
|
||||
.type-nav {
|
||||
position: relative;
|
||||
height: 90rpx;
|
||||
z-index: 10;
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&.selected {
|
||||
background: #fff;
|
||||
border-right: none;
|
||||
font-size: 28rpx;
|
||||
color: $main-bg
|
||||
}
|
||||
}
|
||||
|
||||
// 商品列表
|
||||
.goods-list {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.goods-item {
|
||||
padding: 28rpx 22rpx;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
padding: 20rpx;
|
||||
border: 1px solid #F6F6F6;
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.goods-item_left {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
margin-right: 20rpx;
|
||||
|
||||
.image {
|
||||
display: block;
|
||||
width: 280rpx;
|
||||
height: 280rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_right {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
|
||||
.goods-name {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 68rpx;
|
||||
font-size: 34rpx;
|
||||
line-height: 1.3;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item_desc {
|
||||
margin-top: 20rpx;
|
||||
|
||||
.people {
|
||||
margin-right: 14rpx;
|
||||
}
|
||||
|
||||
.desc_footer {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
position: absolute;
|
||||
right: 0rpx;
|
||||
bottom: 0rpx;
|
||||
min-height: 44rpx;
|
||||
|
||||
.item-prices {
|
||||
padding-right: 6rpx;
|
||||
|
||||
.price_x {
|
||||
margin-right: 14rpx;
|
||||
font-weight: 600;
|
||||
color: #ff0000;
|
||||
font-size: 38rpx;
|
||||
}
|
||||
|
||||
.price_y {
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.goods-sales {
|
||||
padding-top: 8rpx !important;
|
||||
color: #b3b3b3 !important;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
background: #fff;
|
||||
border-radius: 14rpx;
|
||||
padding: 20rpx 4rpx;
|
||||
box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.07);
|
||||
}
|
||||
|
||||
// 排序组件
|
||||
.store-sort {
|
||||
margin-top: 24rpx;
|
||||
position: sticky;
|
||||
top: var(--window-top);
|
||||
display: flex;
|
||||
padding: 20rpx 0;
|
||||
font-size: 28rpx;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
z-index: 99;
|
||||
|
||||
.sort-item {
|
||||
flex-basis: 33.3333%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 50rpx;
|
||||
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
}
|
||||
}
|
||||
|
||||
.sort-item-price .price-arrow {
|
||||
margin-left: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #000;
|
||||
|
||||
.icon {
|
||||
&.active {
|
||||
color: $main-bg;
|
||||
}
|
||||
|
||||
&.up {
|
||||
margin-bottom: -16rpx;
|
||||
}
|
||||
|
||||
&.down {
|
||||
margin-top: -16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
90
package/user/profile/index.vue
Normal file
90
package/user/profile/index.vue
Normal file
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<view class="partner">
|
||||
<!-- 表单组件 -->
|
||||
<view v-if="userInfo" class="form-wrapper">
|
||||
<u-form label-width="240rpx">
|
||||
<u-form-item label="会员ID" prop="name">
|
||||
{{userInfo.user_id}}
|
||||
</u-form-item>
|
||||
<u-form-item label="头像" prop="name">
|
||||
<image :src="userInfo.avatar_url" mode="widthFix" class="logo"></image>
|
||||
</u-form-item>
|
||||
<u-form-item label="昵称" prop="name">
|
||||
{{userInfo.nick_name}}
|
||||
</u-form-item>
|
||||
<u-form-item label="手机号码" prop="name">
|
||||
{{userInfo.mobile}}
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<!-- <view class="footer">
|
||||
<view class="btn">
|
||||
<u-button type="primary" shape="circle">更新资料</u-button>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as UserApi from '@/api/user'
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
disabled: false,
|
||||
userInfo: null,
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.getUserInfo()
|
||||
},
|
||||
methods: {
|
||||
// 获取当前用户信息
|
||||
getUserInfo() {
|
||||
const app = this
|
||||
const userInfo = uni.getStorageSync('userInfo')
|
||||
if(userInfo){
|
||||
app.userInfo = userInfo
|
||||
return
|
||||
}
|
||||
UserApi.info().then(result => {
|
||||
app.userInfo = result.data.userInfo
|
||||
})
|
||||
},
|
||||
groupChange(){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.partner {
|
||||
|
||||
.banner {
|
||||
width: 100%;
|
||||
}
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
.logo{
|
||||
width: 100rpx;
|
||||
}
|
||||
.shipin{
|
||||
width: 400rpx;
|
||||
}
|
||||
}
|
||||
.footer{
|
||||
width: 500rpx;
|
||||
margin: 20rpx auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
116
package/user/shop/index.vue
Normal file
116
package/user/shop/index.vue
Normal file
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<view class="partner">
|
||||
|
||||
<!-- 表单组件 -->
|
||||
<view class="form-wrapper" v-if="shopInfo">
|
||||
<u-form :model="form" ref="uForm" label-width="240rpx">
|
||||
<u-form-item>
|
||||
<image :src="shopInfo.backgroundUrl" mode="widthFix" class="banner"></image>
|
||||
</u-form-item>
|
||||
<u-form-item>
|
||||
<view class="shop-box">
|
||||
<text class="shop-name">{{shopInfo.shopName}}</text>
|
||||
<text v-if="shopInfo.region"><u-icon name="map" :size="26"></u-icon>{{shopInfo.region.province}}{{shopInfo.region.city}}{{shopInfo.region.region}}{{shopInfo.address}}</text>
|
||||
</view>
|
||||
</u-form-item>
|
||||
<u-form-item>
|
||||
<view class="shop-box">
|
||||
<text class="shop-name">站点简介</text>
|
||||
<text>{{shopInfo.summary}}</text>
|
||||
</view>
|
||||
</u-form-item>
|
||||
|
||||
|
||||
</u-form>
|
||||
</view>
|
||||
<!-- 操作按钮 -->
|
||||
<!-- <view class="footer">
|
||||
<view class="btn">
|
||||
<u-button type="primary" shape="circle">更新资料</u-button>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 表单字段元素
|
||||
const form = {
|
||||
// 入驻类型 (合伙人10001,配送员10002,社区门店10003,省代10004)
|
||||
grade_id: 10004,
|
||||
company: '',
|
||||
real_name: '',
|
||||
phone: '',
|
||||
mobile: '',
|
||||
region: [],
|
||||
detail: '',
|
||||
}
|
||||
|
||||
import * as UserApi from '@/api/user'
|
||||
import SelectRegion from '@/components/select-region/select-region'
|
||||
export default {
|
||||
components: {
|
||||
SelectRegion
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form,
|
||||
disabled: false,
|
||||
imageList: [],
|
||||
shopInfo: {},
|
||||
applyInfo: {}
|
||||
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.getUserInfo()
|
||||
},
|
||||
methods: {
|
||||
// 获取当前用户信息
|
||||
getUserInfo() {
|
||||
const app = this
|
||||
UserApi.info().then(result => {
|
||||
app.shopInfo = result.data.shopInfo
|
||||
app.applyInfo = result.data.applyInfo
|
||||
})
|
||||
},
|
||||
groupChange(){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.partner {
|
||||
.banner {
|
||||
padding-top: 20rpx;
|
||||
width: 100%;
|
||||
}
|
||||
.form-wrapper {
|
||||
margin: 20rpx auto 20rpx auto;
|
||||
padding: 0 40rpx;
|
||||
width: 94%;
|
||||
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 16rpx;
|
||||
background: #fff;
|
||||
.shop-box{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.shop-name{
|
||||
font-weight: bold;
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
.logo{
|
||||
width: 100rpx;
|
||||
}
|
||||
.shipin{
|
||||
width: 400rpx;
|
||||
}
|
||||
}
|
||||
.footer{
|
||||
width: 500rpx;
|
||||
margin: 20rpx auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user