|
|
<template>
|
|
|
<view class="container">
|
|
|
<HeaderCustom title='预约服务'></HeaderCustom>
|
|
|
<div class="titleBox">
|
|
|
<div class="title">预约服务</div>
|
|
|
<div class="line"></div>
|
|
|
<div class="desc">
|
|
|
请填写以下相关信息,我们的销售工程师会尽快与您联系,并提供报价单
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="formBox">
|
|
|
<uv-form labelPosition="left" :model="formField" labelWidth="100" :rules="rules" ref="form">
|
|
|
<uv-form-item required label="姓名" prop="name">
|
|
|
<uv-input v-model="formField.name" border="none" placeholder="请输入姓名">
|
|
|
</uv-input>
|
|
|
</uv-form-item>
|
|
|
<uv-form-item required label="手机号码" prop="phone">
|
|
|
<uv-input v-model="formField.phone" border="none" placeholder="请输入手机号码">
|
|
|
</uv-input>
|
|
|
</uv-form-item>
|
|
|
<uv-form-item required label="邮箱" prop="email">
|
|
|
<uv-input v-model="formField.email" border="none" placeholder="请输入邮箱">
|
|
|
</uv-input>
|
|
|
</uv-form-item>
|
|
|
<uv-form-item required label="地址" prop="adress" @click="openAddressPicker">
|
|
|
<uv-input v-model="formField.adress" readonly border="none" placeholder="请选择地址">
|
|
|
</uv-input>
|
|
|
<uv-picker ref="addressPicker" :columns="addressList" keyName="name" @change="addressChange"
|
|
|
@confirm="confirm">
|
|
|
</uv-picker>
|
|
|
</uv-form-item>
|
|
|
<uv-form-item labelPosition='top' required label="咨询业务类型" prop="appointment_type">
|
|
|
<!-- <uv-input v-model="formField.type" readonly border="none" placeholder="请选择咨询业务类型">
|
|
|
</uv-input> -->
|
|
|
<div class="type_select_box">
|
|
|
<div class="item" :class="{selected:formField.appointment_type.includes('别墅梯采购')}"
|
|
|
@click="pickType('别墅梯采购')">
|
|
|
<img class="img" src="/static/imgs/bstcg.png" alt="">
|
|
|
别墅梯采购
|
|
|
</div>
|
|
|
<div class="item" :class="{selected:formField.appointment_type.includes('旧梯换新')}"
|
|
|
@click="pickType('旧梯换新')">
|
|
|
<img class="img" src="/static/imgs/jthx.png" alt="">旧梯换新
|
|
|
</div>
|
|
|
<div class="item" :class="{selected:formField.appointment_type.includes('新梯采购')}"
|
|
|
@click="pickType('新梯采购')">
|
|
|
<img class="img" src="/static/imgs/xtcg.png" alt="">新梯采购
|
|
|
</div>
|
|
|
<div class="item" :class="{selected:formField.appointment_type.includes('旧楼加装')}"
|
|
|
@click="pickType('旧楼加装')">
|
|
|
<img class="img" src="/static/imgs/jljz.png" alt="">旧楼加装
|
|
|
</div>
|
|
|
</div>
|
|
|
</uv-form-item>
|
|
|
<uv-form-item label="需求补充" prop="remark">
|
|
|
<uv-input v-model="formField.remark" border="none" placeholder="请输入需求补充">
|
|
|
</uv-input>
|
|
|
</uv-form-item>
|
|
|
<uv-button type="primary" text="提交" customStyle="margin-top: 10px" @click="submit"></uv-button>
|
|
|
</uv-form>
|
|
|
</div>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
import {
|
|
|
computed,
|
|
|
onMounted,
|
|
|
ref
|
|
|
} from "vue";
|
|
|
import {
|
|
|
onShow
|
|
|
} from "@dcloudio/uni-app";
|
|
|
import {
|
|
|
useAuthStore,
|
|
|
useUserStore
|
|
|
} from "@/store";
|
|
|
import {
|
|
|
regions
|
|
|
} from '/static/json/regions.js'
|
|
|
import HeaderCustom from '/components/HeaderCustom/HeaderCustom.vue'
|
|
|
import RPC from "@/utils/request";
|
|
|
|
|
|
const authStore = useAuthStore()
|
|
|
const userStore = useUserStore()
|
|
|
|
|
|
onShow(() => {
|
|
|
if (!authStore?.isLoggedIn) {
|
|
|
uni.switchTab({
|
|
|
url: `/pages/index/index`,
|
|
|
});
|
|
|
uni.showToast({
|
|
|
title: "请先登录",
|
|
|
icon: "none",
|
|
|
})
|
|
|
}
|
|
|
})
|
|
|
|
|
|
const form = ref(null)
|
|
|
const formField = ref({
|
|
|
name: '',
|
|
|
phone: '',
|
|
|
email: '',
|
|
|
adress: '',
|
|
|
appointment_type: [],
|
|
|
remark: '',
|
|
|
})
|
|
|
const pickType = type => {
|
|
|
const index = formField.value.appointment_type.findIndex(item => item === type)
|
|
|
if (index >= 0) {
|
|
|
formField.value.appointment_type.splice(index, 1)
|
|
|
} else {
|
|
|
formField.value.appointment_type.push(type)
|
|
|
}
|
|
|
}
|
|
|
const rules = {
|
|
|
'name': {
|
|
|
type: 'string',
|
|
|
required: true,
|
|
|
message: '请填写姓名',
|
|
|
trigger: ['blur', 'change']
|
|
|
},
|
|
|
'phone': {
|
|
|
type: 'string',
|
|
|
required: true,
|
|
|
message: '请填写手机号码',
|
|
|
trigger: ['blur', 'change']
|
|
|
},
|
|
|
'email': {
|
|
|
type: 'string',
|
|
|
required: true,
|
|
|
message: '请填写邮箱',
|
|
|
trigger: ['blur', 'change']
|
|
|
},
|
|
|
'adress': {
|
|
|
type: 'string',
|
|
|
required: true,
|
|
|
message: '请选择地址',
|
|
|
trigger: ['blur', 'change']
|
|
|
},
|
|
|
'appointment_type': {
|
|
|
type: 'array',
|
|
|
required: true,
|
|
|
message: '请选择咨询业务类型',
|
|
|
trigger: ['blur', 'change']
|
|
|
},
|
|
|
}
|
|
|
const submit = () => {
|
|
|
// 如果有错误,会在catch中返回报错信息数组,校验通过则在then中返回true
|
|
|
form.value.validate().then(res => {
|
|
|
const params = {
|
|
|
...formField.value,
|
|
|
appointment_type: formField.value.appointment_type.join(',')
|
|
|
}
|
|
|
RPC.post('/appointment/create',params).then(() => {
|
|
|
uni.showToast({
|
|
|
icon: 'success',
|
|
|
title: '预约成功'
|
|
|
})
|
|
|
formField.value = {
|
|
|
name: '',
|
|
|
phone: '',
|
|
|
email: '',
|
|
|
adress: '',
|
|
|
appointment_type: [],
|
|
|
remark: '',
|
|
|
}
|
|
|
})
|
|
|
}).catch(errors => {
|
|
|
|
|
|
})
|
|
|
}
|
|
|
|
|
|
const provinces = ref([])
|
|
|
const citys = ref([])
|
|
|
const areas = ref([])
|
|
|
|
|
|
const addressList = computed(() => [provinces.value, citys.value, areas.value])
|
|
|
|
|
|
const addressPicker = ref(null)
|
|
|
|
|
|
const pickerValue = ref(['0', '0', '0'])
|
|
|
const defaultValue = ref(['3442', '1', '2'])
|
|
|
|
|
|
|
|
|
const addressChange = e => {
|
|
|
const {
|
|
|
columnIndex,
|
|
|
index,
|
|
|
indexs
|
|
|
} = e
|
|
|
// 改变了省
|
|
|
if (columnIndex === 0) {
|
|
|
citys.value = provinces.value[index]?.children || []
|
|
|
areas.value = citys.value[0]?.children || []
|
|
|
addressPicker.value.setIndexs([index, 0, 0], true)
|
|
|
} else if (columnIndex === 1) {
|
|
|
areas.value = citys.value[index]?.children || []
|
|
|
addressPicker.value.setIndexs(indexs, true)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const confirm = e => {
|
|
|
// console.log('确认选择的地区:', e);
|
|
|
// uni.showToast({
|
|
|
// icon: 'none',
|
|
|
// title: `${e.value[0].name}/${e.value[1].name}/${e.value[2].name}`
|
|
|
// })
|
|
|
formField.value.adress = `${e.value[0].name}/${e.value[1].name}/${e.value[2].name}`
|
|
|
}
|
|
|
|
|
|
const handlePickValueDefault = () => {
|
|
|
pickerValue.value[0] = provinces.value.findIndex(item => Number(item.id) == defaultValue.value[0]);
|
|
|
// 设置市
|
|
|
citys.value = provinces.value[pickerValue.value[0]]?.children || [];
|
|
|
pickerValue.value[1] = citys.value.findIndex(item => Number(item.id) == defaultValue.value[1]);
|
|
|
// 设置区
|
|
|
areas.value = citys.value[pickerValue.value[1]]?.children || [];
|
|
|
pickerValue.value[2] = areas.value.findIndex(item => Number(item.id) == defaultValue.value[2]);
|
|
|
// 重置下位置
|
|
|
addressPicker.value.setIndexs([pickerValue.value[0], pickerValue.value[1], pickerValue.value[2]], true);
|
|
|
}
|
|
|
|
|
|
const openAddressPicker = () => {
|
|
|
addressPicker.value.open()
|
|
|
handlePickValueDefault()
|
|
|
}
|
|
|
|
|
|
const getData = () => {
|
|
|
provinces.value = regions.sort((left, right) => (Number(left.code) > Number(right.code) ?
|
|
|
1 : -1));
|
|
|
handlePickValueDefault()
|
|
|
}
|
|
|
onMounted(() => {
|
|
|
getData()
|
|
|
})
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
.container {
|
|
|
font-size: 14px;
|
|
|
min-height: 100vh;
|
|
|
background-color: #f8f8f8;
|
|
|
}
|
|
|
|
|
|
.titleBox {
|
|
|
background-color: #fff;
|
|
|
padding: 20px 4vw;
|
|
|
|
|
|
.title {
|
|
|
font-size: 16px;
|
|
|
font-weight: 700;
|
|
|
}
|
|
|
|
|
|
.line {
|
|
|
width: 5vw;
|
|
|
height: 2px;
|
|
|
background-color: #3F70FF;
|
|
|
margin-top: 4px;
|
|
|
margin-bottom: 8px;
|
|
|
}
|
|
|
|
|
|
.desc {
|
|
|
font-size: 12px;
|
|
|
font-weight: 500;
|
|
|
line-height: 18px;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.formBox {
|
|
|
padding: 10px;
|
|
|
|
|
|
:deep(.uv-form) {
|
|
|
background-color: #fff;
|
|
|
padding: 10px;
|
|
|
border-radius: 10px;
|
|
|
|
|
|
.uv-form-item {
|
|
|
background-color: #F4F4F4;
|
|
|
margin-bottom: 10px;
|
|
|
border-radius: 10px;
|
|
|
padding-left: 20px;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.type_select_box {
|
|
|
display: flex;
|
|
|
flex-wrap: wrap;
|
|
|
gap: 15px;
|
|
|
padding-right: 20px;
|
|
|
margin-top: 10px;
|
|
|
|
|
|
.item {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
justify-content: center;
|
|
|
align-items: center;
|
|
|
background-color: #fff;
|
|
|
font-size: 12px;
|
|
|
width: 90px;
|
|
|
height: 70px;
|
|
|
border-radius: 6px;
|
|
|
|
|
|
.img {
|
|
|
width: 20px;
|
|
|
height: 20px;
|
|
|
margin-bottom: 6px;
|
|
|
}
|
|
|
|
|
|
&.selected {
|
|
|
border: 1px solid #3F70FF;
|
|
|
background-color: rgba(63, 112, 255, 0.1);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
</style> |