对接房间编辑接口

This commit is contained in:
wangxiaowei
2025-12-18 18:10:14 +08:00
parent ee681133b8
commit 10aae8ea46
2 changed files with 422 additions and 302 deletions

View File

@ -21,7 +21,6 @@ export function switchStore(id: number) {
return http.Post('/storeapi/store/switchStore', { id }) return http.Post('/storeapi/store/switchStore', { id })
} }
/** /**
* 编辑门店信息 * 编辑门店信息
*/ */
@ -63,6 +62,34 @@ export function getRoomList(data: IGetRoomListParams) {
return http.Post<any>('/storeapi/store/roomList', data) return http.Post<any>('/storeapi/store/roomList', data)
} }
/**
* 获取房间信息
*/
export function getRoomDetails(id: number) {
return http.Post<any>('/storeapi/store/roomDetails', { id })
}
/**
* 包间列表标签
*/
export function getRoomLabelList(store_id: number) {
return http.Post<any>('/storeapi/store/roomLabelList', { store_id })
}
/**
* 创建包间标签
*/
export function handleCreateTag(data: {store_id: number, label_name: string}) {
return http.Post<any>('/storeapi/store/addLabel', data)
}
/**
* 删除包间标签
*/
export function handleDeleteTag(id: number) {
return http.Post<any>('/storeapi/store/delLabel', {id})
}
/** /**
* 修改房间信息 * 修改房间信息
*/ */

View File

@ -12,11 +12,11 @@
</view> </view>
<view class="store-tabs"> <view class="store-tabs">
<wd-tabs v-model="tab" @change="StoreManage.handleChangeTab"> <wd-tabs v-model="tab" @change="RoomDetail.handleChangeTab">
<wd-tab title="基础信息" /> <wd-tab title="基础信息" />
<wd-tab title="规格与价格" /> <wd-tab title="规格与价格" />
<wd-tab title="套餐详情" /> <wd-tab title="套餐详情" />
<wd-tab title="购买须知" /> <!-- <wd-tab title="购买须知" /> -->
</wd-tabs> </wd-tabs>
</view> </view>
@ -41,7 +41,7 @@
<wd-img width="16rpx" height="16rpx" :src="`${OSS}icon/icon_validate.png`" /> <wd-img width="16rpx" height="16rpx" :src="`${OSS}icon/icon_validate.png`" />
</view> </view>
</view> </view>
<wd-input v-model="form.roomName" no-border placeholder="请输入包间名称" :maxlength="10" show-word-limit <wd-input v-model="form.title" no-border placeholder="请输入包间名称" :maxlength="10" show-word-limit
custom-class="!bg-[#F6F7F8] !rounded-16rpx !px-28rpx !py-20rpx" /> custom-class="!bg-[#F6F7F8] !rounded-16rpx !px-28rpx !py-20rpx" />
</view> </view>
@ -61,17 +61,17 @@
</view> </view>
</view> </view>
<view class="flex flex-wrap items-center gap-16rpx"> <view class="flex flex-wrap items-center gap-16rpx">
<view v-for="(tag, index) in form.tags" :key="index" <view v-for="(tag, index) in tags" :key="index"
class="flex items-center rounded-20rpx bg-[#F6F7F8] px-20rpx py-8rpx"> class="flex items-center rounded-20rpx bg-[#F6F7F8] px-20rpx py-8rpx">
<view class="mr-8rpx text-26rpx text-[#303133] leading-36rpx"> <view class="mr-8rpx text-26rpx text-[#303133] leading-36rpx">
{{ tag }} {{ tag.label_name }}
</view> </view>
<wd-icon name="close" size="14px" color="#909399" <wd-icon name="close" size="14px" color="#909399"
@click="StoreManage.handleRemoveTag(index)" /> @click="RoomDetail.handleRemoveTag(index)" />
</view> </view>
<view v-if="form.tags.length < 2" <view v-if="form.tags.length < 2"
class="flex items-center border-2rpx border-[#E5E5E5] rounded-20rpx border-dashed px-20rpx py-8rpx" class="flex items-center border-2rpx border-[#E5E5E5] rounded-20rpx border-dashed px-20rpx py-8rpx"
@click="StoreManage.handleAddTag"> @click="RoomDetail.handleAddTag">
<wd-icon name="add" size="16px" color="#909399" class="mr-8rpx" /> <wd-icon name="add" size="16px" color="#909399" class="mr-8rpx" />
<view class="text-26rpx text-[#909399] leading-36rpx"> <view class="text-26rpx text-[#909399] leading-36rpx">
添加标签 添加标签
@ -81,7 +81,7 @@
</view> </view>
<!-- 团购视频 --> <!-- 团购视频 -->
<view class="mt-28rpx"> <!-- <view class="mt-28rpx">
<view class="mb-28rpx flex items-center"> <view class="mb-28rpx flex items-center">
<view class="mr-10rpx text-32rpx text-[#303133] font-bold leading-44rpx"> <view class="mr-10rpx text-32rpx text-[#303133] font-bold leading-44rpx">
团购视频 团购视频
@ -94,12 +94,12 @@
</view> </view>
<view <view
class="absolute right-8rpx top-8rpx h-32rpx w-32rpx flex items-center justify-center rounded-full bg-black bg-opacity-50" class="absolute right-8rpx top-8rpx h-32rpx w-32rpx flex items-center justify-center rounded-full bg-black bg-opacity-50"
@click="StoreManage.handleRemoveVideo"> @click="RoomDetail.handleRemoveVideo">
<wd-icon name="close" size="14px" color="#fff" /> <wd-icon name="close" size="14px" color="#fff" />
</view> </view>
</view> </view>
<wd-upload v-else :file-list="[]" :limit="1" image-mode="scaleToFill" accept="video" <wd-upload v-else :file-list="[]" :limit="1" image-mode="scaleToFill" accept="video"
:action="action" @change="StoreManage.handleUploadVideo"> :action="action" @change="RoomDetail.handleUploadVideo">
<view <view
class="h-184rpx w-184rpx flex flex-col items-center justify-center border-2rpx border-[#E5E5E5] rounded-16rpx border-dashed"> class="h-184rpx w-184rpx flex flex-col items-center justify-center border-2rpx border-[#E5E5E5] rounded-16rpx border-dashed">
<wd-img width="64rpx" height="64rpx" :src="`${OSS}icon/icon_video.png`" mode="aspectFill" /> <wd-img width="64rpx" height="64rpx" :src="`${OSS}icon/icon_video.png`" mode="aspectFill" />
@ -108,7 +108,7 @@
</view> </view>
</view> </view>
</wd-upload> </wd-upload>
</view> </view> -->
<!-- 团购图片 --> <!-- 团购图片 -->
<view class="mt-28rpx"> <view class="mt-28rpx">
@ -122,30 +122,18 @@
</view> </view>
</view> </view>
<view class="text-26rpx text-[#9CA3AF] font-400 leading-36rpx"> <view class="text-26rpx text-[#9CA3AF] font-400 leading-36rpx">
可添加3~9张图片 可添加1张图片
</view> </view>
</view> </view>
<view class="flex flex-wrap items-center gap-16rpx"> <view class="flex flex-wrap items-center gap-16rpx">
<view v-for="(image, index) in form.images" :key="index" <wd-upload
class="relative h-184rpx w-184rpx overflow-hidden rounded-16rpx"> :header="{'token': token}"
<wd-img width="100%" height="100%" :src="image" mode="aspectFill" /> :file-list="fileList"
<view :limit="1"
class="absolute right-8rpx top-8rpx h-32rpx w-32rpx flex items-center justify-center rounded-full bg-black bg-opacity-50" image-mode="scaleToFill"
@click="StoreManage.handleRemoveImage(index)"> :action="action"
<wd-icon name="close" size="14px" color="#fff" /> @success="RoomDetail.handleUploadSuccess">
</view> <wd-img width="184rpx" height="184rpx" :src="form.img || `${OSS}images/store/my/image1.png`" mode="aspectFill" radius="16rpx" />
</view>
<wd-upload v-if="form.images.length < 9" :file-list="[]" :limit="9 - form.images.length"
image-mode="scaleToFill" accept="image" :action="action"
@change="StoreManage.handleUploadImage">
<view
class="h-184rpx w-184rpx flex flex-col items-center justify-center border-2rpx border-[#E5E5E5] rounded-16rpx border-dashed">
<wd-img width="64rpx" height="64rpx" :src="`${OSS}icon/icon_upload.png`"
mode="aspectFill" />
<view class="mt-12rpx text-26rpx text-[#303133] font-400 leading-36rpx">
添加图片
</view>
</view>
</wd-upload> </wd-upload>
</view> </view>
</view> </view>
@ -157,17 +145,17 @@
规格与价格 规格与价格
</view> </view>
<!-- 小时优惠 --> <!-- -->
<view class="mb-28rpx"> <view class="mb-28rpx">
<view class="mb-20rpx flex items-center"> <view class="mb-20rpx flex items-center">
<view class="mr-10rpx text-30rpx text-[#303133] font-bold leading-44rpx"> <view class="mr-10rpx text-30rpx text-[#303133] font-bold leading-44rpx">
小时优惠
</view> </view>
<view class="flex items-center"> <view class="flex items-center">
<wd-img width="16rpx" height="16rpx" :src="`${OSS}icon/icon_validate.png`" /> <wd-img width="16rpx" height="16rpx" :src="`${OSS}icon/icon_validate.png`" />
</view> </view>
</view> </view>
<wd-input v-model="form.hourlyPrice" no-border placeholder="请输入小时优惠价" type="digit" <wd-input v-model="form.price" no-border placeholder="价" type="digit"
custom-class="!bg-[#F6F7F8] !rounded-16rpx !px-28rpx !py-20rpx"> custom-class="!bg-[#F6F7F8] !rounded-16rpx !px-28rpx !py-20rpx">
<template #prefix> <template #prefix>
<view class="mr-8rpx text-28rpx text-[#303133]"> <view class="mr-8rpx text-28rpx text-[#303133]">
@ -189,11 +177,11 @@
</view> </view>
</view> </view>
<view class="text-24rpx text-[#9CA3AF] font-400 leading-34rpx"> <view class="text-24rpx text-[#9CA3AF] font-400 leading-34rpx">
范围1~5 <!-- 范围1~5 -->
</view> </view>
</view> </view>
<view class="flex items-center"> <view class="flex items-center">
<wd-input v-model="form.minBookingTime" no-border placeholder="请输入起订时间" type="number" :max="5" <wd-input v-model="form.hours" no-border placeholder="请输入起订时间" type="number" :max="5"
:min="1" custom-class="!bg-[#F6F7F8] !rounded-16rpx !px-28rpx !py-20rpx" /> :min="1" custom-class="!bg-[#F6F7F8] !rounded-16rpx !px-28rpx !py-20rpx" />
<view class="ml-16rpx text-28rpx text-[#303133]"> <view class="ml-16rpx text-28rpx text-[#303133]">
小时 小时
@ -202,7 +190,7 @@
</view> </view>
<!-- 库存 --> <!-- 库存 -->
<view class="mb-28rpx"> <!-- <view>
<view class="mb-20rpx flex items-center justify-between"> <view class="mb-20rpx flex items-center justify-between">
<view class="flex items-center"> <view class="flex items-center">
<view class="mr-10rpx text-30rpx text-[#303133] font-bold leading-44rpx"> <view class="mr-10rpx text-30rpx text-[#303133] font-bold leading-44rpx">
@ -218,7 +206,7 @@
</view> </view>
<wd-input v-model="form.inventory" no-border placeholder="请输入库存" type="number" :max="999" :min="1" <wd-input v-model="form.inventory" no-border placeholder="请输入库存" type="number" :max="999" :min="1"
custom-class="!bg-[#F6F7F8] !rounded-16rpx !px-28rpx !py-20rpx" /> custom-class="!bg-[#F6F7F8] !rounded-16rpx !px-28rpx !py-20rpx" />
</view> </view> -->
</view> </view>
<!-- 套餐详情 --> <!-- 套餐详情 -->
@ -228,7 +216,7 @@
</view> </view>
<!-- 套餐介绍 --> <!-- 套餐介绍 -->
<view class="add-textarea mb-28rpx"> <!-- <view class="add-textarea mb-28rpx">
<view class="mb-20rpx flex items-center justify-between"> <view class="mb-20rpx flex items-center justify-between">
<view class="flex items-center"> <view class="flex items-center">
<view class="mr-10rpx text-30rpx text-[#303133] font-bold leading-44rpx"> <view class="mr-10rpx text-30rpx text-[#303133] font-bold leading-44rpx">
@ -245,7 +233,7 @@
<wd-textarea v-model="form.packageIntro" <wd-textarea v-model="form.packageIntro"
custom-class="!rounded-18rpx !border-2rpx !border-[#EFF0EF] !bg-[#F8F9FA] !mt-20rpx" custom-class="!rounded-18rpx !border-2rpx !border-[#EFF0EF] !bg-[#F8F9FA] !mt-20rpx"
custom-textarea-class="!bg-[#F8F9FA]" placeholder="请输入套餐介绍,每条内容换行输入" /> custom-textarea-class="!bg-[#F8F9FA]" placeholder="请输入套餐介绍,每条内容换行输入" />
</view> </view> -->
<!-- 其他说明 --> <!-- 其他说明 -->
<view class="add-textarea mt-30rpx"> <view class="add-textarea mt-30rpx">
@ -254,7 +242,7 @@
其他说明 其他说明
</view> </view>
</view> </view>
<wd-textarea v-model="form.otherNotes" <wd-textarea v-model="form.other_describe"
custom-class="!rounded-18rpx !border-2rpx !border-[#EFF0EF] !bg-[#F8F9FA] !mt-20rpx" custom-class="!rounded-18rpx !border-2rpx !border-[#EFF0EF] !bg-[#F8F9FA] !mt-20rpx"
custom-textarea-class="!bg-[#F8F9FA]" placeholder="请输入其他说明" /> custom-textarea-class="!bg-[#F8F9FA]" placeholder="请输入其他说明" />
</view> </view>
@ -262,12 +250,12 @@
<!-- 购买须知 --> <!-- 购买须知 -->
<view v-if="tab === 3"> <view v-if="tab === 3">
<view class="mb-30rpx text-34rpx text-[#303133] font-bold leading-48rpx"> <!-- <view class="mb-30rpx text-34rpx text-[#303133] font-bold leading-48rpx">
购买须知 购买须知
</view> </view> -->
<!-- 使用人数 --> <!-- 使用人数 -->
<view class="mb-28rpx"> <!-- <view class="mb-28rpx">
<view class="mb-20rpx flex items-center"> <view class="mb-20rpx flex items-center">
<view class="mr-10rpx text-30rpx text-[#303133] font-bold leading-44rpx"> <view class="mr-10rpx text-30rpx text-[#303133] font-bold leading-44rpx">
使用人数 使用人数
@ -278,10 +266,10 @@
</view> </view>
<wd-input v-model="form.userCount" no-border placeholder="建议4~6人使用" <wd-input v-model="form.userCount" no-border placeholder="建议4~6人使用"
custom-class="!bg-[#F6F7F8] !rounded-16rpx !px-28rpx !py-20rpx" /> custom-class="!bg-[#F6F7F8] !rounded-16rpx !px-28rpx !py-20rpx" />
</view> </view> -->
<!-- 退改说明 --> <!-- 退改说明 -->
<view class="add-textarea mt-28rpx"> <!-- <view class="add-textarea mt-28rpx">
<view class="mb-20rpx flex items-center"> <view class="mb-20rpx flex items-center">
<view class="mr-10rpx text-32rpx text-[#303133] font-bold leading-44rpx"> <view class="mr-10rpx text-32rpx text-[#303133] font-bold leading-44rpx">
退改说明 退改说明
@ -293,7 +281,7 @@
<wd-textarea v-model="form.refundPolicy" <wd-textarea v-model="form.refundPolicy"
custom-class="!rounded-18rpx !border-2rpx !border-[#EFF0EF] !bg-[#F8F9FA] !mt-20rpx" custom-class="!rounded-18rpx !border-2rpx !border-[#EFF0EF] !bg-[#F8F9FA] !mt-20rpx"
custom-textarea-class="!bg-[#F8F9FA]" placeholder="请输入退改说明" /> custom-textarea-class="!bg-[#F8F9FA]" placeholder="请输入退改说明" />
</view> </view> -->
</view> </view>
</view> </view>
@ -301,7 +289,7 @@
<view class="fixed bottom-0 left-0 right-0 h-152rpx bg-white"> <view class="fixed bottom-0 left-0 right-0 h-152rpx bg-white">
<view class="mt-34rpx flex items-center justify-center"> <view class="mt-34rpx flex items-center justify-center">
<wd-button custom-class="!text-32rpx !w-630rpx !h-90rpx !bg-[#4C9F44] !rounded-8rpx !text-[#fff]" <wd-button custom-class="!text-32rpx !w-630rpx !h-90rpx !bg-[#4C9F44] !rounded-8rpx !text-[#fff]"
@click="StoreManage.handleSave"> @click="RoomDetail.handleSave">
保存 保存
</wd-button> </wd-button>
</view> </view>
@ -309,10 +297,10 @@
<!-- 选择标签弹窗 --> <!-- 选择标签弹窗 -->
<wd-popup v-model="showTagSelectPopup" lock-scroll custom-style="border-radius: 32rpx 32rpx 0rpx 0rpx;" <wd-popup v-model="showTagSelectPopup" lock-scroll custom-style="border-radius: 32rpx 32rpx 0rpx 0rpx;"
position="bottom" @close="StoreManage.handleCloseTagSelect"> position="bottom" @close="RoomDetail.handleCloseTagSelect">
<view class="relative bg-white px-30rpx pb-56rpx pt-50rpx"> <view class="relative bg-white px-30rpx pb-56rpx pt-50rpx">
<!-- 关闭按钮 --> <!-- 关闭按钮 -->
<view class="absolute right-30rpx top-18rpx" @click="StoreManage.handleCloseTagSelect"> <view class="absolute right-30rpx top-18rpx" @click="RoomDetail.handleCloseTagSelect">
<wd-icon name="close" size="20px" color="#C0C4CC" /> <wd-icon name="close" size="20px" color="#C0C4CC" />
</view> </view>
@ -327,7 +315,7 @@
我的标签 我的标签
</view> </view>
<view class="text-28rpx text-[#4C9F44] leading-40rpx" <view class="text-28rpx text-[#4C9F44] leading-40rpx"
@click="isTagManageMode ? StoreManage.handleExitManagement() : StoreManage.handleEnterManagement()"> @click="isTagManageMode ? RoomDetail.handleExitManagement() : RoomDetail.handleEnterManagement()">
{{ isTagManageMode ? '退出管理' : '管理' }} {{ isTagManageMode ? '退出管理' : '管理' }}
</view> </view>
</view> </view>
@ -339,23 +327,23 @@
<!-- 标签列表 --> <!-- 标签列表 -->
<view class="flex flex-wrap gap-16rpx"> <view class="flex flex-wrap gap-16rpx">
<view v-for="tag in availableTags" :key="tag" <view v-for="(item, index) in availableTags" :key="item.id"
class="flex items-center rounded-20rpx px-20rpx py-8rpx" class="flex items-center rounded-20rpx px-20rpx py-8rpx"
:class="selectedTags.includes(tag) ? 'bg-[#4C9F44]' : 'bg-[#F6F7F8]'" :class="selectedTags.includes(index) ? 'bg-[#4C9F44]' : 'bg-[#F6F7F8]'"
@click="StoreManage.handleSelectTag(tag)"> @click="RoomDetail.handleSelectTag(index)">
<view class="text-26rpx leading-36rpx" <view class="text-26rpx leading-36rpx"
:class="selectedTags.includes(tag) ? 'text-[#fff]' : 'text-[#303133]'" :class="selectedTags.includes(index) ? 'text-[#fff]' : 'text-[#303133]'"
:style="{ marginRight: isTagManageMode ? '8rpx' : '0' }"> :style="{ marginRight: isTagManageMode ? '8rpx' : '0' }">
{{ tag }} {{ item.label_name }}
</view> </view>
<wd-icon v-if="isTagManageMode" name="close-circle-filled" size="14px" <wd-icon v-if="isTagManageMode" name="close-circle-filled" size="14px"
:color="selectedTags.includes(tag) ? '#fff' : '#909399'" :color="selectedTags.includes(index) ? '#fff' : '#909399'"
@click.stop="StoreManage.handleRemoveTagFromList(tag, $event)" /> @click.stop="RoomDetail.handleRemoveTagFromList(index, $event)" />
</view> </view>
<!-- 新建标签按钮 --> <!-- 新建标签按钮 -->
<view v-if="!isTagManageMode" <view v-if="!isTagManageMode"
class="flex items-center border-2rpx border-[#E5E5E5] rounded-20rpx border-dashed px-20rpx py-8rpx" class="flex items-center border-2rpx border-[#E5E5E5] rounded-20rpx border-dashed px-20rpx py-8rpx"
@click="StoreManage.handleShowCreateTag"> @click="RoomDetail.handleShowCreateTag">
<wd-icon name="add" size="16px" color="#909399" class="mr-8rpx" /> <wd-icon name="add" size="16px" color="#909399" class="mr-8rpx" />
<view class="text-26rpx text-[#909399] leading-36rpx"> <view class="text-26rpx text-[#909399] leading-36rpx">
新建标签 新建标签
@ -367,7 +355,7 @@
<view <view
class="mt-40rpx h-90rpx rounded-8rpx bg-[#4C9F44] text-center text-30rpx text-[#fff] leading-90rpx" class="mt-40rpx h-90rpx rounded-8rpx bg-[#4C9F44] text-center text-30rpx text-[#fff] leading-90rpx"
:class="isTagManageMode ? 'opacity-0 pointer-events-none' : ''" :class="isTagManageMode ? 'opacity-0 pointer-events-none' : ''"
@click="StoreManage.handleConfirmTags"> @click="RoomDetail.handleConfirmTags">
确认 确认
</view> </view>
</view> </view>
@ -375,17 +363,17 @@
<!-- 新建标签弹窗 --> <!-- 新建标签弹窗 -->
<wd-popup v-model="showCreateTagPopup" lock-scroll custom-style="border-radius: 32rpx 32rpx 0rpx 0rpx;" <wd-popup v-model="showCreateTagPopup" lock-scroll custom-style="border-radius: 32rpx 32rpx 0rpx 0rpx;"
position="bottom" @close="StoreManage.handleCloseCreateTag"> position="bottom" @close="RoomDetail.handleCloseCreateTag">
<view class="relative bg-white px-30rpx pb-78rpx pt-50rpx"> <view class="relative bg-white px-30rpx pb-78rpx pt-50rpx">
<!-- 导航栏 --> <!-- 导航栏 -->
<view class="mb-40rpx flex items-center justify-between"> <view class="mb-40rpx flex items-center justify-between">
<view class="flex items-center" @click="StoreManage.handleCloseCreateTag"> <view class="flex items-center" @click="RoomDetail.handleCloseCreateTag">
<wd-icon name="arrow-left" size="20px" color="#303133" /> <wd-icon name="arrow-left" size="20px" color="#303133" />
</view> </view>
<view class="text-center text-36rpx text-[#121212] leading-50rpx"> <view class="text-center text-36rpx text-[#121212] leading-50rpx">
新建标签 新建标签
</view> </view>
<view class="flex items-center" @click="StoreManage.handleCloseCreateTag"> <view class="flex items-center" @click="RoomDetail.handleCloseCreateTag">
<wd-icon name="close" size="20px" color="#C0C4CC" /> <wd-icon name="close" size="20px" color="#C0C4CC" />
</view> </view>
</view> </view>
@ -398,7 +386,7 @@
<!-- 完成按钮 --> <!-- 完成按钮 -->
<view class="h-90rpx rounded-8rpx bg-[#4C9F44] text-center text-30rpx text-[#fff] leading-90rpx" <view class="h-90rpx rounded-8rpx bg-[#4C9F44] text-center text-30rpx text-[#fff] leading-90rpx"
@click="StoreManage.handleCompleteCreateTag"> @click="RoomDetail.handleCompleteCreateTag">
完成 完成
</view> </view>
</view> </view>
@ -408,258 +396,362 @@
<script lang="ts" setup> <script lang="ts" setup>
import { toast } from '@/utils/toast' import { getRoomDetails, getRoomLabelList, handleCreateTag, handleDeleteTag, editRoom } from '@/api/store'
import { updateUserInfo } from '@/api/user'
import { router } from '@/utils/tools'
import { toast } from '@/utils/toast'
import { useStoreStore } from '@/store'
const OSS = inject('OSS') const OSS = inject('OSS')
const navbarHeight = inject('navbarHeight') const token = ref<string>('') // 用户token
const useStore = useStoreStore()
// tab // tab
const tab = ref<number>(0) const tab = ref<number>(0)
// 上传文件 // 上传文件
const action = 'https://www.mocky.io/v2/5cc8019d300000980a055e76' // 仅做测试使用,实际请换成真实上传接口 const fileList = ref<any[]>([])
const action = import.meta.env.VITE_UPLOAD_BASEURL
// 表单 // 标签相关
const form = reactive({ const showTagSelectPopup = ref(false)
roomName: '', const showCreateTagPopup = ref(false)
tags: [] as string[], const newTagName = ref('')
video: null as any, const isTagManageMode = ref(false) // 是否处于管理模式
images: [] as string[], const selectedTags = ref<number[]>([]) // 临时选中的标签,点击确认后才回填到表单
hourlyPrice: '', // Mock 已有标签列表
minBookingTime: '', const availableTags = ref<Array<{
inventory: '', id: number
packageIntro: '', label_name: string
otherNotes: '', }>>([
userCount: '', {id: 0, label_name: ''}
refundPolicy: '', ])
})
// 标签相关 const roomId = ref<number>(0) // 包间ID
const showTagSelectPopup = ref(false) // 表单
const showCreateTagPopup = ref(false) const form = reactive({
const newTagName = ref('') title: '',
const isTagManageMode = ref(false) // 是否处于管理模式 image: '',
const selectedTags = ref<string[]>([]) // 临时选中的标签,点击确认后才回填到表单 tags: [] as string[],
// Mock 已有标签列表 price: '',
const availableTags = ref([ hours: '',
'全息投影', video: null as any,
'环境优雅', other_describe: '',
'幽静雅致', })
'禅意悠然', const tags = ref<Array<{ id: number, label_name: string, index: number }>>([])
'雅室禅意浓', const roomLabelId = ref<string>('')
'古朴韵悠长',
])
const StoreManage = { onLoad(async (args) => {
/** token.value = uni.getStorageSync('token')
* 切换tab
*/
handleChangeTab: (e: any) => {
tab.value = e.name
},
/** roomId.value = args.id || 0
* 添加标签 - 显示选择标签弹窗 await RoomDetail.handleGetRoomDetails()
*/ await RoomDetail.handleGetRoomLabels()
handleAddTag: () => { })
// 初始化临时选中的标签为当前表单中的标签
selectedTags.value = [...form.tags]
showTagSelectPopup.value = true
},
/** const RoomDetail = {
* 关闭选择标签弹窗 /**
*/ * 初始化信息
handleCloseTagSelect: () => { */
showTagSelectPopup.value = false handleGetRoomDetails: async () => {
isTagManageMode.value = false // 关闭时重置管理模式 const res = await getRoomDetails(roomId.value)
selectedTags.value = [] // 清空临时选中的标签 fileList.value = [{url: res.details.room.img, name: res.details.room.img }]
}, roomLabelId.value = res.details.room.label_id
/** form.title = res.details.room.title
* 选择标签(临时选择,不直接修改表单) form.image = res.details.room.img
*/ form.price = res.details.room.price.toString()
handleSelectTag: (tag: string) => { form.hours = res.details.room.hours.toString()
if (isTagManageMode.value) { form.other_describe = res.details.room.other_describe || ''
// 管理模式时,点击标签不进行选择操作 },
return
} /**
if (selectedTags.value.includes(tag)) { * 获取包间标签列表
// 如果已选择,则取消选择 */
const index = selectedTags.value.indexOf(tag) handleGetRoomLabels: async () => {
selectedTags.value.splice(index, 1)
} const res = await getRoomLabelList(useStore.defaultStore.id)
else { availableTags.value = res.list
// 如果未选择,则添加
if (selectedTags.value.length >= 2) { if (roomLabelId.value) {
toast.info('最多只能选择2个标签') const labelIds = roomLabelId.value.split(',').map((id: string) => parseInt(id))
tags.value = labelIds.map((id: number) => {
const tagIndex = availableTags.value.findIndex(tag => tag.id === id)
const tag = availableTags.value[tagIndex]
return {
id: tag.id,
label_name: tag.label_name,
index: tagIndex
}
})
console.log("🚀 ~ form.tags:", tags.value)
// 设置已选择的标签
selectedTags.value = []
labelIds.forEach((id: number) => {
const index = availableTags.value.findIndex(tag => tag.id === id)
if (index !== -1) {
selectedTags.value.push(index)
}
})
}
console.log("🚀 ~ availableTags.value:", availableTags.value)
},
/**
* 切换tab
*/
handleChangeTab: (e: any) => {
tab.value = e.name
},
/**
* 添加标签 - 显示选择标签弹窗
*/
handleAddTag: () => {
// 初始化临时选中的标签为当前表单中的标签
// selectedTags.value = availableTags.value
showTagSelectPopup.value = true
},
/**
* 上传图片
*/
handleUploadSuccess: async (e: any) => {
try {
const response = JSON.parse(e.file.response)
if (response.code) {
const avatarUrl = response.data.uri
await updateUserInfo({ avatar: avatarUrl })
form.image = avatarUrl
toast.info('头像上传成功')
} else {
throw new Error('上传失败')
}
} catch (error) {
toast.info('上传失败')
}
},
/**
* 关闭选择标签弹窗
*/
handleCloseTagSelect: () => {
showTagSelectPopup.value = false
isTagManageMode.value = false // 关闭时重置管理模式
// selectedTags.value = [] // 清空临时选中的标签
},
/**
* 选择标签(临时选择,不直接修改表单)
*/
handleSelectTag: (id: number) => {
if (isTagManageMode.value) {
// 管理模式时,点击标签不进行选择操作
return return
} }
selectedTags.value.push(tag) if (selectedTags.value.includes(id)) {
} // 如果已选择,则取消选择
}, const index = selectedTags.value.indexOf(id)
selectedTags.value.splice(index, 1)
/**
* 从选择列表删除标签
*/
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张图片')
} }
} else {
}, // 如果未选择,则添加
if (selectedTags.value.length >= 2) {
toast.info('最多只能选择2个标签')
return
}
selectedTags.value.push(id)
}
},
/** /**
* 删除图片 * 从选择列表删除标签
*/ */
handleRemoveImage: (index: number) => { handleRemoveTagFromList: async (index: number, event: any) => {
form.images.splice(index, 1) event.stopPropagation()
}, uni.showLoading({
title: '操作中...',
mask: true
})
/** try {
* 保存 const tagId = availableTags.value[index].id
*/ availableTags.value.splice(index, 1)
handleSave: () => { await handleDeleteTag(tagId)
// TODO: 实现保存功能 tags.value = tags.value.filter(tag => tag.id !== tagId)
console.log('保存表单:', form) uni.hideLoading()
toast.info('保存成功')
},
/** toast.info('删除成功')
* 点击更多选项 } catch(e) {
*/ uni.hideLoading()
handleMore: () => { toast.info('删除失败,请稍后重试')
// TODO: 实现更多选项功能 }
console.log('更多选项') },
},
/** /**
* 点击目标图标 * 确认选择标签
*/ */
handleTarget: () => { handleConfirmTags: () => {
// TODO: 实现目标功能 tags.value = selectedTags.value.map(index => {
console.log('目标功能') return {
}, id: availableTags.value[index].id,
} label_name: availableTags.value[index].label_name,
index
}
})
showTagSelectPopup.value = false
isTagManageMode.value = false
// selectedTags.value = []
},
/**
* 进入管理模式
*/
handleEnterManagement: () => {
isTagManageMode.value = true
selectedTags.value = []
},
/**
* 退出管理模式
*/
handleExitManagement: () => {
isTagManageMode.value = false
},
/**
* 显示新建标签弹窗
*/
handleShowCreateTag: () => {
showTagSelectPopup.value = false
showCreateTagPopup.value = true
},
/**
* 关闭新建标签弹窗
*/
handleCloseCreateTag: () => {
showCreateTagPopup.value = false
newTagName.value = ''
},
/**
* 完成新建标签
*/
handleCompleteCreateTag: async () => {
const tagName = newTagName.value.trim()
if (!tagName) {
toast.info('请输入标签名称')
return
}
if (tagName.length > 5) {
toast.info('标签不能超过5个字')
return
}
uni.showLoading({
title: '操作者中...'
})
try {
await handleCreateTag({
store_id: useStore.defaultStore.id,
label_name: tagName
})
uni.hideLoading()
RoomDetail.handleGetRoomLabels()
showCreateTagPopup.value = false
newTagName.value = ''
showTagSelectPopup.value = true
toast.info('标签创建成功')
} catch (e) {
uni.hideLoading()
}
},
/**
* 删除标签
*/
handleRemoveTag: (index: number) => {
tags.value.splice(index, 1)
},
/**
* 上传视频
*/
handleUploadVideo: (event: any) => {
if (event.fileList && event.fileList.length > 0) {
form.video = event.fileList[0]
}
},
/**
* 删除视频
*/
handleRemoveVideo: () => {
form.video = null
},
/**
* 保存
*/
handleSave: async () => {
// TODO: 实现保存功能
if (!form.title) {
toast.info('请输入包间名称')
return
}
if (tags.value.length === 0) {
toast.info('请选择包间标签')
return
}
if (!form.image) {
toast.info('请上传团购图片')
return
}
if (!form.price) {
toast.info('请输入价格')
return
}
if (!form.hours) {
toast.info('请输入起订时间')
return
}
let params = {
id: roomId.value,
img: form.image,
title: form.title,
label_id: tags.value.map(tag => tag.id).join(','),
price: Number(form.price),
hours: Number(form.hours),
other_describe: form.other_describe,
}
uni.showLoading({
title: '保存中...',
mask: true
})
try {
await editRoom(params)
uni.hideLoading()
toast.info('修改成功')
router.navigateBack(1, 500)
} catch (e) {
toast.info('修改失败,请稍后重试')
uni.hideLoading()
return
}
},
}
</script> </script>
@ -668,6 +760,7 @@ page {
background: #f6f7f8; background: #f6f7f8;
} }
.store-tabs { .store-tabs {
:deep() { :deep() {
.wd-tabs__line { .wd-tabs__line {