Commit b70012fa authored by wxf's avatar wxf

feat: 飞鹤预约分包代码

parent bf26bf60
import requestModule from './reservation-request.js'
const {
api
} = requestModule
/**
* 获取手机号
* @returns
* @param {string} memberId 用户memberId
* @param {string} code 微信code
*/
export const decodePhone = (data) => api.post('/decode_phone.php', data)
/**
* 获取日期
* @returns
* @param {string} memberId 用户memberId
*/
export const getDateConfig = (data) => api.post('/get_day.php', data)
/**
* 获取时间
* @returns
* @param {string} memberId 用户memberId
* @param {string} day 日期
*/
export const getTimeConfig = (data) => api.post('/get_time.php', data)
/**
* 获取工厂
* @returns
* @param {string} memberId 用户memberId
*/
export const getGround = (data) => api.post('/get_ground.php', data)
/**
* 预约列表
* @returns
* @param {string} memberId 用户memberId
*/
export const reservationList = (data) => api.post('/reservation_list.php', data)
/**
* 预约详情
* @returns
* @param {string} id 预约id
*/
export const reservationDetail = (data) =>
api.post('/reservation_detail.php', data)
/**
* 取消预约
* @returns
* @param {string} id 预约id
*/
export const reservationCancel = (data) =>
api.post('/reservation_cancel.php', data)
/**
* 发起预约
* @returns
* @param {string} data.memberId 用户memberId
* @param {string} data.reservation_date 预约日期
* @param {string} data.reservation_time 预约时间
* @param {string} data.realname 预约人姓名
* @param {string} data.telephone 预约人手机号
* @param {string} data.visitor_number 访客人数
* @param {string} data.type 访客类型
*/
export const reservation = (data) => api.post('/reservation.php', data)
\ No newline at end of file
import {
HTTP_STATUS
} from '../config.js'
// request.js
// 通常可以吧 baseUrl 单独放在一个 js 文件了
// const baseUrl = "http://172.16.224.178:7777/pmall";
// const baseUrl = "https://momclub-uat.feihe.com/pmall";//测试环境
const baseUrl = 'https://essence.jzvcode.com/feihe' //生产环境
const request = (options = {}) => {
// 对options.data 进行一些处理
// 如果没有传入 memberId ,则从本地存储中获取
console.log(options.data, 'options.data')
if (!options.data?.memberId) {
options.data.memberId = uni.getStorageSync('memberId') || ''
}
return new Promise((resolve, reject) => {
uni
.request({
url: baseUrl + options.url || '',
method: options.type || 'GET',
data: options.data || {},
header: {
...options.header,
},
})
.then((data) => {
console.log('request data ===>', data)
if (data.statusCode !== HTTP_STATUS.SUCCESS) {
uni.showToast({
title: data.errMsg,
icon: 'none',
})
reject(data)
} else {
resolve(data.data)
}
// else if (!data.data?.ok) {
// uni.showToast({
// title: data.data?.message,
// icon: 'none',
// })
// reject(data.data)
// }
})
.catch((error) => {
reject(error)
})
})
}
const get = (url, data, options = {}) => {
options.type = 'GET'
options.data = data
options.url = url
return request(options)
}
const post = (url, data, options = {}) => {
options.type = 'POST'
options.data = data
options.url = url
return request(options)
}
export default {
request,
api: {
get,
post,
},
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon-下拉</title>
<g id="UI-绿" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<g id="1-首页-1" transform="translate(-185, -827)" stroke="#EEEEEE" stroke-width="2">
<g id="icon-下拉" transform="translate(193, 839)">
<polyline id="路径备份" transform="translate(8, 4) scale(1, -1) translate(-8, -4)" points="0 8 8 0 16 8"></polyline>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="19px" height="19px" viewBox="0 0 19 19" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon-右</title>
<g id="UI-绿" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<g id="2-预约信息" transform="translate(-118, -180)" stroke="#DAB97B" stroke-width="1.58333333">
<g id="icon-右" transform="translate(127.5, 189.5) rotate(-90) translate(-127.5, -189.5)translate(122.75, 187.125)">
<polyline id="路径备份" transform="translate(4.75, 2.375) scale(1, -1) translate(-4.75, -2.375)" points="0 4.75 4.75 0 9.5 4.75"></polyline>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="19px" height="19px" viewBox="0 0 19 19" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>icon-右</title>
<g id="UI-绿" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<g id="2-预约信息" transform="translate(-118, -180)" stroke="#ffffff" stroke-width="1.58333333">
<g id="icon-右" transform="translate(127.5, 189.5) rotate(-90) translate(-127.5, -189.5)translate(122.75, 187.125)">
<polyline id="路径备份" transform="translate(4.75, 2.375) scale(1, -1) translate(-4.75, -2.375)" points="0 4.75 4.75 0 9.5 4.75"></polyline>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="172px" height="20px" viewBox="0 0 172 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Logo@2x</title>
<g id="UI-绿" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="1-首页-4" transform="translate(-115, -120)">
<image id="Logo@2x" x="115" y="120" width="171.034483" height="20" xlink:href="data:image/png;base64,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"></image>
</g>
</g>
</svg>
\ No newline at end of file
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
"navigationStyle": "custom"
}
},
{
"path": "pages/person/person",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom"
}
},
{
"path": "pages/webview/webview",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom"
}
},
{
"path": "pages/search/search",
"style": {
"navigationStyle": "custom",
"usingComponents": {
"van-tab": "../../wxcomponents/vant/tab/index",
"van-tabs": "../../wxcomponents/vant/tabs/index"
}
}
},
{
"path" : "pages/product/product",
"style" :
{
"navigationBarTitleText": "",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black"
}
},
{
"path": "pages/library/ContentLibrary",
"style": {
"navigationStyle": "custom"
}
},
{
"path" : "pages/goodsDetail/goodsDetail",
"style" :
{
"navigationBarTitleText" : ""
}
},
{
"path" : "pages/rightsDetail/rightsDetail",
"style" :
{
"navigationBarTitleText" : ""
}
},
{
"path" : "pages/naming/naming",
"style" :
{
"navigationBarTitleText" : "宝宝取名",
"enablePullDownRefresh" : false,
"navigationStyle": "custom"
}
},
{
"path" : "pages/naming/namingResult",
"style" :
{
"navigationBarTitleText" : "AI-宝宝取名",
"enablePullDownRefresh" : false,
"navigationStyle": "custom"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8",
"navigationStyle": "default"
},
"uniIdRouter": {}
{
"pages": [{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
"navigationStyle": "custom"
}
},
{
"path": "pages/person/person",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom"
}
},
{
"path": "pages/webview/webview",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom"
}
},
{
"path": "pages/search/search",
"style": {
"navigationStyle": "custom",
"usingComponents": {
"van-tab": "../../wxcomponents/vant/tab/index",
"van-tabs": "../../wxcomponents/vant/tabs/index"
}
}
},
{
"path": "pages/product/product",
"style": {
"navigationBarTitleText": "",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black"
}
},
{
"path": "pages/library/ContentLibrary",
"style": {
"navigationStyle": "custom"
}
},
{
"path": "pages/goodsDetail/goodsDetail",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/rightsDetail/rightsDetail",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/naming/naming",
"style": {
"navigationBarTitleText": "宝宝取名",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
},
{
"path": "pages/naming/namingResult",
"style": {
"navigationBarTitleText": "AI-宝宝取名",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
}
],
"subPackages": [{
"root": "reservation",
"pages": [{
"path": "home/index",
"style": {
"navigationBarTitleText": "首页"
}
},
{
"path": "subscribe/index",
"style": {
"navigationBarTitleText": "预约"
}
},
{
"path": "record/index",
"style": {
"navigationBarTitleText": "预约记录"
}
},
{
"path": "record/detail",
"style": {
"navigationBarTitleText": "预约详情"
}
},
{
"path": "status/index",
"style": {
"navigationBarTitleText": "预约状态"
}
}
]
}],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8",
"navigationStyle": "default"
},
"uniIdRouter": {}
}
\ No newline at end of file
<template>
<view class="custom-picker" v-if="show">
<!-- 遮罩层 -->
<view class="mask" @click="close"></view>
<!-- 内容 -->
<view class="custom-picker-content">
<view class="custom-picker-header">
<view>{{ title }}</view>
<view class="close"> </view>
</view>
<picker-view
:indicator-style="indicatorStyle"
:indicator-class="indicatorClass"
:value="value"
:mask-style="maskStyle"
:immediate-change="true"
@change="bindChange"
class="picker-view"
>
<picker-view-column>
<view
class="item"
v-for="(item, index) in range"
:class="{ active: activeIndex == index }"
:key="index"
>{{ item.name }}</view
>
</picker-view-column>
</picker-view>
<view class="custom-picker-footer">
<fh-button>确认选择</fh-button>
</view>
</view>
</view>
</template>
<script>
import fhButton from './fh-button.vue'
export default {
name: '',
components: {
fhButton,
},
props: {
// 是否显示 接收v-model
show: {
type: Boolean,
default: false,
},
// 标题
title: {
type: String,
default: '请选择',
},
// 范围
range: {
type: Array,
default: () => [],
},
// 范围的key
rangeKey: {
type: String,
default: 'id',
},
},
data() {
return {
indicatorClass: 'indicatorClass',
indicatorStyle: `height: 50px;`,
activeIndex: 0,
maskStyle: `background: transparent !important;`,
value: [0],
}
},
mounted() {
this.show = this.show
},
methods: {
bindChange(e) {
console.log(e)
this.value = e.detail.value
this.activeIndex = e.detail.value[0]
},
close() {
this.$emit('close')
},
},
}
</script>
<style lang="scss" scoped>
::v-deep {
.indicatorClass:before,
.indicatorClass:after {
color: transparent !important;
border-color: transparent !important;
}
}
.custom-picker {
width: 100%;
height: 100vh;
position: relative;
overflow: hidden;
.mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.3);
z-index: 1000;
}
&-content {
width: 100%;
padding: 0 52rpx;
box-sizing: border-box;
height: 850rpx;
overflow: hidden;
background: #ffffff;
box-shadow: 0rpx 19rpx 37rpx 0rpx rgba(0, 64, 152, 0.1);
border-radius: 34rpx 34rpx 0rpx 0rpx;
position: absolute;
bottom: 0;
left: 0;
z-index: 1001;
display: flex;
flex-direction: column;
}
&-header {
width: 100%;
padding-top: 42rpx;
text-align: center;
position: relative;
padding-bottom: 20rpx;
.close {
position: absolute;
right: 0;
top: 0;
width: 100rpx;
}
}
&-footer {
width: 100%;
padding: 20rpx 0rpx 52rpx;
box-sizing: border-box;
.confirm {
width: 100%;
height: 97rpx;
background: #dab97b;
color: #fff;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
font-size: 36rpx;
border-radius: 50rpx;
}
}
.picker-view {
overflow: hidden;
flex: 1;
.item {
height: 50px !important;
text-align: center;
font-size: 30rpx;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.15s linear;
}
.active {
color: #d3a358;
font-weight: bold;
font-size: 40rpx;
}
}
}
</style>
<template>
<view class="fh-button" :class="type">
<slot></slot>
</view>
</template>
<script setup>
const props = defineProps({
type: {
type: String,
default: 'primary',
},
})
</script>
<style lang="less" scoped>
.fh-button {
width: 100%;
height: 97rpx;
background-color: #fff;
border-radius: 50rpx;
font-size: 34rpx;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
border: 2rpx solid transparent;
}
.primary {
background-color: #dab97b;
border: 2rpx solid #dab97b;
color: #fff;
}
.plain {
background-color: #fff;
color: #dab97b;
border: 2rpx solid #dab97b;
}
</style>
export const baseUrl = 'https://essence.jzvcode.com/feihe'
// 声明字体
@font-face {
font-family: 'fz';
src: url('https://essence.jzvcode.com/feihe/images/fz.ttf') format('truetype');
}
@font-face {
font-family: 'fz-bold';
src: url('https://essence.jzvcode.com/feihe/images/fz-bold.ttf')
format('truetype');
}
.blur-bg {
background: linear-gradient(
180deg,
rgba(255, 255, 255, 0.1) 0%,
rgba(255, 255, 255, 0.3) 100%
);
box-shadow: 0rpx 19rpx 37rpx 0rpx rgba(0, 0, 0, 0.3);
border-radius: 26rpx;
border: 2rpx solid rgba(255, 255, 255, 0.2);
backdrop-filter: blur(15px);
}
.fz {
font-family: 'fz';
}
.fz-bold {
font-family: 'fz-bold';
}
.home {
width: 100%;
height: 100vh;
.scroll {
width: 100%;
height: 100%;
}
.scroll-item {
width: 100%;
flex-shrink: 0;
height: 100vh;
scroll-snap-align: start;
scroll-snap-stop: always;
}
}
.home-page {
width: 100%;
height: 100%;
background-size: 100% 100%;
background-position: top;
overflow: hidden;
.logo {
margin: 37rpx auto;
text-align: center;
image {
width: 320rpx;
height: 37rpx;
}
}
}
.footer {
position: fixed;
bottom: 130rpx;
width: 100%;
padding: 30rpx;
box-sizing: border-box;
left: 0;
display: flex;
justify-content: space-around;
font-size: 34rpx;
font-family: 'fz';
color: #fff;
.footer-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 200rpx;
height: 200rpx;
overflow: hidden;
image {
width: 54rpx;
height: 54rpx;
}
}
}
.footer-down {
position: fixed;
bottom: 30rpx;
left: 0;
width: 100%;
height: 80rpx;
text-align: center;
image {
width: 60rpx;
height: 60rpx;
}
}
.title {
font-size: 86rpx;
margin-top: 153rpx;
font-family: 'fz-bold';
}
.sub-title {
font-size: 37rpx;
margin-top: 44rpx;
font-family: 'fz-bold';
}
.desc {
font-size: 22rpx;
margin-top: 24rpx;
line-height: 37rpx;
text-align: left;
font-family: 'fz';
}
.page1,
.page2,
.page3,
.page4 {
position: relative;
color: #fff;
padding: 0 37rpx;
box-sizing: border-box;
text-align: center;
}
.page1 {
padding: 0 108rpx;
}
.page2 {
padding: 0;
.title {
margin-top: 74rpx;
}
.desc {
text-align: center;
width: 400rpx;
margin: 40rpx auto;
}
.swiper {
width: 100%;
height: 450rpx;
.swiper-item {
height: 450rpx;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
.swiper-item-box {
width: 490rpx;
height: 365rpx;
overflow: hidden;
padding: 18rpx;
box-sizing: border-box;
background: transparent;
}
.swiper-item-active {
width: 597rpx;
height: 448rpx;
}
image {
width: 100%;
height: 100%;
transition: all 0.6s;
}
}
}
}
.page4 {
.title {
margin-top: 74rpx;
}
.card {
margin-top: 40rpx;
padding: 39rpx 50rpx 39rpx 75rpx;
box-sizing: border-box;
font-size: 21rpx;
font-family: 'fz';
color: #fff;
text-align: left;
.card-item {
margin-bottom: 20rpx;
position: relative;
line-height: 30rpx;
}
.card-item::before {
content: '';
margin-right: 10rpx;
position: absolute;
width: 7rpx;
height: 7rpx;
background: #8bd278;
border-radius: 50%;
left: -20rpx;
top: 10rpx;
}
.card-item:last-child {
margin-bottom: 0;
}
}
}
<template>
<view class="home">
<swiper class="scroll" vertical :current="current" @change="handleScrollChange">
<swiper-item>
<home-page1 class="scroll-item"></home-page1>
</swiper-item>
<swiper-item>
<home-page2 class="scroll-item"></home-page2>
</swiper-item>
<swiper-item>
<home-page3 class="scroll-item"></home-page3>
</swiper-item>
<swiper-item>
<home-page4 class="scroll-item"></home-page4>
</swiper-item>
</swiper>
<!-- 底部导航 -->
<view class="footer">
<view class="footer-item blur-bg" @click="goToPage()">
<view>
<image style="width: 59rpx; height: 59rpx" src="@/assets/reservation-images/twitter.png" mode="widthFix">
</image>
</view>
<view>了解飞鹤</view>
</view>
<view class="footer-item blur-bg" @click="goToPage('/reservation/subscribe/index')">
<view>
<image src="@/assets/reservation-images/briefcase.png" mode="widthFix"></image>
</view>
<view>现在预约</view>
</view>
<view class="footer-item blur-bg" @click="goToPage('/reservation/record/index')">
<view>
<image src="@/assets/reservation-images/calendar.png" mode="widthFix"></image>
</view>
<view>预约记录</view>
</view>
</view>
<!-- 底部箭头 -->
<view class="footer-down" @click="changeCurrent" v-if="current < 3">
<image src="@/assets/reservation-images/icon-down.svg" mode="widthFix"></image>
</view>
</view>
</template>
<script setup>
import {
useUserStore
} from "@/stores/user.js";
import homePage1 from './page1.vue'
import homePage2 from './page2.vue'
import homePage3 from './page3.vue'
import homePage4 from './page4.vue'
import {
ref,
onMounted
} from 'vue'
const current = ref(0) // 当前页码
const userStore = useUserStore();
onMounted(() => {
let cuk = uni.getStorageSync('cuk')
let memberId = uni.getStorageSync('memberId')
// 如果本地没有缓存登录信息,则需要登录
if (!cuk || !memberId) {
userStore.wxAutoLogin();
}
})
const changeCurrent = () => {
if (current.value >= 3) {
current.value = 0
} else {
current.value++
}
}
const handleScrollChange = (e) => {
console.log(e)
current.value = e.detail.current
}
const goToPage = (path) => {
if (!path) return
uni.navigateTo({
url: path,
})
}
</script>
<style lang="less" scoped>
@import './index.less';
</style>
\ No newline at end of file
<template>
<view
class="home-page page1"
:style="{ backgroundImage: `url(${baseUrl}/images/bg-1.png)` }"
>
<view class="logo">
<image src="@/assets/reservation-images/logo.svg" mode="widthFix"></image>
</view>
<!-- 内容 -->
<view class="title"> 探秘之旅 </view>
<view class="sub-title"> 探秘中国飞鹤世界级智能工厂 </view>
<view class="desc">
奇趣探秘、知识科普、多样互动,了解WCM世界级工厂管理体系见证一滴牛奶华丽变身为奶粉的过程,探索探索中国飞鹤对高品质奶粉不懈追求背后的故事。
</view>
</view>
</template>
<script setup>
import { baseUrl } from '@/reservation/config'
defineOptions({
name: 'page1',
})
</script>
<style lang="less" scoped>
@import './index.less';
</style>
<template>
<view
class="home-page page2"
:style="{ backgroundImage: `url(${baseUrl}/images/bg-2.png)` }"
>
<view class="logo">
<image src="@/assets/reservation-images/logo.svg" mode="widthFix"></image>
</view>
<!-- 内容 -->
<view class="title"> 环节介绍 </view>
<view class="desc">
见证一滴牛奶华丽变身为奶粉的全过程, 了解高品质产品背后的科学知识
</view>
<!-- 轮播图 -->
<swiper
class="swiper"
:circular="true"
previous-margin="90rpx"
next-margin="90rpx"
:current="current"
@change="handleChange"
>
<block v-for="(item, index) in list" :key="index">
<swiper-item>
<view class="swiper-item">
<view
class="swiper-item-box blur-bg"
:class="current === index ? 'swiper-item-active' : ''"
>
<image class="" :src="item.image" mode="scaleToFill" />
</view>
</view>
</swiper-item>
</block>
</swiper>
<!-- -->
<view class="sub-title"> {{ list[current].title }} </view>
<view class="desc" style="width: 450rpx">
{{ list[current].desc }}
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
// 导入图片
import { baseUrl } from '@/reservation/config'
import s1 from '@/assets/reservation-images/s-1.png'
import s2 from '@/assets/reservation-images/s-2.png'
defineOptions({
name: 'page2',
})
const current = ref(0)
const list = ref([
{
image: s1,
title: '寓教于乐的互动体验',
desc: '显微镇观察实验、冰淇淋DIY、手工奶片DIY、 牛奶「烟花」等',
},
{
image: s2,
title: '冰淇淋DIY',
desc: '寓教于乐的互动体验,冰淇淋DIY、手工奶片DIY、 牛奶「烟花」',
},
{
image: s1,
title: '手工奶片DIY、 牛奶',
desc: '冰淇淋DIY',
},
])
const handleChange = (e) => {
current.value = e.detail.current
}
</script>
<style lang="less" scoped>
@import './index.less';
</style>
<template>
<view class="home-page page2" :style="{ backgroundImage: `url(${baseUrl}/images/bg-3.png)` }">
<view class="logo">
<image src="@/assets/reservation-images/logo.svg" mode="widthFix"></image>
</view>
<!-- 内容 -->
<view class="title"> 环节介绍 </view>
<view class="desc">
见证一滴牛奶华丽变身为奶粉的全过程, 了解高品质产品背后的科学知识
</view>
<!-- 轮播图 -->
<swiper class="swiper" :circular="true" previous-margin="90rpx" next-margin="90rpx" :current="current"
@change="handleChange">
<block v-for="(item, index) in list" :key="index">
<swiper-item>
<view class="swiper-item">
<view class="swiper-item-box blur-bg" :class="current === index ? 'swiper-item-active' : ''">
<image class="" :src="item.image" mode="scaleToFill" />
</view>
</view>
</swiper-item>
</block>
</swiper>
<!-- -->
<view class="sub-title"> {{ list[current].title }} </view>
<view class="desc" style="width: 450rpx">
{{ list[current].desc }}
</view>
</view>
</template>
<script setup>
import {
baseUrl
} from '@/reservation/config'
import {
ref
} from 'vue'
import s1 from '@/assets/reservation-images/s-1.png'
import s2 from '@/assets/reservation-images/s-2.png'
defineOptions({
name: 'page3',
})
const current = ref(0)
const list = ref([{
image: s1,
title: '寓教于乐的互动体验',
desc: '显微镇观察实验、冰淇淋DIY、手工奶片DIY、 牛奶「烟花」等',
},
{
image: s2,
title: '冰淇淋DIY',
desc: '寓教于乐的互动体验,冰淇淋DIY、手工奶片DIY、 牛奶「烟花」',
},
{
image: s1,
title: '手工奶片DIY、 牛奶',
desc: '冰淇淋DIY',
},
])
const handleChange = (e) => {
current.value = e.detail.current
}
</script>
<style lang="less" scoped>
@import './index.less';
</style>
\ No newline at end of file
<template>
<view
class="home-page page4"
:style="{ backgroundImage: `url(${baseUrl}/images/bg-4.png)` }"
>
<view class="logo">
<image src="@/assets/reservation-images/logo.svg" mode="widthFix"></image>
</view>
<!-- 内容 -->
<view class="title"> 注意事项 </view>
<view class="card blur-bg">
<view class="card-item" v-for="(item, index) in list" :key="index">
{{ item }}
</view>
</view>
</view>
</template>
<script setup>
import { baseUrl } from '@/reservation/config'
import { ref } from 'vue'
defineOptions({
name: 'page4',
})
const list = ref([
'若有特殊参观要求,如参观路线、时长,讲解内容等,请联系工厂工作人员。',
'提交预约信息后,工作人员审核后生效。请抵达工厂时向正作人员出示入场二维码。',
'每日可提交次日预约信息,如遇时段已满或闭馆情况,请更换预约时间。',
'所有参观人员须实名预约,实名入场参观。',
'除特殊工作犬外,不得携带任何宠物。',
'馆内禁止吸烟,请自觉维护环境卫生,勿丢弃杂物。',
'酗酒者、衣冠不整者以及无行为能力或限制行为能力者、无监护人陪伴的,谢绝入馆。',
'管制械具、打火机等易燃易爆品,饮料、食品及宠物等禁止带入场馆,请提前处理。',
'参观前请路将随身包裹奇存,贵重物品自行保管。',
'参观时清自觉遵守参观秩序,不要大声喧哗,以免影响其他观众。请将手机设置为静音。',
])
</script>
<style lang="less" scoped>
@import './index.less';
</style>
<template>
<view class="record record-detail">
<view class="record-bg" :style="{ backgroundImage: `url(${baseUrl}/images/bg-6.png)` }"></view>
<view class="record-content">
<view class="tips">请凭下方预约二维码现场签到进场</view>
<view class="card detail">
<view class="title">{{ detail.title }}</view>
<view class="date">
{{ detail.reservation_date }} {{ detail.week }}{{ detail.reservation_start_time }} -
{{ detail.reservation_end_time }}
</view>
<view class="line"></view>
<view class="info">
预约人:{{ detail.realname }}
</view>
<view class="info">
手机:{{ detail.telephone }}
</view>
<view class="info">
访客人数:{{ detail.visitor_number }}
</view>
<view class="qrcode">
<image :src="detail.qrcode" mode="widthFix" />
</view>
</view>
<view class="buttons" @click="cancelReservation">
<fh-button type="plain" @click="cancelReservation">
取消预约
</fh-button>
</view>
</view>
</view>
</template>
<script setup>
import {
baseUrl
} from '@/reservation/config'
import {
onLoad
} from "@dcloudio/uni-app";
import fhButton from "../components/fh-button.vue";
import {
ref
} from 'vue'
import {
reservationDetail,
reservationCancel
} from '@/api/reservation'
defineOptions({
name: 'record-detail',
})
// 获取参数
const id = ref(0)
const detail = ref({
title: '', // 预约标题
reservation_date: '', // 预约日期
reservation_start_time: '', // 预约开始时间
reservation_end_time: '', // 预约结束时间
week: '', // 星期
qrcode: '', // 预约二维码
realname: '', // 预约人姓名
telephone: '', // 预约人手机号
visitor_number: '', // 访客人数
})
onLoad((options) => {
id.value = options.id
console.log(id.value)
options.id && getDetail()
})
const getDetail = () => {
reservationDetail({
id: id.value,
}).then((res) => {
detail.value = res.data
// 翻译星期
detail.value.week = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'][Number(detail.value.week)]
})
}
const cancelReservation = () => {
console.log('取消预约')
reservationCancel({
id: id.value,
}).then((res) => {
console.log(res)
if (res.code == 0) {
uni.showToast({
title: '取消成功',
icon: 'success',
})
uni.navigateBack()
} else {
uni.showToast({
title: res.msg,
icon: 'none',
})
}
})
}
</script>
<style lang="less" scoped>
@import './index.less';
</style>
\ No newline at end of file
// 声明字体
@font-face {
font-family: 'fz';
src: url('https://essence.jzvcode.com/feihe/images/fz.ttf') format('truetype');
}
@font-face {
font-family: 'fz-bold';
src: url('https://essence.jzvcode.com/feihe/images/fz-bold.ttf')
format('truetype');
}
.record {
background: #eee;
width: 100%;
height: 100vh;
overflow: hidden;
&-bg {
width: 100%;
height: 600rpx;
background-size: 100% auto;
background-repeat: no-repeat;
background-position: top center;
}
&-content {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 1;
padding: 52rpx;
box-sizing: border-box;
padding-top: 120rpx;
.tips {
font-size: 26rpx;
color: #fff;
font-family: 'fz';
margin-left: 55rpx;
margin-bottom: 28rpx;
text-shadow: 0px 0px 15px rgba(0, 0, 0, 0.56);
}
.buttons {
position: absolute;
bottom: 100rpx;
left: 0;
width: 100%;
padding: 0 52rpx;
box-sizing: border-box;
}
.card {
min-height: 40vh;
max-height: 70vh;
overflow-y: auto;
background: #fff;
box-shadow: 0rpx 19rpx 37rpx 0rpx rgba(0, 0, 0, 0.04);
border-radius: 26rpx;
padding: 37rpx 42rpx;
box-sizing: border-box;
&-tab {
display: flex;
justify-content: center;
align-items: center;
background: #ffffff;
border-radius: 37rpx;
border: 2rpx solid #be8e38;
padding: 8rpx;
box-sizing: border-box;
width: 388rpx;
height: 74rpx;
margin: 0 auto;
.card-tab-item {
width: 188rpx;
height: 59rpx;
border-radius: 33rpx;
color: #be8e38;
display: flex;
justify-content: center;
align-items: center;
font-size: 26rpx;
transition: all 0.3s ease;
font-family: 'fz';
}
.active {
background: #dab97b;
color: #fff;
font-size: 28rpx;
font-family: 'fz-bold';
}
}
&-list {
width: 100%;
height: 100%;
.card-list-item {
height: 180rpx;
border-bottom: 2rpx solid #efefef;
display: flex;
align-items: center;
&-icon {
width: 68rpx;
height: 80rpx;
}
&-right {
margin-left: 44rpx;
.record-name {
font-size: 34rpx;
color: #1d1e25;
font-family: 'fz-bold';
margin-bottom: 8rpx;
}
.record-time {
font-size: 26rpx;
color: #a0a0a0;
font-family: 'fz';
display: flex;
align-items: center;
font-size: 0rpx;
}
}
}
.card-list-item:last-child {
border-bottom: none;
}
}
}
}
.detail {
padding-top: 70rpx;
.title {
font-size: 37rpx;
color: #d3a358;
font-family: 'fz-bold';
margin-bottom: 28rpx;
}
.line {
margin: 28rpx 0;
height: 2rpx;
background: #efefef;
}
.info {
font-size: 30rpx;
color: #1d1e25;
font-family: 'fz';
line-height: 35rpx;
margin-bottom: 12rpx;
}
.qrcode {
width: 425rpx;
height: 425rpx;
margin: 35rpx auto;
image {
width: 100%;
height: 100%;
}
}
}
}
<template>
<view class="record">
<view class="record-bg" :style="{ backgroundImage: `url(${baseUrl}/images/bg-6.png)` }"></view>
<view class="record-content">
<view class="card">
<view class="card-tab">
<view class="card-tab-item" :class="{ active: type == 1 }" @click="
type = 1;
getList()
">
<text>未出行</text>
</view>
<view class="card-tab-item" :class="{ active: type == 2 }" @click="
type = 2;
getList()
">
<text>已完成</text>
</view>
</view>
<view class="card-list">
<view class="card-list-item" v-for="item in list" :key="item.id" @click="goToDetail(item.id)">
<image class="card-list-item-icon" src="@/assets/reservation-images/icon-list.png" mode="widthFix" />
<view class="card-list-item-right">
<view class="record-name">{{ item.title }}</view>
<view class="record-time">
<image style="width: 30rpx; height: 30rpx; margin-right: 12rpx"
src="@/assets/reservation-images/calendar-gray.png" mode="widthFix" />
<text style="font-size: 26rpx">{{ item.date }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import {
baseUrl
} from '@/reservation/config'
import {
ref,
onMounted
} from 'vue'
import {
reservationList
} from '@/api/reservation'
defineOptions({
name: 'record',
})
const list = ref([])
const type = ref(1) // 1: 未出行 2: 已完成
onMounted(() => {
getList()
})
const getList = () => {
reservationList({
type: type.value,
}).then((res) => {
list.value = res.data
})
}
const goToDetail = (id) => {
uni.navigateTo({
url: '/reservation/record/detail?id=' + id,
})
}
</script>
<style lang="less" scoped>
@import './index.less';
</style>
\ No newline at end of file
// 声明字体
@font-face {
font-family: 'fz';
src: url('https://essence.jzvcode.com/feihe/images/fz.ttf') format('truetype');
}
@font-face {
font-family: 'fz-bold';
src: url('https://essence.jzvcode.com/feihe/images/fz-bold.ttf')
format('truetype');
}
.record {
background: #eee;
width: 100%;
height: 100vh;
overflow: hidden;
&-bg {
width: 100%;
height: 600rpx;
background-size: 100% auto;
background-repeat: no-repeat;
background-position: top center;
}
&-content {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 1;
padding: 52rpx;
box-sizing: border-box;
.card {
margin-top: 120rpx;
min-height: 40vh;
max-height: 60vh;
overflow-y: auto;
background: #fff;
box-shadow: 0rpx 19rpx 37rpx 0rpx rgba(0, 0, 0, 0.04);
border-radius: 26rpx;
padding: 37rpx 86rpx;
box-sizing: border-box;
font-family: 'fz';
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.title {
font-size: 52rpx;
color: #d3a358;
line-height: 67rpx;
text-align: left;
}
.image {
width: 370rpx;
height: 370rpx;
margin: 0 auto;
image {
width: 100%;
height: 100%;
}
}
.desc {
font-size: 30rpx;
color: #000000;
line-height: 45rpx;
text-align: left;
font-style: normal;
margin-top: 20rpx;
}
}
}
.buttons {
position: absolute;
left: 0;
width: 100%;
padding: 0 52rpx;
box-sizing: border-box;
bottom: 100rpx;
}
}
<template>
<view class="record">
<view
class="record-bg"
:style="{ backgroundImage: `url(${baseUrl}/images/bg-6.png)` }"
></view>
<view class="record-content">
<view class="card">
<view class="title">预约成功!</view>
<view class="image">
<image
src="@/assets/reservation-images/success.png"
mode="widthFix"
/>
</view>
<view class="desc"
>您的预约已完成,届时请凭预约详情内二维码现场签到进场。</view
>
</view>
<view class="buttons">
<view style="margin-bottom: 37rpx" @click.stop="handleDetail">
<fh-button>查看预约详情</fh-button>
</view>
<view @click.stop="handleHome">
<fh-button>返回首页</fh-button>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { baseUrl } from '@/reservation/config'
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import fhButton from '../components/fh-button.vue'
defineOptions({
name: 'record',
})
const id = ref(0)
onLoad((options) => {
id.value = options.id
console.log(id.value)
})
const handleDetail = () => {
uni.redirectTo({
url: '/reservation/record/detail?id=' + id.value,
})
}
const handleHome = () => {
uni.reLaunch({ url: '/reservation/home/index' })
}
</script>
<style lang="less" scoped>
@import './index.less';
</style>
<template>
<view class="date-panel"> </view>
</template>
<script setup>
defineOptions({
name: 'datePanel',
})
</script>
<style lang="less" scoped>
.date-panel {
width: 100%;
height: 100%;
}
</style>
// 声明字体
@font-face {
font-family: 'fz';
src: url('https://essence.jzvcode.com/feihe/images/fz.ttf') format('truetype');
}
@font-face {
font-family: 'fz-bold';
src: url('https://essence.jzvcode.com/feihe/images/fz-bold.ttf')
format('truetype');
}
.subscribe {
width: 100%;
height: auto;
background-size: cover;
background-repeat: no-repeat;
background-position: top;
background-color: #fff;
box-sizing: border-box;
padding: 30rpx;
padding-bottom: calc(env(safe-area-inset-bottom) + 30rpx);
.record {
padding-left: 40rpx;
color: #fff;
font-size: 26rpx;
display: flex;
align-items: center;
font-family: 'fz-bold';
margin-bottom: 28rpx;
}
.card {
padding: 30rpx 60rpx 60rpx;
box-sizing: border-box;
background: rgba(255, 255, 255, 0.2);
box-shadow: 0rpx 19rpx 37rpx 0rpx rgba(0, 0, 0, 0.3);
border-radius: 26rpx;
border: 2rpx solid rgba(255, 255, 255, 0.2);
backdrop-filter: blur(15px);
color: #fff;
position: relative;
margin-bottom: 37rpx;
.card-title {
font-size: 34rpx;
font-family: 'fz-bold';
margin-bottom: 24rpx;
}
.card-image {
width: 100%;
height: 410rpx;
border-radius: 26rpx;
overflow: hidden;
border: 2rpx solid rgba(255, 255, 255, 0.2);
image {
width: 100%;
height: 100%;
}
}
.card-swiper {
width: 100%;
height: 410rpx;
position: relative;
.swiper-item {
width: 100%;
}
}
.name {
font-size: 37rpx;
font-family: 'fz';
text-align: center;
margin-top: 39rpx;
margin-bottom: 29rpx;
position: relative;
line-height: 45rpx;
.swiper-left,
.swiper-right {
position: absolute;
top: 0rpx;
width: 44rpx;
height: 44rpx;
image {
width: 100%;
height: 100%;
}
}
.swiper-left {
left: 0;
transform: rotate(180deg);
}
.swiper-right {
right: 0;
}
}
.desc {
font-size: 22rpx;
font-family: 'fz';
}
.line {
width: 100%;
height: 2rpx;
background: rgba(255, 255, 255, 0.2);
margin: 50rpx 0;
}
}
}
.phone-code {
display: flex;
align-items: center;
justify-content: space-between;
.phone-code-btn {
width: 270rpx;
height: 60rpx;
background: #dab97b;
border-radius: 30rpx;
font-size: 28rpx;
color: #ffffff;
line-height: 34rpx;
text-align: center;
font-style: normal;
font-family: 'fz-bold';
line-height: 60rpx;
margin-left: 26rpx;
}
}
.form-item {
padding-bottom: 10rpx;
width: 100%;
border-bottom: 2rpx solid rgba(255, 255, 255, 0.2);
margin-bottom: 50rpx;
box-sizing: border-box;
padding-left: 12rpx;
.form-item__label {
font-size: 34rpx;
font-family: 'fz-bold';
color: #fff;
margin-bottom: 30rpx;
}
.form-item__value {
display: flex;
width: 100%;
align-items: center;
justify-content: space-between;
font-size: 28rpx;
.area {
display: flex;
align-items: center;
width: 130rpx;
image {
width: 44rpx;
height: 44rpx;
transform: rotate(90deg);
}
}
.area-line {
width: 2rpx;
height: 30rpx;
background: rgba(255, 255, 255, 0.2);
margin-right: 22rpx;
}
input {
flex: 1;
font-size: 28rpx;
font-weight: 400;
font-family: 'fz';
}
.form-item__value-text {
font-family: 'fz';
flex: 1;
color: #fff;
&-placeholder {
color: rgba(255, 255, 255, 0.5);
}
}
image {
width: 44rpx;
height: 44rpx;
transform: rotate(90deg);
}
}
}
.popup-box {
background: #fff;
width: 100%;
padding: 44rpx 37rpx;
box-sizing: border-box;
box-shadow: 0rpx 19rpx 37rpx 0rpx rgba(0, 64, 152, 0.1);
border-radius: 34rpx 34rpx 0rpx 0rpx;
display: flex;
flex-direction: column;
font-family: 'fz';
padding-bottom: calc(env(safe-area-inset-bottom) + 50rpx);
.popup-header {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
position: relative;
box-sizing: border-box;
margin-bottom: 40rpx;
.close {
position: absolute;
right: 40rpx;
top: 50;
width: 44rpx;
height: 44rpx;
image {
width: 40rpx;
height: 40rpx;
}
}
}
.popup-content {
flex: 1;
overflow-y: auto;
margin-bottom: 40rpx;
.date-line {
width: 100%;
height: 2rpx;
background: #efefef;
margin: 10rpx 0 30rpx;
}
.date-card {
display: flex;
flex-wrap: wrap;
.date-item {
width: 150rpx;
height: 150rpx;
border: 2rpx solid #dab97b;
border-radius: 22rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 26rpx;
color: #1d1e25;
line-height: 32rpx;
margin-right: 18rpx;
margin-bottom: 18rpx;
&-week {
margin-bottom: 22rpx;
}
&-active {
background: #dab97b;
color: #fff;
}
&-disabled {
color: #ccc;
border-color: #ccc;
}
}
.date-item:nth-child(4n) {
margin-right: 0;
}
}
.time-card {
display: flex;
flex-wrap: wrap;
.time-item {
width: 318rpx;
height: 97rpx;
border: 2rpx solid #dab97b;
border-radius: 22rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 26rpx;
color: #1d1e25;
line-height: 32rpx;
margin-right: 18rpx;
margin-bottom: 18rpx;
&-week {
margin-bottom: 22rpx;
}
&-active {
background: #dab97b;
color: #fff;
}
&-disabled {
color: #ccc;
border-color: #ccc;
}
}
.time-item:nth-child(2n) {
margin-right: 0;
}
}
}
}
::v-deep {
.indicatorClass:before,
.indicatorClass:after {
color: transparent !important;
border-color: transparent !important;
}
}
.picker-view {
overflow: hidden;
height: 500rpx;
.item {
height: 50px !important;
text-align: center;
font-size: 30rpx;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.15s linear;
}
.active {
color: #d3a358;
font-weight: bold;
font-size: 40rpx;
}
}
<template>
<view
class="subscribe"
:style="{ backgroundImage: `url(${baseUrl}/images/bg-5.png)` }"
>
<view class="record" @click="goToRecord">
<text>预约记录</text>
<image
src="@/assets/reservation-images/icon-right.svg"
mode="widthFix"
style="width: 30rpx; height: 30rpx"
/>
</view>
<view class="card">
<view class="card-title">参观园区</view>
<swiper
circular
class="card-swiper"
:current="swiperIndex"
@change="handleSwiperChange"
>
<swiper-item
class="swiper-item"
v-for="(item, index) in cardList"
:key="index"
>
<view class="card-image">
<image :src="item.image" mode="widthFix" />
</view>
</swiper-item>
</swiper>
<view class="name">
{{ currentGround.title }}
<view class="swiper-left" @click="handleSwiperLeft">
<image
src="@/assets/reservation-images/icon-right-y.svg"
mode="widthFix"
/>
</view>
<view class="swiper-right" @click="handleSwiperRight">
<image
src="@/assets/reservation-images/icon-right-y.svg"
mode="widthFix"
/>
</view>
</view>
<view class="desc">
{{ currentGround.detail }}
</view>
<!-- 分割线 -->
<view class="line"></view>
<!-- 到访时间 -->
<view class="time">
<view class="form-item" style="margin-bottom: 0rpx">
<view class="form-item__label">到访时间</view>
<view class="form-item__value" @click="handleDate">
<view class="form-item__value-text">
<text
v-if="formData.reservation_date && formData.reservation_time"
>
{{ formData.reservation_date }} {{ formData.reservation_time }}
</text>
<text v-else class="form-item__value-text-placeholder">
请选择到访日期及时间
</text>
</view>
<image
src="@/assets/reservation-images/icon-right-y.svg"
mode="widthFix"
/>
</view>
</view>
</view>
</view>
<view class="card" style="padding-top: 60rpx">
<view class="form-item">
<view class="form-item__label">预约人姓名</view>
<view class="form-item__value">
<input
type="text"
v-model="formData.realname"
placeholder="请填写访客姓名"
placeholder-style="color: #fff;opacity: 0.5"
/>
</view>
</view>
<!-- <view class="form-item">
<view class="form-item__label">预约人手机</view>
<view class="form-item__value">
<view class="area">
<view>+86</view>
<image src="@/assets/reservation-images/icon-right-y.svg" mode="widthFix" />
</view>
<view class="area-line"></view>
<input
type="text"
maxlength="11"
v-model="formData.telephone"
placeholder="请输入手机号"
placeholder-style="color: #fff;opacity: 0.5"
/>
</view>
</view> -->
<!-- 验证码 -->
<view class="phone-code">
<view class="form-item" style="flex: 1">
<view class="form-item__label">预约人手机</view>
<view class="form-item__value">
<input
type="number"
maxlength="11"
v-model="formData.telephone"
placeholder="请填写手机号"
placeholder-style="color: #fff;opacity: 0.5"
/>
</view>
</view>
<button
class="phone-code-btn"
open-type="getPhoneNumber"
@getphonenumber="decryptPhoneNumber"
>
获取手机号
</button>
</view>
<!-- 访客人数 -->
<view class="form-item">
<view class="form-item__label">访客人数</view>
<view class="form-item__value">
<input
type="number"
v-model="formData.visitor_number"
placeholder="请填写访客人数"
placeholder-style="color: #fff;opacity: 0.5"
/>
</view>
</view>
<!-- 访客类型 -->
<view class="form-item" style="margin-bottom: 0rpx">
<view class="form-item__label">访客类型</view>
<view class="form-item__value" @click="handleType">
<input
type="text"
v-model="formData.typeStr"
readonly
placeholder="请选择访客类型"
placeholder-style="color: #fff;opacity: 0.5"
/>
<image
src="@/assets/reservation-images/icon-right-y.svg"
mode="widthFix"
/>
</view>
</view>
</view>
<!-- 提交按钮 -->
<view class="submit-btn" @click="handleSubmit">
<fh-button>确认预约</fh-button>
</view>
<!-- 到访日期弹窗 -->
<uni-popup ref="datePanelRef" :safe-area="false">
<view class="popup-box" style="max-height: 85vh">
<view class="popup-header">
<view class="title">到访时间</view>
<view class="close" @click="datePanelRef.close()">
<image
src="@/assets/reservation-images/close.png"
mode="widthFix"
/>
</view>
</view>
<view class="popup-content">
<view class="date-card">
<view
class="date-item"
v-for="(item, index) in dateList"
:key="index"
@click="handleDateItemClick(item)"
:class="{
'date-item-active': item.is_selected,
'date-item-disabled': item.is_open == 0,
}"
>
<view class="date-item-week">{{ item.week }}</view>
<view class="date-item-day">{{ item.dayStr }}</view>
</view>
</view>
<view class="date-line"></view>
<view class="time-card">
<view
class="time-item"
v-for="(item, index) in timeList"
:key="index"
@click="handleTimeItemClick(item)"
:class="{
'time-item-active': item.is_selected,
'time-item-disabled': item.is_open == 0,
}"
>
<view class="time-item-day" style="text-align: center">
<view>{{ item.time }}</view>
<view v-if="item.is_open == 0">{{ item.status }}</view>
</view>
</view>
</view>
</view>
<view class="popup-footer" @click="handleDateConfirm">
<fh-button>确认选择</fh-button>
</view>
</view>
</uni-popup>
<!-- 访客类型下拉框 -->
<uni-popup ref="typePanelRef" :safe-area="false">
<view class="popup-box" style="max-height: 85vh">
<view class="popup-header">
<view class="title">访客类型</view>
<view class="close" @click="typePanelRef.close()">
<image
src="@/assets/reservation-images/close.png"
mode="widthFix"
/>
</view>
</view>
<view class="popup-content">
<picker-view
:indicator-style="indicatorStyle"
:indicator-class="indicatorClass"
:value="typeValue"
:mask-style="maskStyle"
:immediate-change="true"
@change="bindTypeChange"
class="picker-view"
>
<picker-view-column>
<view
class="item"
v-for="(item, index) in typeList"
:class="{ active: activeIndex == index }"
:key="index"
>{{ item.name }}</view
>
</picker-view-column>
</picker-view>
</view>
<view class="popup-footer" @click="handleTypeConfirm">
<fh-button>确认选择</fh-button>
</view>
</view>
</uni-popup>
</view>
</template>
<script setup>
import { fetchUserInfo, fetchAutoPhone } from '@/api/user.js'
import { baseUrl } from '@/reservation/config'
import { ref, onMounted } from 'vue'
import {
getDateConfig,
getTimeConfig,
reservation,
getGround,
} from '@/api/reservation'
import fhButton from '../components/fh-button.vue'
defineOptions({
name: 'subscribe',
})
const swiperIndex = ref(0)
// 工厂数据
const cardList = ref([])
// 当前选中的工厂信息
const currentGround = ref({
ground: '',
title: '',
detail: '',
image: '',
})
// 到访日期Ref
const datePanelRef = ref(null)
// 到访日期数据
const dateList = ref([])
// 到访时间数据
const timeList = ref([])
// 访客类型下拉框 配置
const typePanelRef = ref(null)
const indicatorStyle = ref('height: 50px')
const indicatorClass = ref('indicatorClass')
const maskStyle = ref('background: transparent !important;')
const typeValue = ref([0])
const activeIndex = ref(0)
// 访客类型数据
const typeList = ref([
{
type: 1,
name: '内部学习/培训',
},
{
type: 2,
name: '产品/品牌体验',
},
{
type: 3,
name: '公众参观|科普教育',
},
{
type: 4,
name: '商业邀约/参观',
},
{
type: 5,
name: '社会团体/学术交流',
},
{
type: 6,
name: '政府考察/调研',
},
{
type: 7,
name: 'VIP/定向邀约',
},
{
type: 8,
name: '媒体/机构',
},
{
type: 9,
name: '其他',
},
])
const formData = ref({
reservation_date: '', // 到访日期
reservation_time: '', // 到访时间
realname: '', // 姓名
telephone: '', // 电话
visitor_number: '', // 参观人数
ground: '', // 工厂
type: '', // 参观类型
typeStr: '', // 参观类型名称
})
onMounted(async () => {
// 获取工厂数据
await getGround({}).then((res) => {
console.log(res, 'res')
cardList.value = res.data
// 设置当前选中的工厂
currentGround.value = cardList.value[0] || {}
})
// 获取到访日期
getDateConfig({}).then((res) => {
dateList.value = res.data.map((item, index) => ({
...item,
dayStr: formatDate(item.day),
}))
// 如果dateList 有值,则默认查询第一条数据的timeList
if (dateList.value.length > 0) {
getTimeList(dateList.value[0].day)
}
})
})
/**
* 获取到访时间
* @param day 到访日期 2025-07-11
*/
const getTimeList = (day) => {
getTimeConfig({
day: day,
ground: cardList.value[swiperIndex.value].ground || '',
}).then((res) => {
timeList.value = res.data
console.log(timeList.value, 'timeList')
})
}
/**
* 获取手机号
*/
const decryptPhoneNumber = async (e) => {
if (e.detail.errMsg !== 'getPhoneNumber:ok') {
uni.showToast({
title: '请授权使用手机号',
icon: 'none',
})
return
}
uni.login({
provider: 'weixin',
success: async (res) => {
if (res.errMsg === 'login:ok') {
let data = e.detail
getMobileByAuth(data, res)
} else {
uni.showToast({
title: res.errMsg,
icon: 'error',
})
}
},
})
}
/**
* 解析手机号
*/
const getMobileByAuth = (data, res) => {
fetchAutoPhone({
phoneEncryptedData: data.encryptedData,
phoneIv: data.iv,
code: data.code,
codeLogin: res.code,
}).then((res) => {
// 如果接口调用成功,则通过获取用户信息接口获取手机号
console.log(res, 'res')
getUserInfo()
})
}
/**
* 获取用户信息
*/
const getUserInfo = () => {
fetchUserInfo({}).then((res) => {
let data = res.data
if (data?.memberId !== 'not_login') {
formData.value.telephone = data.mobile
}
})
}
/**
* 访客类型下拉框 选择事件
*/
const handleType = () => {
typePanelRef.value.open('bottom')
}
/**
* 访客类型下拉框 确认选择事件
*/
const handleTypeConfirm = () => {
formData.value.typeStr = typeList.value[activeIndex.value].name
formData.value.type = typeList.value[activeIndex.value].type
typePanelRef.value.close()
}
/**
* 轮播图 左滑事件
*/
const handleSwiperLeft = () => {
swiperIndex.value--
if (swiperIndex.value < 0) {
swiperIndex.value = cardList.value.length - 1
}
}
/**
* 轮播图 右滑事件
*/
const handleSwiperRight = () => {
swiperIndex.value++
if (swiperIndex.value >= cardList.value.length) {
swiperIndex.value = 0
}
}
/**
* 访客类型下拉框 选择事件
* @param e 事件对象
*/
const bindTypeChange = (e) => {
console.log(e, 'e')
activeIndex.value = e.detail.value[0]
formData.value.type = typeList.value[activeIndex.value].type
}
/**
* 轮播图切换事件
* @param e 事件对象
*/
const handleSwiperChange = (e) => {
swiperIndex.value = e.detail.current
formData.value.ground = cardList.value[swiperIndex.value].ground || ''
currentGround.value = cardList.value[swiperIndex.value] || {}
console.log(currentGround.value, 'currentGround')
getTimeList(dateList.value[0].day)
}
const handleDate = () => {
datePanelRef.value.open('bottom')
}
// 自定义时间处理函数,后续可以替换 将 2025-07-11 转成 07-11
const formatDate = (date) => {
// 保留月和日
return date.split('-').slice(1).join('-')
}
/**
* 到访日期点击事件
* @param item 到访日期对象
*/
const handleDateItemClick = (item) => {
if (item.is_selected || item.is_open == 0) return
dateList.value.forEach((item) => {
item.is_selected = false
})
item.is_selected = true
// 设置formData.reservation_date
formData.value.reservation_date = item.day
getTimeList(item.day)
}
/**
* 到访时间点击事件
* @param item 到访时间对象
*/
const handleTimeItemClick = (item) => {
if (item.is_selected || item.is_open == 0) return
timeList.value.forEach((item) => {
item.is_selected = false
})
item.is_selected = true
// 设置formData.reservation_time
formData.value.reservation_time = item.time
}
/**
* 日期和时间确认选择
*/
const handleDateConfirm = () => {
// 判断日期是否选择
if (!formData.value.reservation_date) {
uni.showToast({
title: '请选择日期',
icon: 'none',
})
return
}
// 判断时间是否选择
if (!formData.value.reservation_time) {
uni.showToast({
title: '请选择时间',
icon: 'none',
})
return
}
datePanelRef.value.close()
}
// 校验表单,返回promise
const validateForm = () => {
return new Promise((resolve, reject) => {
if (!formData.value.reservation_date) {
reject('请选择日期')
}
if (!formData.value.reservation_time) {
reject('请选择时间')
}
if (!formData.value.realname) {
reject('请填写姓名')
}
if (!formData.value.telephone) {
reject('请填写手机号')
}
if (!formData.value.visitor_number) {
reject('请填写访客人数')
}
if (!formData.value.type) {
reject('请选择访客类型')
}
resolve()
})
}
const handleSubmit = () => {
// 校验表单
validateForm()
.then(() => {
reservation({
...formData.value,
ground: currentGround.value?.ground || '',
}).then((res) => {
console.log(res, 'res')
if (res.code == 0) {
uni.showToast({
title: '预约成功',
icon: 'success',
})
uni.redirectTo({
url: '/reservation/status/index?id=' + res.data.id,
})
} else {
uni.showToast({
title: res.msg,
icon: 'none',
})
}
})
})
.catch((err) => {
console.log(err, 'err')
uni.showToast({
title: err,
icon: 'none',
})
})
}
const goToRecord = () => {
uni.navigateTo({
url: '/reservation/record/index',
})
}
</script>
<style lang="less" scoped>
@import './index.less';
</style>
import { defineStore } from "pinia";
import {
defineStore
} from "pinia";
import {
autoLoginByCode,
fetchUserInfo,
......@@ -8,8 +10,12 @@ import {
fetchBabyInfoById,
updateBabyInfo,
} from "../api/user.js";
import { useGlobalStore } from "./global.js";
import { useHomeStore } from "./home.js";
import {
useGlobalStore
} from "./global.js";
import {
useHomeStore
} from "./home.js";
import md from "../md.js";
const globalStore = useGlobalStore();
......@@ -46,7 +52,9 @@ export const useUserStore = defineStore("userInfo", {
async changeBabySelected(babyId) {
// 更新选中状态
const { data } = await fetchBabyInfoById(babyId);
const {
data
} = await fetchBabyInfoById(babyId);
console.log("babyInfo", data);
if (data?.memberId !== "not_login") {
this.babyInfo = data;
......@@ -69,13 +77,14 @@ export const useUserStore = defineStore("userInfo", {
// console.log('wxAutoLogin', res);
if (res.errMsg === "login:ok") {
// 用户手机授权
const { data: babyExistence } = await fetchAutoPhone({
const {
data: babyExistence
} = await fetchAutoPhone({
phoneEncryptedData: data.encryptedData,
phoneIv: data.iv,
code: data.code,
codeLogin: res.code,
});
!babyExistence && onOpenRegisterFn && onOpenRegisterFn();
const homeStore = useHomeStore();
......@@ -97,9 +106,13 @@ export const useUserStore = defineStore("userInfo", {
* 获取用户信息
*/
async loadUserInfo() {
const { data } = await fetchUserInfo();
const {
data
} = await fetchUserInfo();
console.log("userInfo", data);
if (data?.memberId !== "not_login") {
// 缓存用户memberId
uni.setStorageSync('memberId', data?.memberId)
this.userInfo = data;
}
},
......@@ -110,7 +123,10 @@ export const useUserStore = defineStore("userInfo", {
if (findIndex > -1) {
this.babyNickCache[findIndex].name = name;
} else {
this.babyNickCache.push({ id, name });
this.babyNickCache.push({
id,
name
});
}
},
......@@ -118,7 +134,9 @@ export const useUserStore = defineStore("userInfo", {
* 获取宝宝信息
*/
async loadBabyInfo() {
const { data } = await fetchBabyInfo();
const {
data
} = await fetchBabyInfo();
console.log("babyInfo", data);
if (data?.memberId !== "not_login") {
this.babyInfo = data;
......@@ -143,7 +161,9 @@ export const useUserStore = defineStore("userInfo", {
* 获取用户积分信息
*/
async loadMemberInfo() {
const { data } = await fetchMemberInfo();
const {
data
} = await fetchMemberInfo();
console.log("fetchMemberInfo=", data);
this.setMemberInfo(data);
// this.memberInfo = data;
......@@ -164,7 +184,9 @@ export const useUserStore = defineStore("userInfo", {
* @param {String} code
*/
async autoLoginByCode(code) {
const { data } = await autoLoginByCode(code);
const {
data
} = await autoLoginByCode(code);
console.log("autoLoginByCode", data);
// 如果登录成功,获取用户信息和宝宝信息,更新到state中,方便全局使用
if (data && data.cuk) {
......@@ -211,4 +233,4 @@ export const useUserStore = defineStore("userInfo", {
}
},
},
});
});
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment