feat:"完成页面接口的对接"

This commit is contained in:
2026-01-29 17:58:19 +08:00
parent 2774a539bf
commit 2b69da3c15
98 changed files with 9504 additions and 592 deletions

View File

@@ -55,25 +55,47 @@
/>
</view>
<!-- 沙发类型 -->
<!-- 服务类型 -->
<view class="form-item">
<text class="form-label">沙发类型</text>
<text class="form-label">
<text class="required">*</text>
服务类型
</text>
<view class="type-grid">
<view
class="type-item"
:class="{ 'type-active': formData.sofaType == item.id }"
v-for="item in sofaTypes"
:class="{ 'type-active': formData.serviceId == item.id }"
v-for="item in serviceList"
:key="item.id"
@click="selectSofaType(item.id)"
@click="selectService(item.id)"
>
<text
class="type-text"
:class="{ 'type-text-active': formData.sofaType == item.id }"
:class="{ 'type-text-active': formData.serviceId == item.id }"
>{{ item.name }}</text>
</view>
</view>
</view>
<!-- 预约时间 -->
<view class="form-item">
<text class="form-label">
<text class="required">*</text>
预约时间
</text>
<picker
mode="date"
:value="formData.appointmentDate"
:start="minDate"
@change="onDateChange"
>
<view class="picker-value">
<text class="picker-text" v-if="formData.appointmentDate">{{ formData.appointmentDate }}</text>
<text class="picker-placeholder" v-else>请选择预约日期</text>
</view>
</picker>
</view>
<!-- 问题描述 -->
<view class="form-item">
<text class="form-label">问题描述</text>
@@ -106,7 +128,7 @@
<text class="add-text">添加图片</text>
</view>
</view>
<text class="upload-tip">最多可上传9张图片</text>
<text class="upload-tip">提示:当前仅支持预览,图片暂不会上传到服务器</text>
</view>
</view>
@@ -124,22 +146,25 @@
</template>
<script setup lang="uts">
import { submitBooking } from '@/api/index.uts'
import { SOFA_CATEGORIES } from '@/utils/config.uts'
import { submitBooking, getActiveServices } from '@/api/index.uts'
// 表单类型
type FormData = {
userName : string
phone : string
address : string
sofaType : string
serviceId : number
appointmentDate : string
problem : string
}
// 沙发类型
type SofaType = {
id : string
// 服务类型
type ServiceItem = {
id : number
name : string
type : string
description : string
price : number
}
// 表单数据
@@ -147,32 +172,82 @@
userName: '',
phone: '',
address: '',
sofaType: '',
serviceId: 0,
appointmentDate: '',
problem: ''
})
// 图片列表
const imageList = ref<string[]>([])
// 沙发类型列表
const sofaTypes = ref<SofaType[]>([])
// 服务列表
const serviceList = ref<ServiceItem[]>([])
// 提交中
const submitting = ref(false)
// 初始化沙发类型
const initSofaTypes = () => {
sofaTypes.value = SOFA_CATEGORIES.filter((item) : boolean => item.id != 'all').map((item) : SofaType => {
return {
id: item.id,
name: item.name
} as SofaType
})
// 最小日期(今天)
const minDate = ref('')
// 加载服务列表
const loadServices = async () => {
try {
const res = await getActiveServices()
console.log('服务列表响应:', res)
if (res.code == 0 && res.data != null) {
const data = res.data as UTSJSONObject
// 兼容两种格式:直接数组 或 {list: [], total: n}
let list : UTSJSONObject[] = []
if (Array.isArray(data)) {
list = data as UTSJSONObject[]
} else {
list = data['list'] as UTSJSONObject[] || []
}
console.log('解析的服务列表:', list)
serviceList.value = list.map((item) : ServiceItem => {
const basePrice = item['basePrice'] as string || '0'
return {
id: item['id'] as number,
name: item['name'] as string,
type: item['type'] as string,
description: item['description'] as string,
price: parseFloat(basePrice)
} as ServiceItem
})
console.log('最终服务列表:', serviceList.value)
} else {
console.error('服务列表响应异常code:', res.code, 'data:', res.data)
}
} catch (e) {
console.error('加载服务列表失败', e)
}
}
// 选择沙发类型
const selectSofaType = (id : string) => {
formData.value.sofaType = id
// 初始化最小日期和默认日期(明天)
const initMinDate = () => {
const now = new Date()
const year = now.getFullYear()
const month = String(now.getMonth() + 1).padStart(2, '0')
const day = String(now.getDate()).padStart(2, '0')
minDate.value = `${year}-${month}-${day}`
// 设置默认预约时间为明天
const tomorrow = new Date()
tomorrow.setDate(tomorrow.getDate() + 1)
const tYear = tomorrow.getFullYear()
const tMonth = String(tomorrow.getMonth() + 1).padStart(2, '0')
const tDay = String(tomorrow.getDate()).padStart(2, '0')
formData.value.appointmentDate = `${tYear}-${tMonth}-${tDay}`
}
// 选择服务
const selectService = (id : number) => {
formData.value.serviceId = id
}
// 日期选择
const onDateChange = (e : any) => {
formData.value.appointmentDate = e.detail.value
}
// 选择图片
@@ -228,6 +303,22 @@
return false
}
if (formData.value.serviceId == 0) {
uni.showToast({
title: '请选择服务类型',
icon: 'none'
})
return false
}
if (formData.value.appointmentDate == '') {
uni.showToast({
title: '请选择预约时间',
icon: 'none'
})
return false
}
return true
}
@@ -239,21 +330,35 @@
submitting.value = true
try {
// 注意当前暂不支持图片上传如需上传图片请先将图片上传到图床获取URL
// 过滤掉微信临时路径后端需要永久URL
const validImages = imageList.value.filter((url) => {
return url.startsWith('http://') || url.startsWith('https://')
})
if (imageList.value.length > 0 && validImages.length === 0) {
console.log('警告:图片为微信临时路径,暂不支持上传')
}
// 构造后端需要的数据格式
const data = {
userName: formData.value.userName,
phone: formData.value.phone,
serviceId: formData.value.serviceId,
contactName: formData.value.userName,
contactPhone: formData.value.phone,
address: formData.value.address,
sofaType: formData.value.sofaType,
problem: formData.value.problem,
images: imageList.value
appointmentTime: formData.value.appointmentDate + 'T10:00:00.000Z', // 默认上午10点
requirements: formData.value.problem,
images: validImages // 只提交有效的URL
} as UTSJSONObject
console.log('提交预约数据:', data)
const res = await submitBooking(data)
const result = res.data as UTSJSONObject
console.log('预约提交结果:', res)
// request.uts 会自动处理失败情况并显示 toast这里只处理成功
uni.showModal({
title: '预约成功',
content: result['message'] as string,
content: '我们会尽快与您联系,请保持电话畅通',
showCancel: false,
success: () => {
// 返回上一页或首页
@@ -267,18 +372,16 @@
}
})
} catch (e) {
console.error('提交预约失败', e)
uni.showToast({
title: '提交失败,请重试',
icon: 'none'
})
console.error('提交预约异常:', e)
// request.uts 已经显示了错误 toast这里只需要记录日志
}
submitting.value = false
}
onLoad(() => {
initSofaTypes()
initMinDate()
loadServices()
})
</script>
@@ -347,6 +450,25 @@
color: #C0C4CC;
}
/* 日期选择器 */
.picker-value {
background-color: #f5f5f5;
border-radius: 12rpx;
padding: 24rpx;
height: 40px;
justify-content: center;
}
.picker-text {
font-size: 28rpx;
color: #303133;
}
.picker-placeholder {
font-size: 28rpx;
color: #C0C4CC;
}
/* 沙发类型选择 */
.type-grid {
flex-direction: row;