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_SERVER_URL=https://gxtyzx-server.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_SERVER_URL=https://gxtyzx-server.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));
}
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));
}
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">
<uv-sticky bg-color="white">
<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>
</uv-sticky>
<template v-if="merchantId !== 37">
@@ -178,7 +179,9 @@ export default {
disabled: false,
// 购物车信息
showCarInfo: false,
timeList: []
timeList: [],
timeListOrigin: [],
activeIndex: 0
}
},
onLoad(option) {
@@ -200,7 +203,7 @@ export default {
else totalPrice += d.price
})
carStore.totalPrice = totalPrice
console.log('totalPrice: ', totalPrice);
// console.log('totalPrice: ', totalPrice);
return totalPrice;
},
carNum() {
@@ -260,7 +263,7 @@ export default {
setDateList() {
this.next7day = []
let day = 7
if (this.merchantId === 37) day = 7
if (this.merchantId === 37) day = 1
for (let i = 0; i < day; i++) {
const day = dayjs().add(i, 'day')
this.next7day.push({
@@ -275,25 +278,92 @@ export default {
},
async getTimeList() {
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()
},
makeTimeList() {
this.periodList = []
this.timeList.forEach(item => {
this.timeListOrigin.forEach(item => {
const weekList = JSON.parse(item.week)
if (parseInt(this.merchantId) === 37) {
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 {
// 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)
}
})
// 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() {
this.disabled = !this.disabled;
},
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.dateTime = e.dateTime
this.makeTimeList()
@@ -348,7 +418,7 @@ export default {
const checkTimePeriod = field.periodVoList.find(d => (d.period === timePeriod && d.id === item.id))
// console.log('here', field, item)
// 已被预定
if (checkTimePeriod.sold) {
if (checkTimePeriod.sold || checkTimePeriod.took) {
return
}
const app = this
@@ -420,7 +490,7 @@ export default {
const timePeriod = item.timePeriod
const checkTimePeriod = field.periodVoList.find(d => (d.period === timePeriod && d.id === item.id))
// console.log('checkTimePeriod', checkTimePeriod, timePeriod)
if (checkTimePeriod && checkTimePeriod.sold) {
if (checkTimePeriod && (checkTimePeriod.sold || checkTimePeriod.took)) {
if (item.isHalf === 1) {
return 'web-bg-warning'
}
@@ -439,7 +509,7 @@ export default {
uni.navigateTo({
url: '/package/booking/confirm',
success: (res) => {
console.log(this.selection)
// console.log(this.selection)
res.eventChannel.emit('data', this.selection)
}
})
+5 -2
View File
@@ -262,8 +262,8 @@ export default {
this.userInfo = await userStore.fetchUserInfo();
eventChannel.on('data', async (data) => {
_this.list = data
if (data[0].isHalf === 1) _this.payPrice = data.reduce((a, b) => a + b.halfPrice, 0)
else _this.payPrice = data.reduce((a, b) => a + b.price, 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 + parseFloat(b.price), 0)
_this.originPrice = JSON.parse(JSON.stringify(_this.payPrice))
const thinkOrderInfos = []
@@ -294,6 +294,7 @@ export default {
code: null,
payType: 1,
thinkOrderInfos,
day: dayjs(item.dateTime).format('D') - 1,
startTime: thinkOrderInfos.map(item => item.startTime).join()
}
})
@@ -558,10 +559,12 @@ export default {
async onPayType(index) {
// app.payType = index;
this.form.payType = index;
console.log(this.form.payType)
this.form.vid = null
this.form.code = null
this.reducePrice = 0
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 === 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">
<view v-if="protocol">
<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 class="p-30">
<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 {getArticle, pageArticle} from "@/api/cms/article";
import coordtransform from "coordtransform";
import dayjs from "dayjs";
const carStore = useCarStore();
@@ -151,6 +152,13 @@ export default {
}
},
openProtocol() {
const hour = dayjs().format('H')
if (hour < 8 || hour === 23) {
return uni.showModal({
showCancel: false,
title: '场地预定时间为:8:00-23:00。',
})
}
if (this.timer) {
clearInterval(this.timer)
this.timer = null
+9 -2
View File
@@ -305,14 +305,21 @@ export default {
});
setTimeout(function () {
app.disabled = false;
uni.redirectTo({
url: '/package/user/card'
uni.setStorageSync('orderType', JSON.stringify({
label: '会员卡订单',
value: 1
}))
uni.switchTab({
url: '/pages/order'
});
}, 500);
},
fail: function (err) {
console.log('支付失败', err);
app.disabled = false;
uni.switchTab({
url: '/pages/order'
});
}
});
uni.hideLoading();
+45 -16
View File
@@ -1,5 +1,30 @@
<template>
<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">
<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">
@@ -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 {addThinkGoodsOrder} from "@/api/think/thinkGoodsOrder";
import {getThinkUsers, thinkUserInfo} from "@/api/think/thinkUsers";
import {pageThinkUsersAddress} from "@/api/think/thinkUsersAddress";
const mpStore = useMpStore();
const userStore = useUserStore();
@@ -263,6 +289,7 @@ export default {
payPassword: '',
canPointPay: false,
thinkUserInfo: {},
needExpress: false
};
},
onLoad(where) {
@@ -299,18 +326,21 @@ export default {
this.canPointPay = true
this.totalPoint += parseInt(item.goods.maxIntegral) * item.cartNum
}
if (item.goods.isFh === 1) this.needExpress = true
return item
})
this.totalPrice = app.carts.reduce((a, b) => a + b.price * b.cartNum, 0)
}
})
UserAddressApi.pageUserAddress({
userId: uni.getStorageSync('user_id')
this.getUserAddress()
},
getUserAddress(){
pageThinkUsersAddress({
uid: uni.getStorageSync('uid')
}).then((res) => {
app.addressList = res.list;
this.addressList = res.list;
const arr = res.list.filter((d) => d.isDefault === true);
app.address = arr[0];
this.address = arr[0];
});
},
onDisabled() {
@@ -347,13 +377,9 @@ export default {
})
this.payType = index;
},
openAddressList() {
if (this.deliveryType === 0) {
this.$refs.userAddressForm.open('center');
}
if (this.deliveryType === 1) {
this.$refs.shopAddressForm.open('center');
}
async openAddressList() {
this.getUserAddress()
this.$refs.userAddressForm.open('center');
},
// 弹出登录提示框
openLogin() {
@@ -397,7 +423,10 @@ export default {
},
save() {
const app = this;
if (this.needExpress && !this.address.id) return uni.showToast({
title: '请选择收货地址',
icon: 'none'
})
if (!this.disabled) {
uni.showToast({
title: '请先阅读并同意服务协议',
@@ -421,9 +450,9 @@ export default {
})
})
addThinkGoodsOrder({
name: '',
phone: '',
address: '',
name: this.address ? this.address.name : '' ,
phone: this.address ? this.address.phone : '',
address: this.address ? `${this.address.region}${this.address.address}` : '',
totalPrice: this.totalPrice,
num: 1,
payPrice: this.totalPrice,
+8 -2
View File
@@ -36,7 +36,14 @@ const info = ref({})
const expired = ref(false)
const getInfo = async (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();
@@ -63,7 +70,6 @@ const checkAuth = async () => {
checkAuth()
const disabled = ref(false)
const doCheck = async () => {
+14 -8
View File
@@ -4,7 +4,7 @@
<!-- <uv-image :src="`${IMG_URL}${form.qrcode}`" width="200" height="200"/>-->
<text class="text-25 mb-20 text-gray">{{ countDown }}秒后自动刷新</text>
<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>
<uni-card title="预定信息" :border="false" :is-shadow="false" :padding="0">
<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 :title="`姓名`" :value="`${form.name}`" :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.orderNum}`" :cellStyle="{ padding: '8px' }"
" />
<!-- <uv-cell :title="`订单号`" :value="`${form.id}`" :cellStyle="{ padding: '8px' }"/>-->
<uv-cell :title="`订单编号`" :value="`${form.orderNum}`" :cellStyle="{ padding: '8px' }"/>
<uv-cell :title="`订单状态`" :cellStyle="{ padding: '8px' }">
<template v-slot:value>
<view v-if="form.payStatus === 2">
@@ -143,7 +142,7 @@ export default {
colorIndex: 0,
activeColor: '#108001',
styleType: 'text',
countDown: 120,
countDown: 30,
interval: null
};
},
@@ -151,8 +150,7 @@ export default {
this.orderId = option.id;
// 判断是否登录
this.openLogin();
// 加载数据
this.reload();
},
onShow() {
// 判断是否登录
@@ -202,11 +200,13 @@ export default {
this.$refs.login.open('bottom');
return false;
}
// 加载数据
this.reload();
},
async getOrder() {
const app = this
if (this.interval) clearInterval(this.interval);
this.countDown = 120
this.countDown = 30
OrderApi.getThinkOrder(this.orderId).then((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>
-32
View File
@@ -135,38 +135,6 @@ export default {
}
],
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: {
// 对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' }">
<view class="content web-cell web-cell-align-top">
<view class="card-info web-cell-content">
<view class="title-bar">
<view class="web-text-heading" style="color: #ffffff; font-size: 17px; font-weight: 600">{{
form.name
}}
<view class="title-bar w-100p">
<view class="flex justify-between items-center w-90p">
<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 class="desc" style="font-size: 14px">{{ cardType[form.type] }}</view>
<view class="mt-20" v-if="form.expireTime">
@@ -30,6 +33,14 @@
<ws-login ref="login" :logo="logo" @done="reload"/>
</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'">
<view class="money-bar web-cell">
<view class="money-item web-cell-content">
@@ -112,7 +123,7 @@
</template>
<script>
import {getThinkUsersVip} from "@/api/think/thinkUsersVip";
import {getThinkUsersVip, thinkUsersVipCode} from "@/api/think/thinkUsersVip";
import dayjs from "dayjs";
const cardType = ['', '年卡', '次卡', '月卡', '会员VIP卡', '充值卡'];
@@ -129,7 +140,11 @@ export default {
cardType,
payType: 1,
isLogin: false,
disabled: false
disabled: false,
code: '',
countDown: 30,
interval: null,
showCode: false,
};
},
onLoad(option) {
@@ -145,6 +160,25 @@ export default {
},
methods: {
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() {
this.form = await getThinkUsersVip(this.id)
},
@@ -176,6 +210,12 @@ export default {
return false;
}
},
},
onHide() {
if (this.interval) clearInterval(this.interval);
},
onUnload() {
if (this.interval) clearInterval(this.interval);
}
};
</script>
+1 -3
View File
@@ -1,8 +1,6 @@
<template>
<view>
<!-- <view class="segmented">
<uni-segmented-control :current="current" :values="items" :styleType="styleType" :activeColor="activeColor" inActiveColor="#808080" @clickItem="onClickItem" />
</view> -->
<view class="card-list">
<block v-if="!hideTools || cardList.length > 0">
<view
+3 -7
View File
@@ -94,7 +94,6 @@
fields: {},
logo: '',
bookingUser: {},
server: [],
order: [],
}
},
@@ -120,12 +119,6 @@
app.isLogin = false
app.form = {}
}
// 菜单数据
MpMenuApi.listMpMenu({}).then(res => {
app.server = res.filter(d => d.type == 0)
app.order = res.filter(d => d.type == 1)
})
},
navTo(item) {
if (!this.isLogin) {
@@ -171,6 +164,9 @@
title: '保存成功',
icon: 'success'
})
setTimeout(() => {
uni.navigateBack()
}, 1500)
})
}
}
+7 -7
View File
@@ -232,13 +232,13 @@
"enablePullDownRefresh": false
}
},
{
"path": "goods/index",
"style": {
"navigationBarTitleText": "商品列表",
"enablePullDownRefresh": false
}
},
// {
// "path": "goods/index",
// "style": {
// "navigationBarTitleText": "商品列表",
// "enablePullDownRefresh": false
// }
// },
{
"path": "goods/detail",
"style": {
+26 -19
View File
@@ -46,31 +46,33 @@
<block v-for="(item,index) in orderList" :key="index">
<uni-card :border="false" :is-shadow="false" :padding="0">
<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">
<text class="merchant-name">订单号: {{ item.orderNum }}</text>
</view>
<view class="web-cell web-cell-content flex justify-between items-center" v-if="orderType === 1">
<text class="merchant-name">{{ item.siteNames }}</text>
<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="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-gray" v-else-if="item.status === 3">已退款</text>
<text class="text-25 text-gray" v-else-if="item.status === 0">已取消</text>
</view>
<block v-if="item.orderStatus === 3">
<text class="btn-status web-text-secondary">已取消</text>
</block>
<block v-else-if="item.orderStatus === 1">
<text class="btn-status web-text-success">已完成</text>
</block>
<block v-else>
<text v-if="item.payStatus === 1" class="btn-status web-text-success">已支付</text>
<view v-if="item.payStatus === 0" class="btn-status web-text-danger">
<uv-count-down :time="item.timestamp" format="mm:ss"></uv-count-down>
<text class="no-pay" style="margin-left: 10rpx;">未支付</text>
</view>
</block>
</div>
<template v-else>
<block v-if="item.orderStatus === 3">
<text class=" web-text-secondary">已取消</text>
</block>
<block v-else-if="item.orderStatus === 1">
<text class=" web-text-success">已完成</text>
</block>
<block v-else>
<text v-if="item.payStatus === 1" class=" web-text-success">已支付</text>
<view v-if="item.payStatus === 0" class=" web-text-danger">
<uv-count-down :time="item.timestamp" format="mm:ss"></uv-count-down>
<text class="no-pay" style="margin-left: 10rpx;">未支付</text>
</view>
</block>
</template>
</view>
</template>
<view class="order-body web-cell web-cell-align-top">
<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.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() {
@@ -319,6 +323,9 @@ export default {
confirmOrderType({value}) {
this.orderType = value[0].value
this.orderTypeStr = value[0].label
if (uni.getStorageSync('orderType')) {
uni.removeStorageSync('orderType')
}
this.reload()
},
confirmOrderStatus({value}) {
@@ -591,7 +598,7 @@ export default {
})
await addThinkOrderRefundLog({
uid: order.uid,
refundAmount: order.payPrice,
refundAmount: order.price,
sid: order.sid,
oid: order.id,
status: 1,
+73 -20
View File
@@ -35,22 +35,22 @@
</view>
</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">
<uv-icon name="https://oss.wsdns.cn/20241126/92f728b3b4e146d6a916259bde11a209.png"/>
<text class="text-30 ml-20">扫码核销</text>
</view>
<uv-icon name="arrow-right" size="24rpx"/>
</view>
<!-- <button class="share-btn" open-type="contact">-->
<!-- <view class="flex justify-between items-center py-20 border-bottom">-->
<!-- <view class="flex justify-start items-center">-->
<!-- <uv-icon name="https://oss.wsdns.cn/20240806/670b965e729b4a92a60927bf51bc8afe.png"/>-->
<!-- <text class="text-30 ml-20" style="font-weight: normal!important;">联系客服</text>-->
<!-- </view>-->
<!-- <uv-icon name="arrow-right" size="24rpx"/>-->
<!-- </view>-->
<!-- </button>-->
<!-- <button class="share-btn" open-type="contact">-->
<!-- <view class="flex justify-between items-center py-20 border-bottom">-->
<!-- <view class="flex justify-start items-center">-->
<!-- <uv-icon name="https://oss.wsdns.cn/20240806/670b965e729b4a92a60927bf51bc8afe.png"/>-->
<!-- <text class="text-30 ml-20" style="font-weight: normal!important;">联系客服</text>-->
<!-- </view>-->
<!-- <uv-icon name="arrow-right" size="24rpx"/>-->
<!-- </view>-->
<!-- </button>-->
</view>
<!-- <view class="server" style="min-height: 200px">-->
<!-- <uni-list :border="false">-->
@@ -93,15 +93,15 @@
</view>
</block>
</block>
<!-- <button class="share-btn" open-type="contact">-->
<!-- <view class="flex justify-between items-center py-20 border-bottom">-->
<!-- <view class="flex justify-start items-center">-->
<!-- <uv-icon name="https://oss.wsdns.cn/20240806/670b965e729b4a92a60927bf51bc8afe.png"/>-->
<!-- <text class="text-30 ml-20" style="font-weight: normal!important;">联系客服</text>-->
<!-- </view>-->
<!-- <uv-icon name="arrow-right" size="24rpx"/>-->
<!-- </view>-->
<!-- </button>-->
<!-- <button class="share-btn" open-type="contact">-->
<!-- <view class="flex justify-between items-center py-20 border-bottom">-->
<!-- <view class="flex justify-start items-center">-->
<!-- <uv-icon name="https://oss.wsdns.cn/20240806/670b965e729b4a92a60927bf51bc8afe.png"/>-->
<!-- <text class="text-30 ml-20" style="font-weight: normal!important;">联系客服</text>-->
<!-- </view>-->
<!-- <uv-icon name="arrow-right" size="24rpx"/>-->
<!-- </view>-->
<!-- </button>-->
</view>
<!-- <uni-list :border="false">-->
<!-- <block v-for="(item, index) in mpMenus" :key="index">-->
@@ -170,6 +170,16 @@
<!-- 退出按钮 -->
<ws-logout v-if="isLogin" @done="reload"></ws-logout>
</block>
<uv-action-sheet
safeAreaInsetBottom
closeOnClickOverlay
round="15"
cancelText="取消"
ref="actionSheet"
:actions="[{name: '订单核销'}, {name: '游泳年/月卡使用'}]"
title="请选择操作"
@select="selectActionSheet">
</uv-action-sheet>
</layout>
</template>
@@ -186,7 +196,7 @@ import Layout from "@/components/layout.vue";
import {useTenantStore} from '@/store/modules/tenant';
import {authUser} from "@/api/user";
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 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>