From 3653db5756ad6ae89eb573409a3b0fa9926175a5 Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期三, 05 六月 2024 17:37:58 +0800
Subject: [PATCH] 原型制作,新增现场巡查和区县巡查统计

---
 src/views/HomeView.vue                           |    6 
 src/views/inspection/TaskTrack.vue               |   69 +++++
 src/views/management/ManagementView.vue          |   11 
 src/assets/styles/index.scss                     |   16 +
 src/assets/styles/element/index.scss             |    7 
 src/views/inspection/ProblemTrack.vue            |   39 +++
 src/assets/styles/base.scss                      |  117 +++++++++
 src/views/management/TaskStats.vue               |   59 ++++
 src/components.d.ts                              |   11 
 src/components/inspection/TaskNode.vue           |   35 ++
 src/components/inspection/SubtaskItem.vue        |   59 ++++
 src/assets/fonts/SOURCEHANSANSCN-MEDIUM.OTF      |    0 
 src/assets/styles/text.scss                      |    0 
 src/views/inspection/InspectionView.vue          |   20 +
 src/assets/styles/layout.scss                    |   14 +
 src/assets/fonts/SIMHEI.TTF                      |    0 
 src/components/inspection/TaskItem.vue           |  108 +++++++++
 src/views/main/MonitorView.vue                   |   33 ++
 src/components/core/CoreHeader.vue               |   14 +
 src/views/visualization/VisualizationView.vue    |   12 
 src/App.vue                                      |    8 
 src/components/inspection/SubtaskExamineItem.vue |   59 ++++
 22 files changed, 667 insertions(+), 30 deletions(-)

diff --git a/src/App.vue b/src/App.vue
index 8f6d93e..afb2f2e 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -11,4 +11,10 @@
   </el-config-provider>
 </template>
 
-<style scoped></style>
+<style>
+html,
+body {
+  margin: 0;
+  font-family: '鎬濇簮榛戜綋';
+}
+</style>
diff --git a/src/assets/fonts/SIMHEI.TTF b/src/assets/fonts/SIMHEI.TTF
new file mode 100644
index 0000000..5bd4687
--- /dev/null
+++ b/src/assets/fonts/SIMHEI.TTF
Binary files differ
diff --git a/src/assets/fonts/SOURCEHANSANSCN-MEDIUM.OTF b/src/assets/fonts/SOURCEHANSANSCN-MEDIUM.OTF
new file mode 100644
index 0000000..53e03e0
--- /dev/null
+++ b/src/assets/fonts/SOURCEHANSANSCN-MEDIUM.OTF
Binary files differ
diff --git a/src/assets/styles/base.scss b/src/assets/styles/base.scss
new file mode 100644
index 0000000..8f27fcf
--- /dev/null
+++ b/src/assets/styles/base.scss
@@ -0,0 +1,117 @@
+/************************************** font size **************************************/
+$fontsize: (
+  s: var(--el-font-size-small),
+  b: var(--el-font-size-base),
+  m: var(--el-font-size-medium),
+  l: var(--el-font-size-large)
+);
+
+@each $dName, $dValue in $fontsize {
+  .f-#{$dName} {
+    font-size: #{$dValue};
+  }
+}
+
+/************************************** color **************************************/
+$colors: (
+  p: var(--el-color-primary),
+  s: var(--el-color-success),
+  w: var(--el-color-warning),
+  d: var(--el-color-danger),
+  e: var(--el-color-error),
+  i: var(--el-color-info)
+);
+
+@each $dName, $dValue in $colors {
+  .color-#{$dName} {
+    color: #{$dValue};
+  }
+  .b-color-#{$dName} {
+    background-color: #{$dValue};
+  }
+}
+
+/************************************** 鍐呭杈硅窛 **************************************/
+$direction: (
+  l: 'left',
+  t: 'top',
+  r: 'right',
+  b: 'bottom'
+);
+$size: (2, 4, 8, 10, 16);
+@each $dName, $dValue in $direction {
+  @each $i in $size {
+    .p-#{$dName}-#{$i} {
+      padding-#{$dValue}: #{$i}px;
+    }
+    .m-#{$dName}-#{$i} {
+      margin-#{$dValue}: #{$i}px;
+    }
+  }
+}
+
+@each $i in $size {
+  .p-v-#{$i} {
+    padding: #{$i}px 0;
+  }
+  .p-h-#{$i} {
+    padding: 0 #{$i}px;
+  }
+  .p-#{$i} {
+    padding: #{$i}px;
+  }
+  .m-v-#{$i} {
+    margin: #{$i}px 0;
+  }
+  .m-h-#{$i} {
+    margin: 0 #{$i}px;
+  }
+  .m-#{$i} {
+    margin: #{$i}px;
+  }
+}
+
+/************************************** 瀹介珮 **************************************/
+$csize: (
+  small: var(--el-component-size-small),
+  default: var(--el-component-size-default),
+  large: var(--el-component-size-large)
+);
+$ws: (20, 40, 50, 60, 80, 100, 120, 150, 200, 250, 300);
+@each $name, $value in $csize {
+  .w-#{$name} {
+    width: #{$value};
+  }
+  .h-#{$name} {
+    height: #{$value};
+  }
+}
+@each $i in $ws {
+  .w-#{$i} {
+    width: #{$i}px;
+  }
+  .h-#{$i} {
+    height: #{$i}px;
+  }
+}
+
+/************************************** 杈规 **************************************/
+$bsize: (
+  small: var(--el-border-radius-small),
+  base: var(--el-border-radius-base),
+  round: var(--el-border-radius-round),
+  circle: var(--el-border-radius-circle)
+);
+@each $name, $value in $bsize {
+  .border-r-#{$name} {
+    border: var(--el-border);
+    border-radius: $value;
+  }
+}
+
+/************************************** 瀵归綈 **************************************/
+.v-center {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
diff --git a/src/assets/styles/element/index.scss b/src/assets/styles/element/index.scss
new file mode 100644
index 0000000..063bc6d
--- /dev/null
+++ b/src/assets/styles/element/index.scss
@@ -0,0 +1,7 @@
+// @forward 'element-plus/theme-chalk/src/common/var.scss' with (
+//   $colors: (
+//     'primary': (
+//       'base': green
+//     )
+//   )
+// );
diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss
index e69de29..6d14fb6 100644
--- a/src/assets/styles/index.scss
+++ b/src/assets/styles/index.scss
@@ -0,0 +1,16 @@
+@use './base.scss';
+@use './text.scss';
+@use './layout.scss';
+@use './element/index.scss' as *;
+
+@font-face {
+  font-family: 'SIMHEI';
+  src: url(../fonts/SIMHEI.TTF);
+}
+
+@font-face {
+  font-family: '鎬濇簮榛戜綋';
+  src: url(../fonts/SOURCEHANSANSCN-MEDIUM.OTF);
+  font-weight: normal;
+  font-style: normal;
+}
diff --git a/src/assets/styles/layout.scss b/src/assets/styles/layout.scss
new file mode 100644
index 0000000..91e786b
--- /dev/null
+++ b/src/assets/styles/layout.scss
@@ -0,0 +1,14 @@
+:root {
+  --fy-header-height: 40px;
+  --fy-body-height: calc(100vh - var(--fy-header-height));
+}
+
+.fy-header {
+  height: var(--fy-header-height);
+  // background-color: antiquewhite;
+}
+
+.fy-body {
+  height: var(--fy-body-height);
+  // background-color: azure;
+}
diff --git a/src/assets/styles/text.scss b/src/assets/styles/text.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/assets/styles/text.scss
diff --git a/src/components.d.ts b/src/components.d.ts
index 0c63b5f..fb94fc6 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -7,10 +7,21 @@
 /* prettier-ignore */
 declare module 'vue' {
   export interface GlobalComponents {
+    CoreHeader: typeof import('./components/core/CoreHeader.vue')['default']
+    ElButton: typeof import('element-plus/es')['ElButton']
+    ElCard: typeof import('element-plus/es')['ElCard']
     ElCol: typeof import('element-plus/es')['ElCol']
     ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
+    ElProgress: typeof import('element-plus/es')['ElProgress']
     ElRow: typeof import('element-plus/es')['ElRow']
+    ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
+    ElTag: typeof import('element-plus/es')['ElTag']
+    ElText: typeof import('element-plus/es')['ElText']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
+    SubtaskExamineItem: typeof import('./components/inspection/SubtaskExamineItem.vue')['default']
+    SubtaskItem: typeof import('./components/inspection/SubtaskItem.vue')['default']
+    TaskItem: typeof import('./components/inspection/TaskItem.vue')['default']
+    TaskNode: typeof import('./components/inspection/TaskNode.vue')['default']
   }
 }
diff --git a/src/components/core/CoreHeader.vue b/src/components/core/CoreHeader.vue
new file mode 100644
index 0000000..dd8137e
--- /dev/null
+++ b/src/components/core/CoreHeader.vue
@@ -0,0 +1,14 @@
+<template>
+  <el-row class="fy-header"> 绯荤粺鏍囬銆佹椂闂淬�佸ぉ姘旂瓑淇℃伅 </el-row>
+</template>
+
+<script>
+export default {
+  props: {},
+  data() {
+    return {}
+  },
+  methods: {}
+}
+</script>
+<style scoped></style>
diff --git a/src/components/inspection/SubtaskExamineItem.vue b/src/components/inspection/SubtaskExamineItem.vue
new file mode 100644
index 0000000..52c6b41
--- /dev/null
+++ b/src/components/inspection/SubtaskExamineItem.vue
@@ -0,0 +1,59 @@
+<template>
+  <div :class="itemClass + ' p-v-4 f-s'">
+    <div>
+      <el-text class="w-200" size="default" truncated>
+        {{ name }}
+      </el-text>
+    </div>
+    <el-row justify="space-between">
+      <div>{{ type }}</div>
+      <!-- <el-text size="small"> {{ type }} </el-text> -->
+      <el-progress
+        class="w-150"
+        :percentage="(checked / total) * 100"
+        status="warning"
+        striped
+        striped-flow
+      >
+        <span>{{ checked + '/' + total }}</span>
+      </el-progress>
+    </el-row>
+  </div>
+</template>
+
+<script>
+/**
+ * 宸℃煡瀛愪换鍔¢棶棰樺鏍哥姸鎬佷俊鎭�
+ */
+export default {
+  props: {
+    index: Number,
+    name: String,
+    district: String,
+    planTime: String,
+    type: String,
+    total: Number,
+    checked: Number
+  },
+  data() {
+    return {}
+  },
+  watch: {},
+  computed: {
+    itemClass() {
+      return this.index % 2 == 0 ? 'wrapper-even' : 'wrapper-odd'
+    }
+  },
+  methods: {}
+}
+</script>
+
+<style scoped>
+.wrapper-odd {
+  background-color: aliceblue;
+}
+
+.wrapper-even {
+  /* background-color: aliceblue; */
+}
+</style>
diff --git a/src/components/inspection/SubtaskItem.vue b/src/components/inspection/SubtaskItem.vue
new file mode 100644
index 0000000..f7f0e75
--- /dev/null
+++ b/src/components/inspection/SubtaskItem.vue
@@ -0,0 +1,59 @@
+<template>
+  <div :class="itemClass + ' p-v-4 f-s'">
+    <div>
+      <!-- <el-row justify="center"> -->
+      <el-text class="w-200" size="default" truncated>
+        {{ name }}
+      </el-text>
+      <!-- </el-row> -->
+    </div>
+    <el-row justify="space-between">
+      <el-tag type="primary" size="small" effect="plain">
+        {{ district }}
+      </el-tag>
+      <div>{{ planTime }}</div>
+      <!-- <div>| {{ startTime }} | {{ endTime }}</div> -->
+      <div>{{ userName }}</div>
+      <!-- <div>{{ status }}</div> -->
+      <!-- <el-button type="primary">queding</el-button> -->
+    </el-row>
+  </div>
+</template>
+
+<script>
+/**
+ * 宸℃煡瀛愪换鍔℃墽琛岀姸鎬佷俊鎭�
+ */
+export default {
+  props: {
+    index: Number,
+    name: String,
+    district: String,
+    planTime: String,
+    startTime: String,
+    endTime: String,
+    userName: String,
+    status: String
+  },
+  data() {
+    return {}
+  },
+  watch: {},
+  computed: {
+    itemClass() {
+      return this.index % 2 == 0 ? 'wrapper-even' : 'wrapper-odd'
+    }
+  },
+  methods: {}
+}
+</script>
+
+<style scoped>
+.wrapper-odd {
+  background-color: aliceblue;
+}
+
+.wrapper-even {
+  /* background-color: aliceblue; */
+}
+</style>
diff --git a/src/components/inspection/TaskItem.vue b/src/components/inspection/TaskItem.vue
new file mode 100644
index 0000000..be50b89
--- /dev/null
+++ b/src/components/inspection/TaskItem.vue
@@ -0,0 +1,108 @@
+<template>
+  <div class="demo-progress border-r-small f-b">
+    <el-row>
+      <el-col span="8">
+        <el-progress :width="100" type="dashboard" :percentage="(finish / total) * 100">
+          <template #default="{ percentage }">
+            <span class="percentage-value">{{ percentage }}%</span>
+            <span class="percentage-label">{{ finish + '/' + total }}</span>
+          </template>
+        </el-progress>
+      </el-col>
+      <el-col span="16">
+        <div>{{ name }}</div>
+        <!-- <div>{{ planTime }}</div> -->
+        <div>{{ userName }}</div>
+        <el-row style="gap: 10px">
+          <div class="v-center" v-for="item in count" :key="item.sceneType">
+            <el-progress
+              :width="50"
+              :stroke-width="3"
+              type="dashboard"
+              :percentage="(item.finish / item.total) * 100"
+            >
+              <template #default="{ percentage }">
+                <span class="percentage-value-small">{{ percentage }}%</span>
+              </template>
+            </el-progress>
+            <div>
+              <el-text size="small">{{ item.sceneType }}</el-text>
+              <el-text size="small">{{ item.finish + '/' + item.total }}</el-text>
+            </div>
+            <div></div>
+            <!-- <div class="percentage-label-small">{{ item.sceneType }}</div> -->
+            <!-- <span class="percentage-label-small">{{ item.finish + '/' + item.total }} </span> -->
+          </div>
+        </el-row>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+/**
+ * 宸℃煡浠诲姟鍖哄煙缁熻淇℃伅
+ */
+export default {
+  props: {
+    name: String,
+    district: String,
+    planTime: String,
+    startTime: String,
+    endTime: String,
+    userName: String,
+    status: String,
+
+    count: Array
+  },
+  data() {
+    return {}
+  },
+  watch: {},
+  computed: {
+    total() {
+      let t = 0
+      this.count.forEach((c) => {
+        t += c.total
+      })
+      return t
+    },
+    finish() {
+      let t = 0
+      this.count.forEach((c) => {
+        t += c.finish
+      })
+      return t
+    }
+  },
+  methods: {}
+}
+</script>
+
+<style scoped>
+.wrapper {
+  border: var(--el-border);
+  border-radius: var(--el-border-radius-base);
+}
+
+.percentage-value {
+  display: block;
+  margin-top: 10px;
+  font-size: var(--el-font-size-base);
+}
+.percentage-value-small {
+  display: block;
+  /* margin-top: 10px; */
+  font-size: var(--el-font-size-small);
+}
+.percentage-label {
+  display: block;
+  margin-top: 10px;
+  font-size: var(--el-font-size-base);
+}
+.percentage-label-small {
+  display: block;
+  /* margin-top: 10px; */
+  font-size: var(--el-font-size-small);
+}
+</style>
diff --git a/src/components/inspection/TaskNode.vue b/src/components/inspection/TaskNode.vue
new file mode 100644
index 0000000..4d5b161
--- /dev/null
+++ b/src/components/inspection/TaskNode.vue
@@ -0,0 +1,35 @@
+<template>
+  <div>
+    <el-row justify="center">{{ title }}</el-row>
+    <div class="border-r-small f-b">
+      <div v-for="(item, i) in items" :key="title + i">
+        <slot :item="item" :index="i"></slot>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+/**
+ * 宸℃煡瀛愪换鍔¤妭鐐�
+ */
+export default {
+  props: {
+    title: String,
+    count: Number,
+    items: Array
+  },
+  data() {
+    return {}
+  },
+  watch: {},
+  methods: {}
+}
+</script>
+
+<style scoped>
+.wrapper {
+  border: var(--el-border);
+  border-radius: var(--el-border-radius-base);
+}
+</style>
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index 8384c7d..ed6c588 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -1,6 +1,8 @@
 <template>
-  <el-row> 绯荤粺鏍囬銆佹椂闂淬�佸ぉ姘旂瓑淇℃伅 </el-row>
-  <router-view></router-view>
+  <core-header></core-header>
+  <div class="fy-body">
+    <router-view></router-view>
+  </div>
 </template>
 
 <script setup></script>
diff --git a/src/views/inspection/InspectionView.vue b/src/views/inspection/InspectionView.vue
index a9d296b..d6f44b8 100644
--- a/src/views/inspection/InspectionView.vue
+++ b/src/views/inspection/InspectionView.vue
@@ -1,11 +1,17 @@
 <template>
-  <el-row>
-    <el-col :span="8">1</el-col>
-    <el-col :span="8">2</el-col>
-    <el-col :span="8">3</el-col>
-  </el-row>
+  <div class="wrapper">
+    <div>鐜板満宸℃煡</div>
+    <TaskTrack></TaskTrack>
+  </div>
 </template>
 
-<script setup></script>
+<script setup>
+import TaskTrack from '@/views/inspection/TaskTrack.vue'
+</script>
 
-<style scoped></style>
+<style scoped>
+.wrapper {
+  /* height: calc(var(--fy-body-height) / 2);
+  background-color: burlywood; */
+}
+</style>
diff --git a/src/views/inspection/ProblemTrack.vue b/src/views/inspection/ProblemTrack.vue
new file mode 100644
index 0000000..2faea00
--- /dev/null
+++ b/src/views/inspection/ProblemTrack.vue
@@ -0,0 +1,39 @@
+<template>
+  <el-card shadow="hover">
+    <div class="f-l">宸℃煡闂璺熻釜</div>
+  </el-card>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      subtaskList: []
+    }
+  },
+  watch: {},
+  methods: {},
+  mounted() {
+    let i = 0
+    while (i < 3) {
+      this.subtaskList.push({
+        guid: 'SMuheEkjswioSn7A',
+        name: '涓鐢熸�佹暟瀛楁腐椤圭洰宸℃煡',
+        district: '閲戝北鍖�',
+        planTime: '2024-06-04',
+        startTime: '2024-06-04 13:31:26',
+        endTime: '2024-06-04 13:33:37',
+        userName: '鏈辨寮�',
+        status: '宸茬粨鏉�'
+      })
+      i++
+    }
+  }
+}
+</script>
+
+<style scoped>
+.text {
+  background-color: aliceblue;
+}
+</style>
diff --git a/src/views/inspection/TaskTrack.vue b/src/views/inspection/TaskTrack.vue
new file mode 100644
index 0000000..97097a3
--- /dev/null
+++ b/src/views/inspection/TaskTrack.vue
@@ -0,0 +1,69 @@
+<template>
+  <div>
+    <el-row justify="space-evenly">
+      <!-- <div class="f-l">鐜板満宸℃煡璺熻釜锛堢幇鍦轰汉鍛樺贰鏌ユ儏鍐靛疄鏃舵帉鎻★級</div> -->
+      <!-- <SubtaskItem v-for="item in subtaskList" :key="item.guid" v-bind="item"> </SubtaskItem> -->
+      <el-col :span="4">
+        <TaskNode title="鏂颁换鍔�" :items="subtaskList" v-slot="{ item, index }">
+          <SubtaskItem v-bind="item" :index="index"> </SubtaskItem>
+        </TaskNode>
+      </el-col>
+      <el-col :span="4">
+        <TaskNode title="姝e湪鎵ц" :items="subtaskList" v-slot="{ item, index }">
+          <SubtaskItem v-bind="item" :index="index"> </SubtaskItem>
+        </TaskNode>
+      </el-col>
+      <el-col :span="4">
+        <TaskNode title="寰呭鏍�" :items="subtaskList" v-slot="{ item, index }">
+          <SubtaskExamineItem v-bind="item" :index="index" type="闂瀹℃牳"> </SubtaskExamineItem>
+        </TaskNode>
+      </el-col>
+      <el-col :span="4">
+        <TaskNode title="寰呮暣鏀�" :items="subtaskList" v-slot="{ item, index }">
+          <SubtaskExamineItem v-bind="item" :index="index" type="寰呮暣鏀�"> </SubtaskExamineItem>
+        </TaskNode>
+      </el-col>
+      <el-col :span="4">
+        <TaskNode title="寰呯‘璁�" :items="subtaskList" v-slot="{ item, index }">
+          <SubtaskExamineItem v-bind="item" :index="index" type="鏁存敼瀹℃牳"> </SubtaskExamineItem>
+        </TaskNode>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      subtaskList: []
+    }
+  },
+  watch: {},
+  methods: {},
+  mounted() {
+    let i = 0
+    while (i < 5) {
+      this.subtaskList.push({
+        guid: 'SMuheEkjswioSn7A',
+        name: '涓鐢熸�佹暟瀛楁腐椤圭洰宸℃煡涓鐢熸�佹暟瀛楁腐椤圭洰宸℃煡',
+        district: '閲戝北鍖�',
+        planTime: '2024-06-04',
+        startTime: '2024-06-04 13:31:26',
+        endTime: '2024-06-04 13:33:37',
+        userName: '鏈辨寮�',
+        status: '宸茬粨鏉�',
+        total: 4,
+        checked: 2
+      })
+      i++
+    }
+  }
+}
+</script>
+
+<style scoped>
+.text {
+  background-color: aliceblue;
+}
+</style>
diff --git a/src/views/main/MonitorView.vue b/src/views/main/MonitorView.vue
index e1fb6b2..5f35cd8 100644
--- a/src/views/main/MonitorView.vue
+++ b/src/views/main/MonitorView.vue
@@ -1,13 +1,17 @@
 <template>
   <el-row>
-    <el-col :span="8">
-      <InspectionView></InspectionView>
+    <el-col :span="16">
+      <el-scrollbar class="page-left-top">
+        <VisualizationView></VisualizationView>
+      </el-scrollbar>
+      <el-scrollbar class="page-left-bottom">
+        <InspectionView></InspectionView>
+      </el-scrollbar>
     </el-col>
-    <el-col :span="8">
-      <ManagementView></ManagementView>
-    </el-col>
-    <el-col :span="8">
-      <VisualizationView></VisualizationView>
+    <el-col :span="8" class="page-right">
+      <el-scrollbar height="var(--fy-body-height)">
+        <ManagementView></ManagementView>
+      </el-scrollbar>
     </el-col>
   </el-row>
 </template>
@@ -18,4 +22,17 @@
 import VisualizationView from '@/views/visualization/VisualizationView.vue'
 </script>
 
-<style scoped></style>
+<style scoped>
+.page-left-top {
+  height: calc(var(--fy-body-height) / 2);
+  background-color: aquamarine;
+}
+.page-left-bottom {
+  height: calc(var(--fy-body-height) / 2);
+  background-color: bisque;
+}
+
+.page-right {
+  /* background-color: aliceblue; */
+}
+</style>
diff --git a/src/views/management/ManagementView.vue b/src/views/management/ManagementView.vue
index a9d296b..681eeb0 100644
--- a/src/views/management/ManagementView.vue
+++ b/src/views/management/ManagementView.vue
@@ -1,11 +1,10 @@
 <template>
-  <el-row>
-    <el-col :span="8">1</el-col>
-    <el-col :span="8">2</el-col>
-    <el-col :span="8">3</el-col>
-  </el-row>
+  <el-row> 缁熻绠$悊 </el-row>
+  <TaskStats></TaskStats>
 </template>
 
-<script setup></script>
+<script setup>
+import TaskStats from '@/views/management/TaskStats.vue'
+</script>
 
 <style scoped></style>
diff --git a/src/views/management/TaskStats.vue b/src/views/management/TaskStats.vue
new file mode 100644
index 0000000..509ba31
--- /dev/null
+++ b/src/views/management/TaskStats.vue
@@ -0,0 +1,59 @@
+<template>
+  <div class="border-r-small">
+    <div class="f-l">鍚勭洃绠″尯鍘跨殑宸℃煡瀹屾垚鎯呭喌</div>
+    <el-row>
+      <TaskItem v-for="item in tasks" :key="item.guid" v-bind="item"></TaskItem>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      tasks: []
+    }
+  },
+  watch: {},
+  methods: {},
+  mounted() {
+    let i = 0
+    while (i < 3) {
+      this.tasks.push({
+        guid: 'SMuheEkjswioSn7A',
+        name: '2024骞�6鏈堜笂娴峰競闈欏畨鍖哄贰鏌ヤ换鍔�',
+        district: '闈欏畨鍖�',
+        planTime: '2024-06',
+        startTime: '2024-06-01 00:00:00',
+        endTime: '2024-06-30 23:59:59',
+        userName: '鏈辨寮�#閭㈠瓙鐞�',
+        status: '姝e湪鎵ц',
+        count: [
+          {
+            sceneType: '宸ュ湴',
+            total: 90,
+            finish: 45
+          },
+          {
+            sceneType: '椁愰ギ',
+            total: 90,
+            finish: 45
+          },
+          {
+            sceneType: '姹戒慨',
+            total: 90,
+            finish: 45
+          }
+        ]
+      })
+      i++
+    }
+  }
+}
+</script>
+
+<style scoped>
+.text {
+  background-color: aliceblue;
+}
+</style>
diff --git a/src/views/visualization/VisualizationView.vue b/src/views/visualization/VisualizationView.vue
index a9d296b..920b0aa 100644
--- a/src/views/visualization/VisualizationView.vue
+++ b/src/views/visualization/VisualizationView.vue
@@ -1,11 +1,11 @@
 <template>
-  <el-row>
-    <el-col :span="8">1</el-col>
-    <el-col :span="8">2</el-col>
-    <el-col :span="8">3</el-col>
-  </el-row>
+  <el-row class="wrapper"> 鍙鍖� </el-row>
 </template>
 
 <script setup></script>
 
-<style scoped></style>
+<style scoped>
+.wrapper {
+  /* background-color: aquamarine; */
+}
+</style>

--
Gitblit v1.9.3