| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- <template>
- <ScreenLayout :show-back-btn="true" back-text="返回登记" back-target="/visitor">
- <div class="page-appointment">
- <h1 class="page-title">预约核验</h1>
- <div class="verify-options">
- <!-- 身份证读取 -->
- <div class="verify-card" @click="handleIdCard">
- <div class="verify-icon">
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
- <rect x="2" y="4" width="20" height="16" rx="2" />
- <line x1="6" y1="8" x2="10" y2="8" />
- <line x1="6" y1="12" x2="18" y2="12" />
- <line x1="6" y1="16" x2="14" y2="16" />
- </svg>
- </div>
- <h3>身份证读取</h3>
- <p>请将身份证放置读卡区</p>
- </div>
- <!-- 手机号查询 -->
- <div class="verify-card" @click="showPhoneInput = true">
- <div class="verify-icon">
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
- <rect x="5" y="2" width="14" height="20" rx="2" ry="2" />
- <line x1="12" y1="18" x2="12.01" y2="18" />
- </svg>
- </div>
- <h3>手机号查询</h3>
- <p>输入预约手机号查询</p>
- </div>
- </div>
- <!-- 手机号输入弹窗 -->
- <div v-if="showPhoneInput" class="phone-modal">
- <div class="modal-content">
- <h2>请输入预约手机号</h2>
- <NumericKeyboard
- v-model="phoneNumber"
- label="手机号"
- placeholder="请输入11位手机号"
- :max-length="11"
- type="phone"
- @confirm="handlePhoneConfirm"
- />
- <div class="modal-actions">
- <button class="btn-cancel" @click="showPhoneInput = false">取消</button>
- <button class="btn-confirm" @click="handlePhoneConfirm(phoneNumber)">查询</button>
- </div>
- </div>
- </div>
- </div>
- </ScreenLayout>
- </template>
- <script setup>
- import { ref } from 'vue'
- import { useRouter } from 'vue-router'
- import { useScreenStore } from '@/stores/screen'
- import { useVisitorStore } from '@/stores/visitor'
- import ScreenLayout from '@/layouts/ScreenLayout.vue'
- import NumericKeyboard from '@/components/NumericKeyboard.vue'
- const router = useRouter()
- const screenStore = useScreenStore()
- const visitorStore = useVisitorStore()
- const showPhoneInput = ref(false)
- const phoneNumber = ref('')
- const handleIdCard = async () => {
- try {
- const result = await visitorStore.readIdCard()
- screenStore.showAlert({
- type: 'success',
- message: '身份证读取成功'
- })
- // 查询预约
- if (result.idCardNo) {
- try {
- await visitorStore.queryAppointment({ idCardNo: result.idCardNo })
- router.push('/visitor/appointment-confirm')
- } catch {
- screenStore.showAlert({
- type: 'info',
- message: '未查询到预约信息,请选择现场登记'
- })
- }
- }
- } catch {
- screenStore.showAlert({
- type: 'error',
- message: '身份证读取失败,请重试或选择其他方式'
- })
- }
- }
- const handlePhoneConfirm = async (phone) => {
- if (!phone || phone.length !== 11) {
- screenStore.showAlert({
- type: 'warning',
- message: '请输入正确的11位手机号'
- })
- return
- }
- try {
- await visitorStore.queryAppointment({ mobile: phone })
- showPhoneInput.value = false
- router.push('/visitor/appointment-confirm')
- } catch {
- screenStore.showAlert({
- type: 'info',
- message: '未查询到预约信息'
- })
- }
- }
- </script>
- <style scoped>
- .page-appointment {
- width: 100%;
- height: 100%;
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 20px 0;
- }
- .page-title {
- font-size: 32px;
- font-weight: 600;
- color: var(--text-primary);
- margin: 0 0 40px;
- }
- .verify-options {
- display: grid;
- grid-template-columns: repeat(2, 1fr);
- gap: 40px;
- max-width: 700px;
- width: 100%;
- }
- .verify-card {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 16px;
- padding: 40px 24px;
- background: var(--bg-card);
- border-radius: var(--radius-xl);
- box-shadow: var(--shadow-md);
- cursor: pointer;
- transition: all var(--transition-normal);
- }
- .verify-card:hover {
- transform: translateY(-6px);
- box-shadow: var(--shadow-xl);
- }
- .verify-icon {
- width: 64px;
- height: 64px;
- display: flex;
- align-items: center;
- justify-content: center;
- background: var(--primary-soft);
- border-radius: 16px;
- color: var(--primary);
- }
- .verify-icon svg {
- width: 36px;
- height: 36px;
- }
- .verify-card h3 {
- font-size: 24px;
- font-weight: 600;
- color: var(--text-primary);
- margin: 0;
- }
- .verify-card p {
- font-size: 15px;
- color: var(--text-muted);
- margin: 0;
- }
- /* 手机号输入弹窗 */
- .phone-modal {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0, 0, 0, 0.5);
- display: flex;
- align-items: center;
- justify-content: center;
- z-index: 100;
- animation: fadeIn 0.2s ease-out;
- }
- .modal-content {
- width: 90%;
- max-width: 450px;
- padding: 32px;
- background: var(--bg-card);
- border-radius: var(--radius-xl);
- box-shadow: var(--shadow-xl);
- }
- .modal-content h2 {
- font-size: 24px;
- font-weight: 600;
- color: var(--text-primary);
- text-align: center;
- margin: 0 0 24px;
- }
- .modal-actions {
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 16px;
- margin-top: 24px;
- }
- .btn-cancel,
- .btn-confirm {
- height: 56px;
- font-size: 18px;
- border-radius: var(--radius-lg);
- cursor: pointer;
- transition: all var(--transition-fast);
- }
- .btn-cancel {
- background: var(--bg-page);
- color: var(--text-secondary);
- border: 2px solid var(--border-light);
- }
- .btn-cancel:hover {
- border-color: var(--text-muted);
- }
- .btn-confirm {
- background: var(--primary);
- color: white;
- border: none;
- }
- .btn-confirm:hover {
- background: var(--primary-dark);
- }
- @keyframes fadeIn {
- from {
- opacity: 0;
- }
- to {
- opacity: 1;
- }
- }
- </style>
|