167 lines
4.7 KiB
Vue
167 lines
4.7 KiB
Vue
<template>
|
|
<div style="display: flex; height: calc(100vh - 100px);">
|
|
<!-- 左侧导航树 -->
|
|
<div style="width: 280px; min-width: 200px; border-right: 1px solid #eee; padding: 10px 0;">
|
|
<el-tree :data="warehouseTreeData" node-key="warehouseId" :props="treeProps" highlight-current
|
|
@node-click="handleTreeNodeClick" :default-expand-all="true" style="height: 100%; overflow-y: auto;" />
|
|
</div>
|
|
<!-- 右侧图表 -->
|
|
<div style="flex: 1; height: calc(100vh - 100px); overflow-y: scroll; overflow-x: hidden;">
|
|
<el-row :gutter="10">
|
|
<el-col :span="12">
|
|
<el-card>
|
|
<template #header>
|
|
物料统计TOP10
|
|
</template>
|
|
<div style="height: 300px;">
|
|
<ChartWrapper>
|
|
<material-bar ref="materialBar" :stock-data="stockData"
|
|
:selected-warehouse-id="currentTreeNode ? currentTreeNode.warehouseId : null"
|
|
:warehouse-tree-data="warehouseTreeData" />
|
|
</ChartWrapper>
|
|
</div>
|
|
|
|
</el-card>
|
|
</el-col>
|
|
|
|
<el-col :span="12">
|
|
<el-card>
|
|
<template #header>
|
|
变动趋势
|
|
<el-date-picker style="float: right;" v-model="defaultTimeRange" type="daterange" range-separator="至"
|
|
start-placeholder="开始日期" end-placeholder="结束日期" value-format="yyyy-MM-dd" />
|
|
</template>
|
|
<div style="height: 300px;">
|
|
<ChartWrapper>
|
|
<TrendChart ref="trendChart" :warehouseId="currentTreeNode ? currentTreeNode.warehouseId : null"
|
|
:time-range="defaultTimeRange"></TrendChart>
|
|
</ChartWrapper>
|
|
</div>
|
|
</el-card>
|
|
</el-col>
|
|
</el-row>
|
|
<el-row>
|
|
<el-col :span="24">
|
|
<el-card>
|
|
<template #header>
|
|
仓库库存
|
|
</template>
|
|
<div style="height: 600px;">
|
|
<ChartWrapper>
|
|
<rea-tree ref="reaTree" :stock-data="stockData" :warehouse-tree-data="warehouseTreeData" height="600px" />
|
|
</ChartWrapper>
|
|
</div>
|
|
</el-card>
|
|
</el-col>
|
|
</el-row>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { listStock } from "@/api/wms/stock";
|
|
import { listWarehouse } from "@/api/wms/warehouse";
|
|
import ReaTree from './panels/reattree.vue';
|
|
import MaterialBar from './panels/bar.vue';
|
|
import TrendChart from './panels/trendChart.vue';
|
|
import ChartWrapper from '@/components/ChartWrapper/index.vue';
|
|
|
|
export default {
|
|
name: "StockBox",
|
|
components: {
|
|
ReaTree,
|
|
MaterialBar,
|
|
TrendChart,
|
|
ChartWrapper
|
|
},
|
|
data() {
|
|
return {
|
|
stockData: [],
|
|
warehouseData: [],
|
|
warehouseTreeData: [],
|
|
treeProps: {
|
|
label: 'warehouseName',
|
|
children: 'children',
|
|
isLeaf: 'isLeaf',
|
|
id: 'id'
|
|
},
|
|
currentTreeNode: null,
|
|
defaultTimeRange: [
|
|
new Date(new Date().setDate(new Date().getDate() - 30)).toISOString().split('T')[0],
|
|
new Date().toISOString().split('T')[0]
|
|
]
|
|
};
|
|
},
|
|
mounted() {
|
|
this.loadData();
|
|
},
|
|
methods: {
|
|
async loadData() {
|
|
try {
|
|
const [warehouseRes, stockRes] = await Promise.all([
|
|
listWarehouse(),
|
|
listStock({ pageNum: 1, pageSize: 9999 })
|
|
]);
|
|
|
|
// 处理树结构
|
|
this.warehouseTreeData = this.handleTree(warehouseRes.data, 'warehouseId', 'parentId');
|
|
this.stockData = stockRes.rows;
|
|
} catch (error) {
|
|
console.error('加载数据失败:', error);
|
|
this.$message.error('库存数据加载失败');
|
|
}
|
|
},
|
|
// 处理树结构
|
|
handleTree(data, id, parentId) {
|
|
if (!Array.isArray(data)) {
|
|
console.error('handleTree: data is not array', data);
|
|
return [];
|
|
}
|
|
|
|
const map = {};
|
|
const tree = [];
|
|
|
|
// 创建节点映射
|
|
data.forEach(item => {
|
|
map[item[id]] = { ...item, children: [] };
|
|
});
|
|
|
|
// 构建树结构
|
|
data.forEach(item => {
|
|
const node = map[item[id]];
|
|
if (!item[parentId] || item[parentId] === 0) {
|
|
tree.push(node);
|
|
} else if (map[item[parentId]]) {
|
|
map[item[parentId]].children.push(node);
|
|
}
|
|
});
|
|
|
|
return tree;
|
|
},
|
|
// 刷新数据
|
|
refresh() {
|
|
this.loadData();
|
|
},
|
|
// 导航树点击事件
|
|
handleTreeNodeClick(node) {
|
|
this.currentTreeNode = node;
|
|
if (node && node.warehouseId) {
|
|
this.$refs.reaTree.highlightNode(node.warehouseId);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
/* 图表容器样式 */
|
|
.treemap-container {
|
|
width: 100%;
|
|
height: 100%;
|
|
min-height: 600px;
|
|
}
|
|
|
|
.el-row {
|
|
margin: 10px !important;
|
|
}
|
|
</style> |