291 lines
9.7 KiB
Vue
291 lines
9.7 KiB
Vue
<template>
|
|
<div class="main">
|
|
<title class="title-block" title="门票系统的某个场馆">
|
|
</title>
|
|
<div :style="height + 'px'" class="container">
|
|
<div class="title">
|
|
<tm-icon name="tmicon-position" color="#fff" :fontSize="40"></tm-icon>
|
|
<div style="margin-left: 10rpx;">门票系统的某个场馆</div>
|
|
</div>
|
|
<div>
|
|
<image src="../../static/logo.png" mode="scaleToFill"
|
|
style="width: 664rpx;height:354rpx;margin-top: 20rpx;display: ;" />
|
|
</div>
|
|
<div class="title-detail">
|
|
<div class="item">
|
|
<div class="name">门票名称</div>
|
|
<div style="margin-left: 20rpx;">首都博物馆门票</div>
|
|
</div>
|
|
<tm-divider realColor></tm-divider>
|
|
<div class="item">
|
|
<div class="name">剩余数量</div>
|
|
<div style="margin-left: 20rpx;">1023/20000</div>
|
|
</div>
|
|
</div>
|
|
<div class="line"></div>
|
|
<div class="title-detail" style="background: #fff;">
|
|
<div class="item">
|
|
<div class="name" style="color: #000000;border-right:1rpx solid #BBC5E0;">预留手机号
|
|
<span style="font-size: 20rpx;"> (+86)</span>
|
|
</div>
|
|
<div style="margin-left: 20rpx; color: #000000;">
|
|
<input type="text" v-model="formData.phone" @input="changePhone" />
|
|
</div>
|
|
</div>
|
|
<tm-divider realColor></tm-divider>
|
|
<div class="item">
|
|
<div class="name" style="color: #000000;border-right:1rpx solid #BBC5E0;">验证码</div>
|
|
<div class="code">
|
|
<input type="text" v-model="formData.code" @input="changePhone" class="inputCode" />
|
|
<div style="color:#B1292E" @click="sendCode" v-if="isCode">{{ code }}</div>
|
|
<div v-else style="color:#B1292E">{{ formattedTime() }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="title-detail" style="background: #fff; color: #000000">
|
|
<div class="item">
|
|
<div class="name" style="color: #000000;border-right:1rpx solid #BBC5E0;">选择时间</div>
|
|
<div class="time">
|
|
<span style="width: 300rpx;">2023年12月16日</span>
|
|
<div style="display: flex;align-items: center;" @click="showHandle">
|
|
<span>选择</span>
|
|
<tm-icon name="tmicon-angle-right" :font-size="24"></tm-icon>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<tm-divider realColor></tm-divider>
|
|
<div class="item">
|
|
<div class="name" style=" color: #000000;border-right:1rpx solid #BBC5E0;">选择人数</div>
|
|
<div style="margin-left: 20rpx;" class="stepper">
|
|
<div style="color: #B29E92;font-size: 24rpx">*单次最多可预约10人</div>
|
|
<div>
|
|
<tm-stepper v-model="formData.num" color="#ef952e" bgColor="primary" circular :defaultValue="0"
|
|
:max="10" :height="40" :width="160" @change="changeNum"></tm-stepper>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div v-for="(item, index) in visitorsList" class="card" :key="index">
|
|
<div class="card-item">
|
|
<div class="name">姓名</div>
|
|
<div style="margin-left: 20rpx; color: #000000;">
|
|
<input type="text" v-model="item.name" />
|
|
</div>
|
|
</div>
|
|
<tm-divider realColor></tm-divider>
|
|
<div class="card-item">
|
|
<div class="name">身份证号</div>
|
|
<div style="margin-left: 20rpx; color: #000000;">
|
|
<input type="idcard" v-model="item.idCard" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<tm-button @click="reservation" color="#000000" :width="436" :height="60" :round="25">预约</tm-button>
|
|
<select-day :show.sync="show"></select-day>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { onMounted, ref, reactive, watch } from "vue";
|
|
import { useTimer } from '@/tmui/tool/useFun/useTimer'
|
|
import selectDay from './select-day/index'
|
|
const { start, stop, formattedTime, status, restart, timeObj, times, change } = useTimer({
|
|
totalTime: 10, unit: 'ss', format: 'ss秒'
|
|
});
|
|
let height = ref(0)
|
|
let code = ref('获取验证码')
|
|
let isCode = ref(true)
|
|
let show = ref(false)
|
|
const formData = reactive({
|
|
phone: '',
|
|
code: '',
|
|
num: 0
|
|
})
|
|
let visitorsList = ref([])
|
|
const msg = ref(null)
|
|
|
|
onMounted(() => {
|
|
uni.createSelectorQuery().select('.title-block').boundingClientRect(data => {
|
|
let res = uni.getSystemInfoSync();
|
|
height = res.windowHeight - data.bottom;
|
|
}).exec()
|
|
})
|
|
const sendCode = () => {
|
|
restart()
|
|
isCode.value = false;
|
|
if (status.value == -1 || status.value == 0) {
|
|
start();
|
|
}
|
|
}
|
|
watch(times, (newValue) => {
|
|
if (newValue === 0) {
|
|
code.value = '重新获取';
|
|
isCode.value = true;
|
|
stop()
|
|
}
|
|
})
|
|
const changeNum = (value) => {
|
|
formData.num = value
|
|
}
|
|
watch(() => formData.num, (newValue, oldValue) => {
|
|
console.log(newValue, oldValue)
|
|
if (newValue > oldValue) {
|
|
for (let i = 0; i < newValue - oldValue; i++) {
|
|
visitorsList.value.push({
|
|
name: '',
|
|
idCard: ''
|
|
})
|
|
}
|
|
}
|
|
if (newValue < oldValue) {
|
|
visitorsList.value.splice(-(oldValue - newValue))
|
|
}
|
|
})
|
|
|
|
const reservation = () => {
|
|
console.log(visitorsList.value)
|
|
const result = visitorsList.value.filter((item) => item.name && item.idCard)
|
|
if (result.map((item) => item.idCard).some((n, index, arr) => arr.indexOf(n) !== index)) {
|
|
return uni.showToast({
|
|
title: '身份证不能重复',
|
|
icon: "error",
|
|
});
|
|
}
|
|
if (Object.values(formData).some((item) => !item)) {
|
|
return uni.showToast({
|
|
title: '信息填写完整',
|
|
icon: "error",
|
|
});
|
|
}
|
|
}
|
|
const showHandle = () => {
|
|
show.value = false
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.main {
|
|
height: 100vh;
|
|
width: 100%;
|
|
background-image: url('https://cdns.fontree.cn/fonchain-main/prod/image/1833/avatar/16968647-fc99-46fe-b95c-620c55b7646f.png');
|
|
background-size: 100%;
|
|
padding: 0 32rpx 38rpx 32rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
box-sizing: border-box;
|
|
|
|
.container {
|
|
width: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
margin-top: 32rpx;
|
|
box-sizing: border-box;
|
|
overflow-y: auto;
|
|
|
|
.title {
|
|
width: 100%;
|
|
background: url("https://cdns.fontree.cn/fonchain-main/prod/image/default/artwork/f4eff459-319c-4588-8efe-8638b5c66a4f.png") no-repeat;
|
|
background-size: cover;
|
|
height: 60rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 10rpx 20rpx;
|
|
box-sizing: border-box;
|
|
color: #fff;
|
|
}
|
|
|
|
.card {
|
|
margin-top: 20rpx;
|
|
width: 100%;
|
|
height: 190rpx;
|
|
background-color: #fff;
|
|
border-radius: 24rpx;
|
|
padding: 32rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
box-sizing: border-box;
|
|
color: black;
|
|
|
|
.card-item {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.name {
|
|
width: 200rpx;
|
|
border-right: 1rpx solid #BBC5E0;
|
|
}
|
|
|
|
}
|
|
|
|
.title-detail {
|
|
margin-top: 20rpx;
|
|
width: 100%;
|
|
height: 190rpx;
|
|
background-color: #B1292E;
|
|
border-radius: 24rpx;
|
|
padding: 32rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
box-sizing: border-box;
|
|
|
|
.item {
|
|
display: flex;
|
|
color: #fff;
|
|
align-items: center;
|
|
font-size: 28rpx;
|
|
|
|
.name {
|
|
width: 200rpx;
|
|
border-right: 1rpx solid #fff;
|
|
}
|
|
|
|
.code {
|
|
flex: 1;
|
|
margin-left: 20rpx;
|
|
color: #000000;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
|
|
.inputCode {
|
|
width: 250rpx;
|
|
}
|
|
}
|
|
|
|
.stepper {
|
|
flex: 1;
|
|
margin-left: 20rpx;
|
|
color: #000000;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.time {
|
|
flex: 1;
|
|
width: 100%;
|
|
display: flex;
|
|
margin-left: 20rpx;
|
|
color: #000000;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
}
|
|
}
|
|
|
|
.line {
|
|
margin: 30rpx 0;
|
|
width: 100%;
|
|
border-bottom: 1rpx #BBC5E0 dashed;
|
|
}
|
|
}
|
|
|
|
:deep(.stepper--flex) {
|
|
width: 130rpx !important;
|
|
}
|
|
|
|
}
|
|
</style> |