对接接口

This commit is contained in:
wangxiaowei
2025-12-18 15:28:00 +08:00
parent 63d8e04465
commit ee681133b8
15 changed files with 715 additions and 585 deletions

View File

@ -62,3 +62,41 @@ export interface IGetRoomListParams {
export function getRoomList(data: IGetRoomListParams) {
return http.Post<any>('/storeapi/store/roomList', data)
}
/**
* 修改房间信息
*/
export interface IEditRoomParams {
id: number
status?: number
img?: string
label_id?: string
title?: string
price?: number
hours?: number
other_describe?: string
}
export function editRoom(data: IEditRoomParams) {
return http.Post('/storeapi/store/editRoom', data)
}
/**
* 获取设备列表
*/
export function getDeviceList(store_id: number) {
return http.Post<any>('/storeapi/device/deviceList', {store_id})
}
/**
* 门锁控制
*/
export function openLock(data: {type: number, lock_no: string, room_id: number, store_id: number}) {
return http.Post('/storeapi/device/lockOff_On', data)
}
/**
* 空开控制
*/
export function openPower(data: {device_id: string, state: number, room_id: number}) {
return http.Post('/storeapi/device/deviceOff_On', data)
}

View File

@ -21,6 +21,7 @@ export interface IUpdateUserInfoParams {
mobile?: number
band_mobile?: string
password?: string
code?: string
}
export function updateUserInfo(data: IUpdateUserInfoParams) {
@ -58,3 +59,17 @@ export interface IGetStoreVerificationCodeParams {
export function getVerificationCode(data: IGetStoreVerificationCodeParams) {
return http.Post('/storeapi/sms/sendCode', data)
}
/**
* 重置密码
*/
export interface IResetPasswordParams {
mobile: string
code: string
password: string
password_confirm: string
}
export function resetPassword(data: IResetPasswordParams) {
return http.Post('/storeapi/storeLogin/resetPassword', data)
}

View File

@ -113,21 +113,6 @@
import { getVerificationCode } from '@/api/user'
import { SMS_ENUM } from '@/enum/sms'
const OSS = inject('OSS')
// 选择银行卡
const showBankCardPopup = ref<boolean>(false)
const selectedBankCardIndex = ref<number>(0)
const bankList = ref<Array<{ id: number, bankName: string, bankCard: string }>>([
{ id: 1, bankName: '招商银行', bankCard: '3265' },
{ id: 2, bankName: '建设银行', bankCard: '1234' },
{ id: 3, bankName: '农业银行', bankCard: '5678' },
])
// 提现金额
const withdrawMoney = ref<number>(0)
// 验证码倒计时
const countDownTime = ref<number>(1 * 60 * 1000) // 60s倒计时
const startCountDown = ref<boolean>(false) // 是否开始倒计时

View File

@ -12,7 +12,7 @@
<view>
<view class="mt-76rpx">
<!-- 进度1-平台审核中 -->
<view class="mx-98rpx flex">
<view class="mx-98rpx flex" v-if="billDetails.order.status == 0">
<view class="mr-44rpx">
<wd-img width="40rpx" height="260rpx" :src="`${OSS}images/withdraw/withdraw_image1.png`"></wd-img>
</view>
@ -20,11 +20,11 @@
<view>
<view class="font-400 text-#606266">
<view class="text-26rpx leading-36rpx">发起提现申请</view>
<view class="mt-8rpx text-24rpx leading-34rpx ">2025-04-08 21:25:25</view>
<view class="mt-8rpx text-24rpx leading-34rpx">{{ billDetails.order.dtime }}</view>
</view>
<view class="font-400 text-#606266 mt-26rpx">
<view class="text-30rpx leading-42rpx">平台审核中</view>
<view class="mt-10rpx text-26rpx leading-36rpx ">2025-04-08 21:25:25</view>
<view class="mt-10rpx text-26rpx leading-36rpx">{{ billDetails.order.dtime }}</view>
</view>
<view class="mt-44rpx font-400 text-26rpx leading-36rpx text-#BFC2CC">
到账成功
@ -33,7 +33,7 @@
</view>
<!-- 进度2-到账成功 -->
<!-- <view class="mx-98rpx flex">
<view class="mx-98rpx flex" v-if="billDetails.order.status == 1">
<view class="mr-44rpx">
<wd-img width="22rpx" height="260rpx" :src="`${OSS}images/withdraw/withdraw_image2.png`"></wd-img>
</view>
@ -41,18 +41,18 @@
<view>
<view class="font-400 text-#606266">
<view class="text-26rpx leading-36rpx">发起提现申请</view>
<view class="mt-8rpx text-24rpx leading-34rpx ">2025-04-08 21:25:25</view>
<view class="mt-8rpx text-24rpx leading-34rpx">{{ billDetails.order.dtime }}</view>
</view>
<view class="font-400 text-#606266 mt-26rpx">
<view class="text-30rpx leading-42rpx">平台审核中</view>
<view class="mt-10rpx text-26rpx leading-36rpx ">2025-04-08 21:25:25</view>
<view class="mt-10rpx text-26rpx leading-36rpx">{{ billDetails.order.dtime }}</view>
</view>
<view class="mt-44rpx font-400 text-30rpx leading-44rpx">
<view>到账成功</view>
<view class="mt-10rpx text-26rpx leading-36rpx">2025-04-08 21:25:25</view>
<view class="mt-10rpx text-26rpx leading-36rpx">{{ billDetails.order.update_dtime }}</view>
</view>
</view>
</view>
</view> -->
<view class="mt-82rpx mb-38rpx mx-30rpx">
<wd-gap height="2rpx" bg-color="#F6F7F9"></wd-gap>
@ -61,15 +61,15 @@
<view class="mx-60rpx">
<view class="flex items-center justify-between font-400 text-28rpx leading-40rpx">
<view class="text-#606266">提现金额</view>
<view class="text-#303133">5000.00</view>
<view class="text-#303133">{{ billDetails.order.amount }}</view>
</view>
<view class="flex items-center justify-between font-400 text-28rpx leading-40rpx">
<view class="text-#606266">到账银行卡</view>
<view class="text-#303133">招商银行3265)</view>
<view class="text-#303133">{{ billDetails.order.bank_name }}{{ Progress.handleFormatBankCardNumber(billDetails.order.bank_card) }})</view>
</view>
</view>
<view class="mx-60rpx mt-90rpx bg-#F6F7F8 rounded-8rpx h-90rpx leading-90rpx text-center">
<view class="mx-60rpx mt-90rpx bg-#F6F7F8 rounded-8rpx h-90rpx leading-90rpx text-center" @click="router.navigateBack">
完成
</view>
</view>
@ -78,6 +78,7 @@
<script lang="ts" setup>
import { getUserTransactionDetailsInfo } from '@/api/user'
import { router } from '@/utils/tools'
const OSS = inject('OSS')
@ -88,12 +89,12 @@
amount: 0,
change_type: 0,
order: {
order_sn: '',
pay_way: '', // 支付方式 1余额支付 2微信支付 3门店支付
nickname: '',
mobile: '',
update_dtime: '',
service_price: ''
dtime: "",
bank_card: "",
bank_name: "",
status: 0,
amount: 0,
update_dtime: ""
}
})
@ -104,6 +105,19 @@
console.log("🚀 ~ billDetails.value:", billDetails.value)
})
const Progress = {
/**
* 格式化银行卡号
* @param bankCardNumber 银行卡号
*/
handleFormatBankCardNumber: (bankCardNumber: string) => {
if (!bankCardNumber) return ''
const noSpace = bankCardNumber.replace(/\s/g, '')
if (noSpace.length <= 4) return noSpace
return noSpace.slice(-4)
},
}
</script>

View File

@ -210,7 +210,9 @@
uni.hideLoading
toast.success('提现申请提交成功')
router.redirectTo('/bundle/wallet/wallet', 500)
uni.$emit('refreshWalletPage')
router.navigateBack(1, 500)
} catch (error) {
uni.hideLoading
toast.info('获取可提现金额失败,请稍后重试')
@ -218,7 +220,9 @@
}
},
// 添加银行卡
/**
* 添加新银行卡
*/
handleAddNewBankCard: () => {
showBankCardPopup.value = false
uni.navigateTo({

View File

@ -27,7 +27,7 @@
no-border
custom-class="!bg-[#F6F7F8] !border !border-solid !border-[#EAECF0] !rounded-16rpx"
custom-input-class="!px-32rpx !h-104rpx"
@input="mobile.handleInputMobile"
@input="ChangeMobile.handleInputMobile"
/>
</view>
</view>
@ -43,9 +43,9 @@
</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-[#4C9F44] text-32rpx font-400 leading-44rpx" v-if="!startCountDown" @click="ChangeMobile.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>
<wd-count-down ref="countDown" :time="countDownTime" millisecond :auto-start="false" format="ss" custom-class="!text-[#C9C9C9] !text-32rpx" @finish="ChangeMobile.handleFinishCountDown"></wd-count-down>
<view> S后重发</view>
</view>
</view>
@ -57,7 +57,7 @@
</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="h-90rpx leading-90rpx mx-60rpx rounded-8rpx text-center mt-112rpx bg-[#4C9F44] text-[#fff]" :class="disabled ? 'opacity-40' : ''" @click="ChangeMobile.handleConfirm">确定</view>
<!-- 手机号修改成功 -->
<wd-popup v-model="showEditSuccessPopup" lock-scroll custom-style="border-radius: 32rpx 32rpx 0rpx 0rpx;" position="bottom">
@ -69,7 +69,7 @@
</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 class="w-630rpx h-90rpx leading-90rpx text-center bg-[#4C9F44] rounded-8rpx text-[#fff] mt-174rpx mx-auto" @click="router.switchTab('/pages/my/my')">好的</view>
</view>
</wd-popup>
</view>
@ -80,23 +80,25 @@
import {mobile as testMobile} from '@/utils/test'
import { useToast } from 'wot-design-uni'
import { router } from '@/utils/tools'
import { SMS_ENUM } from '@/enum/sms'
import { getVerificationCode, updateUserInfo } from '@/api/user'
const OSS = inject('OSS')
const toast = useToast()
const disabled = ref<boolean>(true)
/** 页面 **/
// 页面
const pageType = ref<string>('') // 页面类型 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
@ -104,7 +106,6 @@
mobile: '',
code: ''
})
/** 结束 **/
onLoad((args) => {
@ -121,15 +122,20 @@
}
})
const mobile = {
// 验证手机号
const ChangeMobile = {
/**
* 验证手机号
* @param e
*/
handleInputMobile: (e: {value: string}) => {
model.mobile = e.value
disabled.value = !testMobile(model.mobile)
},
// 发送验证码
handleCountDown: () => {
/**
* 发送验证码
*/
handleCountDown: async () => {
if (disabled.value) {
toast.show({
iconClass: 'info-circle',
@ -139,6 +145,8 @@
return
}
await getVerificationCode({ scene: SMS_ENUM.BGSJHM, mobile: String(model.mobile)})
startCountDown.value = true
nextTick(() => {
countDown.value?.start()
@ -152,19 +160,10 @@
startCountDown.value = false
},
// 登录
handleToLogin: () => {
// TODO 如果是edit的话就是修改手机号
if (pageType === 'login' && !agree.value) {
toast.show({
iconClass: 'info-circle',
msg: '请同意服务协议和隐私政策',
direction: 'vertical'
})
return
}
/**
* 修改
*/
handleConfirm: async() => {
if (!testMobile(model.mobile)) {
toast.show({
iconClass: 'info-circle',
@ -174,6 +173,8 @@
return
}
if (pageType.value == 'edit') {
// TODO 如果是edit的话就是修改手机号
if (!model.code) {
toast.show({
iconClass: 'info-circle',
@ -183,7 +184,19 @@
return
}
router.navigateTo('/bundle/profile/set-password')
await updateUserInfo({
mobile: Number(model.mobile),
code: model.code
})
showEditSuccessPopup.value = true
} else if (pageType.value == 'change') {
await updateUserInfo({
band_mobile: model.mobile,
})
toast.success('绑定手机号修改成功')
router.switchTab('/pages/my/my', 500)
}
},
// 获取手机号

View File

@ -27,7 +27,7 @@
no-border
custom-class="!bg-[#F6F7F8] !border !border-solid !border-[#EAECF0] !rounded-16rpx"
custom-input-class="!px-32rpx !h-104rpx"
@input="mobile.handleInputMobile"
@input="Mobile.handleInputMobile"
/>
</view>
</view>
@ -43,9 +43,9 @@
</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-[#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>
<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>
@ -57,21 +57,7 @@
</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 class="h-90rpx leading-90rpx mx-60rpx rounded-8rpx text-center mt-112rpx bg-[#4C9F44] text-[#fff]" :class="disabled ? 'opacity-40' : ''" @click="Mobile.handleNext">下一步</view>
</view>
</template>
@ -79,16 +65,17 @@
<script lang="ts" setup>
import { mobile as testMobile } from '@/utils/test'
import { useToast } from 'wot-design-uni'
import { getVerificationCode } from '@/api/user'
import { SMS_ENUM } from '@/enum/sms'
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倒计时
@ -103,32 +90,25 @@
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 = {
// 验证手机号
const Mobile = {
/**
* 验证手机号码
* @param e 手机号
*/
handleInputMobile: (e: {value: string}) => {
model.mobile = e.value
disabled.value = !testMobile(model.mobile)
},
// 发送验证码
handleCountDown: () => {
/**
* 发送验证码
*/
handleCountDown: async () => {
if (disabled.value) {
toast.show({
iconClass: 'info-circle',
@ -138,6 +118,8 @@
return
}
await getVerificationCode({ scene: SMS_ENUM.ZHDLMM, mobile: String(model.mobile)})
startCountDown.value = true
nextTick(() => {
countDown.value?.start()
@ -178,25 +160,30 @@
console.log("🚀 ~ e:", e)
},
handleAgree: (e: any) => {
console.log('e', e)
},
// 跳转到服务协议页面
handleToService: () => {
disabled.value = !disabled.value
console.log("🚀 ~ disabled:", disabled)
},
// 跳转到隐私政策页面
handleToPrivacy: () => {
},
// 修改手机成功后返回
handleToBack: () => {
uni.navigateBack()
/**
* 下一步
*/
handleNext: () => {
if (disabled.value) {
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?mobile=${model.mobile}&code=${model.code}`)
},
}
</script>

View File

@ -20,37 +20,35 @@
<view class="font-400 text-30rpx text-[#606266] leading-44rpx">密码</view>
<view class="mt-20rpx">
<wd-input
v-model="model.mobile"
v-model="model.password"
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="mt-40rpx">
<view class="font-400 text-30rpx text-[#606266] leading-44rpx">再次确认</view>
<view class="mt-20rpx">
<wd-input
v-model="model.mobile"
v-model="model.password_confirm"
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>
<view class="h-90rpx leading-90rpx mx-60rpx rounded-8rpx text-center mt-112rpx bg-[#4C9F44] text-[#fff]" @click="SetPassword.handleToConfirm">确定</view>
<!-- 手机号修改成功 -->
<wd-popup v-model="showEditSuccessPopup" lock-scroll custom-style="border-radius: 32rpx 32rpx 0rpx 0rpx;" position="bottom">
@ -62,7 +60,7 @@
</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 class="w-630rpx h-90rpx leading-90rpx text-center bg-[#4C9F44] rounded-8rpx text-[#fff] mt-174rpx mx-auto" @click="router.switchTab('/pages/my/my')">好的</view>
</view>
</wd-popup>
</view>
@ -71,134 +69,92 @@
<script lang="ts" setup>
import {mobile as testMobile} from '@/utils/test'
import { resetPassword } from '@/api/user'
import { useToast } from 'wot-design-uni'
import { useUserStore } from '@/store'
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
password: string
password_confirm: string
}>({
mobile: '',
code: ''
password: '',
password_confirm: ''
})
/** 结束 **/
/** 服务协议和隐私政策 **/
const agree = ref<boolean>(false)
/** 结束 **/
// 手机和验证码
const mobile = ref<string>('')
const code = ref<string>('')
onLoad((args) => {
// 从个人登录页面进入
if (args.type === 'edit') {
userId.value = Number(args.userId) || 0 // userId仅做测试使用实际请传真实用户ID
page.value.title = '修改手机号'
page.value.desc = '手机号一年内可修改2次'
pageType = 'edit'
}
mobile.value = args.mobile || ''
code.value = args.code || ''
})
const mobile = {
// 验证手机号
handleInputMobile: (e: {value: string}) => {
model.mobile = e.value
disabled.value = !testMobile(model.mobile)
},
// 发送验证码
handleCountDown: () => {
if (disabled.value) {
const SetPassword = {
/**
* 确认密码
*/
handleToConfirm: async () => {
if (!mobile) {
toast.show({
iconClass: 'info-circle',
msg: '手机号码错误请重新输入',
msg: '手机号异常,请重新操作',
direction: 'vertical'
})
return
}
startCountDown.value = true
nextTick(() => {
countDown.value?.start()
// 发送验证码请求
})
},
// 验证码倒计时结束
handleFinishCountDown: () => {
startCountDown.value = false
},
// 登录
handleToLogin: () => {
// TODO 如果是edit的话就是修改手机号
if (pageType === 'login' && !agree.value) {
if (!code) {
toast.show({
iconClass: 'info-circle',
msg: '请同意服务协议和隐私政策',
msg: '验证码异常,请重新操作',
direction: 'vertical'
})
return
}
if (!testMobile(model.mobile)) {
if (!model.password) {
toast.show({
iconClass: 'info-circle',
msg: '手机号码错误请重新输入',
msg: '请输入密码',
direction: 'vertical'
})
return
}
if (!model.code) {
if (model.password !== model.password_confirm) {
toast.show({
iconClass: 'info-circle',
msg: '验证码错误',
msg: '两次输入的密码不一致',
direction: 'vertical'
})
return
}
},
// 获取手机号
handleGetPhoneNumber: (e: object) => {
console.log("🚀 ~ e:", e)
},
await resetPassword({
mobile: mobile.value,
code: code.value,
password: model.password,
password_confirm: model.password_confirm
})
handleAgree: (e: any) => {
console.log('e', e)
},
showEditSuccessPopup.value = true
// 跳转到服务协议页面
handleToService: () => {
disabled.value = !disabled.value
console.log("🚀 ~ disabled:", disabled)
},
// 跳转到隐私政策页面
handleToPrivacy: () => {
},
// 修改手机成功后返回
handleToBack: () => {
uni.navigateBack()
// const userStore = useUserStore()
// await userStore.logout()
// if (!userStore.isLoggedIn) {
// toast.info('退出成功')
// router.redirectTo('/pages/login/login')
// }
}
}
</script>

View File

@ -272,6 +272,7 @@
<!-- 适用包间 -->
<view class="mt-28rpx">
<view class="flex items-center mb-20rpx">
<!-- TODO 有包间的显示包间还需要添加一个全使适合用没有包间的显示通用 -->
<view class="text-30rpx leading-44rpx text-#303133 mr-10rpx font-bold">适用包间</view>
<view class="flex items-center">
<wd-img width="16rpx" height="16rpx" :src="`${OSS}icon/icon_validate.png`"></wd-img>
@ -334,6 +335,7 @@
<script lang="ts" setup>
import { router } from '@/utils/tools'
const OSS = inject('OSS')

View File

@ -117,6 +117,7 @@
import { toast } from '@/utils/toast'
import { getStoreDetails, editStoreInfo } from '@/api/store'
import { useStoreStore } from '@/store'
import { router } from '@/utils/tools'
const OSS = inject('OSS')
const useStore = useStoreStore()
@ -300,9 +301,13 @@
try {
await editStoreInfo(form.value)
// 更新默认store信息
useStore.defaultStore.name = form.value.name
EditStore.handleGetStoreDetails()
uni.hideLoading()
toast.info('保存成功')
router.navigateBack(1, 500)
} catch (error) {
uni.hideLoading()
toast.info('保存失败,请稍后重试')

View File

@ -118,6 +118,7 @@
import type { IUserResult } from '@/api/types/user'
import { getUserInfo, getUserTransactionDetails } from '@/api/user'
import { router } from '@/utils/tools'
import { u } from '@tanstack/vue-query/build/legacy/queryClient-CAHOJcvF'
const OSS = inject('OSS')
const userStore = useUserStore()
@ -142,7 +143,10 @@
})
const Wallet = {
// 上拉加载的回调: 其中num:当前页 从1开始, size:每页数据条数,默认10
/**
* 上拉加载
* @param mescroll
*/
upCallback: (mescroll) => {
const filter = {
page: mescroll.num,
@ -179,6 +183,12 @@
* 去提现
*/
handleToRecharge: () => {
uni.$on('refreshWalletPage', () => {
uni.$off('refreshWalletPage')
// 切换tab时,重置当前的mescroll
list.value = []
getMescroll().resetUpScroll();
})
uni.navigateTo({
url: '/bundle/parten/pages/withdraw/withdraw'
})

View File

@ -1,6 +1,8 @@
// 短信枚举
export enum SMS_ENUM {
BGSJHM = 'BGSJHM', // 变更手机号
ZHDLMM = 'ZHDLMM', // 找回登录密码
YZMDL = 'YZMDL', // 验证码登录
BANK = 'BANK', // 绑定银行卡
}

View File

@ -12,7 +12,7 @@
</view>
<view class="mt-50rpx mx-40rpx">
<view class="">
<view>
<view class="font-bold text-36rpx leading-50rpx text-[#303133]">大门</view>
<view class="relative mt-30rpx">
<wd-img width="670rpx" height="202rpx" :src="`${OSS}images/store/store/image1.png`" mode="aspectFill" />
@ -23,35 +23,43 @@
</view>
<view class="relative h-64rpx">
<wd-img width="224rpx" height="64rpx" :src="`${OSS}images/reserve_room/reserve_room_image5.png`"/>
<view class="text-[#4C9F44] font-bold text-32rpx leading-44rpx absolute top-[50%] transform translate-y-[-50%] left-74rpx">点击开锁</view>
<!-- TODO 如果没有大门锁的话 -->
<!-- <view class="text-[#4C9F44] font-bold text-32rpx leading-44rpx absolute top-[50%] transform translate-y-[-50%] left-74rpx">暂无门锁</view> -->
<view
class="text-[#4C9F44] font-bold text-32rpx leading-44rpx absolute top-[50%] transform translate-y-[-50%] left-74rpx"
v-if="device.is_lock == 1" @click="Device.handleOpenLock('door')">
点击开锁
</view>
<view
class="text-[#4C9F44] font-bold text-32rpx leading-44rpx absolute top-[50%] transform translate-y-[-50%] left-74rpx"
v-if="device.is_lock == 0">
暂无门锁
</view>
</view>
</view>
</view>
</view>
<view class="mt-30rpx">
<view class="mb-40rpx" v-for="(item, index) in 5" :key="index">
<view class="font-bold text-36rpx leading-50rpx text-[#303133] mb-30rpx">大楼开门码</view>
<view class="mb-40rpx" v-for="(item, index) in device.roomDevice" :key="index">
<view class="font-bold text-36rpx leading-50rpx text-[#303133] mb-30rpx">{{ item.title }}</view>
<view class="flex items-center justify-between">
<view class="w-240rpx h-280rpx bg-white rounded-32rpx flex flex-col items-center justify-center">
<view class="">
<wd-img width="90rpx" height="90rpx" :src="`${OSS}images/store/store/image2.png`" mode="aspectFill" />
</view>
<view class="font-bold text-34rpx text-[#303133] leading-48rpx">门锁</view>
<view class="bg-[#4C9F44] rounded-20rpx w-168rpx h-60rpx text-center leading-60rpx text-[#fff] mt-10rpx" @cliclk="Device.handleOpenLock">
<view class="bg-[#4C9F44] rounded-20rpx w-168rpx h-60rpx text-center leading-60rpx text-[#fff] mt-10rpx"
@click="Device.handleOpenLock('room', item)">
开锁
</view>
</view>
<view class="w-410rpx h-280rpx bg-white rounded-16rpx pl-60rpx pr-34rpx">
<view class="flex items-top justify-between px-20rpx py-4rpx pt-40rpx">
<wd-img width="90rpx" height="90rpx" :src="`${OSS}images/store/store/image3.png`" mode="aspectFill" />
<view class="text-28rpx leading-40rpx text-[#303133] mt-12rpx">ON</view>
<view class="text-28rpx leading-40rpx text-[#303133] mt-12rpx">{{ item.is_open ? 'OFF' : 'ON' }}</view>
</view>
<view class="font-bold text-28rpx text-[#303133] leading-40rpx mt-34rpx flex items-center justify-between">
<view class="font-bold text-34rpx leading-48rpx text-[#303133]">插座空开</view>
<wd-switch v-model="item.checked" size="48rpx" active-color="#4C9F44"/>
<wd-switch v-model="item.is_open" size="48rpx" active-color="#4C9F44" @change="Device.handleToggleSocket($event, item)"/>
</view>
</view>
</view>
@ -64,39 +72,31 @@
<script lang="ts" setup>
import { OrderSource, OrderStatus, TeaRoomOrderStatusText, TeaRoomOrderStatusValue } from '@/utils/order'
import ComboCard from '@/components/order/ComboCard.vue'
import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
import useMescroll from "@/uni_modules/mescroll-uni/hooks/useMescroll.js"
import { getTeaRoomOrderList } from '@/api/tea-room'
import { getDeviceList, openLock, openPower } from '@/api/store'
import { router } from '@/utils/tools'
import { useStoreStore } from '@/store'
import { toast } from '@/utils/toast'
const OSS = inject('OSS')
const useStore = useStoreStore()
const checked = ref<boolean>(false)
// mescroll
const { mescrollInit, downCallback, getMescroll } = useMescroll(onPageScroll, onReachBottom) // 调用mescroll的hook
const downOption = {
auto: true
// 设备
const device = ref({
store_id: useStore.defaultStore.id,
is_lock: 0, //是否存在大门门锁 0:不存在 1:存在
lock_no: '', // 门锁编号
roomDevice: [
{
room_id: 0, // 包间ID
title: '', // 包间名称
lock_no: '', // 门锁编号
is_open: false, //空开状态:后端返回的是 0关闭 1打开前端转换为数字
}
const upOption = {
auto: true,
textNoMore: '~ 已经到底啦 ~', //无更多数据的提示
}
const orderStatus = ref<string>('')
const list = ref<Array<any>>([]) // 茶室列表
const keywords = ref<string>('') // 搜索关键词
// tab
const tab = ref<string>('list')
const tabList = ref<Array<{title: string, num: number, name: string}>>([
{ title: '已上架', num: 10, name: 'list'},
{ title: '已下架', num: 11, name: 'delist' },
// { title: '草稿箱', num: 0, name: 'draft' }
])
]
})
onLoad((args) => {
Device.handleGetDeviceList()
})
onUnload(() => {
@ -104,12 +104,78 @@
const Device = {
/**
* 开锁
* 初始化设备列表
*/
handleOpenLock: () => {
handleGetDeviceList: async () => {
const res = await getDeviceList(useStore.defaultStore.id)
device.value = res
device.value.roomDevice.map((item) => {
item.is_open = Boolean(item.is_open)
})
},
/**
* 开门锁
* @params type 类型 door:大门门锁 room:包间门锁
* @params item 设备项
*/
handleOpenLock: async (type: string, item: any = null) => {
let params = {
type: 0,
lock_no: '',
store_id: device.value.store_id,
room_id: 0
}
if (type === 'door') {
params.type = 1
params.lock_no = device.value.lock_no
} else if (type === 'room') {
params.type = 2
params.lock_no = item.lock_no
params.room_id = item.room_id
}
uni.showLoading({
title: '开锁中...',
mask: true,
})
try {
uni.hideLoading
// await openLock(params)
Device.handleGetDeviceList()
toast.success('开锁成功')
} catch(e) {
uni.hideLoading
toast.info('开锁失败,请稍后重试')
}
},
/**
* 插座空开
* @params event 事件参数
* @params item 设备项
*/
handleToggleSocket: (event: {value: boolean}, item: any) => {
let params = {
device_id: item.device_id,
state: Number(event.value),
room_id: item.room_id
}
uni.showLoading({
title: '操作中...',
mask: true,
})
try {
uni.hideLoading
// await openPower(params)
Device.handleGetDeviceList()
toast.success('操作成功')
} catch(e) {
uni.hideLoading
toast.info('操作失败,请稍后重试')
}
}
}
</script>

View File

@ -5,261 +5,6 @@
}
}</route>
<script lang="ts" setup>
import { toast } from '@/utils/toast'
const OSS = inject('OSS')
const navbarHeight = inject('navbarHeight')
// tab
const tab = ref<number>(0)
// 上传文件
const action = 'https://www.mocky.io/v2/5cc8019d300000980a055e76' // 仅做测试使用,实际请换成真实上传接口
// 表单
const form = reactive({
roomName: '',
tags: [] as string[],
video: null as any,
images: [] as string[],
hourlyPrice: '',
minBookingTime: '',
inventory: '',
packageIntro: '',
otherNotes: '',
userCount: '',
refundPolicy: '',
})
// 标签相关
const showTagSelectPopup = ref(false)
const showCreateTagPopup = ref(false)
const newTagName = ref('')
const isTagManageMode = ref(false) // 是否处于管理模式
const selectedTags = ref<string[]>([]) // 临时选中的标签,点击确认后才回填到表单
// Mock 已有标签列表
const availableTags = ref([
'全息投影',
'环境优雅',
'幽静雅致',
'禅意悠然',
'雅室禅意浓',
'古朴韵悠长',
])
const StoreManage = {
/**
* 切换tab
*/
handleChangeTab: (e: any) => {
tab.value = e.name
},
/**
* 添加标签 - 显示选择标签弹窗
*/
handleAddTag: () => {
// 初始化临时选中的标签为当前表单中的标签
selectedTags.value = [...form.tags]
showTagSelectPopup.value = true
},
/**
* 关闭选择标签弹窗
*/
handleCloseTagSelect: () => {
showTagSelectPopup.value = false
isTagManageMode.value = false // 关闭时重置管理模式
selectedTags.value = [] // 清空临时选中的标签
},
/**
* 选择标签(临时选择,不直接修改表单)
*/
handleSelectTag: (tag: string) => {
if (isTagManageMode.value) {
// 管理模式时,点击标签不进行选择操作
return
}
if (selectedTags.value.includes(tag)) {
// 如果已选择,则取消选择
const index = selectedTags.value.indexOf(tag)
selectedTags.value.splice(index, 1)
}
else {
// 如果未选择,则添加
if (selectedTags.value.length >= 2) {
toast.info('最多只能选择2个标签')
return
}
selectedTags.value.push(tag)
}
},
/**
* 从选择列表删除标签
*/
handleRemoveTagFromList: (tag: string, event: any) => {
event.stopPropagation()
const index = availableTags.value.indexOf(tag)
if (index > -1) {
availableTags.value.splice(index, 1)
}
// 如果该标签已被选中,也从临时选中列表中移除
const selectedIndex = selectedTags.value.indexOf(tag)
if (selectedIndex > -1) {
selectedTags.value.splice(selectedIndex, 1)
}
// 如果该标签在表单中,也从表单中移除
const formIndex = form.tags.indexOf(tag)
if (formIndex > -1) {
form.tags.splice(formIndex, 1)
}
},
/**
* 确认选择标签
*/
handleConfirmTags: () => {
form.tags = [...selectedTags.value]
showTagSelectPopup.value = false
isTagManageMode.value = false
selectedTags.value = []
},
/**
* 进入管理模式
*/
handleEnterManagement: () => {
isTagManageMode.value = true
},
/**
* 退出管理模式
*/
handleExitManagement: () => {
isTagManageMode.value = false
},
/**
* 显示新建标签弹窗
*/
handleShowCreateTag: () => {
showTagSelectPopup.value = false
showCreateTagPopup.value = true
},
/**
* 关闭新建标签弹窗
*/
handleCloseCreateTag: () => {
showCreateTagPopup.value = false
newTagName.value = ''
},
/**
* 完成新建标签
*/
handleCompleteCreateTag: () => {
const tagName = newTagName.value.trim()
if (!tagName) {
toast.info('请输入标签名称')
return
}
if (tagName.length > 5) {
toast.info('标签不能超过5个字')
return
}
if (availableTags.value.includes(tagName)) {
toast.info('该标签已存在')
return
}
// 添加到可用标签列表
availableTags.value.push(tagName)
// 如果当前临时选中的标签少于2个自动选中新创建的标签
if (selectedTags.value.length < 2) {
selectedTags.value.push(tagName)
}
// 关闭弹窗,重新打开选择标签弹窗
showCreateTagPopup.value = false
newTagName.value = ''
showTagSelectPopup.value = true
toast.info('标签创建成功')
},
/**
* 删除标签
*/
handleRemoveTag: (index: number) => {
form.tags.splice(index, 1)
},
/**
* 上传视频
*/
handleUploadVideo: (event: any) => {
if (event.fileList && event.fileList.length > 0) {
form.video = event.fileList[0]
}
},
/**
* 删除视频
*/
handleRemoveVideo: () => {
form.video = null
},
/**
* 上传图片
*/
handleUploadImage: (event: any) => {
if (event.fileList && event.fileList.length > 0) {
const newImages = event.fileList.map((file: any) => file.url || file.tempFilePath)
form.images.push(...newImages)
// 限制最多9张
if (form.images.length > 9) {
form.images = form.images.slice(0, 9)
toast.info('最多只能上传9张图片')
}
}
},
/**
* 删除图片
*/
handleRemoveImage: (index: number) => {
form.images.splice(index, 1)
},
/**
* 保存
*/
handleSave: () => {
// TODO: 实现保存功能
console.log('保存表单:', form)
toast.info('保存成功')
},
/**
* 点击更多选项
*/
handleMore: () => {
// TODO: 实现更多选项功能
console.log('更多选项')
},
/**
* 点击目标图标
*/
handleTarget: () => {
// TODO: 实现目标功能
console.log('目标功能')
},
}
</script>
<template>
<view class="pb-180rpx">
<view>
@ -287,7 +32,7 @@ const StoreManage = {
</view>
<!-- 包间名称 -->
<view class="mt-28rpx">
<view class="mt-28rpx add-textarea">
<view class="mb-20rpx flex items-center">
<view class="mr-10rpx text-32rpx text-[#303133] font-bold leading-44rpx">
包间名称
@ -621,7 +366,7 @@ const StoreManage = {
<!-- 确认按钮 -->
<view
class="mt-40rpx h-90rpx rounded-8rpx bg-[#4C9F44] text-center text-30rpx text-[#fff] leading-90rpx"
:class="{ 'opacity-0 pointer-events-none': isTagManageMode }"
:class="isTagManageMode ? 'opacity-0 pointer-events-none' : ''"
@click="StoreManage.handleConfirmTags">
确认
</view>
@ -661,6 +406,263 @@ const StoreManage = {
</view>
</template>
<script lang="ts" setup>
import { toast } from '@/utils/toast'
const OSS = inject('OSS')
const navbarHeight = inject('navbarHeight')
// tab
const tab = ref<number>(0)
// 上传文件
const action = 'https://www.mocky.io/v2/5cc8019d300000980a055e76' // 仅做测试使用,实际请换成真实上传接口
// 表单
const form = reactive({
roomName: '',
tags: [] as string[],
video: null as any,
images: [] as string[],
hourlyPrice: '',
minBookingTime: '',
inventory: '',
packageIntro: '',
otherNotes: '',
userCount: '',
refundPolicy: '',
})
// 标签相关
const showTagSelectPopup = ref(false)
const showCreateTagPopup = ref(false)
const newTagName = ref('')
const isTagManageMode = ref(false) // 是否处于管理模式
const selectedTags = ref<string[]>([]) // 临时选中的标签,点击确认后才回填到表单
// Mock 已有标签列表
const availableTags = ref([
'全息投影',
'环境优雅',
'幽静雅致',
'禅意悠然',
'雅室禅意浓',
'古朴韵悠长',
])
const StoreManage = {
/**
* 切换tab
*/
handleChangeTab: (e: any) => {
tab.value = e.name
},
/**
* 添加标签 - 显示选择标签弹窗
*/
handleAddTag: () => {
// 初始化临时选中的标签为当前表单中的标签
selectedTags.value = [...form.tags]
showTagSelectPopup.value = true
},
/**
* 关闭选择标签弹窗
*/
handleCloseTagSelect: () => {
showTagSelectPopup.value = false
isTagManageMode.value = false // 关闭时重置管理模式
selectedTags.value = [] // 清空临时选中的标签
},
/**
* 选择标签(临时选择,不直接修改表单)
*/
handleSelectTag: (tag: string) => {
if (isTagManageMode.value) {
// 管理模式时,点击标签不进行选择操作
return
}
if (selectedTags.value.includes(tag)) {
// 如果已选择,则取消选择
const index = selectedTags.value.indexOf(tag)
selectedTags.value.splice(index, 1)
}
else {
// 如果未选择,则添加
if (selectedTags.value.length >= 2) {
toast.info('最多只能选择2个标签')
return
}
selectedTags.value.push(tag)
}
},
/**
* 从选择列表删除标签
*/
handleRemoveTagFromList: (tag: string, event: any) => {
event.stopPropagation()
const index = availableTags.value.indexOf(tag)
if (index > -1) {
availableTags.value.splice(index, 1)
}
// 如果该标签已被选中,也从临时选中列表中移除
const selectedIndex = selectedTags.value.indexOf(tag)
if (selectedIndex > -1) {
selectedTags.value.splice(selectedIndex, 1)
}
// 如果该标签在表单中,也从表单中移除
const formIndex = form.tags.indexOf(tag)
if (formIndex > -1) {
form.tags.splice(formIndex, 1)
}
},
/**
* 确认选择标签
*/
handleConfirmTags: () => {
form.tags = [...selectedTags.value]
showTagSelectPopup.value = false
isTagManageMode.value = false
selectedTags.value = []
},
/**
* 进入管理模式
*/
handleEnterManagement: () => {
isTagManageMode.value = true
},
/**
* 退出管理模式
*/
handleExitManagement: () => {
isTagManageMode.value = false
},
/**
* 显示新建标签弹窗
*/
handleShowCreateTag: () => {
showTagSelectPopup.value = false
showCreateTagPopup.value = true
},
/**
* 关闭新建标签弹窗
*/
handleCloseCreateTag: () => {
showCreateTagPopup.value = false
newTagName.value = ''
},
/**
* 完成新建标签
*/
handleCompleteCreateTag: () => {
const tagName = newTagName.value.trim()
if (!tagName) {
toast.info('请输入标签名称')
return
}
if (tagName.length > 5) {
toast.info('标签不能超过5个字')
return
}
if (availableTags.value.includes(tagName)) {
toast.info('该标签已存在')
return
}
// 添加到可用标签列表
availableTags.value.push(tagName)
// 如果当前临时选中的标签少于2个自动选中新创建的标签
if (selectedTags.value.length < 2) {
selectedTags.value.push(tagName)
}
// 关闭弹窗,重新打开选择标签弹窗
showCreateTagPopup.value = false
newTagName.value = ''
showTagSelectPopup.value = true
toast.info('标签创建成功')
},
/**
* 删除标签
*/
handleRemoveTag: (index: number) => {
form.tags.splice(index, 1)
},
/**
* 上传视频
*/
handleUploadVideo: (event: any) => {
if (event.fileList && event.fileList.length > 0) {
form.video = event.fileList[0]
}
},
/**
* 删除视频
*/
handleRemoveVideo: () => {
form.video = null
},
/**
* 上传图片
*/
handleUploadImage: (event: any) => {
if (event.fileList && event.fileList.length > 0) {
const newImages = event.fileList.map((file: any) => file.url || file.tempFilePath)
form.images.push(...newImages)
// 限制最多9张
if (form.images.length > 9) {
form.images = form.images.slice(0, 9)
toast.info('最多只能上传9张图片')
}
}
},
/**
* 删除图片
*/
handleRemoveImage: (index: number) => {
form.images.splice(index, 1)
},
/**
* 保存
*/
handleSave: () => {
// TODO: 实现保存功能
console.log('保存表单:', form)
toast.info('保存成功')
},
/**
* 点击更多选项
*/
handleMore: () => {
// TODO: 实现更多选项功能
console.log('更多选项')
},
/**
* 点击目标图标
*/
handleTarget: () => {
// TODO: 实现目标功能
console.log('目标功能')
},
}
</script>
<style lang="scss">
page {
background: #f6f7f8;
@ -676,9 +678,8 @@ page {
.add-textarea {
:deep() {
.wd-textarea__value,
.wd-textarea__count {
.wd-input__value,
.wd-input__count {
background: transparent !important;
}
}

View File

@ -17,7 +17,7 @@
<mescroll-body ref="mescrollItem0" @init="mescrollInit" @down="downCallback" @up="RoomManage.upCallback" :down="downOption" :up="upOption">
<view class="grid grid-cols-2 gap-24rpx">
<view v-for="room in list" :key="room.id"
<view v-for="(room, index) in list" :key="room.id"
class="flex flex-col overflow-hidden rounded-16rpx bg-white"
@click="RoomManage.handleClickRoom(room)">
<!-- 房间图片 -->
@ -35,22 +35,22 @@
<view class="flex flex-col p-24rpx">
<!-- 房间名称 -->
<view class="mb-0rpx text-center text-28rpx text-[#303133] leading-40rpx">
{{ room.title }} ({{ room.type }})
{{ room.title }}
</view>
<!-- 状态指示器 -->
<view class="flex items-baseline justify-center align-middle">
<view class="flex items-baseline justify-center align-middle" @click.stop="RoomManage.handleEditRoomStatus(room, index)">
<!-- 状态点 -->
<view class="mr-8rpx h-12rpx w-12rpx flex-shrink-0 rounded-full"
:style="{ backgroundColor: getStatusConfig(room.status).color }" />
:style="{ backgroundColor: RoomManage.handleGetStatusConfig(room.status).color }" />
<!-- 状态文字 -->
<view class="text-24rpx text-[#303133] leading-34rpx"
:style="{ color: getStatusConfig(room.status).color }">
{{ getStatusConfig(room.status).text }}
:style="{ color: RoomManage.handleGetStatusConfig(room.status).color }">
{{ RoomManage.handleGetStatusConfig(room.status).text }}
</view>
<!-- 右箭头 -->
<view class="ml-8rpx">
<wd-icon name="arrow-right" size="12px" :color="getStatusConfig(room.status).color" />
<wd-icon name="arrow-right" size="12px" :color="RoomManage.handleGetStatusConfig(room.status).color" />
</view>
</view>
</view>
@ -58,84 +58,84 @@
</view>
</mescroll-body>
</view>
<!-- 状态修改弹窗 -->
<wd-action-sheet v-model="showActionMenu" :actions="actions" @select="RoomManage.handleSelectAction" />
</view>
</template>
<script lang="ts" setup>
import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
import useMescroll from "@/uni_modules/mescroll-uni/hooks/useMescroll.js"
import { getRoomList } from '@/api/store'
import { getRoomList, editRoom } from '@/api/store'
import { router } from '@/utils/tools'
import { toast } from '@/utils/toast'
const OSS = inject('OSS')
const navbarHeight = inject('navbarHeight')
// 房间状态枚举
enum RoomStatus {
AVAILABLE = 'available', // 空闲中 - 绿
CLEANING = 'cleaning', // 待打扫 - 蓝色/橙
MAINTENANCE = 'maintenance', // 维护中 - 红色
IN_USE = 'in_use', // 使用中 -
WAIT_CLEANING = 1, // 待打扫 -
AVAILABLE = 2, // 空闲中 - 绿
MAINTENANCE = 3, // 维护中 - 红色
CLEANING = 4, // 打扫中 -
IN_USE = 5, // 使用中 - 蓝色
}
// 房间状态配置
const statusConfig = {
[RoomStatus.WAIT_CLEANING]: {
text: '待打扫',
color: '#818CA9', // 灰色
},
[RoomStatus.AVAILABLE]: {
text: '空闲中',
color: '#4C9F44', // 绿色
},
[RoomStatus.CLEANING]: {
text: '待打扫',
color: '#F29747', // 蓝色
},
[RoomStatus.MAINTENANCE]: {
text: '维护中',
color: '#F65353', // 红色
},
[RoomStatus.CLEANING]: {
text: '打扫中',
color: '#F29747', // 橙色
},
[RoomStatus.IN_USE]: {
text: '使用中',
color: '#1890FF', // 蓝色
},
}
// Mock 房间数据
const roomList = ref([
// 房间数据
const showActionMenu = ref<boolean>(false)
const actions = ref([
{
id: 1,
name: '对月',
type: '榻榻米',
image: `${OSS}images/room1.jpg`, // Mock图片实际需要替换
status: RoomStatus.AVAILABLE,
name: '待打扫',
value: RoomStatus.WAIT_CLEANING
},
{
id: 2,
name: '听雨',
type: '榻榻米',
image: `${OSS}images/room2.jpg`,
status: RoomStatus.CLEANING,
name: '空闲中',
value: RoomStatus.AVAILABLE
},
{
id: 3,
name: '观星',
type: '榻榻米',
image: `${OSS}images/room3.jpg`,
status: RoomStatus.MAINTENANCE,
name: '维护中',
value: RoomStatus.MAINTENANCE
},
{
id: 4,
name: '品茶',
type: '榻榻米',
image: `${OSS}images/room4.jpg`,
status: RoomStatus.CLEANING,
name: '打扫中',
value: RoomStatus.CLEANING
},
{
id: 5,
name: '静心',
type: '榻榻米',
image: `${OSS}images/room5.jpg`,
status: RoomStatus.IN_USE,
},
name: '使用中',
value: RoomStatus.IN_USE
}
])
const selectRoom = ref<{
id: number,
index: number
}>({
id: 0,
index: -1
})
// mescroll
const { mescrollInit, downCallback, getMescroll } = useMescroll(onPageScroll, onReachBottom) // 调用mescroll的hook
@ -163,7 +163,6 @@
}
getRoomList(filter).then((res) => {
console.log("🚀 ~ res:", res)
const curPageData = res.list || [] // 当前页数据
if(mescroll.num == 1) list.value = [] // 第一页需手动制空列表
list.value = list.value.concat(curPageData) //追加新数据
@ -205,13 +204,46 @@
// TODO: 实现目标功能
console.log('目标功能')
},
}
/**
* 获取状态配置
* 点击编辑房间状态
*/
function getStatusConfig(status: RoomStatus) {
handleEditRoomStatus: (item: any, index: number) => {
selectRoom.value.id = item.id
selectRoom.value.index = index
showActionMenu.value = true
},
/**
* 获取房间状态
*/
handleGetStatusConfig: (status: RoomStatus) => {
return statusConfig[status] || statusConfig[RoomStatus.AVAILABLE]
},
/**
* 修改房间选择状态
*/
handleSelectAction: async (action: any) => {
uni.showLoading({
title: '修改中...'
})
try {
const status = action.item.value
await editRoom({
id: selectRoom.value.id,
status
})
uni.hideLoading()
toast.success('修改状态成功')
list.value[selectRoom.value.index].status = status
} catch (error) {
uni.hideLoading()
toast.info('修改状态失败')
}
}
}
</script>