From 3443eef779d9fa60ded99ad12a72e2710a3c8f3f Mon Sep 17 00:00:00 2001
From: zouyu <2723363702@qq.com>
Date: 星期六, 10 一月 2026 14:11:43 +0800
Subject: [PATCH] Merge branch 'dev_tide' into dev_tide_sbjkxt
---
src/views/financialManagement/accounting/index.vue | 547 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 547 insertions(+), 0 deletions(-)
diff --git a/src/views/financialManagement/accounting/index.vue b/src/views/financialManagement/accounting/index.vue
new file mode 100644
index 0000000..91588fd
--- /dev/null
+++ b/src/views/financialManagement/accounting/index.vue
@@ -0,0 +1,547 @@
+<template>
+ <div style="padding: 20px;">
+ <!-- 椤甸潰鏍囬鍜岀瓫閫夋潯浠� -->
+ <div class="w-full md:w-auto flex items-center gap-3" style="margin-bottom: 20px;">
+ <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>
+ </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>
+ </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="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) }}
+ </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, computed, onMounted, reactive } from 'vue';
+import 'element-plus/dist/index.css';
+import Echarts from "@/components/Echarts/echarts.vue";
+import { getLedgerPage } from "@/api/equipmentManagement/ledger";
+import dayjs from "dayjs";
+
+// 绛涢�夋潯浠�
+const dateRange = ref(null);
+const equipmentType = ref('');
+
+
+// 鍥哄畾璧勪骇淇℃伅
+const assetInfo = ref({
+ totalEquipment: 0,
+ totalOriginalValue: 0,
+ totalDepreciation: 0,
+ totalNetValue: 0
+});
+
+// 璁惧鍒楄〃
+const equipmentList = ref([]);
+const pagination = ref({
+ currentPage: 1,
+ pageSize: 10,
+ total: 0
+});
+
+// 鍥捐〃閰嶇疆
+const chartStyle = {
+ width: '100%',
+ height: '100%',
+ position: 'relative',
+};
+
+const grid = {
+ left: '3%',
+ right: '4%',
+ bottom: '3%',
+ containLabel: true
+};
+
+const lineLegend = {
+ show: false,
+};
+
+// 鎶樼嚎鍥炬彁绀烘
+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;
+
+ // 鏍规嵁 equipmentList 鎸� deviceName 杩涜鍒嗙被缁熻
+ const deviceNameMap = {};
+ equipmentList.value.forEach(item => {
+ const deviceName = item.deviceName;
+ if (!deviceNameMap[deviceName]) {
+ deviceNameMap[deviceName] = {
+ name: deviceName,
+ count: 0,
+ totalValue: 0
+ };
+ }
+ deviceNameMap[deviceName].count += item.number || 1; // 鍋囪 number 涓鸿澶囨暟閲�
+ deviceNameMap[deviceName].totalValue += item.taxIncludingPriceTotal || 0; // 绱姞鍚◣鎬讳环
+ });
+
+ // 杞崲涓� typeDistributionData 鏍煎紡
+ typeDistributionData.value = Object.values(deviceNameMap).map(item => ({
+ name: item.name,
+ value: item.count,
+ count: item.count,
+ amount: `楼${formatCurrency(item.totalValue)}`
+ }));
+
+ // 鏇存柊x杞存暟鎹�
+ xAxis.value[0].data = typeDistributionData.value.map(item => item.name);
+
+ // 鏋勫缓鎶樼嚎鍥炬暟鎹�
+ typeDistributionLineSeries.value = [
+ {
+ name: '璁惧鏁伴噺',
+ type: 'line',
+ data: typeDistributionData.value.map(item => item.count)
+ }
+ ];
+ }
+ } 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 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">
+/* 鍩虹鏍峰紡琛ュ厖 */
+:root {
+ --el-color-primary: #4f46e5;
+}
+
+.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 {
+ position: absolute;
+ left: 0;
+ top: 0px;
+ content: '';
+ width: 4px;
+ height: 18px;
+ background-color: #002FA7;
+ border-radius: 2px;
+}
+
+.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>
--
Gitblit v1.9.3