index.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <template>
  2. <div class="material-dashboard app-container">
  3. <!-- 标题 -->
  4. <h2 style="margin-bottom: 20px;">物资数量概览</h2>
  5. <!-- 库存统计卡片 -->
  6. <div class="stats">
  7. <el-card v-for="item in materials" :key="item.name" class="stat-card" shadow="hover">
  8. <div class="title">{{ item.name }}</div>
  9. <div class="count" :class="{ low: item.count < 20 }">{{ item.count }}</div>
  10. <div class="status" v-if="item.count < 20">⚠ 库存不足,请及时补充</div>
  11. </el-card>
  12. </div>
  13. <!-- 柱状图展示 -->
  14. <el-card style="margin-top: 30px;" shadow="always">
  15. <div slot="header">物资数量分布</div>
  16. <div id="materialChart" style="height: 400px;"></div>
  17. </el-card>
  18. <!-- 折线图展示 -->
  19. <el-card style="margin-top: 30px;" shadow="always">
  20. <div slot="header">近7天物资消耗趋势</div>
  21. <div id="trendChart" style="height: 400px;"></div>
  22. </el-card>
  23. </div>
  24. </template>
  25. <script>
  26. import * as echarts from "echarts";
  27. export default {
  28. name: "MaterialDashboard",
  29. data() {
  30. return {
  31. // 库存死数据
  32. materials: [
  33. { name: "武器", count: 35 },
  34. { name: "弹药", count: 12 }, // 库存不足
  35. { name: "装备", count: 50 },
  36. { name: "物资", count: 18 }, // 库存不足
  37. { name: "其他", count: 42 },
  38. ],
  39. // 近7天消耗死数据
  40. trendData: {
  41. dates: ["8-28", "8-29", "8-30", "8-31", "9-1", "9-2", "9-3"],
  42. 武器: [5, 3, 6, 2, 4, 5, 3],
  43. 弹药: [10, 8, 12, 6, 7, 11, 9],
  44. 装备: [2, 1, 3, 2, 1, 2, 2],
  45. 物资: [7, 6, 8, 5, 9, 7, 8],
  46. 其他: [3, 4, 2, 5, 3, 4, 3],
  47. },
  48. };
  49. },
  50. mounted() {
  51. this.initChart();
  52. this.initTrendChart();
  53. },
  54. methods: {
  55. // 柱状图
  56. initChart() {
  57. const chart = echarts.init(document.getElementById("materialChart"));
  58. chart.setOption({
  59. tooltip: { trigger: "axis" },
  60. xAxis: {
  61. type: "category",
  62. data: this.materials.map((m) => m.name),
  63. },
  64. yAxis: { type: "value" },
  65. series: [
  66. {
  67. name: "数量",
  68. type: "bar",
  69. data: this.materials.map((m) => m.count),
  70. itemStyle: {
  71. color: (params) => {
  72. return params.data < 20 ? "#ff4d4f" : "#1890ff"; // 库存不足显示红色
  73. },
  74. },
  75. },
  76. ],
  77. });
  78. },
  79. // 折线图
  80. initTrendChart() {
  81. const chart = echarts.init(document.getElementById("trendChart"));
  82. chart.setOption({
  83. tooltip: { trigger: "axis" },
  84. legend: { data: Object.keys(this.trendData).filter((k) => k !== "dates") },
  85. xAxis: {
  86. type: "category",
  87. data: this.trendData.dates,
  88. },
  89. yAxis: { type: "value" },
  90. series: Object.keys(this.trendData)
  91. .filter((k) => k !== "dates")
  92. .map((key) => ({
  93. name: key,
  94. type: "line",
  95. smooth: true,
  96. data: this.trendData[key],
  97. })),
  98. });
  99. },
  100. },
  101. };
  102. </script>
  103. <style scoped>
  104. .stats {
  105. display: flex;
  106. gap: 20px;
  107. flex-wrap: wrap;
  108. }
  109. .stat-card {
  110. width: 200px;
  111. text-align: center;
  112. padding: 15px;
  113. }
  114. .stat-card .title {
  115. font-size: 18px;
  116. margin-bottom: 10px;
  117. }
  118. .stat-card .count {
  119. font-size: 32px;
  120. font-weight: bold;
  121. color: #1890ff;
  122. }
  123. .stat-card .count.low {
  124. color: #ff4d4f;
  125. }
  126. .stat-card .status {
  127. margin-top: 5px;
  128. color: #ff4d4f;
  129. font-size: 14px;
  130. }
  131. </style>