From 38f0a9145a29f570331f11505968f90bd1c08646 Mon Sep 17 00:00:00 2001
From: batman <978517621@qq.com>
Date: 星期一, 06 三月 2023 13:22:33 +0800
Subject: [PATCH] 新修改添加页面

---
 src/views/intellectInspect/inspectIndex2/components/inspectList.vue |  411 +++++++
 src/views/system/video/index.vue                                    |  250 ++++
 src/views/specialWorkSystem/specialIndex/index.vue                  | 1144 +++++++++++++++++++
 src/router/route.ts                                                 |   16 
 src/views/intellectInspect/inspectIndex2/components/unusualList.vue |  404 ++++++
 src/api/systemManage/video/index.ts                                 |   37 
 package.json                                                        |    2 
 src/views/system/video/component/videoDialog.vue                    |  158 ++
 src/views/system/user/component/userDialog.vue                      |   11 
 src/views/intellectInspect/inspectIndex2/index.vue                  | 1003 +++++++++++-----
 10 files changed, 3,082 insertions(+), 354 deletions(-)

diff --git a/package.json b/package.json
index 8b2ab23..c9b6baa 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,7 @@
 	},
 	"dependencies": {
 		"@element-plus/icons-vue": "^2.0.6",
-		"@kjgl77/datav-vue3": "^1.2.1",
+		"@kjgl77/datav-vue3": "^1.4.1",
 		"@wangeditor/editor": "^5.1.14",
 		"axios": "^0.27.2",
 		"countup.js": "^2.2.0",
diff --git a/src/api/systemManage/video/index.ts b/src/api/systemManage/video/index.ts
new file mode 100644
index 0000000..21aa37b
--- /dev/null
+++ b/src/api/systemManage/video/index.ts
@@ -0,0 +1,37 @@
+import request from '/@/utils/request';
+
+export function videoApi() {
+    return {
+        // v1
+        getVideoList: (data: any) => {
+            return request({
+                url: import.meta.env.VITE_API_URL + `/sysAdmin/camera/find/byCondition`,
+                method: 'post',
+                data: data
+            });
+        },
+
+        addVideo: (data: any) => {
+            return request({
+                url: import.meta.env.VITE_API_URL + `/sysAdmin/camera/add`,
+                method: 'post',
+                data: data
+            });
+        },
+
+        modVideo: (data: any) => {
+            return request({
+                url: import.meta.env.VITE_API_URL + `/sysAdmin/camera/mod`,
+                method: 'post',
+                data: data
+            });
+        },
+
+        delVideo: (cameraId: number | null) => {
+            return request({
+                url: import.meta.env.VITE_API_URL + `/sysAdmin/camera/del?cameraId=${cameraId == null ? null : cameraId}`,
+                method: 'get'
+            });
+        }
+    };
+}
diff --git a/src/router/route.ts b/src/router/route.ts
index 3a95b31..0b49e22 100644
--- a/src/router/route.ts
+++ b/src/router/route.ts
@@ -112,4 +112,20 @@
             title: '巡检首页'
         }
     },
+    {
+        path: '/video',
+        name: 'video',
+        component: () => import('/@/views/system/video/index.vue'),
+        meta: {
+            title: '视频设备管理'
+        }
+    },
+    {
+        path: '/specialIndex',
+        name: 'specialIndex',
+        component: () => import('/@/views/specialWorkSystem/specialIndex/index.vue'),
+        meta: {
+            title: '特殊作业首页'
+        }
+    }
 ];
diff --git a/src/views/intellectInspect/inspectIndex2/components/inspectList.vue b/src/views/intellectInspect/inspectIndex2/components/inspectList.vue
new file mode 100644
index 0000000..b8e06d9
--- /dev/null
+++ b/src/views/intellectInspect/inspectIndex2/components/inspectList.vue
@@ -0,0 +1,411 @@
+<template>
+    <el-dialog v-model="inspectListDialog" title="当前巡检任务" width="80%" center>
+      <div class="main-card">
+          <el-table :data="tableData" style="width: 100%" stripe border :header-cell-style="{ background: '#fafafa' }">
+            <el-table-column label="任务信息" align="center">
+              <template #default="scope">
+                <div class="left-info">
+                  <span>{{ scope.row.taskName }},</span>
+                  <p v-if="scope.row.execUserName == null">该任务暂无人认领</p>
+                  <p v-else>
+                      <span class="time">{{ scope.row.taskStatus == 2 ? scope.row.startTime : scope.row.endTime }}</span>由<span class="name">{{ scope.row.execUserName }}</span>进行的巡检任务
+                  </p>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="taskStatus" label="任务状态" align="center" width="180">
+              <template #default="scope">
+                <span :style="{color: scope.row.taskStatus == 1 ? '#999' : scope.row.taskStatus == 2 ? '#44b100' : scope.row.taskStatus == 3 ? '#409eff' : 'red'}">{{ scope.row.taskStatus == 1 ? '待巡检' : scope.row.taskStatus == 2 ? '巡检中' : scope.row.taskStatus == 3 ? '已巡检' : '超期未巡检' }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" align="center" width="180">
+              <template #default="scope">
+                <el-button type="text" size="small" v-if="scope.row.taskStatus == 2" @click="toLine(scope.row)">查看实时巡检</el-button>
+                <el-button type="text" size="small" v-else @click="toDetails('查看', scope.row)">查看巡检记录</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+      </div>
+      <template #footer>
+        <span class="dialog-footer" style="display: flex;justify-content: right">
+          <el-pagination v-model:currentPage="pageIndex" v-model:page-size="pageSize" :page-sizes="[10, 15]" small="false" background layout="total, sizes, prev, pager, next, jumper" :total="totalSize" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
+        </span>
+      </template>
+        <inspect-record-dialog ref="inspectRecordDialogRef" @refreshInspectRecord="getInspectRecord"></inspect-record-dialog>
+    </el-dialog>
+</template>
+
+<script lang="ts">
+import { toRefs, reactive, ref, onMounted } from 'vue';
+import { storeToRefs } from 'pinia';
+import { initBackEndControlRoutes } from '/@/router/backEnd';
+import { useUserInfo } from '/@/stores/userInfo';
+import { Session } from '/@/utils/storage';
+import { Edit, View, Plus, Delete, Refresh, Search, Download } from '@element-plus/icons-vue';
+import { ElTable } from 'element-plus';
+import { FormInstance, FormRules, ElMessage } from 'element-plus';
+import { inspectRecordApi } from '/@/api/intellectInspectSystem/inspectRecord';
+import { useRouter } from 'vue-router';
+import inspectRecordDialog from './inspectRecordDialog.vue';
+import { departmentApi } from '/@/api/systemManage/department';
+// 定义接口来定义对象的类型
+interface stateType {
+    tableData: Array<string>;
+    unchecked: null | number;
+    unusual: null | number;
+    uncheckedList: [];
+    abnormalList: [];
+    pageIndex: number;
+    pageSize: number;
+    totalSize: number;
+    workTypeList: Array<type>;
+    timeType: Array<type>;
+    classGroupList: Array<classGroup>;
+    quotaList: [];
+    departmentList: [];
+    inspectPointAllList: [];
+    inspectListDialog: boolean
+}
+interface type {
+    id: number;
+    name: string;
+}
+interface classGroup {
+    id: number;
+    groupName: string;
+}
+export default {
+    name: 'inspectList',
+    components: { inspectRecordDialog },
+    setup() {
+        const router = useRouter();
+        const state = reactive<stateType>({
+            inspectListDialog: false,
+            pageIndex: 1,
+            pageSize: 10,
+            totalSize: 0,
+            tableData: [],
+            unchecked: null,
+            unusual: null,
+            departmentList: [],
+            uncheckedList: [],
+            abnormalList: [],
+            workTypeList: [
+                { id: 1, name: '日常任务' },
+                { id: 2, name: '周期任务' }
+            ],
+            timeType: [
+                { id: 1, name: '分' },
+                { id: 2, name: '小时' },
+                { id: 3, name: '日' },
+                { id: 4, name: '月' },
+                { id: 5, name: '年' }
+            ],
+            classGroupList: [],
+            quotaList: [],
+            inspectPointAllList: []
+        });
+        const inspectRecordDialogRef = ref();
+        interface User {
+            name: string;
+            startTime: string;
+            endTime: string;
+            info: string;
+        }
+
+        // 页面载入时执行方法
+        onMounted(() => {
+            getInspectRecord();
+        });
+
+        const showInspectList = ()=>{
+          state.inspectListDialog = true
+          getInspectRecord();
+        }
+        // 分页获取工作时段列表
+        const getInspectRecord = async () => {
+            const data = { pageSize: state.pageSize, pageIndex: state.pageIndex };
+            let res = await inspectRecordApi().getInspectRecordByIndex(data);
+            if (res.data.code === '200') {
+                state.tableData = res.data.data.records;
+                state.totalSize = res.data.data.total;
+            } else {
+                ElMessage({
+                    type: 'warning',
+                    message: res.data.msg
+                });
+            }
+        };
+
+        const handleSizeChange = (val: number) => {
+            state.pageSize = val;
+            getInspectRecord();
+        };
+        const handleCurrentChange = (val: number) => {
+            state.pageIndex = val;
+            getInspectRecord();
+        };
+
+        const toLine = (item) => {
+          console.log(item,'item')
+            let id = item.id;
+            console.log(id,'id')
+            router.push({
+                path: 'intelligentLine',
+                query: {
+                    id: id
+                }
+            });
+        };
+
+        const toOverTime = (id) => {
+            console.log(state.uncheckedList, 'list');
+            router.push({
+                path: 'inspectRecord',
+                query: {
+                    id: id,
+                }
+            });
+        };
+        const toDetails = (type: string, item) => {
+            inspectRecordDialogRef.value.showInspectRecordDialog(type, item, state.workTypeList, state.departmentList, state.timeType, state.classGroupList, state.quotaList, state.inspectPointAllList);
+        };
+        return {
+            View,
+            Edit,
+            Delete,
+            Refresh,
+            Plus,
+            router,
+            inspectRecordDialogRef,
+            showInspectList,
+            toLine,
+            toOverTime,
+            toDetails,
+            handleSizeChange,
+            handleCurrentChange,
+            ...toRefs(state)
+        };
+    }
+};
+</script>
+
+<style scoped lang="scss">
+$homeNavLengh: 8;
+@media screen and (min-width: 1366px) {
+    .topCard {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        font-weight: bolder;
+
+        .top-info {
+            display: flex;
+            font-size: 16px;
+            align-items: center;
+            padding: 10px 15px;
+            background: #ffeb87;
+            border-radius: 8px;
+            border: 1px solid #ffae00;
+
+            & > div {
+                vertical-align: middle;
+                white-space: nowrap;
+                span {
+                    font-size: 22px;
+                    color: #f3001e;
+                    margin: 0 4px;
+                    cursor: pointer;
+
+                    &:hover{
+                        text-decoration: underline;
+                    }
+                }
+            }
+        }
+    }
+    .left-info {
+        width: 70%;
+        display: flex;
+        align-items: center;
+        justify-content: left;
+        font-size: 16px;
+        overflow-x: auto;
+        & > span {
+            white-space: nowrap;
+        }
+        p {
+            white-space: nowrap;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            & > span {
+                white-space: nowrap;
+            }
+        }
+    }
+}
+@media screen and (min-width: 1200px) and (max-width: 1366px) {
+    .topCard {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        font-weight: bolder;
+
+        .top-info {
+            display: flex;
+            font-size: 14px;
+            align-items: center;
+            padding: 6px 10px;
+            background: #ffeb87;
+            border-radius: 4px;
+            border: 1px solid #ffae00;
+
+            & > div {
+                vertical-align: middle;
+                white-space: nowrap;
+                span {
+                    font-size: 18px;
+                    color: #f3001e;
+                    margin: 0 2px;
+                    cursor: pointer;
+
+                    &:hover{
+                        text-decoration: underline;
+                    }
+                }
+            }
+        }
+    }
+    .left-info {
+        width: 70%;
+        display: flex;
+        align-items: center;
+        justify-content: left;
+        font-size: 15px;
+        color: #333;
+        overflow-x: auto;
+        & > span {
+            white-space: nowrap;
+        }
+        p {
+            white-space: nowrap;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            & > span {
+                white-space: nowrap;
+            }
+        }
+    }
+}
+@media screen and (max-width: 1200px) {
+    .topCard {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        font-weight: bolder;
+
+        .top-info {
+            display: flex;
+            font-size: 14px;
+            align-items: center;
+            padding: 2px 6px;
+            background: #ffeb87;
+            border-radius: 4px;
+            border: 1px solid #ffae00;
+
+            & > div {
+                vertical-align: middle;
+                white-space: nowrap;
+                span {
+                    font-size: 16px;
+                    color: #f3001e;
+                    margin: 0 1px;
+                    cursor: pointer;
+
+                    &:hover{
+                        text-decoration: underline;
+                    }
+                }
+            }
+        }
+    }
+    .left-info {
+        width: 70%;
+        display: flex;
+        align-items: center;
+        justify-content: left;
+        font-size: 12px;
+        color: #333;
+        overflow-x: auto;
+        & > span {
+            white-space: nowrap;
+        }
+        p {
+            white-space: nowrap;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            & > span {
+                white-space: nowrap;
+            }
+        }
+    }
+}
+
+.home-container {
+    height: calc(100vh - 144px);
+    box-sizing: border-box;
+    overflow: hidden;
+    .homeCard {
+        width: 100%;
+        padding: 20px;
+        box-sizing: border-box;
+        background: #fff;
+        border-radius: 4px;
+
+        .title {
+            font-size: 20px;
+            font-weight: bolder;
+        }
+        .main-card {
+            width: 100%;
+            height: 100%;
+        }
+        &:last-of-type {
+            position: relative;
+            padding-top: 0;
+            height: calc(100% - 60px);
+        }
+    }
+    .el-row {
+        display: flex;
+        align-items: center;
+        margin-bottom: 20px;
+        &:last-child {
+            margin-bottom: 0;
+        }
+        .grid-content {
+            align-items: center;
+            min-height: 36px;
+        }
+    }
+}
+.el-input {
+    width: 100% !important;
+}
+.el-date-editor::v-deep {
+    width: 100%;
+}
+.el-select {
+    width: 100%;
+}
+:deep(.el-textarea.is-disabled .el-textarea__inner) {
+    background-color: var(--el-card-bg-color);
+    color: var(--el-input-text-color, var(--el-text-color-regular));
+}
+:deep(.el-input.is-disabled .el-input__inner) {
+    color: var(--el-input-text-color, var(--el-text-color-regular));
+}
+:deep(.el-input.is-disabled .el-input__wrapper) {
+    background-color: var(--el-card-bg-color);
+}
+</style>
diff --git a/src/views/intellectInspect/inspectIndex2/components/unusualList.vue b/src/views/intellectInspect/inspectIndex2/components/unusualList.vue
new file mode 100644
index 0000000..c9059d3
--- /dev/null
+++ b/src/views/intellectInspect/inspectIndex2/components/unusualList.vue
@@ -0,0 +1,404 @@
+<template>
+    <el-dialog v-model="unusualListDialog" title="当前巡检任务" width="90%" center>
+      <div class="main-card">
+          <el-table :data="tableData" style="width: 100%" stripe border :header-cell-style="{ background: '#fafafa' }">
+            <el-table-column label="工单编号" align="center"/>
+            <el-table-column label="异常巡检点" align="center"/>
+            <el-table-column label="巡检(发现)时间" align="center"/>
+            <el-table-column label="所属巡检任务" align="center"/>
+            <el-table-column label="设备/区域名称" align="center"/>
+            <el-table-column label="正常参考值" align="center"/>
+            <el-table-column label="实际巡检值" align="center"/>
+            <el-table-column label="隐患处置人" align="center"/>
+            <el-table-column label="电话" align="center"/>
+            <el-table-column prop="taskStatus" label="处置状态" align="center" width="180">
+              <template #default="scope">
+                <span :style="{color: scope.row.taskStatus == 1 ? '#999' : scope.row.taskStatus == 2 ? '#44b100' : scope.row.taskStatus == 3 ? '#409eff' : 'red'}">
+                  {{ scope.row.taskStatus == 1 ? '待巡检' : scope.row.taskStatus == 2 ? '巡检中' : scope.row.taskStatus == 3 ? '已巡检' : '超期未巡检' }}
+                </span>
+              </template>
+            </el-table-column>
+            <el-table-column label="处置描述反馈" align="center"/>
+            <el-table-column label="操作" align="center" width="190" fixed="right">
+              <template #default="scope">
+                <el-button type="text" size="small">验收</el-button>
+                <el-button type="text" size="small">查看现场照片</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+      </div>
+      <template #footer>
+        <span class="dialog-footer" style="display: flex;justify-content: right">
+          <el-pagination v-model:currentPage="pageIndex" v-model:page-size="pageSize" :page-sizes="[10, 15]" small="false" background layout="total, sizes, prev, pager, next, jumper" :total="totalSize" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
+        </span>
+      </template>
+        <inspect-record-dialog ref="inspectRecordDialogRef" @refreshInspectRecord="getInspectRecord"></inspect-record-dialog>
+    </el-dialog>
+</template>
+
+<script lang="ts">
+import { toRefs, reactive, ref, onMounted } from 'vue';
+import { storeToRefs } from 'pinia';
+import { initBackEndControlRoutes } from '/@/router/backEnd';
+import { useUserInfo } from '/@/stores/userInfo';
+import { Session } from '/@/utils/storage';
+import { Edit, View, Plus, Delete, Refresh, Search, Download } from '@element-plus/icons-vue';
+import { ElTable } from 'element-plus';
+import { FormInstance, FormRules, ElMessage } from 'element-plus';
+import { inspectRecordApi } from '/@/api/intellectInspectSystem/inspectRecord';
+import { useRouter } from 'vue-router';
+import inspectRecordDialog from './inspectRecordDialog.vue';
+import { departmentApi } from '/@/api/systemManage/department';
+// 定义接口来定义对象的类型
+interface stateType {
+    tableData: Array<string>;
+    unchecked: null | number;
+    unusual: null | number;
+    uncheckedList: [];
+    abnormalList: [];
+    pageIndex: number;
+    pageSize: number;
+    totalSize: number;
+    workTypeList: Array<type>;
+    classGroupList: Array<classGroup>;
+    quotaList: [];
+    departmentList: [];
+    inspectPointAllList: [];
+    unusualListDialog: boolean
+}
+interface type {
+    id: number;
+    name: string;
+}
+interface classGroup {
+    id: number;
+    groupName: string;
+}
+export default {
+    name: 'inspectList',
+    components: { inspectRecordDialog },
+    setup() {
+        const router = useRouter();
+        const state = reactive<stateType>({
+            unusualListDialog: false,
+            pageIndex: 1,
+            pageSize: 10,
+            totalSize: 0,
+            tableData: [],
+            unchecked: null,
+            unusual: null,
+            departmentList: [],
+            uncheckedList: [],
+            abnormalList: [],
+            workTypeList: [
+                { id: 1, name: '日常任务' },
+                { id: 2, name: '周期任务' }
+            ],
+            classGroupList: [],
+            quotaList: [],
+            inspectPointAllList: []
+        });
+        const inspectRecordDialogRef = ref();
+        interface User {
+            name: string;
+            startTime: string;
+            endTime: string;
+            info: string;
+        }
+
+        // 页面载入时执行方法
+        onMounted(() => {
+
+        });
+
+        const showUnusualList = ()=>{
+          state.unusualListDialog = true
+          getInspectRecord();
+        }
+        // 分页获取工作时段列表
+        const getInspectRecord = async () => {
+            const data = { pageSize: state.pageSize, pageIndex: state.pageIndex };
+            let res = await inspectRecordApi().getInspectRecordByIndex(data);
+            if (res.data.code === '200') {
+                state.tableData = res.data.data.records;
+                state.totalSize = res.data.data.total;
+            } else {
+                ElMessage({
+                    type: 'warning',
+                    message: res.data.msg
+                });
+            }
+        };
+
+        const handleSizeChange = (val: number) => {
+            state.pageSize = val;
+            getInspectRecord();
+        };
+        const handleCurrentChange = (val: number) => {
+            state.pageIndex = val;
+            getInspectRecord();
+        };
+
+        const toLine = (item) => {
+          console.log(item,'item')
+            let id = item.id;
+            console.log(id,'id')
+            router.push({
+                path: 'intelligentLine',
+                query: {
+                    id: id
+                }
+            });
+        };
+
+        const toOverTime = (id) => {
+            console.log(state.uncheckedList, 'list');
+            router.push({
+                path: 'inspectRecord',
+                query: {
+                    id: id,
+                }
+            });
+        };
+        const toDetails = (type: string, item: object) => {
+
+        };
+        return {
+            View,
+            Edit,
+            Delete,
+            Refresh,
+            Plus,
+            router,
+            inspectRecordDialogRef,
+            showUnusualList,
+            toLine,
+            toOverTime,
+            toDetails,
+            handleSizeChange,
+            handleCurrentChange,
+            ...toRefs(state)
+        };
+    }
+};
+</script>
+
+<style scoped lang="scss">
+$homeNavLengh: 8;
+@media screen and (min-width: 1366px) {
+    .topCard {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        font-weight: bolder;
+
+        .top-info {
+            display: flex;
+            font-size: 16px;
+            align-items: center;
+            padding: 10px 15px;
+            background: #ffeb87;
+            border-radius: 8px;
+            border: 1px solid #ffae00;
+
+            & > div {
+                vertical-align: middle;
+                white-space: nowrap;
+                span {
+                    font-size: 22px;
+                    color: #f3001e;
+                    margin: 0 4px;
+                    cursor: pointer;
+
+                    &:hover{
+                        text-decoration: underline;
+                    }
+                }
+            }
+        }
+    }
+    .left-info {
+        width: 70%;
+        display: flex;
+        align-items: center;
+        justify-content: left;
+        font-size: 16px;
+        overflow-x: auto;
+        & > span {
+            white-space: nowrap;
+        }
+        p {
+            white-space: nowrap;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            & > span {
+                white-space: nowrap;
+            }
+        }
+    }
+}
+@media screen and (min-width: 1200px) and (max-width: 1366px) {
+    .topCard {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        font-weight: bolder;
+
+        .top-info {
+            display: flex;
+            font-size: 14px;
+            align-items: center;
+            padding: 6px 10px;
+            background: #ffeb87;
+            border-radius: 4px;
+            border: 1px solid #ffae00;
+
+            & > div {
+                vertical-align: middle;
+                white-space: nowrap;
+                span {
+                    font-size: 18px;
+                    color: #f3001e;
+                    margin: 0 2px;
+                    cursor: pointer;
+
+                    &:hover{
+                        text-decoration: underline;
+                    }
+                }
+            }
+        }
+    }
+    .left-info {
+        width: 70%;
+        display: flex;
+        align-items: center;
+        justify-content: left;
+        font-size: 15px;
+        color: #333;
+        overflow-x: auto;
+        & > span {
+            white-space: nowrap;
+        }
+        p {
+            white-space: nowrap;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            & > span {
+                white-space: nowrap;
+            }
+        }
+    }
+}
+@media screen and (max-width: 1200px) {
+    .topCard {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        font-weight: bolder;
+
+        .top-info {
+            display: flex;
+            font-size: 14px;
+            align-items: center;
+            padding: 2px 6px;
+            background: #ffeb87;
+            border-radius: 4px;
+            border: 1px solid #ffae00;
+
+            & > div {
+                vertical-align: middle;
+                white-space: nowrap;
+                span {
+                    font-size: 16px;
+                    color: #f3001e;
+                    margin: 0 1px;
+                    cursor: pointer;
+
+                    &:hover{
+                        text-decoration: underline;
+                    }
+                }
+            }
+        }
+    }
+    .left-info {
+        width: 70%;
+        display: flex;
+        align-items: center;
+        justify-content: left;
+        font-size: 12px;
+        color: #333;
+        overflow-x: auto;
+        & > span {
+            white-space: nowrap;
+        }
+        p {
+            white-space: nowrap;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            & > span {
+                white-space: nowrap;
+            }
+        }
+    }
+}
+
+.home-container {
+    height: calc(100vh - 144px);
+    box-sizing: border-box;
+    overflow: hidden;
+    .homeCard {
+        width: 100%;
+        padding: 20px;
+        box-sizing: border-box;
+        background: #fff;
+        border-radius: 4px;
+
+        .title {
+            font-size: 20px;
+            font-weight: bolder;
+        }
+        .main-card {
+            width: 100%;
+            height: 100%;
+        }
+        &:last-of-type {
+            position: relative;
+            padding-top: 0;
+            height: calc(100% - 60px);
+        }
+    }
+    .el-row {
+        display: flex;
+        align-items: center;
+        margin-bottom: 20px;
+        &:last-child {
+            margin-bottom: 0;
+        }
+        .grid-content {
+            align-items: center;
+            min-height: 36px;
+        }
+    }
+}
+.el-input {
+    width: 100% !important;
+}
+.el-date-editor::v-deep {
+    width: 100%;
+}
+.el-select {
+    width: 100%;
+}
+:deep(.el-textarea.is-disabled .el-textarea__inner) {
+    background-color: var(--el-card-bg-color);
+    color: var(--el-input-text-color, var(--el-text-color-regular));
+}
+:deep(.el-input.is-disabled .el-input__inner) {
+    color: var(--el-input-text-color, var(--el-text-color-regular));
+}
+:deep(.el-input.is-disabled .el-input__wrapper) {
+    background-color: var(--el-card-bg-color);
+}
+</style>
diff --git a/src/views/intellectInspect/inspectIndex2/index.vue b/src/views/intellectInspect/inspectIndex2/index.vue
index 2e64240..c530dfd 100644
--- a/src/views/intellectInspect/inspectIndex2/index.vue
+++ b/src/views/intellectInspect/inspectIndex2/index.vue
@@ -1,62 +1,174 @@
 <template>
     <div class="home-container">
         <div style="height: 100%">
-            <div class="homeCard topCard">
-                <div class="title">当前巡检任务</div>
-                <div class="top-info" v-if="unchecked != 0 || unusual != 0">
-                    <el-icon :size="18" color="#F3001E" style="margin-right: 4px"><BellFilled /></el-icon>
-                    预警消息:
-                    <div v-if="unchecked != 0">
+          <div class="topChart">
+            <div class="chart-item">
+              <div class="chart-tit">
+                <span class="tit">年度巡检异常趋势</span>
+              </div>
+              <div class="chart" :id="xjLine"></div>
+            </div>
+            <div class="chart-item">
+              <div class="chart-tit">
+                <span class="tit">异常区域设备统计</span>
+                <el-switch
+                    v-model="chartStatus"
+                    class="ml-2"
+                    inline-prompt
+                    style="--el-switch-on-color: #13ce66; --el-switch-off-color: #13ce66"
+                    active-text="区域"
+                    inactive-text="设备"
+                />
+              </div>
+              <dv-active-ring-chart :config="conf" class="chart"/>
+              <el-radio-group v-model="period" label="size control" size="small" height="250px" style="display: flex;justify-content: center;margin-top: 10px">
+                <el-radio-button label="week">近7天</el-radio-button>
+                <el-radio-button label="month">近30天</el-radio-button>
+                <el-radio-button label="season">近90天</el-radio-button>
+                <el-radio-button label="year">近一年</el-radio-button>
+              </el-radio-group>
+            </div>
+          </div>
+            <div class="midChart">
+              <div class="chart-item">
+                <div class="chart-tit">
+                  <div style="display: flex;align-items: center">
+                    <span class="tit">当前巡检任务</span>
+                    <div class="top-info" v-if="unchecked != 0 || unusual != 0">
+                      <el-icon :size="18" color="#F3001E" style="margin-right: 4px"><BellFilled /></el-icon>
+                      <div>预警消息:</div>
+                      <div v-if="unchecked != 0">
                         当日超期未巡检任务<el-tooltip
-                            class="box-item"
-                            effect="light"
-                            content="查看相关记录"
-                            placement="bottom-start"
-                    ><span @click="toOverTime(4)">{{ unchecked }}</span></el-tooltip>个
-                    </div>
-                    <span v-if="unchecked != 0 && unusual != 0">,</span>
-                    <div v-if="unusual != 0">
+                          class="box-item"
+                          effect="light"
+                          content="查看相关记录"
+                          placement="bottom-start"
+                      ><span @click="toOverTime(4)">{{ unchecked }}</span></el-tooltip>个
+                      </div>
+                      <span v-if="unchecked != 0 && unusual != 0">,</span>
+                      <div v-if="unusual != 0">
                         存在异常任务<el-tooltip
-                            class="box-item"
-                            effect="light"
-                            content="查看相关记录"
-                            placement="bottom-start"
-                    ><span @click="toOverTime(5)">{{ unusual }}</span
-                        ></el-tooltip>个
+                          class="box-item"
+                          effect="light"
+                          content="查看相关记录"
+                          placement="bottom-start"
+                      ><span @click="toOverTime(5)">{{ unusual }}</span
+                      ></el-tooltip>个
+                      </div>
+                      。
                     </div>
-                    。
+                  </div>
+                  <div class="checkAll" @click="checkAllRecord()">
+                    全部记录>>
+                  </div>
                 </div>
-            </div>
-            <div class="homeCard">
-                <div class="main-card">
-                    <div class="list">
-                        <div class="cardTop" v-for="(item, index) in tableData" :key="index">
-                            <div class="left-info">
-                                <span class="num">{{ pageSize * (pageIndex - 1) + index + 1 }}、</span>
-                                <span class="place">{{ item.taskName }},</span>
-                                <p v-if="item.execUserName == null">该任务暂无人认领</p>
-                                <p v-else>
-                                    <span class="time">{{ item.taskStatus == 2 ? item.startTime : item.endTime }}</span
-                                    >由<span class="name">{{ item.execUserName }}</span
-                                    >进行的巡检任务
-                                </p>
-                            </div>
-                            <div class="mid-info">
-                                任务状态:<span :class="item.taskStatus == 1 ? 'grey' : item.taskStatus == 2 ? 'green' : item.taskStatus == 3 ? 'blue' : 'red'">{{ item.taskStatus == 1 ? '待巡检' : item.taskStatus == 2 ? '巡检中' : item.taskStatus == 3 ? '已巡检' : '超期未巡检' }}</span>
-                            </div>
-                            <div class="right-info">
-                                <div v-if="item.taskStatus == 2" @click="toLine(item)" class="checkBtn">查看实时巡检</div>
-                                <div v-else class="reviewBtn" @click="toDetails('查看', item)">[查看巡检记录]</div>
-                            </div>
-                        </div>
+                <div class="chart">
+<!--                  <el-table :data="tableData" style="width: 100%" stripe border>-->
+<!--                    <el-table-column label="任务信息" align="center">-->
+<!--                      <template #default="scope">-->
+<!--                        <div class="left-info">-->
+<!--                          <span>{{ scope.row.taskName }},</span>-->
+<!--                          <p v-if="scope.row.execUserName == null">该任务暂无人认领</p>-->
+<!--                          <p v-else>-->
+<!--                              <span class="time">{{ scope.row.taskStatus == 2 ? scope.row.startTime : scope.row.endTime }}</span>由<span class="name">{{ scope.row.execUserName }}</span>进行的巡检任务-->
+<!--                          </p>-->
+<!--                        </div>-->
+<!--                      </template>-->
+<!--                    </el-table-column>-->
+<!--                    <el-table-column prop="taskStatus" label="任务状态" align="center" width="180">-->
+<!--                      <template #default="scope">-->
+<!--                        <span :class="scope.row.taskStatus == 1 ? 'grey' : scope.row.taskStatus == 2 ? 'green' : scope.row.taskStatus == 3 ? 'blue' : 'red'">{{ scope.row.taskStatus == 1 ? '待巡检' : scope.row.taskStatus == 2 ? '巡检中' : scope.row.taskStatus == 3 ? '已巡检' : '超期未巡检' }}</span>-->
+<!--                      </template>-->
+<!--                    </el-table-column>-->
+<!--                    <el-table-column label="操作" align="center" width="180">-->
+<!--                      <template #default="scope">-->
+<!--                        <el-button type="text" v-if="scope.row.taskStatus == 2" @click="toLine(scope.row)" class="checkBtn">查看实时巡检</el-button>-->
+<!--                        <el-button type="text" v-else class="reviewBtn" @click="toDetails('查看', scope.row)">查看巡检记录</el-button>-->
+<!--                      </template>-->
+<!--                    </el-table-column>-->
+<!--                  </el-table>-->
+                  <div class="list">
+                    <div class="list-tit">
+                      <span class="w60">任务信息</span>
+                      <span class="w20">任务状态</span>
+                      <span class="w20">操作</span>
                     </div>
-                    <div class="pageBtn">
-                        <el-pagination v-model:currentPage="pageIndex" v-model:page-size="pageSize" :page-sizes="[10, 15]" small="false" background layout="total, sizes, prev, pager, next, jumper" :total="totalSize" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
+                    <div class="cardTop" v-for="(item, index) in tableData" :key="index">
+                      <div class="l-info">
+                        <span class="place">{{ item.taskName }},</span>
+                        <p v-if="item.execUserName == null">该任务暂无人认领</p>
+                        <p v-else>
+                            <span class="time">{{ item.taskStatus == 2 ? item.startTime : item.endTime }}</span>由<span class="name">{{ item.execUserName }}</span
+                        >进行的巡检任务
+                        </p>
+                      </div>
+                      <div class="m-info">
+                        任务状态:<span :class="item.taskStatus == 1 ? 'grey' : item.taskStatus == 2 ? 'green' : item.taskStatus == 3 ? 'blue' : 'red'">{{ item.taskStatus == 1 ? '待巡检' : item.taskStatus == 2 ? '巡检中' : item.taskStatus == 3 ? '已巡检' : '超期未巡检' }}</span>
+                      </div>
+                      <div class="r-info">
+                        <el-button type="text" v-if="item.taskStatus == 2" @click="toLine(item)" size="small">查看实时巡检</el-button>
+                        <el-button type="text" v-else class="reviewBtn" @click="toDetails('查看', item)" size="small">查看巡检记录</el-button>
+                      </div>
                     </div>
+                  </div>
+<!--                  <div class="pageBtn">-->
+<!--                    <el-pagination v-model:currentPage="pageIndex" v-model:page-size="pageSize" :page-sizes="[10, 15]" small="false" background layout="total, sizes, prev, pager, next, jumper" :total="totalSize" @size-change="handleSizeChange" @current-change="handleCurrentChange" />-->
+<!--                  </div>-->
                 </div>
+              </div>
             </div>
+          <div class="midChart">
+            <div class="chart-item">
+              <div class="chart-tit">
+                  <span class="tit">巡检异常清单</span>
+                  <div class="checkAll" @click="checkAllList()">
+                    全部记录>>
+                  </div>
+              </div>
+              <div class="chart">
+                <div class="list">
+                  <div class="list-tit">
+                    <span class="w10">工单编号</span>
+                    <span class="w10">异常巡检点</span>
+                    <span class="w10">巡检(发现)时间</span>
+                    <span class="w10">所属巡检任务</span>
+                    <span class="w10">设备/区域名称</span>
+                    <span class="w10">正常参考值</span>
+                    <span class="w10">实际巡检值</span>
+                    <span class="w10">隐患处置人</span>
+                    <span class="w10">电话</span>
+                    <span class="w10">处置状态</span>
+                    <span class="w10">处置描述反馈</span>
+                    <span class="w15">操作</span>
+                  </div>
+                  <div class="cardTop" v-for="(item, index) in unusualData" :key="index">
+                    <span class="w10">{{item.num}}</span>
+                    <span class="w10">{{item.spot}}</span>
+                    <span class="w10">{{item.time}}</span>
+                    <span class="w10">{{item.job}}</span>
+                    <span class="w10">{{item.area}}</span>
+                    <span class="w10">{{item.refer}}</span>
+                    <span class="w10">{{item.real}}</span>
+                    <span class="w10">{{item.name}}</span>
+                    <span class="w10">{{item.phone}}</span>
+                    <span class="w10">{{item.status}}</span>
+                    <span class="w10">{{item.describe}}</span>
+                    <span class="w15">
+                      <el-button type="text" @click="toLine(item)" size="small">验收</el-button>
+                      <el-button type="text" @click="toPhotos('查看', item)" size="small">查看现场照片</el-button>
+                    </span>
+                  </div>
+                </div>
+<!--                <div class="pageBtn">-->
+<!--                  <el-pagination v-model:currentPage="pageIndex" v-model:page-size="pageSize" :page-sizes="[10, 15]" small="false" background layout="total, sizes, prev, pager, next, jumper" :total="totalSize" @size-change="handleSizeChange" @current-change="handleCurrentChange" />-->
+<!--                </div>-->
+              </div>
+            </div>
+          </div>
         </div>
         <inspect-record-dialog ref="inspectRecordDialogRef" @refreshInspectRecord="getInspectRecord"></inspect-record-dialog>
+        <inspect-list ref="inspectListRef"></inspect-list>
+        <unusual-list ref="unusualListRef"></unusual-list>
     </div>
 </template>
 
@@ -71,11 +183,15 @@
 import { FormInstance, FormRules, ElMessage } from 'element-plus';
 import { inspectRecordApi } from '/@/api/intellectInspectSystem/inspectRecord';
 import { useRouter } from 'vue-router';
+import * as echarts from 'echarts'
 import inspectRecordDialog from './components/inspectRecordDialog.vue';
+import inspectList from './components/inspectList.vue';
+import unusualList from './components/unusualList.vue';
 import { departmentApi } from '/@/api/systemManage/department';
 // 定义接口来定义对象的类型
 interface stateType {
     tableData: Array<string>;
+    unusualData: Array<any>;
     unchecked: null | number;
     unusual: null | number;
     uncheckedList: [];
@@ -89,6 +205,9 @@
     classGroupList: Array<classGroup>;
     quotaList: [];
     inspectPointAllList: [];
+    conf:{};
+    chartStatus:boolean;
+    period: string
 }
 interface type {
     id: number;
@@ -100,16 +219,73 @@
 }
 export default {
     name: 'workingHours',
-    components: { inspectRecordDialog },
+    components: { inspectRecordDialog, inspectList, unusualList },
     setup() {
         const router = useRouter();
+        const xjLine = ref("eChartXjLine" + Date.now() + Math.random())
         const state = reactive<stateType>({
             pageIndex: 1,
-            pageSize: 10,
+            pageSize: 4,
             totalSize: 0,
             tableData: [],
+            unusualData: [
+              {
+                num: '202302280001',
+                spot: '70736',
+                time: '2023-03-02 17:44:25',
+                job: '甲醇车间XXX巡检',
+                area: 'xxx设备',
+                refer: '8.9~10Mpa',
+                real: '15.6Mpa',
+                name: '黄公子',
+                phone: '15261806176',
+                status: '待验收',
+                describe: '更换法兰更换法兰更换法兰更换法兰更换法兰更换法兰'
+              },
+              {
+                num: '202302280001',
+                spot: '70736',
+                time: '2023-03-02 17:44:25',
+                job: '甲醇车间XXX巡检',
+                area: 'xxx设备',
+                refer: '8.9~10Mpa',
+                real: '15.6Mpa',
+                name: '黄公子',
+                phone: '15261806176',
+                status: '待验收',
+                describe: '更换法兰更换法兰更换法兰更换法兰更换法兰更换法兰'
+              },
+              {
+                num: '202302280001',
+                spot: '70736',
+                time: '2023-03-02 17:44:25',
+                job: '甲醇车间XXX巡检',
+                area: 'xxx设备',
+                refer: '8.9~10Mpa',
+                real: '15.6Mpa',
+                name: '黄公子',
+                phone: '15261806176',
+                status: '待验收',
+                describe: '更换法兰更换法兰更换法兰更换法兰更换法兰更换法兰'
+              },
+              {
+                num: '202302280001',
+                spot: '70736',
+                time: '2023-03-02 17:44:25',
+                job: '甲醇车间XXX巡检',
+                area: 'xxx设备',
+                refer: '8.9~10Mpa',
+                real: '15.6Mpa',
+                name: '黄公子',
+                phone: '15261806176',
+                status: '待验收',
+                describe: '更换法兰更换法兰更换法兰更换法兰更换法兰更换法兰'
+              }
+            ],
             unchecked: null,
             unusual: null,
+            chartStatus: true,
+            period: 'month',
             uncheckedList: [],
             abnormalList: [],
             workTypeList: [
@@ -126,9 +302,43 @@
             ],
             classGroupList: [],
             quotaList: [],
-            inspectPointAllList: []
+            inspectPointAllList: [],
+            conf:{
+              radius: '75%',
+              activeRadius: '80%',
+              lineWidth: 24,
+              digitalFlopStyle: {
+                fontSize: 25,
+                fill: '#000',
+              },
+              textColor: '#000',
+              data: [
+                {
+                  name: '区域1',
+                  value: 98,
+                },
+                {
+                  name: '区域2',
+                  value: 150,
+                },
+                {
+                  name: '区域3',
+                  value: 62,
+                },
+                {
+                  name: '区域4',
+                  value: 54,
+                },
+                {
+                  name: '区域5',
+                  value: 54,
+                }
+              ]
+          }
         });
         const inspectRecordDialogRef = ref();
+        const inspectListRef = ref();
+        const unusualListRef = ref();
         interface User {
             name: string;
             startTime: string;
@@ -141,7 +351,102 @@
             getInspectRecord();
             getDayData();
             getDepartmentData();
+            initXjLine()
         });
+        const checkAllRecord =()=>{
+          inspectListRef.value.departmentList = state.departmentList
+          inspectListRef.value.showInspectList()
+        }
+        const checkAllList =()=>{
+          unusualListRef.value.showUnusualList()
+        }
+        type EChartsOption = echarts.EChartsOption
+        const initXjLine =()=>{
+          let dom = document.getElementById(xjLine.value);
+          let myChart = echarts.init(dom);
+
+          let option: EChartsOption;
+
+          option = {
+            tooltip: {
+              trigger: 'axis'
+            },
+            legend: {
+              data: ['总趋势', '事业部'],
+              height: '15%',
+              top: 0,
+              bottom: 0,
+              padding:[1,1,1,0]
+            },
+            grid: {
+              top: '15%',
+              left: '3%',
+              right: '3%',
+              bottom: 0,
+              containLabel: true
+            },
+            toolbox: {
+              feature: {
+                // saveAsImage: {}
+              }
+            },
+            xAxis: {
+              type: 'category',
+              boundaryGap: false,
+              data: ['四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月', '一月', '二月', '三月']
+            },
+            yAxis: {
+              type: 'value'
+            },
+            series: [
+              {
+                name: '总趋势',
+                type: 'line',
+                stack: 'Total',
+                data: [120, 132, 101, 134, 90, 120, 132, 101, 134, 90, 230, 210],
+                label:{
+                  show: true,
+                  color: '#95d475',
+                  fontSize: 12
+                },
+                lineStyle:{
+                  width: 1,
+                  color: '#95d475'
+                },
+                itemStyle:{
+                  color: '#95d475',
+                  borderColor: '#fff',
+                  borderWidth: 2
+                }
+              },
+              {
+                name: '事业部',
+                type: 'line',
+                stack: 'Total',
+                data: [220, 182, 191, 234, 290, 220, 182, 191, 234, 290, 330, 310],
+                label:{
+                  show: true,
+                  color: '#337ecc',
+                  fontSize: 12
+                },
+                lineStyle:{
+                  width: 1,
+                  color: '#337ecc'
+                },
+                itemStyle:{
+                  color: '#337ecc',
+                  borderColor: '#fff',
+                  borderWidth: 2
+                }
+              }
+            ]
+          }
+
+          option && myChart.setOption(option);
+          window.addEventListener("resize",function (){
+            myChart.resize();
+          });
+        }
 
         // 分页获取工作时段列表
         const getInspectRecord = async () => {
@@ -222,9 +527,14 @@
             Edit,
             Delete,
             Refresh,
+            xjLine,
             Plus,
             router,
             inspectRecordDialogRef,
+            inspectListRef,
+            unusualListRef,
+            checkAllRecord,
+            checkAllList,
             toLine,
             toOverTime,
             toDetails,
@@ -239,319 +549,328 @@
 <style scoped lang="scss">
 $homeNavLengh: 8;
 @media screen and (min-width: 1366px) {
-    .topCard {
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        font-weight: bolder;
 
-        .top-info {
-            display: flex;
-            font-size: 16px;
-            align-items: center;
-            padding: 10px 15px;
-            background: #ffeb87;
-            border-radius: 8px;
-            border: 1px solid #ffae00;
-
-            & > div {
-                vertical-align: middle;
-                white-space: nowrap;
-                span {
-                    font-size: 22px;
-                    color: #f3001e;
-                    margin: 0 4px;
-                    cursor: pointer;
-
-                    &:hover{
-                        text-decoration: underline;
-                    }
-                }
-            }
-        }
-    }
-    .left-info {
-        width: 70%;
-        display: flex;
-        align-items: center;
-        justify-content: left;
-        font-size: 18px;
-        color: #333;
-        overflow-x: auto;
-        & > span {
-            white-space: nowrap;
-        }
-        p {
-            white-space: nowrap;
-            overflow: hidden;
-            text-overflow: ellipsis;
-            & > span {
-                white-space: nowrap;
-            }
-        }
-    }
-    .mid-info {
-        width: 20%;
-        font-size: 18px;
-        color: #333;
-    }
-    .right-info {
-        width: 10%;
-        display: flex;
-        justify-content: right;
-        align-items: center;
-        font-size: 16px;
-        color: #fff;
-
-        div {
-            white-space: nowrap;
-        }
-    }
 }
 @media screen and (min-width: 1200px) and (max-width: 1366px) {
-    .topCard {
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        font-weight: bolder;
 
-        .top-info {
-            display: flex;
-            font-size: 14px;
-            align-items: center;
-            padding: 6px 10px;
-            background: #ffeb87;
-            border-radius: 4px;
-            border: 1px solid #ffae00;
-
-            & > div {
-                vertical-align: middle;
-                white-space: nowrap;
-                span {
-                    font-size: 18px;
-                    color: #f3001e;
-                    margin: 0 2px;
-                    cursor: pointer;
-
-                    &:hover{
-                        text-decoration: underline;
-                    }
-                }
-            }
-        }
-    }
-    .left-info {
-        width: 70%;
-        display: flex;
-        align-items: center;
-        justify-content: left;
-        font-size: 15px;
-        color: #333;
-        overflow-x: auto;
-        & > span {
-            white-space: nowrap;
-        }
-        p {
-            white-space: nowrap;
-            overflow: hidden;
-            text-overflow: ellipsis;
-            & > span {
-                white-space: nowrap;
-            }
-        }
-    }
-    .mid-info {
-        width: 20%;
-        font-size: 15px;
-        color: #333;
-    }
-    .right-info {
-        width: 10%;
-        display: flex;
-        justify-content: right;
-        align-items: center;
-        font-size: 13px;
-        color: #fff;
-        div {
-            white-space: nowrap;
-        }
-    }
 }
 @media screen and (max-width: 1200px) {
-    .topCard {
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        font-weight: bolder;
 
-        .top-info {
-            display: flex;
-            font-size: 14px;
-            align-items: center;
-            padding: 2px 6px;
-            background: #ffeb87;
-            border-radius: 4px;
-            border: 1px solid #ffae00;
-
-            & > div {
-                vertical-align: middle;
-                white-space: nowrap;
-                span {
-                    font-size: 16px;
-                    color: #f3001e;
-                    margin: 0 1px;
-                    cursor: pointer;
-
-                    &:hover{
-                        text-decoration: underline;
-                    }
-                }
-            }
-        }
-    }
-    .left-info {
-        width: 70%;
-        display: flex;
-        align-items: center;
-        justify-content: left;
-        font-size: 12px;
-        color: #333;
-        overflow-x: auto;
-        & > span {
-            white-space: nowrap;
-        }
-        p {
-            white-space: nowrap;
-            overflow: hidden;
-            text-overflow: ellipsis;
-            & > span {
-                white-space: nowrap;
-            }
-        }
-    }
-    .mid-info {
-        width: 20%;
-        font-size: 12px;
-        color: #333;
-    }
-    .right-info {
-        width: 10%;
-        display: flex;
-        justify-content: right;
-        align-items: center;
-        font-size: 12px;
-        color: #fff;
-        div {
-            white-space: nowrap;
-        }
-    }
 }
 
 .home-container {
     height: calc(100vh - 144px);
     box-sizing: border-box;
     overflow: hidden;
-    .homeCard {
-        width: 100%;
-        padding: 20px;
-        box-sizing: border-box;
-        background: #fff;
-        border-radius: 4px;
 
-        .title {
+    .topChart{
+      height: calc((100% - 40px) / 3);
+      width: 100%;
+      background: #fff;
+      display: flex;
+      justify-content: space-between;
+      align-items: flex-start;
+      margin-bottom: 20px;
+      padding: 20px 20px 90px;
+
+      .chart-item{
+        width: 70%;
+        height: 120%;
+        padding-right: 10px;
+
+        &:last-of-type{
+          width: 30%;
+          height: 100%;
+          padding-right: 0;
+          padding-left: 10px;
+          position: relative;
+        }
+
+        .chart-tit{
+          width: 100%;
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+          .tit{
             font-size: 20px;
             font-weight: bolder;
+          }
+          :deep(.el-switch__core){
+            width: 120px;
+          }
         }
-        .main-card {
-            width: 100%;
-            height: 100%;
-            .cardTop {
-                display: flex;
-                align-items: center;
-                justify-content: space-between;
-                margin-bottom: 10px;
-                background: #daf3ff;
-                padding: 10px 15px;
-                border-radius: 8px;
-
-                .left-info {
-                    .num {
-                        font-weight: bolder;
-                        margin-right: 10px;
-                    }
-                    .place {
-                        font-weight: bolder;
-                    }
-                    .time {
-                        font-weight: bolder;
-                        margin-right: 5px;
-                    }
-                    .name {
-                        font-weight: bolder;
-                        margin: 0 5px;
-                        font-weight: bolder;
-                    }
-                }
-                .mid-info {
-                    span {
-                        font-weight: bolder;
-                    }
-
-                    .grey {
-                        color: #999;
-                    }
-                    .green {
-                        color: #44b100;
-                    }
-                    .blue {
-                        color: #409eff;
-                    }
-                    .red {
-                        color: red;
-                    }
-                }
-                .right-info {
-                    .checkBtn {
-                        padding: 10px 15px;
-                        background: #409eff;
-                        border-radius: 4px;
-                        cursor: pointer;
-                    }
-
-                    .reviewBtn {
-                        margin: 10px 15px;
-                        cursor: pointer;
-                        color: #44b100;
-                    }
-                }
-            }
-            .list {
-                height: calc(100% - 60px);
-                overflow-y: auto;
-            }
-            .pageBtn {
-                position: absolute;
-                bottom: 15px;
-                right: 20px;
-                height: 60px;
-                display: flex;
-                align-items: center;
-                justify-content: right;
-
-                .demo-pagination-block + .demo-pagination-block {
-                    margin-top: 10px;
-                }
-                .demo-pagination-block .demonstration {
-                    margin-bottom: 16px;
-                }
-            }
+        .chart{
+          width: 100%;
+          height: 100%;
         }
-        &:last-of-type {
-            position: relative;
-            padding-top: 0;
-            height: calc(100% - 60px);
+        .el-radio-group{
+          width: 100%;
+          flex-wrap: nowrap;
+          position: absolute;
+          left: 50%;
+          transform: translateX(-50%);
         }
+        :deep(.active-ring-info){
+          .active-ring-name{
+            font-size: 1.5rem !important;
+            text-align: center;
+          }
+        }
+      }
     }
+    .midChart{
+      height: calc((100% - 40px) / 3);
+      width: 100%;
+      background: #fff;
+      display: flex;
+      justify-content: space-between;
+      align-items: flex-start;
+      margin-bottom: 20px;
+      padding: 20px;
+
+      .chart-item{
+        width: 100%;
+        height: 100%;
+        padding: 0 0 20px;
+
+        .chart-tit{
+          width: 100%;
+          height: 15%;
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+          .tit{
+            font-size: 20px;
+            font-weight: bolder;
+          }
+          :deep(.el-switch__core){
+            width: 120px;
+
+          }
+          .top-info {
+            display: flex;
+            font-size: 14px;
+            align-items: center;
+            background: #ffeb87;
+            padding: 4px 15px;
+            margin-left: 20px;
+            border-radius: 2px;
+            border: 1px solid #ffae00;
+            & > div {
+              vertical-align: middle;
+              white-space: nowrap;
+              height: 100%;
+              span {
+                color: #f3001e;
+                margin: 0 4px;
+                font-size: 18px;
+                cursor: pointer;
+                font-weight: bolder;
+
+                &:hover{
+                  text-decoration: underline;
+                }
+              }
+            }
+          }
+          .checkAll{
+            cursor: pointer;
+            &:hover{
+              color: #409eff
+            }
+          }
+        }
+        .chart{
+          width: 100%;
+          height: 85%;
+          margin-top: 10px;
+
+          .el-table{
+            height: 100% !important;
+            :deep(.el-table__inner-wrapper){
+              height: 100% !important;
+              .el-table__header-wrapper{
+                height: 20% !important;
+              }
+              .el-table__body-wrapper{
+                height: 80% !important;
+                .el-scrollbar__view{
+                  height: 100% !important;
+                  .el-table__body{
+                    height: 100% !important;
+
+                    .el-table__row{
+                      height: 20% !important;
+                    }
+                  }
+                }
+              }
+            }
+          }
+          .list {
+            height: 100%;
+            margin-top: 10px;
+            border: 1px solid #ebeef5;
+
+            .list-tit{
+              width: 100%;
+              height: 20%;
+              display: flex;
+              align-items: center;
+              border-bottom: 1px solid #ebeef5;
+
+              span{
+                text-align: center;
+                padding: 10px 0;
+              }
+
+              .w60{
+                width: 60%;
+                border-right: 1px solid #ebeef5;
+              }
+              .w20{
+                width: 20%;
+                border-right: 1px solid #ebeef5;
+
+                &:last-of-type{
+                  border-right: none;
+                }
+              }
+              .w15{
+                width: 15%;
+                border-right: 1px solid #ebeef5;
+                text-align: center;
+                white-space: nowrap;
+                overflow: hidden;
+                text-overflow: ellipsis;
+              }
+              .w10{
+                width: 10%;
+                border-right: 1px solid #ebeef5;
+                text-align: center;
+                white-space: nowrap;
+                overflow: hidden;
+                text-overflow: ellipsis;
+              }
+            }
+
+            .cardTop {
+              display: flex;
+              width: 100%;
+              height: 20%;
+              align-items: center;
+              border-bottom: 1px solid #ebeef5;
+
+              &:last-of-type{
+                border-bottom: none;
+              }
+              span{
+                text-align: center;
+                padding: 10px 0;
+              }
+              .l-info{
+                width: 60%;
+                height: 100%;
+                border-right: 1px solid #ebeef5;
+                display: flex;
+                align-items: center;
+                padding: 0 20px;
+
+                .num {
+                  font-weight: bolder;
+                  margin-right: 10px;
+                }
+                .place {
+                  font-weight: bolder;
+                }
+                .time {
+                  font-weight: bolder;
+                  margin-right: 5px;
+                }
+                .name {
+                  font-weight: bolder;
+                  margin: 0 5px;
+                  font-weight: bolder;
+                }
+              }
+              .m-info{
+                height: 100%;
+                width: 20%;
+                display: flex;
+                align-items: center;
+                border-right: 1px solid #ebeef5;
+                justify-content: center;
+
+                span {
+                  font-weight: bolder;
+                }
+
+                .grey {
+                  color: #999;
+                }
+                .green {
+                  color: #44b100;
+                }
+                .blue {
+                  color: #409eff;
+                }
+                .red {
+                  color: red;
+                }
+              }
+              .r-info{
+                width: 20%;
+                text-align: center;
+
+                .reviewBtn {
+                  color: #44b100;
+                }
+              }
+              .w10{
+                width: 10%;
+                border-right: 1px solid #ebeef5;
+                text-align: center;
+                white-space: nowrap;
+                overflow: hidden;
+                text-overflow: ellipsis;
+              }
+              .w15{
+                width: 15%;
+                border-right: 1px solid #ebeef5;
+                text-align: center;
+                white-space: nowrap;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                .el-button{
+                  margin-left: 0 !important;
+                  padding: 12px 0;
+                  &:last-of-type{
+                    margin-left: 12px !important;
+                  }
+                }
+              }
+            }
+          }
+          .pageBtn {
+            position: absolute;
+            bottom: 15px;
+            right: 20px;
+            height: 60px;
+            display: flex;
+            align-items: center;
+            justify-content: right;
+
+            .demo-pagination-block + .demo-pagination-block {
+              margin-top: 10px;
+            }
+            .demo-pagination-block .demonstration {
+              margin-bottom: 16px;
+            }
+          }
+        }
+      }
+    }
+
     .el-row {
         display: flex;
         align-items: center;
diff --git a/src/views/specialWorkSystem/specialIndex/index.vue b/src/views/specialWorkSystem/specialIndex/index.vue
new file mode 100644
index 0000000..e7f696e
--- /dev/null
+++ b/src/views/specialWorkSystem/specialIndex/index.vue
@@ -0,0 +1,1144 @@
+<template>
+    <div class="home-container">
+        <div class="topChart">
+          <div class="chart-item">
+            <div class="chart-tit">
+              <span class="tit">八大作业各分类分布图</span>
+              <div class="filter-part filter-part2">
+                <el-cascader v-model="chartSearch1.searchDep" :options="departmentList" :props="casProps" :show-all-levels="false" size="small"/>
+              </div>
+            </div>
+            <div class="chart" :id="zyfb"></div>
+            <el-radio-group v-model="chartSearch1.period" size="small">
+              <el-radio label="week" border>近7天</el-radio>
+              <el-radio label="month" border>近30天</el-radio>
+              <el-radio label="season" border>近90天</el-radio>
+              <el-radio label="year" border>近一年</el-radio>
+            </el-radio-group>
+          </div>
+          <div class="chart-item">
+            <div class="chart-tit">
+              <span class="tit">各事业部关联作业分析</span>
+              <div class="filter-part">
+                <el-cascader v-model="chartSearch2.searchDep" :options="departmentList" :props="casProps" :show-all-levels="false" size="small"/>
+                <el-select v-model="chartSearch2.type" size="small">
+                  <el-option
+                      v-for="item in workType1"
+                      :key="item.id"
+                      :label="item.name"
+                      :value="item.id"
+                  />
+                </el-select>
+              </div>
+            </div>
+            <div class="chart" :id="slfx"></div>
+          </div>
+        </div>
+        <div class="topChart">
+          <div class="chart-item">
+            <div class="chart-tit">
+              <span class="tit">关联作业趋势图</span>
+              <div class="filter-part filter-part2">
+                <el-cascader v-model="chartSearch3.searchDep" :options="departmentList" :props="casProps" :show-all-levels="false" size="small"/>
+              </div>
+            </div>
+            <div class="chart" :id="zyqs"></div>
+          </div>
+          <div class="chart-item">
+            <div class="chart-tit">
+              <span class="tit">异常警报关联人</span>
+              <div class="filter-part">
+                <el-switch
+                    v-model="chartSearch4.type"
+                    class="ml-2"
+                    inline-prompt
+                    style="--el-switch-on-color: #13ce66; --el-switch-off-color: #13ce66"
+                    active-text="作业人"
+                    inactive-text="监护人"
+                />
+                <el-select v-model="chartSearch4.period" size="small">
+                  <el-option label="近7天" value="week"/>
+                  <el-option label="近30天" value="month"/>
+                  <el-option label="近90天" value="season"/>
+                  <el-option label="近1年" value="year"/>
+                </el-select>
+                <el-select v-model="chartSearch4.workType" size="small">
+                  <el-option
+                      v-for="item in workType1"
+                      :key="item.id"
+                      :label="item.name"
+                      :value="item.id"
+                  />
+                </el-select>
+              </div>
+            </div>
+            <div class="chart">
+              <el-table ref="multipleTableRef" :data="warningData" style="width: 100%" :header-cell-style="{ background: '#fafafa' }">
+                <el-table-column property="name" label="姓名" width="180" align="center"/>
+                <el-table-column property="depName" label="所属部门" align="center"/>
+                <el-table-column property="applyUname" label="异常报警次数" align="center"/>
+                <el-table-column property="operators" label="角色" align="center"/>
+                <el-table-column label="是否持证" align="center" width="180">
+                  <template #default="scope">
+                    <el-tag :type="scope.row.status==2?'success':(scope.row.status==8||scope.row.status==9)?'warning':'danger'">{{ scope.row.statusDesc }}</el-tag>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </div>
+<!--            <div class="chart" :id="slfx"></div>-->
+          </div>
+        </div>
+        <div style="height: 100%">
+            <div class="homeCard">
+                <el-row>
+                  <el-col :span="5" style="display:flex;align-items: center">
+                    <span style="white-space: nowrap">作业类型:</span>
+                    <div class="grid-content topInfo">
+                      <el-select v-model="searchWord">
+                        <el-option
+                            v-for="item in workType"
+                            :key="item.id"
+                            :label="item.name"
+                            :value="item.id"
+                        />
+                      </el-select>
+                    </div>
+                  </el-col>
+                  <el-col :span="5" style="display:flex;align-items: center">
+                    <span style="white-space: nowrap">作业状态:</span>
+                    <div class="grid-content topInfo">
+                      <el-select v-model="searchStatus">
+                        <el-option
+                            v-for="item in workStatus"
+                            :key="item.value"
+                            :label="item.name"
+                            :value="item.value"
+                        />
+                      </el-select>
+                    </div>
+                  </el-col>
+                  <el-col :span="5" style="display:flex;align-items: center">
+                    <span style="white-space: nowrap">作业部门:</span>
+                    <div class="grid-content topInfo">
+                      <el-cascader v-model="searchDep" :options="departmentList" :props="casProps" :show-all-levels="false"/>
+                    </div>
+                  </el-col>
+                  <el-col :span="6" style="display:flex;align-items: center;">
+                    <span style="white-space: nowrap;margin-left: 20px">申请时间:</span>
+                    <div class="grid-content topInfo">
+                      <el-date-picker
+                          v-model="searchDate"
+                          type="daterange"
+                          unlink-panels
+                          range-separator="至"
+                          start-placeholder="开始日期"
+                          end-placeholder="结束日期"
+                          format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss"
+                      />
+                    </div>
+                  </el-col>
+                  <el-button type="primary" style="margin-left: 20px" @click="searchRecord">查询</el-button>
+                  <el-button plain @click="clearSearch">重置</el-button>
+                </el-row>
+                <div class="main-card">
+                    <el-row class="cardTop" style="justify-content: space-between">
+                        <el-col :span="2" class="mainCardBtn">
+                            <el-button type="primary" :icon="Plus" size="default" @click="toApply()">新作业申请</el-button>
+                        </el-col>
+                        <el-col :span="22" style="display: flex;justify-content: end;align-items: center">
+                          <div class="top-info">
+                            <el-icon :size="18" color="#F3001E" style="margin-right: 4px"><BellFilled /></el-icon>
+                            作业编号
+                            <div v-if="unchecked != 0">
+                              <el-tooltip
+                                class="box-item"
+                                effect="light"
+                                content="查看预警详情"
+                                placement="bottom-start"
+                            ><span>123456</span></el-tooltip>
+                            </div>
+                            可燃气体浓度超过18%
+                            ,请及时处理!
+                          </div>
+                          <el-button type="primary" :icon="Refresh" size="default" @click="reLoadData()" />
+                        </el-col>
+                    </el-row>
+                    <el-table ref="multipleTableRef" :data="applyData" style="width: 100%" :header-cell-style="{ background: '#fafafa' }">
+                        <el-table-column property="workPermitNo" label="作业证编号" width="180" align="center"/>
+                      <el-table-column property="depName" label="部门" align="center"/>
+                        <el-table-column property="applyUname" label="申请人" align="center"/>
+                        <el-table-column property="operators" label="作业人" align="center"/>
+                        <el-table-column property="workTypeDesc" label="作业类型" align="center"/>
+                        <el-table-column property="workLevelDesc" label="作业等级" align="center"/>
+                        <el-table-column property="applyTime" label="申请时间" width="180" align="center"/>
+                        <el-table-column property="startTime" label="作业开始时间" width="180" align="center"/>
+                        <el-table-column property="endTime" label="作业结束时间" width="180" align="center"/>
+                        <el-table-column label="作业状态" align="center" width="180">
+                            <template #default="scope">
+                                <el-tag :type="scope.row.status==2?'success':(scope.row.status==8||scope.row.status==9)?'warning':'danger'">{{ scope.row.statusDesc }}</el-tag>
+                            </template>
+                        </el-table-column>
+                        <el-table-column property="stopReason" label="中止原因" align="center"/>
+                        <el-table-column label="安全预警" align="center" width="180">
+                          <template #default="scope">
+                            <el-tag :type="scope.row.saftyWarning==0?'success':(scope.row.saftyWarning==1||scope.row.saftyWarning==2)?'warning':'danger'">{{ scope.row.saftyWarning==0?'正常':'报警' }}</el-tag>
+                          </template>
+                        </el-table-column>
+                        <el-table-column fixed="right" label="操作" align="center" width="250">
+                            <template #default="scope">
+                                <el-button link type="primary" size="small" :icon="View" @click="viewRecord(scope.row)">查看</el-button>
+                                <el-button link type="primary" size="small" :icon="FolderChecked" @click="handleReview(scope.row)">验收</el-button>
+                            </template>
+                        </el-table-column>
+                    </el-table>
+                    <div class="pageBtn">
+                        <el-pagination v-model:currentPage="pageIndex1" v-model:page-size="pageSize1" :page-sizes="[10, 15]" small="false" background layout="total, sizes, prev, pager, next, jumper" :total="totalSize1" @size-change="handleSizeChange1" @current-change="handleCurrentChange1" />
+                    </div>
+                </div>
+            </div>
+        </div>
+        <el-dialog v-model="dialogDetails" title="作业申请详情" center>
+            <fire v-if="dialogType == 1" :details = details></fire>
+            <space v-else-if="dialogType == 2" :details = details></space>
+            <hoist v-else-if="dialogType == 3" :details = details></hoist>
+            <ground v-else-if="dialogType == 4" :details = details></ground>
+            <broken v-else-if="dialogType == 5" :details = details></broken>
+            <height v-else-if="dialogType == 6" :details = details></height>
+            <power v-else-if="dialogType == 7" :details = details></power>
+            <plate v-else :details = details></plate>
+            <template #footer>
+              <span class="dialog-footer">
+                <el-button type="primary" @click="dialogDetails = false"
+                >确认</el-button
+                >
+              </span>
+            </template>
+        </el-dialog>
+        <el-dialog v-model="dialogReview" title="填报验收意见" center>
+          <el-form ref="reviewFormRef" :model="reviewForm" :rules="reviewRules" label-width="120px">
+            <el-form-item label="填报验收意见:" prop="advice">
+              <el-input
+                  v-model="reviewForm.advice"
+                  :autosize="{ minRows: 4, maxRows: 10 }"
+                  type="textarea"
+                  placeholder="请填写验收意见"
+              />
+            </el-form-item>
+          </el-form>
+          <template #footer>
+              <span class="dialog-footer">
+                <el-button type="primary" @click="submitReview(reviewFormRef)">提交验收</el-button>
+              </span>
+          </template>
+        </el-dialog>
+    </div>
+</template>
+
+<script lang="ts">
+import {toRefs, reactive, defineComponent, ref, onMounted, defineAsyncComponent} from 'vue';
+import { storeToRefs } from 'pinia';
+import { initBackEndControlRoutes } from '/@/router/backEnd';
+import { useUserInfo } from '/@/stores/userInfo';
+import { Session } from '/@/utils/storage';
+import { useRouter } from 'vue-router';
+import { Edit, View, Plus, Delete, Refresh, Search, Finished, Download, FolderChecked } from '@element-plus/icons-vue';
+import { ElTable, ElMessage } from 'element-plus';
+import { workApplyApi } from '/@/api/specialWorkSystem/workApply';
+import type { TabsPaneContext } from 'element-plus';
+import type { FormInstance, FormRules } from 'element-plus'
+import {teamManageApi} from "/@/api/systemManage/basicDateManage/personShiftManage/teamManage";
+import Cookies from 'js-cookie';
+import axios from 'axios';
+import * as echarts from "echarts";
+
+// 定义接口来定义对象的类型
+interface stateType {
+    applyData: Array<string>;
+    workTimeList: Array<string>;
+    multipleSelection: Array<any>;
+    casProps: {};
+    approveInfo: Object;
+    dialogDetails: boolean;
+    dialogReview: boolean;
+    pageIndex1: number;
+    pageSize1: number;
+    chosenIndex: null | number;
+    searchWord: number | null;
+    searchStatus: number | null;
+    chartSearch1: object;
+    chartSearch2: object;
+    chartSearch3: object;
+    chartSearch4: object;
+    searchDep2: number | null;
+    searchDep: number | null;
+    searchDate: Array<any>,
+    totalSize1: number;
+    details: {};
+    workType: Array<type>;
+    workType1: Array<type>;
+    dialogType: number | null;
+    departmentList: Array<any>;
+    departmentRecursionList: Array<DepartmentState>;
+    workStatus: Array<status>;
+    reviewForm: object;
+    reviewRules: object;
+}
+interface type {
+    id: number;
+    name: string;
+}
+interface status {
+  name: string
+  value: number
+}
+interface DepartmentState {
+    depId: number;
+    depName: string;
+}
+interface User {
+  name: string;
+  list: [];
+  info: string;
+}
+export default defineComponent({
+    name: 'specialIndex',
+    components: {
+        fire: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/fireLog.vue')),
+        space: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/spaceLog.vue')),
+        hoist: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/hoistLog.vue')),
+        ground: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/groundLog.vue')),
+        broken: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/brokenLog.vue')),
+        height: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/heightLog.vue')),
+        power: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/powerLog.vue')),
+        plate: defineAsyncComponent(() => import('/@/views/specialWorkSystem/workTicket/wdsq/components/plateLog.vue'))
+    },
+    setup() {
+        const userInfo = useUserInfo();
+        const { userInfos } = storeToRefs(userInfo);
+        const router = useRouter();
+        const reviewFormRef = ref<FormInstance>()
+        const zyfb = ref("eChartZyfb" + Date.now() + Math.random())
+        const slfx = ref("eChartSlfx" + Date.now() + Math.random())
+        const zyqs = ref("eChartZyqs" + Date.now() + Math.random())
+        const state = reactive<stateType>({
+            pageIndex1: 1,
+            pageSize1: 10,
+            totalSize1: 0,
+            dialogType: null,
+            dialogReview: false,
+            departmentList: [],
+            departmentRecursionList: [],
+            chosenIndex: null,
+            searchWord: null,
+            searchStatus: null,
+            chartSearch1: {
+              searchDep: null,
+              period: 'month'
+            },
+            chartSearch2: {
+              searchDep: null,
+              type: 0
+            },
+            chartSearch3: {
+              searchDep: null
+            },
+            chartSearch4: {
+              searchDep: null
+            },
+            searchDep2: null,
+            searchDep: null,
+            searchDate: [],
+            applyData: [],
+            workTimeList: [],
+            multipleSelection: [],
+            approveInfo: {
+                approvalSteps: [],
+                operators: []
+            },
+            casProps: {
+                expandTrigger: 'hover',
+                emitPath: false,
+                value: 'depId',
+                label: 'depName',
+                checkStrictly: true
+            },
+            dialogDetails: false,
+            details: {},
+            workType1: [
+              { id: 0, name: '所有作业' },
+              { id: 1, name: '动火作业' },
+              { id: 2, name: '受限空间作业' },
+              { id: 3, name: '吊装作业' },
+              { id: 4, name: '动土作业' },
+              { id: 5, name: '断路作业' },
+              { id: 6, name: '高处作业' },
+              { id: 7, name: '临时用电作业' },
+              { id: 8, name: '盲板抽堵作业' }
+            ],
+            workType: [
+                { id: 1, name: '动火作业' },
+                { id: 2, name: '受限空间作业' },
+                { id: 3, name: '吊装作业' },
+                { id: 4, name: '动土作业' },
+                { id: 5, name: '断路作业' },
+                { id: 6, name: '高处作业' },
+                { id: 7, name: '临时用电作业' },
+                { id: 8, name: '盲板抽堵作业' }
+            ],
+            workStatus: [
+              {
+                name: '作业进行中',
+                value: 0
+              },
+              {
+                name: '作业终止',
+                value: 1
+              },
+              {
+                name: '作业结束待验收',
+                value: 2
+              },
+              {
+                name: '作业完成',
+                value: 3
+              }
+            ],
+            reviewForm: {
+              advice: ''
+            },
+            reviewRules:{
+              advice: [{ required: true, message: '请填写验收意见', trigger: 'blur' }]
+            }
+        });
+      // 页面载入时执行方法
+      onMounted(() => {
+        getListByPage();
+        getAllDepartment();
+        initZyfb()
+        initSlfx()
+        initZyqs()
+      });
+
+      type EChartsOption = echarts.EChartsOption
+      const initZyfb =()=>{
+        let dom = document.getElementById(zyfb.value);
+        let myChart = echarts.init(dom);
+        let option: EChartsOption;
+        option = {
+          tooltip: {
+            trigger: 'item'
+          },
+          legend: {
+            orient: 'vertical',
+            left: 'left',
+            top: 'center'
+          },
+          series: [
+            {
+              name: 'Access From',
+              type: 'pie',
+              radius: ['40%', '70%'],
+              avoidLabelOverlap: false,
+              itemStyle: {
+                borderRadius: 1,
+                borderColor: '#fff',
+                borderWidth: 2
+              },
+              label: {
+                show: false,
+                position: 'center'
+              },
+              emphasis: {
+                label: {
+                  show: true,
+                  fontSize: 40,
+                  fontWeight: 'bold'
+                }
+              },
+              labelLine: {
+                show: true
+              },
+              data: [
+                { value: 1048, name: '动火作业' },
+                { value: 735, name: '受限空间作业' },
+                { value: 580, name: '吊装作业' },
+                { value: 484, name: '动土作业' },
+                { value: 735, name: '断路作业' },
+                { value: 580, name: '高处作业' },
+                { value: 484, name: '临时用电作业' },
+                { value: 300, name: '盲板抽堵作业' }
+              ]
+            }
+          ]
+        }
+
+        option && myChart.setOption(option);
+        window.addEventListener("resize",function (){
+          myChart.resize();
+        });
+      }
+      const initSlfx =()=>{
+        let dom = document.getElementById(slfx.value);
+        let myChart = echarts.init(dom);
+        let option: EChartsOption;
+        option = {
+          tooltip: {
+            trigger: 'axis',
+            axisPointer: {
+              type: 'shadow'
+            }
+          },
+          grid: {
+            left: '3%',
+            right: '4%',
+            bottom: '3%',
+            containLabel: true
+          },
+          xAxis: [
+            {
+              type: 'category',
+              data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
+              axisTick: {
+                alignWithLabel: true
+              }
+            }
+          ],
+          yAxis: [
+            {
+              type: 'value'
+            }
+          ],
+          series: [
+            {
+              name: 'Direct',
+              type: 'bar',
+              barWidth: '60%',
+              data: [10, 52, 200, 334, 390, 330, 220]
+            }
+          ]
+        }
+
+        option && myChart.setOption(option);
+        window.addEventListener("resize",function (){
+          myChart.resize();
+        });
+      }
+      const initZyqs =()=>{
+        let dom = document.getElementById(zyqs.value);
+        let myChart = echarts.init(dom);
+        let option: EChartsOption;
+        option = {
+          xAxis: {
+            type: 'category',
+            data: ['四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月', '一月', '二月', '三月']
+          },
+          yAxis: {
+            type: 'value'
+          },
+          grid: {
+            top: '8%',
+            bottom: '8%'
+          },
+          series: [
+            {
+              data: [150, 230, 224, 218, 135, 147, 230, 224, 218, 135, 147, 260],
+              type: 'line'
+            }
+          ]
+        }
+
+        option && myChart.setOption(option);
+        window.addEventListener("resize",function (){
+          myChart.resize();
+        });
+      }
+        // 刷新
+        const reLoadData = async () => {
+            getListByPage();
+        };
+
+        // 填写表单
+        const toApply = () => {
+            router.push({
+                path: 'zysq'
+            });
+        };
+
+        // 获取部门列表
+        const getAllDepartment = async () => {
+            let res = await teamManageApi().getAllDepartment();
+            if (res.data.code === '200') {
+                state.departmentList = JSON.parse(JSON.stringify(res.data.data))
+                // recursion(state.departmentList);
+            } else {
+                ElMessage({
+                    type: 'warning',
+                    message: res.data.msg
+                });
+            }
+        };
+
+        // 分页获取列表
+        const getListByPage = async () => {
+            const dateRange = JSON.parse(JSON.stringify(state.searchDate))
+            if(dateRange[1]){dateRange[1] = dateRange[1].replace('00:00:00','23:59:59')}
+            const data = { pageSize: state.pageSize1, pageIndex: state.pageIndex1, searchParams: { workType: state.searchWord, applyDepId: state.searchDep,applyStartTime: dateRange[0],applyEndTime: dateRange[1]} };
+            let res = await workApplyApi().getApplyList(data);
+            if (res.data.code === '200') {
+                state.applyData = JSON.parse(JSON.stringify(res.data.data));
+                state.applyData = state.applyData.map((item) => {
+                    if (item.operators == null || item.operators == []) {
+                        item.operators = [];
+                    } else {
+                        item.operators = Array.from(item.operators, ({ operatorUname }) => operatorUname);
+                    }
+                    return item;
+                });
+                state.totalSize1 = res.data.total;
+            } else {
+                ElMessage({
+                    type: 'warning',
+                    message: res.data.msg
+                });
+            }
+        };
+
+        // 表格数据格式化
+        const toNames = (row, column, cellValue, index) => {
+            if (row.list == []) {
+                return [];
+            } else {
+                const nameList = [];
+                for (let i = 0; i < row.list.length; i++) {
+                    for (let t = 0; t < state.workTimeList.length; t++) {
+                        if (row.list[i] == state.workTimeList[t].id) {
+                            nameList.push(state.workTimeList[t].name);
+                        }
+                    }
+                }
+                return nameList.join();
+            }
+        };
+
+        // 关键词查询记录
+        const searchRecord = async () => {
+            if (state.searchWord == null && state.searchStatus == null && state.searchDep == null && state.searchDate == []) {
+                ElMessage({
+                    type: 'warning',
+                    message: '请输入查询关键词'
+                });
+            } else {
+                getListByPage();
+            }
+        };
+        // 重置搜索
+        const clearSearch = async () => {
+            state.searchWord = null;
+            state.searchDep = null;
+            state.searchDate = []
+            getListByPage();
+        };
+
+        const handleSizeChange1 = (val: number) => {
+            state.pageSize1 = val;
+            getListByPage();
+        };
+        const handleCurrentChange1 = (val: number) => {
+            state.pageIndex1 = val;
+            getListByPage();
+        };
+
+        // 查看记录
+        const viewRecord = (row: any) => {
+            state.dialogType = row.workType
+            state.details = JSON.parse(JSON.stringify(row));
+            if(state.details.workDetail.otherSpecialWork == '' || !state.details.workDetail.otherSpecialWork){
+                state.details.workDetail.otherSpecialWork=[]
+            }
+            else {
+                const a = state.details.workDetail.otherSpecialWork
+                state.details.workDetail.otherSpecialWork = a.split(',').map((item) => {
+                    return state.workType.find((i: { id: number }) => i.id === Number(item))?.name;
+                });
+            }
+            if(state.details.workDetail.involvedDepIds == '' || !state.details.workDetail.involvedDepIds){
+                state.details.workDetail.involvedDepIds=[]
+            }
+            else {
+                const a = state.details.workDetail.involvedDepIds
+                state.details.workDetail.involvedDepIds = a.split(',').map((item) => {
+                    return state.departmentRecursionList.find((i: { depId: number }) => i.depId === Number(item))?.depName;
+                });
+            }
+            if(state.details.workDetail.csDepId){
+                state.details.workDetail.csDepId = state.departmentRecursionList.find((i: { depId: number }) => i.depId === Number(state.details.workDetail.csDepId))?.depName;
+            }
+            if(state.details.workDetail.operationDepId){
+                state.details.workDetail.operationDepId = state.departmentRecursionList.find((i: { depId: number }) => i.depId === Number(state.details.workDetail.operationDepId))?.depName;
+            }
+            if(state.details.workDetail.gbPath){
+                state.details.workDetail.gbPath = state.details.workDetail.gbPath.split(',')
+            }
+            if(state.details.workDetail.bcPath){
+                state.details.workDetail.bcPath = state.details.workDetail.bcPath.split(',')
+            }
+            if(state.details.workDetail.bpLocationMapPath){
+                state.details.workDetail.bpLocationMapPath = state.details.workDetail.bpLocationMapPath.split(',')
+            }
+            state.dialogDetails = true;
+        };
+
+        const handleReview = (row)=>{
+          state.dialogReview = true
+        }
+
+      const submitReview = async (formEl: FormInstance | undefined) => {
+        if (!formEl) return
+        await formEl.validate((valid, fields) => {
+          if (valid) {
+            console.log('submit!')
+          } else {
+            console.log('error submit!', fields)
+          }
+        })
+      }
+
+        // 折线图
+        const renderMenu = async (value: string) => {
+            Session.set('projectId', value);
+            userInfos.value.projectId = value;
+            await initBackEndControlRoutes();
+        };
+
+        return {
+            View,
+            Edit,
+            Delete,
+            Refresh,
+            Plus,
+            Finished,
+            Download,
+            FolderChecked,
+            reviewFormRef,
+            zyfb,
+            slfx,
+            zyqs,
+            handleReview,
+            submitReview,
+            reLoadData,
+            toApply,
+            toNames,
+            searchRecord,
+            clearSearch,
+            viewRecord,
+            getListByPage,
+            handleSizeChange1,
+            handleCurrentChange1,
+            ...toRefs(state)
+        };
+    }
+});
+</script>
+
+<style scoped lang="scss">
+$homeNavLengh: 8;
+.home-container {
+    height: calc(100vh - 144px);
+    box-sizing: border-box;
+    overflow: hidden;
+    .demo-tabs {
+        width: 100%;
+        height: 100%;
+
+        &::v-deep(.el-tabs__content) {
+            height: calc(100% - 60px);
+        }
+
+        .el-tab-pane {
+            height: 100%;
+        }
+    }
+    .topChart{
+      width: 100%;
+      display: flex;
+      justify-content: space-between;
+      align-items: flex-start;
+      margin-bottom: 20px;
+      height: 40%;
+
+      .chart-item{
+        width: calc(50% - 10px);
+        height: 100%;
+        margin-right: 10px;
+        position: relative;
+        background: #fff;
+        padding: 20px;
+
+        &:last-of-type{
+          margin-right: 0;
+        }
+
+        .chart-tit{
+          width: 100%;
+          display: flex;
+          align-items: flex-start;
+          justify-content: space-between;
+          .tit{
+            font-size: 16px;
+            font-weight: bolder;
+          }
+          .filter-part{
+            display: flex;
+            align-items: center;
+            justify-content: right;
+            :deep(.el-cascader){
+              width: 35% !important;
+            }
+            .el-select{
+              width: 35% !important;
+              margin-left: 10px;
+            }
+            .el-switch{
+              width: 25% !important;
+
+              :deep(.el-switch__core){
+                width: 100% !important;
+              }
+            }
+          }
+          .filter-part2{
+            :deep(.el-cascader){
+              width: 100% !important;
+            }
+          }
+
+        }
+        .chart{
+          width: 100%;
+          height: 88%;
+        }
+        .el-radio-group{
+          width: 20%;
+          display: flex;
+          flex-flow: column nowrap;
+          align-items: flex-start;
+          position: absolute;
+          right: 10px;
+          top: 50%;
+          transform: translateY(-30%);
+
+          .el-radio{
+            width: 100%;
+            margin-bottom: 4px;
+          }
+        }
+        :deep(.active-ring-info){
+          .active-ring-name{
+            font-size: 1.5rem !important;
+            text-align: center;
+          }
+        }
+      }
+    }
+    .homeCard {
+        width: 100%;
+        padding: 20px;
+        box-sizing: border-box;
+        background: #fff;
+        border-radius: 4px;
+
+        .main-card {
+            width: 100%;
+            height: 100%;
+            .cardTop {
+                display: flex;
+                align-items: center;
+                justify-content: space-between;
+                margin-bottom: 20px;
+                .mainCardBtn {
+                    margin: 0;
+                }
+
+              .top-info {
+                display: flex;
+                font-size: 16px;
+                font-weight: bolder;
+                align-items: center;
+                padding: 6px 10px;
+                background: #ffeb87;
+                border-radius: 4px;
+                border: 1px solid #ffae00;
+                margin-right: 20px;
+
+                & > div {
+                  vertical-align: middle;
+                  white-space: nowrap;
+                  span {
+                    font-size: 22px;
+                    color: #f3001e;
+                    margin: 0 2px;
+                    cursor: pointer;
+
+                    &:hover{
+                      text-decoration: underline;
+                    }
+                  }
+                }
+              }
+            }
+            .pageBtn {
+                height: 60px;
+                display: flex;
+                align-items: center;
+                justify-content: right;
+
+                .demo-pagination-block + .demo-pagination-block {
+                    margin-top: 10px;
+                }
+                .demo-pagination-block .demonstration {
+                    margin-bottom: 16px;
+                }
+            }
+        }
+    }
+    .stepItem {
+        display: flex;
+        align-items: flex-start;
+        margin-top: 30px;
+        margin-left: 30px;
+        padding-bottom: 30px;
+        padding-left: 40px;
+        border-left: 1px solid #a0cfff;
+        position: relative;
+        &:first-of-type {
+            margin-top: 30px;
+        }
+        &:first-of-type {
+            margin-bottom: 0;
+            border-left: none;
+        }
+        .stepNum {
+            position: absolute;
+            width: 40px;
+            height: 40px;
+            border-radius: 20px;
+            box-sizing: border-box;
+            font-size: 18px;
+            color: #333;
+            border: 1px solid #a0cfff;
+            line-height: 38px;
+            text-align: center;
+            left: -20px;
+            top: -30px;
+            background: #d9ecff;
+        }
+        .stepCard {
+            width: 100%;
+            margin-top: -30px;
+
+            .box-card {
+                width: 100%;
+
+                .card-header {
+                    display: flex;
+                    justify-content: space-between;
+                    align-items: center;
+
+                    span {
+                        font-weight: bold;
+                        margin-left: 10px;
+                    }
+                }
+
+                .text {
+                    width: 100%;
+                    font-size: 14px;
+                    margin-bottom: 10px;
+                    padding-left: 10px;
+
+                    span {
+                        font-weight: bolder;
+                        color: #409eff;
+                    }
+
+                    &:last-of-type {
+                        margin-bottom: 0;
+                    }
+                }
+                .approveUnit {
+                    width: 100%;
+                    font-size: 14px;
+                    margin-bottom: 20px;
+                    padding: 10px 15px;
+                    border: 1px solid #fff;
+                    background: #ecf8ff;
+                    border-radius: 6px;
+                    .item-tit {
+                        width: 100%;
+                        display: flex;
+                        color: #409eff;
+                        align-items: flex-start;
+                        justify-content: space-between;
+                        padding-bottom: 10px;
+                        border-bottom: 1px solid #a0cfff;
+
+                        & > span {
+                            flex: 1;
+                            &:last-of-type{
+                                text-align: center;
+                            }
+                        }
+                        & > div {
+                            flex: 1;
+                            text-align: center;
+                        }
+                    }
+                    .item-cont {
+                        width: 100%;
+                        display: flex;
+                        align-items: center;
+                        justify-content: space-between;
+                        padding: 10px 0;
+                        border-bottom: 1px solid #c6e2ff;
+
+                        & > span {
+                            flex: 1;
+                            &:last-of-type{
+                                text-align: center;
+                            }
+                        }
+                        & > div {
+                            flex: 1;
+                            text-align: center;
+
+                            & > div {
+                                text-align: left;
+                                width: 100%;
+                                display: flex;
+                                justify-content: center;
+                                align-items: center;
+                                span {
+                                    width: 45%;
+                                    &:first-of-type {
+                                        width: 30%;
+                                    }
+                                }
+                            }
+                        }
+                        &:last-of-type {
+                            border-bottom: 0;
+                        }
+                    }
+                }
+                .approveItem {
+                    width: 100%;
+                    font-size: 14px;
+                    margin-bottom: 20px;
+                    padding: 10px 15px;
+                    background: #ecf8ff;
+                    border: 1px solid #fff;
+                    border-radius: 6px;
+                    .item-tit {
+                        width: 100%;
+                        display: flex;
+                        color: #409eff;
+                        align-items: flex-start;
+                        justify-content: space-between;
+                        padding-bottom: 10px;
+                        border-bottom: 1px solid #a0cfff;
+
+                        & > span {
+                            flex: 1;
+                        }
+                        & > div {
+                            flex: 2;
+                            text-align: center;
+                        }
+                    }
+                    .item-cont {
+                        width: 100%;
+                        display: flex;
+                        align-items: center;
+                        justify-content: space-between;
+                        padding: 10px 0;
+                        border-bottom: 1px solid #c6e2ff;
+
+                        & > span {
+                            flex: 1;
+                        }
+                        & > div {
+                            flex: 2;
+                            text-align: center;
+
+                            & > div {
+                                text-align: left;
+                                width: 100%;
+                                display: flex;
+                                justify-content: center;
+                                align-items: flex-start;
+                                margin-bottom: 10px;
+                                span {
+                                    width: 50%;
+                                    &:first-of-type {
+                                        width: 25%;
+                                    }
+                                }
+                            }
+                        }
+                        &:last-of-type {
+                            border-bottom: 0;
+                        }
+                    }
+                }
+            }
+        }
+        &:hover .card-header {
+            color: #0098f5;
+        }
+        &:hover .stepNum {
+            border: 2px solid #0098f5;
+            color: #0098f5;
+        }
+    }
+    .el-row {
+        display: flex;
+        align-items: center;
+        margin-bottom: 20px;
+        &:last-child {
+            margin-bottom: 0;
+        }
+        .grid-content {
+            align-items: center;
+            min-height: 36px;
+        }
+
+        .topInfo {
+            width: 100%;
+            display: flex;
+            align-items: center;
+            font-size: 16px;
+            font-weight: bold;
+
+            & > div {
+                white-space: nowrap;
+                margin-right: 20px;
+            }
+        }
+    }
+}
+.el-card {
+    border: 0;
+}
+.el-input{
+    width: 100% !important;
+}
+::v-deep(.el-date-editor){
+    width: 100%;
+}
+.el-select{
+    width: 100%;
+}
+:deep(.el-cascader){
+    width: 100% !important;
+}
+</style>
diff --git a/src/views/system/user/component/userDialog.vue b/src/views/system/user/component/userDialog.vue
index 86cffbd..fae4942 100644
--- a/src/views/system/user/component/userDialog.vue
+++ b/src/views/system/user/component/userDialog.vue
@@ -99,7 +99,6 @@
 interface roleData {}
 interface dutyData {}
 interface sexData {}
-interface type {}
 interface UserState {
     title: string;
     disabled: boolean;
@@ -113,7 +112,6 @@
         phone: string;
         email: string;
         gender: number | null;
-        type: number | null;
         password: string;
         expireTime: string;
         status: number;
@@ -126,7 +124,6 @@
     roleData: Array<roleData>;
     dutyData: Array<dutyData>;
     sexList: Array<sexData>;
-    userTypeList: Array<type>;
 }
 
 export default defineComponent({
@@ -148,7 +145,6 @@
                 gender: null, // 性别
                 password: '', // 账户密码
                 positionId: null, // 岗位
-                type: null, // 用户类型
                 expireTime: '', // 账户过期
                 status: 1 // 用户状态
             },
@@ -159,7 +155,6 @@
                 depId: [{ required: true, message: '请选择部门', trigger: 'change' }],
                 positionId: [{ required: true, message: '请选择职务', trigger: 'change' }],
                 phone: [{ required: true, message: '请填写手机号', trigger: 'blur' }],
-                type: [{ required: true, message: '请填写用户类型', trigger: 'blur' }],
                 gender: [{ required: true, message: '请选择性别', trigger: 'change' }],
                 expireTime: [{ required: true, message: '请输入账户过期时间', trigger: 'blur' }],
                 password: [{ required: true, message: '请输入账户密码', trigger: 'blur' }],
@@ -170,11 +165,6 @@
             sexList: [
                 { id: 1, name: '男' },
                 { id: 0, name: '女' }
-            ],
-            userTypeList: [
-                { id: 1, name: '超级管理员' },
-                { id: 2, name: '管理员' },
-                { id: 3, name: '普通员工' }
             ]
         });
         // 打开弹窗
@@ -196,7 +186,6 @@
                     identify: '',
                     positionId: null,
                     gender: null,
-                    type: null,
                     password: '',
                     expireTime: '',
                     status: 1
diff --git a/src/views/system/video/component/videoDialog.vue b/src/views/system/video/component/videoDialog.vue
new file mode 100644
index 0000000..c6729c7
--- /dev/null
+++ b/src/views/system/video/component/videoDialog.vue
@@ -0,0 +1,158 @@
+<template>
+    <div class="system-add-user-container">
+        <el-dialog :title="title" v-model="isShowVideoDialog" width="50%">
+            <el-form :model="videoForm" size="default" ref="userRef" :rules="videoFormRules" label-width="120px">
+                <el-row :gutter="35">
+                    <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
+                        <el-form-item label="视频设备名称" prop="name">
+                            <el-input v-model.trim="videoForm.name" placeholder="请输入设备名称" clearable></el-input>
+                        </el-form-item>
+                    </el-col>
+                    <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
+                        <el-form-item label="设备简称" prop="shortName">
+                            <el-input v-model.trim="videoForm.shortName" placeholder="请输入设备简称" clearable></el-input>
+                        </el-form-item>
+                    </el-col>
+                    <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
+                        <el-form-item label="所属部门" prop="bizDepId">
+                            <el-cascader v-model="videoForm.bizDepId" :options="departmentData" :props="{ emitPath: false, checkStrictly: true, value: 'depId', label: 'depName' }" placeholder="请选择部门" clearable class="w100"> </el-cascader>
+                        </el-form-item>
+                    </el-col>
+                    <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
+                      <el-form-item label="设备号" prop="deviceNo">
+                        <el-input v-model.trim="videoForm.deviceNo" placeholder="请输入设备号" clearable></el-input>
+                      </el-form-item>
+                    </el-col>
+                </el-row>
+            </el-form>
+            <template #footer>
+                <span class="dialog-footer">
+                    <el-button @click="isShowVideoDialog = !isShowVideoDialog" size="default">取 消</el-button>
+                    <el-button type="primary" v-throttle @click="onSubmit" size="default">确 定</el-button>
+                </span>
+            </template>
+        </el-dialog>
+    </div>
+</template>
+
+<script lang="ts">
+import { reactive, toRefs, onMounted, defineComponent, ref } from 'vue';
+import { ElMessageBox, ElMessage } from 'element-plus';
+import { videoApi } from '/@/api/systemManage/video';
+
+// 定义接口来定义对象的类型
+interface DeptData {}
+interface sexData {}
+interface UserState {
+    title: string;
+    isShowVideoDialog: boolean;
+    videoForm: {
+        name: string | null;
+        shortName: string | null;
+        deviceNo: string | null;
+        bizDepId: number | null;
+    };
+    videoFormRules:{
+
+    },
+    departmentData: Array<DeptData>
+}
+
+export default defineComponent({
+    name: 'videoDialog',
+    setup(props, context) {
+        const userRef = ref()
+        const state = reactive<UserState>({
+            title: '',
+            isShowVideoDialog: false,
+            videoForm: {
+                name: '', // 账户名称
+                shortName: '', // 用户昵称
+                deviceNo: '', // 关联角色
+                bizDepId: null
+            },
+            videoFormRules:{
+                name: [{ required: true, message: '请填写设备名称', trigger: 'blur' }],
+                shortName: [{ required: true, message: '请填写设备简称', trigger: 'blur' }],
+                deviceNo: [{ required: true, message: '请输入设备编号', trigger: 'change' }],
+                bizDepId: [{ required: true, message: '请选择部门', trigger: 'change' }]
+            },
+            departmentData: [], // 部门数据
+        });
+        // 打开弹窗
+        const openDialog = (type: string, value: any, departmentList: [], roleList: [], dutyList:[]) => {
+            state.isShowVideoDialog = true;
+            state.departmentData = departmentList;
+            if (type === '新增') {
+                state.title = '新增视频设备';
+                state.videoForm = {
+                    name: '',
+                    shortName: '',
+                    deviceNo: '',
+                    bizDepId: null
+                };
+            } else {
+                state.title = '修改视频设备';
+                state.videoForm = JSON.parse(JSON.stringify(value));
+            }
+        };
+
+        // 新增修改
+        const onSubmit = async () => {
+            userRef.value.validate(async (valid:Boolean) => {
+              console.log(state.videoForm,'state.videoForm')
+                if(valid){
+                    if (state.title === '新增视频设备') {
+                        let res = await videoApi().addVideo(state.videoForm);
+                        if (res.data.code === '200') {
+                            ElMessage({
+                                type: 'success',
+                                message: '视频设备新增成功',
+                                duration: 2000
+                            });
+                            state.isShowVideoDialog = false;
+                            context.emit('getVideoList');
+                        } else {
+                            ElMessage({
+                                type: 'warning',
+                                message: res.data.msg
+                            });
+                        }
+                    } else {
+                        let res = await videoApi().modVideo(state.videoForm);
+                        if (res.data.code === '200') {
+                            ElMessage({
+                                type: 'success',
+                                message: '设备修改成功',
+                                duration: 2000
+                            });
+                            state.isShowVideoDialog = false;
+                            context.emit('getVideoList');
+                        } else {
+                            ElMessage({
+                                type: 'warning',
+                                message: res.data.msg
+                            });
+                        }
+                    }
+                }else{
+                    ElMessage({
+                        type:'warning',
+                        message:'请完善基本信息'
+                    })
+                }
+            })
+
+        };
+
+        // 页面加载时
+        onMounted(() => {});
+        return {
+            userRef,
+            openDialog,
+            onSubmit,
+            ...toRefs(state)
+        };
+    }
+});
+</script>
diff --git a/src/views/system/video/index.vue b/src/views/system/video/index.vue
new file mode 100644
index 0000000..17757a7
--- /dev/null
+++ b/src/views/system/video/index.vue
@@ -0,0 +1,250 @@
+<template>
+    <div class="system-user-container">
+        <el-card shadow="hover">
+            <div class="system-user-search mb15">
+                <el-cascader
+                    v-model="listQuery.bizDepId"
+                    :props="props"
+                    :options="departmentList"
+                    :show-all-levels="false"
+                    placeholder="请选择部门(事业部级别)"
+                    clearable
+                    size="default"
+                ></el-cascader>
+                <el-input size="default" clearable v-model.trim="listQuery.name" placeholder="请输入设备名称" style="max-width: 180px;margin-left: 10px"> </el-input>
+                <el-button size="default" type="primary" class="ml10" @click="initVideoTableData">
+                    <el-icon>
+                        <ele-Search />
+                    </el-icon>
+                    查询
+                </el-button>
+                <el-button size="default" type="success" class="ml10" @click="onOpenVideoDialog('新增', '')">
+                    <el-icon>
+                        <ele-FolderAdd />
+                    </el-icon>
+                    新增设备
+                </el-button>
+            </div>
+            <el-table :data="videoTableData.data" style="width: 100%">
+                <el-table-column type="index" label="序号" width="60" align="center"/>
+                <el-table-column prop="name" label="视频设备名称" align="center" show-overflow-tooltip></el-table-column>
+                <el-table-column prop="shortName" label="设备简称" align="center" show-overflow-tooltip></el-table-column>
+                <el-table-column prop="depName" label="所属部门"  align="center" show-overflow-tooltip></el-table-column>
+                <el-table-column prop="deviceNo" label="设备号" align="center" show-overflow-tooltip></el-table-column>
+                <el-table-column label="操作" width="100" align="center">
+                    <template #default="scope">
+                        <el-button :disabled="scope.row.userName === 'admin'" size="small" text type="primary" @click="onOpenVideoDialog('修改', scope.row)">修改</el-button>
+                        <el-button style="color: red" :disabled="scope.row.userName === 'admin'" size="small" text type="primary" @click="onRowDel(scope.row)">删除</el-button>
+                    </template>
+                </el-table-column>
+            </el-table>
+            <br />
+            <el-pagination @size-change="onHandleSizeChange" @current-change="onHandleCurrentChange" class="page-position" :pager-count="5" :page-sizes="[10, 20, 30]" v-model:current-page="listQuery.pageIndex" background v-model:page-size="listQuery.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="videoTableData.total"> </el-pagination>
+            <br />
+            <br />
+        </el-card>
+        <videoDialog ref="userRef" @getVideoList="initVideoTableData"/>
+    </div>
+</template>
+
+<script lang="ts">
+import { toRefs, reactive, onMounted, ref, defineComponent } from 'vue';
+import { ElMessageBox, ElMessage } from 'element-plus';
+import videoDialog from '/@/views/system/video/component/videoDialog.vue';
+import { videoApi } from '/@/api/systemManage/video';
+import { dutyApi } from '/@/api/systemManage/duty';
+import { departmentApi } from '/@/api/systemManage/department';
+import { useRoleApi } from '/@/api/systemManage/role';
+
+// 定义接口来定义对象的类型
+interface TableDataRow {
+    name: string;
+    userNickname: string;
+    roleSign: string;
+    department: string[];
+    phone: string;
+    email: string;
+    sex: string;
+    password: string;
+    overdueTime: Date;
+    status: boolean;
+    describe: string;
+    createTime: string;
+}
+interface DepartmentDataRow {}
+interface TableDataState {
+    videoTableData: {
+        data: Array<TableDataRow>;
+        total: number;
+        loading: boolean;
+    };
+    listQuery: {
+      bizDepId: string | null;
+      name: string | null;
+      shortName: string | null;
+      pageIndex: number;
+      pageSize: number;
+    };
+    departmentList: [];
+    roleList: [];
+    dutyList: [];
+    props:{}
+}
+
+export default defineComponent({
+    name: 'systemVideo',
+    components: { videoDialog },
+    setup() {
+        const userRef = ref();
+        const state = reactive<TableDataState>({
+            videoTableData: {
+                data: [],
+                total: 0,
+                loading: false,
+            },
+            listQuery: {
+              bizDepId: null,
+              name: '',
+              shortName: '',
+              pageIndex: 1,
+              pageSize: 10
+            },
+            departmentList: [],
+            roleList: [],
+            dutyList: [],
+            props: {
+              label: 'depName',
+              value: 'depId',
+              checkStrictly: true,
+              emitPath: false
+            }
+        });
+        // 初始化表格数据
+        const initVideoTableData = async () => {
+            let res = await videoApi().getVideoList(state.listQuery);
+            if (res.data.code === '200') {
+                state.videoTableData.data = res.data.data;
+                state.videoTableData.total = res.data.total;
+            } else {
+                ElMessage({
+                    type: 'warning',
+                    message: res.data.msg
+                });
+            }
+        };
+
+        // 回显职务信息
+        const parseNumber = (value: number) => {
+            return state.dutyList.find((i) => i.positionId === value)?.positionName;
+        };
+        const getDepartmentData = async () => {
+            let res = await departmentApi().getDepartmentList();
+            if (res.data.code === '200') {
+                state.departmentList = res.data.data;
+            } else {
+                ElMessage({
+                    type: 'warning',
+                    message: res.data.msg
+                });
+            }
+        };
+
+        const getRoleData = async () => {
+            let res = await useRoleApi().getRoleList();
+            if (res.data.code === '200') {
+                state.roleList = res.data.data;
+            } else {
+                ElMessage({
+                    type: 'warning',
+                    message: res.data.msg
+                });
+            }
+        };
+
+      const getDutyData = async () => {
+        let res = await dutyApi().getAllList({positionName: '',positionCode: ''});
+        if (res.data.code === '200') {
+          state.dutyList = res.data.data;
+        } else {
+          ElMessage({
+            type: 'warning',
+            message: res.data.msg
+          });
+        }
+      };
+
+        // 打开新增修改用户弹窗
+        const onOpenVideoDialog = (type: string, value: any) => {
+            userRef.value.openDialog(type, value, state.departmentList, state.roleList, state.dutyList);
+        };
+
+        // 删除用户
+        const onRowDel = (row: TableDataRow) => {
+            ElMessageBox.confirm(`此操作将永久删除设备名称:“${row.name}”,是否继续?`, '提示', {
+                confirmButtonText: '确认',
+                cancelButtonText: '取消',
+                type: 'warning'
+            })
+                .then(async () => {
+                    let res = await videoApi().delVideo(row.id);
+                    if (res.data.code === '200') {
+                        ElMessage({
+                            type: 'success',
+                            duration: 2000,
+                            message: '删除成功'
+                        });
+                        await initVideoTableData();
+                    } else {
+                        ElMessage({
+                            type: 'warning',
+                            message: res.data.msg
+                        });
+                    }
+                })
+                .catch(() => {});
+        };
+        // 分页改变
+        const onHandleSizeChange = (val: number) => {
+            state.listQuery.pageSize = val;
+            initVideoTableData();
+        };
+        // 分页改变
+        const onHandleCurrentChange = (val: number) => {
+            state.listQuery.pageIndex = val;
+            initVideoTableData();
+        };
+        // 页面加载时
+        onMounted(() => {
+            let a = { name: 1, c: { name: 1 } };
+            let b = Object.assign({}, a);
+            b.c.name = 2;
+            initVideoTableData();
+            getDepartmentData();
+            getRoleData();
+            getDutyData()
+        });
+        return {
+            userRef,
+            onOpenVideoDialog,
+            onRowDel,
+            parseNumber,
+            onHandleSizeChange,
+            initVideoTableData,
+            onHandleCurrentChange,
+            ...toRefs(state)
+        };
+    }
+});
+</script>
+<style  scoped>
+:deep(.el-textarea.is-disabled .el-textarea__inner) {
+    background-color: var(--el-card-bg-color);
+    color: var(--el-input-text-color, var(--el-text-color-regular));
+}
+:deep(.el-input.is-disabled .el-input__inner) {
+    color: var(--el-input-text-color, var(--el-text-color-regular));
+}
+:deep(.el-input.is-disabled .el-input__wrapper) {
+    background-color: var(--el-card-bg-color);
+}
+</style>

--
Gitblit v1.9.2