This commit is contained in:
2025-03-20 10:58:18 +08:00
parent 4d21314fc6
commit ce0ab24c57
24 changed files with 791 additions and 138 deletions
+2 -2
View File
@@ -2,6 +2,6 @@ VITE_APP_NAME=后台管理系统
VITE_SOCKET_URL=wss://server.gxwebsoft.com VITE_SOCKET_URL=wss://server.gxwebsoft.com
VITE_SERVER_URL=https://gxtyzx-server.websoft.top/api VITE_SERVER_URL=https://gxtyzx-server.websoft.top/api
VITE_API_URL=https://gxtyzx-modules.websoft.top/api VITE_API_URL=https://gxtyzx-modules.websoft.top/api
VITE_THINK_URL=https://gxtyzx-api.websoft.top/api #VITE_THINK_URL=https://gxtyzx-api2.websoft.top/api
#VITE_THINK_URL=http://127.0.0.1:9099/api VITE_THINK_URL=http://127.0.0.1:9099/api
+1 -1
View File
@@ -2,4 +2,4 @@ VITE_APP_NAME=后台管理系统
VITE_SOCKET_URL=wss://server.gxwebsoft.com VITE_SOCKET_URL=wss://server.gxwebsoft.com
VITE_SERVER_URL=https://gxtyzx-server.websoft.top/api VITE_SERVER_URL=https://gxtyzx-server.websoft.top/api
VITE_API_URL=https://gxtyzx-modules.websoft.top/api VITE_API_URL=https://gxtyzx-modules.websoft.top/api
VITE_THINK_URL=https://gxtyzx-api.websoft.top/api VITE_THINK_URL=https://gxtyzx-api2.websoft.top/api
+10
View File
@@ -124,3 +124,13 @@ export async function thinkOrderRepay(data: ThinkOrder) {
} }
return Promise.reject(new Error(res.data.message)); return Promise.reject(new Error(res.data.message));
} }
export async function thinkOrderCheckCode(data: ThinkOrder) {
const res = await request.post<ApiResult<ThinkOrder>>(
THINK_API_URL + '/think/think-order/check-code', data
);
if (res.data.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.data.message));
}
+10
View File
@@ -124,3 +124,13 @@ export async function thinkUsersVipLog(id: number) {
} }
return Promise.reject(new Error(res.data.message)); return Promise.reject(new Error(res.data.message));
} }
export async function thinkUsersVipCode(id: number) {
const res = await request.get<ApiResult<any[]>>(
THINK_API_URL + `/think/think-users-vip/code/${id}`
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
+80 -10
View File
@@ -2,7 +2,8 @@
<view class="container"> <view class="container">
<uv-sticky bg-color="white"> <uv-sticky bg-color="white">
<view class="merchant-name">{{ merchant.name }}</view> <view class="merchant-name">{{ merchant.name }}</view>
<uv-tabs :list="next7day" :itemStyle="{height: '58px'}" :activeStyle="{ color: '#2ba91c'}" lineColor="#2ba91c" <uv-tabs :current="activeIndex" :list="next7day" :itemStyle="{height: '58px'}" :activeStyle="{ color: '#2ba91c'}"
lineColor="#2ba91c"
:inactiveStyle="{ color: '#808080' }" @change="onDateTime"></uv-tabs> :inactiveStyle="{ color: '#808080' }" @change="onDateTime"></uv-tabs>
</uv-sticky> </uv-sticky>
<template v-if="merchantId !== 37"> <template v-if="merchantId !== 37">
@@ -178,7 +179,9 @@ export default {
disabled: false, disabled: false,
// 购物车信息 // 购物车信息
showCarInfo: false, showCarInfo: false,
timeList: [] timeList: [],
timeListOrigin: [],
activeIndex: 0
} }
}, },
onLoad(option) { onLoad(option) {
@@ -200,7 +203,7 @@ export default {
else totalPrice += d.price else totalPrice += d.price
}) })
carStore.totalPrice = totalPrice carStore.totalPrice = totalPrice
console.log('totalPrice: ', totalPrice); // console.log('totalPrice: ', totalPrice);
return totalPrice; return totalPrice;
}, },
carNum() { carNum() {
@@ -260,7 +263,7 @@ export default {
setDateList() { setDateList() {
this.next7day = [] this.next7day = []
let day = 7 let day = 7
if (this.merchantId === 37) day = 7 if (this.merchantId === 37) day = 1
for (let i = 0; i < day; i++) { for (let i = 0; i < day; i++) {
const day = dayjs().add(i, 'day') const day = dayjs().add(i, 'day')
this.next7day.push({ this.next7day.push({
@@ -275,25 +278,92 @@ export default {
}, },
async getTimeList() { async getTimeList() {
this.timeList = await listThinkSiteTime({sid: this.merchantId}) this.timeList = await listThinkSiteTime({sid: this.merchantId})
// console.log(this.week)
// console.log(this.dateTime)
this.timeListOrigin = JSON.parse(JSON.stringify(this.timeList))
this.timeList = this.timeList.filter(item => {
return JSON.parse(item.week).map(Number).includes(parseInt(this.week))
})
console.log(this.timeList)
this.makeTimeList() this.makeTimeList()
}, },
makeTimeList() { makeTimeList() {
this.periodList = [] this.periodList = []
this.timeList.forEach(item => { this.timeListOrigin.forEach(item => {
const weekList = JSON.parse(item.week) const weekList = JSON.parse(item.week)
if (parseInt(this.merchantId) === 37) { if (parseInt(this.merchantId) === 37) {
const today = dayjs().format('YYYY-MM-DD') const today = dayjs().format('YYYY-MM-DD')
if (dayjs().isBefore(dayjs(today + ' 21:00:00')) || dayjs(this.dateTime).isAfter(dayjs())) this.periodList.push(item) if ((dayjs().isBefore(dayjs(today + ' 21:00:00')) || dayjs(this.dateTime).isAfter(dayjs())) && weekList.includes(this.week)) this.periodList.push(item)
} else { } else {
// console.log(this.dateTime + ' ' + item.timePeriod.split(' - ')[0])
// console.log(dayjs().isBefore(dayjs(this.dateTime + ' ' + item.timePeriod.split(' - ')[0])))
if (weekList.includes(this.week) && dayjs().isBefore(dayjs(this.dateTime + ' ' + item.timePeriod.split(' - ')[0]))) this.periodList.push(item) if (weekList.includes(this.week) && dayjs().isBefore(dayjs(this.dateTime + ' ' + item.timePeriod.split(' - ')[0]))) this.periodList.push(item)
} }
}) })
// console.log(this.periodList) const month = dayjs().format('YYYY-MM')
this.periodList.map(item => {
if (item.prices && item.prices.includes('{')) {
const dataList = JSON.parse(item.prices)[month]
if (dataList) {
const price = dataList[dayjs(this.dateTime).format('D') - 1]
if (price && price !== '') {
item.price = price
}
}
}
if (item.halfPrices && item.halfPrices.includes('{')) {
const dataList = JSON.parse(item.halfPrices)[month]
if (dataList) {
const price = dataList[dayjs(this.dateTime).format('D') - 1]
if (price && price !== '') {
item.halfPrices = price
}
}
}
return item
})
}, },
onDisabled() { onDisabled() {
this.disabled = !this.disabled; this.disabled = !this.disabled;
}, },
onDateTime(e) { onDateTime(e) {
this.periodList = []
if (![37, 44, 32].includes(this.merchantId)) {
const date = dayjs().format('d')
const hour = dayjs().format('H')
const clickedDate = dayjs(e.dateTime).format('d')
if ([0, 5, 6].includes(parseInt(clickedDate))) {
if ([1, 2, 3].includes(parseInt(date))) {
return uni.showModal({
showCancel: false,
title: '周末场地需要周四17点后才能预定。',
})
} else if (parseInt(date) === 4) {
if (parseInt(hour) < 17) {
return uni.showModal({
showCancel: false,
title: '周末场地需要周四17点后才能预定。',
})
}
} else if ([0, 5, 6].includes(parseInt(date))) {
const diff = dayjs(e.dateTime).diff(dayjs(), 'day')
if (diff > 2) {
return uni.showModal({
showCancel: false,
title: '周末场地需要周四17点后才能预定。',
})
}
}
}
if (hour < 8 || hour === 23) {
return uni.showModal({
showCancel: false,
title: '场地预定时间为:8:00-23:00。',
})
}
}
this.activeIndex = e.index
this.week = e.week this.week = e.week
this.dateTime = e.dateTime this.dateTime = e.dateTime
this.makeTimeList() this.makeTimeList()
@@ -348,7 +418,7 @@ export default {
const checkTimePeriod = field.periodVoList.find(d => (d.period === timePeriod && d.id === item.id)) const checkTimePeriod = field.periodVoList.find(d => (d.period === timePeriod && d.id === item.id))
// console.log('here', field, item) // console.log('here', field, item)
// 已被预定 // 已被预定
if (checkTimePeriod.sold) { if (checkTimePeriod.sold || checkTimePeriod.took) {
return return
} }
const app = this const app = this
@@ -420,7 +490,7 @@ export default {
const timePeriod = item.timePeriod const timePeriod = item.timePeriod
const checkTimePeriod = field.periodVoList.find(d => (d.period === timePeriod && d.id === item.id)) const checkTimePeriod = field.periodVoList.find(d => (d.period === timePeriod && d.id === item.id))
// console.log('checkTimePeriod', checkTimePeriod, timePeriod) // console.log('checkTimePeriod', checkTimePeriod, timePeriod)
if (checkTimePeriod && checkTimePeriod.sold) { if (checkTimePeriod && (checkTimePeriod.sold || checkTimePeriod.took)) {
if (item.isHalf === 1) { if (item.isHalf === 1) {
return 'web-bg-warning' return 'web-bg-warning'
} }
@@ -439,7 +509,7 @@ export default {
uni.navigateTo({ uni.navigateTo({
url: '/package/booking/confirm', url: '/package/booking/confirm',
success: (res) => { success: (res) => {
console.log(this.selection) // console.log(this.selection)
res.eventChannel.emit('data', this.selection) res.eventChannel.emit('data', this.selection)
} }
}) })
+5 -2
View File
@@ -262,8 +262,8 @@ export default {
this.userInfo = await userStore.fetchUserInfo(); this.userInfo = await userStore.fetchUserInfo();
eventChannel.on('data', async (data) => { eventChannel.on('data', async (data) => {
_this.list = data _this.list = data
if (data[0].isHalf === 1) _this.payPrice = data.reduce((a, b) => a + b.halfPrice, 0) if (data[0].isHalf === 1) _this.payPrice = data.reduce((a, b) => a + parseFloat(b.halfPrice), 0)
else _this.payPrice = data.reduce((a, b) => a + b.price, 0) else _this.payPrice = data.reduce((a, b) => a + parseFloat(b.price), 0)
_this.originPrice = JSON.parse(JSON.stringify(_this.payPrice)) _this.originPrice = JSON.parse(JSON.stringify(_this.payPrice))
const thinkOrderInfos = [] const thinkOrderInfos = []
@@ -294,6 +294,7 @@ export default {
code: null, code: null,
payType: 1, payType: 1,
thinkOrderInfos, thinkOrderInfos,
day: dayjs(item.dateTime).format('D') - 1,
startTime: thinkOrderInfos.map(item => item.startTime).join() startTime: thinkOrderInfos.map(item => item.startTime).join()
} }
}) })
@@ -558,10 +559,12 @@ export default {
async onPayType(index) { async onPayType(index) {
// app.payType = index; // app.payType = index;
this.form.payType = index; this.form.payType = index;
console.log(this.form.payType)
this.form.vid = null this.form.vid = null
this.form.code = null this.form.code = null
this.reducePrice = 0 this.reducePrice = 0
if (this.form.sid !== 37) this.payPrice = this.originPrice if (this.form.sid !== 37) this.payPrice = this.originPrice
else this.reCalSwimAmount({value: this.peopleNum})
if (this.form.payType === 2) this.makeUserVipCardList() if (this.form.payType === 2) this.makeUserVipCardList()
if (this.form.payType === 5) this.makeUserCardList() if (this.form.payType === 5) this.makeUserCardList()
}, },
+9 -1
View File
@@ -85,7 +85,7 @@
<uv-popup ref="protocolPopup" mode="center" round="15" :closeOnClickOverlay="true" :safe-area-inset-bottom="false"> <uv-popup ref="protocolPopup" mode="center" round="15" :closeOnClickOverlay="true" :safe-area-inset-bottom="false">
<view v-if="protocol"> <view v-if="protocol">
<view class="p-30" style="width: 80vw; max-height: 80vh; overflow-y: scroll"> <view class="p-30" style="width: 80vw; max-height: 80vh; overflow-y: scroll">
<uv-parse :content="protocol.content"></uv-parse> <uv-parse :content="protocol.content" :preview-img="false"></uv-parse>
</view> </view>
<view class="p-30"> <view class="p-30">
<uv-button type="primary" shape="circle" :disabled="countDown > 0" @click="save">{{ <uv-button type="primary" shape="circle" :disabled="countDown > 0" @click="save">{{
@@ -107,6 +107,7 @@ import request from "@/utils/request";
import X2js from 'x2js'; import X2js from 'x2js';
import {getArticle, pageArticle} from "@/api/cms/article"; import {getArticle, pageArticle} from "@/api/cms/article";
import coordtransform from "coordtransform"; import coordtransform from "coordtransform";
import dayjs from "dayjs";
const carStore = useCarStore(); const carStore = useCarStore();
@@ -151,6 +152,13 @@ export default {
} }
}, },
openProtocol() { openProtocol() {
const hour = dayjs().format('H')
if (hour < 8 || hour === 23) {
return uni.showModal({
showCancel: false,
title: '场地预定时间为:8:00-23:00。',
})
}
if (this.timer) { if (this.timer) {
clearInterval(this.timer) clearInterval(this.timer)
this.timer = null this.timer = null
+9 -2
View File
@@ -305,14 +305,21 @@ export default {
}); });
setTimeout(function () { setTimeout(function () {
app.disabled = false; app.disabled = false;
uni.redirectTo({ uni.setStorageSync('orderType', JSON.stringify({
url: '/package/user/card' label: '会员卡订单',
value: 1
}))
uni.switchTab({
url: '/pages/order'
}); });
}, 500); }, 500);
}, },
fail: function (err) { fail: function (err) {
console.log('支付失败', err); console.log('支付失败', err);
app.disabled = false; app.disabled = false;
uni.switchTab({
url: '/pages/order'
});
} }
}); });
uni.hideLoading(); uni.hideLoading();
+45 -16
View File
@@ -1,5 +1,30 @@
<template> <template>
<view class="container"> <view class="container">
<uni-card :border="false" :is-shadow="false" v-if="needExpress">
<uv-cell v-if="address && address.name"
:title="`${address.name} &nbsp; ${address.phone}`"
:label="`${address.address}`"
icon="map"
:cellStyle="{ padding: '5px 0' }"
:border="false"
@click="openAddressList"
>
<template v-slot:right-icon>
<uv-icon name="arrow-right"></uv-icon>
</template>
</uv-cell>
<uv-cell v-else
title="点击添加地址"
icon="map"
:cellStyle="{ padding: '5px 0' }"
:border="false"
@click="openAddressList"
>
<template v-slot:right-icon>
<uv-icon name="arrow-right"></uv-icon>
</template>
</uv-cell>
</uni-card>
<uni-card :border="false" :padding="10"> <uni-card :border="false" :padding="10">
<uv-cell-group :customStyle="{backgroundColor: '#ffffff', marginBottom: '20px'}" :border="false"> <uv-cell-group :customStyle="{backgroundColor: '#ffffff', marginBottom: '20px'}" :border="false">
<uv-cell v-for="(cart, index) in carts" :cellStyle="{padding: '12px 0'}" :border="false" :index="index"> <uv-cell v-for="(cart, index) in carts" :cellStyle="{padding: '12px 0'}" :border="false" :index="index">
@@ -216,6 +241,7 @@ import UniCard from "@/uni_modules/uni-card/components/uni-card/uni-card.vue";
import UvGap from "@/uni_modules/uv-gap/components/uv-gap/uv-gap.vue"; import UvGap from "@/uni_modules/uv-gap/components/uv-gap/uv-gap.vue";
import {addThinkGoodsOrder} from "@/api/think/thinkGoodsOrder"; import {addThinkGoodsOrder} from "@/api/think/thinkGoodsOrder";
import {getThinkUsers, thinkUserInfo} from "@/api/think/thinkUsers"; import {getThinkUsers, thinkUserInfo} from "@/api/think/thinkUsers";
import {pageThinkUsersAddress} from "@/api/think/thinkUsersAddress";
const mpStore = useMpStore(); const mpStore = useMpStore();
const userStore = useUserStore(); const userStore = useUserStore();
@@ -263,6 +289,7 @@ export default {
payPassword: '', payPassword: '',
canPointPay: false, canPointPay: false,
thinkUserInfo: {}, thinkUserInfo: {},
needExpress: false
}; };
}, },
onLoad(where) { onLoad(where) {
@@ -299,18 +326,21 @@ export default {
this.canPointPay = true this.canPointPay = true
this.totalPoint += parseInt(item.goods.maxIntegral) * item.cartNum this.totalPoint += parseInt(item.goods.maxIntegral) * item.cartNum
} }
if (item.goods.isFh === 1) this.needExpress = true
return item return item
}) })
this.totalPrice = app.carts.reduce((a, b) => a + b.price * b.cartNum, 0) this.totalPrice = app.carts.reduce((a, b) => a + b.price * b.cartNum, 0)
} }
}) })
this.getUserAddress()
UserAddressApi.pageUserAddress({ },
userId: uni.getStorageSync('user_id') getUserAddress(){
pageThinkUsersAddress({
uid: uni.getStorageSync('uid')
}).then((res) => { }).then((res) => {
app.addressList = res.list; this.addressList = res.list;
const arr = res.list.filter((d) => d.isDefault === true); const arr = res.list.filter((d) => d.isDefault === true);
app.address = arr[0]; this.address = arr[0];
}); });
}, },
onDisabled() { onDisabled() {
@@ -347,13 +377,9 @@ export default {
}) })
this.payType = index; this.payType = index;
}, },
openAddressList() { async openAddressList() {
if (this.deliveryType === 0) { this.getUserAddress()
this.$refs.userAddressForm.open('center'); this.$refs.userAddressForm.open('center');
}
if (this.deliveryType === 1) {
this.$refs.shopAddressForm.open('center');
}
}, },
// 弹出登录提示框 // 弹出登录提示框
openLogin() { openLogin() {
@@ -397,7 +423,10 @@ export default {
}, },
save() { save() {
const app = this; const app = this;
if (this.needExpress && !this.address.id) return uni.showToast({
title: '请选择收货地址',
icon: 'none'
})
if (!this.disabled) { if (!this.disabled) {
uni.showToast({ uni.showToast({
title: '请先阅读并同意服务协议', title: '请先阅读并同意服务协议',
@@ -421,9 +450,9 @@ export default {
}) })
}) })
addThinkGoodsOrder({ addThinkGoodsOrder({
name: '', name: this.address ? this.address.name : '' ,
phone: '', phone: this.address ? this.address.phone : '',
address: '', address: this.address ? `${this.address.region}${this.address.address}` : '',
totalPrice: this.totalPrice, totalPrice: this.totalPrice,
num: 1, num: 1,
payPrice: this.totalPrice, payPrice: this.totalPrice,
+8 -2
View File
@@ -36,7 +36,14 @@ const info = ref({})
const expired = ref(false) const expired = ref(false)
const getInfo = async (id) => { const getInfo = async (id) => {
info.value = await getThinkOrder(id) info.value = await getThinkOrder(id)
if (dayjs().isAfter(dayjs(info.value.startTime * 1000))) expired.value = true const date = dayjs(info.value.startTime * 1000).format('YYYY-MM-DD')
console.log(dayjs().isAfter(dayjs(`${date} 21:30:00`)))
if (info.value.sid === 37) {
if (dayjs().isAfter(dayjs(`${date} 21:30:00`))) expired.value = true
} else {
if (dayjs().isAfter(dayjs(info.value.startTime * 1000))) expired.value = true
}
console.log(expired.value)
} }
const userStore = useUserStore(); const userStore = useUserStore();
@@ -63,7 +70,6 @@ const checkAuth = async () => {
checkAuth() checkAuth()
const disabled = ref(false) const disabled = ref(false)
const doCheck = async () => { const doCheck = async () => {
+14 -8
View File
@@ -4,7 +4,7 @@
<!-- <uv-image :src="`${IMG_URL}${form.qrcode}`" width="200" height="200"/>--> <!-- <uv-image :src="`${IMG_URL}${form.qrcode}`" width="200" height="200"/>-->
<text class="text-25 mb-20 text-gray">{{ countDown }}秒后自动刷新</text> <text class="text-25 mb-20 text-gray">{{ countDown }}秒后自动刷新</text>
<uv-qrcode size="300px" :value="form.qrcode" v-if="form.qrcode" @click="getOrder"/> <uv-qrcode size="300px" :value="form.qrcode" v-if="form.qrcode" @click="getOrder"/>
<text class="web-text-secondary">核销码(每120秒刷新,点击二维码手动刷新)</text> <text class="web-text-secondary">核销码(每30秒刷新,点击二维码手动刷新)</text>
</view> </view>
<uni-card title="预定信息" :border="false" :is-shadow="false" :padding="0"> <uni-card title="预定信息" :border="false" :is-shadow="false" :padding="0">
<view class="order-body web-cell web-cell-align-top"> <view class="order-body web-cell web-cell-align-top">
@@ -39,9 +39,8 @@
<uv-cell-group :customStyle="{ backgroundColor: '#ffffff', padding: '8px 0' }" :border="false"> <uv-cell-group :customStyle="{ backgroundColor: '#ffffff', padding: '8px 0' }" :border="false">
<uv-cell :title="`姓名`" :value="`${form.name}`" :cellStyle="{ padding: '8px' }"/> <uv-cell :title="`姓名`" :value="`${form.name}`" :cellStyle="{ padding: '8px' }"/>
<uv-cell :title="`手机号码`" :value="`${form.phone}`" :cellStyle="{ padding: '8px' }"/> <uv-cell :title="`手机号码`" :value="`${form.phone}`" :cellStyle="{ padding: '8px' }"/>
<uv-cell :title="`订单号`" :value="`${form.id}`" :cellStyle="{ padding: '8px' }"/> <!-- <uv-cell :title="`订单号`" :value="`${form.id}`" :cellStyle="{ padding: '8px' }"/>-->
<uv-cell :title="`订单编号`" :value="`${form.orderNum}`" :cellStyle="{ padding: '8px' }" <uv-cell :title="`订单编号`" :value="`${form.orderNum}`" :cellStyle="{ padding: '8px' }"/>
" />
<uv-cell :title="`订单状态`" :cellStyle="{ padding: '8px' }"> <uv-cell :title="`订单状态`" :cellStyle="{ padding: '8px' }">
<template v-slot:value> <template v-slot:value>
<view v-if="form.payStatus === 2"> <view v-if="form.payStatus === 2">
@@ -143,7 +142,7 @@ export default {
colorIndex: 0, colorIndex: 0,
activeColor: '#108001', activeColor: '#108001',
styleType: 'text', styleType: 'text',
countDown: 120, countDown: 30,
interval: null interval: null
}; };
}, },
@@ -151,8 +150,7 @@ export default {
this.orderId = option.id; this.orderId = option.id;
// 判断是否登录 // 判断是否登录
this.openLogin(); this.openLogin();
// 加载数据
this.reload();
}, },
onShow() { onShow() {
// 判断是否登录 // 判断是否登录
@@ -202,11 +200,13 @@ export default {
this.$refs.login.open('bottom'); this.$refs.login.open('bottom');
return false; return false;
} }
// 加载数据
this.reload();
}, },
async getOrder() { async getOrder() {
const app = this const app = this
if (this.interval) clearInterval(this.interval); if (this.interval) clearInterval(this.interval);
this.countDown = 120 this.countDown = 30
OrderApi.getThinkOrder(this.orderId).then((data) => { OrderApi.getThinkOrder(this.orderId).then((data) => {
app.form = data; app.form = data;
// 页面标题 // 页面标题
@@ -257,6 +257,12 @@ export default {
}) })
} }
},
onHide() {
if (this.interval) clearInterval(this.interval);
},
onUnload() {
if (this.interval) clearInterval(this.interval);
} }
}; };
</script> </script>
-32
View File
@@ -135,38 +135,6 @@ export default {
} }
], ],
regions, regions,
dataTree: [{
text: "一年级",
value: "1-0",
children: [{
text: "1.1班",
value: "1-1"
},
{
text: "1.2班",
value: "1-2"
}
]
},
{
text: "二年级",
value: "2-0",
children: [{
text: "2.1班",
value: "2-1"
},
{
text: "2.2班",
value: "2-2"
}
]
},
{
text: "三年级",
value: "3-0",
disable: true
}
],
rules: { rules: {
// 对name字段进行必填验证 // 对name字段进行必填验证
name: { name: {
+46 -6
View File
@@ -7,10 +7,13 @@
:style="{ background: `url(https://oss.wsdns.cn/20240920/5e3327e1ad97472e942c824ab1776f52.jpg?x-oss-process=image/resize,m_fixed,w_750/quality,Q_90) no-repeat center center`, backgroundSize: '100%', opacity: '0.85' }"> :style="{ background: `url(https://oss.wsdns.cn/20240920/5e3327e1ad97472e942c824ab1776f52.jpg?x-oss-process=image/resize,m_fixed,w_750/quality,Q_90) no-repeat center center`, backgroundSize: '100%', opacity: '0.85' }">
<view class="content web-cell web-cell-align-top"> <view class="content web-cell web-cell-align-top">
<view class="card-info web-cell-content"> <view class="card-info web-cell-content">
<view class="title-bar"> <view class="title-bar w-100p">
<view class="web-text-heading" style="color: #ffffff; font-size: 17px; font-weight: 600">{{ <view class="flex justify-between items-center w-90p">
form.name <view class="web-text-heading" style="color: #ffffff; font-size: 17px; font-weight: 600">{{
}} form.name
}}
</view>
<uv-icon v-if="(form.type === 1 || form.type === 3) && form.sid.includes('37')" @click="doShowCode" size="60rpx" name="https://oss.wsdns.cn/20250108/80f2256ffd2a4b0ca09d18c44ab37a41.png"/>
</view> </view>
<view class="desc" style="font-size: 14px">{{ cardType[form.type] }}</view> <view class="desc" style="font-size: 14px">{{ cardType[form.type] }}</view>
<view class="mt-20" v-if="form.expireTime"> <view class="mt-20" v-if="form.expireTime">
@@ -30,6 +33,14 @@
<ws-login ref="login" :logo="logo" @done="reload"/> <ws-login ref="login" :logo="logo" @done="reload"/>
</view> </view>
<view class="card m-20" v-if="showCode && (form.type === 1 || form.type === 3) && form.sid.includes('37')">
<view class="qrcode">
<text class="text-25 mb-20 text-gray">{{ countDown }}秒后自动刷新</text>
<uv-qrcode size="300px" :value="code" v-if="code" @click="getCode"/>
<text class="web-text-secondary">会员码(每30秒刷新,点击二维码手动刷新)</text>
</view>
</view>
<uni-card :border="false" :is-shadow="false" :padding="'12px 0'"> <uni-card :border="false" :is-shadow="false" :padding="'12px 0'">
<view class="money-bar web-cell"> <view class="money-bar web-cell">
<view class="money-item web-cell-content"> <view class="money-item web-cell-content">
@@ -112,7 +123,7 @@
</template> </template>
<script> <script>
import {getThinkUsersVip} from "@/api/think/thinkUsersVip"; import {getThinkUsersVip, thinkUsersVipCode} from "@/api/think/thinkUsersVip";
import dayjs from "dayjs"; import dayjs from "dayjs";
const cardType = ['', '年卡', '次卡', '月卡', '会员VIP卡', '充值卡']; const cardType = ['', '年卡', '次卡', '月卡', '会员VIP卡', '充值卡'];
@@ -129,7 +140,11 @@ export default {
cardType, cardType,
payType: 1, payType: 1,
isLogin: false, isLogin: false,
disabled: false disabled: false,
code: '',
countDown: 30,
interval: null,
showCode: false,
}; };
}, },
onLoad(option) { onLoad(option) {
@@ -145,6 +160,25 @@ export default {
}, },
methods: { methods: {
dayjs, dayjs,
doShowCode() {
this.showCode = true
this.getCode()
},
setCountDown() {
this.interval = setInterval(() => {
if (this.countDown > 0) {
this.countDown--
} else {
clearInterval(this.interval)
this.getCode()
}
}, 1000)
},
async getCode() {
this.code = await thinkUsersVipCode(this.id)
this.countDown = 30
this.setCountDown()
},
async getInfo() { async getInfo() {
this.form = await getThinkUsersVip(this.id) this.form = await getThinkUsersVip(this.id)
}, },
@@ -176,6 +210,12 @@ export default {
return false; return false;
} }
}, },
},
onHide() {
if (this.interval) clearInterval(this.interval);
},
onUnload() {
if (this.interval) clearInterval(this.interval);
} }
}; };
</script> </script>
+1 -3
View File
@@ -1,8 +1,6 @@
<template> <template>
<view> <view>
<!-- <view class="segmented">
<uni-segmented-control :current="current" :values="items" :styleType="styleType" :activeColor="activeColor" inActiveColor="#808080" @clickItem="onClickItem" />
</view> -->
<view class="card-list"> <view class="card-list">
<block v-if="!hideTools || cardList.length > 0"> <block v-if="!hideTools || cardList.length > 0">
<view <view
+3 -7
View File
@@ -94,7 +94,6 @@
fields: {}, fields: {},
logo: '', logo: '',
bookingUser: {}, bookingUser: {},
server: [],
order: [], order: [],
} }
}, },
@@ -120,12 +119,6 @@
app.isLogin = false app.isLogin = false
app.form = {} app.form = {}
} }
// 菜单数据
MpMenuApi.listMpMenu({}).then(res => {
app.server = res.filter(d => d.type == 0)
app.order = res.filter(d => d.type == 1)
})
}, },
navTo(item) { navTo(item) {
if (!this.isLogin) { if (!this.isLogin) {
@@ -171,6 +164,9 @@
title: '保存成功', title: '保存成功',
icon: 'success' icon: 'success'
}) })
setTimeout(() => {
uni.navigateBack()
}, 1500)
}) })
} }
} }
+7 -7
View File
@@ -232,13 +232,13 @@
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
}, },
{ // {
"path": "goods/index", // "path": "goods/index",
"style": { // "style": {
"navigationBarTitleText": "商品列表", // "navigationBarTitleText": "商品列表",
"enablePullDownRefresh": false // "enablePullDownRefresh": false
} // }
}, // },
{ {
"path": "goods/detail", "path": "goods/detail",
"style": { "style": {
+26 -19
View File
@@ -46,31 +46,33 @@
<block v-for="(item,index) in orderList" :key="index"> <block v-for="(item,index) in orderList" :key="index">
<uni-card :border="false" :is-shadow="false" :padding="0"> <uni-card :border="false" :is-shadow="false" :padding="0">
<template v-slot:title> <template v-slot:title>
<div class="order-title web-cell"> <view class="order-title web-cell text-25">
<view class="web-cell web-cell-content"> <view class="web-cell web-cell-content">
<text class="merchant-name">订单号: {{ item.orderNum }}</text> <text class="merchant-name">订单号: {{ item.orderNum }}</text>
</view> </view>
<view class="web-cell web-cell-content flex justify-between items-center" v-if="orderType === 1"> <view class="web-cell web-cell-content flex justify-end items-end" v-if="orderType === 1">
<text class="merchant-name">{{ item.siteNames }}</text> <!-- <text class="merchant-name">{{ item.siteNames }}</text>-->
<text class="text-25 text-red" v-if="item.status === 2">待支付</text> <text class="text-25 text-red" v-if="item.status === 2">待支付</text>
<text class="text-25 text-green" v-else-if="item.status === 1">已支付</text> <text class="text-25 text-green" v-else-if="item.status === 1">已支付</text>
<text class="text-25 text-gray" v-else-if="item.status === 3">已退款</text> <text class="text-25 text-gray" v-else-if="item.status === 3">已退款</text>
<text class="text-25 text-gray" v-else-if="item.status === 0">已取消</text> <text class="text-25 text-gray" v-else-if="item.status === 0">已取消</text>
</view> </view>
<block v-if="item.orderStatus === 3"> <template v-else>
<text class="btn-status web-text-secondary">已取消</text> <block v-if="item.orderStatus === 3">
</block> <text class=" web-text-secondary">已取消</text>
<block v-else-if="item.orderStatus === 1"> </block>
<text class="btn-status web-text-success">已完成</text> <block v-else-if="item.orderStatus === 1">
</block> <text class=" web-text-success">已完成</text>
<block v-else> </block>
<text v-if="item.payStatus === 1" class="btn-status web-text-success">已支付</text> <block v-else>
<view v-if="item.payStatus === 0" class="btn-status web-text-danger"> <text v-if="item.payStatus === 1" class=" web-text-success">已支付</text>
<uv-count-down :time="item.timestamp" format="mm:ss"></uv-count-down> <view v-if="item.payStatus === 0" class=" web-text-danger">
<text class="no-pay" style="margin-left: 10rpx;">未支付</text> <uv-count-down :time="item.timestamp" format="mm:ss"></uv-count-down>
</view> <text class="no-pay" style="margin-left: 10rpx;">未支付</text>
</block> </view>
</div> </block>
</template>
</view>
</template> </template>
<view class="order-body web-cell web-cell-align-top"> <view class="order-body web-cell web-cell-align-top">
<view class="web-cell-content" @click="toDetail(item.id)"> <view class="web-cell-content" @click="toDetail(item.id)">
@@ -295,7 +297,9 @@ export default {
this.hasMerchantClerkRole = userInfo.roles.find((d) => d.roleCode === 'merchantClerk'); this.hasMerchantClerkRole = userInfo.roles.find((d) => d.roleCode === 'merchantClerk');
this.hasSuperAdminRole = userInfo.roles.find((d) => d.roleCode === 'superAdmin'); this.hasSuperAdminRole = userInfo.roles.find((d) => d.roleCode === 'superAdmin');
} }
await this.reload() if (uni.getStorageSync('orderType')) {
this.confirmOrderType({value: [JSON.parse(uni.getStorageSync('orderType'))]})
} else this.reset()
}, },
// 触底函数 // 触底函数
onReachBottom() { onReachBottom() {
@@ -319,6 +323,9 @@ export default {
confirmOrderType({value}) { confirmOrderType({value}) {
this.orderType = value[0].value this.orderType = value[0].value
this.orderTypeStr = value[0].label this.orderTypeStr = value[0].label
if (uni.getStorageSync('orderType')) {
uni.removeStorageSync('orderType')
}
this.reload() this.reload()
}, },
confirmOrderStatus({value}) { confirmOrderStatus({value}) {
@@ -591,7 +598,7 @@ export default {
}) })
await addThinkOrderRefundLog({ await addThinkOrderRefundLog({
uid: order.uid, uid: order.uid,
refundAmount: order.payPrice, refundAmount: order.price,
sid: order.sid, sid: order.sid,
oid: order.id, oid: order.id,
status: 1, status: 1,
+73 -20
View File
@@ -35,22 +35,22 @@
</view> </view>
</block> </block>
</block> </block>
<view class="flex justify-between items-center py-20 border-bottom" @click="scan"> <view class="flex justify-between items-center py-20 border-bottom" @click="showActionSheet">
<view class="flex justify-start items-center"> <view class="flex justify-start items-center">
<uv-icon name="https://oss.wsdns.cn/20241126/92f728b3b4e146d6a916259bde11a209.png"/> <uv-icon name="https://oss.wsdns.cn/20241126/92f728b3b4e146d6a916259bde11a209.png"/>
<text class="text-30 ml-20">扫码核销</text> <text class="text-30 ml-20">扫码核销</text>
</view> </view>
<uv-icon name="arrow-right" size="24rpx"/> <uv-icon name="arrow-right" size="24rpx"/>
</view> </view>
<!-- <button class="share-btn" open-type="contact">--> <!-- <button class="share-btn" open-type="contact">-->
<!-- <view class="flex justify-between items-center py-20 border-bottom">--> <!-- <view class="flex justify-between items-center py-20 border-bottom">-->
<!-- <view class="flex justify-start items-center">--> <!-- <view class="flex justify-start items-center">-->
<!-- <uv-icon name="https://oss.wsdns.cn/20240806/670b965e729b4a92a60927bf51bc8afe.png"/>--> <!-- <uv-icon name="https://oss.wsdns.cn/20240806/670b965e729b4a92a60927bf51bc8afe.png"/>-->
<!-- <text class="text-30 ml-20" style="font-weight: normal!important;">联系客服</text>--> <!-- <text class="text-30 ml-20" style="font-weight: normal!important;">联系客服</text>-->
<!-- </view>--> <!-- </view>-->
<!-- <uv-icon name="arrow-right" size="24rpx"/>--> <!-- <uv-icon name="arrow-right" size="24rpx"/>-->
<!-- </view>--> <!-- </view>-->
<!-- </button>--> <!-- </button>-->
</view> </view>
<!-- <view class="server" style="min-height: 200px">--> <!-- <view class="server" style="min-height: 200px">-->
<!-- <uni-list :border="false">--> <!-- <uni-list :border="false">-->
@@ -93,15 +93,15 @@
</view> </view>
</block> </block>
</block> </block>
<!-- <button class="share-btn" open-type="contact">--> <!-- <button class="share-btn" open-type="contact">-->
<!-- <view class="flex justify-between items-center py-20 border-bottom">--> <!-- <view class="flex justify-between items-center py-20 border-bottom">-->
<!-- <view class="flex justify-start items-center">--> <!-- <view class="flex justify-start items-center">-->
<!-- <uv-icon name="https://oss.wsdns.cn/20240806/670b965e729b4a92a60927bf51bc8afe.png"/>--> <!-- <uv-icon name="https://oss.wsdns.cn/20240806/670b965e729b4a92a60927bf51bc8afe.png"/>-->
<!-- <text class="text-30 ml-20" style="font-weight: normal!important;">联系客服</text>--> <!-- <text class="text-30 ml-20" style="font-weight: normal!important;">联系客服</text>-->
<!-- </view>--> <!-- </view>-->
<!-- <uv-icon name="arrow-right" size="24rpx"/>--> <!-- <uv-icon name="arrow-right" size="24rpx"/>-->
<!-- </view>--> <!-- </view>-->
<!-- </button>--> <!-- </button>-->
</view> </view>
<!-- <uni-list :border="false">--> <!-- <uni-list :border="false">-->
<!-- <block v-for="(item, index) in mpMenus" :key="index">--> <!-- <block v-for="(item, index) in mpMenus" :key="index">-->
@@ -170,6 +170,16 @@
<!-- 退出按钮 --> <!-- 退出按钮 -->
<ws-logout v-if="isLogin" @done="reload"></ws-logout> <ws-logout v-if="isLogin" @done="reload"></ws-logout>
</block> </block>
<uv-action-sheet
safeAreaInsetBottom
closeOnClickOverlay
round="15"
cancelText="取消"
ref="actionSheet"
:actions="[{name: '订单核销'}, {name: '游泳年/月卡使用'}]"
title="请选择操作"
@select="selectActionSheet">
</uv-action-sheet>
</layout> </layout>
</template> </template>
@@ -186,7 +196,7 @@ import Layout from "@/components/layout.vue";
import {useTenantStore} from '@/store/modules/tenant'; import {useTenantStore} from '@/store/modules/tenant';
import {authUser} from "@/api/user"; import {authUser} from "@/api/user";
import UvAvatar from "@/uni_modules/uv-avatar/components/uv-avatar/uv-avatar.vue"; import UvAvatar from "@/uni_modules/uv-avatar/components/uv-avatar/uv-avatar.vue";
import {getThinkOrderByCode} from "@/api/think/thinkOrder"; import {getThinkOrderByCode, thinkOrderCheckCode} from "@/api/think/thinkOrder";
const tenantStore = useTenantStore(); const tenantStore = useTenantStore();
const mpStore = useMpStore(); const mpStore = useMpStore();
@@ -388,6 +398,49 @@ export default {
}) })
} }
}); });
},
showActionSheet(){
this.$refs.actionSheet.open()
},
selectActionSheet({name}){
if (name === '订单核销') {
this.scan()
}
else if (name === '游泳年/月卡使用') {
this.useCard()
}
},
async useCard(){
uni.scanCode({
onlyFromCamera: true,
success: async ({result}) => {
const res = await thinkOrderCheckCode({qrcode: result}).catch(err => {
uni.showToast({
title: err.data,
icon: 'none'
})
})
if (res) {
uni.showToast({
title: '使用成功',
icon: 'success'
})
}
// if (!res.res) return uni.showToast({
// title: res.msg,
// icon: 'none'
// })
// uni.navigateTo({url: `/package/order/check?id=${res.data.id}`})
console.log(res)
},
fail: (err) => {
uni.showToast({
title: '扫码失败',
icon: 'none'
})
}
});
} }
} }
}; };
@@ -0,0 +1,7 @@
## 1.0.2(2023-07-02)
uv-action-sheet 由于弹出层uv-popup的修改,打开和关闭方法更改,详情参考文档:https://www.uvui.cn/components/actionSheet.html
## 1.0.1(2023-05-16)
1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
2. 优化部分功能
## 1.0.0(2023-05-10)
uv-action-sheet 底部操作菜单
@@ -0,0 +1,50 @@
export default {
props: {
// 标题,有值则显示,同时会显示关闭按钮
title: {
type: String,
default: ''
},
// 选项上方的描述信息
description: {
type: String,
default: ''
},
// 数据
actions: {
type: Array,
default: () => []
},
// 取消按钮的文字,不为空时显示按钮
cancelText: {
type: String,
default: ''
},
// 点击某个菜单项时是否关闭弹窗
closeOnClickAction: {
type: Boolean,
default: true
},
// 处理底部安全区(默认true)
safeAreaInsetBottom: {
type: Boolean,
default: true
},
// 小程序的打开方式
openType: {
type: String,
default: ''
},
// 点击遮罩是否允许关闭 (默认true)
closeOnClickOverlay: {
type: Boolean,
default: true
},
// 圆角值
round: {
type: [Boolean, String, Number],
default: 0
},
...uni.$uv?.props?.actionSheet
}
}
@@ -0,0 +1,280 @@
<template>
<uv-popup
ref="popup"
mode="bottom"
:safeAreaInsetBottom="safeAreaInsetBottom"
:round="round"
:close-on-click-overlay="closeOnClickOverlay"
@change="popupChange"
>
<view class="uv-action-sheet">
<view
class="uv-action-sheet__header"
v-if="title"
>
<text class="uv-action-sheet__header__title uv-line-1">{{title}}</text>
<view
class="uv-action-sheet__header__icon-wrap"
@tap.stop="cancel"
>
<uv-icon
name="close"
size="17"
color="#c8c9cc"
bold
></uv-icon>
</view>
</view>
<text
class="uv-action-sheet__description"
:style="[{
marginTop: `${title && description ? 0 : '18px'}`
}]"
v-if="description"
>{{description}}</text>
<slot>
<uv-line v-if="description"></uv-line>
<view class="uv-action-sheet__item-wrap">
<view v-for="(item, index) in actions" :key="index">
<!-- #ifdef MP -->
<button
class="uv-reset-button"
:openType="item.openType"
@getuserinfo="onGetUserInfo"
@contact="onContact"
@getphonenumber="onGetPhoneNumber"
@error="onError"
@launchapp="onLaunchApp"
@opensetting="onOpenSetting"
:lang="lang"
:session-from="sessionFrom"
:send-message-title="sendMessageTitle"
:send-message-path="sendMessagePath"
:send-message-img="sendMessageImg"
:show-message-card="showMessageCard"
:app-parameter="appParameter"
@tap="selectHandler(index)"
:hover-class="!item.disabled && !item.loading ? 'uv-action-sheet--hover' : ''"
>
<!-- #endif -->
<view
class="uv-action-sheet__item-wrap__item"
@tap.stop="selectHandler(index)"
:hover-class="!item.disabled && !item.loading ? 'uv-action-sheet--hover' : ''"
:hover-stay-time="150"
>
<template v-if="!item.loading">
<text
class="uv-action-sheet__item-wrap__item__name"
:style="[itemStyle(index)]"
>{{ item.name }}</text>
<text
v-if="item.subname"
class="uv-action-sheet__item-wrap__item__subname"
>{{ item.subname }}</text>
</template>
<uv-loading-icon
v-else
custom-class="van-action-sheet__loading"
size="18"
mode="circle"
/>
</view>
<!-- #ifdef MP -->
</button>
<!-- #endif -->
<uv-line v-if="index !== actions.length - 1"></uv-line>
</view>
</view>
</slot>
<uv-gap
bgColor="#eaeaec"
height="6"
v-if="cancelText"
></uv-gap>
<view hover-class="uv-action-sheet--hover">
<text
@touchmove.stop.prevent
:hover-stay-time="150"
v-if="cancelText"
class="uv-action-sheet__cancel-text"
@tap="cancel"
>{{cancelText}}</text>
</view>
</view>
</uv-popup>
</template>
<script>
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
import button from '@/uni_modules/uv-ui-tools/libs/mixin/button.js'
import openType from '@/uni_modules/uv-ui-tools/libs/mixin/openType.js'
import props from './props.js';
/**
* ActionSheet 操作菜单
* @description 本组件用于从底部弹出一个操作菜单,供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheetAPI,配置更加灵活,所有平台都表现一致。
* @tutorial https://www.uvui.cn/components/actionSheet.html
* @property {Boolean} show 操作菜单是否展示 (默认 false )
* @property {String} title 操作菜单标题
* @property {String} description 选项上方的描述信息
* @property {Array<Object>} actions 按钮的文字数组,见官方文档示例
* @property {String} cancelText 取消按钮的提示文字,不为空时显示按钮
* @property {Boolean} closeOnClickAction 点击某个菜单项时是否关闭弹窗 (默认 true )
* @property {Boolean} safeAreaInsetBottom 处理底部安全区 (默认 true )
* @property {String} openType 小程序的打开方式 (contact | launchApp | getUserInfo | openSetting |getPhoneNumber |error )
* @property {Boolean} closeOnClickOverlay 点击遮罩是否允许关闭 (默认 true )
* @property {String} lang 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文
* @property {String} sessionFrom 会话来源,openType="contact"时有效
* @property {String} sendMessageTitle 会话内消息卡片标题,openType="contact"时有效
* @property {String} sendMessagePath 会话内消息卡片点击跳转小程序路径,openType="contact"时有效
* @property {String} sendMessageImg 会话内消息卡片图片,openType="contact"时有效
* @property {Boolean} showMessageCard 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,openType="contact"时有效 (默认 false )
* @property {String} appParameter 打开 APP 时,向 APP 传递的参数,openType=launchApp 时有效
*
* @event {Function} select 点击ActionSheet列表项时触发
* @event {Function} close 点击取消按钮时触发
* @event {Function} getuserinfo 用户点击该按钮时,会返回获取到的用户信息,回调的 detail 数据与 wx.getUserInfo 返回的一致,openType="getUserInfo"时有效
* @event {Function} contact 客服消息回调,openType="contact"时有效
* @event {Function} getphonenumber 获取用户手机号回调,openType="getPhoneNumber"时有效
* @event {Function} error 当使用开放能力时,发生错误的回调,openType="error"时有效
* @event {Function} launchapp 打开 APP 成功的回调,openType="launchApp"时有效
* @event {Function} opensetting 在打开授权设置页后回调,openType="openSetting"时有效
* @example <uv-action-sheet ref="actionSheet" :actions="list" :title="title" ></uv-action-sheet>
*/
export default {
name: "uv-action-sheet",
mixins: [openType, button, mpMixin , mixin, props],
emits: ['close', 'select'],
computed: {
// 操作项目的样式
itemStyle() {
return (index) => {
let style = {};
if (this.actions[index].color) style.color = this.actions[index].color
if (this.actions[index].fontSize) style.fontSize = this.$uv.addUnit(this.actions[index].fontSize)
// 选项被禁用的样式
if (this.actions[index].disabled) style.color = '#c0c4cc'
return style;
}
},
},
methods: {
open() {
this.$refs.popup.open();
},
close() {
this.$refs.popup.close();
},
popupChange(e) {
if(!e.show) this.$emit('close');
},
// 点击取消按钮
cancel() {
this.close();
},
selectHandler(index) {
const item = this.actions[index]
if (item && !item.disabled && !item.loading) {
this.$emit('select', item)
if (this.closeOnClickAction) {
this.close();
}
}
},
}
}
</script>
<style lang="scss" scoped>
$show-lines: 1;
$show-reset-button: 1;
@import '@/uni_modules/uv-ui-tools/libs/css/variable.scss';
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
@import '@/uni_modules/uv-ui-tools/libs/css/color.scss';
$uv-action-sheet-reset-button-width:100% !default;
$uv-action-sheet-title-font-size: 16px !default;
$uv-action-sheet-title-padding: 12px 30px !default;
$uv-action-sheet-title-color: $uv-main-color !default;
$uv-action-sheet-header-icon-wrap-right:15px !default;
$uv-action-sheet-header-icon-wrap-top:15px !default;
$uv-action-sheet-description-font-size:13px !default;
$uv-action-sheet-description-color:14px !default;
$uv-action-sheet-description-margin: 18px 15px !default;
$uv-action-sheet-item-wrap-item-padding:15px !default;
$uv-action-sheet-item-wrap-name-font-size:16px !default;
$uv-action-sheet-item-wrap-subname-font-size:13px !default;
$uv-action-sheet-item-wrap-subname-color: #c0c4cc !default;
$uv-action-sheet-item-wrap-subname-margin-top:10px !default;
$uv-action-sheet-cancel-text-font-size:16px !default;
$uv-action-sheet-cancel-text-color:$uv-content-color !default;
$uv-action-sheet-cancel-text-font-size:15px !default;
$uv-action-sheet-cancel-text-hover-background-color:rgb(242, 243, 245) !default;
.uv-reset-button {
width: $uv-action-sheet-reset-button-width;
}
.uv-action-sheet {
text-align: center;
&__header {
position: relative;
padding: $uv-action-sheet-title-padding;
&__title {
font-size: $uv-action-sheet-title-font-size;
color: $uv-action-sheet-title-color;
font-weight: bold;
text-align: center;
}
&__icon-wrap {
position: absolute;
right: $uv-action-sheet-header-icon-wrap-right;
top: $uv-action-sheet-header-icon-wrap-top;
}
}
&__description {
font-size: $uv-action-sheet-description-font-size;
color: $uv-tips-color;
margin: $uv-action-sheet-description-margin;
text-align: center;
}
&__item-wrap {
&__item {
padding: $uv-action-sheet-item-wrap-item-padding;
@include flex;
align-items: center;
justify-content: center;
flex-direction: column;
&__name {
font-size: $uv-action-sheet-item-wrap-name-font-size;
color: $uv-main-color;
text-align: center;
}
&__subname {
font-size: $uv-action-sheet-item-wrap-subname-font-size;
color: $uv-action-sheet-item-wrap-subname-color;
margin-top: $uv-action-sheet-item-wrap-subname-margin-top;
text-align: center;
}
}
}
&__cancel-text {
font-size: $uv-action-sheet-cancel-text-font-size;
color: $uv-action-sheet-cancel-text-color;
text-align: center;
padding: $uv-action-sheet-cancel-text-font-size;
}
&--hover {
background-color: $uv-action-sheet-cancel-text-hover-background-color;
}
}
</style>
@@ -0,0 +1,92 @@
{
"id": "uv-action-sheet",
"displayName": "uv-action-sheet 底部操作菜单 全面兼容小程序、nvue、vue2、vue3等多端",
"version": "1.0.2",
"description": "该组件用于从底部弹出一个操作菜单,供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheet API,配置更加灵活,所有平台都表现一致。",
"keywords": [
"action-sheet",
"uvui",
"uv-ui",
"操作菜单",
"菜单选择"
],
"repository": "",
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"type": "component-vue",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "插件不采集任何数据",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [
"uv-ui-tools",
"uv-popup",
"uv-icon",
"uv-line",
"uv-loading-icon",
"uv-gap"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "y"
},
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y",
"钉钉": "u",
"快手": "u",
"飞书": "u",
"京东": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}
+13
View File
@@ -0,0 +1,13 @@
## ActionSheet 操作菜单
> **组件名:uv-action-sheet**
本组件用于从底部弹出一个操作菜单,供用户选择并返回结果。
本组件功能类似于uni的uni.showActionSheet API,配置更加灵活,所有平台都表现一致。
### <a href="https://www.uvui.cn/components/actionSheet.html" target="_blank">查看文档</a>
### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui)
#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>