移动端页面适配

This commit is contained in:
2025-12-10 14:17:31 +08:00
parent 403e2c28c0
commit ffbdcb29c4
13 changed files with 3169 additions and 645 deletions

View File

@@ -66,27 +66,29 @@
<!-- 开票信息管理 -->
<div v-if="activeTab === 'info'" class="info-form-section">
<div class="info-header">
<div class="info-header" :class="{ 'mobile-header': isMobile }">
<h3 class="section-title">开票信息管理</h3>
<div class="info-actions">
<div class="info-actions" :class="{ 'mobile-actions': isMobile }">
<el-button
v-if="!isEditing"
type="primary"
size="large"
:size="isMobile ? 'default' : 'large'"
@click="startEdit"
class="edit-btn"
>
<i class="el-icon-edit"></i>
编辑信息
<span v-if="!isMobile">编辑信息</span>
<span v-else>编辑</span>
</el-button>
<el-button
type="primary"
size="large"
:size="isMobile ? 'default' : 'large'"
@click="showApplyDialog = true"
class="apply-btn"
>
<i class="el-icon-plus"></i>
申请开票
<span v-if="!isMobile">申请开票</span>
<span v-else>申请</span>
</el-button>
</div>
</div>
@@ -94,7 +96,7 @@
<!-- 只读信息显示 -->
<div v-if="!isEditing" class="info-display">
<div class="info-card">
<div class="info-row">
<div class="info-row" :class="{ 'mobile-info-row': isMobile }">
<div class="info-item">
<span class="info-label">公司名称</span>
<span class="info-value">{{ invoiceInfo.company_name || '未填写' }}</span>
@@ -104,7 +106,7 @@
<span class="info-value">{{ invoiceInfo.taxpayer_id || '未填写' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-row" :class="{ 'mobile-info-row': isMobile }">
<div class="info-item">
<span class="info-label">开户银行</span>
<span class="info-value">{{ invoiceInfo.bank_name || '未填写' }}</span>
@@ -114,7 +116,7 @@
<span class="info-value">{{ invoiceInfo.bank_account || '未填写' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-row" :class="{ 'mobile-info-row': isMobile }">
<div class="info-item">
<span class="info-label">企业地址</span>
<span class="info-value">{{ invoiceInfo.company_address || '未填写' }}</span>
@@ -124,7 +126,7 @@
<span class="info-value">{{ invoiceInfo.company_phone || '未填写' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-row" :class="{ 'mobile-info-row': isMobile }">
<div class="info-item">
<span class="info-label">接收邮箱</span>
<span class="info-value">{{ invoiceInfo.receiving_email || '未填写' }}</span>
@@ -139,10 +141,10 @@
ref="infoFormRef"
:model="editingInfo"
:rules="infoRules"
label-width="120px"
:label-width="isMobile ? '100px' : '120px'"
class="invoice-form"
>
<div class="form-row">
<div class="form-row" :class="{ 'mobile-form-row': isMobile }">
<el-form-item label="公司名称" prop="company_name">
<el-input
v-model="editingInfo.company_name"
@@ -170,7 +172,7 @@
</el-form-item>
</div>
<div class="form-row">
<div class="form-row" :class="{ 'mobile-form-row': isMobile }">
<el-form-item label="开户银行" prop="bank_name">
<el-input v-model="editingInfo.bank_name" placeholder="请输入开户银行" />
</el-form-item>
@@ -180,7 +182,7 @@
</el-form-item>
</div>
<div class="form-row">
<div class="form-row" :class="{ 'mobile-form-row': isMobile }">
<el-form-item label="企业地址" prop="company_address">
<el-input v-model="editingInfo.company_address" placeholder="请输入企业注册地址" />
</el-form-item>
@@ -190,7 +192,7 @@
</el-form-item>
</div>
<div class="form-row">
<div class="form-row" :class="{ 'mobile-form-row': isMobile }">
<el-form-item label="接收邮箱" prop="receiving_email">
<el-input v-model="editingInfo.receiving_email" placeholder="请输入发票接收邮箱" />
</el-form-item>
@@ -287,8 +289,8 @@
<div v-else class="records-list">
<div v-for="record in records" :key="record.id" class="record-item">
<div class="record-header">
<div class="record-info">
<div class="record-header" :class="{ 'mobile-record-header': isMobile }">
<div class="record-info" :class="{ 'mobile-record-info': isMobile }">
<div class="record-id">申请编号{{ record.id }}</div>
<div class="record-status" :class="getStatusClass(record.status)">
{{ getStatusText(record.status) }}
@@ -298,19 +300,19 @@
</div>
<div class="record-details">
<div class="detail-row">
<div class="detail-row" :class="{ 'mobile-detail-row': isMobile }">
<span class="detail-label">发票类型</span>
<span class="detail-value">{{ getInvoiceTypeText(record.invoice_type) }}</span>
</div>
<div class="detail-row">
<div class="detail-row" :class="{ 'mobile-detail-row': isMobile }">
<span class="detail-label">申请时间</span>
<span class="detail-value">{{ formatDateTime(record.created_at) }}</span>
</div>
<div v-if="record.processed_at" class="detail-row">
<div v-if="record.processed_at" class="detail-row" :class="{ 'mobile-detail-row': isMobile }">
<span class="detail-label">处理时间</span>
<span class="detail-value">{{ formatDateTime(record.processed_at) }}</span>
</div>
<div v-if="record.reject_reason" class="detail-row">
<div v-if="record.reject_reason" class="detail-row" :class="{ 'mobile-detail-row': isMobile }">
<span class="detail-label">拒绝原因</span>
<span class="detail-value reject-reason">{{ record.reject_reason }}</span>
</div>
@@ -319,7 +321,7 @@
<!-- 开票信息详情 -->
<div class="invoice-info-details">
<div class="info-section-title">开票信息</div>
<div class="info-grid">
<div class="info-grid" :class="{ 'mobile-info-grid': isMobile }">
<div class="info-item">
<span class="info-label">公司名称</span>
<span class="info-value">{{ record.company_name || '未填写' }}</span>
@@ -383,11 +385,17 @@
<el-dialog
v-model="showApplyDialog"
title="申请开票"
width="600px"
:width="isMobile ? '95%' : '600px'"
:close-on-click-modal="false"
:close-on-press-escape="false"
class="apply-dialog"
>
<el-form ref="applyFormRef" :model="applyForm" :rules="applyRules" label-width="120px">
<el-form
ref="applyFormRef"
:model="applyForm"
:rules="applyRules"
:label-width="isMobile ? '100px' : '120px'"
>
<el-form-item label="发票类型" prop="invoice_type">
<el-radio-group v-model="applyForm.invoice_type" class="w-full">
<el-radio label="general">增值税普通发票普票</el-radio>
@@ -489,11 +497,13 @@
<script setup>
import { invoiceApi } from '@/api'
import { ElMessage, ElMessageBox } from 'element-plus'
import FilterItem from '@/components/common/FilterItem.vue'
import FilterSection from '@/components/common/FilterSection.vue'
import { useMobileTable } from '@/composables/useMobileTable'
import { ElMessage, ElMessageBox } from 'element-plus'
const router = useRouter()
const { isMobile } = useMobileTable()
// 响应式数据
const activeTab = ref('info')
@@ -1523,6 +1533,60 @@ const resetFilters = () => {
font-weight: 600;
}
/* 移动端样式 */
.mobile-header {
flex-direction: column;
align-items: flex-start;
gap: 12px;
}
.mobile-actions {
width: 100%;
display: flex;
gap: 8px;
}
.mobile-actions .el-button {
flex: 1;
}
.mobile-info-row {
grid-template-columns: 1fr !important;
gap: 12px !important;
}
.mobile-form-row {
grid-template-columns: 1fr !important;
gap: 12px !important;
}
.mobile-info-grid {
grid-template-columns: 1fr !important;
gap: 12px !important;
}
.mobile-record-header {
flex-direction: column;
align-items: flex-start;
gap: 8px;
}
.mobile-record-info {
flex-direction: column;
align-items: flex-start;
gap: 6px;
width: 100%;
}
.mobile-detail-row {
flex-direction: column;
gap: 3px;
}
.mobile-detail-row .detail-label {
width: auto;
}
/* 响应式设计 */
@media (max-width: 768px) {
.invoice-balance-card {
@@ -1544,7 +1608,66 @@ const resetFilters = () => {
}
.invoice-tabs {
padding: 2px;
}
.tab-item {
padding: 6px 12px;
font-size: 13px;
}
.tab-item i {
font-size: 14px;
}
.section-title {
font-size: 16px;
}
.info-header {
flex-direction: column;
align-items: flex-start;
gap: 12px;
}
.info-actions {
width: 100%;
display: flex;
gap: 8px;
}
.info-actions .el-button {
flex: 1;
font-size: 13px;
}
.info-card {
padding: 16px;
}
.info-row {
grid-template-columns: 1fr;
gap: 12px;
}
.info-item {
flex-direction: column;
align-items: flex-start;
gap: 4px;
}
.info-label {
width: auto;
font-size: 13px;
}
.info-value {
font-size: 13px;
word-break: break-word;
}
.invoice-form {
padding: 12px;
}
.form-row {
@@ -1552,6 +1675,19 @@ const resetFilters = () => {
gap: 12px;
}
.form-actions {
flex-direction: column;
width: 100%;
}
.form-actions .el-button {
width: 100%;
}
.record-item {
padding: 12px;
}
.record-header {
flex-direction: column;
align-items: flex-start;
@@ -1562,6 +1698,17 @@ const resetFilters = () => {
flex-direction: column;
align-items: flex-start;
gap: 6px;
width: 100%;
}
.record-id {
font-size: 12px;
}
.record-amount {
font-size: 16px;
width: 100%;
text-align: left;
}
.detail-row {
@@ -1571,6 +1718,118 @@ const resetFilters = () => {
.detail-label {
width: auto;
font-size: 12px;
}
.detail-value {
font-size: 12px;
word-break: break-word;
}
.invoice-info-details {
padding: 12px;
}
.info-grid {
grid-template-columns: 1fr;
gap: 12px;
}
.info-item {
flex-direction: column;
align-items: flex-start;
gap: 4px;
}
.info-label {
width: auto;
font-size: 12px;
}
.info-value {
font-size: 12px;
word-break: break-word;
}
.record-actions {
width: 100%;
}
.record-actions .el-button {
width: 100%;
}
/* 弹窗样式 */
.apply-dialog :deep(.el-dialog) {
margin: 5vh auto;
max-height: 90vh;
overflow-y: auto;
}
.apply-dialog :deep(.el-dialog__body) {
padding: 16px;
max-height: calc(90vh - 120px);
overflow-y: auto;
}
.preview-content {
gap: 6px;
}
.preview-item {
flex-direction: column;
align-items: flex-start;
gap: 4px;
}
.preview-label {
width: auto;
font-size: 12px;
}
.preview-value {
font-size: 12px;
word-break: break-word;
}
.dialog-footer {
flex-direction: column;
width: 100%;
}
.dialog-footer .el-button {
width: 100%;
}
}
@media (max-width: 480px) {
.tab-item {
padding: 5px 8px;
font-size: 12px;
}
.tab-item i {
font-size: 12px;
}
.section-title {
font-size: 15px;
}
.info-card {
padding: 12px;
}
.invoice-form {
padding: 10px;
}
.record-item {
padding: 10px;
}
.invoice-info-details {
padding: 10px;
}
}
</style>