| | |
| | | <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-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-button |
| | | type="primary" |
| | | icon="Refresh" |
| | | @click="resetFilters" |
| | | size="default" |
| | | > |
| | | 重置 |
| | | </el-button> |
| | | <el-form :inline="true"> |
| | | <el-form-item label="年份"> |
| | | <el-date-picker |
| | | v-model="selectedYear" |
| | | type="year" |
| | | placeholder="请选择年份" |
| | | format="YYYY" |
| | | value-format="YYYY" |
| | | clearable |
| | | @change="fetchData()" |
| | | style="width: 200px" |
| | | :disabled-date="(date) => date.getFullYear() > new Date().getFullYear()" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button |
| | | type="primary" |
| | | icon="Refresh" |
| | | @click="resetFilters" |
| | | size="default" |
| | | > |
| | | 重置 |
| | | </el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | |
| | | <main class="container mx-auto px-4 pb-10"> |
| | |
| | | <el-card class="bg3"> |
| | | <p>资产原值</p> |
| | | <h3> |
| | | ¥{{ assetInfo.totalOriginalValue }} |
| | | ¥{{ formatCurrency(assetInfo.totalOriginalValue) }} |
| | | </h3> |
| | | </el-card> |
| | | |
| | |
| | | <el-card class="bg4"> |
| | | <p>累计折旧</p> |
| | | <h3> |
| | | ¥{{ assetInfo.totalDepreciation }} |
| | | ¥{{ formatCurrency(assetInfo.totalDepreciation) }} |
| | | </h3> |
| | | </el-card> |
| | | |
| | |
| | | <el-card class="bg5"> |
| | | <p>净值</p> |
| | | <h3> |
| | | ¥{{ assetInfo.totalNetValue }} |
| | | ¥{{ formatCurrency(assetInfo.totalNetValue) }} |
| | | </h3> |
| | | </el-card> |
| | | <!-- 负债 --> |
| | | <el-card class="bg2"> |
| | | <p>负债</p> |
| | | <h3> |
| | | ¥{{ formatCurrency(assetInfo.debt) }} |
| | | </h3> |
| | | </el-card> |
| | | <!-- 库存资产 --> |
| | | <el-card class="bg3"> |
| | | <p>库存资产</p> |
| | | <h3> |
| | | ¥{{ formatCurrency(assetInfo.inventoryValue) }} |
| | | </h3> |
| | | </el-card> |
| | | </div> |
| | |
| | | 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> |
| | | <span style="font-size: 36px; font-weight: 500; font-family: 'MyCustomFont', sans-serif;">{{ deviceTypeTotalCount }}</span> |
| | | </div> |
| | | </Echarts> |
| | | <Echarts |
| | |
| | | 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="deviceName" label="设备名称" width="250" /> |
| | | <el-table-column prop="deviceModel" label="型号规格" min-width="150" /> |
| | | <el-table-column prop="supplierName" label="供应商" min-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) }} |
| | | {{ formatCurrency(row.taxIncludingPriceTotal) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="depreciation" label="累计折旧(元)" width="140"> |
| | | <template #default="{ row }"> |
| | | ¥{{ formatCurrency(row.taxIncludingPriceTotal-row.unTaxIncludingPriceTotal) }} |
| | | {{ formatCurrency(row.deprAmount) }} |
| | | </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> |
| | | {{ formatCurrency(row.netValue) }} |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | 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 { getLedgerPage } from "@/api/equipmentManagement/ledger"; |
| | | import { getAccountingTotal, getDeviceTypeDistribution, getCalculateDepreciation } from "@/api/financialManagement/accounting"; |
| | | import dayjs from "dayjs"; |
| | | |
| | | // 筛选条件 |
| | | const dateRange = ref(null); |
| | | const equipmentType = ref(''); |
| | | const selectedYear = ref(dayjs().format('YYYY')); // 默认当前年份 |
| | | |
| | | |
| | | // 固定资产信息 |
| | | const assetInfo = ref({ |
| | | totalEquipment: 0, |
| | | totalOriginalValue: 0, |
| | | totalDepreciation: 0, |
| | | totalNetValue: 0 |
| | | totalEquipment: 0, // deviceTotal |
| | | totalOriginalValue: 0, // deviceAmount |
| | | totalDepreciation: 0, // deprAmount |
| | | totalNetValue: 0, // netValue |
| | | debt: 0, // 负债 |
| | | inventoryValue: 0 // 库存资产 |
| | | }); |
| | | |
| | | // 设备类型总数(用于图表显示) |
| | | const deviceTypeTotalCount = ref(0); |
| | | |
| | | // 设备列表 |
| | | const equipmentList = ref([]); |
| | |
| | | const fetchData = async () => { |
| | | try { |
| | | // 获取固定资产汇总信息 |
| | | const assetInfoRes = await getAssetInfo({ |
| | | const assetInfoRes = await getAccountingTotal({ |
| | | startDate: dateRange.value ? dateRange.value[0] : null, |
| | | endDate: dateRange.value ? dateRange.value[1] : null, |
| | | equipmentType: equipmentType.value |
| | | equipmentType: equipmentType.value, |
| | | year: selectedYear.value |
| | | }); |
| | | |
| | | if (assetInfoRes.code === 200) { |
| | | assetInfo.value = assetInfoRes.data; |
| | | // 映射后端字段到前端字段 |
| | | const data = assetInfoRes.data; |
| | | assetInfo.value = { |
| | | totalEquipment: data.deviceTotal || 0, // 设备总数 |
| | | totalOriginalValue: data.deviceAmount || 0, // 资产原值 |
| | | totalDepreciation: data.deprAmount || 0, // 累计折旧 |
| | | totalNetValue: data.netValue || 0, // 净值 |
| | | debt: data.debt || 0, // 负债 |
| | | inventoryValue: data.inventoryValue || 0 // 库存资产 |
| | | }; |
| | | } |
| | | |
| | | // 获取设备列表 |
| | | const equipmentListRes = await getLedgerPage({ |
| | | // 获取设备类型分布数据(饼图和折线图) |
| | | const distributionRes = await getDeviceTypeDistribution({ |
| | | startDate: dateRange.value ? dateRange.value[0] : null, |
| | | endDate: dateRange.value ? dateRange.value[1] : null, |
| | | equipmentType: equipmentType.value, |
| | | year: selectedYear.value |
| | | }); |
| | | |
| | | if (distributionRes.code === 200) { |
| | | const data = distributionRes.data; |
| | | |
| | | // 更新设备类型总数 |
| | | deviceTypeTotalCount.value = data.totalCount || 0; |
| | | |
| | | // 转换饼图数据格式 |
| | | if (data.details && data.details.length > 0) { |
| | | typeDistributionData.value = data.details.map(item => ({ |
| | | name: item.type || '', |
| | | value: Number(item.count || 0), |
| | | count: Number(item.count || 0), |
| | | amount: `¥${formatCurrency(item.amount || 0)}` |
| | | })); |
| | | } else if (data.categories && data.categories.length > 0) { |
| | | // 如果没有 details,使用 categories、countData 和 amountData 构建 |
| | | typeDistributionData.value = data.categories.map((category, index) => ({ |
| | | name: category, |
| | | value: Number(data.countData[index] || 0), |
| | | count: Number(data.countData[index] || 0), |
| | | amount: `¥${formatCurrency(data.amountData[index] || 0)}` |
| | | })); |
| | | } else { |
| | | typeDistributionData.value = []; |
| | | } |
| | | |
| | | // 更新x轴数据 |
| | | xAxis.value[0].data = data.categories || typeDistributionData.value.map(item => item.name); |
| | | |
| | | // 构建折线图数据 |
| | | typeDistributionLineSeries.value = [ |
| | | { |
| | | name: '设备数量', |
| | | type: 'line', |
| | | data: data.countData || typeDistributionData.value.map(item => item.count) |
| | | } |
| | | ]; |
| | | } |
| | | |
| | | // 获取设备列表(折旧计算数据) |
| | | const equipmentListRes = await getCalculateDepreciation({ |
| | | 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 |
| | | equipmentType: equipmentType.value, |
| | | year: selectedYear.value |
| | | }); |
| | | |
| | | if (equipmentListRes.code === 200) { |
| | | equipmentList.value = equipmentListRes.data.records; |
| | | pagination.value.total = equipmentListRes.data.total; |
| | | // 如果返回的是分页数据 |
| | | if (equipmentListRes.data.records) { |
| | | equipmentList.value = equipmentListRes.data.records; |
| | | pagination.value.total = equipmentListRes.data.total; |
| | | } else if (Array.isArray(equipmentListRes.data)) { |
| | | // 如果返回的是数组 |
| | | equipmentList.value = equipmentListRes.data; |
| | | pagination.value.total = equipmentListRes.data.length; |
| | | } else { |
| | | equipmentList.value = []; |
| | | pagination.value.total = 0; |
| | | } |
| | | } |
| | | |
| | | // // 获取设备类型分布数据 |
| | | // 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); |
| | | } |
| | |
| | | } |
| | | }; |
| | | |
| | | // 处理日期范围变化 |
| | | const handleDateChange = (newRange) => { |
| | | dateRange.value = newRange; |
| | | fetchData(); |
| | | }; |
| | | |
| | | // 处理筛选条件变化 |
| | | const handleFilterChange = () => { |
| | | fetchData(); |
| | | }; |
| | | |
| | | // 重置筛选条件 |
| | | const resetFilters = () => { |
| | | dateRange.value = null; |
| | | equipmentType.value = ''; |
| | | selectedYear.value = dayjs().format('YYYY'); // 重置为当前年份 |
| | | fetchData(); |
| | | }; |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | /* 大屏幕及以上 (lg:grid-cols-5) */ |
| | | /* 大屏幕及以上 (lg:grid-cols-6) */ |
| | | @media (min-width: 1024px) { |
| | | .grid-container { |
| | | grid-template-columns: repeat(5, minmax(0, 1fr)); |
| | | grid-template-columns: repeat(6, minmax(0, 1fr)); |
| | | } |
| | | } |
| | | |