zmc
2023-09-04 34257f504330191b1a698eb48b52217095db47fe
扬尘vue
已修改18个文件
已删除9个文件
已添加8个文件
已重命名5个文件
4385 ■■■■■ 文件已修改
.eslintrc-auto-import.json 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
auto-imports.d.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components.d.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/audit/submitApi.js 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/exportExcel/requetsApi.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/layout/AppAside.vue 54 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/layout/AppHeader.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.ts 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.ts 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/sfc/BreadCrumb.vue 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/sfc/ButtonClick.vue 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/sfc/ButtonExportExcel.vue 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/sfc/ExportExcel.vue 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/sfc/FanPurifierChart.vue 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/sfc/FumeFanPurifierChart.vue 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/sfc/TableD.vue 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/sfc/TimeSelectWithShortCuts.vue 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/stores/counter.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/TestDrawer.vue 548 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/TestNoData.vue 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/TestSelect.vue 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/TestWa.vue 382 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/common.js 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/exception_common_function/index.js 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/test.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/data_management/BusinessReport.vue 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/data_management/DataAccessManagement.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/views/data_management/HistoryData.vue 328 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/exception/FlightInspection.vue 200 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/exception/SiteAuditAssistance.vue 1115 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/exception/components/DustExceptionText.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/views/exception/components/DustLineChart.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/views/line_graph/DataRiskModel.vue 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/line_graph/DataRiskRank.vue 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/line_graph/SiteComprehensiveRskRanking.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/line_graph/components/LineChart.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/LoginSystem.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/origin_data/HistoryData.vue 385 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pass_login/LoginAndGetData.vue 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/setting/SetConfiguration.vue 64 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.eslintrc-auto-import.json
@@ -59,6 +59,7 @@
    "watchEffect": true,
    "watchPostEffect": true,
    "watchSyncEffect": true,
    "ElMessage": true
    "ElMessage": true,
    "ElMessageBox": true
  }
}
auto-imports.d.ts
@@ -6,6 +6,7 @@
declare global {
  const EffectScope: typeof import('vue')['EffectScope']
  const ElMessage: typeof import('element-plus/es')['ElMessage']
  const ElMessageBox: typeof import('element-plus/es')['ElMessageBox']
  const computed: typeof import('vue')['computed']
  const createApp: typeof import('vue')['createApp']
  const customRef: typeof import('vue')['customRef']
components.d.ts
@@ -13,6 +13,8 @@
    ElAside: typeof import('element-plus/es')['ElAside']
    ElAutocomplete: typeof import('element-plus/es')['ElAutocomplete']
    ElAvatar: typeof import('element-plus/es')['ElAvatar']
    ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
    ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
    ElButton: typeof import('element-plus/es')['ElButton']
    ElCard: typeof import('element-plus/es')['ElCard']
    ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
@@ -42,6 +44,7 @@
    ElSelect: typeof import('element-plus/es')['ElSelect']
    ElSkeleton: typeof import('element-plus/es')['ElSkeleton']
    ElSpace: typeof import('element-plus/es')['ElSpace']
    ElStatistic: typeof import('element-plus/es')['ElStatistic']
    ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
    ElTable: typeof import('element-plus/es')['ElTable']
    ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
@@ -57,10 +60,12 @@
    IEpArrowDown: typeof import('~icons/ep/arrow-down')['default']
    IEpBell: typeof import('~icons/ep/bell')['default']
    IEpDataLine: typeof import('~icons/ep/data-line')['default']
    IEpDownload: typeof import('~icons/ep/download')['default']
    IEpExpand: typeof import('~icons/ep/expand')['default']
    IEpFold: typeof import('~icons/ep/fold')['default']
    IEpHistogram: typeof import('~icons/ep/histogram')['default']
    IEpMonitor: typeof import('~icons/ep/monitor')['default']
    IEpSearch: typeof import('~icons/ep/search')['default']
    IEpStopwatch: typeof import('~icons/ep/stopwatch')['default']
    RouterLink: typeof import('vue-router')['RouterLink']
    RouterView: typeof import('vue-router')['RouterView']
src/api/audit/submitApi.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,62 @@
import { $http } from '@/api/index.js';
export default {
    /**
     * æäº¤å®¡æ ¸
     * @param: å®¡æ ¸äººï¼Œå®¡æ ¸äººå¤‡æ³¨ï¼Œä¼ä¸šå¤‡æ³¨ï¼Œå¼‚常记录编号, è¯¥æ¡å¼‚常的审核状态
     * @returns:
     */
    submitAudit(reviewer,checkerNotes,enterpriseNotes,id,status){
        const params = {
            // checker:reviewer,
            checkerContent:checkerNotes,
            enterpriseContent:enterpriseNotes,
            exceptionId:id,
            auditStatus:status
        }
        if(reviewer == '' || reviewer  == null){
            params.checker = 'admin'
        }else{
            params.checker = reviewer
        }
        return $http.post('/dust/audit',params)
    },
    /**
     * è¿”回审核表所有数据
     * @param:
     * @returns:
     */
    backAuditAllData(){
        return $http.get('dust/auditAllData')
    },
    /**
     * æ›´æ–°å®¡æ ¸è®°å½•
     * @param:  å¼‚常编号Id,审核人备注,企业备注,该条异常的审核状态
     * @returns:
     */
    updateAudit(id,checkerContent,enterpriseContent,auditStatus){
        const params = {
            exceptionId:id,
            auditStatus:auditStatus,
        }
        if(checkerContent){
            params.checkerContent = checkerContent
        }
        if(enterpriseContent){
            params.enterpriseContent = enterpriseContent
        }
        return $http.put('/dust/auditUpdate',params)
    },
    getAuditNumByTime(beginTime,endTime){
        if(beginTime!='' || endTime!=''){
            const params = {
                beginTime:beginTime,
                endTime:endTime
            }
            return $http.get('/dust/auditnum',{params:params})
        }
    }
};
src/api/exportExcel/requetsApi.js
@@ -10,6 +10,11 @@
        return $http.get('dust/analysisall',{params:argsObj});
    },
    /**
     * æ ¹æ®ç«™ç‚¹ï¼Œæ—¶é—´æ®µæŸ¥è¯¢åŽ†å²è¡¨ä¸­æ‰€æœ‰æ•°æ®
     * @param:
     * @returns:
     */
    fetchAlSiteData(argsObj){
        
        return $http.get('dust/historyall',{params:argsObj});
src/components/layout/AppAside.vue
@@ -11,6 +11,7 @@
      optionClick: [
        ' æ•°æ®é£Žé™©æ¨¡åž‹',
        '数据风险排名',
        '站点综合风险排名',
        '飞行巡检',
        '站点审核辅助',
        '历史数据管理',
@@ -23,11 +24,13 @@
  methods:{
    calMenuHeight() {
      const h1 = this.$refs.headerRef.$el.offsetHeight;
      return `calc(100vh - ${h1}px `;
      return `calc(100vh - ${h1}px - 8px`;
    },
  },
  mounted(){
    this.menuHeight = this.calMenuHeight();
    console.log('meta:',this.$route.matched);
  }
};
</script>
@@ -41,24 +44,17 @@
        class="el-menu-vertical-demo"
        default-active="2"
        text-color="#fff"
        @open="handleOpen"
        @close="handleClose"
        router
        :collapse="isCollapseAside"
      >
      <el-row ref="headerRef" class="header">
      <el-space>
        <el-link href="/hdata" class="logo" >
          <!-- <img src="@/assets/companylogo.png" alt="" /> -->
          <h1>在线监测数据质量评估与风险分析</h1>
        </el-link>
 
      </el-space>
      <div class="line">
        </div>
    </el-row>
      <hr/>
        <el-scrollbar :height="menuHeight">
        <el-sub-menu index="1">
@@ -74,7 +70,12 @@
          <el-menu-item index="analysis" @click="selected = optionClick[1]">
            <el-icon><i-ep-Stopwatch /></el-icon>
            æ•°æ®é£Žé™©æŽ’名
          </el-menu-item><el-menu-item index="riskrank" @click="selected = optionClick[2]">
            <el-icon><i-ep-Stopwatch /></el-icon>
            ç«™ç‚¹ç»¼åˆé£Žé™©æŽ’名
          </el-menu-item>
        </el-sub-menu>
@@ -83,12 +84,12 @@
            <el-icon><i-ep-Histogram /></el-icon>
            <span class="parent-title">线上巡检</span>
          </template>
          <el-menu-item index="edata" @click="selected = optionClick[2]">
          <el-menu-item index="edata" @click="selected = optionClick[3]">
            <el-icon><i-ep-Bell /></el-icon>
          é£žè¡Œå·¡æ£€
          </el-menu-item>
          <el-menu-item index="testdata" @click="selected = optionClick[3]">
          <el-menu-item index="testData" @click="selected = optionClick[4]">
            <el-icon><i-ep-Bell /></el-icon>
          ç«™ç‚¹å®¡æ ¸è¾…助
          </el-menu-item>
@@ -106,18 +107,18 @@
            <el-icon><i-ep-Histogram /></el-icon>
          åŽ†å²æ•°æ®ç®¡ç†
          </el-menu-item>
          <!-- <el-menu-item index="management" @click="selected = optionClick[5]">
          <el-menu-item index="management" @click="selected = optionClick[5]">
            <el-icon><i-ep-Histogram /></el-icon>
          æ•°æ®æŽ¥å…¥ç®¡ç†
          </el-menu-item>
          <el-menu-item index="report" @click="selected = optionClick[6]">
            <el-icon><i-ep-Histogram /></el-icon>
          ä¸šåŠ¡æŠ¥è¡¨
          </el-menu-item> -->
          </el-menu-item>
          </el-sub-menu>
          <!-- <el-sub-menu index="4">
          <el-sub-menu index="4">
              <template #title>
                <el-icon><i-ep-DataLine /></el-icon>
                  <span class="parent-title">配置管理</span>
@@ -127,7 +128,7 @@
                <el-icon><i-ep-Histogram /></el-icon>
                   æ•°æ®æŽ¥å…¥é…ç½®
              </el-menu-item>
          </el-sub-menu> -->
          </el-sub-menu>
    </el-scrollbar>
      </el-menu>
@@ -137,8 +138,6 @@
<style lang="scss" scoped>
.el-aside {
  background-color: #2876aa;
  height: 100vh;
  width: auto;
}
@@ -148,16 +147,17 @@
  width: 220px;
  border-right: none;
  &.el-menu--collapse {
    //侧边栏折叠时的样式
    width: 65px;
    & h1 {
      //折叠时隐藏h1文字
      display: none;
    }
    & span {
      display: none;
    }
    & hr {
      display: none;
    }
  }
@@ -171,10 +171,11 @@
  text-decoration: none;
  color: black;
  margin-left: 20px;
  img {
    width: 32px;
    height: 32px;
  }
  margin-right: 20px;
  // img {
  //   width: 32px;
  //   height: 32px;
  // }
}
@@ -188,10 +189,5 @@
  font-weight: bold;
  font-size: 18px;
}
// .line {
//   width: 180px;
//   border: 1px solid rgb(255,255,255,0.2);
//   margin: 0px;
//   padding: 0px;
// }
</style>
src/components/layout/AppHeader.vue
@@ -1,8 +1,11 @@
<script >
 import { isCollapse } from './isCollapse'
 import { selectedName } from './selectName'
 import BreadCrumb from '@/sfc/BreadCrumb.vue'
  export default {
    components:{
      BreadCrumb,
    },
    data() {
      return{
        isCollapseHeader: isCollapse ,  //折叠
@@ -37,16 +40,11 @@
        <i-ep-Expand v-show="isCollapseHeader" />
        <i-ep-Fold v-show="!isCollapseHeader"/>
      </el-icon>
      {{ selected }}
      <!-- {{ selected }} -->
      
    <!-- é¢åŒ…屑 -->
    <!-- <el-breadcrumb separator="/">
        <el-breadcrumb-item :to="{ path: '/hdata' }">主页</el-breadcrumb-item>
        <el-breadcrumb-item><a href="/">promotion management</a></el-breadcrumb-item> -->
        <!-- <el-breadcrumb-item>promotion list</el-breadcrumb-item>
        <el-breadcrumb-item>promotion detail</el-breadcrumb-item> -->
    <!-- </el-breadcrumb> -->
      <BreadCrumb></BreadCrumb>
   <!-- ä¸‹æ‹‰èœå• -->
    <el-dropdown>
src/main.ts
@@ -14,11 +14,21 @@
const app = createApp(App)
function SecretPiniaPlugin() {
    return { secret: 'the cake is a lie',vue:'333.0' }
  }
  const pinia = createPinia()
  // å°†æ’件提供给 pinia
  pinia.use(SecretPiniaPlugin)
  // pinia.use(() => ({'天':'雨天'}))
// axios.defaults.baseURL = 'http://192.168.1.4:8081'
axios.defaults.baseURL = 'http://localhost:8081'
app.config.globalProperties.$http = axios
app.use(createPinia())
app.use(pinia)
app.use(router)
src/router/index.ts
@@ -7,63 +7,78 @@
    {
      path: '/layout',
      name: 'home',
      meta: { title: '首页' },
      component: () => import('@/components/layout/AppLayout.vue'),
      children: [
        // æ•°æ®åˆ†é™©æ¨¡åž‹
        {
          path:"/avgDay",
          name:'avgDay',
              meta: { title: '数据分险模型' },
          component: () => import('@/views/line_graph/DataRiskModel.vue')
         },
        //  æ•°æ®é£Žé™©æŽ’名
         {
          path:"/analysis",
          name:'analysis',
              meta: { title: '数据风险排名' },
          component: () => import('@/views/line_graph/DataRiskRank.vue')
         },
        //  åŽ†å²æ•°æ®ç®¡ç†
            //  æ•°æ®é£Žé™©æŽ’名
         {
          path:"/hdata",
          name:'hdata',
          component: () => import('@/views/origin_data/HistoryData.vue')
              path: "/riskrank",
              name: 'riskrank',
              meta: { title: '数据风险排名' },
              component: () => import('@/views/line_graph/SiteComprehensiveRskRanking.vue')
         },
        // é£žè¡Œå·¡æ£€
         {
          path:"/edata",
          name:'edata',
              meta: { title: '飞行巡检' },
          component: () => import('@/views/exception/FlightInspection.vue')
         },
         
        //  ç«™ç‚¹å®¡æ ¸è¾…助
         {
          path:"/testdata",
          name:'testdata',
              path: "/testData",
              name: 'testData',
              meta: { title: '站点审核辅助' },
          component: () => import('@/views/exception/SiteAuditAssistance.vue')
         },
        
        //  æ•°æ®æŽ¥å…¥é…ç½®
          {
          path:"/setting",
          name:'setting',
          component: () => import('@/views/setting/SetConfiguration.vue')
         },
            {
              path: "/hdata",
              name: 'hdata',
              meta: { title: '历史数据管理' },
              component: () => import('@/views/data_management/HistoryData.vue')
            },
         //  æ•°æ®æŽ¥å…¥ç®¡ç†
         { 
          path:"/management",
          name:'management',
          component: () => import('@/views/origin_data/DataAccessManagement.vue')
              meta: { title: '数据接入管理' },
              component: () => import('@/views/data_management/DataAccessManagement.vue')
         },
          //  ä¸šåŠ¡æŠ¥è¡¨
          { 
            path:"/report",
            name:'report',
            component: () => import('@/views/origin_data/BusinessReport.vue')
              meta: { title: '业务报表' },
              component: () => import('@/views/data_management/BusinessReport.vue')
            },
            //  æ•°æ®æŽ¥å…¥é…ç½®
            {
              path: "/setting",
              name: 'setting',
              meta: { title: '数据接入配置' },
              component: () => import('@/views/setting/SetConfiguration.vue')
           },
         
      ],
@@ -77,7 +92,7 @@
     },
     {
      path: '/',
      redirect:'/hdata'
      redirect: '/edata'
    },
  ]
})
src/sfc/BreadCrumb.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
<!-- é¢åŒ…屑 -->
<script>
import { ArrowRight } from '@element-plus/icons-vue'
export default {
   data(){
      return{
        list:[]
      }
   },
 setup(){
    return {ArrowRight}
 },
   watch:{
    $route(to,from){
        this.list = to.matched
    }
   },
   mounted (){
    this.list = this.$route.matched
   },
   methods:{
   }
}
</script>
<template>
    <el-breadcrumb :separator-icon="ArrowRight">
            <el-breadcrumb-item v-for="item in list" :key="item.path" :to="{ path: '/' }">
                <router-link :to="item.path">{{ item.meta.title }}</router-link>
            </el-breadcrumb-item>
    </el-breadcrumb>
</template>
<style scoped>
.el-breadcrumb__inner a {
  font-weight: 500;
  color: rgba(0, 0, 0);
}
.el-breadcrumb__item:last-child .el-breadcrumb__inner a {
    color: rgb(209, 207, 207);
}
</style>
src/sfc/ButtonClick.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,50 @@
<!--
    æœç´¢æŒ‰é’®
    ç‚¹å‡»æŒ‰é’®åŽï¼Œå‘父组件发生点击事件,由父组件来完成点击后的具体执行
    **父组件
    <ButtonClick content="搜索" type="warning" :loading="loading.queryButton" @do-search="doSearch"></ButtonClick>
 -->
<script>
export default {
   props:{
    // æŒ‰é’®æ–‡å­—
    content:{
        type:String,
        default:'点击'
    },
    // æŒ‰é’®æ ·å¼
    type:{
        type:String,
        default:'success'
    },
    // åŠ è½½æ•ˆæžœ
    loading:{
        type:Boolean,
        default:false
    },
    size:{
        type:String,
        default:'default'
    }
   },
   emits:['doSearch' ],
}
</script>
<template>
  <div>
    <el-button :type="type"  :loading="loading" :size="size"  @click="$emit('doSearch')">
        <el-icon >
            <i-ep-Search/>
        </el-icon>
        {{ content }}
    </el-button>
  </div>
</template>
<style scoped>
.el-icon {
   margin-right: 6px;
   font-size: 1.2em;
}
</style>
src/sfc/ButtonExportExcel.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,49 @@
<!--
    å¯¼å‡ºæˆExcel组件
    **父组件
   <ButtonExportExcel  content="导出数据" type="success" :loading="exportButton" @do-export="exportDom"></ButtonExportExcel>
 -->
<script>
export default {
    props: {
        // æŒ‰é’®æ–‡å­—
        content: {
            type: String,
            default: '导出数据'
        },
        // æŒ‰é’®æ ·å¼
        type: {
            type: String,
            default: 'success'
        },
        // åŠ è½½æ•ˆæžœ
        loading: {
            type: Boolean,
            default: false
        },
        size: {
            type: String,
            default: 'default'
        }
    },
    emits: ['doExport'],
}
</script>
<template>
    <el-button :type="type" :size="size" @click="$emit('doExport')" :loading="loading"  round>
        <el-icon >
            <i-ep-Download/>
        </el-icon>
        {{ content }}
    </el-button>
</template>
<style scoped>
   .el-icon {
        margin-right: 6px;
        margin-bottom:2px;
        font-size: 1.2em;
    }
</style>
src/sfc/ExportExcel.vue
ÎļþÒÑɾ³ý
src/sfc/FanPurifierChart.vue
ÎļþÒÑɾ³ý
src/sfc/FumeFanPurifierChart.vue
ÎļþÒÑɾ³ý
src/sfc/TableD.vue
ÎļþÒÑɾ³ý
src/sfc/TimeSelectWithShortCuts.vue
@@ -13,20 +13,26 @@
  ***
-->
<script>
import dayjs from 'dayjs'
import dayjs from 'dayjs';
  export default {
  props: {
    timeType: {
      type: String,
      default: 'month'
    }
  },
    emits: ['submitTime'],
    data() {
      return{
        //保存开始和结束时间
      // éšä¾¿è®¾ç½®åˆå§‹å€¼ ï¼Œmounted时再设正确的,目的是改变时间了触发change
        time: ['2023-06-01 12:00:00', '2023-06-20 16:00:00'],
        shortcuts:[],
      }
      shortcuts: []
    };
    },
    mounted() {
        this.initShortCuts()
        this.initOneWeekAgoTime()
    this.initShortCuts();
    this.initOneWeekAgoTime();
        this.$emit('submitTime', this.time);
    },
    methods: {
@@ -35,46 +41,66 @@
            {
    text: '前一日',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24)
      return [start, end]
    },
            const end = new Date();
            const start = new Date();
            start.setTime(start.getTime() - 3600 * 1000 * 24);
            return [start, end];
          }
  },
                
  {
    text: '前7天',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
      return [start, end]
    },
            const end = new Date();
            const start = new Date();
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
            return [start, end];
          }
  },
  {
    text: '前一月',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
      return [start, end]
    },
  },
]
            const end = new Date();
            const start = new Date();
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
            return [start, end];
          }
        }
      ];
        },
        initOneWeekAgoTime(){
      // ç»™æ—¶é—´é€‰æ‹©å™¨è®¾ç½®é»˜è®¤æ—¶é—´ä¸ºä¸€å‘¨å‰
    this.time[0] = dayjs().subtract(6, 'week').format('YYYY-MM-DD HH:mm:ss');
      switch (this.timeType) {
        case 'day':
          this.time[0] = dayjs()
            .subtract(1, 'day')
            .format('YYYY-MM-DD HH:mm:ss');
          this.time[1] = dayjs().format('YYYY-MM-DD HH:mm:ss');
          break;
        case 'week':
          this.time[0] = dayjs()
            .subtract(1, 'week')
            .format('YYYY-MM-DD HH:mm:ss');
          this.time[1] = dayjs().format('YYYY-MM-DD HH:mm:ss');
          break;
        case 'month':
          this.time[0] = dayjs()
            .subtract(1, 'month')
            .format('YYYY-MM-DD HH:mm:ss');
          this.time[1] = dayjs().format('YYYY-MM-DD HH:mm:ss');
          break;
        default:
          this.time[0] = dayjs().subtract(1, 'month').format('YYYY-MM-DD HH:mm:ss');
    this.time[1] = dayjs().format('YYYY-MM-DD HH:mm:ss');
    }
     }
}
};
</script>
<template>
    <div class="block">
        <span class="demonstration">起止时间:</span>
    <div class="pick-date">
        <el-date-picker
          v-model="time"
          type="datetimerange"
@@ -84,8 +110,9 @@
          end-placeholder="结束时间"
          value-format="YYYY-MM-DD HH:mm:ss"
          @change="$emit('submitTime', time)"
          class="pick-date"
        />
  </div>
  </div>
</template>
@@ -101,7 +128,7 @@
  font-size: 16px;
}
.pick-date {
  margin-top: 5px;
}
/* .pick-date {
  width: 200px;
} */
</style>
src/stores/counter.js
ÎļþÃû´Ó src/stores/counter.ts ÐÞ¸Ä
@@ -1,11 +1,12 @@
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const doubleCount = computed(() => count.value * 2)
  function increment() {
    count.value++
  function increment(num) {
    count.value = num + count.value + 1
    return 1
  }
  return { count, doubleCount, increment }
src/test/TestDrawer.vue
ÎļþÒÑɾ³ý
src/test/TestNoData.vue
ÎļþÒÑɾ³ý
src/test/TestSelect.vue
ÎļþÒÑɾ³ý
src/test/TestWa.vue
ÎļþÒÑɾ³ý
src/utils/common.js
@@ -6,6 +6,7 @@
     * @createTime:2023-08-18
     * @returns:超过一个月返回true,不超过一个月则返回false
     */
    function isExceedOneMonth(dateStr1, dateStr2) {
        // è¶…过一个月,返回True,否则返回False
        // å°†æ—¥æœŸå­—符串转为日期对象
@@ -49,7 +50,7 @@
      }
         /**
     * description:百分号比较大小
     * ç™¾åˆ†å·æ¯”较大小
     * @param: a是否大于b
     * @returns:大于,则返回true。否则返回false
     */
@@ -73,12 +74,6 @@
      // åˆ›å»ºxlsx对象
      const xls = XLSX.utils.json_to_sheet(itemsFormatted);
     
    //   xls['A1'].v = '设备编号';
    //   xls['B1'].v = '异常类型';
    //   xls['C1'].v = '地区';
    //   xls['D1'].v = '开始时间';
    //   xls['E1'].v = '结束时间';
     // ç¼–辑表头行       ä¿®æ”¹è¡¨å¤´
      excelColumnsName.forEach(item =>{
        xls[item[0]].v = item[1]
@@ -91,6 +86,29 @@
    
    }
    return {isExceedOneMonth,cmpp,exportToExcel}
     /**
     * description:返回时间数组,间隔15分钟。
     * @param: å¼‚常的开始,异常结束时间
     * @createTime:2023-08-17
     * @returns:比如12:00:00-13:00:00 æ‰€ä»¥è¿”回的数组元素是 12:00:00 ,12:15:00,12:30:00,12:45:00,13:00:00
     */
     function  descFiftyTime(begin, end) {
      let time = [];
      if (begin == end) {
        time.push(begin);
        return time;
      }
      time.push(begin);
      let temp = dayjs(begin).add(15, 'minute').format('YYYY-MM-DD HH:mm:ss');
      while (temp != end) {
        time.push(temp);
        temp = dayjs(temp).add(15, 'minute').format('YYYY-MM-DD HH:mm:ss');
      }
      // åŠ ä¸Šå¼‚å¸¸çš„ç»“æŸæ—¶é—´
      time.push(temp);
      return time;
    }
    return {isExceedOneMonth,cmpp,exportToExcel,descFiftyTime}
}
src/utils/exception_common_function/index.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,138 @@
import dayjs from 'dayjs'
export default  {
    /**
     * description:返回时间数组,间隔15分钟。
     * @param: å¼‚常的开始,异常结束时间
     * @createTime:2023-08-17
     * @returns:比如12:00:00-13:00:00 æ‰€ä»¥è¿”回的数组元素是 12:00:00 ,12:15:00,12:30:00,12:45:00,13:00:00
     */
    descFiftyTime(begin, end) {
        let time = [];
        if (begin == end) {
          time.push(begin);
          return time;
        }
        time.push(begin);
        let temp = dayjs(begin).add(15, 'minute').format('YYYY-MM-DD HH:mm:ss');
        while (temp != end) {
          time.push(temp);
          temp = dayjs(temp).add(15, 'minute').format('YYYY-MM-DD HH:mm:ss');
        }
        // åŠ ä¸Šå¼‚å¸¸çš„ç»“æŸæ—¶é—´
        time.push(temp);
        return time;
      },
      /**
     * description:返回开始时间的前45分钟的时间点,结束时间后45分钟的时间点
     * @param: å¼‚常的开始时间,异常的结束时间。
     * @returns:数组。time[0],time[1],time[2],time[3]分别代表异常区间前45分钟的时间点,前15分钟的时间点,后15分钟的时间点,后45分钟的时间点
     */
    before45AndAfter45(begin, end) {
        let time = [];
        // å‰ä¸€æ®µçš„开始时间
        const before45MinBegin = dayjs(begin)
          .subtract(45, 'minute')
          .format('YYYY-MM-DD HH:mm:ss');
        // å‰ä¸€æ®µçš„结束时间
        const before15MinBegin = dayjs(begin)
          .subtract(15, 'minute')
          .format('YYYY-MM-DD HH:mm:ss');
        // åŽä¸€æ®µçš„开始时间
        const after15MinBegin = dayjs(end)
          .add(15, 'minute')
          .format('YYYY-MM-DD HH:mm:ss');
        // å¾€åŽ40分钟
        const after45MinEnd = dayjs(end)
          .add(45, 'minute')
          .format('YYYY-MM-DD HH:mm:ss');
        time.push(before45MinBegin);
        time.push(before15MinBegin);
        time.push(after15MinBegin);
        time.push(after45MinEnd);
        return time;
      },
       /**
     * description:返回某站点在该时段历史数据的get请求参数
     * @param: ç«™ç‚¹åç§°ï¼Œ å¼€å§‹æ—¶é—´ï¼Œ ç»“束时间
     * @returns:对象
     */
    requestGetParms(name, begin, end) {
        return {
          siteName: name,
          beginTime: begin,
          endTime: end
        };
      },
      /**
     * description:相差多少个15分钟  è®¡ç®—中包括开始时间,结束时间。
     * @param: å¼‚常开始时间,异常结束时间
     * @returns:整数
     */
    diffFiftyMinutesNum(beginNormal, endNormal) {
        // å°†å¼€å§‹æ—¶é—´å’Œç»“束时间转换为dayjs对象
        const start = dayjs(beginNormal).subtract(15, 'minute');
        const end = dayjs(endNormal);
        // è®¡ç®—结束时间减去开始时间中间相差多少个十分钟
        const diffInMinutes = end.diff(start, 'minute');
        const diffInTenMinutes = Math.floor(diffInMinutes / 15);
        return diffInTenMinutes;
      },
       /**
     * description:判断data中是否有该日期时间,存在返回该时间对应的浓度值,否则返回-1
     * @param: åŠ ä¸Šå‰åŽåŒºé—´çš„å¼‚å¸¸æ•°æ®ï¼Œæ—¶é—´å­—ç¬¦ä¸²
     * @returns:
     */
    findTimeInExceptionData(data, time) {
        for (let i = 0; i < data.length; i++) {
          if (data[i] == null) {
            continue;
          }
          if (data[i]['lst'] == time) {
            return data[i]['dustValue'];
          }
        }
        return -1;
      },
      /**
     * description:根据开始和结束时间,返回以15分钟为间隔的时间和对应的值
     * @param: å‰åŒºé—´çš„开始时间, åŽåŒºé—´çš„结束时间, åŠ ä¸Šå‰åŽåŒºé—´çš„æ€»æ—¶é—´æ®µçš„å¼‚å¸¸æ•°æ®çš„å¯¹è±¡æ•°ç»„
     * @returns:对象。包含了折线图的x轴,y轴的配置数据
     */
    keepContinuousByEachFiftyMinutes(
        intervalStarTime,
        intervalEndTime,
        headAndTailExceptionData
      ) {
        let xAxis = [];
        let yAxis = [];
        let obj = {};
        let current = intervalStarTime;
        let tail = dayjs(intervalEndTime)
          .add(15, 'minute')
          .format('YYYY-MM-DD HH:mm:ss');
        while (current != tail) {
          let value = this.findTimeInExceptionData(
            headAndTailExceptionData,
            current
          );
          if (value != -1) {
            xAxis.push(current);
            yAxis.push(value);
          } else {
            xAxis.push(current);
            yAxis.push(null);
          }
          current = dayjs(current)
            .add(15, 'minute')
            .format('YYYY-MM-DD HH:mm:ss');
        }
        obj['xAxis'] = xAxis;
        obj['yAxis'] = yAxis;
        return obj;
      },
}
src/utils/test.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,5 @@
export default {
    add(a,b){
        return a+b
    }
}
src/views/data_management/BusinessReport.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
<script>
import {useCounterStore} from '@/stores/counter';
export default {
   data(){
      return{
      }
   },
   setup(){
    const store = useCounterStore()
    return{
      store
    }
   },
    mounted() {
    },
    methods: {
     }
}
</script>
<template>
  <div>
    ä¸šåŠ¡æŠ¥è¡¨ {{ store.count }}
  </div>
</template>
<style  scoped>
</style>
src/views/data_management/DataAccessManagement.vue
src/views/data_management/HistoryData.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,328 @@
<script>
import TimeSelectWithShortCuts from '@/sfc/TimeSelectWithShortCuts.vue';
import ScenarioType from '@/sfc/ScenarioType.vue';
import InputSearch from '@/sfc/InputSearch.vue';
import AreaAndmonitorType from '@/sfc/AreaAndmonitorType.vue'
import { useCommonFunction } from '../../utils/common.js';
import requetsApi from '@/api/exportExcel/requetsApi.js'
import ButtonClick from '@/sfc/ButtonClick.vue'
import ButtonExportExcel from '@/sfc/ButtonExportExcel.vue'
import dayjs from 'dayjs';
export default {
  components: {
    TimeSelectWithShortCuts,
    ScenarioType,
    InputSearch,
    ButtonClick,
    ButtonExportExcel,
    AreaAndmonitorType
  },
  data() {
    return {
      form: {
        // ç«™ç‚¹åç§°
        name: '',
        // è®¾å¤‡ç¼–号
        number: '',
        // å¼€å§‹æ—¶é—´
        beginTime: '',
        // ç»“束时间
        endTime: ''
      },
      // è¿”回的数据
      tableData: [],
      // è¡¨æ ¼æ•°æ®
      displayData: [],
      // å½“前页
      currentPage: 1,
      // æ¯é¡µæ¡æ•°
      pageSize: 20,
      total: 0,
      // åŠ è½½ä¸­
      loading: false,
      queryButton: false,
      exportButton:false,
      // ç©ºçŠ¶æ€
      isNoData: false,
      // å·²é€‰ä¸­çš„场景类型
      scenarioType: [],
      // è¡¨æ ¼é«˜åº¦
      tableHeight: '500'
    };
  },
  setup() {
    const { isExceedOneMonth, exportToExcel } = useCommonFunction()
    return { isExceedOneMonth, exportToExcel }
  },
  mounted() {
    this.backMinuteDataAWeekAgo();
    this.calTableHeight();
  },
  methods: {
    exportDom() {
      let params = {
        'beginTime': this.form.beginTime,
        'endTime': this.form.endTime,
      }
      if (this.form.name) {
        params['siteName'] = this.form.name;
      }
      if (this.form.number) {
        params['mnCode'] = this.form.numbe;
      }
      if (this.scenarioType.length != 0) {
        params['scenarioType'] = this.scenarioType;
      }
      this.exportButton = true
      requetsApi.fetchAlSiteData(params).then(res => {
        const data = res.data.data
        if (data.length != 0) {
          const tableColumns = [
            'name',
            'address',
            'dutyCompany',
            'mnCode',
            'typeName',
            'dustValue',
            'noiseValue',
            'lst',
            'quality',
            'groupName',
          ]
          const excelColumns = [['A1', '站点名称'],
          ['B1', '地址'], ['C1', '供应商'], ['D1', '设备编号'],
          ['E1', '类型'], ['F1', '扬尘浓度(mg/m³)'], ['G1', '噪声(dB)'],
          ['H1', '采集时间'], ['I1', '等级'], ['J1', '所在区县']]
          this.exportToExcel(data, tableColumns, excelColumns, '历史数据表.xlsx')
        }else{
          ElMessage('无数据需要导出')
        }
        this.exportButton = false
      })
    },
    // åŠŸèƒ½ï¼šè¡¨æ ¼é«˜åº¦æ ¹æ®å†…å®¹è‡ªé€‚åº”
    calTableHeight() {
      const h1 = this.$refs.h1.$el.offsetHeight;
      const h2 = this.$refs.h2.$el.offsetHeight;
      // å…¶ä¸­ä¸€ä¸ª40是盒子的总外边距
      this.tableHeight = `calc(100vh - ${h1}px - ${h2}px - 40px - 40px - var(--el-main-padding) * 2`;
    },
    giveTime(val) {
      //将中国标准时间转为指定格式(该组件返回的标准时间的格式,所以必须的加这个函数)
      this.form.beginTime = dayjs(val[0]).format('YYYY-MM-DD HH:mm:ss');
      this.form.endTime = dayjs(val[1]).format('YYYY-MM-DD HH:mm:ss');
    },
    // é¡µå¤§å°æ”¹å˜æ—¶è§¦å‘
    handleSizeChange(val) {
      this.pageSize = val;
      // æ”¹å˜æ¯é¡µæ˜¾ç¤ºæ•°ç›®æ—¶è·³åˆ°å½“前页
      this.handleCurrentChange(1);
    },
    // é¡µå·æ”¹å˜æ—¶è§¦å‘
    handleCurrentChange(val) {
      console.log('当前页为:', val);
      // å°†å½“前页号给currentPage
      this.currentPage = val;
      // é¡µé¢å˜åŒ–时调用 æŸ¥è¯¢æ•°æ®å‡½æ•°
      this.handleSubmit();
    },
    //序号递增
    indexMethod(index) {
      return index + 1 + (this.currentPage - 1) * this.pageSize;
    },
    // æŸ¥è¯¢æ•°æ®
    handleSubmit() {
      // if (this.isExceedOneMonth(this.form.beginTime, this.form.endTime)) {
      //   alert('时间跨度不能超过一个月');
      //   return;
      // }
      this.loading = true;
      this.queryButton = true
      let params = {};
      params['page'] = this.currentPage;
      params['pageSize'] = this.pageSize;
      if (this.form.name) {
        params['siteName'] = this.form.name;
      }
      if (this.form.number) {
        params['mnCode'] = this.form.number;
      }
      params['beginTime'] = this.form.beginTime;
      params['endTime'] = this.form.endTime;
      if (this.scenarioType.length != 0) {
        params['scenarioType'] = this.scenarioType.join();
      }
      this.$http.get('/dust/history1', { params: params }).then((response) => {
        // ä¿å­˜è¿”回的
        this.tableData = response.data.data.rows;
        this.displayData = this.tableData;
        this.loading = false;
        this.queryButton = false
        if (response.data.data.total == 0) {
          ElMessage('该时段无数据');
          this.loading = false;
          this.queryButton = false
          this.isNoData = true;
          return;
        }
        this.total = response.data.data.total;
        // ç§»é™¤ç©ºæ•°æ®çŠ¶æ€
        this.isNoData = false;
      });
    },
    backMinuteDataAWeekAgo() {
      // æ‰“开页面加载最近一周的数据
      this.loading = true;
      // ç»™è¾“入框设置默认的选择项
      let params = {};
      params['siteName'] = this.form.name;
      params['beginTime'] = this.form.beginTime;
      params['endTime'] = this.form.endTime;
      this.$http.get('/dust/history1', { params: params }).then((response) => {
        // ä¿å­˜è¿”回的
        this.tableData = response.data.data.rows;
        this.displayData = this.tableData;
        if (response.data.data.total == 0) {
          ElMessage('该时段无数据');
          this.isNoData = true;
          return;
        }
        this.total = response.data.data.total;
        this.loading = false;
      });
    }
  }
};
</script>
<template>
  <el-row>
    <el-col ref="h1" class="head-row">
      <el-card>
        <el-form :inline="true">
          <div class="demo-form-inline">
            <el-row>
              <el-col>
                <el-form-item>
                  <AreaAndmonitorType></AreaAndmonitorType>
                </el-form-item>
                <el-form-item>
                  <template #label> </template>
                  <InputSearch isNeedDefaultSite="1" @submit-value="(n) => (form.name = n)">
                  </InputSearch>
                </el-form-item>
                <el-form-item>
                  <template #label>
                    <span class="font-label">设备编号:</span>
                  </template>
                  <el-input v-model="form.number" clearable placeholder="请输入"></el-input>
                </el-form-item>
                <el-form-item>
                  <ScenarioType @submitScenarioType="(val) => (scenarioType = val)">
                  </ScenarioType>
                </el-form-item>
              </el-col>
              <el-form-item>
                <TimeSelectWithShortCuts @submit-time="giveTime"></TimeSelectWithShortCuts>
              </el-form-item>
            </el-row>
          </div>
          <div class="button-and-export">
            <el-form-item>
              <!-- <el-button
                type="primary"
                @click="handleSubmit"
                style="margin-left: 10px"
                ><el-icon style="margin-right: 6px;font-size: 1.2em;"><i-ep-Search/></el-icon>查询</el-button
              >
              <el-button type="success" @click="exportDom" round><el-icon style="margin-right: 6px;margin-bottom:2px;font-size: 1.2em;"><i-ep-Download ></i-ep-Download></el-icon>导出数据</el-button> -->
              <ButtonClick style="margin-right: 12px;" content="搜索" type="primary" :loading="queryButton" @do-search="handleSubmit"></ButtonClick>
              <ButtonExportExcel  content="导出数据" type="success" :loading="exportButton" @do-export="exportDom"></ButtonExportExcel>
            </el-form-item>
          </div>
        </el-form>
      </el-card>
    </el-col>
  </el-row>
  <el-row>
    <el-col v-show="!isNoData">
      <el-table border size="default" :highlight-current-row="true" :data="displayData" :height="tableHeight"
        v-loading="loading">
        <!--绑定一个方法,将返回值赋给index,即表格每行数据的下标-->
        <el-table-column type="index" label="序号" align="center" fixed :index="indexMethod"></el-table-column>
        <el-table-column prop="name" label="站点名称" show-overflow-tooltip></el-table-column>
        <el-table-column prop="address" label="地址" align="center" show-overflow-tooltip></el-table-column>
        <el-table-column prop="dutyCompany" label="供应商" align="center" show-overflow-tooltip></el-table-column>
        <el-table-column prop="mnCode" label="设备编号" show-overflow-tooltip></el-table-column>
        <el-table-column prop="typeName" label="类型" align="center" show-overflow-tooltip></el-table-column>
        <el-table-column prop="dustValue" label="扬尘浓度(mg/m³)" align="center" sortable
          show-overflow-tooltip></el-table-column>
        <el-table-column prop="noiseValue" label="噪声(dB)" align="center" sortable show-overflow-tooltip></el-table-column>
        <el-table-column prop="lst" label="采集时间" sortable align="center" show-overflow-tooltip></el-table-column>
        <el-table-column prop="quality" label="等级" align="center" show-overflow-tooltip></el-table-column>
        <el-table-column prop="groupName" label="所在区县" align="center" show-overflow-tooltip>
        </el-table-column>
      </el-table>
      <!--size-change æ˜¯pageSize æ”¹å˜æ—¶ä¼šè§¦å‘的事件,handleSizeChange是事件处理函数
     current-change æ˜¯currentPage æ”¹å˜æ—¶ä¼šè§¦å‘的事件    -->
      <el-pagination ref="h2" background @size-change="handleSizeChange" @current-change="handleCurrentChange"
        :page-sizes="[10, 20, 50, 100]" :page-size="pageSize" :total="total"
        layout="total,sizes, prev, pager, next, jumper" :current-page="currentPage"></el-pagination>
    </el-col>
    <el-empty v-show="isNoData" :image-size="200" />
  </el-row>
</template>
<style lang="scss" scoped>
// æ•´ä½“左外边距
.el-row {
  margin-left: 10px;
}
.head-row {
  margin: 10px 0px;
}
.el-card {
  border-radius: 9px;
}
.font-label {
  margin-top: 3px;
  font-weight: bold;
}
.demo-form-inline {
  display: flex;
}
.button-and-export {
  display: flex;
  justify-content: flex-end;
  /* ä»Žè¡Œå°¾ä½ç½®å¼€å§‹æŽ’列 */
}
.el-pagination {
  margin: 10px 0px;
}
</style>
src/views/exception/FlightInspection.vue
@@ -1,15 +1,16 @@
<script>
import InputSearch from '../../sfc/InputSearch.vue';
import ExceptionType from '../../sfc/ExceptionType.vue';
import TimeSelectWithShortCuts from '../../sfc/TimeSelectWithShortCuts.vue';
import DustExceptionText from '../../sfc/DustExceptionText.vue';
import InputSearch from '@/sfc/InputSearch.vue';
import ExceptionType from '@/sfc/ExceptionType.vue';
import TimeSelectWithShortCuts from '@/sfc/TimeSelectWithShortCuts.vue';
import DustExceptionText from './components/DustExceptionText.vue';
import { useFetch } from '../../utils/fetch.js';
import { useCommonFunction } from '../../utils/common.js';
import AreaAndmonitorType from '../../sfc/AreaAndmonitorType.vue'
import AreaAndmonitorType from '@/sfc/AreaAndmonitorType.vue'
import ButtonClick from '@/sfc/ButtonClick.vue'
import index from '@/utils/exception_common_function/index.js'
//  å¼‚常图形异步组件
const DustLineChart = defineAsyncComponent(() =>
  import('../../sfc/DustLineChart.vue')
  import('./components/DustLineChart.vue')
);
import dayjs from 'dayjs';
@@ -20,6 +21,7 @@
    TimeSelectWithShortCuts,
    DustExceptionText,
    DustLineChart,
    ButtonClick,
    AreaAndmonitorType
  },
  data() {
@@ -169,7 +171,6 @@
    },
    // å½“选择的时间发生变化时,异常分析部分的异常店铺数量同步变化
        beginTime() {
          this.getShopNames();
      },
@@ -181,31 +182,14 @@
    }
  },
  mounted() {
    // æµ‹è¯•组合式函数
    // let param = {
    //   siteName: '金山区金山新城JSC1-0401单元1-11-01地块项目09',
    //   beginTime: '2023-07-01 00:00:00',
    //   endTime: '2023-07-10 00:00:00'
    // };
    // this.backData = this.request('/dust/history1', param);
    // console.log('历史数据为:', this.backData.value);
    this.backExceptionDataAWeekAgo();
    // this.calTableHeight();
    // æŸ¥è¯¢æ—¶é—´æ®µçš„各异常的站点,查询该时间区间的各异常数量
    this.getShopNames();
    // this.exception.exception0 = this.getSiteNameByExceptionType('0',this.beginTime,this.endTime)
    // console.log('异常数据为:',this.exception.exception0);
  },
  methods: {
    // getExceptionSiteNum(){
    //   this.$http.get('/dust/exceptionsitenum').then(result => {
    //     this.exceptionSiteNum = result.data.data.length
    //   })
    // },
    /**
     * description:点击异常站点名字时 è¿”回的数据
     * @param: 
@@ -226,35 +210,12 @@
      this.selectedRowIndex = this.displayData.indexOf(this.tableCurrentRowData);
    },
    /**
     * description:返回时间数组,从开始时间的后15分钟到结束时间为止。
     * @param: å¼‚常的开始,异常结束时间
     * @createTime:2023-08-17
     * @returns:比如12:00:00-13:00:00 æ‰€ä»¥è¿”回的数组元素是 12:00:00 ,12:15:00,12:30:00,12:45:00,13:00:00
     */
    descTenTime(begin, end) {
      let time = [];
      if (begin == end) {
        time.push(begin);
        return time;
      }
      time.push(begin);
      let temp = dayjs(begin).add(15, 'minute').format('YYYY-MM-DD HH:mm:ss');
      while (temp != end) {
        time.push(temp);
        temp = dayjs(temp).add(15, 'minute').format('YYYY-MM-DD HH:mm:ss');
      }
      // åŠ ä¸Šå¼‚å¸¸çš„ç»“æŸæ—¶é—´
      time.push(temp);
      return time;
    },
    /**
     * description:断电或断网时设置的表格数据
     */
    setOfflineTbleData(){
      // æ— æ•°æ®æ—¶çš„æ—¶é—´æ•°ç»„ æ—¶é—´ç›¸å·®15分钟
      const abnormalTimeTenMinute = this.descTenTime(
      const abnormalTimeTenMinute = index.descFiftyTime(
        this.tableCurrentRowData.beginTime,
        this.tableCurrentRowData.endTime
      );
@@ -275,63 +236,9 @@
      this.exceptionTotal = abnormalTimeTenMinute.length;
    },
    /**
     * description:返回开始时间的前45分钟的时间点,结束时间后45分钟的时间点
     * @param: å¼‚常的开始时间,异常的结束时间。
     * @returns:数组。time[0],time[1],time[2],time[3]分别代表异常区间前45分钟的时间点,前15分钟的时间点,后15分钟的时间点,后45分钟的时间点
     */
    before45AndAfter45(begin, end) {
      let time = [];
      // å‰ä¸€æ®µçš„开始时间
      const before45MinBegin = dayjs(begin)
        .subtract(45, 'minute')
        .format('YYYY-MM-DD HH:mm:ss');
      // å‰ä¸€æ®µçš„结束时间
      const before15MinBegin = dayjs(begin)
        .subtract(15, 'minute')
        .format('YYYY-MM-DD HH:mm:ss');
      // åŽä¸€æ®µçš„开始时间
      const after15MinBegin = dayjs(end)
        .add(15, 'minute')
        .format('YYYY-MM-DD HH:mm:ss');
      // å¾€åŽ40分钟
      const after45MinEnd = dayjs(end)
        .add(45, 'minute')
        .format('YYYY-MM-DD HH:mm:ss');
      time.push(before45MinBegin);
      time.push(before15MinBegin);
      time.push(after15MinBegin);
      time.push(after45MinEnd);
      return time;
    },
    /**
     * description:返回某站点在该时段历史数据的get请求参数
     * @param: ç«™ç‚¹åç§°ï¼Œ å¼€å§‹æ—¶é—´ï¼Œ ç»“束时间
     * @returns:对象
     */
    requestGetParms(name, begin, end) {
      return {
        siteName: name,
        beginTime: begin,
        endTime: end
      };
    },
    /**
     * description:相差多少个15分钟  è®¡ç®—中包括开始时间,结束时间。
     * @param: å¼‚常开始时间,异常结束时间
     * @returns:整数
     */
    diffFiftyMinutesNum(beginNormal, endNormal) {
      // å°†å¼€å§‹æ—¶é—´å’Œç»“束时间转换为dayjs对象
      const start = dayjs(beginNormal).subtract(15, 'minute');
      const end = dayjs(endNormal);
      // è®¡ç®—结束时间减去开始时间中间相差多少个十分钟
      const diffInMinutes = end.diff(start, 'minute');
      const diffInTenMinutes = Math.floor(diffInMinutes / 15);
      return diffInTenMinutes;
    },
    // æ®µç”µæˆ–断网区间无数据,需要补充。其他的都有数据,直接一次请求全部时段就好
    // æ ¹æ®å¼‚常区间构造前后端首尾 å‰åŒºé—´ ä¸­é—´åŒºé—´ åŽåŒºé—´
@@ -362,7 +269,7 @@
        let timeAndValue = {};
        // ä»Žæ·»åŠ äº†é¦–ä½åŒºé—´çš„å¼€å§‹å’Œç»“æŸæ—¶é—´è¿›è¡ŒéåŽ† ä¿è¯æ—¶é—´ä»¥10分钟为间隔
        timeAndValue = this.keepContinuousByEachFiftyMinutes(
        timeAndValue = index.keepContinuousByEachFiftyMinutes(
            allTime[0],
            allTime[3],
            this.dialog.allExceptionTimeData
@@ -384,59 +291,7 @@
            });
       
    },
    /**
     * description:判断data中是否有该日期时间,存在返回该时间对应的浓度值,否则返回-1
     * @param: åŠ ä¸Šå‰åŽåŒºé—´çš„å¼‚å¸¸æ•°æ®ï¼Œæ—¶é—´å­—ç¬¦ä¸²
     * @returns:
     */
    findTimeInExceptionData(data, time) {
      for (let i = 0; i < data.length; i++) {
        if (data[i] == null) {
          continue;
        }
        if (data[i]['lst'] == time) {
          return data[i]['dustValue'];
        }
      }
      return -1;
    },
    /**
     * description:根据开始和结束时间,返回以15分钟为间隔的时间和对应的值
     * @param: å‰åŒºé—´çš„开始时间, åŽåŒºé—´çš„结束时间, åŠ ä¸Šå‰åŽåŒºé—´çš„æ€»æ—¶é—´æ®µçš„å¼‚å¸¸æ•°æ®çš„å¯¹è±¡æ•°ç»„
     * @returns:对象。包含了折线图的x轴,y轴的配置数据
     */
    keepContinuousByEachFiftyMinutes(
      intervalStarTime,
      intervalEndTime,
      headAndTailExceptionData
    ) {
      let xAxis = [];
      let yAxis = [];
      let obj = {};
      let current = intervalStarTime;
      let tail = dayjs(intervalEndTime)
        .add(15, 'minute')
        .format('YYYY-MM-DD HH:mm:ss');
      while (current != tail) {
        let value = this.findTimeInExceptionData(
          headAndTailExceptionData,
          current
        );
        if (value != -1) {
          xAxis.push(current);
          yAxis.push(value);
        } else {
          xAxis.push(current);
          yAxis.push(null);
        }
        current = dayjs(current)
          .add(15, 'minute')
          .format('YYYY-MM-DD HH:mm:ss');
      }
      obj['xAxis'] = xAxis;
      obj['yAxis'] = yAxis;
      return obj;
    },
    /**
     * description:绘制折线图
@@ -891,13 +746,13 @@
      // beforeAndAfterTime[1]:前15分钟的时间点
      // beforeAndAfterTime[2]:后15分钟的时间点
      // beforeAndAfterTime[3]:后45分钟的时间点
      let beforeAndAfterTime = this.before45AndAfter45(
      let beforeAndAfterTime = index.before45AndAfter45(
        exceptionBeginTime,
        exceptionEndTime
      );
      // æž„造异常时间前后区间数据请求参数(除了断网中都用到)
      let paramsAllTime = this.requestGetParms(
      let paramsAllTime = index.requestGetParms(
        this.tableCurrentRowData.name,
        beforeAndAfterTime[0],
        beforeAndAfterTime[3]
@@ -924,7 +779,7 @@
        // å¾—到上一行的数据
        this.tableCurrentRowData = this.displayData[this.selectedRowIndex]
        let params = this.requestGetParms(this.tableCurrentRowData.name,this.tableCurrentRowData.beginTime,this.tableCurrentRowData.endTime)
        let params = index.requestGetParms(this.tableCurrentRowData.name,this.tableCurrentRowData.beginTime,this.tableCurrentRowData.endTime)
        this.loading.preButton = true
        this.$http
          .get('/dust/history', { params: params })
@@ -960,7 +815,7 @@
         // å¾—到上一行的数据
         this.tableCurrentRowData = this.displayData[this.selectedRowIndex]
        let params = this.requestGetParms(this.tableCurrentRowData.name,this.tableCurrentRowData.beginTime,this.tableCurrentRowData.endTime)
        let params = index.requestGetParms(this.tableCurrentRowData.name,this.tableCurrentRowData.beginTime,this.tableCurrentRowData.endTime)
        this.loading.afterButton = true
        this.$http
          .get('/dust/history', { params: params })
@@ -1360,7 +1215,7 @@
          </el-form-item>
          <el-form-item>
            <InputSearch
              :isNeedDefaultSite="0"
              isNeedDefaultSite="0"
              @submit-value="(n) => (form.name = n)"
              @submit-site-Nums="(n) => (siteTotal = n)"
            >
@@ -1380,7 +1235,8 @@
        <div class="head-container-search">
          <el-form-item>
            <el-button type="warning" :loading="loading.queryButton" @click="handleSubmit">查询</el-button>
            <!-- <el-button type="warning" :loading="loading.queryButton" @click="handleSubmit">查询</el-button> -->
            <ButtonClick content="分析" type="warning" :loading="loading.queryButton" @do-search="handleSubmit"></ButtonClick>
          </el-form-item>
        </div>
      </el-form>
@@ -1608,7 +1464,7 @@
              <!-- æ ‡å¤´ -->
              <div class="card-text1">
                <image class="card-header-image"></image>
                <span class="card-header-text">滑动平均值异常</span>
                <span class="card-header-text">变化趋势异常</span>
              </div>
              <div class="card-content-text">
@@ -1745,7 +1601,7 @@
              <!-- æ ‡å¤´ -->
              <div class="card-text1">
                <image class="card-header-image"></image>
                <span class="card-header-text">断电或断网</span>
                <span class="card-header-text">数据缺失异常</span>
              </div>
              <div class="card-content-text">
@@ -2009,7 +1865,7 @@
        ref="table"
        :data="displayData"
        :height="tableHeight"
        highlight-current-row="true"
        :highlight-current-row="true"
        size="default"
        v-loading="loading.tableLoading"
        border
@@ -2333,10 +2189,7 @@
/* æŸ¥çœ‹è¯¦æƒ…对话框模块的样式 */
:deep(.el-dialog) {
  // å¯¹è¯æ¡†é«˜åº¦
}
.diag-head {
  // å¯¹è¯æ¡†å¤´éƒ¨åŒºåŸŸ
  min-height: 200px;
@@ -2361,11 +2214,6 @@
  border: 2px solid #7bc0fc;
}
.chart-jump-button {
  // â€˜ä¸Šä¸€æ¡â€™ï¼Œâ€˜ä¸‹ä¸€æ¡â€™ æŒ‰é’®
  // border: 1px solid #fdc2db;
  // min-height: 30px;
  // width: 200px;
  // float: right;
  display: flex;
  justify-content: right;
}
src/views/exception/SiteAuditAssistance.vue
@@ -1,25 +1,25 @@
<script>
import InputSearch from '../../sfc/InputSearch.vue';
import ExceptionType from '../../sfc/ExceptionType.vue';
import TimeSelectWithShortCuts from '../../sfc/TimeSelectWithShortCuts.vue';
import { useFetch } from '../../utils/fetch.js';
import InputSearch from '@/sfc/InputSearch.vue';
import ExceptionType from '@/sfc/ExceptionType.vue';
import TimeSelectWithShortCuts from '@/sfc/TimeSelectWithShortCuts.vue';
import { useCommonFunction } from '../../utils/common.js';
import AreaAndmonitorType from '../../sfc/AreaAndmonitorType.vue'
import AreaAndmonitorType from '@/sfc/AreaAndmonitorType.vue';
//  å¼‚常图形异步组件
const DustLineChart = defineAsyncComponent(() =>
  import('../../sfc/DustLineChart.vue')
  import('./components/DustLineChart.vue')
);
import submitApi from '@/api/audit/submitApi.js';
import dayjs from 'dayjs';
import ButtonClick from '@/sfc/ButtonClick.vue';
import index from '@/utils/exception_common_function/index.js';
export default {
  components: {
    ExceptionType,
    InputSearch,
    TimeSelectWithShortCuts,
    DustLineChart,
    AreaAndmonitorType
    AreaAndmonitorType,
    ButtonClick
  },
  data() {
    return {
@@ -28,8 +28,7 @@
        // ç«™ç‚¹åç§°
        name: '',
        // é€‰æ‹©çš„异常类型
        exceptionName: [],
        exceptionName: []
      },
      beginTime: '',
      endTime: '',
@@ -37,6 +36,8 @@
      tableData: [],
      // è¡¨æ ¼å±•示的数据
      displayData: [],
      // è¡¨æ ¼åˆ—多选
      multipleSelection: [],
      // è¡¨æ ¼é«˜åº¦
      tableHeight: 400,
      // è¡¨æ ¼æ•°æ®
@@ -51,40 +52,6 @@
      // å¯¹è¯æ¡†æ˜¾ç¤º
      dialogTableVisible: false,
      // ä¿å­˜å¼‚常对应的店铺名称和设备编号
      exception: {
        // æ–­ç”µæˆ–断网
        exception0: [],
        // æ•°æ®è¶…低
        exception1: [],
        // è¶…æ ‡
        exception2: [],
        // æ•°æ®é•¿æ—¶æ®µæ— æ³¢åЍ
        exception3: [],
        // é‡çº§çªå˜å¼‚常
        exception4: [],
        // ä¸´è¿‘超标异常
        exception5: [],
        // å•日超标次数临界异常
        exception6: [],
        // æ»‘动平均值异常
        exception7: [],
        // è¯¥æ—¶æ®µçš„异常数量
        exception0Num: 0,
        exception1Num: 0,
        exception2Num: 0,
        exception3Num: 0,
        exception4Num: 0,
        exception5Num: 0,
        exception6Num: 0,
        exception7Num: 0,
      },
      // ç«™ç‚¹æ€»æ•°é‡
      siteTotal: 0,
      // å¼‚常的站点总数量
      // exceptionSiteNum:0,
      // é€‰ä¸­è¡¨æ ¼å½“前行的数据
      tableCurrentRowData: null,
@@ -92,6 +59,7 @@
      selectedRowIndex:-2,
      // é¡µé¢ä¸Šçš„æŒ‰é’®åŠ è½½çŠ¶æ€
      loading: {
        submitAudit: false,
        // æŸ¥è¯¢æŒ‰é’®
        queryButton:false,
            // è¡¨æ ¼åŠ è½½ä¸­
@@ -101,8 +69,7 @@
        // ä¸‹ä¸€æ¡æŒ‰é’®
        afterButton: false,
        // æŠ˜çº¿å›¾
        lineChart: false,
        lineChart: false
      },
      dialog: {
@@ -126,18 +93,22 @@
        banTouch:0,
        // 0代表分页,1代表不分页
        originClick:0
      }
      },
      auditDialog: {
        visible: false,
        // å®¡æ ¸äºº
        checker: 'admin',
        checkDate: '',
        checkerNotes: '',
        enterpriseNotes: ''
      },
      auditTableData: [],
      auditNumByTime: 0
    };
  },
  setup() {
    // provide('search',readonly(form))
    const { backData, error, request } = useFetch();
    const { isExceedOneMonth } = useCommonFunction();
    return {
      backData,
      error,
      request,
      isExceedOneMonth
    };
  },
@@ -167,29 +138,266 @@
      }
    },
    // å½“选择的时间发生变化时,异常分析部分的异常店铺数量同步变化
        beginTime() {
          this.getShopNames();
      },
      endTime() {
        this.getShopNames();
      },
    dialogTableVisible() {
      window.addEventListener('resize', this.updateChart);
    }
  },
  computed: {
    unCheckedNUm() {
      return this.total - this.auditNumByTime;
    },
    // å®¡æ ¸æ¯”例
    checkedRate() {
      return (this.auditNumByTime / this.total) * 100;
    }
  },
  mounted() {
    this.backExceptionDataAWeekAgo();
    this.calTableHeight();
    // æŸ¥è¯¢æ—¶é—´æ®µçš„各异常的站点,查询该时间区间的各异常数量
    this.getShopNames();
  },
  methods: {
    /**
     * æŸ¥çœ‹è¯¥æ®µæ—¶é—´å†…已审核的数量
     * @param:
     * @returns:
     */
    gethasCheckedNumByTime() {
      submitApi.getAuditNumByTime(this.beginTime, this.endTime).then((res) => {
        this.auditNumByTime = res.data.data.length;
      });
    },
    /**
     * å¤šé€‰åˆ—(已审核的行不会加入其中)
     * @param
     * @returns
     */
    handleSelectionChange(val) {
      console.log('选中的行为:', val);
      this.multipleSelection = val.filter((row) => row.auditStatus != 3);
    },
    /**
     * è§¦å‘批量审核
     * @param:
     * @returns:
     */
    quickReview() {
      if (this.multipleSelection.length != 0) {
        ElMessageBox.confirm('确定要批量审核吗?', {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'warning',
          center: true
        }).then(() => {
          this.noNoteCheck(this.multipleSelection);
          setTimeout(() => {
            this.gethasCheckedNumByTime();
            ElMessage.success('批量审核完成');
          }, 1500);
        });
      } else {
        ElMessage('未选中表格的行');
      }
    },
    /**
     * æ¸…除已选中的表格行:
     * @param:
     * @returns:
     */
    clearSelected() {
      this.$refs.table.clearSelection();
    },
    toggleSelection() {
      this.$refs.table.clearSelection();
    },
    /**
     *提交批量审核。默认审核人,空备注
     * @param: éœ€è¦å¿«é€Ÿå®¡æ ¸çš„行
     * @returns:
     */
    noNoteCheck(rows) {
      rows.forEach((item) => {
        submitApi.submitAudit('admin', '无', '无', item.id, 3);
        item.auditStatus = 3;
      });
    },
    close() {
      // if (this.auditDialog.checkerNotes || this.auditDialog.enterpriseNotes) {
      //   ElMessageBox.confirm('这将会,确定要关闭吗', '提示',
      //     {
      //       confirmButtonText: '确定',
      //       cancelButtonText: '取消',
      //       type: 'warning',
      //       center :'true',
      //       icon: markRaw(Delete),
      //       draggable: true,
      //     }).then(() => {
      //       ElMessage({
      //         type: 'success',
      //         message: '已关闭',
      //       })
      //       this.auditDialog.visible = false
      //     })
      // }else{
      //   this.auditDialog.visible = false
      // }
      this.auditDialog.visible = false;
    },
    // è¡¨æ ¼è¡Œçš„颜色
    tableRowClassName({ row }) {
      if (row.auditStatus == 0) {
        return 'black-row';
      } else if (row.auditStatus == 1 || row.auditStatus == 2) {
        return 'deep-gray-row';
      } else {
        return 'complete--gray-row';
      }
    },
    /**
     * å‘请求
     * @param:审核人,审核人备注,企业备注,异常记录编号 è¯¥æ¡å¼‚常的审核状态
     * @returns:
     */
    sendAudit(user, checker, enterprise, exceptionId, status) {
      submitApi
        .submitAudit(
          user,
          this.auditDialog.checkerNotes,
          this.auditDialog.enterpriseNotes,
          exceptionId,
          status
        )
        .then((res) => {
          if (res.data.code == 1) {
            ElMessage.success('提交成功');
            this.tableCurrentRowData.auditStatus = status;
            this.tableCurrentRowData.checker = user;
            if (checker) {
              this.tableCurrentRowData.checkerContent = checker;
            }
            if (enterprise) {
              this.tableCurrentRowData.enterpriseContent = enterprise;
            }
          } else {
            ElMessage.warning('提交失败');
          }
          this.loading.submitAudit = false;
          this.auditDialog.visible = false;
        });
    },
    // æ›´æ–°å®¡æ ¸å†…容
    updateAud(exceptionId, checkerContent, enterpriseContent, auditStatus) {
      submitApi
        .updateAudit(
          exceptionId,
          checkerContent,
          enterpriseContent,
          auditStatus
        )
        .then((res) => {
          if (res.data.code == 1) {
            ElMessage.success('提交成功');
            this.tableCurrentRowData.auditStatus = auditStatus;
            if (checkerContent) {
              this.tableCurrentRowData.checkerContent = checkerContent;
            }
            if (enterpriseContent) {
              this.tableCurrentRowData.enterpriseContent = enterpriseContent;
            }
          } else {
            ElMessage.warning('提交失败');
          }
          this.loading.submitAudit = false;
          this.auditDialog.visible = false;
        });
    },
    /**
     * æäº¤å®¡æ ¸
     * @param:
     * @returns:
     */
    submitAudit() {
      // åŒæ—¶å¡«å†™äº†å®¡æ ¸äººå‘˜å’Œä¼ä¸šçš„备注
      this.loading.submitAudit = true;
      if (this.auditDialog.checkerNotes && this.auditDialog.enterpriseNotes) {
        this.sendAudit(
          this.auditDialog.checker,
          this.auditDialog.checkerNotes,
          this.auditDialog.enterpriseNotes,
          this.tableCurrentRowData.id,
          3
        );
      }
      // åªå¡«äº†å®¡æ ¸äººå‘˜å¤‡æ³¨
      else if (
        this.auditDialog.checkerNotes &&
        !this.auditDialog.enterpriseNotes
      ) {
        // ç¬¬ä¸€æ¬¡åˆ›å»º
        if (this.tableCurrentRowData.auditStatus == 0) {
          this.sendAudit(
            this.auditDialog.checker,
            this.auditDialog.checkerNotes,
            this.auditDialog.enterpriseNotes,
            this.tableCurrentRowData.id,
            1
          );
        }
        // åªæ›´æ–°
        else {
          this.updateAud(
            this.tableCurrentRowData.id,
            this.auditDialog.checkerNotes,
            this.auditDialog.enterpriseNotes,
            3
          );
        }
      }
      // åªå¡«äº†ä¼ä¸šå¤‡æ³¨å¤‡æ³¨
      else if (
        this.auditDialog.enterpriseNotes &&
        !this.auditDialog.checkerNotes
      ) {
        // ç¬¬ä¸€æ¬¡åˆ›å»º
        if (this.tableCurrentRowData.auditStatus == 0) {
          this.sendAudit(
            this.auditDialog.checker,
            this.auditDialog.checkerNotes,
            this.auditDialog.enterpriseNotes,
            this.tableCurrentRowData.id,
            2
          );
        } else {
          // åªæ›´æ–°
          this.updateAud(
            this.tableCurrentRowData.id,
            this.auditDialog.checkerNotes,
            this.auditDialog.enterpriseNotes,
            3
          );
        }
      } else {
        ElMessage.warning('请填写完整才能提交');
      }
      this.loading.submitAudit = false;
      // æ¸…除
      this.auditDialog.checkerNotes = '';
      this.auditDialog.enterpriseNotes = '';
    },
    /**
     * å¼¹å‡ºå¯¹è¯æ¡†å¹¶ä¸”保存当前行数据
     * @param:
     * @createTime:2023-08-17
     * @returns:
     */
    openAuditDiag(row) {
      this.auditDialog.visible = true;
      this.tableCurrentRowData = row;
      console.log(row);
    },
    /**
     * description:点击异常站点名字时 è¿”回的数据
@@ -198,48 +406,27 @@
     * @returns:
     */
    getAbnormalDataByClick(val) {
      this.flag.originClick = 1
      this.flag.originClick = 1;
      this.tableData = val
      this.total = this.tableData.length
      this.tableData = val;
      this.total = this.tableData.length;
      // é»˜è®¤æ˜¾ç¤ºç¬¬ä¸€é¡µ
      this.handleCurrentChange(1);
    },
     // ç‚¹å‡»è¡¨æ ¼çš„行时
     selectTableRow() {
      // èŽ·å–å½“å‰è¡Œçš„ç´¢å¼•
      this.selectedRowIndex = this.displayData.indexOf(this.tableCurrentRowData);
      this.selectedRowIndex = this.displayData.indexOf(
        this.tableCurrentRowData
      );
    },
    /**
     * description:返回时间数组,从开始时间的后15分钟到结束时间为止。
     * @param: å¼‚常的开始,异常结束时间
     * @createTime:2023-08-17
     * @returns:比如12:00:00-13:00:00 æ‰€ä»¥è¿”回的数组元素是 12:00:00 ,12:15:00,12:30:00,12:45:00,13:00:00
     */
    descTenTime(begin, end) {
      let time = [];
      if (begin == end) {
        time.push(begin);
        return time;
      }
      time.push(begin);
      let temp = dayjs(begin).add(15, 'minute').format('YYYY-MM-DD HH:mm:ss');
      while (temp != end) {
        time.push(temp);
        temp = dayjs(temp).add(15, 'minute').format('YYYY-MM-DD HH:mm:ss');
      }
      // åŠ ä¸Šå¼‚å¸¸çš„ç»“æŸæ—¶é—´
      time.push(temp);
      return time;
    },
    /**
     * description:断电或断网时设置的表格数据
     */
    setOfflineTbleData(){
      // æ— æ•°æ®æ—¶çš„æ—¶é—´æ•°ç»„ æ—¶é—´ç›¸å·®15分钟
      const abnormalTimeTenMinute = this.descTenTime(
      const abnormalTimeTenMinute = index.descFiftyTime(
        this.tableCurrentRowData.beginTime,
        this.tableCurrentRowData.endTime
      );
@@ -260,63 +447,6 @@
      this.exceptionTotal = abnormalTimeTenMinute.length;
    },
    /**
     * description:返回开始时间的前45分钟的时间点,结束时间后45分钟的时间点
     * @param: å¼‚常的开始时间,异常的结束时间。
     * @returns:数组。time[0],time[1],time[2],time[3]分别代表异常区间前45分钟的时间点,前15分钟的时间点,后15分钟的时间点,后45分钟的时间点
     */
    before45AndAfter45(begin, end) {
      let time = [];
      // å‰ä¸€æ®µçš„开始时间
      const before45MinBegin = dayjs(begin)
        .subtract(45, 'minute')
        .format('YYYY-MM-DD HH:mm:ss');
      // å‰ä¸€æ®µçš„结束时间
      const before15MinBegin = dayjs(begin)
        .subtract(15, 'minute')
        .format('YYYY-MM-DD HH:mm:ss');
      // åŽä¸€æ®µçš„开始时间
      const after15MinBegin = dayjs(end)
        .add(15, 'minute')
        .format('YYYY-MM-DD HH:mm:ss');
      // å¾€åŽ40分钟
      const after45MinEnd = dayjs(end)
        .add(45, 'minute')
        .format('YYYY-MM-DD HH:mm:ss');
      time.push(before45MinBegin);
      time.push(before15MinBegin);
      time.push(after15MinBegin);
      time.push(after45MinEnd);
      return time;
    },
    /**
     * description:返回某站点在该时段历史数据的get请求参数
     * @param: ç«™ç‚¹åç§°ï¼Œ å¼€å§‹æ—¶é—´ï¼Œ ç»“束时间
     * @returns:对象
     */
    requestGetParms(name, begin, end) {
      return {
        siteName: name,
        beginTime: begin,
        endTime: end
      };
    },
    /**
     * description:相差多少个15分钟  è®¡ç®—中包括开始时间,结束时间。
     * @param: å¼‚常开始时间,异常结束时间
     * @returns:整数
     */
    diffFiftyMinutesNum(beginNormal, endNormal) {
      // å°†å¼€å§‹æ—¶é—´å’Œç»“束时间转换为dayjs对象
      const start = dayjs(beginNormal).subtract(15, 'minute');
      const end = dayjs(endNormal);
      // è®¡ç®—结束时间减去开始时间中间相差多少个十分钟
      const diffInMinutes = end.diff(start, 'minute');
      const diffInTenMinutes = Math.floor(diffInMinutes / 15);
      return diffInTenMinutes;
    },
    // æ®µç”µæˆ–断网区间无数据,需要补充。其他的都有数据,直接一次请求全部时段就好
    // æ ¹æ®å¼‚常区间构造前后端首尾 å‰åŒºé—´ ä¸­é—´åŒºé—´ åŽåŒºé—´
@@ -330,14 +460,14 @@
     */
     otherExceptionRequest(allTimeArgs,allTime,exceptionBT,exceptionET) {
       // æŠ˜çº¿å›¾åŠ è½½ä¸­æ•ˆæžœ
      this.loading.lineChart = true
      this.loading.lineChart = true;
      this.$http
        .get('/dust/history', { params: allTimeArgs })
        .then((result) => {
          this.dialog.allExceptionTimeData = result.data.data;
        //  æ–­ç”µæˆ–断网时重新设置表格
        if(this.tableCurrentRowData.exceptionType == '0'){
            this.setOfflineTbleData()
            this.setOfflineTbleData();
        }
            // x轴日期时间
@@ -347,7 +477,7 @@
        let timeAndValue = {};
        // ä»Žæ·»åŠ äº†é¦–ä½åŒºé—´çš„å¼€å§‹å’Œç»“æŸæ—¶é—´è¿›è¡ŒéåŽ† ä¿è¯æ—¶é—´ä»¥10分钟为间隔
        timeAndValue = this.keepContinuousByEachFiftyMinutes(
          timeAndValue = index.keepContinuousByEachFiftyMinutes(
            allTime[0],
            allTime[3],
            this.dialog.allExceptionTimeData
@@ -356,71 +486,20 @@
        dustValue = timeAndValue['yAxis'];
        
        // æå–异常起始时间点在整个区间内的数据索引
        let startIndex = dateList.findIndex(
            (item) => item === exceptionBT
        );
          let startIndex = dateList.findIndex((item) => item === exceptionBT);
        let endIndex = dateList.findIndex((item) => item === exceptionET);
        // è®¾ç½®æŠ˜çº¿å›¾é…ç½®é¡¹
        this.reSetChart(dateList,dustValue,exceptionBT, exceptionET,
          this.reSetChart(
            dateList,
            dustValue,
            exceptionBT,
            exceptionET,
                    startIndex,
                    endIndex)
         this.loading.lineChart = false
            });
    },
    /**
     * description:判断data中是否有该日期时间,存在返回该时间对应的浓度值,否则返回-1
     * @param: åŠ ä¸Šå‰åŽåŒºé—´çš„å¼‚å¸¸æ•°æ®ï¼Œæ—¶é—´å­—ç¬¦ä¸²
     * @returns:
     */
    findTimeInExceptionData(data, time) {
      for (let i = 0; i < data.length; i++) {
        if (data[i] == null) {
          continue;
        }
        if (data[i]['lst'] == time) {
          return data[i]['dustValue'];
        }
      }
      return -1;
    },
    /**
     * description:根据开始和结束时间,返回以15分钟为间隔的时间和对应的值
     * @param: å‰åŒºé—´çš„开始时间, åŽåŒºé—´çš„结束时间, åŠ ä¸Šå‰åŽåŒºé—´çš„æ€»æ—¶é—´æ®µçš„å¼‚å¸¸æ•°æ®çš„å¯¹è±¡æ•°ç»„
     * @returns:对象。包含了折线图的x轴,y轴的配置数据
     */
    keepContinuousByEachFiftyMinutes(
      intervalStarTime,
      intervalEndTime,
      headAndTailExceptionData
    ) {
      let xAxis = [];
      let yAxis = [];
      let obj = {};
      let current = intervalStarTime;
      let tail = dayjs(intervalEndTime)
        .add(15, 'minute')
        .format('YYYY-MM-DD HH:mm:ss');
      while (current != tail) {
        let value = this.findTimeInExceptionData(
          headAndTailExceptionData,
          current
            endIndex
        );
        if (value != -1) {
          xAxis.push(current);
          yAxis.push(value);
        } else {
          xAxis.push(current);
          yAxis.push(null);
        }
        current = dayjs(current)
          .add(15, 'minute')
          .format('YYYY-MM-DD HH:mm:ss');
      }
      obj['xAxis'] = xAxis;
      obj['yAxis'] = yAxis;
      return obj;
          this.loading.lineChart = false;
        });
    },
    /**
@@ -831,8 +910,7 @@
                      }
                    ]
                  ]
                },
                }
              }
            ],
            // æŒ‡å®šæ—¶é—´åŒºé—´çš„线段变颜色
@@ -859,15 +937,14 @@
          };
          break;
        default:
          console.log('没有设置该异常类型!');;
          console.log('没有设置该异常类型!');
      }
      this.flag.banTouch = 0
      this.flag.banTouch = 0;
    },
    /**
     * description:划分出异常起始时间,构造请求前中后的参数
     */
    timeAndDataProcessed() {
      //异常的开始时间 ç»“束时间
      let exceptionBeginTime = this.tableCurrentRowData.beginTime;
      let exceptionEndTime = this.tableCurrentRowData.endTime;
@@ -876,20 +953,25 @@
      // beforeAndAfterTime[1]:前15分钟的时间点
      // beforeAndAfterTime[2]:后15分钟的时间点
      // beforeAndAfterTime[3]:后45分钟的时间点
      let beforeAndAfterTime = this.before45AndAfter45(
      let beforeAndAfterTime = index.before45AndAfter45(
        exceptionBeginTime,
        exceptionEndTime
      );
      // æž„造异常时间前后区间数据请求参数(除了断网中都用到)
      let paramsAllTime = this.requestGetParms(
      let paramsAllTime = index.requestGetParms(
        this.tableCurrentRowData.name,
        beforeAndAfterTime[0],
        beforeAndAfterTime[3]
      );
    // å°†å¼‚常数据进行预处理,随后将结果作为折线图的配置项
      this.otherExceptionRequest(paramsAllTime,beforeAndAfterTime,exceptionBeginTime,exceptionEndTime)
      this.otherExceptionRequest(
        paramsAllTime,
        beforeAndAfterTime,
        exceptionBeginTime,
        exceptionEndTime
      );
    },
    /**
@@ -899,7 +981,7 @@
    //     // ä¸æ˜¯è¡¨æ ¼çš„æœ€åŽä¸€è¡Œ
      if (this.selectedRowIndex < this.displayData.length - 1) {
        // ç‚¹å‡»è¿‡ç¨‹ä¸­ é”ä½ä¸Šä¸‹æ¡æŒ‰é’®  åœ¨è®¾ç½®å®Œå›¾å½¢é…ç½®é¡¹åŽè§£é”
        this.flag.banTouch = 1
        this.flag.banTouch = 1;
        //得到上一行数据索引
        this.selectedRowIndex = this.selectedRowIndex + 1;
@@ -908,25 +990,22 @@
        // this.setinfo(this.selectedRowIndex);
        // å¾—到上一行的数据
        this.tableCurrentRowData = this.displayData[this.selectedRowIndex]
        let params = this.requestGetParms(this.tableCurrentRowData.name,this.tableCurrentRowData.beginTime,this.tableCurrentRowData.endTime)
        this.loading.preButton = true
        this.$http
          .get('/dust/history', { params: params })
          .then((response) => {
        this.tableCurrentRowData = this.displayData[this.selectedRowIndex];
        let params = index.requestGetParms(
          this.tableCurrentRowData.name,
          this.tableCurrentRowData.beginTime,
          this.tableCurrentRowData.endTime
        );
        this.loading.preButton = true;
        this.$http.get('/dust/history', { params: params }).then((response) => {
            // ä¿å­˜è¿”回的超标数据
            this.dialog.historyData = response.data.data;
            this.dialog.exceptionTotal = response.data.data.length;
            // é€»è¾‘处理
            this.timeAndDataProcessed()
            this.loading.preButton = false
          this.timeAndDataProcessed();
          this.loading.preButton = false;
          });
      }
        //得到上一行数据索引
        // this.selectedRowIndex = this.selectedRowIndex + 1;
        // this.tableCurrentRowData = this.displayData[this.selectedRowIndex]
        // console.log('当前行数据为:',this.tableCurrentRowData);
    },
    /**
     * description:获取下一条异常信息
@@ -935,228 +1014,31 @@
         // ä¸æ˜¯è¡¨æ ¼çš„第一行
      if (this.selectedRowIndex !== 0) {
        // ç‚¹å‡»è¿‡ç¨‹ä¸­ é”ä½ä¸Šä¸‹æ¡æŒ‰é’®  åœ¨è®¾ç½®å®Œå›¾å½¢é…ç½®é¡¹åŽè§£é”
        this.flag.banTouch = 1
        this.flag.banTouch = 1;
        //得到上一行数据索引
        this.selectedRowIndex = this.selectedRowIndex - 1;
        //请求数据 æ”¹å˜exceedingData
        // this.setinfo(this.selectedRowIndex);
         // å¾—到上一行的数据
         this.tableCurrentRowData = this.displayData[this.selectedRowIndex]
        this.tableCurrentRowData = this.displayData[this.selectedRowIndex];
        let params = this.requestGetParms(this.tableCurrentRowData.name,this.tableCurrentRowData.beginTime,this.tableCurrentRowData.endTime)
        this.loading.afterButton = true
        this.$http
          .get('/dust/history', { params: params })
          .then((response) => {
        let params = index.requestGetParms(
          this.tableCurrentRowData.name,
          this.tableCurrentRowData.beginTime,
          this.tableCurrentRowData.endTime
        );
        this.loading.afterButton = true;
        this.$http.get('/dust/history', { params: params }).then((response) => {
            // ä¿å­˜è¿”回的超标数据
            this.dialog.historyData = response.data.data;
            this.dialog.exceptionTotal = response.data.data.length;
            // é€»è¾‘处理
            this.timeAndDataProcessed()
            this.loading.afterButton = false
          this.timeAndDataProcessed();
          this.loading.afterButton = false;
          });
      }
    },
    /**
     * description:从子组件获得某站点该时段的异常数据
     * @createTime:2023-08-18
     */
    backExceptionData(val1, val2) {
      this.displayData = val1;
      this.total = val2;
    },
    /**
     * description:当用户改变查询的时间区间时,会根据该区间查询各异常的站点,查询该时间区间的各异常数量
     * @createTime:2023-08-18
     */
    getShopNames() {
      /* æŸ¥è¯¢å¼‚常的站点 */
      this.$http
        .get('/dust/sitenamecode', {
          params: {
            exceptionType: '0',
            beginTime: this.beginTime,
            endTime: this.endTime
          }
        })
        .then((result) => {
          this.exception.exception0 = result.data.data;
        });
      this.$http
        .get('/dust/sitenamecode', {
          params: {
            exceptionType: '1',
            beginTime: this.beginTime,
            endTime: this.endTime
          }
        })
        .then((result) => {
          this.exception.exception1 = result.data.data;
        });
      this.$http
        .get('/dust/sitenamecode', {
          params: {
            exceptionType: '2',
            beginTime: this.beginTime,
            endTime: this.endTime
          }
        })
        .then((result) => {
          this.exception.exception2 = result.data.data;
        });
      this.$http
        .get('/dust/sitenamecode', {
          params: {
            exceptionType: '3',
            beginTime: this.beginTime,
            endTime: this.endTime
          }
        })
        .then((result) => {
          this.exception.exception3 = result.data.data;
        });
        this.$http
        .get('/dust/sitenamecode', {
          params: {
            exceptionType: '4',
            beginTime: this.beginTime,
            endTime: this.endTime
          }
        })
        .then((result) => {
          this.exception.exception4 = result.data.data;
        });
        this.$http
        .get('/dust/sitenamecode', {
          params: {
            exceptionType: '5',
            beginTime: this.beginTime,
            endTime: this.endTime
          }
        })
        .then((result) => {
          this.exception.exception5 = result.data.data;
        });
        this.$http
        .get('/dust/sitenamecode', {
          params: {
            exceptionType: '6',
            beginTime: this.beginTime,
            endTime: this.endTime
          }
        })
        .then((result) => {
          this.exception.exception6 = result.data.data;
        });
      /* å¼‚常异常数量 */
      this.$http
        .get('/dust/exceptionnum', {
          params: {
            exceptionType: '0',
            beginTime: this.beginTime,
            endTime: this.endTime
          }
        })
        .then((result) => {
          this.exception.exception0Num = result.data.data;
        });
      this.$http
        .get('/dust/exceptionnum', {
          params: {
            exceptionType: '1',
            beginTime: this.beginTime,
            endTime: this.endTime
          }
        })
        .then((result) => {
          this.exception.exception1Num = result.data.data;
        });
      this.$http
        .get('/dust/exceptionnum', {
          params: {
            exceptionType: '2',
            beginTime: this.beginTime,
            endTime: this.endTime
          }
        })
        .then((result) => {
          this.exception.exception2Num = result.data.data;
        });
      this.$http
        .get('/dust/exceptionnum', {
          params: {
            exceptionType: '3',
            beginTime: this.beginTime,
            endTime: this.endTime
          }
        })
        .then((result) => {
          this.exception.exception3Num = result.data.data;
        });
        this.$http
        .get('/dust/exceptionnum', {
          params: {
            exceptionType: '4',
            beginTime: this.beginTime,
            endTime: this.endTime
          }
        })
        .then((result) => {
          this.exception.exception4Num = result.data.data;
        });
        this.$http
        .get('/dust/exceptionnum', {
          params: {
            exceptionType: '5',
            beginTime: this.beginTime,
            endTime: this.endTime
          }
        })
        .then((result) => {
          this.exception.exception5Num = result.data.data;
        });
        this.$http
        .get('/dust/exceptionnum', {
          params: {
            exceptionType: '6',
            beginTime: this.beginTime,
            endTime: this.endTime
          }
        })
        .then((result) => {
          this.exception.exception6Num = result.data.data;
        });
    },
    /**
     * description:请求异常的店铺名字
     * @param:异常类型,开始时间,结束时间
     * @createTime:2023-08-18
     * @returns: å¼‚常的数据
     */
    // getSiteNameByExceptionType(exception, beginT, endT) {
    //   let param = {
    //     exceptionType: exception,
    //     beginTime: beginT,
    //     endTime: endT
    //   };
    //   this.$http.get('/dust/sitenamecode', { params: param }).then((res) => {
    //     return res.data.data;
    //   });
    //   return;
    // },
    /**
     * description:显示对话框,返回该异常时间段的所有数据
@@ -1193,9 +1075,10 @@
        this.dialog.historyData = response.data.data;
        this.dialog.exceptionTotal = response.data.data.length;
        // é€»è¾‘处理
        this.timeAndDataProcessed()
        this.timeAndDataProcessed();
      });
    },
    /**
     * description:条件查询异常的数据
     * @createTime:2023-08-18
@@ -1205,9 +1088,9 @@
        alert('时间跨度不能超过一个月');
        return;
      }
      this.loading.queryButton = true
      this.flag.originClick = 0
      this.loading.tableLoading = true;
      this.flag.originClick = 0;
      let params = {};
      params['page'] = this.currentPage;
      params['pageSize'] = this.pageSize;
@@ -1219,24 +1102,27 @@
      }
      params['beginTime'] = this.beginTime;
      params['endTime'] = this.endTime;
      this.loading.tableLoading = true;
      this.loading.queryButton = true;
      this.$http
        .get('/dust/exceptiondata', { params: params })
        .then((response) => {
          // ä¿å­˜è¿”回的
          // this.tableData = response.data.data.rows;
          this.displayData = response.data.data.rows;
          this.loading.queryButton = false
          this.loading.tableLoading = false;
          this.loading.queryButton = false;
          if (response.data.data.total == 0) {
            ElMessage('该时段无数据');
            this.isNoData = true;
            return;
          }
          this.total = response.data.data.total;
          this.loading.tableLoading = false;
          // ç§»é™¤ç©ºæ•°æ®çŠ¶æ€
          this.isNoData = false;
        });
      this.gethasCheckedNumByTime();
    },
    /**
@@ -1264,12 +1150,14 @@
          if (response.data.data.total == 0) {
            ElMessage('该时段无数据');
            this.loading.tableLoading = false;
            this.isNoData = true;
            return;
          }
          this.total = response.data.data.total;
          this.loading.tableLoading = false;
          this.total = response.data.data.total;
        });
      this.gethasCheckedNumByTime();
    },
    /**
@@ -1287,7 +1175,8 @@
      const h2 = this.$refs.h2.$el.offsetHeight;
      const h4 = this.$refs.h4.$el.offsetHeight;
      // å…¶ä¸­ä¸€ä¸ª40是盒子的总外边距
      this.tableHeight = `calc(100vh - ${h1}px - ${h2}px  - ${h4}px - 100px - var(--el-main-padding) * 2)`;
      this.tableHeight = `calc(100vh - ${h1}px - ${h2}px  - ${h4}px - 20px - 100px - var(--el-main-padding) * 2)`;
      // this.tableHeight = `calc(100vh - ${h1}px  - ${h4}px - 100px - var(--el-main-padding) * 2)`;
    },
    // é¡µå¤§å°æ”¹å˜æ—¶è§¦å‘
@@ -1309,7 +1198,6 @@
      console.log('当前页为:', val);
      // å°†å½“前页号给currentPage
      this.currentPage = val;
      // é¡µé¢å˜åŒ–时调用 æŸ¥è¯¢æ•°æ®å‡½æ•°
      if(this.flag.originClick==0){
@@ -1334,7 +1222,6 @@
</script>
<template>
  <el-row ref="h1">
    <el-col>
      <el-form :inline="true">
@@ -1344,41 +1231,72 @@
          </el-form-item>
          <el-form-item>
            <InputSearch
              :isNeedDefaultSite="0"
              isNeedDefaultSite="0"
              @submit-value="(n) => (form.name = n)"
              @submit-site-Nums="(n) => (siteTotal = n)"
            >
            </InputSearch>
          </el-form-item>
          <el-form-item>
            <TimeSelectWithShortCuts @submit-time="giveTime"></TimeSelectWithShortCuts>
            <TimeSelectWithShortCuts
              @submit-time="giveTime"
              timeType="month"
            ></TimeSelectWithShortCuts>
          </el-form-item>
          <el-form-item>
            <ExceptionType
              @submit-value="(n) => form.exceptionName = n"
              @submit-value="(n) => (form.exceptionName = n)"
            ></ExceptionType>
          </el-form-item>
        </div>
        <div class="head-container-search">
          <span class="head-describtion-text">
            é‡‘山区 {{ beginTime }} â€”— {{ endTime }} æ‰¬å°˜ç›‘测异常信息汇总</span
          >
          <el-form-item>
            <el-button type="warning" :loading="loading.queryButton" @click="handleSubmit">查询</el-button>
            <!-- <el-button type="warning" :loading="loading.queryButton" @click="handleSubmit"><el-icon
                style="margin-right: 6px;font-size: 1.2em;"><i-ep-Search /></el-icon>查询</el-button> -->
            <ButtonClick
              content="搜索"
              type="warning"
              :loading="loading.queryButton"
              @do-search="handleSubmit"
            ></ButtonClick>
          </el-form-item>
        </div>
      </el-form>
    </el-col>
  </el-row>
  <el-row class="head-describtion-text" ref="h2">
    <el-row>
      <span> é‡‘山区 {{ beginTime }} â€”— {{ endTime }} æ‰¬å°˜ç›‘测异常信息汇总</span>
    </el-row>
  </el-row>
  <el-row class="anasysis" ref="h2">
    <el-col :span="6">
      <el-card>
        <el-statistic title="全部审核数" :value="total" />
      </el-card>
    </el-col>
    <el-col :span="6">
      <el-card>
        <el-statistic title="待审核数" :value="unCheckedNUm"> </el-statistic>
      </el-card>
    </el-col>
    <el-col :span="6">
      <el-card>
        <el-statistic title="已审核数" :value="auditNumByTime" />
      </el-card>
    </el-col>
    <el-col :span="6">
      <el-card>
        <el-statistic title="审核比例" :value="checkedRate">
          <template #suffix> % </template>
        </el-statistic>
      </el-card>
    </el-col>
  </el-row>
  <el-row>
    <el-col v-show="!isNoData">
@@ -1386,11 +1304,14 @@
        ref="table"
        :data="displayData"
        :height="tableHeight"
        highlight-current-row="true"
        :highlight-current-row="true"
        :row-class-name="tableRowClassName"
        size="default"
        v-loading="loading.tableLoading"
        @selection-change="handleSelectionChange"
        border
      >
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column
          type="index"
          label="序号"
@@ -1448,17 +1369,60 @@
          align="center"
          show-overflow-tooltip
        />
        <el-table-column label="操作" align="center">
        <el-table-column label="操作" align="center" width="200" fixed="right">
          <template #default="{ row }">
            <el-button type="primary" @click="showDialog(row)">
              æŸ¥çœ‹è¯¦æƒ…
            </el-button>
            <el-button
              type="primary"
              class="table-button"
              @click="showDialog(row)"
              >查看详情</el-button
              v-if="row.auditStatus == 3"
              size="default"
              type="info"
              @click="openAuditDiag(row)"
              >已审核</el-button
            >
            <el-button
              type="success"
              size="default"
              plain
              v-else-if="row.auditStatus == 1 || row.auditStatus == 2"
              @click="openAuditDiag(row)"
              >审核</el-button
            >
            <el-button
              v-else
              size="default"
              type="danger"
              @click="openAuditDiag(row)"
              >审核</el-button
            >
            <!-- <span v-if="row.auditStatus == 3">已审核</span
              ><span v-else>审核</span> -->
          </template>
        </el-table-column>
      </el-table>
      <!-- <el-row ref="h2">
    <el-row> -->
      <div class="check-button">
        <el-button
          type="primary"
          size="small"
          :disabled="multipleSelection.length == 0"
          @click="quickReview"
          >批量审核</el-button
        >
        <el-button
          type="primary"
          size="small"
          :disabled="multipleSelection.length == 0"
          @click="clearSelected"
          >清除选中</el-button
        >
      </div>
      <!-- </el-row>
  </el-row> -->
      <el-pagination
        ref="h4"
@@ -1476,6 +1440,65 @@
  </el-row>
  <el-empty v-show="isNoData" :image-size="200" />
  <el-dialog v-model="auditDialog.visible" :show-close="false" draggable>
    <template #header>
      <!-- <div class="title-text">添加备注</div> -->
      <span class="title-text">{{ tableCurrentRowData.name }}</span
      ><span>站点异常数据审核</span>
    </template>
    <el-form label-position="top">
      <el-form-item label="审核人">
        <el-input v-model="auditDialog.checker"></el-input>
      </el-form-item>
      <el-form-item label="审核情况">
        <el-input
          v-model="auditDialog.checkerNotes"
          type="textarea"
          :autosize="true"
          placeholder="审核人员填写"
          :disabled="tableCurrentRowData.auditStatus == 1"
        />
      </el-form-item>
      <el-form-item label="企业反馈">
        <el-input
          v-model="auditDialog.enterpriseNotes"
          type="textarea"
          :autosize="true"
          placeholder="企业填写"
          :disabled="tableCurrentRowData.auditStatus == 2"
        />
      </el-form-item>
    </el-form>
    <el-card>
      <template #header>审核详情</template>
      <el-form>
        <el-form-item label="审核人">{{
          tableCurrentRowData.checker
        }}</el-form-item>
        <el-form-item label="审核情况">{{
          tableCurrentRowData.checkerContent
        }}</el-form-item>
        <el-form-item label="审核人员">{{
          tableCurrentRowData.enterpriseContent
        }}</el-form-item>
      </el-form>
    </el-card>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="close">取消</el-button>
        <el-button
          type="primary"
          :loading="loading.submitAudit"
          :disabled="tableCurrentRowData.auditStatus == 3"
          @click="submitAudit"
        >
          æäº¤
        </el-button>
      </span>
    </template>
  </el-dialog>
  <el-dialog v-model="dialogTableVisible" draggable align-center height="300px">
    <!-- å¤´ -->
@@ -1495,17 +1518,22 @@
          <span v-else-if="tableCurrentRowData.exceptionType == '1'"
            >数据超低</span
          >
          <span v-else-if="tableCurrentRowData.exceptionType == '2'">超标</span>
            <span v-else-if="tableCurrentRowData.exceptionType == '2'"
              >超标</span
            >
          <span v-else-if="tableCurrentRowData.exceptionType == '3'"
            >数据长时间无波动</span
          >
          <span v-else-if="tableCurrentRowData.exceptionType == '4'"
            >量级突变异常</span
          > <span v-else-if="tableCurrentRowData.exceptionType == '5'"
            >
            <span v-else-if="tableCurrentRowData.exceptionType == '5'"
            >临近超标异常</span
          > <span v-else-if="tableCurrentRowData.exceptionType == '6'"
            >
            <span v-else-if="tableCurrentRowData.exceptionType == '6'"
            >单日超标次数临界异常</span
          > <span v-else-if="tableCurrentRowData.exceptionType == '7'"
            >
            <span v-else-if="tableCurrentRowData.exceptionType == '7'"
            >滑动平均值异常</span
          >
        </div>
@@ -1536,14 +1564,13 @@
      </div>
    </template>
    <!-- :option="dialog.option" -->
    <!-- å›¾å½¢ -->
    <DustLineChart
      :option="dialog.option"
      :is-open-dialog="dialogTableVisible"
      v-loading="loading.lineChart"
    ></DustLineChart>
    >
    </DustLineChart>
    <!-- è¡¨æ ¼ -->
    <div>
@@ -1605,11 +1632,7 @@
          >异常数据:</span
        >
        <span class="table-line-num">{{ dialog.exceptionTotal }}条</span>
        <span
          v-show="
            tableCurrentRowData.exceptionType === '0'
          "
        >
        <span v-show="tableCurrentRowData.exceptionType === '0'">
          (逻辑计算)</span
        >
      </el-tag>
@@ -1619,14 +1642,14 @@
<style lang="scss" scoped>
.el-row {
  margin-left: 10px;
  margin-left: 20px;
}
/* æ¡ä»¶æŸ¥è¯¢æ¨¡å—的样式 */
.head-container-search {
  // display: flex;
  // justify-content: flex-end;
  float: right;
  display: flex;
  justify-content: space-between;
  // float: right;
}
.head-describtion-text {
@@ -1635,110 +1658,73 @@
  font-size: 14px;
  color: gray;
}
/* æ¡ä»¶æŸ¥è¯¢æ¨¡å—结束 */
/* å¼‚常分析模块的样式 */
.card-text1 {
  // é»‘体的异常名字部分
  margin: 10px;
/*分析 */
.anasysis {
  margin-bottom: 20px;
}
.card-text1 + div {
  // é»‘体的异常名字下面的
  margin: 12px;
}
.card-exception-buttom {
  // å¼‚常站点文本按钮区域
  padding: 11px;
}
.card-header {
  margin-left: 5px;
  font-size: 18px;
:deep(.el-statistic__head) {
  font-weight: bold;
}
.card-content-unnormal {
  min-height: 200px;
  border: 2px solid #FFCF8B;
  border-radius: 20px;
}
.card-content-normal {
  min-height: 200px;
  border: 2px solid red;
  border-radius: 20px;
}
.card-header-image {
}
.card-header-text {
  font-size: 16px;
  font-weight: bold;
  margin-top: 4px;
  margin-left: 4px;
}
.card-content-text {
  white-space: nowrap;
}
.card-exceptionname-text1 {
  // å¼‚常站点占比
  font-size: 14px;
  white-space: nowrap;
}
.card-exceptionname-text2 {
  // å¼‚常数占比的外边距
  // margin-left: 50px;
  font-size: 14px;
  white-space: nowrap;
}
.text-blank {
  // é€—号
  margin-right: 10px;
  color: #000000;
}
.card-row {
  margin-bottom: 10px;
}
/* å¼‚常分析模块结束 */
/* åˆ†æžç»“束 */
/* è¡¨æ ¼æ¨¡å—的样式 */
:global(.el-table .black-row) {
  color: black;
}
:global(.el-table .complete--gray-row) {
  color: #86909c;
}
:global(.el-table .deep-gray-row) {
  color: #7f9fcf;
}
//对话框标题
.el-form-item__labe {
  font-weight: bold;
}
.title-text {
  font-weight: bold;
  margin-right: 20px;
}
.check-button {
  // justify-content: flex-end;
  float: right;
  margin-top: 10px;
  margin-right: 20px;
}
/* è¡¨æ ¼æ¨¡å—结束 */
/* æŸ¥çœ‹è¯¦æƒ…对话框模块的样式 */
:deep(.el-dialog) {
  // å¯¹è¯æ¡†é«˜åº¦
}
.diag-head {
  // å¯¹è¯æ¡†å¤´éƒ¨åŒºåŸŸ
  min-height: 200px;
  // border: 1px solid #fdc2db;
}
.diag-head-text1 {
  // å¯¹è¯æ¡†å¤´éƒ¨çš„属性字段加粗
  font-weight: bold;
}
.diag-head-text span:nth-child(2) {
  // å¯¹è¯æ¡†å¤´éƒ¨â€˜å¼‚常类型’属性
  // margin-left: 150px;
}
.diag-head-text > div {
  // å¯¹è¯æ¡†å¼‚常时间段
  margin-top: 15px;
}
.diag-head-text {
  margin: 10px;
  padding: 10px;
  background: linear-gradient(90deg, #00c9ff 0%, #92fe9d 100%);
  border: 2px solid #7bc0fc;
}
.chart-jump-button {
  // â€˜ä¸Šä¸€æ¡â€™ï¼Œâ€˜ä¸‹ä¸€æ¡â€™ æŒ‰é’®
  // border: 1px solid #fdc2db;
  min-height: 30px;
  width: 200px;
  float: right;
@@ -1751,11 +1737,12 @@
  margin-bottom: 20px;
  min-width: 600px;
}
.mx-1 {
  position: absolute;
  left: 10px;
  bottom: 10px;
}
/* æŸ¥çœ‹è¯¦æƒ…对话框模块结束 */
</style>
src/views/exception/components/DustExceptionText.vue
src/views/exception/components/DustLineChart.vue
src/views/line_graph/DataRiskModel.vue
@@ -1,8 +1,8 @@
<!-- æ—¥å‡å€¼ -->
<script>
import TimeSelectWithShortCuts from '../../sfc/TimeSelectWithShortCuts.vue';
import InputSearch from '../../sfc/InputSearch.vue';
import AreaAndmonitorType from '../../sfc/AreaAndmonitorType.vue';
import TimeSelectWithShortCuts from '@/sfc/TimeSelectWithShortCuts.vue';
import InputSearch from '@/sfc/InputSearch.vue';
import AreaAndmonitorType from '@/sfc/AreaAndmonitorType.vue';
import DustRadarChart from './components/DustRadarChart.vue';
import exceptionApi from '@/api/exceptionApi.js';
@@ -361,7 +361,7 @@
          </el-form-item>
          <el-form-item>
            <InputSearch
              :isNeedDefaultSite="1"
              isNeedDefaultSite="1"
              @submit-value="(n) => (form.name = n)"
            ></InputSearch>
          </el-form-item>
@@ -388,7 +388,10 @@
              shadow="never"
            >
              <DustRadarChart :name="['数据有效率','典型异常复现率','异常类型聚集度','数据超标率','数据在线率']" :yData="[bill.valid,bill.exceptionRecurrence,bill.exceptionTypeAggregation,bill.exceeding,bill.online]" ></DustRadarChart>
            æƒé‡ï¼š{{ ((bill.online*0.1+bill.valid*0.2+bill.exceeding*0.2+bill.exceptionTypeAggregation*0.2+bill.exceptionRecurrence*0.3)*0.01).toFixed(2) }}
            </el-card>
          </el-col>
          <el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="4">
@@ -420,14 +423,7 @@
                  {{ bill.exceptionRecurrence*100  }}%
                </el-form-item>
              </el-form>
                <!-- <div class="date-text">最大值:{{ bill.max }} mg/m³</div> -->
                <!-- <div>最小值:{{ bill.min }} mg/m³</div>
                <div>均值:{{ bill.avg }} mg/m³</div>
                <div>数据有效率:{{ bill.online }}%</div>
                <div>数据在线率:{{ bill.valid }}%</div>
                <div>数据超标率:{{ bill.exceeding }}%</div>
                <div>异常类型聚集度:{{ bill.exceptionTypeAggregation*100 }}%</div>
                <div>典型异常复现率:{{ bill.exceptionRecurrence*100 }}%</div> -->
            
            </el-card>
          </el-col>
src/views/line_graph/DataRiskRank.vue
@@ -1,14 +1,12 @@
<script>
import TimeSelectWithShortCuts from '../../sfc/TimeSelectWithShortCuts.vue';
// import InputSearch from '../../sfc/InputSearch.vue';
import AreaAndmonitorType from '../../sfc/AreaAndmonitorType.vue';
import TimeSelectWithShortCuts from '@/sfc/TimeSelectWithShortCuts.vue';
import AreaAndmonitorType from '@/sfc/AreaAndmonitorType.vue';
import {useCommonFunction} from '../../utils/common.js';
import requetsApi from '@/api/exportExcel/requetsApi.js'
import dayjs from 'dayjs';
export default {
  components: {
    TimeSelectWithShortCuts,
    // InputSearch
    AreaAndmonitorType
  },
  data() {
@@ -26,10 +24,6 @@
      // end: '2023-05-15', //结束时间
      form: {
        // ç«™ç‚¹åç§°
        name: '',
        // è®¾å¤‡ç¼–号
        number: '',
        // å¼€å§‹æ—¶é—´
        beginTime: '',
        // ç»“束时间
@@ -43,14 +37,6 @@
    return {cmpp,exportToExcel} 
  },
  //   watch:{
  //     pageSize(){
  //         this.handleSizeChange()
  //     },
  //     currentPage(){
  //         this.handleCurrentChange()
  //     },
  //   },
  mounted() {
    this.form.name = '';
@@ -174,13 +160,11 @@
  <div class="search-container">
    <el-container>
      <el-main>
        <el-form :inline="true" :model="form" class="demo-form-inline">
        <el-form :inline="true" :model="form" >
          <el-form-item>
            <AreaAndmonitorType></AreaAndmonitorType>
          </el-form-item>
          <!-- <el-form-item>
            <InputSearch  @submit-value="(n) => (form.name = n)"></InputSearch>
          </el-form-item> -->
          <el-form-item>
            <TimeSelectWithShortCuts
              @submit-time="giveTime"
@@ -194,7 +178,6 @@
        <el-card>
          <el-empty v-show="isNoData" :image-size="200" />
          <!-- <LineChart :chartData="option"> </LineChart> -->
        </el-card>
        <el-table
src/views/line_graph/SiteComprehensiveRskRanking.vue
ÎļþÃû´Ó src/views/origin_data/BusinessReport.vue ÐÞ¸Ä
@@ -16,7 +16,7 @@
<template>
  <div>
    ä¸šåŠ¡æŠ¥è¡¨
站点综合风险排名
  </div>
</template>
src/views/line_graph/components/LineChart.vue
@@ -53,11 +53,11 @@
    },
  },
  beforeUnmount() {
    if (this.chart) {
      this.chart.dispose();
    }
  },
  // beforeUnmount() {
  //   if (this.chart) {
  //     this.chart.dispose();
  //   }
  // },
  methods: {
    intiChart() {
      // åˆ›å»ºecharts实例
src/views/login/LoginSystem.vue
@@ -20,6 +20,7 @@
          placeholder="请输入密码"
          type="password"
          size="large"
          show-password
        ></el-input>
      </el-form-item>
src/views/origin_data/HistoryData.vue
ÎļþÒÑɾ³ý
src/views/pass_login/LoginAndGetData.vue
@@ -0,0 +1,25 @@
<script>
  export default {
    data() {
      return{
      }
    },
    mounted() {
    },
    methods: {
     }
}
</script>
<template>
  <div>
    æ¨¡æ‹Ÿç™»å½•
  </div>
</template>
<style  scoped>
</style>
src/views/setting/SetConfiguration.vue
@@ -1,34 +1,76 @@
<script>
// import DustRadarChart from '../../sfc/DustRadarChart.vue';
// import TimeSelectWithShortCuts from '../../sfc/TimeSelectWithShortCuts.vue'
import dayjs from 'dayjs';
import {useCounterStore} from '@/stores/counter';
  export default {
    components :{
    // DustRadarChart,
    // TimeSelectWithShortCuts
  },
    data() {
      return{
      }
    },
   setup(){
    const store = useCounterStore()
    const unsubscribe = store.$onAction(
  ({
    name, // action çš„名字
    store, // store å®žä¾‹
    args, // è°ƒç”¨è¿™ä¸ª action çš„参数
    after, // åœ¨è¿™ä¸ª action æ‰§è¡Œå®Œæ¯•之后,执行这个函数
    onError, // åœ¨è¿™ä¸ª action æŠ›å‡ºå¼‚常的时候,执行这个函数
  }) => {
    // è®°å½•开始的时间变量
    const startTime = Date.now()
    // è¿™å°†åœ¨ `store` ä¸Šçš„æ“ä½œæ‰§è¡Œä¹‹å‰è§¦å‘
    console.log(`Start "${name}" with params [${args.join(', ')}].`)
    // å¦‚æžœ action æˆåŠŸå¹¶ä¸”å®Œå…¨è¿è¡ŒåŽï¼Œafter å°†è§¦å‘。
    // å®ƒå°†ç­‰å¾…任何返回的 promise
    after((result) => {
      console.log(
        `Finished "${name}" after ${
          Date.now() - startTime
        }ms.\nResult: ${result}.`
      )
    })
    // å¦‚æžœ action æŠ›å‡ºæˆ–返回 Promise.reject ï¼ŒonError å°†è§¦å‘
    onError((error) => {
      console.warn(
        `Failed "${name}" after ${Date.now() - startTime}ms.\nError: ${error}.`
      )
    })
  }
)
    return{
      store,unsubscribe
    }
   },
   computed:{
    a(){
      return this.store.doubleCount*2
    },
   },
    mounted() {
    },
    methods: {
    doThing(){
      this.store.increment(5)
      this.store.doubleCount
    }
     }
}
</script>
<template>
  <div>
    æ•°æ®æŽ¥å…¥é…ç½®
    <el-button type="primary" @click="doThing">点击{{ store.doubleCount }}</el-button>
  </div>
  <div>{{ a }}</div>
  <div>{{ store.secret }}</div>
  <div>{{ store.vue }}</div>
  <div>{{ store.天 }}</div>
</template>
<style  scoped>
</style>