From 0152b0200faff12f0ece317cdb32dcbcf486757d Mon Sep 17 00:00:00 2001
From: yaowanxin <3588231647@qq.com>
Date: 星期日, 04 一月 2026 14:32:03 +0800
Subject: [PATCH] 添加库存核算统计页面,调整固定资产页面图表
---
src/views/financialManagement/accounting/index.vue | 110 ++++-------
src/views/financialManagement/inventoryAccounting/index.vue | 390 +++++++++++++++++++++++++++++++++++++++++++
src/api/inventoryManagement/stockIn.js | 8
3 files changed, 436 insertions(+), 72 deletions(-)
diff --git a/src/api/inventoryManagement/stockIn.js b/src/api/inventoryManagement/stockIn.js
index 5e104f7..55cef01 100644
--- a/src/api/inventoryManagement/stockIn.js
+++ b/src/api/inventoryManagement/stockIn.js
@@ -64,5 +64,11 @@
}
-//
+//鏌ヨ搴撳瓨鍥捐〃鏁版嵁
+export function getStockInChartData() {
+ return request({
+ url: '/stockin/listReport',
+ method: 'get'
+ })
+}
diff --git a/src/views/financialManagement/accounting/index.vue b/src/views/financialManagement/accounting/index.vue
index ad998e4..f8e4a9f 100644
--- a/src/views/financialManagement/accounting/index.vue
+++ b/src/views/financialManagement/accounting/index.vue
@@ -2,43 +2,13 @@
<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>
</div>
@@ -117,9 +87,9 @@
: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">
@@ -358,33 +328,42 @@
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);
- // }
+ // 鏍规嵁 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);
}
@@ -416,17 +395,6 @@
default:
return 'info';
}
-};
-
-// 澶勭悊鏃ユ湡鑼冨洿鍙樺寲
-const handleDateChange = (newRange) => {
- dateRange.value = newRange;
- fetchData();
-};
-
-// 澶勭悊绛涢�夋潯浠跺彉鍖�
-const handleFilterChange = () => {
- fetchData();
};
// 閲嶇疆绛涢�夋潯浠�
diff --git a/src/views/financialManagement/inventoryAccounting/index.vue b/src/views/financialManagement/inventoryAccounting/index.vue
new file mode 100644
index 0000000..3acf5d9
--- /dev/null
+++ b/src/views/financialManagement/inventoryAccounting/index.vue
@@ -0,0 +1,390 @@
+<template>
+ <div class="inventory-statistics">
+ <!-- 绛涢�夎〃鍗� -->
+ <div class="filter-form">
+ <el-form :model="filterForm" inline>
+<!-- <el-form-item label="鏃堕棿鑼冨洿">-->
+<!-- <el-date-picker-->
+<!-- v-model="filterForm.dateRange"-->
+<!-- type="daterange"-->
+<!-- range-separator="鑷�"-->
+<!-- start-placeholder="寮�濮嬫棩鏈�"-->
+<!-- end-placeholder="缁撴潫鏃ユ湡"-->
+<!-- />-->
+<!-- </el-form-item>-->
+<!-- <el-form-item label="渚涘簲鍟嗗悕绉�">-->
+<!-- <el-input v-model="filterForm.supplierName" style="width: 240px" placeholder="璇疯緭鍏�" clearable prefix-icon="Search" />-->
+<!-- </el-form-item>-->
+<!-- <el-form-item label="浜у搧鍚嶇О">-->
+<!-- <el-input v-model="filterForm.productCategory" style="width: 240px" placeholder="璇疯緭鍏�" clearable prefix-icon="Search" />-->
+<!-- </el-form-item>-->
+ <el-form-item>
+ <el-button type="primary" @click="handleSearch">鏌ヨ</el-button>
+<!-- <el-button @click="handleReset">閲嶇疆</el-button>-->
+<!-- <el-button type="success" @click="handleExport">瀵煎嚭</el-button>-->
+ </el-form-item>
+ </el-form>
+ </div>
+
+ <!-- 缁熻姹囨�诲崱鐗� -->
+ <div class="summary-cards">
+ <el-row :gutter="20">
+ <el-col :span="6">
+ <el-card class="summary-card">
+ <div class="summary-item">
+ <p class="summary-title">鎬诲簱瀛樻暟閲�</p>
+ <p class="summary-value">{{ summaryData.totalInventoryCount }}</p>
+ </div>
+ </el-card>
+ </el-col>
+ <el-col :span="6">
+ <el-card class="summary-card">
+ <div class="summary-item">
+ <p class="summary-title">鎬诲簱瀛橀噾棰�</p>
+ <p class="summary-value">楼{{ summaryData.totalInventoryValue }}</p>
+ </div>
+ </el-card>
+ </el-col>
+ <el-col :span="6">
+ <el-card class="summary-card">
+ <div class="summary-item">
+ <p class="summary-title">搴撳瓨鍙樺姩鏁伴噺</p>
+ <p class="summary-value">{{ summaryData.inventoryChangeCount }}</p>
+ </div>
+ </el-card>
+ </el-col>
+ <el-col :span="6">
+ <el-card class="summary-card">
+ <div class="summary-item">
+ <p class="summary-title">搴撳瓨鍙樺姩閲戦</p>
+ <p class="summary-value">楼{{ summaryData.inventoryChangeValue }}</p>
+ </div>
+ </el-card>
+ </el-col>
+ </el-row>
+ </div>
+
+ <!-- 鍥捐〃鍖哄煙 -->
+ <div class="chart-section">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-card class="chart-card">
+ <template #header>
+ <div class="card-header">
+ <span>搴撳瓨鍒嗙被鍗犳瘮</span>
+ </div>
+ </template>
+ <div id="category-pie-chart" style="height: 400px;"></div>
+ </el-card>
+ </el-col>
+ <el-col :span="12">
+ <el-card class="chart-card">
+ <template #header>
+ <div class="card-header">
+ <span>搴撳瓨閲戦瓒嬪娍</span>
+ </div>
+ </template>
+ <div id="amount-trend-chart" style="height: 400px;"></div>
+ </el-card>
+ </el-col>
+ </el-row>
+ </div>
+
+ <!-- 鏁版嵁琛ㄦ牸 -->
+ <div class="table_list">
+ <el-table
+ :data="tableData"
+ v-loading="loading"
+ border
+ style="width: 100%"
+ :header-cell-style="{ background: '#f5f7fa', color: '#606266' }"
+ >
+ <el-table-column align="center" type="selection" width="55" />
+ <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+ <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" width="240" show-overflow-tooltip />
+ <el-table-column label="浜у搧" prop="productCategory" min-width="100" show-overflow-tooltip />
+ <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" min-width="200" show-overflow-tooltip />
+ <el-table-column label="鍗曚綅" prop="unit" width="70" show-overflow-tooltip />
+ <el-table-column label="鍏ュ簱鏁伴噺" prop="inboundNum" width="90" show-overflow-tooltip />
+ <el-table-column label="搴撳瓨鏁伴噺" prop="inboundNum0" width="90" show-overflow-tooltip />
+ <el-table-column label="鍚◣鍗曚环" prop="taxInclusiveUnitPrice" width="100" show-overflow-tooltip />
+ <el-table-column label="鍚◣鎬讳环" prop="taxInclusiveTotalPrice" width="100" show-overflow-tooltip />
+ <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" show-overflow-tooltip />
+ <el-table-column label="涓嶅惈绋庢�讳环" prop="taxExclusiveTotalPrice" width="100" show-overflow-tooltip />
+ <el-table-column label="鍏ュ簱浜�" prop="createBy" width="100" show-overflow-tooltip />
+ </el-table>
+ <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper" :page="page.current" :limit="page.size" @pagination="paginationChange" />
+ </div>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, nextTick } from 'vue'
+import * as echarts from 'echarts'
+import {getStockInChartData, getStockInPage} from "@/api/inventoryManagement/stockIn.js";
+
+// 鐘舵�佸彉閲�
+const loading = ref(false)
+const total = ref(0)
+const tableData = ref([])
+const summaryData = ref({})
+const page = reactive({
+ current: 1,
+ size: 100,
+})
+
+// 鍥捐〃瀹炰緥
+const categoryPieChart = ref(null)
+const amountTrendChart = ref(null)
+
+// 绛涢�夎〃鍗�
+const filterForm = reactive({
+ dateRange: [],
+ supplierName: '',
+ productCategory: ''
+})
+
+const paginationChange = (obj) => {
+ page.current = obj.page;
+ page.size = obj.limit;
+ loadData()
+}
+
+// 鍒濆鍖栨暟鎹�
+onMounted(() => {
+ loadSummaryData()
+ loadData()
+})
+
+// 鍔犺浇缁熻姹囨�绘暟鎹�
+const loadSummaryData = () => {
+ getStockInChartData().then(res => {
+ summaryData.value = res.data
+ })
+}
+
+// 鍔犺浇搴撳瓨鏁版嵁
+const loadData = () => {
+ loading.value = true
+ getStockInPage({ ...filterForm, ...page }).then(res => {
+ loading.value = false
+ tableData.value = res.data.records
+ total.value = res.data.total
+ console.log('res', res.data.records)
+
+ // 鏁版嵁鍔犺浇瀹屾垚鍚庢覆鏌撳浘琛�
+ nextTick(() => {
+ renderCategoryPieChart()
+ renderAmountTrendChart()
+ })
+ }).catch(() => {
+ loading.value = false
+ })
+}
+
+// 娓叉煋鍒嗙被鍗犳瘮楗煎浘
+const renderCategoryPieChart = () => {
+ if (!categoryPieChart.value) {
+ categoryPieChart.value = echarts.init(document.getElementById('category-pie-chart'))
+ }
+ // 鏍规嵁 tableData 鎸� productCategory 鍒嗙被骞惰绠� inboundNum0 鏁伴噺鎬诲拰
+ const categoryMap = tableData.value.reduce((acc, cur) => {
+ acc[cur.productCategory] = (acc[cur.productCategory] || 0) + cur.inboundNum0
+ return acc
+ }, {})
+
+ // 灏嗗垎绫荤粨鏋滆浆鎹负 ECharts 楗煎浘鎵�闇�鐨勬暟鎹牸寮�
+ const categoryData = Object.entries(categoryMap).map(([name, value]) => ({
+ name: name,
+ value: value
+ }))
+ const option = {
+ title: {
+ text: '搴撳瓨鍒嗙被鍗犳瘮',
+ left: 'center'
+ },
+ tooltip: {
+ trigger: 'item',
+ formatter: '{a} <br/>{b}: {c} ({d}%)'
+ },
+ legend: {
+ orient: 'vertical',
+ left: 'left'
+ },
+ series: [
+ {
+ name: '搴撳瓨鍒嗙被',
+ type: 'pie',
+ radius: ['40%', '70%'],
+ avoidLabelOverlap: false,
+ itemStyle: {
+ borderRadius: 10,
+ borderColor: '#fff',
+ borderWidth: 2
+ },
+ label: {
+ show: true,
+ formatter: '{b}: {d}%'
+ },
+ emphasis: {
+ label: {
+ show: true,
+ fontSize: '16',
+ fontWeight: 'bold'
+ }
+ },
+ data: categoryData
+ }
+ ]
+ }
+
+ categoryPieChart.value.setOption(option)
+}
+// 娓叉煋閲戦瓒嬪娍鎶樼嚎鍥�
+const renderAmountTrendChart = () => {
+ if (!amountTrendChart.value) {
+ amountTrendChart.value = echarts.init(document.getElementById('amount-trend-chart'))
+ }
+ // 鎸夋湀浠藉垎缁勫苟璁$畻taxInclusiveTotalPrice鎬诲拰
+ const monthlyAmounts = tableData.value.reduce((acc, cur) => {
+ const date = new Date(cur.createTime);
+ const month = date.getMonth() + 1;
+
+ // 纭繚month鍦�1-12鑼冨洿鍐�
+ if (month >= 1 && month <= 12) {
+ acc[month] = (acc[month] || 0) + cur.taxInclusiveTotalPrice;
+ }
+ return acc;
+ }, {});
+
+ // 鐢熸垚12涓湀鐨勬暟鎹紝缂哄け鏈堜唤鐢�0浠f浛
+ const amounts = [];
+ for (let i = 1; i <= 12; i++) {
+ amounts.push(monthlyAmounts[i] || 0);
+ }
+ const dates = ['1鏈�', '2鏈�', '3鏈�', '4鏈�', '5鏈�', '6鏈�', '7鏈�', '8鏈�', '9鏈�', '10鏈�', '11鏈�', '12鏈�']
+
+ const option = {
+ title: {
+ text: '搴撳瓨閲戦瓒嬪娍',
+ left: 'center'
+ },
+ tooltip: {
+ trigger: 'axis',
+ formatter: '{b}: 楼{c}'
+ },
+ xAxis: {
+ type: 'category',
+ data: dates
+ },
+ yAxis: {
+ type: 'value',
+ axisLabel: {
+ formatter: '楼{value}'
+ }
+ },
+ series: [
+ {
+ name: '搴撳瓨閲戦',
+ type: 'line',
+ data: amounts,
+ smooth: true,
+ areaStyle: {}
+ }
+ ]
+ }
+
+ amountTrendChart.value.setOption(option)
+}
+
+// 鏌ヨ鎿嶄綔
+const handleSearch = () => {
+ loadData()
+}
+
+// 閲嶇疆鎿嶄綔
+const handleReset = () => {
+ filterForm.dateRange = []
+ filterForm.supplierName = ''
+ filterForm.productCategory = ''
+ loadData()
+}
+
+// 瀵煎嚭鎿嶄綔
+const handleExport = () => {
+ console.log('瀵煎嚭鏁版嵁')
+}
+
+// 绐楀彛澶у皬鏀瑰彉鏃讹紝閲嶆柊璋冩暣鍥捐〃澶у皬
+window.addEventListener('resize', () => {
+ if (categoryPieChart.value) categoryPieChart.value.resize()
+ if (amountTrendChart.value) amountTrendChart.value.resize()
+})
+</script>
+
+<style scoped>
+.inventory-statistics {
+ padding: 20px;
+}
+
+.filter-form {
+ margin-bottom: 20px;
+}
+
+.summary-cards {
+ margin-bottom: 20px;
+}
+
+.summary-card {
+ text-align: center;
+ height: 100px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.summary-item {
+ width: 100%;
+}
+
+.summary-title {
+ font-size: 14px;
+ color: #606266;
+ margin-bottom: 5px;
+}
+
+.summary-value {
+ font-size: 24px;
+ font-weight: bold;
+ color: #303133;
+}
+
+.summary-value.warning {
+ color: #e6a23c;
+}
+
+.summary-value.danger {
+ color: #f56c6c;
+}
+
+.chart-section {
+ margin-bottom: 20px;
+}
+
+.chart-card {
+ height: 460px;
+}
+
+.card-header {
+ font-weight: bold;
+}
+
+.table_list {
+ margin-top: 20px;
+}
+
+.pagination {
+ text-align: right;
+ margin-top: 20px;
+}
+</style>
--
Gitblit v1.9.3