| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888 |
- <template>
- <div class="confirm-layout">
- <!-- 顶部状态栏 -->
- <StatusBar :title="robotName" />
- <!-- 主内容区 -->
- <div class="layout-main">
- <div class="confirm-page">
- <!-- 动态背景层 -->
- <div class="bg-layer">
- <div class="bg-orb orb-1"></div>
- <div class="bg-orb orb-2"></div>
- <div class="bg-orb orb-3"></div>
- <div class="bg-grid-overlay"></div>
- </div>
- <!-- 内容区 -->
- <div class="confirm-content">
- <!-- 标题区 -->
- <div class="confirm-hero">
- <h1 class="page-title">预约信息确认</h1>
- <p class="page-subtitle">请核对预约信息,如需调整可修改被访人与来访事由</p>
- </div>
- <!-- 表单卡片 -->
- <div class="form-card">
- <!-- 预约单号:只读 -->
- <div class="form-row form-row-readonly">
- <span class="form-label">预约单号</span>
- <span class="form-value">{{ form.appointmentNo || '--' }}</span>
- </div>
- <!-- 访客姓名:只读 -->
- <div class="form-row form-row-readonly">
- <span class="form-label">访客姓名</span>
- <span class="form-value">{{ form.visitorName }}</span>
- </div>
- <!-- 身份证号:只读 -->
- <div class="form-row form-row-readonly">
- <span class="form-label">身份证号</span>
- <span class="form-value">{{ maskIdCard(form.idCardNo || appointment?.idCardNo) }}</span>
- </div>
- <!-- 手机号码:只读 -->
- <div class="form-row form-row-readonly">
- <span class="form-label">手机号码</span>
- <span class="form-value">{{ form.mobile }}</span>
- </div>
- <!-- 被访人:可编辑 -->
- <div class="form-row form-row-editable" @click="openTextModal('visitedPerson', '修改被访人', form.visitedPerson)">
- <span class="form-label">被访人</span>
- <div class="form-value-editable-wrapper">
- <span v-if="form.visitedPerson" class="form-value form-value-editable">{{ form.visitedPerson }}</span>
- <span v-else class="form-value form-value-placeholder">请输入被访人</span>
- <svg class="edit-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
- <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
- <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
- </svg>
- </div>
- </div>
- <!-- 预约时间:只读 -->
- <div class="form-row form-row-readonly">
- <span class="form-label">预约时间</span>
- <span class="form-value">{{ form.appointmentTime || '--' }}</span>
- </div>
- <!-- 来访事由:可编辑 -->
- <div class="form-row form-row-editable" @click="openReasonModal">
- <span class="form-label">来访事由</span>
- <div class="form-value-editable-wrapper">
- <span v-if="currentReasonLabel" class="form-value form-value-editable">{{ currentReasonLabel }}</span>
- <span v-else class="form-value form-value-placeholder">请选择来访事由</span>
- <svg class="edit-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
- <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
- <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
- </svg>
- </div>
- </div>
- </div>
- <!-- 表单卡片底部提示 -->
- <div class="form-hint">蓝色标记项可点击修改</div>
- <!-- 底部按钮 -->
- <div class="confirm-actions">
- <button class="btn-back" @click="goBack">
- <svg class="back-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
- <path d="M15 18l-6-6 6-6" />
- </svg>
- <span>返回核验</span>
- </button>
- <button class="btn-confirm" :disabled="loading" @click="handleConfirm">
- <span v-if="loading" class="loading-spinner"></span>
- <span v-else>确认登记</span>
- </button>
- </div>
- </div>
- </div>
- </div>
- <!-- ===== 文本编辑弹窗 ===== -->
- <Teleport to="body">
- <div v-if="showTextModal" class="modal-overlay" @click.self="closeTextModal">
- <div class="modal-card">
- <div class="modal-header">
- <h2>{{ textModalTitle }}</h2>
- </div>
- <div class="modal-input-wrapper">
- <input
- ref="textInputRef"
- v-model="tempText"
- class="modal-text-input"
- type="text"
- :placeholder="textModalPlaceholder"
- @keydown.enter="confirmTextEdit"
- />
- </div>
- <div class="modal-text-actions">
- <button class="btn-modal-cancel" @click="closeTextModal">取消</button>
- <button class="btn-modal-save" @click="confirmTextEdit">保存</button>
- </div>
- </div>
- </div>
- </Teleport>
- <!-- ===== 来访事由选项弹窗 ===== -->
- <Teleport to="body">
- <div v-if="showReasonModal" class="modal-overlay" @click.self="closeReasonModal">
- <div class="modal-card modal-reason-card">
- <div class="modal-header">
- <h2>选择来访事由</h2>
- </div>
- <div class="reason-options">
- <button
- v-for="opt in visitReasonOptions"
- :key="opt.value"
- class="reason-btn"
- :class="{ 'reason-btn-active': tempReason === opt.value }"
- @click="tempReason = opt.value"
- >
- {{ opt.label }}
- </button>
- </div>
- <div class="modal-reason-actions">
- <button class="btn-modal-cancel" @click="closeReasonModal">取消</button>
- <button class="btn-modal-save" @click="confirmReasonEdit">保存</button>
- </div>
- </div>
- </div>
- </Teleport>
- </div>
- </template>
- <script setup>
- import { ref, reactive, computed, nextTick } from 'vue'
- import { useRouter } from 'vue-router'
- import StatusBar from '@/components/StatusBar.vue'
- import { useScreenStore } from '@/stores/screen'
- import { useVisitorStore } from '@/stores/visitor'
- import { maskIdCard } from '@/utils/device'
- const router = useRouter()
- const screenStore = useScreenStore()
- const visitorStore = useVisitorStore()
- const robotName = computed(() => screenStore.screenTheme?.robotName || '迎宾巡逻机器人')
- const loading = ref(false)
- const visitReasonOptions = visitorStore.visitReasonOptions
- const appointment = visitorStore.appointmentInfo
- // 表单数据
- const form = reactive({
- appointmentNo: '',
- visitorName: '',
- idCardNo: '',
- mobile: '',
- visitedPerson: '',
- appointmentTime: '',
- visitPurpose: ''
- })
- // 初始化表单数据
- const initForm = () => {
- if (appointment) {
- form.appointmentNo = appointment.appointmentNo || ''
- form.visitorName = appointment.visitorName || ''
- form.idCardNo = appointment.idCardNo || ''
- form.mobile = appointment.mobile || ''
- form.visitedPerson = appointment.visitedPerson || ''
- form.appointmentTime = appointment.appointmentTime || ''
- form.visitPurpose = appointment.visitPurpose || appointment.visitReason || ''
- }
- }
- initForm()
- // 来访事由标签
- const currentReasonLabel = computed(() => {
- const found = visitReasonOptions.find(o => o.value === form.visitPurpose)
- return found ? found.label : ''
- })
- // ===== 文本编辑弹窗 =====
- const showTextModal = ref(false)
- const textModalField = ref('')
- const textModalTitle = ref('')
- const textModalPlaceholder = ref('')
- const tempText = ref('')
- const textInputRef = ref(null)
- const openTextModal = (field, title, currentValue) => {
- textModalField.value = field
- textModalTitle.value = title
- textModalPlaceholder.value = title.replace('修改', '请输入')
- tempText.value = currentValue
- showTextModal.value = true
- nextTick(() => {
- if (textInputRef.value) {
- textInputRef.value.focus()
- }
- })
- }
- const closeTextModal = () => {
- showTextModal.value = false
- textModalField.value = ''
- }
- const confirmTextEdit = () => {
- if (!tempText.value.trim()) {
- screenStore.showAlert({
- type: 'warning',
- message: `${textModalTitle.value.replace('修改', '')}不能为空`,
- duration: 3000
- })
- return
- }
- if (textModalField.value === 'visitedPerson') {
- form.visitedPerson = tempText.value
- }
- closeTextModal()
- }
- // ===== 来访事由选项弹窗 =====
- const showReasonModal = ref(false)
- const tempReason = ref('')
- const openReasonModal = () => {
- tempReason.value = form.visitPurpose
- showReasonModal.value = true
- }
- const closeReasonModal = () => {
- showReasonModal.value = false
- }
- const confirmReasonEdit = () => {
- if (!tempReason.value) {
- screenStore.showAlert({
- type: 'warning',
- message: '请选择来访事由',
- duration: 3000
- })
- return
- }
- form.visitPurpose = tempReason.value
- closeReasonModal()
- }
- // ===== 导航 =====
- const goBack = () => {
- router.push('/visitor/appointment')
- }
- // ===== 确认登记 =====
- const handleConfirm = async () => {
- if (loading.value) return
- // 手机号校验
- if (!form.mobile || !/^1[3-9]\d{9}$/.test(form.mobile)) {
- screenStore.showAlert({
- type: 'warning',
- message: '请输入正确的11位手机号',
- duration: 3000
- })
- return
- }
- // 被访人非空校验
- if (!form.visitedPerson || !form.visitedPerson.trim()) {
- screenStore.showAlert({
- type: 'warning',
- message: '请填写被访人姓名',
- duration: 3000
- })
- return
- }
- // 来访事由非空校验
- if (!form.visitPurpose) {
- screenStore.showAlert({
- type: 'warning',
- message: '请选择来访事由',
- duration: 3000
- })
- return
- }
- loading.value = true
- try {
- visitorStore.appointmentInfo = {
- ...visitorStore.appointmentInfo,
- ...form,
- visitReason: form.visitPurpose
- }
- await visitorStore.submitRegistration()
- router.push('/visitor/success')
- } catch (error) {
- screenStore.showAlert({
- type: 'error',
- message: '登记失败,请重试',
- duration: 3000
- })
- } finally {
- loading.value = false
- }
- }
- </script>
- <style scoped>
- /* ===== 布局结构 ===== */
- .confirm-layout {
- width: 100vw;
- height: 100vh;
- display: flex;
- flex-direction: column;
- overflow: hidden;
- background: linear-gradient(155deg, #e8f4fd 0%, #dbeafe 40%, #eff6ff 100%);
- }
- .layout-main {
- flex: 1;
- display: flex;
- flex-direction: column;
- overflow: hidden;
- }
- .confirm-page {
- flex: 1;
- display: flex;
- flex-direction: column;
- position: relative;
- overflow: hidden;
- }
- /* ===== 动态背景层 ===== */
- .bg-layer {
- position: absolute;
- inset: 0;
- overflow: hidden;
- pointer-events: none;
- z-index: 0;
- }
- .bg-orb {
- position: absolute;
- border-radius: 50%;
- filter: blur(60px);
- opacity: 0.45;
- }
- .orb-1 {
- width: 380px;
- height: 380px;
- background: radial-gradient(circle, rgba(59, 130, 246, 0.35) 0%, transparent 70%);
- top: -80px;
- right: -80px;
- animation: float1 18s ease-in-out infinite;
- }
- .orb-2 {
- width: 300px;
- height: 300px;
- background: radial-gradient(circle, rgba(99, 102, 241, 0.30) 0%, transparent 70%);
- bottom: -40px;
- left: -60px;
- animation: float2 22s ease-in-out infinite;
- }
- .orb-3 {
- width: 240px;
- height: 240px;
- background: radial-gradient(circle, rgba(14, 165, 233, 0.28) 0%, transparent 70%);
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- animation: float3 16s ease-in-out infinite;
- }
- .bg-grid-overlay {
- position: absolute;
- inset: 0;
- background-image:
- linear-gradient(rgba(147, 197, 253, 0.15) 1px, transparent 1px),
- linear-gradient(90deg, rgba(147, 197, 253, 0.15) 1px, transparent 1px);
- background-size: 48px 48px;
- mask-image: radial-gradient(ellipse 80% 80% at 50% 50%, black 40%, transparent 100%);
- -webkit-mask-image: radial-gradient(ellipse 80% 80% at 50% 50%, black 40%, transparent 100%);
- }
- @keyframes float1 {
- 0%, 100% { transform: translate(0, 0) scale(1); }
- 33% { transform: translate(-20px, 25px) scale(1.05); }
- 66% { transform: translate(15px, -15px) scale(0.96); }
- }
- @keyframes float2 {
- 0%, 100% { transform: translate(0, 0) scale(1); }
- 40% { transform: translate(25px, -20px) scale(1.08); }
- 70% { transform: translate(-10px, 15px) scale(0.95); }
- }
- @keyframes float3 {
- 0%, 100% { transform: translate(-50%, -50%) scale(1); }
- 50% { transform: translate(-45%, -55%) scale(1.1); }
- }
- /* ===== 内容区 ===== */
- .confirm-content {
- flex: 1;
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 0 32px 32px;
- position: relative;
- z-index: 1;
- overflow-y: auto;
- }
- /* ===== 标题区 ===== */
- .confirm-hero {
- text-align: center;
- margin: 28px 0 24px;
- flex-shrink: 0;
- }
- .page-title {
- font-size: 40px;
- font-weight: 900;
- color: var(--text-primary);
- margin: 0 0 10px;
- letter-spacing: 3px;
- }
- .page-subtitle {
- font-size: 20px;
- color: var(--text-secondary);
- margin: 0;
- font-weight: 500;
- }
- /* ===== 表单卡片 ===== */
- .form-card {
- width: 100%;
- max-width: 640px;
- background: rgba(255, 255, 255, 0.88);
- border-radius: 32px;
- padding: 8px 0;
- box-shadow:
- 0 24px 64px rgba(30, 64, 175, 0.10),
- 0 8px 24px rgba(0, 0, 0, 0.06);
- backdrop-filter: blur(20px);
- -webkit-backdrop-filter: blur(20px);
- border: 1px solid rgba(255, 255, 255, 0.60);
- margin-bottom: 12px;
- }
- .form-hint {
- text-align: center;
- font-size: 16px;
- color: #94a3b8;
- font-weight: 500;
- letter-spacing: 0.5px;
- margin-bottom: 16px;
- }
- .form-row {
- display: flex;
- align-items: center;
- padding: 0 32px;
- min-height: 80px;
- border-bottom: 1px solid rgba(226, 232, 240, 0.80);
- }
- .form-row:last-child {
- border-bottom: none;
- }
- .form-row-readonly {
- cursor: default;
- }
- .form-row-editable {
- cursor: pointer;
- transition: background 0.15s;
- }
- .form-row-editable:hover {
- background: rgba(59, 130, 246, 0.04);
- }
- .form-row-editable:active {
- background: rgba(59, 130, 246, 0.08);
- }
- .form-label {
- font-size: 22px;
- font-weight: 600;
- color: var(--text-secondary);
- width: 140px;
- flex-shrink: 0;
- letter-spacing: 0.5px;
- }
- .form-value {
- flex: 1;
- font-size: 24px;
- font-weight: 700;
- color: var(--text-primary);
- text-align: right;
- letter-spacing: 1px;
- }
- .form-value-editable-wrapper {
- flex: 1;
- display: flex;
- align-items: center;
- justify-content: flex-end;
- gap: 8px;
- }
- .form-value-editable {
- color: var(--primary);
- }
- .form-value-placeholder {
- color: #94a3b8;
- font-weight: 500;
- font-size: 22px;
- }
- .edit-icon {
- width: 22px;
- height: 22px;
- color: var(--primary);
- flex-shrink: 0;
- opacity: 0.7;
- transition: opacity 0.15s;
- }
- .form-row-editable:hover .edit-icon {
- opacity: 1;
- }
- /* ===== 底部按钮 ===== */
- .confirm-actions {
- display: grid;
- grid-template-columns: 1fr 1.8fr;
- gap: 16px;
- width: 100%;
- max-width: 640px;
- flex-shrink: 0;
- }
- .btn-back,
- .btn-confirm {
- height: 78px;
- font-size: 24px;
- font-weight: 800;
- border-radius: 999px;
- cursor: pointer;
- transition: all 0.22s ease;
- letter-spacing: 1.5px;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .btn-back {
- background: rgba(255, 255, 255, 0.80);
- color: var(--text-secondary);
- border: 2px solid var(--border-light);
- backdrop-filter: blur(10px);
- -webkit-backdrop-filter: blur(10px);
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06);
- gap: 8px;
- }
- .btn-back:hover {
- background: rgba(255, 255, 255, 0.95);
- border-color: var(--text-muted);
- transform: translateY(-2px);
- box-shadow: 0 12px 32px rgba(0, 0, 0, 0.10);
- }
- .btn-back:active {
- transform: scale(0.97);
- }
- .back-icon {
- width: 22px;
- height: 22px;
- flex-shrink: 0;
- }
- .btn-confirm {
- background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
- color: white;
- border: none;
- box-shadow: 0 12px 28px rgba(37, 99, 235, 0.28);
- }
- .btn-confirm:hover:not(:disabled) {
- box-shadow: 0 16px 36px rgba(37, 99, 235, 0.36);
- transform: translateY(-2px);
- }
- .btn-confirm:active {
- transform: scale(0.97);
- }
- .btn-confirm:disabled {
- background: linear-gradient(135deg, #93c5fd 0%, #60a5fa 100%);
- cursor: not-allowed;
- box-shadow: none;
- transform: none;
- }
- .loading-spinner {
- width: 26px;
- height: 26px;
- border: 3px solid rgba(255, 255, 255, 0.35);
- border-top-color: white;
- border-radius: 50%;
- animation: spin 1s linear infinite;
- }
- @keyframes spin {
- to { transform: rotate(360deg); }
- }
- /* ===== 弹窗遮罩 ===== */
- .modal-overlay {
- position: fixed;
- inset: 0;
- background: rgba(0, 0, 0, 0.50);
- backdrop-filter: blur(4px);
- -webkit-backdrop-filter: blur(4px);
- display: flex;
- align-items: center;
- justify-content: center;
- z-index: 1000;
- animation: fadeIn 0.2s ease;
- }
- @keyframes fadeIn {
- from { opacity: 0; }
- to { opacity: 1; }
- }
- /* ===== 弹窗卡片 ===== */
- .modal-card {
- width: 560px;
- background: rgba(255, 255, 255, 0.96);
- border-radius: 32px;
- padding: 40px 36px 36px;
- box-shadow:
- 0 40px 80px rgba(0, 0, 0, 0.20),
- 0 16px 40px rgba(0, 0, 0, 0.12);
- backdrop-filter: blur(20px);
- -webkit-backdrop-filter: blur(20px);
- animation: slideUp 0.22s ease;
- }
- @keyframes slideUp {
- from { transform: translateY(20px) scale(0.98); opacity: 0; }
- to { transform: translateY(0) scale(1); opacity: 1; }
- }
- /* ===== 弹窗标题 ===== */
- .modal-header {
- text-align: center;
- margin-bottom: 24px;
- }
- .modal-header h2 {
- font-size: 30px;
- font-weight: 800;
- color: var(--text-primary);
- margin: 0 0 8px;
- letter-spacing: 2px;
- }
- /* ===== 文本输入弹窗 ===== */
- .modal-input-wrapper {
- background: linear-gradient(160deg, #f0f7ff 0%, #e8f4fd 100%);
- border: 2px solid rgba(59, 130, 246, 0.18);
- border-radius: 20px;
- padding: 0 24px;
- height: 96px;
- display: flex;
- align-items: center;
- margin-bottom: 16px;
- }
- .modal-text-input {
- width: 100%;
- height: 100%;
- font-size: 30px;
- font-weight: 700;
- color: var(--text-primary);
- background: transparent;
- border: none;
- outline: none;
- letter-spacing: 1px;
- }
- .modal-text-input::placeholder {
- font-size: 26px;
- font-weight: 500;
- color: #b0bec5;
- }
- .modal-text-actions {
- display: grid;
- grid-template-columns: 1fr 1.5fr;
- gap: 14px;
- }
- /* ===== 来访事由选项弹窗 ===== */
- .modal-reason-card {
- width: 560px;
- }
- .reason-options {
- display: grid;
- grid-template-columns: repeat(2, 1fr);
- gap: 14px;
- margin-bottom: 20px;
- }
- .reason-btn {
- height: 72px;
- font-size: 22px;
- font-weight: 700;
- color: var(--text-primary);
- background: rgba(255, 255, 255, 0.80);
- border: 2px solid var(--border-light);
- border-radius: 20px;
- cursor: pointer;
- transition: all 0.18s ease;
- letter-spacing: 0.5px;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .reason-btn:hover {
- background: rgba(59, 130, 246, 0.06);
- border-color: rgba(59, 130, 246, 0.30);
- transform: translateY(-1px);
- }
- .reason-btn:active {
- transform: scale(0.97);
- }
- .reason-btn-active {
- background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
- color: white;
- border-color: transparent;
- box-shadow: 0 8px 20px rgba(37, 99, 235, 0.24);
- }
- .reason-btn-active:hover {
- background: linear-gradient(135deg, #2563eb 0%, #1e40af 100%);
- border-color: transparent;
- box-shadow: 0 10px 24px rgba(37, 99, 235, 0.30);
- }
- .modal-reason-actions {
- display: grid;
- grid-template-columns: 1fr 1.5fr;
- gap: 14px;
- }
- /* ===== 弹窗通用按钮 ===== */
- .btn-modal-cancel,
- .btn-modal-save {
- height: 72px;
- font-size: 24px;
- font-weight: 800;
- border-radius: 999px;
- cursor: pointer;
- transition: all 0.20s ease;
- letter-spacing: 1.5px;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .btn-modal-cancel {
- background: rgba(255, 255, 255, 0.80);
- color: var(--text-secondary);
- border: 2px solid var(--border-light);
- box-shadow: 0 6px 20px rgba(0, 0, 0, 0.06);
- }
- .btn-modal-cancel:hover {
- background: rgba(255, 255, 255, 0.95);
- border-color: var(--text-muted);
- transform: translateY(-1px);
- }
- .btn-modal-save {
- background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
- color: white;
- border: none;
- box-shadow: 0 10px 24px rgba(37, 99, 235, 0.26);
- }
- .btn-modal-save:hover {
- box-shadow: 0 14px 32px rgba(37, 99, 235, 0.34);
- transform: translateY(-1px);
- }
- .btn-modal-cancel:active,
- .btn-modal-save:active {
- transform: scale(0.97);
- }
- /* ===== 响应式适配 ===== */
- @media (max-height: 700px) {
- .confirm-content {
- padding: 0 24px 20px;
- }
- .confirm-hero {
- margin: 16px 0 16px;
- }
- .page-title {
- font-size: 32px;
- }
- .page-subtitle {
- font-size: 18px;
- }
- .form-row {
- min-height: 68px;
- }
- .form-label {
- font-size: 20px;
- width: 120px;
- }
- .form-value {
- font-size: 22px;
- }
- .confirm-actions {
- grid-template-columns: 1fr 1.5fr;
- }
- .btn-back,
- .btn-confirm {
- height: 68px;
- font-size: 22px;
- }
- }
- </style>
|