添加页面
This commit is contained in:
@ -7,7 +7,7 @@
|
||||
}</route>
|
||||
|
||||
<template>
|
||||
<view class="mt-26rpx">
|
||||
<view>
|
||||
<view>
|
||||
<navbar title="订单详情" custom-class="!bg-[transparent]"></navbar>
|
||||
</view>
|
||||
|
||||
241
src/bundle/profile/change-mobile.vue
Normal file
241
src/bundle/profile/change-mobile.vue
Normal file
@ -0,0 +1,241 @@
|
||||
<route lang="jsonc" type="page">{
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
}</route>
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<view class="mx-60rpx mt-20rpx">
|
||||
<view class="text-[#303133] text-48rpx leading-80rpx font-600">
|
||||
修改手机号码
|
||||
</view>
|
||||
<view class="font-400 text-28rpx leading-44rpx text-[#6B7280] mt-12rpx">手机号一年内可修改2次</view>
|
||||
</view>
|
||||
<view class="mt-106rpx mx-48rpx">
|
||||
<wd-form ref="form" :model="model">
|
||||
<view>
|
||||
<view class="font-400 text-30rpx text-[#606266] leading-44rpx">手机号</view>
|
||||
<view class="mt-20rpx">
|
||||
<wd-input
|
||||
v-model="model.mobile"
|
||||
type="text"
|
||||
placeholder="请输入手机号码"
|
||||
inputmode="numeric"
|
||||
no-border
|
||||
custom-class="!bg-[#F6F7F8] !border !border-solid !border-[#EAECF0] !rounded-16rpx"
|
||||
custom-input-class="!px-32rpx !h-104rpx"
|
||||
@input="mobile.handleInputMobile"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="mt-40rpx">
|
||||
<view class="font-400 text-30rpx text-[#606266] leading-44rpx">验证码</view>
|
||||
<view class="mt-20rpx">
|
||||
<wd-input type="text" placeholder="请输入验证码" v-model="model.code" inputmode="numeric" no-border custom-class="!bg-[#F6F7F8] !border !border-solid !border-[#EAECF0] !rounded-16rpx" custom-input-class="!px-32rpx !h-104rpx">
|
||||
<template #suffix>
|
||||
<view class="flex items-center mr-34rpx">
|
||||
<view class="flex items-center">
|
||||
<wd-divider color="#C9C9C9" vertical />
|
||||
</view>
|
||||
|
||||
<view class="flex items-center">
|
||||
<view class="text-[#4C9F44] text-32rpx font-400 leading-44rpx" v-if="!startCountDown" @click="mobile.handleCountDown">发送验证码</view>
|
||||
<view class="!text-[#C9C9C9] text-32rpx font-400 leading-44rpx flex items-center" v-if="startCountDown">
|
||||
<wd-count-down ref="countDown" :time="countDownTime" millisecond :auto-start="false" format="ss" custom-class="!text-[#C9C9C9] !text-32rpx" @finish="mobile.handleFinishCountDown"></wd-count-down>
|
||||
<view> S后重发</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</wd-input>
|
||||
</view>
|
||||
</view>
|
||||
</wd-form>
|
||||
</view>
|
||||
|
||||
<view class="h-90rpx leading-90rpx mx-60rpx rounded-8rpx text-center mt-112rpx bg-[#4C9F44] text-[#fff]" :class="disabled ? 'opacity-40' : ''" @click="mobile.handleToLogin">登录</view>
|
||||
|
||||
<view class="flex items-center mx-52rpx mt-56rpx" v-if="pageType === 'login'">
|
||||
<view class="w-32rpx h-32rpx">
|
||||
<wd-checkbox v-model="agree" @change="mobile.handleAgree" checked-color="#4C9F44" size="large"> </wd-checkbox>
|
||||
</view>
|
||||
<view class="font-400 text-26rpx leading-40rpx text-[#8F959E] ml-14rpx flex-1" @click="agree = !agree">
|
||||
我已阅读并同意 <text class="text-[#4C9F44]" @click.stop="mobile.handleToService">《服务协议》</text> 和<text class="text-[#4C9F44]" @click.stop="mobile.handleToPrivacy">《隐私政策》</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 手机号修改成功 -->
|
||||
<wd-popup v-model="showEditSuccessPopup" lock-scroll custom-style="border-radius: 32rpx 32rpx 0rpx 0rpx;" position="bottom">
|
||||
<view class="relative pt-64rpx pb-74rpx">
|
||||
<view class="flex justify-center items-center">
|
||||
<view class="bg-[#4C9F44] w-280rpx rounded-280rpx">
|
||||
<wd-img width="280rpx" height="280rpx" :src="`${OSS}images/reserve_room/reserve_room_image7.png`"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="text-[#303133] text-36rpx leading-46rpx text-center mt-48rpx">手机号修改成功</view>
|
||||
<view class="text-[#9CA3AF] text-28rpx leading-44rpx mt-16rpx text-center">{{ page.desc }}</view>
|
||||
<view class="w-630rpx h-90rpx leading-90rpx text-center bg-[#4C9F44] rounded-8rpx text-[#fff] mt-174rpx mx-auto" @click="mobile.handleToBack">好的</view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {mobile as testMobile} from '@/utils/test'
|
||||
import { useToast } from 'wot-design-uni'
|
||||
import { router } from '@/utils/tools'
|
||||
|
||||
const OSS = inject('OSS')
|
||||
const toast = useToast()
|
||||
const disabled = ref<boolean>(true)
|
||||
|
||||
/** 页面 **/
|
||||
let pageType = 'login' // 页面类型 login:登录 edit:修改手机号
|
||||
const page = ref<{title: string, desc: string}>({title: '其他手机号登录', desc: '请输入你要登录的手机号'})
|
||||
const showEditSuccessPopup = ref<boolean>(false) // 显示手机号修改成功弹窗
|
||||
const userId = ref<number>(0) // 用户ID,修改手机号时需要传
|
||||
|
||||
/** 验证码倒计时 **/
|
||||
const countDownTime = ref<number>(1 * 60 * 1000) // 60s倒计时
|
||||
const startCountDown = ref<boolean>(false) // 是否开始倒计时
|
||||
const countDown = ref<any>(null) // 倒计时组件
|
||||
|
||||
/** 表单相关 **/
|
||||
const model = reactive<{
|
||||
mobile: string
|
||||
code: string
|
||||
}>({
|
||||
mobile: '',
|
||||
code: ''
|
||||
})
|
||||
/** 结束 **/
|
||||
|
||||
/** 服务协议和隐私政策 **/
|
||||
const agree = ref<boolean>(false)
|
||||
/** 结束 **/
|
||||
|
||||
onLoad((args) => {
|
||||
// 从个人登录页面进入
|
||||
if (args.type === 'edit') {
|
||||
userId.value = Number(args.userId) || 0 // userId仅做测试使用,实际请传真实用户ID
|
||||
|
||||
page.value.title = '修改手机号'
|
||||
page.value.desc = '手机号一年内可修改2次'
|
||||
pageType = 'edit'
|
||||
}
|
||||
})
|
||||
|
||||
const mobile = {
|
||||
// 验证手机号
|
||||
handleInputMobile: (e: {value: string}) => {
|
||||
model.mobile = e.value
|
||||
disabled.value = !testMobile(model.mobile)
|
||||
},
|
||||
|
||||
// 发送验证码
|
||||
handleCountDown: () => {
|
||||
if (disabled.value) {
|
||||
toast.show({
|
||||
iconClass: 'info-circle',
|
||||
msg: '手机号码错误请重新输入',
|
||||
direction: 'vertical'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
startCountDown.value = true
|
||||
nextTick(() => {
|
||||
countDown.value?.start()
|
||||
|
||||
// 发送验证码请求
|
||||
})
|
||||
},
|
||||
|
||||
// 验证码倒计时结束
|
||||
handleFinishCountDown: () => {
|
||||
startCountDown.value = false
|
||||
},
|
||||
|
||||
// 登录
|
||||
handleToLogin: () => {
|
||||
// TODO 如果是edit的话就是修改手机号
|
||||
|
||||
if (pageType === 'login' && !agree.value) {
|
||||
toast.show({
|
||||
iconClass: 'info-circle',
|
||||
msg: '请同意服务协议和隐私政策',
|
||||
direction: 'vertical'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (!testMobile(model.mobile)) {
|
||||
toast.show({
|
||||
iconClass: 'info-circle',
|
||||
msg: '手机号码错误请重新输入',
|
||||
direction: 'vertical'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (!model.code) {
|
||||
toast.show({
|
||||
iconClass: 'info-circle',
|
||||
msg: '验证码错误',
|
||||
direction: 'vertical'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
router.navigateTo('/bundle/profile/set-password')
|
||||
},
|
||||
|
||||
// 获取手机号
|
||||
handleGetPhoneNumber: (e: object) => {
|
||||
console.log("🚀 ~ e:", e)
|
||||
},
|
||||
|
||||
handleAgree: (e: any) => {
|
||||
console.log('e', e)
|
||||
},
|
||||
|
||||
// 跳转到服务协议页面
|
||||
handleToService: () => {
|
||||
disabled.value = !disabled.value
|
||||
console.log("🚀 ~ disabled:", disabled)
|
||||
},
|
||||
|
||||
// 跳转到隐私政策页面
|
||||
handleToPrivacy: () => {
|
||||
|
||||
},
|
||||
|
||||
// 修改手机成功后返回
|
||||
handleToBack: () => {
|
||||
uni.navigateBack()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.service {
|
||||
:deep() {
|
||||
.wd-checkbox {
|
||||
display: flex;
|
||||
align-content: flex-start;
|
||||
}
|
||||
|
||||
.wd-checkbox__label {
|
||||
margin-left: 6rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
219
src/bundle/profile/change-password.vue
Normal file
219
src/bundle/profile/change-password.vue
Normal file
@ -0,0 +1,219 @@
|
||||
<route lang="jsonc" type="page">{
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
}</route>
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<view class="mx-60rpx mt-20rpx">
|
||||
<view class="text-[#303133] text-48rpx leading-80rpx font-600">
|
||||
修改密码
|
||||
</view>
|
||||
<view class="font-400 text-28rpx leading-44rpx text-[#6B7280] mt-12rpx">需要验证绑定手机</view>
|
||||
</view>
|
||||
<view class="mt-106rpx mx-48rpx">
|
||||
<wd-form ref="form" :model="model">
|
||||
<view>
|
||||
<view class="font-400 text-30rpx text-[#606266] leading-44rpx">手机号</view>
|
||||
<view class="mt-20rpx">
|
||||
<wd-input
|
||||
v-model="model.mobile"
|
||||
type="text"
|
||||
placeholder="请输入手机号码"
|
||||
inputmode="numeric"
|
||||
no-border
|
||||
custom-class="!bg-[#F6F7F8] !border !border-solid !border-[#EAECF0] !rounded-16rpx"
|
||||
custom-input-class="!px-32rpx !h-104rpx"
|
||||
@input="mobile.handleInputMobile"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="mt-40rpx">
|
||||
<view class="font-400 text-30rpx text-[#606266] leading-44rpx">验证码</view>
|
||||
<view class="mt-20rpx">
|
||||
<wd-input type="text" placeholder="请输入验证码" v-model="model.code" inputmode="numeric" no-border custom-class="!bg-[#F6F7F8] !border !border-solid !border-[#EAECF0] !rounded-16rpx" custom-input-class="!px-32rpx !h-104rpx">
|
||||
<template #suffix>
|
||||
<view class="flex items-center mr-34rpx">
|
||||
<view class="flex items-center">
|
||||
<wd-divider color="#C9C9C9" vertical />
|
||||
</view>
|
||||
|
||||
<view class="flex items-center">
|
||||
<view class="text-[#4C9F44] text-32rpx font-400 leading-44rpx" v-if="!startCountDown" @click="mobile.handleCountDown">发送验证码</view>
|
||||
<view class="!text-[#C9C9C9] text-32rpx font-400 leading-44rpx flex items-center" v-if="startCountDown">
|
||||
<wd-count-down ref="countDown" :time="countDownTime" millisecond :auto-start="false" format="ss" custom-class="!text-[#C9C9C9] !text-32rpx" @finish="mobile.handleFinishCountDown"></wd-count-down>
|
||||
<view> S后重发</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</wd-input>
|
||||
</view>
|
||||
</view>
|
||||
</wd-form>
|
||||
</view>
|
||||
|
||||
<view class="h-90rpx leading-90rpx mx-60rpx rounded-8rpx text-center mt-112rpx bg-[#4C9F44] text-[#fff]" :class="disabled ? 'opacity-40' : ''" @click="mobile.handleToLogin">下一步</view>
|
||||
|
||||
<!-- 手机号修改成功 -->
|
||||
<wd-popup v-model="showEditSuccessPopup" lock-scroll custom-style="border-radius: 32rpx 32rpx 0rpx 0rpx;" position="bottom">
|
||||
<view class="relative pt-64rpx pb-74rpx">
|
||||
<view class="flex justify-center items-center">
|
||||
<view class="bg-[#4C9F44] w-280rpx rounded-280rpx">
|
||||
<wd-img width="280rpx" height="280rpx" :src="`${OSS}images/reserve_room/reserve_room_image7.png`"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="text-[#303133] text-36rpx leading-46rpx text-center mt-48rpx">手机号修改成功</view>
|
||||
<view class="text-[#9CA3AF] text-28rpx leading-44rpx mt-16rpx text-center">{{ page.desc }}</view>
|
||||
<view class="w-630rpx h-90rpx leading-90rpx text-center bg-[#4C9F44] rounded-8rpx text-[#fff] mt-174rpx mx-auto" @click="mobile.handleToBack">好的</view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {mobile as testMobile} from '@/utils/test'
|
||||
import { useToast } from 'wot-design-uni'
|
||||
|
||||
const OSS = inject('OSS')
|
||||
const toast = useToast()
|
||||
const disabled = ref<boolean>(true)
|
||||
|
||||
/** 页面 **/
|
||||
let pageType = 'login' // 页面类型 login:登录 edit:修改手机号
|
||||
const page = ref<{title: string, desc: string}>({title: '其他手机号登录', desc: '请输入你要登录的手机号'})
|
||||
const showEditSuccessPopup = ref<boolean>(false) // 显示手机号修改成功弹窗
|
||||
const userId = ref<number>(0) // 用户ID,修改手机号时需要传
|
||||
|
||||
/** 验证码倒计时 **/
|
||||
const countDownTime = ref<number>(1 * 60 * 1000) // 60s倒计时
|
||||
const startCountDown = ref<boolean>(false) // 是否开始倒计时
|
||||
const countDown = ref<any>(null) // 倒计时组件
|
||||
|
||||
/** 表单相关 **/
|
||||
const model = reactive<{
|
||||
mobile: string
|
||||
code: string
|
||||
}>({
|
||||
mobile: '',
|
||||
code: ''
|
||||
})
|
||||
/** 结束 **/
|
||||
|
||||
/** 服务协议和隐私政策 **/
|
||||
const agree = ref<boolean>(false)
|
||||
/** 结束 **/
|
||||
|
||||
onLoad((args) => {
|
||||
// 从个人登录页面进入
|
||||
if (args.type === 'edit') {
|
||||
userId.value = Number(args.userId) || 0 // userId仅做测试使用,实际请传真实用户ID
|
||||
|
||||
page.value.title = '修改手机号'
|
||||
page.value.desc = '手机号一年内可修改2次'
|
||||
pageType = 'edit'
|
||||
}
|
||||
})
|
||||
|
||||
const mobile = {
|
||||
// 验证手机号
|
||||
handleInputMobile: (e: {value: string}) => {
|
||||
model.mobile = e.value
|
||||
disabled.value = !testMobile(model.mobile)
|
||||
},
|
||||
|
||||
// 发送验证码
|
||||
handleCountDown: () => {
|
||||
if (disabled.value) {
|
||||
toast.show({
|
||||
iconClass: 'info-circle',
|
||||
msg: '手机号码错误请重新输入',
|
||||
direction: 'vertical'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
startCountDown.value = true
|
||||
nextTick(() => {
|
||||
countDown.value?.start()
|
||||
|
||||
// 发送验证码请求
|
||||
})
|
||||
},
|
||||
|
||||
// 验证码倒计时结束
|
||||
handleFinishCountDown: () => {
|
||||
startCountDown.value = false
|
||||
},
|
||||
|
||||
// 登录
|
||||
handleToLogin: () => {
|
||||
// TODO 如果是edit的话就是修改手机号
|
||||
if (!testMobile(model.mobile)) {
|
||||
toast.show({
|
||||
iconClass: 'info-circle',
|
||||
msg: '手机号码错误请重新输入',
|
||||
direction: 'vertical'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (!model.code) {
|
||||
toast.show({
|
||||
iconClass: 'info-circle',
|
||||
msg: '验证码错误',
|
||||
direction: 'vertical'
|
||||
})
|
||||
return
|
||||
}
|
||||
},
|
||||
|
||||
// 获取手机号
|
||||
handleGetPhoneNumber: (e: object) => {
|
||||
console.log("🚀 ~ e:", e)
|
||||
},
|
||||
|
||||
handleAgree: (e: any) => {
|
||||
console.log('e', e)
|
||||
},
|
||||
|
||||
// 跳转到服务协议页面
|
||||
handleToService: () => {
|
||||
disabled.value = !disabled.value
|
||||
console.log("🚀 ~ disabled:", disabled)
|
||||
},
|
||||
|
||||
// 跳转到隐私政策页面
|
||||
handleToPrivacy: () => {
|
||||
|
||||
},
|
||||
|
||||
// 修改手机成功后返回
|
||||
handleToBack: () => {
|
||||
uni.navigateBack()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.service {
|
||||
:deep() {
|
||||
.wd-checkbox {
|
||||
display: flex;
|
||||
align-content: flex-start;
|
||||
}
|
||||
|
||||
.wd-checkbox__label {
|
||||
margin-left: 6rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,6 +1,5 @@
|
||||
<route lang="jsonc" type="page">
|
||||
{
|
||||
"needLogin": true,
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
@ -101,7 +100,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 修改手机号 -->
|
||||
<view class="flex justify-between items-center" @click="Profile.handleToEditMobile">
|
||||
<view class="flex justify-between items-center mb-54rpx" @click="Profile.handleToEditMobile">
|
||||
<view class="font-400 text-[#303133] text-30rpx leading-42rpx">修改手机号</view>
|
||||
<view class="flex justify-end">
|
||||
<view class="flex items-center">
|
||||
@ -114,6 +113,36 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 修改手机号 -->
|
||||
<view class="flex justify-between items-center mb-54rpx" @click="router.navigateTo('/bundle/profile/change-password')">
|
||||
<view class="font-400 text-[#303133] text-30rpx leading-42rpx">修改手机号</view>
|
||||
<view class="flex justify-end">
|
||||
<view class="flex items-center">
|
||||
<view class="font-400 text-[#303133] text-30rpx leading-42rpx">
|
||||
{{ user.nickname }}
|
||||
</view>
|
||||
<view>
|
||||
<wd-icon name="arrow-right" size="32rpx" color="#C0C4CC" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 修改绑定用户 -->
|
||||
<view class="flex justify-between items-center" @click="router.navigateTo('/bundle/profile/change-password')">
|
||||
<view class="font-400 text-[#303133] text-30rpx leading-42rpx">修改绑定用户</view>
|
||||
<view class="flex justify-end">
|
||||
<view class="flex items-center">
|
||||
<view class="font-400 text-[#303133] text-30rpx leading-42rpx">
|
||||
{{ user.nickname }}
|
||||
</view>
|
||||
<view>
|
||||
<wd-icon name="arrow-right" size="32rpx" color="#C0C4CC" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bg-white rounded-16rpx mt-144rpx mx-30rpx px-30rpx py-32rpx text-center font-400 text-[#303133] text-30rpx leading-42rpx" @click="showLogoutPopup = true">
|
||||
@ -166,7 +195,7 @@
|
||||
onLoad(() => {
|
||||
token.value = uni.getStorageSync('token')
|
||||
|
||||
Profile.handleInit()
|
||||
// Profile.handleInit()
|
||||
})
|
||||
|
||||
const Profile = {
|
||||
|
||||
223
src/bundle/profile/set-password.vue
Normal file
223
src/bundle/profile/set-password.vue
Normal file
@ -0,0 +1,223 @@
|
||||
<route lang="jsonc" type="page">{
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"navigationBarBackgroundColor": "#fff"
|
||||
}
|
||||
}</route>
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<view class="mx-60rpx mt-20rpx">
|
||||
<view class="text-[#303133] text-48rpx leading-80rpx font-600">
|
||||
设置新密码
|
||||
</view>
|
||||
<view class="font-400 text-28rpx leading-44rpx text-[#6B7280] mt-12rpx">请设置你得新密码</view>
|
||||
</view>
|
||||
<view class="mt-106rpx mx-48rpx">
|
||||
<wd-form ref="form" :model="model">
|
||||
<view>
|
||||
<view class="font-400 text-30rpx text-[#606266] leading-44rpx">密码</view>
|
||||
<view class="mt-20rpx">
|
||||
<wd-input
|
||||
v-model="model.mobile"
|
||||
type="text"
|
||||
placeholder="请输入密码"
|
||||
inputmode="numeric"
|
||||
no-border
|
||||
custom-class="!bg-[#F6F7F8] !border !border-solid !border-[#EAECF0] !rounded-16rpx"
|
||||
custom-input-class="!px-32rpx !h-104rpx"
|
||||
@input="mobile.handleInputMobile"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view>
|
||||
<view class="font-400 text-30rpx text-[#606266] leading-44rpx">再次确认</view>
|
||||
<view class="mt-20rpx">
|
||||
<wd-input
|
||||
v-model="model.mobile"
|
||||
type="text"
|
||||
placeholder="再次确认新的密码"
|
||||
inputmode="numeric"
|
||||
no-border
|
||||
custom-class="!bg-[#F6F7F8] !border !border-solid !border-[#EAECF0] !rounded-16rpx"
|
||||
custom-input-class="!px-32rpx !h-104rpx"
|
||||
@input="mobile.handleInputMobile"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</wd-form>
|
||||
</view>
|
||||
|
||||
<view class="h-90rpx leading-90rpx mx-60rpx rounded-8rpx text-center mt-112rpx bg-[#4C9F44] text-[#fff]" :class="disabled ? 'opacity-40' : ''" @click="mobile.handleToLogin">确定</view>
|
||||
|
||||
<!-- 手机号修改成功 -->
|
||||
<wd-popup v-model="showEditSuccessPopup" lock-scroll custom-style="border-radius: 32rpx 32rpx 0rpx 0rpx;" position="bottom">
|
||||
<view class="relative pt-64rpx pb-74rpx">
|
||||
<view class="flex justify-center items-center">
|
||||
<view class="bg-[#4C9F44] w-280rpx rounded-280rpx">
|
||||
<wd-img width="280rpx" height="280rpx" :src="`${OSS}images/reserve_room/reserve_room_image7.png`"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="text-[#303133] text-36rpx leading-46rpx text-center mt-48rpx">密码修改成功</view>
|
||||
<view class="text-[#9CA3AF] text-28rpx leading-44rpx mt-16rpx text-center">请记住你的登录密码</view>
|
||||
<view class="w-630rpx h-90rpx leading-90rpx text-center bg-[#4C9F44] rounded-8rpx text-[#fff] mt-174rpx mx-auto" @click="mobile.handleToBack">好的</view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {mobile as testMobile} from '@/utils/test'
|
||||
import { useToast } from 'wot-design-uni'
|
||||
|
||||
const OSS = inject('OSS')
|
||||
const toast = useToast()
|
||||
const disabled = ref<boolean>(true)
|
||||
|
||||
/** 页面 **/
|
||||
let pageType = 'login' // 页面类型 login:登录 edit:修改手机号
|
||||
const page = ref<{title: string, desc: string}>({title: '其他手机号登录', desc: '请输入你要登录的手机号'})
|
||||
const showEditSuccessPopup = ref<boolean>(false) // 显示手机号修改成功弹窗
|
||||
const userId = ref<number>(0) // 用户ID,修改手机号时需要传
|
||||
|
||||
/** 验证码倒计时 **/
|
||||
const countDownTime = ref<number>(1 * 60 * 1000) // 60s倒计时
|
||||
const startCountDown = ref<boolean>(false) // 是否开始倒计时
|
||||
const countDown = ref<any>(null) // 倒计时组件
|
||||
|
||||
/** 表单相关 **/
|
||||
const model = reactive<{
|
||||
mobile: string
|
||||
code: string
|
||||
}>({
|
||||
mobile: '',
|
||||
code: ''
|
||||
})
|
||||
/** 结束 **/
|
||||
|
||||
/** 服务协议和隐私政策 **/
|
||||
const agree = ref<boolean>(false)
|
||||
/** 结束 **/
|
||||
|
||||
onLoad((args) => {
|
||||
// 从个人登录页面进入
|
||||
if (args.type === 'edit') {
|
||||
userId.value = Number(args.userId) || 0 // userId仅做测试使用,实际请传真实用户ID
|
||||
|
||||
page.value.title = '修改手机号'
|
||||
page.value.desc = '手机号一年内可修改2次'
|
||||
pageType = 'edit'
|
||||
}
|
||||
})
|
||||
|
||||
const mobile = {
|
||||
// 验证手机号
|
||||
handleInputMobile: (e: {value: string}) => {
|
||||
model.mobile = e.value
|
||||
disabled.value = !testMobile(model.mobile)
|
||||
},
|
||||
|
||||
// 发送验证码
|
||||
handleCountDown: () => {
|
||||
if (disabled.value) {
|
||||
toast.show({
|
||||
iconClass: 'info-circle',
|
||||
msg: '手机号码错误请重新输入',
|
||||
direction: 'vertical'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
startCountDown.value = true
|
||||
nextTick(() => {
|
||||
countDown.value?.start()
|
||||
|
||||
// 发送验证码请求
|
||||
})
|
||||
},
|
||||
|
||||
// 验证码倒计时结束
|
||||
handleFinishCountDown: () => {
|
||||
startCountDown.value = false
|
||||
},
|
||||
|
||||
// 登录
|
||||
handleToLogin: () => {
|
||||
// TODO 如果是edit的话就是修改手机号
|
||||
|
||||
if (pageType === 'login' && !agree.value) {
|
||||
toast.show({
|
||||
iconClass: 'info-circle',
|
||||
msg: '请同意服务协议和隐私政策',
|
||||
direction: 'vertical'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (!testMobile(model.mobile)) {
|
||||
toast.show({
|
||||
iconClass: 'info-circle',
|
||||
msg: '手机号码错误请重新输入',
|
||||
direction: 'vertical'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (!model.code) {
|
||||
toast.show({
|
||||
iconClass: 'info-circle',
|
||||
msg: '验证码错误',
|
||||
direction: 'vertical'
|
||||
})
|
||||
return
|
||||
}
|
||||
},
|
||||
|
||||
// 获取手机号
|
||||
handleGetPhoneNumber: (e: object) => {
|
||||
console.log("🚀 ~ e:", e)
|
||||
},
|
||||
|
||||
handleAgree: (e: any) => {
|
||||
console.log('e', e)
|
||||
},
|
||||
|
||||
// 跳转到服务协议页面
|
||||
handleToService: () => {
|
||||
disabled.value = !disabled.value
|
||||
console.log("🚀 ~ disabled:", disabled)
|
||||
},
|
||||
|
||||
// 跳转到隐私政策页面
|
||||
handleToPrivacy: () => {
|
||||
|
||||
},
|
||||
|
||||
// 修改手机成功后返回
|
||||
handleToBack: () => {
|
||||
uni.navigateBack()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.service {
|
||||
:deep() {
|
||||
.wd-checkbox {
|
||||
display: flex;
|
||||
align-content: flex-start;
|
||||
}
|
||||
|
||||
.wd-checkbox__label {
|
||||
margin-left: 6rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -428,7 +428,6 @@
|
||||
|
||||
.add-textarea {
|
||||
:deep() {
|
||||
|
||||
.wd-textarea__value,
|
||||
.wd-textarea__count {
|
||||
background: transparent !important;
|
||||
|
||||
547
src/bundle/setmeal/detail.vue
Normal file
547
src/bundle/setmeal/detail.vue
Normal file
@ -0,0 +1,547 @@
|
||||
<!-- 使用 type="home" 属性设置首页,其他页面不需要设置,默认为page -->
|
||||
<route lang="jsonc" type="page">{
|
||||
"needLogin": true,
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
}</route>
|
||||
<template>
|
||||
<view class="pb-180rpx">
|
||||
<!-- 费用明细 -->
|
||||
<wd-popup v-model="showCostPopup" lock-scroll custom-style="border-radius: 32rpx 32rpx 0rpx 0rpx;" @close="showCostPopup = false" position="bottom">
|
||||
<view class='bg-[#FBFBFB] py-40rpx realtive'>
|
||||
<view class="absolute top-18rpx right-30rpx" @click="showCostPopup = false">
|
||||
<wd-img width="60rpx" height='60rpx' :src="`${OSS}icon/icon_close.png`"></wd-img>
|
||||
</view>
|
||||
<view class="text-36rpx text-[#121212] leading-50rpx text-center">费用明细</view>
|
||||
<view class="mx-30rpx bg-white rounded-16rpx px-30rpx pt-40rpx mt-40rpx pb-30rpx">
|
||||
<view class="flex justify-between items-center text-30rpx text-[#303133] leading-42rpx">
|
||||
<view>茶室费</view>
|
||||
<view>¥{{ bill.service.total }}</view>
|
||||
</view>
|
||||
|
||||
<view class="flex justify-between items-center text-24rpx text-[#909399] leading-34rpx mt-16rpx">
|
||||
<view>茶室费(¥{{ teaRoomPrice }}元/小时)</view>
|
||||
<view>x{{ bill.service.num }}</view>
|
||||
</view>
|
||||
|
||||
<view class="mt-52rpx">
|
||||
<view class="flex justify-between items-center text-30rpx text-[#303133] leading-42rpx">
|
||||
<view>优惠</view>
|
||||
<view class="text-[#4C9F44]">-¥{{ bill.totalDiscount }}</view>
|
||||
</view>
|
||||
<view class="flex justify-between items-center text-24rpx text-[#909399] leading-34rpx mt-16rpx">
|
||||
<view>优惠券</view>
|
||||
<view>-¥{{ bill.coupon || 0 }}</view>
|
||||
</view>
|
||||
<view class="flex justify-between items-center text-24rpx text-[#909399] leading-34rpx mt-16rpx">
|
||||
<view>团购券</view>
|
||||
<view>-¥{{ bill.groupCoupon || 0 }}</view>
|
||||
</view>
|
||||
<view class="flex justify-between items-center text-24rpx text-[#909399] leading-34rpx mt-16rpx">
|
||||
<view>会员八折</view>
|
||||
<view>-¥{{ bill.discount || 0 }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="my-30rpx">
|
||||
<wd-gap height="2rpx" bgColor='#F6F7F9'></wd-gap>
|
||||
</view>
|
||||
|
||||
<view class="flex justify-between items-center text-30rpx text-[#303133] leading-42rpx">
|
||||
<view>实付金额</view>
|
||||
<view>¥{{ bill.total }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
|
||||
<!-- 支付 -->
|
||||
<wd-popup v-model="showPayPopup" lock-scroll custom-style="border-radius: 32rpx 32rpx 0rpx 0rpx;" @close="showPayPopup = false" position="bottom">
|
||||
<view class='bg-[#FBFBFB] py-40rpx realtive'>
|
||||
<view class="absolute top-18rpx right-30rpx" @click="showPayPopup = false">
|
||||
<wd-img width="60rpx" height='60rpx' :src="`${OSS}icon/icon_close.png`"></wd-img>
|
||||
</view>
|
||||
<view class="text-36rpx text-[#121212] leading-50rpx text-center">支付</view>
|
||||
<view class="mx-30rpx bg-white rounded-16rpx px-30rpx pt-40rpx mt-40rpx pb-30rpx">
|
||||
<wd-radio-group v-model="pay" shape="dot" checked-color="#4C9F44">
|
||||
<view class="pay" v-for="(item, index) in payList" :key="index" @click="pay = item.id">
|
||||
<view class="flex justify-between items-center" v-if="pay == item.value" >
|
||||
<view class="flex items-center">
|
||||
<wd-img width="50rpx" height="50rpx" :src="item.icon"></wd-img>
|
||||
<view class="ml-20rpx text-30rpx text-[#303133] leading-42rpx">{{ item.name }}</view>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<wd-radio :value="item.value">
|
||||
<view class="text-[#303133] text-26rpx leading-36rpx mr-20rpx">可用202.22</view>
|
||||
</wd-radio>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</wd-radio-group>
|
||||
</view>
|
||||
|
||||
<view class='bg-[#4C9F44] text-[#fff] rounded-8rpx h-90rpx leading-90rpx mx-60rpx box-border text-center mt-170rpx' @click="Detail.handlePay">确定付款</view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
|
||||
<!-- 选择预定时间 -->
|
||||
<booking-time v-model="showBookTimePopup" :day="sevenDay" @selectedTime="Detail.handleChooseReserveTime"></booking-time>
|
||||
|
||||
<view>
|
||||
<navbar :title="isGroupBuying ? '团购套餐' : '预定'" custom-class='!bg-[#F6F7F8]'></navbar>
|
||||
</view>
|
||||
|
||||
<view>
|
||||
<view class="mt-20rpx mx-30rpx swiper">
|
||||
<wd-swiper value-key="image" height="320rpx"
|
||||
:indicator="{ type: 'dots-bar' }" :list="swiperList" v-model:current="current" mode="aspectFit">
|
||||
</wd-swiper>
|
||||
</view>
|
||||
|
||||
<view class="bg-white rounded-16rpx py-26rpx px-30rpx mt-24rpx mx-30rpx">
|
||||
<view class="font-bold text-36rpx text-[#303133] leading-50rpx">{{ isGroupBuying ? teaRoomPackage.title : teaRoom.name }}</view>
|
||||
<view class="mt-14rpx flex" v-if="!isGroupBuying">
|
||||
<template v-for="(label, labelIndex) in teaRoom.label" :key="labelIndex">
|
||||
<view class="mr-20rpx flex items-start" v-if="label.category_id == 1">
|
||||
<wd-tag color="#40AE36" bg-color="#40AE36" plain custom-class="!rounded-4rpx">文艺小清新</wd-tag>
|
||||
</view>
|
||||
<view class="flex items-start" v-if="label.category_id == 2">
|
||||
<wd-tag color="#F55726" bg-color="#F55726" plain>全息投影</wd-tag>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
<view class="flex justify-between items-center" :class="`${ isGroupBuying ? 'mt-24rpx' : ''}`">
|
||||
<view class="text-[#303133] text-26rpx leading-48rpx font-500" v-if="isGroupBuying">{{ teaRoomPackage.introduce }}</view>
|
||||
<!-- <view class="text-[#6A6363] flex-1 text-22rpx leading-32rpx text-right">已售 10+</view> -->
|
||||
</view>
|
||||
<view v-if="isGroupBuying">
|
||||
<view class="mt-20rpx mb-24rpx" >
|
||||
<wd-gap height="2rpx" bgColor="#F6F7F9"></wd-gap>
|
||||
</view>
|
||||
<view class="text-[#303133] text-28rpx leading-48rpx">
|
||||
<rich-text :nodes="teaRoomPackage.details"></rich-text>
|
||||
<!-- <view>
|
||||
<text class="font-bold mr-26rpx">须知</text>
|
||||
<text class="font-500">{{ teaRoomPackage.details }}</text>
|
||||
</view>
|
||||
<view class="mt-22rpx">
|
||||
<text class="font-bold mr-26rpx">保障</text>
|
||||
<text class="font-500">随时退</text>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="!isGroupBuying">
|
||||
<!-- 使用说明 -->
|
||||
<view class="bg-white rounded-16rpx py-26rpx px-30rpx mt-24rpx mx-30rpx">
|
||||
<view class="text-[#303133] text-32rpx leading-44rpx font-bold mb-24rpx">使用说明</view>
|
||||
<view class="">
|
||||
<rich-text :nodes="teaRoom.textarea1"></rich-text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 预定时间 -->
|
||||
<view class="bg-white rounded-16rpx py-26rpx px-30rpx mt-24rpx mx-30rpx" @click="showBookTimePopup = true">
|
||||
<view class="text-[#303133] text-32rpx leading-44rpx font-bold mb-24rpx">预定时间</view>
|
||||
<view class="flex items-center justify-between">
|
||||
<view class="text-[26rpx] text-[#606266] leading-36rpx">{{ sevenDay.minimum_time }}小时起订</view>
|
||||
<view class="flex items-center">
|
||||
<view class="text-[28rpx] text-[#909399] leading-40rpx w-430rpx line-1 text-right">
|
||||
<template v-if="reserveTime.length > 0">
|
||||
{{ reserveTime[0] }} {{ reserveTime[1].join(',') }}
|
||||
</template>
|
||||
<template v-else>
|
||||
请选择
|
||||
</template>
|
||||
</view>
|
||||
<view>
|
||||
<wd-icon name="chevron-right" size="32rpx" color="#909399"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 优惠券 -->
|
||||
<view class="bg-white rounded-16rpx py-26rpx px-30rpx mt-24rpx mx-30rpx" @click="Detail.handleToCoupon(CouponType.Discount)">
|
||||
<view class="text-[#303133] text-32rpx leading-44rpx font-bold mb-24rpx">优惠券</view>
|
||||
<view class="flex items-center justify-between">
|
||||
<view class="text-[26rpx] text-[#606266] leading-36rpx">优惠券</view>
|
||||
<view class="flex items-center">
|
||||
<view class="text-[28rpx] text-[#909399] leading-40rpx">
|
||||
<template v-if="selectedCoupon?.id > 0">
|
||||
{{ selectedCoupon.name }}
|
||||
</template>
|
||||
<template v-else>
|
||||
请选择
|
||||
</template>
|
||||
</view>
|
||||
<view class="mt-4rpx">
|
||||
<wd-icon name="chevron-right" size="22px" color="#909399"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 团购券 -->
|
||||
<view class="bg-white rounded-16rpx py-26rpx px-30rpx mt-24rpx mx-30rpx" @click="Detail.handleToCoupon(CouponType.GroupBuy)">
|
||||
<view class="text-[#303133] text-32rpx leading-44rpx font-bold mb-24rpx">团购券</view>
|
||||
<view class="flex items-center justify-between">
|
||||
<view class="text-[26rpx] text-[#606266] leading-36rpx">团购券</view>
|
||||
<view class="flex items-center">
|
||||
<view class="text-[28rpx] text-[#909399] leading-40rpx">
|
||||
<template v-if="selectedGroupCoupon?.id > 0">
|
||||
{{ selectedGroupCoupon.name }}
|
||||
</template>
|
||||
<template v-else>
|
||||
请选择
|
||||
</template>
|
||||
</view>
|
||||
<view class="mt-4rpx">
|
||||
<wd-icon name="chevron-right" size="22px" color="#909399"></wd-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="isGroupBuying">
|
||||
<!-- 套餐详情 -->
|
||||
<view class="bg-white rounded-16rpx py-26rpx px-30rpx mt-24rpx mx-30rpx">
|
||||
<view class="text-[#303133] text-32rpx leading-44rpx font-bold mb-24rpx">套餐详情</view>
|
||||
<view class="">
|
||||
<rich-text :nodes="teaRoomPackage.introduce_details"></rich-text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 购买须知 -->
|
||||
<view class="bg-white rounded-16rpx py-26rpx px-30rpx mt-24rpx mx-30rpx">
|
||||
<view class="text-[#303133] text-32rpx leading-44rpx font-bold mb-24rpx">购买须知</view>
|
||||
<view class="">
|
||||
<rich-text :nodes="teaRoomPackage.buy_details"></rich-text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {toast} from '@/utils/toast'
|
||||
import { ReserveServiceCategory, OrderType } from '@/utils/order'
|
||||
import type { ITeaSpecialistFuture7DaysResult } from '@/api/types/tea'
|
||||
import { getNext7Days, getTeaRoomBalance, createTeaRoomOrder } from '@/api/tea-room'
|
||||
import { CouponType } from '@/utils/coupon'
|
||||
import { router, toTimes, toPlus, toMinus } from '@/utils/tools'
|
||||
import type { IUserInfoVo } from '@/api/types/login'
|
||||
import { useUserStore } from '@/store'
|
||||
import { getTeaRoomDetail, createTeaRoomPackageOrder, getTeaRoomPackageDetail, calculateTeaRoomPrice } from '@/api/tea-room'
|
||||
import PriceFormat from '@/components/PriceFormat.vue'
|
||||
import BookingTime from '@/components/BookingTime.vue'
|
||||
import { getUserInfo } from '@/api/user'
|
||||
|
||||
const OSS = inject('OSS')
|
||||
|
||||
// 用户信息
|
||||
const userInfo = ref<IUserInfoVo>(null)
|
||||
|
||||
const swiperList = ref<string[]>([])
|
||||
const current = ref<number>(0)
|
||||
const html: string = '<p>这里是富文本内容,需要后台传递</p>'
|
||||
const isGroupBuying = ref<boolean>(false)// 是否是团购套餐
|
||||
const pay = ref<number>(1) // 支付方式
|
||||
const payList = ref<Array<any>>([
|
||||
{
|
||||
id: 1,
|
||||
name: '平台余额',
|
||||
icon: `${OSS}icon/icon_platform_balance.png`,
|
||||
balance: 0,
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '门店余额',
|
||||
icon: `${OSS}icon/icon_store_balance.png`,
|
||||
balance: 0,
|
||||
value: 2
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '微信支付',
|
||||
icon: `${OSS}icon/icon_weichat.png`,
|
||||
balance: 0,
|
||||
value: 3
|
||||
}
|
||||
])
|
||||
|
||||
// 选择预定时间
|
||||
const showBookTimePopup = ref<boolean>(false)
|
||||
const sevenDay = reactive<ITeaSpecialistFuture7DaysResult>({
|
||||
minimum_time: 0,
|
||||
time: []
|
||||
})
|
||||
const reserveTime = ref<Array<any>>([])
|
||||
|
||||
// 计算费用明细 service(服务费) coupon(优惠券) discount(会员优惠) totalDiscount(总优惠) total(总费用) groupCoupon(团购券)
|
||||
const bill = ref<{service: any, discount:number, totalDiscount: number, coupon: number, groupCoupon: number, total: number}>({
|
||||
service: {
|
||||
total: 0,
|
||||
unitPrice: 0,
|
||||
num: 0,
|
||||
startTime: 0,
|
||||
endTime: 0,
|
||||
dayTime: '',
|
||||
startHour: '',
|
||||
endHour: ''
|
||||
},
|
||||
discount: 0,
|
||||
totalDiscount: 0,
|
||||
coupon: 0,
|
||||
groupCoupon: 0,
|
||||
total: 0
|
||||
})
|
||||
|
||||
// 费用明细相关
|
||||
const showCostPopup = ref<boolean>(false) // 费用明细popup
|
||||
const showPayPopup = ref<boolean>(false) // 支付popup
|
||||
|
||||
// 包间内容
|
||||
const storeId = ref<number>(0) // 门店ID
|
||||
const id = ref<number>(0) // id
|
||||
const teaRoom = ref<any>({})
|
||||
const teaRoomPrice = ref<number>(0)
|
||||
|
||||
// 门店余额
|
||||
const storeMoney = ref<number>(0)
|
||||
|
||||
// 选择的优惠券
|
||||
const selectedCoupon = ref<{id: number, name: string}>({id: 0, name: ''})
|
||||
const selectedGroupCoupon = ref<{id: number, name: string}>({id: 0, name: ''})
|
||||
|
||||
// 用户信息
|
||||
const user = ref<any>(null)
|
||||
|
||||
// 套餐
|
||||
const teaRoomPackage = ref<any>({})
|
||||
|
||||
onLoad((args) => {
|
||||
storeId.value = Number(args.storeId)
|
||||
id.value = Number(args.id)
|
||||
teaRoomPrice.value = Number(args.price) || 0
|
||||
|
||||
if (args.type == ReserveServiceCategory.GroupBuying) {
|
||||
isGroupBuying.value = true
|
||||
pay.value = 3
|
||||
Detail.handleInitGroupBuying()
|
||||
}
|
||||
Detail.handleInitReserveRoom()
|
||||
|
||||
// 获取用户需求详
|
||||
getUserInfo().then(res => {
|
||||
user.value = res
|
||||
})
|
||||
})
|
||||
|
||||
const Detail = {
|
||||
/**
|
||||
* 初始包间详情
|
||||
*/
|
||||
handleInitReserveRoom: async () => {
|
||||
// 包间详情
|
||||
const userStore = useUserStore()
|
||||
userInfo.value = userStore.userInfo
|
||||
|
||||
const res = await getTeaRoomDetail({
|
||||
id: storeId.value,
|
||||
latitude: uni.getStorageSync('latitude'),
|
||||
longitude: uni.getStorageSync('longitude'),
|
||||
user_id: userInfo.value.id || 0
|
||||
})
|
||||
teaRoom.value = res.details
|
||||
swiperList.value = teaRoom.value.img_arr
|
||||
|
||||
// 预定时间
|
||||
const next7 = await getNext7Days()
|
||||
Object.assign(sevenDay, next7)
|
||||
|
||||
// 获取门店余额
|
||||
const balance = await getTeaRoomBalance({ store_id: storeId.value })
|
||||
storeMoney.value = balance.data.money || 0
|
||||
},
|
||||
|
||||
/*
|
||||
* 初始化套餐详情
|
||||
*/
|
||||
handleInitGroupBuying: async () => {
|
||||
const res = await getTeaRoomPackageDetail({ id: id.value })
|
||||
teaRoomPackage.value = res.details
|
||||
},
|
||||
|
||||
/**
|
||||
* 选中预定时间
|
||||
*/
|
||||
handleChooseReserveTime: (params: any) => {
|
||||
reserveTime.value = params
|
||||
|
||||
bill.value.service = {
|
||||
total: 0,
|
||||
unitPrice: 0,
|
||||
num: params[3],
|
||||
startTime: params[2][0],
|
||||
endTime: params[2][params[2].length - 1],
|
||||
dayTime: params[0],
|
||||
startHour: params[1][0],
|
||||
endHour: params[1][params[1].length - 1]
|
||||
}
|
||||
|
||||
Detail.handleCalculateTeaRoomPrice()
|
||||
},
|
||||
|
||||
/**
|
||||
* 跳转优惠券页面
|
||||
*/
|
||||
handleToCoupon(type) {
|
||||
if (reserveTime.value.length == 0) {
|
||||
toast.info('请选择预定时间')
|
||||
return
|
||||
}
|
||||
uni.$on('chooseCoupon', params => {
|
||||
console.log("🚀 ~ params:", params)
|
||||
uni.$off('chooseCoupon')
|
||||
|
||||
if (type === CouponType.Discount) {
|
||||
selectedCoupon.value = {id: params.coupon.user_coupon_id, name: `${params.coupon.name}减${params.coupon.coupon_price}` }
|
||||
bill.value.coupon = params.coupon.coupon_price
|
||||
} else {
|
||||
selectedGroupCoupon.value = {id: params.coupon.id, name: `团购券-${params.coupon.tea_store_group.title}` }
|
||||
bill.value.groupCoupon = params.coupon.coupon_price
|
||||
}
|
||||
|
||||
Detail.handleCalculateTeaRoomPrice()
|
||||
})
|
||||
|
||||
// 获取预定了几个小时
|
||||
const count = bill.value.service.num
|
||||
router.navigateTo(`/bundle/coupon/coupon?id=${id.value}&numbers=${count}&type=${type}&storeId=${storeId.value}`)
|
||||
},
|
||||
|
||||
// 选择支付方式
|
||||
handleGetPayValue: (value: number) => {
|
||||
pay.value = value
|
||||
},
|
||||
|
||||
/**
|
||||
* 提交订单
|
||||
*/
|
||||
handleSubmitOrder: async () => {
|
||||
// 只有预定茶室才会选择时间
|
||||
if (!isGroupBuying.value && bill.value.service.num == 0) {
|
||||
toast.info('请选择预定时间')
|
||||
return
|
||||
}
|
||||
|
||||
uni.showLoading({
|
||||
title: '提交中...'
|
||||
})
|
||||
|
||||
try {
|
||||
let res: any = null
|
||||
if (isGroupBuying.value) {
|
||||
res = await createTeaRoomPackageOrder({
|
||||
group_id: id.value
|
||||
})
|
||||
} else {
|
||||
res = await createTeaRoomOrder({
|
||||
store_id: storeId.value,
|
||||
room_id: id.value,
|
||||
day_time: bill.value.service.dayTime,
|
||||
start_time: bill.value.service.startHour,
|
||||
end_time: bill.value.service.endHour,
|
||||
user_coupon_id: selectedCoupon.value.id || 0,
|
||||
hours: bill.value.service.num,
|
||||
group_coupon_id: selectedGroupCoupon.value.id || 0
|
||||
})
|
||||
}
|
||||
|
||||
uni.hideLoading()
|
||||
|
||||
// 支付后的处理
|
||||
uni.$on('payment', params => {
|
||||
setTimeout(() => {
|
||||
uni.$off("payment")
|
||||
if (params.result) {
|
||||
uni.redirectTo({
|
||||
url: `/pages/notice/reserve?type=${OrderType.TeaRoomOrder}&orderId=${params.orderId}&isGroupBuying=${isGroupBuying.value ? 1 : 0}`
|
||||
})
|
||||
} else {
|
||||
if (isGroupBuying.value) {
|
||||
router.redirectTo(`/bundle/order/platform/order-list`)
|
||||
} else {
|
||||
router.redirectTo(`/bundle/order/tea-room/order-list?isGroupBuying=${isGroupBuying.value ? 1 : 0}`)
|
||||
}
|
||||
}
|
||||
}, 1000)
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
const name = isGroupBuying.value ? teaRoomPackage.value.title : teaRoom.value.name
|
||||
|
||||
router.navigateTo(
|
||||
`/pages/cashier/cashier?from=${OrderType.TeaRoomOrder}&orderId=${res.id}&name=${name}&storeId=${storeId.value}&isGroupBuying=${isGroupBuying.value ? 1 : 0}`
|
||||
)
|
||||
}, 800)
|
||||
} catch (error) {
|
||||
uni.hideLoading()
|
||||
toast.info('订单提交失败,请稍后重试')
|
||||
return
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 计算茶室价格
|
||||
*/
|
||||
handleCalculateTeaRoomPrice: async () => {
|
||||
const res = await calculateTeaRoomPrice({
|
||||
room_id: id.value,
|
||||
coupon_id: selectedCoupon.value.id || 0,
|
||||
group_coupon_id: selectedGroupCoupon.value.id,
|
||||
nums: bill.value.service.num,
|
||||
})
|
||||
|
||||
bill.value.service.total = res.details.room_price // 茶室价格
|
||||
bill.value.discount = res.details.discount_room_price // 茶室总价
|
||||
bill.value.totalDiscount = res.details.discount_all_price // 总优惠
|
||||
bill.value.groupCoupon = res.details.group_price // 团购优惠
|
||||
bill.value.total = res.details.order_amount // 订单金额
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: $cz-page-background;
|
||||
}
|
||||
|
||||
.swiper {
|
||||
:deep() {
|
||||
.wd-swiper-nav__item--dots-bar {
|
||||
width: 56rpx !important;
|
||||
height: 6rpx !important;
|
||||
border-radius: 3rpx !important;
|
||||
}
|
||||
|
||||
.is-active {
|
||||
background-color: #2B9F93 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pay {
|
||||
:deep() {
|
||||
.wd-radio {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
99
src/bundle/user/bill-detail.vue
Normal file
99
src/bundle/user/bill-detail.vue
Normal file
@ -0,0 +1,99 @@
|
||||
<route lang="jsonc" type="page">{
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarBackgroundColor": "#fff"
|
||||
}
|
||||
}</route>
|
||||
|
||||
<template>
|
||||
<view class="pb-40rpx">
|
||||
<view>
|
||||
<navbar title="消费明细" custom-class="!bg-[#F6F7F9]"></navbar>
|
||||
</view>
|
||||
|
||||
<view class="mt-28rpx mx-32rpx">
|
||||
<mescroll-body ref="mescrollItem0" @init="mescrollInit" @down="downCallback" @up="BillDetail.upCallback" :down="downOption" :up="upOption">
|
||||
<view class="bg-white rounded-16rpx py-28rpx mb-20rpx">
|
||||
<view class="flex items-center">
|
||||
<view class="w-8rpx h-32rpx bg-[#4C9F44] mr-22rpx"></view>
|
||||
<view class="font-bold text-28rpx leading-40rpx text-[#303133]">订单号:1744601722882174</view>
|
||||
</view>
|
||||
<view class="mx-18rpx mt-16rpx mb-22rpx">
|
||||
<wd-gap height="2rpx" bg-color="#E5E5E5"></wd-gap>
|
||||
</view>
|
||||
<view class="flex items-center justify-between px-18rpx">
|
||||
<view class="font-400 text-28rpx text-[#606266] leading-40rpx">
|
||||
<view class="mb-16rpx">门店:茶址24小时-碧云店</view>
|
||||
<view class="mb-16rpx">类型:包间预定</view>
|
||||
<view class="mb-16rpx">支付方式:平台余额</view>
|
||||
<view>支付时间:2025-04-14 11:35</view>
|
||||
</view>
|
||||
<view class="text-right">
|
||||
<price-format weight="bold" color="#303133" :first-size="44" :second-size="44" :subscript-size="28" :price="23.02"></price-format>
|
||||
<view class="mt-6rpx font-400 text-28rpx leading-40rpx text-[#303133]">金额</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { toTimes, copy } from '@/utils/tools'
|
||||
import { router } from '@/utils/tools'
|
||||
import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
|
||||
import useMescroll from "@/uni_modules/mescroll-uni/hooks/useMescroll.js"
|
||||
|
||||
// mescroll
|
||||
const { mescrollInit, downCallback, getMescroll } = useMescroll(onPageScroll, onReachBottom) // 调用mescroll的hook
|
||||
const downOption = {
|
||||
auto: true
|
||||
}
|
||||
const upOption = {
|
||||
auto: true,
|
||||
textNoMore: '~ 已经到底啦 ~', //无更多数据的提示
|
||||
}
|
||||
const list = ref<Array<any>>([]) // 茶室列表
|
||||
|
||||
const OSS = inject('OSS')
|
||||
|
||||
const mark = ref<string>('')
|
||||
|
||||
onLoad((args) => {
|
||||
})
|
||||
|
||||
const BillDetail = {
|
||||
/**
|
||||
* 分页加载
|
||||
* @param mescroll
|
||||
*/
|
||||
upCallback: (mescroll) => {
|
||||
// 需要留一下数据为空的时候显示的空数据图标内容
|
||||
// getTeaRoomOrderList(filter).then((res) => {
|
||||
// const curPageData = res.list || [] // 当前页数据
|
||||
// if(mescroll.num == 1) list.value = [] // 第一页需手动制空列表
|
||||
// list.value = list.value.concat(curPageData) //追加新数据
|
||||
// mescroll.endSuccess(curPageData.length, Boolean(res.more))
|
||||
// }).catch(() => {
|
||||
mescroll.endErr() // 请求失败, 结束加载
|
||||
// })
|
||||
},
|
||||
|
||||
// 打电话
|
||||
handleCall: (phone) => {
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: phone
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: $cz-page-background;
|
||||
}
|
||||
|
||||
</style>
|
||||
132
src/bundle/user/user-detail.vue
Normal file
132
src/bundle/user/user-detail.vue
Normal file
@ -0,0 +1,132 @@
|
||||
<route lang="jsonc" type="page">{
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarBackgroundColor": "#fff"
|
||||
}
|
||||
}</route>
|
||||
|
||||
<template>
|
||||
<view class="pb-40rpx">
|
||||
<view>
|
||||
<navbar title="用户详情" custom-class="!bg-[#F6F7F9]"></navbar>
|
||||
</view>
|
||||
|
||||
<view class="mt-28rpx mx-30rpx">
|
||||
<view class="bg-white rounded-16rpx px-28rpx pt-40rpx pb-26rpx">
|
||||
<view>
|
||||
<view class="flex items-center">
|
||||
<wd-img width="140rpx" height='140rpx' src="https://shchazhi.oss-cn-hangzhou.aliyuncs.com/fronted/icon/icon_avatar.png" :round="true"></wd-img>
|
||||
<view class="ml-20rpx">
|
||||
<view class="flex items-center">
|
||||
<view class="font-bold text-28rpx text-[#303133] leading-40rpx mr-12rpx">用户昵称</view>
|
||||
<!-- TODO 如果是vip的话才显示这个皇冠 -->
|
||||
<view>
|
||||
<wd-img width="40rpx" height='40rpx' :src="`${OSS}icon/icon_crown.png`"></wd-img>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mt-18rpx font-400 text-28rpx text-[#303133] leading-40rpx">手机号:18857339563</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- TODO VIP显示这块内容 -->
|
||||
<view class="relative mt-22rpx">
|
||||
<wd-img width="650rpx" height='70rpx' :src="`${OSS}images/store/user/image1.png`"></wd-img>
|
||||
<view class="absolute top-18rpx left-28rpx flex items-center">
|
||||
<wd-img width="40rpx" height='40rpx' :src="`${OSS}icon/icon_vip.png`"></wd-img>
|
||||
<view class="font-400 text-24rpx text-[#EECC99] leading-34rpx ml-18rpx">2026.03.06到期</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="flex items-center justify-around px-90rpx mt-46rpx">
|
||||
<view class="flex flex-col items-center justify-start">
|
||||
<view class="font-400 text-24rpx text-[#606266] text-34rpx">平台余额</view>
|
||||
<view class="font-bold text-32rpx text-[#303133] leading-34rpx mt-34rpx">3,1.46</view>
|
||||
</view>
|
||||
<view class="h-98rpx">
|
||||
<wd-divider vertical color="#EAEEF2" custom-class="!h-98rpx"></wd-divider>
|
||||
</view>
|
||||
<view class="flex flex-col items-center justify-start">
|
||||
<view class="font-400 text-24rpx text-[#606266] text-34rpx">门店余额</view>
|
||||
<view class="font-bold text-32rpx text-[#303133] leading-34rpx mt-34rpx">3,662.46</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="mt-50rpx relative">
|
||||
<wd-img width="650rpx" height='216rpx' :src="`${OSS}images/store/user/image2.png`"></wd-img>
|
||||
<view class="absolute top-24rpx left-40rpx">
|
||||
<view class="">消费金额</view>
|
||||
<view class="mt-22rpx">
|
||||
<price-format color="#FF5951" :first-size="34" :second-size="34" :subscript-size="34" :price="23.02"></price-format>
|
||||
</view>
|
||||
<view
|
||||
@click="router.navigateTo('/bundle/user/bill-detail')"
|
||||
class="bg-[#3C7FFF] w-124rpx h-48rpx rounded-24rpx text-[#fff] text-center leading-48rpx text-28rpx font-bold mt-12rpx">
|
||||
去查看
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="mt-26rpx mb-18rpx">
|
||||
<wd-gap height="2rpx" bg-color="#E5E5E5"></wd-gap>
|
||||
</view>
|
||||
|
||||
<view class="font-400 text-26rpx text-[#9CA3AF] leading-36rpx">注册日期:2025-04-23</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bg-white rounded-16rpx px-30rpx pt-36rpx pb-34rpx mt-20rpx">
|
||||
<view class="flex items-center">
|
||||
<wd-img width="40rpx" height='40rpx' :src="`${OSS}icon/icon_qizhi.png`"></wd-img>
|
||||
<view class="text-30rpx leading-42rpx text-[#303133] ml-10rpx">备注</view>
|
||||
</view>
|
||||
|
||||
<view class="add-textarea">
|
||||
<wd-textarea v-model="mark"
|
||||
placeholder="有想说的可以在这里写哦!"
|
||||
custom-class='!rounded-18rpx !border-2rpx !border-[#EFF0EF] !bg-[#F8F9FA] !mt-20rpx'
|
||||
custom-textarea-class='!bg-[#F8F9FA] !h-100rpx' :maxlength='30' show-word-limit />
|
||||
</view>
|
||||
|
||||
<view class="bg-[#4C9F44] rounded-8rpx text-[#fff] w-626rpx h-90rpx text-center leading-90rpx mt-52rpx">修改备注</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { toTimes, copy } from '@/utils/tools'
|
||||
import { router } from '@/utils/tools'
|
||||
|
||||
const OSS = inject('OSS')
|
||||
|
||||
const mark = ref<string>('')
|
||||
|
||||
onLoad((args) => {
|
||||
})
|
||||
|
||||
const UserList = {
|
||||
// 打电话
|
||||
handleCall: (phone) => {
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: phone
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: $cz-page-background;
|
||||
}
|
||||
|
||||
.add-textarea {
|
||||
:deep() {
|
||||
.wd-textarea__value,
|
||||
.wd-textarea__count {
|
||||
background: transparent !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
103
src/bundle/user/user-list.vue
Normal file
103
src/bundle/user/user-list.vue
Normal file
@ -0,0 +1,103 @@
|
||||
<route lang="jsonc" type="page">{
|
||||
"layout": "default",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarBackgroundColor": "#fff"
|
||||
}
|
||||
}</route>
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<view>
|
||||
<navbar title="用户列表" custom-class="!bg-[transparent]"></navbar>
|
||||
</view>
|
||||
|
||||
<view>
|
||||
<mescroll-body ref="mescrollItem0" @init="mescrollInit" @down="downCallback" @up="UserList.upCallback" :down="downOption" :up="upOption">
|
||||
<view class="mb-22rpx">
|
||||
<view class="mx-64rpx flex justify-between items-center mb-10rpx">
|
||||
<view class="flex items-center" @click="router.navigateTo('/bundle/user/user-detail')">
|
||||
<wd-img width="100rpx" height='100rpx' src="https://shchazhi.oss-cn-hangzhou.aliyuncs.com/fronted/icon/icon_avatar.png" :round="true"></wd-img>
|
||||
<view class="ml-20rpx">
|
||||
<view class="flex items-center">
|
||||
<view class="font-bold text-28rpx text-[#303133] leading-40rpx mr-12rpx">用户昵称</view>
|
||||
<!-- TODO 如果是vip的话才显示这个皇冠 -->
|
||||
<view>
|
||||
<wd-img width="40rpx" height='40rpx' :src="`${OSS}icon/icon_crown.png`"></wd-img>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mt-14rpx font-400 text-26rpx text-[#303133] leading-36rpx">13525626532</view>
|
||||
<view class="mt-10rpx text-24rpx text-[#F29747] leading-34rpx w-400rpx line-1">这里是备注信息,备注信息这里是备注信息,备注信息</view>
|
||||
</view>
|
||||
</view>
|
||||
<view @click="UserList.handleCall">
|
||||
<wd-img width="64rpx" height='64rpx' :src="`${OSS}icon/icon_phone3.png`"></wd-img>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="mx-30rpx">
|
||||
<wd-gap height="2rpx" bg-color="#E5E5E5"></wd-gap>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { router } from '@/utils/tools'
|
||||
import { toTimes, copy } from '@/utils/tools'
|
||||
import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
|
||||
import useMescroll from "@/uni_modules/mescroll-uni/hooks/useMescroll.js"
|
||||
|
||||
// mescroll
|
||||
const { mescrollInit, downCallback, getMescroll } = useMescroll(onPageScroll, onReachBottom) // 调用mescroll的hook
|
||||
const downOption = {
|
||||
auto: true
|
||||
}
|
||||
const upOption = {
|
||||
auto: true,
|
||||
textNoMore: '~ 已经到底啦 ~', //无更多数据的提示
|
||||
}
|
||||
const list = ref<Array<any>>([]) // 茶室列表
|
||||
|
||||
const OSS = inject('OSS')
|
||||
|
||||
onLoad((args) => {
|
||||
})
|
||||
|
||||
const UserList = {
|
||||
/**
|
||||
* 分页加载
|
||||
* @param mescroll
|
||||
*/
|
||||
upCallback: (mescroll) => {
|
||||
// 需要留一下数据为空的时候显示的空数据图标内容
|
||||
// getTeaRoomOrderList(filter).then((res) => {
|
||||
// const curPageData = res.list || [] // 当前页数据
|
||||
// if(mescroll.num == 1) list.value = [] // 第一页需手动制空列表
|
||||
// list.value = list.value.concat(curPageData) //追加新数据
|
||||
// mescroll.endSuccess(curPageData.length, Boolean(res.more))
|
||||
// }).catch(() => {
|
||||
mescroll.endErr() // 请求失败, 结束加载
|
||||
// })
|
||||
},
|
||||
|
||||
/**
|
||||
* 电话
|
||||
* @param phone
|
||||
*/
|
||||
handleCall: (phone) => {
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: phone
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #fff;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user