websoft-uniapp仓库模板
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

772 lines
16 KiB

<template>
<view class="container">
<!-- <view class="merchant-name">{{ merchant.merchantName }}</view> -->
<uv-tabs :list="list" :itemStyle="{height: '58px'}" :activeStyle="{ color: '#2ba91c'}" lineColor="#2ba91c"
:inactiveStyle="{ color: '#808080' }"></uv-tabs>
<view class="uni-padding-wrap uni-common-mt">
<uni-segmented-control :current="current" :values="items" activeColor="#2ba91c" inActiveColor="#ff0000"
@clickItem="onClickItem" />
</view>
<view class="uni-badge-wrap">
<view class="badge-item">
<uv-badge :isDot="true" type="blank"></uv-badge>
<text class="web-text-secondary">可预约</text>
</view>
<view class="badge-item">
<uv-badge :isDot="true" type="info"></uv-badge>
<text class="web-text-secondary">已出售</text>
</view>
<view class="badge-item">
<uv-badge :isDot="true" type="success"></uv-badge>
<text class="web-text-secondary">我的选择</text>
</view>
<view class="badge-item">
<uv-badge :isDot="true" type="warning"></uv-badge>
<text class="web-text-secondary">已预定半场</text>
</view>
<!-- error | warning | success | primary | info -->
</view>
{{ order }}
<view class="checkout-body web-text-primary">
<template v-for="(item,index) in periodList" :key="index">
<view class="period-item">
<view class="period">{{ item.timePeriod }}</view>
<view class="field-list">
<template v-for="(item2,index2) in fieldList" :key="index2">
<view class="field" :class="isActive(`${item.periodId}_${item2.fieldId}`) ? 'active web-bg-success' : ''" @click="onField(index,index2)">
<text class="field-name">{{ item2.fieldName }}</text>
<text class="price">{{ item.price }}元</text>
</view>
</template>
</view>
</view>
</template>
<!-- 排版样式备份 -->
<view class="period-item" style="display: none;">
<view class="period">18:00 - 20:00</view>
<view class="field-list">
<view class="field web-bg-info">
<text class="field-name">1号场地</text>
<text class="price">580元</text>
</view>
<view class="field web-bg-success active">
<text class="field-name">2号场地</text>
<text class="price">580元</text>
</view>
<view class="field web-bg-warning">
<text class="field-name">3号场地</text>
<text class="price">580元</text>
</view>
</view>
</view>
</view>
</view>
<view class="checkout-car">
<view class="car-selected">
<uv-icon name="shopping-cart" size="36" color="#ffffff"></uv-icon>
<uv-badge type="error" max="99" :value="order.length"></uv-badge>
<!-- <text>已选</text> -->
</view>
<view class="car-total">
<text style="color: #ebcf00;">¥</text>
<uv-count-to :startVal="0" decimals="2" duration="100" color="#ebcf00" bold :endVal="total"></uv-count-to>
</view>
<uv-button class="save-btn"
:customStyle="{background: 'linear-gradient(to right, #70b915, #008e04)',borderRadius: '0 30px 30px 0',color: '#ffffff', order: 'none', padding: '22px 30px'}"
text="去支付" @click="save"></uv-button>
</view>
<!-- 登录组件 -->
<ws-login ref="login" :logo="logo" @done="reload" />
</template>
<script>
import * as GoodsApi from '@/api/shop/goods';
import * as Api from '@/api/layout';
import * as MerchantApi from '@/api/shop/merchant';
import * as MpMenuApi from '@/api/cms/mp-menu/index';
import * as FieldApi from '@/api/booking/field';
import * as PeriodApi from '@/api/booking/period';
import {
useTenantStore
} from '@/store/modules/tenant';
const tenantStore = useTenantStore();
const lineBg =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAOCAYAAABdC15GAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAFxSURBVHgBzZNRTsJAEIb/WTW+lpiY+FZPIDew3ABP4GJ8hxsI9zBpOYHeQDwBPQI+mRiRvpLojtPdYhCorQqF/6GdbGd2vvwzBXZcNAt4oj1ANeUoAT5iqkUjbEFLHNmhD1YPEvpZ3ghkGlVDCkc94/BmHMq998I5ONiY1ZBfpKAyuOtgAc5yOEDmYEWNh32BHF91sGHZHmwW4azciN9aQwnz3SJEgOmte+R2tdLprTYoa50mvuomlLpD4Y3oQZnov6D2RzCqI93bWOHaEmAGqQUyRBlZR1WfarcD/EJ2z8DtzDGvsMCwpm8XOCfDUsVOCYhiqRxI/CTQo4UOvjzO7Pow18vfywneuUHHUUxLn55lLw5JFpZ8bEUcY8oXdOLWiHLTxvoGpLqoUmy6dBT15o/ox3znpoycAmxUsiJTbs1cmxeVKp+0zmFIS7bGWiVghC7Vwse8jFKAX9eljh4ggKLLv7uaQvG9/F59Oo2SouxPu7OTCxN/s8wAAAAASUVORK5CYII=";
export default {
data() {
return {
id: 0,
list: [{
name: '周三',
value: '05月08日'
}, {
name: '周四',
value: '05月09日'
}, {
name: '周五',
value: '05月10日'
}, {
name: '周六',
value: '05月11日'
}, {
name: '周日',
value: '05月12日'
}, {
name: '周一',
value: '05月13日'
}, {
name: '周二',
value: '05月14日'
}],
week: 0,
items: ['全场', '半场'],
lineBg: lineBg,
// 时段
periodList: [],
// 场地
fieldList: [],
order: [],
// 订单总金额
total: 0,
keys: [],
// 场馆列表
merchant: {},
// 网站参数
fields: {},
// 幻灯片广告
ads: [],
// 小程序导航图标
navigation: [],
// 小程序导航图标(双排)
doubleNavigation: [],
isLogin: false,
disabled: false,
styleType: {
color: '#ff0000',
},
activeColor: {
color: '#303133',
}
}
},
onLoad(option) {
this.id = option.id
this.reload();
},
computed: {
total() {
const app = this
app.total = 0
app.order.map(d => {
console.log(d.totalPrice);
app.total = app.total + d.totalPrice
})
return app.total;
},
},
methods: {
async reload() {
const app = this
// 获取服务租户信息包
const info = await tenantStore.fetchTenantInfo();
// 登录状态
if (uni.getStorageSync('user_id') && uni.getStorageSync('access_token')) {
app.isLogin = true;
}
// 解析网站参数
if (info.fields) {
info.fields.map(d => {
const key = d.name;
app.fields[key] = d.value;
})
}
if (info.serverTime) {
this.week = info.serverTime.week
}
// 解析幻灯片数据
// if (info.ads) {
// const ad = info.ads.filter(d => d.adType == '幻灯片');
// const adsList = JSON.parse(ad[0].images);
// adsList.map(d => {
// app.ads.push(d.url);
// });
// }
// 解析网站logo
if (info.websiteLogo) {
uni.setStorageSync('app_logo', info.websiteLogo)
app.logo = info.websiteLogo
}
// 解析小程序导航图标
if (info.mpMenus) {
console.log('info.mpMenus: ', info.mpMenus);
const arr = info.mpMenus.filter(d => d.type == 2 && d.rows == 0)
const arr1 = info.mpMenus.filter(d => (d.type == 2 && d.rows == 1))
const arr2 = info.mpMenus.filter(d => (d.type == 2 && d.rows == 2))
if (arr) {
app.navigation = arr
}
if (arr1) {
app.doubleNavigation.push(arr1)
}
if (arr2) {
app.doubleNavigation.push(arr2)
}
}
// 请求数据
Promise.all([app.getMerchant(), app.getBookingField(), app.getBookingPeriod()])
.then((res) => {
app.merchant = res[0];
console.log('Promise.all', app.merchant);
})
},
getSiteInfo() {
const app = this
return new Promise((resolve, reject) => {
Api.getSiteInfo()
.then(result => {
resolve(result)
})
.catch(reject)
})
},
onDisabled() {
this.disabled = !this.disabled;
},
navTo(url) {
uni.navigateTo({
url
})
},
listAdList() {
},
pageGoods() {
const app = this
return new Promise((resolve, reject) => {
GoodsApi.pageGoods({})
.then(result => {
resolve(result.list)
})
.catch(reject)
})
},
getMerchantList() {
const app = this
return new Promise((resolve, reject) => {
MerchantApi.listMerchant({})
.then(result => {
resolve(result)
})
.catch(reject)
})
},
getMerchant() {
MerchantApi.getMerchant(this.id).then(data => {
app.merchant = data
if (data.files) {
app.ads = JSON.parse(data.files)
}
uni.setNavigationBarTitle({
title: data.merchantName
})
})
},
getBookingField() {
FieldApi.listField({
merchantId: this.id,
isStatus: 1
}).then(list => {
this.fieldList = list;
})
},
getBookingPeriod() {
const {
week
} = this
const merchantId = this.id
const isStatus = 1
PeriodApi.listPeriod({
merchantId,
isStatus,
week
}).then(list => {
this.periodList = list;
})
},
change(e) {
const {
index
} = e.detail;
const id = this.merchant[index].merchantId
this.openUrl(`/package/booking/booking?id=${id}`)
},
callPhone(phone) {
uni.makePhoneCall({
phoneNumber: phone
});
},
onMap() {
uni.getLocation({
type: 'gcj02', //返回可以用于uni.openLocation的经纬度
success: function(res) {
console.log('返回可以用于uni.openLocation的经纬度: ', res);
const latitude = this.merchant.latitude;
const longitude = this.merchant.longitude;
uni.openLocation({
latitude: latitude,
longitude: longitude,
success: function() {
console.log('success');
}
});
}
});
},
openUrl(url) {
if (!this.isLogin) {
this.$refs.login.open('bottom')
return false;
} else {
uni.navigateTo({
url
});
}
},
onField(i,i2) {
const app = this
const p = this.periodList[i]
const f = this.fieldList[i2]
const key = `${p.periodId}_${f.fieldId}`
const index = app.order.findIndex(d => d.key == key)
console.log('index: ',index);
console.log('app.order.length: ',app.order.length);
if(index >= 0){
app.order.splice(index,1)
}else{
if(app.order.length > 1){
uni.showToast({
title: '最多预定两个场地!',
icon: 'none'
})
return false
}
// 添加到购物车
app.order.push({
key,
fid: f.fieldId,
pid: p.periodId,
totalPrice: p.price
})
}
// this.periodList[i].key = key
// this.fieldList[i2].key = key
// console.log('this.: ',this.fieldList[i2]);
// if(!f.selected){
// app.fieldList[i].key = key
// app.order.push({
// key: key,
// fid: f.fieldId,
// pid: p.periodId
// })
// }else{
// app.fieldList[i].key = undefined
// const index = app.order.filter((d) => d.fid == f.fid && d.pid == p.pid)
// app.order.splice(index,1)
// }
// f.selected = !f.selected
},
isActive(text){
const index = this.order.find(d => d.key == text)
if(index){
return true
}
},
save(){
uni.navigateTo({
url: '/package/booking/cashier'
})
}
}
}
</script>
<style>
page {
background-size: 100%;
background-repeat: no-repeat;
background-color: #f0f2f5;
width: 750rpx;
overflow-x: hidden;
}
</style>
<style lang="scss" scoped>
.container {}
.merchant-name {
padding: 30rpx;
font-weight: 500;
font-size: 42rpx;
background-color: #ffffff;
}
.checkout-car{
width: 700rpx;
left: 25rpx;
position: fixed;
bottom: 30rpx;
display: flex;
justify-content: space-between;
background-color: #000000;
border-radius: 100px;
align-items: center;
.car-selected{
color: #ccc;
display: flex;
align-items: center;
padding: 0 20rpx;
}
.car-total{
display: flex;
color: #ebcf00;
align-items: center;
.save-btn{
}
}
}
.booking-tel {
position: fixed;
z-index: 1;
top: 270px;
right: 0;
width: 80px;
height: 38px;
border-radius: 50px 0 0 50px;
background: linear-gradient(to right, #ccff66, #008e04);
display: flex;
align-items: center;
justify-content: center;
color: #ffffff;
font-size: 26rpx;
}
.popup-booking-tel {
background-color: #ffffff;
width: 560rpx;
min-height: 400rpx;
border-radius: 20rpx;
margin: auto;
padding: 20px;
z-index: 9999;
display: flex;
flex-direction: column;
.title {
font-weight: bold;
font-size: 38rpx;
text-align: center;
padding: 10px 0;
}
.desc {
line-height: 2rem;
}
}
.uni-padding-wrap {
width: 180rpx;
margin: 20rpx auto;
}
.uni-badge-wrap {
display: flex;
justify-content: space-around;
.badge-item {
display: flex;
justify-content: center;
align-items: center;
font-size: 28rpx;
text {
padding: 2rpx;
}
.web-text-secondary {
padding-left: 8rpx;
}
}
}
.checkout-body {
padding: 20rpx;
.period-item {
margin: 12rpx 0;
.period {
line-height: 2rem;
padding-left: 12rpx;
font-size: 28rpx;
}
.field-list {
display: flex;
flex-wrap: wrap;
.web-bg-info {
// color: #cccccc !important;
background-color: #e6e6e6 !important;
// border: none !important;
}
.web-bg-success {
// color: #ffffff !important;
// background-color: #2ba91c !important;
// border: none !important;
color: #2ba91c !important;
border: 1px solid #2ba91c !important;
}
.web-bg-warning {
// color: #ffffff !important;
// background-color: #8fe01e !important;
// border: none !important;
background-color: #c9e294 !important;
}
.active {
&:before {
border-radius: 0 0 12rpx 0;
content: "";
position: absolute;
right: 0;
bottom: 0;
border: 24rpx solid #2ba91c;
border-top-color: transparent;
border-left-color: transparent;
}
&:after {
content: "";
width: 5px;
height: 10px;
position: absolute;
right: 3px;
bottom: 4px;
border: 1px solid #fff;
border-top-color: transparent;
border-left-color: transparent;
transform: rotate(45deg);
border-radius: 4rpx;
}
}
.field {
width: 118rpx;
height: 118rpx;
margin: 9rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 16rpx;
line-height: 1.3rem;
position: relative;
color: #333333;
background-color: #ffffff;
border: 1px solid #808080;
.field-name {
font-size: 23rpx;
}
.price {
font-size: 25rpx;
}
}
}
}
}
.xieyi {
margin: 30rpx auto;
padding: 20rpx 30rpx;
.text {
margin-left: 5rpx;
.link {
color: #0f80ff;
}
}
}
// .segmented {
// display: block;
// justify-content: space-around;
// text-align: center;
// width: 200rpx;
// margin: auto;
// color: #ffffff;
// .item {
// color: #666;
// font-size: 28rpx;
// padding: 0 12rpx;
// }
// .active {
// color: #333;
// font-size: 30rpx;
// font-weight: 500;
// }
// }
.user-oreder {
padding: 16px 0;
.web-cell-content {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.web-text-center {
text-align: center;
}
}
.card-title {
width: 700rpx;
margin: 12rpx auto;
font-size: 38rpx;
font-weight: 500;
margin-top: 32rpx;
}
.merchant-card-title {
width: 700rpx;
margin: 12rpx auto;
font-size: 40rpx;
font-weight: 500;
margin-top: 32rpx;
}
.card-body {
width: 740rpx;
margin: auto;
.merchant-card {
margin: 12rpx auto;
background: #ffffff;
border-radius: 10rpx;
border-color: slategrey;
border-radius: 16rpx;
.merchant-image {
width: 200rpx;
border-radius: 16rpx 16rpx 0 0;
height: 140rpx !important;
}
.merchant-name {
padding: 12rpx;
font-weight: 500;
font-size: 26rpx;
text-align: center;
}
.merchant-desc {
width: 400rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
@mixin flex($direction: row) {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: $direction;
}
.navigation {
padding: 0 30rpx 0 30rpx;
}
.scroll-list {
@include flex(column);
&__item {
margin-right: 20px;
&__image {
width: 60px;
height: 60px;
border-radius: 4px;
}
&__text {
color: $uni-text-color-placeholder;
text-align: center;
font-size: 12px;
margin-top: 5px;
}
}
&__line {
@include flex;
margin-top: 10px;
&__item {
margin-right: 30px;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
&__image {
width: 61px;
height: 48px;
}
&__text {
margin-top: 5px;
color: $uni-text-color-placeholder;
font-size: 12px;
text-align: center;
}
&--no-margin-right {
margin-right: 0;
}
}
}
&__line__item__text {
white-space: nowrap;
}
}
</style>