调试接口

This commit is contained in:
wangxiaowei
2025-12-30 19:08:44 +08:00
parent f69536a7e4
commit 031649e9c4
11 changed files with 455 additions and 327 deletions

View File

@ -0,0 +1,8 @@
import { http } from '@/http/alova'
/**
* 茶艺师个人介绍
*/
export function getTeaSpecialistProfile() {
return http.Post<any>('/teamapi/user/Introduction')
}

View File

@ -79,3 +79,74 @@ export function resetPassword(data: IResetPasswordParams) {
export function getUserBalance(store_id: number) {
return http.Post<any>('/storeapi/user/checkMoney', {store_id})
}
/**
* 修改个人信息
*/
// export function setUserAvatar() {
// return http.Post('/storeapi/user/updateUser', { avatar })
// }
/**
* 编辑工作时间
*/
export interface ISetUserWorkTimeParams {
work_day: string // 1,2,3,4,5也就是周一、二、三、四、五
work_start: string // 09:00
work_end: string // 18:00
}
export function setUserWorkTime(data: ISetUserWorkTimeParams) {
return http.Post('/teamapi/user/editWork', data)
}
/**
* 地址列表
*/
export interface IUserAddressListParams {
id: number
team_user_id: number
city_id: number
longitude: number
latitude: number
address: string
}
export function getUserAddressList() {
return http.Post<Array<IUserAddressListResult>>('/teamapi/user/addressList')
}
/**
* 获取已开通城市列表
*/
export function getOpenCityList() {
return http.Post<any>('/teamapi/user/teaStoreCity')
}
/**
* 新增地址
*/
export interface IAddUserAddressListParams {
city_id: number
longitude: number
latitude: number
address: string
}
export function addUserAddress(data: IAddUserAddressListParams) {
return http.Post('/teamapi/user/addAddress', data)
}
/**
* 编辑地址
*/
export function editUserAddress(data: IAddUserAddressListParams & { id: number }) {
return http.Post('/teamapi/user/editAddress', data)
}
/**
* 删除地址
*/
export function deleteUserAddress(id: number) {
return http.Post('/teamapi/user/delAddress', { id })
}

View File

@ -15,12 +15,12 @@
<navbar title="新增地址" :leftArrow="false" custom-class='!bg-[#F6F7F8]'></navbar>
<view class="bg-white mx-32rpx rounded-16rpx px-42rpx py-34rpx mt-32rpx">
<view class="bg-white mx-32rpx rounded-16rpx px-42rpx mt-32rpx">
<view class="flex items-center">
<view class="text-30rpx leading-42rpx text-[#303133] w-200rpx">选择地区</view>
<wd-picker :columns="cityColumns" v-model="form.city" use-default-slot>
<wd-picker :columns="cityColumns" v-model="form.city_id" use-default-slot @confirm="Add.handleConfirmAddress">
<view class="flex items-center">
<wd-input readonly v-model="form.city" size="large" placeholder="请选择地区" no-border placeholderStyle="font-size: 30rpx; line-height: 42rpx; color: #c9c9c9;"></wd-input>
<wd-input readonly v-model="city" size="large" placeholder="请选择地区" no-border placeholderStyle="font-size: 30rpx; line-height: 42rpx; color: #c9c9c9;"></wd-input>
<wd-icon name="chevron-right" size="32rpx" color="#909399"></wd-icon>
</view>
</wd-picker>
@ -48,8 +48,7 @@
</view>
<view class="flex items-center justify-between mx-30rpx" v-if="addressId > 0">
<view class="w-330rpx h-90rpx leading-90rpx text-center bg-[#F6F7F8] text-#303133 rounded-8rpx mr-30rpx" @click="Add.handleDeleteAddress">删除地址</view>
<view class="w-330rpx h-90rpx leading-90rpx text-center bg-[#4C9F44] text-#FFFFFF rounded-8rpx" @click="Add.handleAddAddress">确定</view>
<view class="w-630rpx h-90rpx leading-90rpx text-center bg-[#4C9F44] text-#FFFFFF rounded-8rpx" @click="Add.handleAddAddress">确定</view>
</view>
</view>
@ -59,7 +58,7 @@
<script lang="ts" setup>
import { useMessage } from 'wot-design-uni'
import { useColPickerData } from '@/hooks/useColPickerData'
// import { addUserAddress, IAddUserAddressParams, deleteUserAddress, userAddressDetails, editUserAddress } from '@/api/user'
import { addUserAddress, deleteUserAddress, editUserAddress, getOpenCityList } from '@/api/user'
import { toast } from '@/utils/toast'
import { mobile } from '@/utils/test'
import { router } from '@/utils/tools'
@ -70,12 +69,7 @@
const message = useMessage('wd-message-box-slot')
// 获取已开通城市
const cityColumns = ref<Array<{ label: string; value: string }>>([
{ label: '北京市', value: '110000' },
{ label: '上海市', value: '310000' },
{ label: '广州市', value: '440100' },
{ label: '深圳市', value: '440300' },
])
const cityColumns = ref<Array<{ label: string, value: number }>>([])
// 页面标题
const title = ref<string>('新增地址')
@ -85,10 +79,12 @@
// 表单信息
const form = ref({
city: '',
city_id: 0,
latitude: 0,
longitude: 0,
address: '',
id: 0
})
const city = ref<string>('')
onLoad((args) => {
@ -98,18 +94,29 @@
addressId.value = Number(args.id)
// Add.handleGetAddressDetails()
}
Add.handleGetCity()
})
const Add = {
// // 确认省市区
// handleConfirmAddress: (e) => {
// form.province = e.selectedItems[0]?.label || ''
// form.province_id = Number(e.selectedItems[0]?.value) || 0
// form.city = e.selectedItems[1]?.label || ''
// form.city_id = Number(e.selectedItems[1]?.value) || 0
// form.district = e.selectedItems[2]?.label || ''
// form.district_id = Number(e.selectedItems[2]?.value) || 0
// },
/**
* 获取已开通城市
*/
handleGetCity: async () => {
const res = await getOpenCityList()
cityColumns.value = res.list.map((item: any) => ({
label: item.name,
value: item.id
}))
},
/**
* 确认选择的地址
*/
handleConfirmAddress: (e: any) => {
form.value.city_id = Number(e.value)
city.value = e.selectedItems.label || ''
},
// // 获取地址详情
// handleGetAddressDetails: async () => {
@ -136,36 +143,6 @@
// console.log("🚀 ~ address.value:", address.value)
// },
// // 删除地址
// handleDeleteAddress: async () => {
// console.log("🚀 ~ 删除地址:", message)
// message.confirm({
// title: '删除地址',
// msg: '确定要删除该地址吗?',
// confirmButtonText: '确定',
// cancelButtonText: '取消',
// cancelButtonProps: {
// customClass: '!bg-[#F6F7F8] !text-[#303133] !text-32rpx !leading-44rpx !rounded-8rpx',
// },
// confirmButtonProps: {
// customClass: '!bg-[#4C9F44] !text-[#fff] !text-32rpx !leading-44rpx !rounded-8rpx',
// }
// }).then(async (res) => {
// // 点击确认按钮回调事件
// await deleteUserAddress({
// id: addressId.value
// })
// toast.info('删除成功')
// uni.$emit('refreshAddressList')
// router.navigateBack(500)
// }).catch((res) => {
// console.log("🚀 ~ res2:", res)
// // 点击取消按钮回调事件
// })
// },
/**
* 选择地址
*/
@ -177,7 +154,9 @@
// res.name: "嘉兴市南湖区人民政府(景宜路西)"
// res.latitude: 30.74744
// res.longitude: 120.78483
form.value.address = res.address + res.name
form.value.address = res.address
form.value.latitude = res.latitude
form.value.longitude = res.longitude
},
fail: (err) => {
console.log("🚀 ~ err:", err)
@ -189,24 +168,29 @@
* 添加地址
*/
handleAddAddress: async () => {
// if (!form.address) {
// toast.info('请填写地址信息')
// return
// }
if (!form.value.city_id) {
toast.info('请选择地区')
return false
}
// // form.is_default = isDefaultAddress.value ? 1 : 0
if (!form.value.address) {
toast.info('请填写地址信息')
return false
}
// if (addressId.value > 0 ) {
// // 编辑地址
// form.id = addressId.value
// // await editUserAddress(form)
// } else {
// // await addUserAddress(form)
// }
// uni.$emit('refreshAddressList')
// router.navigateBack(500)
}
if (addressId.value > 0 ) {
// 编辑地址
// form.id = addressId.value
// await editUserAddress(form)
} else {
await addUserAddress(form.value)
}
uni.$emit('refreshAddressList')
router.navigateBack(500)
},
// // 添加地址
// handleAddAddress: async () => {
// if (!form.contact) {

View File

@ -26,45 +26,19 @@
<view class="text-28rpx leading-40rpx text-[#8A94A3] mt-18rpx">还没有地址请尽快新建地址</view>
</view>
<!-- <wd-radio-group v-model="addressId" shape="button" >
<wd-radio :value="1">沃特</wd-radio>
<wd-radio :value="2">商家后台</wd-radio>
</wd-radio-group> -->
<!-- 地址列表 -->
<!-- <view class="mx-30rpx mt-20rpx" v-if="addressList.length > 0">
<view class="bg-#fff rounded-16rpx px-30rpx py-36rpx flex items-center mb-20rpx" v-for="(item, index) in addressList" :key="index">
<view @click="List.handleChooseAddress(item)">
<view class="flex items-center">
<view class="mr-10rpx">
<wd-tag color="#4C9F44" bg-color="#F3F3F3" custom-class="!rounded-4rpx !px-10rpx" v-if="item.is_default">默认</wd-tag>
</view>
<view class="text-30rpx leading-42rpx text-#303133">
<text class="mr-16rpx">{{ item.contact}}</text>
<text>{{ item.telephone }}</text>
</view>
</view>
<view class="w-562rpx line-1 text-26rpx leading-34rpx text-#909399 mt-10rpx">{{ item.address }}</view>
</view>
<view class="flex-1 ml-30rpx" @click="List.handleEditAddress(item.id)">
<wd-icon name="edit-outline" size="32rpx" color="#666666"></wd-icon>
</view>
</view>
</view> -->
<view class="mx-30rpx mt-38rpx address-radio">
<wd-radio-group v-model="addressId" shape="dot" >
<view class="bg-white rounded-16rpx px-40rpx py-30rpx mb-20rpx" v-for="item in addressList" :key="item.id">
<view class="bg-white rounded-16rpx px-40rpx py-30rpx mb-20rpx" v-for="(item, index) in addressList" :key="item.id">
<view class="">
<wd-radio :value="item.id" checked-color="#4C9F44">
<view class="flex items-center">
<wd-img :src="`${OSS}icon/icon_location5.png`" width="40rpx" height="40rpx"></wd-img>
<view class="ml-16rpx text-30rpx leading-42rpx text-[#303133]">位置1</view>
<view class="ml-16rpx text-30rpx leading-42rpx text-[#303133]">位置{{ index + 1 }}</view>
</view>
</wd-radio>
</view>
<view class="line-2 text-26rpx leading-34rpx text-[#606266] mt-16rpx">
北京市海淀区恒大新宏福苑西区20号楼2单元301
{{ item.address }}
</view>
<view class="flex items-center justify-end mt-24rpx text-26rpx leading-34rpx text-[##303133]">
@ -99,9 +73,12 @@
import type { IUserAddressListResult } from '@/api/types/user'
import { router } from '@/utils/tools'
import { useMessage } from 'wot-design-uni'
import { getUserAddressList, deleteUserAddress } from '@/api/user'
import { useToast } from 'wot-design-uni'
const OSS = inject('OSS')
const from = ref<string>('')
const toast = useToast()
// 弹出框
const message = useMessage('wd-message-box-slot')
@ -111,24 +88,14 @@
// 选中的地址ID
const addressId = ref<number>(0)
const addressList = ref<Array<{id:number, address: string}>>([
{
id: 1,
address: '浙江省杭州市西湖区文三路138号',
},
{
id: 2,
address: '浙江省杭州市西湖区文三路138号',
}
])
const addressList = ref<Array<{id:number, address: string}>>([])
onLoad((args) => {
if (args.from) {
from.value = args.from as string
}
// 监听地址列表刷新
// 监听地址列表刷新
uni.$on('refreshAddressList', () => {
List.handleInit()
})
@ -146,8 +113,8 @@
* 初始化地址列表
*/
handleInit: async () => {
const res = await getUserAddress()
addressList.value = Array.isArray(res) ? res : []
const res = await getUserAddressList()
addressList.value = res
},
/**
@ -185,17 +152,11 @@
customClass: '!bg-[#4C9F44] !text-[#fff] !text-32rpx !leading-44rpx !rounded-8rpx',
}
}).then(async (res) => {
// // 点击确认按钮回调事件
// await deleteUserAddress({
// id: addressId.value
// })
// toast.info('删除成功')
// uni.$emit('refreshAddressList')
// router.navigateBack(500)
}).catch((res) => {
console.log("🚀 ~ res2:", res)
// 点击取消按钮回调事件
})
// 点击确认按钮回调事件
await deleteUserAddress(id)
toast.show('删除成功')
List.handleInit()
}).catch((res) => { })
},
/**
@ -208,7 +169,7 @@
</script>
<style lang="scss" scoped>
<style lang="scss">
page {
background-color: $cz-page-background;
}

View File

@ -207,9 +207,10 @@
const response = JSON.parse(e.file.response)
if (response.code) {
const avatarUrl = response.data.url
await updateUserInfo({ avatar: avatarUrl })
user.value.avatar = avatarUrl
toast.info('头像上传成功')
console.log("🚀 ~ avatarUrl:", response)
// await updateUserInfo({ avatar: avatarUrl })
// user.value.avatar = avatarUrl
// toast.info('头像上传成功')
} else {
throw new Error('上传失败')
}

View File

@ -0,0 +1,53 @@
<template>
<view class="w-168rpx h-40rpx relative mr-44rpx">
<view class="absolute left-0 top-0 h-36rpx flex items-start">
<!-- 金牌茶艺师 -->
<wd-img :src="levelMap[level].icon" width="36rpx" height="36rpx"></wd-img>
</view>
<view class="bg-[#F0F6EF] text-[#006C2D] font-400 text-22rpx leading-32rpx rounded-4rpx text-center w-150rpx ml-18rpx pb-4rpx">{{ levelMap[level].text }}</view>
</view>
</template>
<script lang="ts" setup name="TeaSpecialistLevel">
/**
* TeaSpecialistLevel 茶艺师等级
* @description 用于展示茶艺师等级
*/
const OSS = inject('OSS')
defineProps({
level: {
type: String,
default: ''
}
})
// 茶艺师等级对应的icon和文字
const levelMap = {
gold: {
icon: `${OSS}icon/icon_gold_medal.png`,
text: '金牌茶艺师'
},
senior: {
icon: `${OSS}icon/icon_senior_medal.png`,
text: '高级茶艺师'
},
intermediate: {
icon: `${OSS}icon/icon_intermediate_medal.png`,
text: '中级茶艺师'
},
junior: {
icon: `${OSS}icon/icon_junior_medal.png`,
text: '初级茶艺师'
},
enthusiast: {
icon: `${OSS}icon/icon_enthusiast_medal.png`,
text: '茶艺爱好者'
}
}
</script>
<script lang="ts">
export default {}
</script>

View File

@ -7,7 +7,7 @@
<template>
<view class="page-container pb-120rpx">
<view class="page-container pb-180rpx">
<wd-navbar safe-area-inset-top :bordered="false" custom-style="background-color: transparent !important;" fixed>
<template #left>
<view class="ml-16rpx flex items-center" />
@ -263,7 +263,11 @@
// 用户信息
const userStore = useUserStore()
const userInfo = userStore.userInfo
const userInfo = ref({
avatar: userStore.userInfo.avatar,
nickname: userStore.userInfo.nickname,
account: userStore.userInfo.account
})
const otherInfo = ref<{
user_money: number // 可提现金额
no_reflect_amount: number // 不可提现金额
@ -322,6 +326,7 @@
handleToProfile: () => {
// TODO: 跳转到个人信息页面
console.log('跳转到个人信息页面')
console.log("🚀 ~ userStore.isLoggedIn:", userStore.isLoggedIn)
if (userStore.isLoggedIn) {
router.navigateTo('/bundle/profile/profile')
} else {
@ -374,6 +379,29 @@
}
},
}
watch(
() => userStore.isLoggedIn,
(newValue, oldValue) => {
if (newValue === false) {
// 用户登出时,清空个人信息
userInfo.value = {
avatar: '',
nickname: '',
account: ''
}
otherInfo.value = {
user_money: 0,
no_reflect_amount: 0,
work: '',
address: '',
work_time: '',
is_mileage: 0
}
}
}
)
</script>

View File

@ -10,13 +10,13 @@
<!-- 顶部背景区域 -->
<wd-navbar safe-area-inset-top :bordered="false" :zIndex="20" fixed custom-style="background: transparent !important;">
<template #left>
<view class="ml-16rpx flex items-center" @click.stop="Profile.handleBack">
<view class="ml-16rpx flex items-center" @click.stop="ProfileDisplay.handleBack">
<wd-img :src="`${OSS}icon/icon_arrow_left2.png`" width="48rpx" height="48rpx"></wd-img>
</view>
</template>
</wd-navbar>
<view class="top-bg fixed left-0 top-0 w-[100%] h-416rpx"
<view class="top-bg fixed left-0 top-0 w-[100%] z-[-1]"
:style="{ backgroundImage: `url('${OSS}images/chayishi/profile_top_bg.png')` }">
</view>
@ -27,36 +27,29 @@
<view class="mb-24rpx flex items-center justify-between">
<view class="flex-1">
<view class="mb-16rpx text-36rpx text-[#303133] font-bold leading-50rpx">
茶艺师的名字
{{ profile.name }}
</view>
<view class="flex items-center">
<view class="mr-12rpx flex items-center">
<wd-icon name="star" size="32rpx" color="#FF0000" />
<wd-icon name="star" size="32rpx" color="#FF0000" />
<wd-icon name="star" size="32rpx" color="#FF0000" />
<wd-icon name="star" size="32rpx" color="#FF0000" />
<wd-icon name="star-half" size="32rpx" color="#FF0000" />
<wd-rate v-model="profile.star" readonly active-color="#FF5951" allow-half active-icon="star-filled" icon="star" space="4rpx"/>
</view>
<text class="text-28rpx text-[#303133] leading-40rpx">4.5 推荐</text>
<text class="text-28rpx text-[#303133] leading-40rpx">{{ profile.star }} 推荐</text>
</view>
</view>
</view>
<!-- 修改按钮 - 绝对定位右侧紧贴屏幕边缘 -->
<view
class="modify-btn absolute right-0 top-0 flex items-center rounded-l-24rpx bg-[#FF0000] py-12rpx pl-24rpx pr-30rpx"
@click="Profile.handleEdit">
class="modify-btn absolute right-0 top-100rpx flex items-center rounded-l-24rpx bg-[#FF0000] py-12rpx pl-24rpx pr-30rpx z-1"
@click="ProfileDisplay.handleEdit">
<wd-icon name="edit" size="24rpx" color="#fff" class="mr-8rpx" />
<text class="text-24rpx text-[#fff] font-medium">修改</text>
</view>
<!-- 标签 -->
<view class="mb-30rpx flex items-center">
<view class="tag-item mr-16rpx flex items-center rounded-8rpx bg-[#FFE5E5] px-16rpx py-8rpx">
<text class="text-24rpx text-[#FF6B6B] leading-34rpx">90后茶艺师</text>
</view>
<view class="tag-item flex items-center rounded-8rpx bg-[#E7F5E7] px-16rpx py-8rpx">
<wd-img width="24rpx" height="24rpx" :src="`${OSS}images/chayishi/vip.png`" class="mr-6rpx" />
<text class="text-24rpx text-[#07C160] leading-34rpx">高级茶艺师</text>
<view class="mb-30rpx flex items-start">
<wd-tag color="#FF5951" bg-color="#FEF1F0" custom-class="!rounded-6rpx !px-16rpx !py-4rpx !h-40rpx !w-144rpx" v-if="profile.age_range > 0">90后茶艺师</wd-tag>
<view >
<tea-specialist-level :level="TeaSpecialistNumberLevelValue[profile.level]"></tea-specialist-level>
</view>
</view>
@ -64,28 +57,28 @@
<view class="info-grid grid grid-cols-4 mb-30rpx gap-16rpx">
<view class="info-item text-center">
<text class="label-text text-24rpx text-[#909399] leading-40rpx">性别</text>
<text class="value-text mt-8rpx block text-28rpx text-[#303133] leading-40rpx"></text>
<text class="value-text mt-8rpx block text-28rpx text-[#303133] leading-40rpx">{{ profile.sex == 1 ? '男' : '女' }}</text>
</view>
<view class="info-item text-center">
<text class="label-text text-24rpx text-[#909399] leading-40rpx">年龄</text>
<text class="value-text mt-8rpx block text-28rpx text-[#303133] leading-40rpx">21</text>
<text class="value-text mt-8rpx block text-28rpx text-[#303133] leading-40rpx">{{ profile.age }}</text>
</view>
<view class="info-item text-center">
<text class="label-text text-24rpx text-[#909399] leading-40rpx">身高</text>
<text class="value-text mt-8rpx block text-28rpx text-[#303133] leading-40rpx">165cm</text>
<text class="value-text mt-8rpx block text-28rpx text-[#303133] leading-40rpx">{{ profile.height }}cm</text>
</view>
<view class="info-item text-center">
<text class="label-text text-24rpx text-[#909399] leading-40rpx">体重</text>
<text class="value-text mt-8rpx block text-28rpx text-[#303133] leading-40rpx">53kg</text>
<text class="value-text mt-8rpx block text-28rpx text-[#303133] leading-40rpx">{{ profile.weight }}kg</text>
</view>
</view>
<!-- 照片展示 -->
<view class="mb-30rpx">
<view class="photo-grid grid grid-cols-3 gap-16rpx">
<view v-for="(item, index) in photoList" :key="index"
<view v-for="(item, index) in profile.image_arr" :key="index"
class="photo-item aspect-square w-full overflow-hidden rounded-12rpx"
@click="Profile.handlePreviewPhoto(index)">
@click="ProfileDisplay.handlePreviewPhoto(index)">
<wd-img width="100%" height="100%" :src="item" mode="aspectFill" />
</view>
</view>
@ -93,25 +86,30 @@
<!-- 兴趣爱好 -->
<view class="mb-30rpx">
<view class="mb-16rpx flex items-center">
<wd-img width="32rpx" height="32rpx" :src="`${OSS}images/chayishi/hobby.png`"
class="mr-12rpx" />
<text class="text-28rpx text-[#303133] font-bold leading-40rpx">兴趣爱好</text>
</view>
<view class="interest-text text-26rpx text-[#606266] leading-40rpx">
爱好茶艺,喜欢旅游,把爱好当工作
<view class="font-bold text-[#303133] text-32rpx leading-44rpx mb-22rpx">兴趣爱好</view>
<view class="bg-[#FBFBFB] min-h-136rpx px-28rpx py-20rpx rounded-8rpx">
<view class="mb-16rpx flex items-center">
<wd-img width="32rpx" height="32rpx" :src="`${OSS}images/chayishi/hobby.png`"
class="mr-12rpx" />
<text class="text-28rpx text-[#303133] font-bold leading-40rpx">兴趣爱好</text>
</view>
<view class="interest-text text-26rpx text-[#606266] leading-40rpx">
爱好茶艺,喜欢旅游,把爱好当工作
</view>
</view>
</view>
<!-- 费用说明 -->
<view>
<view class="mb-20rpx flex items-center justify-between">
<view class="font-bold text-[#303133] text-32rpx leading-44rpx">
费用说明
</view>
<view class="mb-20rpx flex items-center mt-30rpx">
<view class="flex items-center">
<wd-img width="32rpx" height="32rpx" :src="`${OSS}images/chayishi/count.png`"
class="mr-12rpx" />
<text class="text-28rpx text-[#303133] font-bold leading-40rpx">费用说明</text>
</view>
<text class="text-24rpx text-[#909399] leading-34rpx">计费标准</text>
<view class="font-bold text-28rpx text-[#303133] leading-48rpx">计费标准</view>
</view>
<view class="cost-item flex items-center justify-between">
<text class="text-26rpx text-[#606266] leading-40rpx">服务费</text>
@ -132,6 +130,9 @@
<script lang="ts" setup>
import { router } from '@/utils/tools'
import { getTeaSpecialistProfile } from '@/api/tes-specialist'
import TeaSpecialistLevel from '@/components/TeaSpecialistLevel.vue'
import { TeaSpecialistNumberLevelValue } from '@/utils/teaSpecialist'
const OSS = inject('OSS')
const navbarHeight = inject('navbarHeight')
@ -144,10 +145,50 @@
`${OSS}images/chayishi/photo3.png`,
])
const Profile = {
const profile = ref<{
name: string // 茶艺师名字
star: number // 评分
age_range: number // 显示90茶艺师
age: number // 年龄
sex: number // 性别 1男 2女
height: number // 身高
weight: number // 体重
image_arr: string[] // 照片数组
level: number // 茶艺师等级
hobby_introduce: string // 兴趣爱好介绍
price: number // 服务费
mileage_price: number // 车马费
}>({
name: '',
star: 0,
age_range: 0,
age: 0,
sex: 1,
height: 0,
weight: 0,
image_arr: [],
level: 0,
hobby_introduce: '',
price: 0,
mileage_price: 0,
})
onLoad(() => {
ProfileDisplay.handleInit()
})
const ProfileDisplay = {
/**
* 初始化茶艺师详情
*/
handleInit: async() => {
const res = await getTeaSpecialistProfile()
profile.value = res
},
// 返回
handleBack: () => {
console.log("🚀 ~ Profile.handleBack:", 213)
console.log("🚀 ~ ProfileDisplay.handleBack:", 213)
router.navigateBack()
},
@ -184,10 +225,10 @@ page {
z-index: 1;
}
// .content-wrapper {
// // position: relative;
// // z-index: 10;
// }
.content-wrapper {
position: relative;
z-index: 10;
}
// .right-slot {
// padding-right: v-bind(rightPadding);

View File

@ -21,15 +21,15 @@
<view class="content-wrapper" :style="{ paddingTop: `0px` }">
<!-- 勾选服务方式 -->
<view class="info-card mx-30rpx mt-30rpx rounded-24rpx bg-white p-30rpx">
<!-- <view class="info-card mx-30rpx mt-30rpx rounded-24rpx bg-white p-30rpx">
<view class="mb-24rpx flex items-center justify-between">
<text class="text-32rpx text-[#303133] font-bold leading-44rpx">勾选服务方式</text>
<text class="text-24rpx text-[#909399] leading-34rpx">可多选</text>
</view>
</view> -->
<!-- 服务选项 -->
<view class="service-options-row flex items-center gap-48rpx">
<!-- <view class="service-options-row flex items-center gap-48rpx"> -->
<!-- 上门服务 -->
<view class="service-option-item flex items-center"
<!-- <view class="service-option-item flex items-center"
@click="ServiceMethod.handleToggleService('door')">
<view
class="checkbox-wrapper mr-16rpx h-40rpx w-40rpx flex items-center justify-center rounded-4rpx"
@ -37,9 +37,9 @@
<wd-icon v-if="serviceMethods.door" name="check" size="24rpx" color="#fff" />
</view>
<text class="text-28rpx text-[#303133] leading-40rpx">上门服务</text>
</view>
</view> -->
<!-- 到店服务 -->
<view class="service-option-item flex items-center"
<!-- <view class="service-option-item flex items-center"
@click="ServiceMethod.handleToggleService('store')">
<view
class="checkbox-wrapper mr-16rpx h-40rpx w-40rpx flex items-center justify-center rounded-4rpx"
@ -49,7 +49,7 @@
<text class="text-28rpx text-[#303133] leading-40rpx">到店服务</text>
</view>
</view>
</view>
</view> -->
<!-- 是否免费出行 -->
<view class="info-card mx-30rpx mt-30rpx rounded-24rpx bg-white p-30rpx">
@ -70,7 +70,7 @@
<!-- 保存按钮 -->
<view class="fixed bottom-0 left-0 right-0 px-30rpx pb-40rpx pt-24rpx">
<view class="save-btn h-88rpx rounded-16rpx bg-[#4C9F44] text-center leading-88rpx"
<view class="save-btn h-88rpx rounded-8rpx bg-[#4C9F44] text-center leading-88rpx"
@click="ServiceMethod.handleSave">
<text class="text-32rpx text-[#fff] font-bold">保存</text>
</view>

View File

@ -19,11 +19,11 @@
<view class="text-36rpx text-[#121212] leading-50rpx text-center pt-50rpx pb-40rpx">选择工作日</view>
<view class="px-32rpx">
<view class="workday-grid grid grid-cols-3 gap-24rpx ">
<view v-for="(day, index) in ['周一', '周二', '周三', '周四', '周五', '周六', '周日']" :key="index"
<view v-for="item in workDaysList" :key="item.value"
class="w-216rpx h-64rpx text-center leading-64rpx rounded-8rpx text-28rpx"
:class="workdays.includes(day) ? 'bg-[#E7F5E7] text-[#4C9F44]' : 'bg-[#F5F7FA] text-[#909399]'"
@click="WorkTime.handleToggleWorkday(day)">
{{ day }}
:class="workdays.includes(item.label) ? 'bg-[#E7F5E7] text-[#4C9F44]' : 'bg-[#F5F7FA] text-[#909399]'"
@click="WorkTime.handleToggleWorkday(item.label, item.value)">
{{ item.label }}
</view>
</view>
@ -33,37 +33,12 @@
</view>
</view>
</view>
<!-- <view class="workday-picker-popup">
<view class="picker-header flex items-center justify-between px-30rpx pb-24rpx pt-30rpx">
<text class="text-36rpx text-[#303133] font-bold leading-50rpx">选择工作日</text>
<view class="close-btn h-60rpx w-60rpx flex items-center justify-center rounded-full bg-[#F5F7FA]"
@click="showWorkdayPicker = false">
<wd-icon name="close" size="32rpx" color="#909399" />
</view>
</view>
<view class="workday-grid grid grid-cols-3 gap-24rpx px-30rpx pb-30rpx">
<view v-for="(day, index) in ['周一', '周二', '周三', '周四', '周五', '周六', '周日']" :key="index"
class="workday-item h-88rpx flex items-center justify-center rounded-16rpx text-28rpx leading-40rpx"
:class="workdays.includes(day) ? 'bg-[#E7F5E7] text-[#4C9F44]' : 'bg-[#F5F7FA] text-[#909399]'"
@click="WorkTime.handleToggleWorkday(day)">
{{ day }}
</view>
</view>
<view class="px-30rpx pb-40rpx">
<view class="confirm-btn h-88rpx rounded-16rpx bg-[#4C9F44] text-center leading-88rpx"
@click="WorkTime.handleConfirmWorkdays(workdays)">
<text class="text-32rpx text-[#fff] font-bold">确定</text>
</view>
</view>
</view> -->
</wd-popup>
<!-- 时间选择弹窗 -->
<wd-popup v-model="showTimePicker" position="bottom" custom-style="border-radius: 32rpx 32rpx 0 0;">
<view class="relative pb-26rpx ">
<view class="absolute top-18rpx right-30rpx" @click="showWorkdayPicker = false">
<view class="absolute top-18rpx right-30rpx" @click="showTimePicker = false">
<wd-img width="60rpx" height='60rpx' :src="`${OSS}icon/icon_close.png`"></wd-img>
</view>
</view>
@ -84,8 +59,8 @@
</view>
<view class="time-picker-wrapper px-30rpx pb-30rpx">
<wd-datetime-picker-view type="time" v-model="time.start" label="开始时间" v-if="timePickerType == 'start'"/>
<wd-datetime-picker-view type="time" v-model="time.end" label="结束时间" v-if="timePickerType == 'end'"/>
<wd-datetime-picker-view type="time" v-model="workHours.start" label="开始时间" v-if="timePickerType == 'start'"/>
<wd-datetime-picker-view type="time" v-model="workHours.end" label="结束时间" v-if="timePickerType == 'end'"/>
</view>
<view class="flex items-center gap-24rpx px-30rpx pb-40rpx mt-50rpx">
@ -94,64 +69,11 @@
<text class="text-32rpx text-[#303133]">重置</text>
</view>
<view class="confirm-btn h-88rpx flex-1 rounded-16rpx bg-[#4C9F44] text-center leading-88rpx"
@click="WorkTime.handleConfirmTime(timePickerType === 'start' ? timePickerValue.start : timePickerValue.end)">
@click="showTimePicker = false">
<text class="text-32rpx text-[#fff]">确定</text>
</view>
</view>
</view>
<!-- <view class="time-picker-popup">
<view class="picker-header flex items-center justify-between px-30rpx pb-24rpx pt-30rpx">
<text class="text-36rpx text-[#303133] font-bold leading-50rpx">选择每日工作时间</text>
<view class="close-btn h-60rpx w-60rpx flex items-center justify-center rounded-full bg-[#F5F7FA]"
@click="showTimePicker = false">
<wd-icon name="close" size="32rpx" color="#909399" />
</view>
</view>
<view class="time-tabs flex items-center px-30rpx pb-24rpx">
<view class="time-tab flex-1 rounded-8rpx py-16rpx text-center text-28rpx leading-40rpx"
:class="timePickerType === 'start' ? 'bg-[#4C9F44] text-[#fff]' : 'bg-[#F5F7FA] text-[#909399]'"
@click="timePickerType = 'start'">
开始时间
</view>
<view class="time-tab ml-16rpx flex-1 rounded-8rpx py-16rpx text-center text-28rpx leading-40rpx"
:class="timePickerType === 'end' ? 'bg-[#4C9F44] text-[#fff]' : 'bg-[#F5F7FA] text-[#909399]'"
@click="timePickerType = 'end'">
结束时间
</view>
</view>
<view class="time-picker-wrapper px-30rpx pb-30rpx">
<picker-view class="time-picker-view"
:value="timePickerType === 'start' ? [timePickerValue.start.hour, timePickerValue.start.minute] : [timePickerValue.end.hour, timePickerValue.end.minute]"
@change="WorkTime.handleTimePickerChange">
<picker-view-column>
<view v-for="hour in 24" :key="hour - 1"
class="time-picker-item flex items-center justify-center text-32rpx leading-44rpx">
{{ String(hour - 1).padStart(2, '0') }}
</view>
</picker-view-column>
<picker-view-column>
<view v-for="minute in 60" :key="minute - 1"
class="time-picker-item flex items-center justify-center text-32rpx leading-44rpx">
{{ String(minute - 1).padStart(2, '0') }}
</view>
</picker-view-column>
</picker-view>
</view>
<view class="time-picker-actions flex items-center gap-24rpx px-30rpx pb-40rpx">
<view class="reset-btn h-88rpx flex-1 rounded-16rpx bg-[#F5F7FA] text-center leading-88rpx"
@click="WorkTime.handleResetTime">
<text class="text-32rpx text-[#303133] font-bold">重置</text>
</view>
<view class="confirm-btn h-88rpx flex-1 rounded-16rpx bg-[#4C9F44] text-center leading-88rpx"
@click="WorkTime.handleConfirmTime(timePickerType === 'start' ? timePickerValue.start : timePickerValue.end)">
<text class="text-32rpx text-[#fff] font-bold">确定</text>
</view>
</view>
</view> -->
</wd-popup>
<!-- 导航栏 -->
@ -160,7 +82,7 @@
<view class="content-wrapper" :style="{ paddingTop: `0px` }">
<!-- 每周工作日 -->
<view class="info-card mx-30rpx mt-30rpx rounded-24rpx bg-white p-30rpx"
@click="WorkTime.handleSelectWorkdays">
@click="showWorkdayPicker = true">
<view class="flex items-center justify-between">
<view class="flex-1">
<text class="text-32rpx text-[#303133] font-bold leading-44rpx">每周工作日</text>
@ -201,20 +123,29 @@
</template>
<script lang="ts" setup>
import { router } from '@/utils/tools'
import { getUserInfo } from '@/api/user'
import { useToast } from 'wot-design-uni'
import { setUserWorkTime } from '@/api/user'
const OSS = inject('OSS')
const navbarHeight = inject('navbarHeight')
const rightPadding = inject('capsuleOffset')
const toast = useToast()
// 工作日选择(周一到周六)
const workdays = ref(['周一', '周二', '周三', '周四', '周五', '周六'])
const workdays = ref([]) // 周一、周二...
const wokrdaysValue = ref([]) // 1,2...
// 工作日列表
const workDaysList = ref<Array<{label: string, value: number}>>([
{label: '周一', value: 1},
{label: '周二', value: 2},
{label: '周三', value: 3},
{label: '周四', value: 4},
{label: '周五', value: 5},
{label: '周六', value: 6},
{label: '周日', value: 7},
])
// 工作时间
const workHours = ref({
start: '08:00',
end: '20:00',
})
// 显示工作日选择弹窗
const showWorkdayPicker = ref(false)
@ -223,66 +154,87 @@ const showWorkdayPicker = ref(false)
const showTimePicker = ref(false)
const timePickerType = ref<'start' | 'end'>('start') // 当前选择的是开始时间还是结束时间
// 时间选择器的值
const timePickerValue = ref({
start: { hour: 8, minute: 0 },
end: { hour: 20, minute: 0 },
// 工作时间
const workHours = ref({
start: '',
end: '',
})
const time = ref({
start: '08:00',
end: '20:00'
const timePickerValue = ref({
start: { hour: 0, minute: 0 },
end: { hour: 0, minute: 0 },
})
// 用户信息
const userInfo = ref({
work_start: '',
work_end: '',
})
onLoad(() => {
WorkTime.handleGetUserInfo()
})
const WorkTime = {
// 返回
handleBack: () => {
router.navigateBack()
/**
* 获取个人信息
*/
handleGetUserInfo: async () => {
const res = await getUserInfo()
userInfo.value = res
workdays.value = res.work.split(',')
wokrdaysValue.value = res.work_day.split(',')
workHours.value.start = res.work_start
workHours.value.end = res.work_end
timePickerValue.value.start = {
hour: parseInt(res.work_start.split(':')[0]),
minute: parseInt(res.work_start.split(':')[1]),
}
timePickerValue.value.end = {
hour: parseInt(res.work_end.split(':')[0]),
minute: parseInt(res.work_end.split(':')[1]),
}
},
// 打开工作日选择
handleSelectWorkdays: () => {
showWorkdayPicker.value = true
},
// 打开时间选择
/**
* 打开时间选择
* @param type
*/
handleSelectTime: (type: 'start' | 'end') => {
timePickerType.value = type
showTimePicker.value = true
},
// 确认工作日选择
/**
* 确认工作日选择
* @param selectedDays
*/
handleConfirmWorkdays: (selectedDays: string[]) => {
workdays.value = selectedDays
showWorkdayPicker.value = false
},
// 确认时间选择
handleConfirmTime: (time: { hour: number, minute: number }) => {
const timeStr = `${String(time.hour).padStart(2, '0')}:${String(time.minute).padStart(2, '0')}`
if (timePickerType.value === 'start') {
workHours.value.start = timeStr
timePickerValue.value.start = time
}
else {
workHours.value.end = timeStr
timePickerValue.value.end = time
}
showTimePicker.value = false
},
// 切换工作日
handleToggleWorkday: (day: string) => {
/**
* 切换工作日
* @param day 周一、周二...
* @param value 1、2...
*/
handleToggleWorkday: (day: string, value: number) => {
const index = workdays.value.indexOf(day)
if (index > -1) {
workdays.value.splice(index, 1)
wokrdaysValue.value.splice(index, 1)
}
else {
workdays.value.push(day)
wokrdaysValue.value.push(value)
}
},
// 时间选择器变化
/**
* 时间选择器变化
*/
handleTimePickerChange: (e: any) => {
const [hour, minute] = e.detail.value
if (timePickerType.value === 'start') {
@ -293,28 +245,50 @@ const WorkTime = {
}
},
// 重置时间
/**
* 重置时间
*/
handleResetTime: () => {
time.value = {
start: '08:00',
end: '20:00'
workHours.value = {
start: userInfo.value.work_start,
end: userInfo.value.work_end
}
},
// 保存
handleSave: () => {
// TODO: 实现保存逻辑
console.log('保存工作时间:', {
workdays: workdays.value,
workHours: workHours.value,
/**
* 保存工作时间
*/
handleSave: async () => {
if (wokrdaysValue.value.length === 0) {
toast.show('请选择工作日')
return false
}
if (workHours.value.start >= workHours.value.end) {
toast.show('结束时间必须大于开始时间')
return false
}
toast.loading({
msg: '保存中...'
})
uni.showToast({
title: '保存成功',
icon: 'success',
})
setTimeout(() => {
router.navigateBack()
}, 1500)
try {
await setUserWorkTime({
work_day: wokrdaysValue.value.sort().join(','),
work_start: workHours.value.start,
work_end: workHours.value.end,
})
WorkTime.handleGetUserInfo()
toast.close()
toast.show({
msg: '修改成功',
duration: 1500
})
} catch (error) {
toast.close()
return false
}
},
}
</script>

View File

@ -7,7 +7,6 @@ export enum TeaSpecialistLevel {
Enthusiast = '茶艺爱好者'
}
// 订单来源对应名称
export const TeaSpecialistLevelValue = {
['金牌茶艺师']: 'gold',
['高级茶艺师']: 'senior',
@ -16,6 +15,14 @@ export const TeaSpecialistLevelValue = {
['茶艺爱好者']: 'enthusiast',
}
export const TeaSpecialistNumberLevelValue = {
[1]: 'enthusiast',
[2]: 'junior',
[3]: 'intermediate',
[4]: 'senior',
[5]: 'gold',
}
// 茶艺师对象结构
export const TeaSpecialistLevels = [
{ id: 1, value: 'gold', label: TeaSpecialistLevel.Gold},