| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-row :gutter="16" class="mb-16"> |
| | | <el-col :span="12"> |
| | | <el-card shadow="hover"> |
| | | <div class="section-title">统一会计科目体系</div> |
| | | <el-tree |
| | | :data="accountTree" |
| | | node-key="code" |
| | | :props="{ label: 'label', children: 'children' }" |
| | | highlight-current |
| | | default-expand-all |
| | | /> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-card shadow="hover"> |
| | | <div class="section-title">凭证模板</div> |
| | | <el-table :data="voucherTemplates" border size="small"> |
| | | <el-table-column prop="name" label="模板名称" min-width="140" /> |
| | | <el-table-column prop="bizScene" label="业务场景" min-width="140" /> |
| | | <el-table-column prop="debit" label="借方科目" min-width="160" /> |
| | | <el-table-column prop="credit" label="贷方科目" min-width="160" /> |
| | | <el-table-column prop="auxDims" label="辅助核算维度" min-width="180"> |
| | | <template #default="scope"> |
| | | <el-space wrap> |
| | | <el-tag v-for="dim in scope.row.auxDims" :key="dim" size="small" type="info">{{ dim }}</el-tag> |
| | | </el-space> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | <div style="padding: 20px;"> |
| | | <!-- 页面标题和筛选条件 --> |
| | | <div class="w-full md:w-auto flex items-center gap-3" style="margin-bottom: 20px;"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | type="daterange" |
| | | format="YYYY-MM-DD" |
| | | value-format="YYYY-MM-DD" |
| | | range-separator="至" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | clearable |
| | | @change="handleDateChange" |
| | | class="w-full md:w-auto" |
| | | style="margin-right: 30px;" |
| | | /> |
| | | |
| | | <el-row :gutter="16" class="mb-16"> |
| | | <el-col :span="12"> |
| | | <el-card shadow="hover"> |
| | | <div class="section-title">业务流程 → 凭证自动生成</div> |
| | | <div class="toolbar"> |
| | | <el-text type="info">演示数据仅用于展示结构与字段</el-text> |
| | | </div> |
| | | <el-table :data="generatedVouchers" border size="small"> |
| | | <el-table-column prop="date" label="日期" width="110" /> |
| | | <el-table-column prop="bizScene" label="业务场景" min-width="120" /> |
| | | <el-table-column prop="summary" label="摘要" min-width="160" /> |
| | | <el-table-column prop="amount" label="金额(¥)" width="110" /> |
| | | <el-table-column prop="status" label="状态" width="100"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.status === '已生成' ? 'success' : 'warning'">{{ scope.row.status }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-card shadow="hover"> |
| | | <div class="section-title">多维辅助核算</div> |
| | | <div class="dims"> |
| | | <el-tag type="success">客户</el-tag> |
| | | <el-tag type="warning">项目</el-tag> |
| | | <el-tag type="info">部门</el-tag> |
| | | <el-tag type="primary">管理员</el-tag> |
| | | </div> |
| | | <el-table :data="auxSummary" size="small" border> |
| | | <el-table-column prop="dimension" label="维度" width="100" /> |
| | | <el-table-column prop="category" label="类别" min-width="140" /> |
| | | <el-table-column prop="debit" label="借方(本期)" width="110" /> |
| | | <el-table-column prop="credit" label="贷方(本期)" width="110" /> |
| | | <el-table-column prop="balance" label="余额" width="100" /> |
| | | </el-table> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | <!-- 设备类型筛选 --> |
| | | <el-select |
| | | v-model="equipmentType" |
| | | placeholder="设备类型" |
| | | clearable |
| | | @change="handleFilterChange" |
| | | style="margin-right: 20px; width: 150px;" |
| | | > |
| | | <el-option |
| | | v-for="item in equipmentTypeOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | |
| | | <el-row :gutter="16" class="mb-16"> |
| | | <el-col :span="12"> |
| | | <el-card shadow="hover"> |
| | | <div class="section-title">结账任务(月/季/年)</div> |
| | | <div class="toolbar"> |
| | | <el-space> |
| | | <el-button size="small" @click="runClose('月结')">执行月结</el-button> |
| | | <el-button size="small" @click="runClose('季报')">执行季报</el-button> |
| | | <el-button size="small" @click="runClose('年度结账')">执行年度结账</el-button> |
| | | </el-space> |
| | | </div> |
| | | <el-timeline style="margin-top: 6px;"> |
| | | <el-timeline-item |
| | | v-for="item in closingTasks" |
| | | :key="item.id" |
| | | :type="item.type" |
| | | :timestamp="item.time" |
| | | placement="top" |
| | | > |
| | | <div class="close-item"> |
| | | <div class="title">{{ item.name }}</div> |
| | | <el-tag :type="item.status === '完成' ? 'success' : 'info'" size="small">{{ item.status }}</el-tag> |
| | | <el-button |
| | | type="primary" |
| | | icon="Refresh" |
| | | @click="resetFilters" |
| | | size="default" |
| | | > |
| | | 重置 |
| | | </el-button> |
| | | </div> |
| | | |
| | | <main class="container mx-auto px-4 pb-10"> |
| | | <!-- 固定资产指标卡片 --> |
| | | <div class="grid-container"> |
| | | <!-- 设备总数 --> |
| | | <el-card class="bg2"> |
| | | <p>设备总数</p> |
| | | <h3> |
| | | {{ assetInfo.totalEquipment }} |
| | | </h3> |
| | | </el-card> |
| | | |
| | | <!-- 资产原值 --> |
| | | <el-card class="bg3"> |
| | | <p>资产原值</p> |
| | | <h3> |
| | | ¥{{ assetInfo.totalOriginalValue }} |
| | | </h3> |
| | | </el-card> |
| | | |
| | | <!-- 累计折旧 --> |
| | | <el-card class="bg4"> |
| | | <p>累计折旧</p> |
| | | <h3> |
| | | ¥{{ assetInfo.totalDepreciation }} |
| | | </h3> |
| | | </el-card> |
| | | |
| | | <!-- 净值 --> |
| | | <el-card class="bg5"> |
| | | <p>净值</p> |
| | | <h3> |
| | | ¥{{ assetInfo.totalNetValue }} |
| | | </h3> |
| | | </el-card> |
| | | </div> |
| | | |
| | | <!-- 固定资产统计图表 --> |
| | | <div class="grid-layout"> |
| | | <!-- 按设备类型统计 --> |
| | | <el-card style="margin-bottom: 20px;"> |
| | | <h2 class="section-title">设备类型分布</h2> |
| | | <div class="echarts"> |
| | | <Echarts |
| | | :legend="typeDistributionLegend" |
| | | :chartStyle="chartStylePie" |
| | | :series="typeDistributionSeries" |
| | | :tooltip="pieTooltip" |
| | | style="height: 260px; width: 35%;"> |
| | | <div class="chart-num"> |
| | | <span style="font-size: 22px;">设备类型</span> |
| | | <span style="font-size: 36px; font-weight: 500; font-family: 'MyCustomFont', sans-serif;">{{ assetInfo.totalEquipment }}</span> |
| | | </div> |
| | | </el-timeline-item> |
| | | </el-timeline> |
| | | </Echarts> |
| | | <Echarts |
| | | ref="chart" |
| | | :chartStyle="chartStyle" |
| | | :grid="grid" |
| | | :legend="lineLegend" |
| | | :series="typeDistributionLineSeries" |
| | | :tooltip="tooltip" |
| | | :xAxis="xAxis" |
| | | :yAxis="yAxis" |
| | | style="height: 260px; width: 64%;"></Echarts> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-card shadow="hover"> |
| | | <div class="section-title">审计留痕与审批权限</div> |
| | | <el-table :data="auditTrail" border size="small"> |
| | | <el-table-column prop="time" label="时间" width="160" /> |
| | | <el-table-column prop="action" label="动作" min-width="160" /> |
| | | <el-table-column prop="bizScene" label="关联业务" min-width="140" /> |
| | | <el-table-column prop="role" label="执行角色" width="120" /> |
| | | <el-table-column prop="result" label="结果" width="100"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.result === '通过' ? 'success' : (scope.row.result === '驳回' ? 'danger' : 'info')"> |
| | | {{ scope.row.result }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | <!-- 设备台账表格 --> |
| | | <el-card style="margin-bottom: 20px;"> |
| | | <el-table |
| | | :data="equipmentList" |
| | | stripe |
| | | style="width: 100%" |
| | | :header-cell-style="{ background: '#f5f7fa', color: '#606266' }" |
| | | > |
| | | <el-table-column prop="id" label="资产编号" width="120" /> |
| | | <el-table-column prop="deviceName" label="设备名称" width="150" /> |
| | | <el-table-column prop="deviceModel" label="型号规格" width="150" /> |
| | | <el-table-column prop="supplierName" label="供应商" width="120" /> |
| | | <el-table-column prop="unit" label="单位" width="120" /> |
| | | <el-table-column prop="number" label="数量" width="120" /> |
| | | <el-table-column prop="originalValue" label="原值(元)" width="120"> |
| | | <template #default="{ row }"> |
| | | ¥{{ formatCurrency(row.taxIncludingPriceTotal) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="depreciation" label="累计折旧(元)" width="140"> |
| | | <template #default="{ row }"> |
| | | ¥{{ formatCurrency(row.taxIncludingPriceTotal-row.unTaxIncludingPriceTotal) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="netValue" label="净值(元)" width="120"> |
| | | <template #default="{ row }"> |
| | | ¥{{ formatCurrency(row.unTaxIncludingPriceTotal) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="status" label="状态" width="100"> |
| | | <template #default="{ row }"> |
| | | <el-tag |
| | | :type="getStatusTagType(row.status)" |
| | | size="small" |
| | | > |
| | | {{ row.status }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <!-- 分页 --> |
| | | <div class="pagination-container"> |
| | | <el-pagination |
| | | @size-change="handleSizeChange" |
| | | @current-change="handleCurrentChange" |
| | | :current-page="pagination.currentPage" |
| | | :page-sizes="[10, 20, 50, 100]" |
| | | :page-size="pagination.pageSize" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :total="pagination.total" |
| | | /> |
| | | </div> |
| | | </el-card> |
| | | </main> |
| | | |
| | | </div> |
| | | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref } from 'vue' |
| | | import { ref, computed, onMounted, reactive } from 'vue'; |
| | | import 'element-plus/dist/index.css'; |
| | | import Echarts from "@/components/Echarts/echarts.vue"; |
| | | import { getLedgerPage, getAssetInfo } from "@/api/equipmentManagement/ledger"; |
| | | import dayjs from "dayjs"; |
| | | |
| | | // 科目树(示例) |
| | | const accountTree = ref([ |
| | | { code: '1001', label: '资产', children: [ |
| | | { code: '100101', label: '库存现金' }, |
| | | { code: '100102', label: '银行存款' }, |
| | | { code: '1122', label: '应收账款' }, |
| | | { code: '1601', label: '固定资产' }, |
| | | ]}, |
| | | { code: '2001', label: '负债', children: [ |
| | | { code: '2202', label: '应付账款' }, |
| | | { code: '2241', label: '其他应付款' }, |
| | | ]}, |
| | | { code: '3001', label: '所有者权益', children: [ |
| | | { code: '3103', label: '本年利润' }, |
| | | ]}, |
| | | { code: '4001', label: '成本费用', children: [ |
| | | { code: '5601', label: '制造费用' }, |
| | | { code: '6602', label: '管理费用' }, |
| | | ]}, |
| | | ]) |
| | | // 筛选条件 |
| | | const dateRange = ref(null); |
| | | const equipmentType = ref(''); |
| | | |
| | | // 凭证模板(示例) |
| | | const voucherTemplates = ref([ |
| | | { name: '销售收入确认', bizScene: '销售出库', debit: '1122 应收账款', credit: '6001 主营业务收入', auxDims: ['客户','项目'] }, |
| | | { name: '采购应付确认', bizScene: '采购入库', debit: '1403 在途物资', credit: '2202 应付账款', auxDims: ['项目','部门'] }, |
| | | { name: '费用报销', bizScene: '费用单', debit: '6602 管理费用', credit: '1002 银行存款', auxDims: ['部门'] }, |
| | | { name: '固定资产折旧', bizScene: '月末折旧', debit: '6602 管理费用', credit: '1602 累计折旧', auxDims: ['部门'] }, |
| | | ]) |
| | | |
| | | // 自动生成的凭证(示例) |
| | | const generatedVouchers = ref([ |
| | | { date: '2025-10-01', bizScene: '销售出库', summary: '确认应收与收入', amount: 128000, status: '已生成' }, |
| | | { date: '2025-10-03', bizScene: '采购入库', summary: '确认到货应付', amount: 56000, status: '已生成' }, |
| | | { date: '2025-10-05', bizScene: '费用单', summary: '办公费用报销', amount: 3200, status: '已生成' }, |
| | | ]) |
| | | // 固定资产信息 |
| | | const assetInfo = ref({ |
| | | totalEquipment: 0, |
| | | totalOriginalValue: 0, |
| | | totalDepreciation: 0, |
| | | totalNetValue: 0 |
| | | }); |
| | | |
| | | // 无模拟生成操作,仅展示静态示例数据 |
| | | // 设备列表 |
| | | const equipmentList = ref([]); |
| | | const pagination = ref({ |
| | | currentPage: 1, |
| | | pageSize: 10, |
| | | total: 0 |
| | | }); |
| | | |
| | | // 辅助核算示例汇总(无个人姓名,仅维度类别) |
| | | const auxSummary = ref([ |
| | | { dimension: '客户', category: '重点客户集合', debit: 320000, credit: 210000, balance: 110000 }, |
| | | { dimension: '项目', category: '项目A', debit: 150000, credit: 120000, balance: 30000 }, |
| | | { dimension: '部门', category: '运营中心', debit: 42000, credit: 18000, balance: 24000 }, |
| | | { dimension: '管理员', category: '系统角色', debit: 0, credit: 0, balance: 0 }, |
| | | ]) |
| | | // 图表配置 |
| | | const chartStyle = { |
| | | width: '100%', |
| | | height: '100%', |
| | | position: 'relative', |
| | | }; |
| | | |
| | | // 结账任务 |
| | | const closingTasks = ref([ |
| | | { id: 1, name: '2025年10月 月结', time: '2025-10-31 18:00', status: '完成', type: 'success' }, |
| | | { id: 2, name: '2025年Q4 季报', time: '2025-12-31 18:00', status: '计划', type: 'info' }, |
| | | { id: 3, name: '2025年度 年度结账', time: '2025-12-31 23:00', status: '计划', type: 'info' }, |
| | | ]) |
| | | const grid = { |
| | | left: '3%', |
| | | right: '4%', |
| | | bottom: '3%', |
| | | containLabel: true |
| | | }; |
| | | |
| | | function runClose(kind) { |
| | | closingTasks.value.unshift({ |
| | | id: Date.now(), |
| | | name: `${new Date().getFullYear()}年${kind}`, |
| | | time: new Date().toISOString().replace('T',' ').slice(0,16), |
| | | status: '完成', |
| | | type: 'success', |
| | | }) |
| | | } |
| | | const lineLegend = { |
| | | show: false, |
| | | }; |
| | | |
| | | // 审计留痕(不含个人姓名,仅角色/机制) |
| | | const auditTrail = ref([ |
| | | { time: '2025-10-01 09:12', action: '销售出库触发凭证生成', bizScene: '销售出库', role: '系统自动化', result: '通过' }, |
| | | { time: '2025-10-03 14:20', action: '采购入库触发应付确认', bizScene: '采购入库', role: '系统自动化', result: '通过' }, |
| | | { time: '2025-10-05 10:03', action: '费用单审批', bizScene: '费用单', role: '财务审批', result: '通过' }, |
| | | { time: '2025-10-08 16:45', action: '凭证过账', bizScene: '总账', role: '会计审核', result: '通过' }, |
| | | { time: '2025-10-31 18:05', action: '月结完成并锁账', bizScene: '总账', role: '系统自动化', result: '通过' }, |
| | | ]) |
| | | // 折线图提示框 |
| | | const tooltip = reactive({ |
| | | trigger: 'axis', |
| | | axisPointer: { |
| | | type: 'line', |
| | | lineStyle: { color: '#aaa' } |
| | | }, |
| | | // 自定义内容 |
| | | formatter: function (params) { |
| | | if (!params || !params.length) return ''; |
| | | const axisLabel = params[0].axisValueLabel || params[0].axisValue || ''; |
| | | const rows = params |
| | | .map(p => { |
| | | const colorDot = `<span style="display:inline-block;margin-right:6px;width:8px;height:8px;border-radius:50%;background:${p.color}"></span>`; |
| | | return `${colorDot}${p.seriesName}: ${p.value}`; |
| | | }) |
| | | .join('<br/>'); |
| | | return `<div>${axisLabel}</div><div>${rows}</div>`; |
| | | } |
| | | }); |
| | | |
| | | const xAxis = ref([ |
| | | { |
| | | type: 'category', |
| | | axisTick: { show: true, alignWithLabel: true }, |
| | | data: [], |
| | | }, |
| | | ]); |
| | | |
| | | const yAxis = [ |
| | | { |
| | | type: 'value', |
| | | name: '数量/金额', // 左侧y轴 |
| | | position: 'left', |
| | | min: 0, |
| | | // 坐标轴名称样式 |
| | | nameTextStyle: { |
| | | color: '#000', |
| | | fontSize: 14, |
| | | }, |
| | | } |
| | | ]; |
| | | |
| | | const chartStylePie = { |
| | | width: '100%', |
| | | height: '100%' // 设置图表容器的高度 |
| | | }; |
| | | |
| | | const pieColors = ['#F04864', '#FACC14', '#8543E0', '#1890FF', '#13C2C2', '#2FC25B']; // 可根据实际调整 |
| | | |
| | | // 饼图数据 |
| | | const typeDistributionData = ref([]); |
| | | const departmentDistributionData = ref([]); |
| | | |
| | | // 饼图图例 |
| | | const typeDistributionLegend = computed(() => ({ |
| | | show: true, |
| | | top: 'center', |
| | | left: '60%', |
| | | orient: 'vertical', |
| | | icon: 'circle', |
| | | data: typeDistributionData.value.map(item => item.name), |
| | | formatter: function(name) { |
| | | const item = typeDistributionData.value.find(i => i.name === name); |
| | | if (!item) return name; |
| | | return `${name} | ${item.count} 台 | ${item.amount}`; |
| | | }, |
| | | textStyle: { |
| | | color: '#333', |
| | | fontSize: 14, |
| | | lineHeight: 26, |
| | | } |
| | | })); |
| | | |
| | | |
| | | // 饼图系列 |
| | | const typeDistributionSeries = computed(() => [ |
| | | { |
| | | type: 'pie', |
| | | radius: ['50%', '65%'], |
| | | center: ['25%', '50%'], |
| | | avoidLabelOverlap: false, |
| | | itemStyle: { |
| | | borderColor: '#fff', |
| | | borderWidth: 2 |
| | | }, |
| | | label: { |
| | | show: false |
| | | }, |
| | | data: typeDistributionData.value, |
| | | color: pieColors |
| | | } |
| | | ]); |
| | | |
| | | // 折线图数据 |
| | | const typeDistributionLineSeries = ref([]); |
| | | |
| | | |
| | | // 饼图提示框 |
| | | const pieTooltip = reactive({ |
| | | trigger: 'item', |
| | | formatter: function(params) { |
| | | // 检查数据是否存在 |
| | | if (!params.data) return params.name; |
| | | // 拼接完整内容 |
| | | return ` |
| | | <div> |
| | | <div style="color:${params.color};font-size:16px;">●</div> |
| | | <div>${params.name}</div> |
| | | <div>数量:${params.data.count} 台</div> |
| | | <div>金额:${params.data.amount}</div> |
| | | </div> |
| | | `; |
| | | } |
| | | }); |
| | | |
| | | // 选项数据 |
| | | const equipmentTypeOptions = ref([]); |
| | | |
| | | // 获取数据 |
| | | const fetchData = async () => { |
| | | try { |
| | | // 获取固定资产汇总信息 |
| | | const assetInfoRes = await getAssetInfo({ |
| | | startDate: dateRange.value ? dateRange.value[0] : null, |
| | | endDate: dateRange.value ? dateRange.value[1] : null, |
| | | equipmentType: equipmentType.value |
| | | }); |
| | | |
| | | if (assetInfoRes.code === 200) { |
| | | assetInfo.value = assetInfoRes.data; |
| | | } |
| | | |
| | | // 获取设备列表 |
| | | const equipmentListRes = await getLedgerPage({ |
| | | current: pagination.value.currentPage, |
| | | size: pagination.value.pageSize, |
| | | startDate: dateRange.value ? dateRange.value[0] : null, |
| | | endDate: dateRange.value ? dateRange.value[1] : null, |
| | | equipmentType: equipmentType.value |
| | | }); |
| | | |
| | | if (equipmentListRes.code === 200) { |
| | | equipmentList.value = equipmentListRes.data.records; |
| | | pagination.value.total = equipmentListRes.data.total; |
| | | } |
| | | |
| | | // // 获取设备类型分布数据 |
| | | // const typeDistributionRes = await getEquipmentTypes({ |
| | | // startDate: dateRange.value ? dateRange.value[0] : null, |
| | | // endDate: dateRange.value ? dateRange.value[1] : null, |
| | | // equipmentType: equipmentType.value |
| | | // }); |
| | | // if (typeDistributionRes.code === 200) { |
| | | // typeDistributionData.value = typeDistributionRes.data.map(item => ({ |
| | | // name: item.typeName, |
| | | // value: item.count, |
| | | // count: item.count, |
| | | // amount: `¥${formatCurrency(item.totalValue)}` |
| | | // })); |
| | | // |
| | | // // 构建折线图数据 |
| | | // typeDistributionLineSeries.value = [ |
| | | // { |
| | | // name: '设备数量', |
| | | // type: 'line', |
| | | // data: typeDistributionRes.data.map(item => item.count) |
| | | // } |
| | | // ]; |
| | | // // 更新x轴数据 |
| | | // xAxis.value[0].data = typeDistributionRes.data.map(item => item.typeName); |
| | | // } |
| | | } catch (error) { |
| | | console.error('获取固定资产数据失败:', error); |
| | | } |
| | | }; |
| | | |
| | | // 初始化 |
| | | onMounted(() => { |
| | | // 获取列表数据 |
| | | fetchData(); |
| | | }); |
| | | |
| | | // 格式化货币 |
| | | const formatCurrency = (value) => { |
| | | if (!value) return '0.00'; |
| | | return Number(value).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ','); |
| | | }; |
| | | |
| | | // 获取状态标签类型 |
| | | const getStatusTagType = (status) => { |
| | | switch (status) { |
| | | case '在用': |
| | | return 'success'; |
| | | case '闲置': |
| | | return 'info'; |
| | | case '维修中': |
| | | return 'warning'; |
| | | case '报废': |
| | | return 'danger'; |
| | | default: |
| | | return 'info'; |
| | | } |
| | | }; |
| | | |
| | | // 处理日期范围变化 |
| | | const handleDateChange = (newRange) => { |
| | | dateRange.value = newRange; |
| | | fetchData(); |
| | | }; |
| | | |
| | | // 处理筛选条件变化 |
| | | const handleFilterChange = () => { |
| | | fetchData(); |
| | | }; |
| | | |
| | | // 重置筛选条件 |
| | | const resetFilters = () => { |
| | | dateRange.value = null; |
| | | equipmentType.value = ''; |
| | | fetchData(); |
| | | }; |
| | | |
| | | // 分页处理 |
| | | const handleSizeChange = (size) => { |
| | | pagination.value.pageSize = size; |
| | | fetchData(); |
| | | }; |
| | | |
| | | const handleCurrentChange = (page) => { |
| | | pagination.value.currentPage = page; |
| | | fetchData(); |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .app-container { |
| | | padding: 16px; |
| | | /* 基础样式补充 */ |
| | | :root { |
| | | --el-color-primary: #4f46e5; |
| | | } |
| | | .page-header { |
| | | margin-bottom: 12px; |
| | | h2 { margin: 0 0 6px 0; font-weight: 600; } |
| | | p { margin: 0; color: #666; } |
| | | |
| | | .el-card { |
| | | position: relative; |
| | | border-radius: 12px; |
| | | padding: 14px 10px 10px 10px; |
| | | box-shadow: 0 2px 8px #eee; |
| | | |
| | | :deep(.el-card__body) { |
| | | padding: 10px 20px !important; |
| | | } |
| | | |
| | | &.bg1 { |
| | | background: url(@/assets/icons/png/1.png) no-repeat 100% 100% !important; |
| | | } |
| | | |
| | | &.bg2 { |
| | | background: url(@/assets/icons/png/2.png) no-repeat 100% 100% !important; |
| | | } |
| | | |
| | | &.bg3 { |
| | | background: url(@/assets/icons/png/3.png) no-repeat 100% 100% !important; |
| | | } |
| | | |
| | | &.bg4 { |
| | | background: url(@/assets/icons/png/4.png) no-repeat 100% 100% !important; |
| | | } |
| | | |
| | | &.bg5 { |
| | | background: url(@/assets/icons/png/5.png) no-repeat 100% 100% !important; |
| | | } |
| | | } |
| | | |
| | | .grid-container { |
| | | /* grid 容器基础样式 */ |
| | | display: grid; |
| | | gap: 1rem; /* gap-4 对应 1rem (16px) */ |
| | | margin-bottom: 2rem; /* mb-8 对应 2rem (32px) */ |
| | | |
| | | p { |
| | | font-size: 22px; |
| | | margin-top: 0px; |
| | | color: #fff; |
| | | } |
| | | |
| | | h3 { |
| | | font-size: 36px; |
| | | font-weight: 500; |
| | | font-family: 'MyCustomFont', sans-serif; |
| | | margin: 10px 0; |
| | | color: #fff; |
| | | } |
| | | } |
| | | |
| | | /* 移动端默认样式 (grid-cols-1) */ |
| | | .grid-container { |
| | | grid-template-columns: repeat(1, minmax(0, 1fr)); |
| | | } |
| | | |
| | | /* 小屏幕及以上 (sm:grid-cols-2) */ |
| | | @media (min-width: 640px) { |
| | | .grid-container { |
| | | grid-template-columns: repeat(2, minmax(0, 1fr)); |
| | | } |
| | | } |
| | | |
| | | /* 大屏幕及以上 (lg:grid-cols-5) */ |
| | | @media (min-width: 1024px) { |
| | | .grid-container { |
| | | grid-template-columns: repeat(5, minmax(0, 1fr)); |
| | | } |
| | | } |
| | | |
| | | /* 卡片悬停效果增强 */ |
| | | .el-card:hover { |
| | | transform: translateY(-2px); |
| | | } |
| | | |
| | | .echarts { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | } |
| | | |
| | | /* 图表容器样式 */ |
| | | .el-chart { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | .section-title { |
| | | position: relative; |
| | | font-size: 18px; |
| | | color: #333; |
| | | padding-left: 10px; |
| | | margin-bottom: 10px; |
| | | font-weight: 700; |
| | | } |
| | | |
| | | .section-title::before { |
| | | content: ''; |
| | | position: absolute; |
| | | left: 0; top: 0.2em; |
| | | width: 4px; height: 1.2em; |
| | | background: #002FA7; |
| | | left: 0; |
| | | top: 0px; |
| | | content: ''; |
| | | width: 4px; |
| | | height: 18px; |
| | | background-color: #002FA7; |
| | | border-radius: 2px; |
| | | } |
| | | .mb-16 { margin-bottom: 16px; } |
| | | .toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; } |
| | | .dims { display: flex; gap: 8px; margin-bottom: 10px; } |
| | | .close-item { display: flex; align-items: center; gap: 8px; } |
| | | |
| | | .chart-num { |
| | | position: absolute; |
| | | z-index: 3; |
| | | top: 92px; |
| | | left: 92px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .pagination-container { |
| | | margin-top: 20px; |
| | | display: flex; |
| | | justify-content: center; |
| | | } |
| | | </style> |
| | | |
| | | |