013ed9283200da41902835f9fd679df13299d436..c2f95b0b9090a2394b5b068582b932a5e57b86aa
2023-09-05 zmc
雷达图 新增综合风险排名 数据接入配置
c2f95b 对比 | 目录
2023-09-04 zmc
扬尘vue
34257f 对比 | 目录
已修改22个文件
已删除10个文件
已添加11个文件
已重命名4个文件
5706 ■■■■■ 文件已修改
.eslintrc-auto-import.json 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
auto-imports.d.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components.d.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/audit/submitApi.js 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/data_access_setting/settingApi.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/exceptionApi.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/exportExcel/requetsApi.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/layout/AppAside.vue 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/layout/AppHeader.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.ts 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.ts 131 ●●●●● 补丁 | 查看 | 原始文档 | 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 175 ●●●●● 补丁 | 查看 | 原始文档 | 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 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/exception_common_function/index.js 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/risk_estimate_common_function/index.js 149 ●●●●● 补丁 | 查看 | 原始文档 | 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 291 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/exception/SiteAuditAssistance.vue 1354 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/exception/components/DustExceptionText.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/views/exception/components/DustLineChart.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/views/line_graph/DataRiskModel.vue 289 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/line_graph/DataRiskRank.vue 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/line_graph/SiteComprehensiveRskRanking.vue 270 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/line_graph/components/DustRadarChart.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/line_graph/components/LineChart.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/LoginSystem.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/origin_data/BusinessReport.vue 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/origin_data/HistoryData.vue 385 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pass_login/LoginAndGetData.vue 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/setting/SetConfiguration.vue 61 ●●●● 补丁 | 查看 | 原始文档 | 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']
@@ -37,11 +39,14 @@
    ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
    ElOption: typeof import('element-plus/es')['ElOption']
    ElPagination: typeof import('element-plus/es')['ElPagination']
    ElRadio: typeof import('element-plus/es')['ElRadio']
    ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
    ElRow: typeof import('element-plus/es')['ElRow']
    ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
    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 +62,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']
package-lock.json
@@ -15,6 +15,7 @@
        "dayjs": "^1.11.9",
        "echarts": "^5.4.3",
        "element-plus": "^2.3.6",
        "js-cookie": "^3.0.1",
        "pinia": "^2.1.3",
        "sass": "^1.63.4",
        "vue": "^3.3.4",
@@ -4148,6 +4149,14 @@
      "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz",
      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
      "dev": true
    },
    "node_modules/js-cookie": {
      "version": "3.0.1",
      "resolved": "https://registry.npmmirror.com/js-cookie/-/js-cookie-3.0.1.tgz",
      "integrity": "sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw==",
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/js-stringify": {
      "version": "1.0.2",
@@ -9961,6 +9970,11 @@
      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
      "dev": true
    },
    "js-cookie": {
      "version": "3.0.1",
      "resolved": "https://registry.npmmirror.com/js-cookie/-/js-cookie-3.0.1.tgz",
      "integrity": "sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw=="
    },
    "js-stringify": {
      "version": "1.0.2",
      "resolved": "https://registry.npmmirror.com/js-stringify/-/js-stringify-1.0.2.tgz",
package.json
@@ -19,6 +19,7 @@
    "dayjs": "^1.11.9",
    "echarts": "^5.4.3",
    "element-plus": "^2.3.6",
    "js-cookie": "^3.0.1",
    "pinia": "^2.1.3",
    "sass": "^1.63.4",
    "vue": "^3.3.4",
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/data_access_setting/settingApi.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
import {$http} from '@/api/index.js';
export default {
    /**
     * æ ¹æ®ç«™ç‚¹ï¼Œæ—¶é—´æ®µæŸ¥è¯¢åŽ†å²è¡¨ä¸­æ‰€æœ‰æ•°æ®
     * @param:
     * @returns:
     */
    submitSetting(argsObj){
        return $http.post('dust/setting',argsObj);
    }
}
src/api/exceptionApi.js
@@ -36,5 +36,12 @@
      _params.exceptionType = exceptionType;
    }
    return $http.get('/dust/exceptiondata1', { params: _params });
  },
  getSitesNum(){
    return $http.get('/dust/sitename');
  }
};
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
@@ -1,33 +1,22 @@
<script>
import { isCollapse } from './isCollapse';
import { selectedName } from './selectName';
export default {
  data() {
    return {
      menuHeight: '600px',
      isCollapseAside: isCollapse,
      selected: selectedName,
      optionClick: [
        ' æ•°æ®é£Žé™©æ¨¡åž‹',
        '数据风险排名',
        '飞行巡检',
        '站点审核辅助',
        '历史数据管理',
        '数据接入管理',
        '业务报表',
        '数据接入配置',
      ]
    };
  },
  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 +30,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">
@@ -67,14 +49,19 @@
            <span class="parent-title">风险评估</span>
          </template>
          <el-menu-item index="avgDay" @click="selected = optionClick[0]">
          <el-menu-item index="avgDay" >
            <el-icon><i-ep-Stopwatch /></el-icon>
            æ•°æ®é£Žé™©æ¨¡åž‹
          </el-menu-item>
          <el-menu-item index="analysis" @click="selected = optionClick[1]">
          <el-menu-item index="analysis" >
            <el-icon><i-ep-Stopwatch /></el-icon>
            æ•°æ®é£Žé™©æŽ’名
            æ•°æ®æŽ’名清单
          </el-menu-item><el-menu-item index="riskrank" >
            <el-icon><i-ep-Stopwatch /></el-icon>
            ç»¼åˆé£Žé™©æŽ’名
          </el-menu-item>
        </el-sub-menu>
@@ -83,12 +70,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" >
            <el-icon><i-ep-Bell /></el-icon>
          é£žè¡Œå·¡æ£€
          </el-menu-item>
          <el-menu-item index="testdata" @click="selected = optionClick[3]">
          <el-menu-item index="testData">
            <el-icon><i-ep-Bell /></el-icon>
          ç«™ç‚¹å®¡æ ¸è¾…助
          </el-menu-item>
@@ -102,32 +89,33 @@
          </template>
 
         
            <el-menu-item index="hdata" @click="selected = optionClick[4]">
            <el-menu-item index="hdata" >
            <el-icon><i-ep-Histogram /></el-icon>
          åŽ†å²æ•°æ®ç®¡ç†
          </el-menu-item>
          <!-- <el-menu-item index="management" @click="selected = optionClick[5]">
          <!-- <el-menu-item index="management" >
            <el-icon><i-ep-Histogram /></el-icon>
          æ•°æ®æŽ¥å…¥ç®¡ç†
          </el-menu-item>
          <el-menu-item index="report" @click="selected = optionClick[6]">
          <el-menu-item index="report" >
            <el-icon><i-ep-Histogram /></el-icon>
          ä¸šåŠ¡æŠ¥è¡¨
          </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>
              </template>
              <el-menu-item index="setting" @click="selected = optionClick[7]">
              <el-menu-item index="setting" >
                <el-icon><i-ep-Histogram /></el-icon>
                   æ•°æ®æŽ¥å…¥é…ç½®
              </el-menu-item>
          </el-sub-menu> -->
          </el-sub-menu>
    </el-scrollbar>
      </el-menu>
@@ -137,8 +125,6 @@
<style lang="scss" scoped>
.el-aside {
  background-color: #2876aa;
  height: 100vh;
  width: auto;
}
@@ -148,16 +134,17 @@
  width: 220px;
  border-right: none;
  &.el-menu--collapse {
    //侧边栏折叠时的样式
    width: 65px;
    & h1 {
      //折叠时隐藏h1文字
      display: none;
    }
    & span {
      display: none;
    }
    & hr {
      display: none;
    }
  }
@@ -171,10 +158,11 @@
  text-decoration: none;
  color: black;
  margin-left: 20px;
  img {
    width: 32px;
    height: 32px;
  }
  margin-right: 20px;
  // img {
  //   width: 32px;
  //   height: 32px;
  // }
}
@@ -188,10 +176,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
@@ -1,8 +1,6 @@
// import './assets/main.css'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
// import { createPinia } from 'pinia'
import Cookie from 'js-cookie'
import App from './App.vue'
import router from './router'
@@ -14,11 +12,34 @@
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(() => ({'天':'雨天'}))
router.beforeEach((to,from,next)=>{
  const token = Cookie.get('token')
  if(!token && to.name!='login'){
    next({name:'login'})
  }
  // token存在,但用户切换的是登录页面时,返回默认主界面
  else if(token && to.name =='login'){
    next({name:'edata'})
  }else{
    next()
  }
})
// 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,77 +7,92 @@
    {
      path: '/layout',
      name: 'home',
      meta: { title: '首页' },
      component: () => import('@/components/layout/AppLayout.vue'),
      children: [
        // æ•°æ®åˆ†é™©æ¨¡åž‹
        {
          path:"/avgDay",
          name:'avgDay',
          component: () => import('@/views/line_graph/DataRiskModel.vue')
         },
            // æ•°æ®åˆ†é™©æ¨¡åž‹
            {
              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: "/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:"/analysis",
          name:'analysis',
          component: () => import('@/views/line_graph/DataRiskRank.vue')
         },
        //  åŽ†å²æ•°æ®ç®¡ç†
         {
          path:"/hdata",
          name:'hdata',
          component: () => import('@/views/origin_data/HistoryData.vue')
         },
        // é£žè¡Œå·¡æ£€
         {
          path:"/edata",
          name:'edata',
          component: () => import('@/views/exception/FlightInspection.vue')
         },
        //  ç«™ç‚¹å®¡æ ¸è¾…助
         {
          path:"/testdata",
          name:'testdata',
          component: () => import('@/views/exception/SiteAuditAssistance.vue')
         },
            //  ç«™ç‚¹å®¡æ ¸è¾…助
            {
              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',
              meta: { title: '数据接入管理' },
              component: () => import('@/views/data_management/DataAccessManagement.vue')
            },
         //  æ•°æ®æŽ¥å…¥ç®¡ç†
         {
          path:"/management",
          name:'management',
          component: () => import('@/views/origin_data/DataAccessManagement.vue')
         },
          //  ä¸šåŠ¡æŠ¥è¡¨
          {
            path:"/report",
            name:'report',
            component: () => import('@/views/origin_data/BusinessReport.vue')
           },
            //  ä¸šåŠ¡æŠ¥è¡¨
            {
              path: "/report",
              name: 'report',
              meta: { title: '业务报表' },
              component: () => import('@/views/data_management/BusinessReport.vue')
            },
            //  æ•°æ®æŽ¥å…¥é…ç½®
            {
              path: "/setting",
              name: 'setting',
              meta: { title: '数据接入配置' },
              component: () => import('@/views/setting/SetConfiguration.vue')
            },
      ],
    },
    // ç™»é™†é¡µé¢
    {
      path:"/login",
      name:'fst',
      path: "/login",
      name: 'login',
      component: () => import('@/views/login/LoginSystem.vue')
     },
     {
    },
    {
      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,83 +13,110 @@
  ***
-->
<script>
import dayjs from 'dayjs'
  export default {
    emits: ['submitTime'],
    data() {
      return{
        //保存开始和结束时间
      // éšä¾¿è®¾ç½®åˆå§‹å€¼ ï¼Œmounted时再设正确的,目的是改变时间了触发change
        time: ['2023-06-01 12:00:00', '2023-06-20 16:00:00'],
        shortcuts:[],
      }
    },
    mounted() {
        this.initShortCuts()
        this.initOneWeekAgoTime()
        this.$emit('submitTime', this.time);
    },
    methods: {
        initShortCuts(){
            this.shortcuts = [
            {
    text: '前一日',
    value: () => {
      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]
    },
  },
  {
    text: '前一月',
    value: () => {
      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');
    this.time[1] = dayjs().format('YYYY-MM-DD HH:mm:ss');
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: []
    };
  },
  mounted() {
    this.initShortCuts();
    this.initOneWeekAgoTime();
    this.$emit('submitTime', this.time);
  },
  methods: {
    initShortCuts() {
      this.shortcuts = [
        {
          text: '前一日',
          value: () => {
            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];
          }
        },
        {
          text: '前一月',
          value: () => {
            const end = new Date();
            const start = new Date();
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
            return [start, end];
          }
        }
      ];
    },
    initOneWeekAgoTime() {
      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>
        <el-date-picker
          v-model="time"
          type="datetimerange"
          :shortcuts="shortcuts"
          range-separator="~"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          value-format="YYYY-MM-DD HH:mm:ss"
          @change="$emit('submitTime', time)"
          class="pick-date"
        />
  <div class="block">
    <span class="demonstration">起止时间:</span>
    <div class="pick-date">
    <el-date-picker
      v-model="time"
      type="datetimerange"
      :shortcuts="shortcuts"
      range-separator="~"
      start-placeholder="开始时间"
      end-placeholder="结束时间"
      value-format="YYYY-MM-DD HH:mm:ss"
      @change="$emit('submitTime', time)"
    />
  </div>
  </div>
</template>
<style  scoped>
<style scoped>
.block {
  display: flex;
  width: 570px;
@@ -101,7 +128,7 @@
  font-size: 16px;
}
.pick-date {
  margin-top: 5px;
}
</style>
/* .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
        // å°†æ—¥æœŸå­—符串转为日期对象
@@ -48,8 +49,8 @@
        return false;
      }
         /**
     * description:百分号比较大小
      /**
     * ç™¾åˆ†å·æ¯”较大小
     * @param: a是否大于b
     * @returns:大于,则返回true。否则返回false
     */
@@ -57,7 +58,7 @@
        return Number(a.replace('%', '')) >= Number(b.replace('%', ''));
      }
          /**
      /**
     *导出为excel
     * @param: è¡¨æ ¼æ•°æ®ï¼Œå¾…导出的表格列,excel列,excel文件名
     * @returns
@@ -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/risk_estimate_common_function/index.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,149 @@
import dayjs from 'dayjs';
export default {
  /**
   * è®¡ç®—日期相差几天
   * @param:
   * @createTime:开始时间,结束时间
   * @returns:
   */
  getDaysDifference(startDate, endDate) {
    return dayjs(endDate).diff(startDate, 'day') + 1;
  },
  /**
   * ä»Žåˆ†æžæ•°æ®æ•°ç»„中计算最小和大值 ,平均值,    åœ¨çº¿çŽ‡ï¼Œæœ‰æ•ˆçŽ‡ï¼Œè¶…æ ‡çŽ‡ï¼ˆåŽä¸‰ä¸ªå€¼ä¸º0~100取值)
   * @param:分析表中的数据
   * @returns:
   */
  calBillData(arr, beginTime, endTime) {
    let min = 65536;
    let max = -1;
    let avg = 0;
    let online = 0;
    let valid = 0;
    let exceeding = 0;
    let sumAvg = 0;
    let sumOnline = 0;
    let sumValid = 0;
    let sumExceeding = 0;
    // è®¡ç®—选择的时间的相差的天数
    let begin = dayjs(beginTime).format('YYYY-MM-DD');
    let end = dayjs(endTime).format('YYYY-MM-DD');
    let dayDiff = this.getDaysDifference(begin, end);
    console.log('日期间隔', dayDiff);
    let obj = {};
    // è®¡ç®—最小和大值
    arr.forEach((item) => {
      if (item.min < min) {
        min = item.min;
      }
      if (item.max > max) {
        max = item.max;
      }
      // è®¡ç®—平均值,在线率,有效率,超标率
      sumAvg = sumAvg + item.dayAvg;
      sumOnline = sumOnline + Number(item.dayOnline.slice(0, -1));
      sumValid = sumValid + Number(item.dayValid.slice(0, -1));
      sumExceeding = sumExceeding + Number(item.dayExceeding.slice(0, -1));
    });
    // è®¡ç®—均值
    avg = sumAvg / dayDiff;
    // console.log('sumavg:',sumAvg,dayDiff);
    online = sumOnline / dayDiff;
    valid = sumValid / dayDiff;
    exceeding = sumExceeding / dayDiff;
    obj['min'] = min.toFixed(3);
    obj['max'] = max.toFixed(3);
    obj['avg'] = avg.toFixed(2);
    obj['online'] = online.toFixed(2);
    obj['valid'] = valid.toFixed(2);
    obj['exceeding'] = exceeding.toFixed(2);
    return obj;
  },
  /**
   * è®¡ç®—异常类型聚集度 å¼‚常复现率
   * @param: å¼‚常数据数组
   * @returns:
   */
  calRecur(exceptionArr) {
    // å…¸åž‹å¼‚常复现率
    let exceptionTyprRecurRate = 0;
    // é‡çº§çªå˜
    let mutationCount = 0;
    // è¶…标临近
    let exceedingNearCount = 0;
    // è¶…标次数临界
    let exceedindCriticalDegree = 0;
    // ä¿å­˜å‡ºçŽ°çš„ä¸åŒå¼‚å¸¸ç±»åž‹
    let exception = [];
    // å¼‚常类型聚集度
    let exceptionTypeAggregation = 0;
    exceptionArr.forEach((item) => {
      // å¼‚常复现率
      if (item.exceptionType == 4) {
        mutationCount++;
      } else if (item.exceptionType == 5) {
        exceedingNearCount++;
      } else if (item.exceptionType == 6) {
        exceedindCriticalDegree++;
      }
      // å¼‚常类型聚集度
      if (exception.length == 0) {
        exception.push(item.exceptionType);
      }
      // ä¿å­˜æ–°çš„异常类型
      else if (exception.indexOf(item.exceptionType) == -1) {
        exception.push(item.exceptionType);
      }
    });
    let sum = 0;
    // æ¬¡æ•°å‡1,该异常出现2次,算复现1次。出现3次,算复现2次...
    if (mutationCount > 1) {
      sum = sum + mutationCount - 1;
    }
    if (exceedingNearCount > 1) {
      sum = sum + exceedindCriticalDegree - 1;
    }
    if (exceedindCriticalDegree > 1) {
      sum = sum + exceedindCriticalDegree - 1;
    }
    // console.log('sum:', sum);
    // console.log('exception:', exception);
    // console.log(
    //   '其他',
    //   mutationCount,
    //   exceedindCriticalDegree,
    //   exceedindCriticalDegree
    // );
    switch (sum) {
      case 0:
        exceptionTyprRecurRate = sum / 3;
        break;
      case 1:
        exceptionTyprRecurRate = sum / 3;
        break;
      case 2:
      case sum >= 3:
        exceptionTyprRecurRate = 1;
        break;
      default:
        return 'error';
    }
    exceptionTypeAggregation = exception.length / 8;
    let obj = {};
    obj['exceptionRecurrence'] = exceptionTyprRecurRate;
    obj['exceptionTypeAggregation'] = exceptionTypeAggregation;
    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,25 +1,27 @@
<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 exceptionApi from '@/api/exceptionApi.js';
import dayjs from 'dayjs';
export default {
  components: {
    ExceptionType,
    InputSearch,
    // InputSearch,
    TimeSelectWithShortCuts,
    DustExceptionText,
    DustLineChart,
    ButtonClick,
    AreaAndmonitorType
  },
  data() {
@@ -40,15 +42,17 @@
      displayData: [],
      // è¡¨æ ¼é«˜åº¦
      tableHeight: 400,
      // è¡¨æ ¼æ•°æ®
      // è¡¨æ ¼æ˜¾ç¤º
      isTableShow:false,
      // å½“前页
      currentPage: 1,
      // æ¯é¡µæ¡æ•°
      pageSize: 20,
      // è¡¨æ ¼çš„æ€»è®°å½•æ•°
      total: 0,
  
      // è¡¨æ ¼æŸ¥è¯¢æ— æ•°æ®æ—¶
      isNoData: false,
      // isNoData: false,
      // å¯¹è¯æ¡†æ˜¾ç¤º
      dialogTableVisible: false,
      // ä¿å­˜å¼‚常对应的店铺名称和设备编号
@@ -84,8 +88,6 @@
      // ç«™ç‚¹æ€»æ•°é‡
      siteTotal: 0,
      // å¼‚常的站点总数量
      // exceptionSiteNum:0,
      // é€‰ä¸­è¡¨æ ¼å½“前行的数据
      tableCurrentRowData: null,
@@ -127,8 +129,9 @@
        banTouch:0,
        // 0代表分页,1代表不分页
        originClick:0
      }
      },
      // æ¡ä»¶æŸ¥è¯¢å¯¹è¯æ¡†
      conditionDialogVisible:false
    };
  },
  setup() {
@@ -169,7 +172,6 @@
    },
    // å½“选择的时间发生变化时,异常分析部分的异常店铺数量同步变化
        beginTime() {
          this.getShopNames();
      },
@@ -181,31 +183,21 @@
    }
  },
  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);
    this.getSiteNume()
  },
  methods: {
   // æ”¾å›žç«™ç‚¹æ€»æ•°é‡
    getSiteNume(){
      exceptionApi.getSitesNum().then(res => {
      this.siteTotal = res.data.data.length
    })
    },
    // getExceptionSiteNum(){
    //   this.$http.get('/dust/exceptionsitenum').then(result => {
    //     this.exceptionSiteNum = result.data.data.length
    //   })
    // },
    /**
     * description:点击异常站点名字时 è¿”回的数据
     * @param: 
@@ -226,35 +218,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 +244,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 +277,7 @@
        let timeAndValue = {};
        // ä»Žæ·»åŠ äº†é¦–ä½åŒºé—´çš„å¼€å§‹å’Œç»“æŸæ—¶é—´è¿›è¡ŒéåŽ† ä¿è¯æ—¶é—´ä»¥10分钟为间隔
        timeAndValue = this.keepContinuousByEachFiftyMinutes(
        timeAndValue = index.keepContinuousByEachFiftyMinutes(
            allTime[0],
            allTime[3],
            this.dialog.allExceptionTimeData
@@ -384,59 +299,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 +754,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 +787,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 +823,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 })
@@ -1243,15 +1106,18 @@
          this.displayData = response.data.data.rows;
          this.loading.queryButton = false
          this.loading.tableLoading = false;
          if (response.data.data.total == 0) {
            ElMessage('该时段无数据');
            this.isNoData = true;
            this.isTableShow = false
            return;
          }
          this.isTableShow = true
          this.total = response.data.data.total;
          // ç§»é™¤ç©ºæ•°æ®çŠ¶æ€
          this.isNoData = false;
        });
      this.conditionDialogVisible = false
    },
    /**
@@ -1279,9 +1145,10 @@
          if (response.data.data.total == 0) {
            ElMessage('该时段无数据');
            this.isNoData = true;
            this.isTableShow = false
            return;
          }
          this.isTableShow = true
          this.total = response.data.data.total;
          this.loading.tableLoading = false;
        });
@@ -1350,7 +1217,16 @@
</script>
<template>
 <el-button type="primary" @click="conditionDialogVisible = true">
    æœç´¢æ¡ä»¶
  </el-button>
  <el-dialog
    v-model="conditionDialogVisible"
    title="Tips"
    width="30%"
    class="condition-dialog"
  >
  <el-row ref="h1">
    <el-col>
      <el-form :inline="true">
@@ -1358,34 +1234,56 @@
          <el-form-item >
          <AreaAndmonitorType ></AreaAndmonitorType>
          </el-form-item>
          <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> -->
          <el-form-item>
            <TimeSelectWithShortCuts timeType="day" @submit-time="giveTime" ></TimeSelectWithShortCuts>
          </el-form-item>
          <el-form-item>
            <ExceptionType
              @submit-value="(n) => form.exceptionName = n"
            ></ExceptionType>
          </el-form-item>
          <el-form-item>
            <TimeSelectWithShortCuts @submit-time="giveTime"></TimeSelectWithShortCuts>
          </el-form-item>
        </div>
        <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>
    </el-col>
  </el-row>
<!--
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisible = false">Cancel</el-button>
        <el-button type="primary" @click="dialogVisible = false">
          Confirm
        </el-button>
      </span>
    </template> -->
  </el-dialog>
  <el-row class="head-describtion-text" ref="h2">
    <el-row>
@@ -1608,7 +1506,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 +1643,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">
@@ -2003,13 +1901,13 @@
    </el-col>
  </el-row>
  <el-row>
    <el-col v-show="!isNoData">
  <el-row v-show="isTableShow">
    <el-col >
      <el-table
        ref="table"
        :data="displayData"
        :height="tableHeight"
        highlight-current-row="true"
        :highlight-current-row="true"
        size="default"
        v-loading="loading.tableLoading"
        border
@@ -2098,7 +1996,6 @@
    </el-col>
  </el-row>
  <el-empty v-show="isNoData" :image-size="200" />
  <el-dialog v-model="dialogTableVisible" draggable align-center height="300px">
    <!-- å¤´ -->
@@ -2241,9 +2138,19 @@
</template>
<style lang="scss" scoped>
.el-row {
  margin-left: 10px;
}
/* ä¸‹æ‹‰èœå•开始 */
.example-showcase .el-dropdown-link {
  cursor: pointer;
  color: var(--el-color-primary);
  display: flex;
  align-items: center;
}
/* ä¸‹æ‹‰èœå•结束 */
/* æ¡ä»¶æŸ¥è¯¢æ¨¡å—的样式 */
.head-container-search {
@@ -2333,10 +2240,7 @@
/* æŸ¥çœ‹è¯¦æƒ…对话框模块的样式 */
:deep(.el-dialog) {
  // å¯¹è¯æ¡†é«˜åº¦
}
.diag-head {
  // å¯¹è¯æ¡†å¤´éƒ¨åŒºåŸŸ
  min-height: 200px;
@@ -2361,11 +2265,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,
      // è¡¨æ ¼æ•°æ®
@@ -45,64 +46,30 @@
      // æ¯é¡µæ¡æ•°
      pageSize: 20,
      total: 0,
      // è¡¨æ ¼æŸ¥è¯¢æ— æ•°æ®æ—¶
      isNoData: false,
      // å¯¹è¯æ¡†æ˜¾ç¤º
      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,
      // é€‰ä¸­è¡¨æ ¼å½“前行的索引
      selectedRowIndex:-2,
      selectedRowIndex: -2,
      // é¡µé¢ä¸Šçš„æŒ‰é’®åŠ è½½çŠ¶æ€
      loading: {
        submitAudit: false,
        // æŸ¥è¯¢æŒ‰é’®
        queryButton:false,
            // è¡¨æ ¼åŠ è½½ä¸­
       tableLoading: false,
        queryButton: false,
        // è¡¨æ ¼åŠ è½½ä¸­
        tableLoading: false,
        // ä¸Šä¸€æ¡æŒ‰é’®
        preButton: false,
        // ä¸‹ä¸€æ¡æŒ‰é’®
        afterButton: false,
        // æŠ˜çº¿å›¾
        lineChart: false,
        lineChart: false
      },
      dialog: {
@@ -121,23 +88,29 @@
      },
      // æ ‡è®°ä½
      flag:{
      flag: {
        // åŠ è½½æ—¶ ä¸Šä¸‹æ¡æŒ‰é’®ä¸èƒ½å†ç‚¹å‡»
        banTouch:0,
        banTouch: 0,
        // 0代表分页,1代表不分页
        originClick:0
      }
        originClick: 0
      },
      auditDialog: {
        visible: false,
        // å®¡æ ¸äºº
        checker: 'admin',
        checkDate: '',
        checkerNotes: '',
        enterpriseNotes: '',
      },
      auditTableData: [],
      // å®¡æ ¸çŠ¶æ€ä¸ä¸º0
      auditData: [],
    };
  },
  setup() {
    // provide('search',readonly(form))
    const { backData, error, request } = useFetch();
    const { isExceedOneMonth } = useCommonFunction();
    return {
      backData,
      error,
      request,
      isExceedOneMonth
    };
  },
@@ -167,79 +140,332 @@
      }
    },
    // å½“选择的时间发生变化时,异常分析部分的异常店铺数量同步变化
        beginTime() {
          this.getShopNames();
      },
      endTime() {
        this.getShopNames();
      },
    dialogTableVisible() {
      window.addEventListener('resize', this.updateChart);
    }
  },
  computed: {
    // å®¡è®¡æ€»æ•°ï¼ˆåŒ…括部分审核)
    auditTotal(){
      return this.auditData.length
    },
    // è§„范审计总数
    auditedRegular(){
      let count = 0
      this.auditData.forEach(item => {
        if(item.auditStatus == 3){
           count ++
          }
      })
      return count
    },
    // éƒ¨åˆ†å®¡æ ¸æ•°é‡
    auditPart(){
      let count = 0
      this.auditData.forEach(item => {
        if(item.auditStatus == 1 || item.auditStatus == 2){
           count ++
          }
      })
      return count
    },
    // å¾…审核数
    unCheckedNUm() {
      return this.total - this.auditedRegular;
    },
     // å®¡æ ¸æ¯”例
     checkedRate() {
      return ((this.auditedRegular / this.total) * 100).toFixed(1);
    },
  },
  mounted() {
    this.backExceptionDataAWeekAgo();
    this.calTableHeight();
    // æŸ¥è¯¢æ—¶é—´æ®µçš„各异常的站点,查询该时间区间的各异常数量
    this.getShopNames();
  },
  methods: {
    /**
     * æŸ¥çœ‹è¯¥æ®µæ—¶é—´å†…已审核的数据
     * @param:
     * @returns:
     */
    gethasCheckedNumByTime() {
      submitApi.getAuditNumByTime(this.beginTime, this.endTime).then((res) => {
        this.auditData = res.data.data;
      });
    },
    /**
     * å¤šé€‰åˆ—(已审核的行不会加入其中)
     * @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;
            }
            // æ›´æ–°åˆ†æžçš„æ•°æ®
            setTimeout(() => {
            this.gethasCheckedNumByTime();
            }, 1500);
          } 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;
            }
            // æ›´æ–°åˆ†æžçš„æ•°æ®
            setTimeout(() => {
              this.gethasCheckedNumByTime();
            }, 1500);
          } 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:点击异常站点名字时 è¿”回的数据
     * @param:
     * @param:
     * @createTime:2023-08-17
     * @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() {
    // ç‚¹å‡»è¡¨æ ¼çš„行时
    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(){
    setOfflineTbleData() {
      // æ— æ•°æ®æ—¶çš„æ—¶é—´æ•°ç»„ æ—¶é—´ç›¸å·®15分钟
      const abnormalTimeTenMinute = this.descTenTime(
      const abnormalTimeTenMinute = index.descFiftyTime(
        this.tableCurrentRowData.beginTime,
        this.tableCurrentRowData.endTime
      );
@@ -250,7 +476,7 @@
        this.dialog.historyData.push({
          name: this.tableCurrentRowData.name,
          mnCode: this.tableCurrentRowData.mnCode,
          dutyCompany:this.tableCurrentRowData.dutyCompany,
          dutyCompany: this.tableCurrentRowData.dutyCompany,
          lst: abnormalTimeTenMinute[i],
          dustValue: ''
        });
@@ -260,63 +486,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;
    },
    // æ®µç”µæˆ–断网区间无数据,需要补充。其他的都有数据,直接一次请求全部时段就好
    // æ ¹æ®å¼‚常区间构造前后端首尾 å‰åŒºé—´ ä¸­é—´åŒºé—´ åŽåŒºé—´
@@ -328,99 +497,48 @@
     * description:一次请求回前中后区间的数据,对数据进行分析
     * @param: å‰ä¸­åŽåŒºé—´çš„请求参数,前中后的总区间时间,异常开始时间,一场结束时间
     */
     otherExceptionRequest(allTimeArgs,allTime,exceptionBT,exceptionET) {
       // æŠ˜çº¿å›¾åŠ è½½ä¸­æ•ˆæžœ
      this.loading.lineChart = true
    otherExceptionRequest(allTimeArgs, allTime, exceptionBT, exceptionET) {
      // æŠ˜çº¿å›¾åŠ è½½ä¸­æ•ˆæžœ
      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()
        }
          //  æ–­ç”µæˆ–断网时重新设置表格
          if (this.tableCurrentRowData.exceptionType == '0') {
            this.setOfflineTbleData();
          }
            // x轴日期时间
        let dateList = [];
        // yè½´ è¶…标油烟浓度
        let dustValue = [];
        let timeAndValue = {};
          // x轴日期时间
          let dateList = [];
          // yè½´ è¶…标油烟浓度
          let dustValue = [];
          let timeAndValue = {};
        // ä»Žæ·»åŠ äº†é¦–ä½åŒºé—´çš„å¼€å§‹å’Œç»“æŸæ—¶é—´è¿›è¡ŒéåŽ† ä¿è¯æ—¶é—´ä»¥10分钟为间隔
        timeAndValue = this.keepContinuousByEachFiftyMinutes(
          // ä»Žæ·»åŠ äº†é¦–ä½åŒºé—´çš„å¼€å§‹å’Œç»“æŸæ—¶é—´è¿›è¡ŒéåŽ† ä¿è¯æ—¶é—´ä»¥10分钟为间隔
          timeAndValue = index.keepContinuousByEachFiftyMinutes(
            allTime[0],
            allTime[3],
            this.dialog.allExceptionTimeData
        );
        dateList = timeAndValue['xAxis'];
        dustValue = timeAndValue['yAxis'];
        // æå–异常起始时间点在整个区间内的数据索引
        let startIndex = dateList.findIndex(
            (item) => item === exceptionBT
        );
        let endIndex = dateList.findIndex((item) => item === exceptionET);
          );
          dateList = timeAndValue['xAxis'];
          dustValue = timeAndValue['yAxis'];
        // è®¾ç½®æŠ˜çº¿å›¾é…ç½®é¡¹
        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
        );
        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;
          // æå–异常起始时间点在整个区间内的数据索引
          let startIndex = dateList.findIndex((item) => item === exceptionBT);
          let endIndex = dateList.findIndex((item) => item === exceptionET);
          // è®¾ç½®æŠ˜çº¿å›¾é…ç½®é¡¹
          this.reSetChart(
            dateList,
            dustValue,
            exceptionBT,
            exceptionET,
            startIndex,
            endIndex
          );
          this.loading.lineChart = false;
        });
    },
    /**
@@ -491,7 +609,7 @@
            ]
          };
          break;
        // è¶…æ ‡
        // è¶…æ ‡
        case '2':
          this.dialog.option = {
            tooltip: {},
@@ -605,7 +723,7 @@
          break;
        // æ•°æ®è¶…低 åªæœ‰æ—¶é—´ç‚¹
        case '1':
        this.dialog.option = {
          this.dialog.option = {
            tooltip: {},
            toolbox: {
              // å·¥å…·æ 
@@ -646,7 +764,7 @@
                  }
                  return item;
                }),
                markLine: {
                  symbol: 'none',
                  itemStyle: {
@@ -699,7 +817,7 @@
            }
          };
          break;
        case '3' :
        case '3':
          this.dialog.option = {
            tooltip: {},
            toolbox: {
@@ -784,7 +902,7 @@
          };
          break;
        case '4':
        this.dialog.option = {
          this.dialog.option = {
            tooltip: {},
            toolbox: {
              // å·¥å…·æ 
@@ -831,8 +949,7 @@
                      }
                    ]
                  ]
                },
                }
              }
            ],
            // æŒ‡å®šæ—¶é—´åŒºé—´çš„线段变颜色
@@ -859,15 +976,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,30 +992,35 @@
      // 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
      );
    },
    /**
     * description:获取下一条异常信息
     */
    getPreviousRowData() {
    //     // ä¸æ˜¯è¡¨æ ¼çš„æœ€åŽä¸€è¡Œ
      //     // ä¸æ˜¯è¡¨æ ¼çš„æœ€åŽä¸€è¡Œ
      if (this.selectedRowIndex < this.displayData.length - 1) {
        // ç‚¹å‡»è¿‡ç¨‹ä¸­ é”ä½ä¸Šä¸‹æ¡æŒ‰é’®  åœ¨è®¾ç½®å®Œå›¾å½¢é…ç½®é¡¹åŽè§£é”
        this.flag.banTouch = 1
        this.flag.banTouch = 1;
        //得到上一行数据索引
        this.selectedRowIndex = this.selectedRowIndex + 1;
@@ -908,255 +1029,55 @@
        // 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.dialog.historyData = response.data.data;
            this.dialog.exceptionTotal = response.data.data.length;
            // é€»è¾‘处理
            this.timeAndDataProcessed()
            this.loading.preButton = false
          });
        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.selectedRowIndex = this.selectedRowIndex + 1;
        // this.tableCurrentRowData = this.displayData[this.selectedRowIndex]
        // console.log('当前行数据为:',this.tableCurrentRowData);
    },
    /**
     * description:获取下一条异常信息
     */
    getNextRowData() {
         // ä¸æ˜¯è¡¨æ ¼çš„第一行
      // ä¸æ˜¯è¡¨æ ¼çš„第一行
      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) => {
            // ä¿å­˜è¿”回的超标数据
            this.dialog.historyData = response.data.data;
            this.dialog.exceptionTotal = response.data.data.length;
            // é€»è¾‘处理
            this.timeAndDataProcessed()
            this.loading.afterButton = false
          });
        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;
        });
      }
    },
    /**
     * 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:显示对话框,返回该异常时间段的所有数据
@@ -1166,7 +1087,7 @@
    showDialog(row) {
      // æ‰“开对话框
      this.dialogTableVisible = true;
      // ä¿å­˜å½“前行数据
      this.tableCurrentRowData = row;
@@ -1193,9 +1114,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 +1127,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 +1141,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 +1189,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 +1214,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)`;
    },
    // é¡µå¤§å°æ”¹å˜æ—¶è§¦å‘
@@ -1310,11 +1238,10 @@
      // å°†å½“前页号给currentPage
      this.currentPage = val;
      // é¡µé¢å˜åŒ–时调用 æŸ¥è¯¢æ•°æ®å‡½æ•°
      if(this.flag.originClick==0){
      if (this.flag.originClick == 0) {
        this.handleSubmit();
      }else if(this.flag.originClick ==1){
      } else if (this.flag.originClick == 1) {
        const startIndex = (val - 1) * this.pageSize;
        const endIndex = startIndex + this.pageSize;
@@ -1334,50 +1261,100 @@
</script>
<template>
  <el-row ref="h1">
    <el-col>
      <el-form :inline="true">
        <div class="head-container-text">
          <el-form-item >
          <AreaAndmonitorType ></AreaAndmonitorType>
          <el-form-item>
            <AreaAndmonitorType></AreaAndmonitorType>
          </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> -->
  <div class="checknum">
      <el-row class="anasysis" ref="h2">
        <el-col :span="8">
        <span class="checknum-blue">应审核数:</span> {{ total }}<span class="checknum-rate">({{ checkedRate }}%) </span>
        </el-col>
        <el-col :span="8">
          <div><span class="checknum-green">已审核数:</span>{{ auditTotal }}</div>
          <div>规范审核数:{{ auditedRegular }}</div>
          <div>部分审核数:{{ auditPart }}</div>
        </el-col >
        <el-col :span="8">
          <span><span class="checknum-red">待审核数:</span>{{ unCheckedNUm }}</span>
        </el-col>
      </el-row>
</div>
  <el-row>
@@ -1386,11 +1363,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 +1428,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"
@@ -1477,38 +1500,104 @@
  <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 v-show="tableCurrentRowData.auditStatus==3">
      <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">
    <!-- å¤´ -->
    <template #header>
      <div class="diag-head">
        <div class="diag-head-text">
          <div>
          <span class="diag-head-text1">站点名称:</span
          >{{ tableCurrentRowData.name }}
            <span class="diag-head-text1">站点名称:</span
            >{{ tableCurrentRowData.name }}
          </div>
          <div>
          <span class="diag-head-text1">异常类型:</span>
          <span v-if="tableCurrentRowData.exceptionType == '0'"
            >断电或断网</span
          >
          <span v-else-if="tableCurrentRowData.exceptionType == '1'"
            >数据超低</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
          > <span v-else-if="tableCurrentRowData.exceptionType == '6'"
            >单日超标次数临界异常</span
          > <span v-else-if="tableCurrentRowData.exceptionType == '7'"
            >滑动平均值异常</span
          >
        </div>
            <span class="diag-head-text1">异常类型:</span>
            <span v-if="tableCurrentRowData.exceptionType == '0'"
              >断电或断网</span
            >
            <span v-else-if="tableCurrentRowData.exceptionType == '1'"
              >数据超低</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
            >
            <span v-else-if="tableCurrentRowData.exceptionType == '6'"
              >单日超标次数临界异常</span
            >
            <span v-else-if="tableCurrentRowData.exceptionType == '7'"
              >滑动平均值异常</span
            >
          </div>
          <div>
            <span class="diag-head-text1">异常时间段:</span
@@ -1536,14 +1625,13 @@
      </div>
    </template>
    <!-- :option="dialog.option" -->
    <!-- å›¾å½¢ -->
    <DustLineChart
      :option="dialog.option"
      :is-open-dialog="dialogTableVisible"
      v-loading="loading.lineChart"
    ></DustLineChart>
    >
    </DustLineChart>
    <!-- è¡¨æ ¼ -->
    <div>
@@ -1600,16 +1688,12 @@
            tableCurrentRowData.exceptionType == '1' ||
            tableCurrentRowData.exceptionType == '2' ||
            tableCurrentRowData.exceptionType == '3' ||
            tableCurrentRowData.exceptionType == '4'
            tableCurrentRowData.exceptionType == '4'
          "
          >异常数据:</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,16 +1703,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 {
  justify-content: flex-end;
  margin-bottom: 10px;
@@ -1639,106 +1721,95 @@
/* å¼‚常分析模块的样式 */
.card-text1 {
  // é»‘体的异常名字部分
  margin: 10px;
}
.card-text1 + div {
  // é»‘体的异常名字下面的
  margin: 12px;
}
.card-exception-buttom {
  // å¼‚常站点文本按钮区域
  padding: 11px;
}
.card-header {
  margin-left: 5px;
  font-size: 18px;
  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 {
/*分析 */
// .anasysis {
//   margin-bottom: 20px;
// }
// :deep(.el-statistic__head) {
//   font-weight: bold;
//   font-size: 16px;
// }
.checknum {
  border: 1px solid orange;
  margin-bottom: 10px;
  margin-left: 20px;
  margin: 0px 5px 10px 20px;
}
.checknum-rate{
    margin-left: 5px;
  }
.checknum-blue {
  font-weight: bold;
  color: blue;
}
/* å¼‚常分析模块结束 */
.checknum-green {
  font-weight: bold;
  color: green;
}
.checknum-red {
  font-weight: bold;
  color: red;
}
/* åˆ†æžç»“束 */
/* è¡¨æ ¼æ¨¡å—的样式 */
: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 +1822,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,19 +1,13 @@
<!-- æ—¥å‡å€¼ -->
<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';
import { useWindowSize } from '@vueuse/core';
import LineChart from './components/LineChart.vue'
// const DustRadarChart = defineAsyncComponent(() =>
//   import('./components/DustRadarChart.vue')
// )
import LineChart from './components/LineChart.vue';
import dayjs from 'dayjs';
export default {
@@ -61,14 +55,21 @@
        //  å…¸åž‹å¼‚常复现率
        exceptionRecurrence: '',
        // å¼‚常类型据聚集度
        exceptionTypeAggregation: '',
        exceptionTypeAggregation: ''
      }
    };
  },
  setup() {
    const { height } = useWindowSize();
    return { height };
  computed: {
    weight() {
      return (
        (100 - this.bill.online) * 0.1 +
        (100 - this.bill.valid) * 0.2 +
        this.bill.exceeding * 0.2 +
        this.bill.exceptionTypeAggregation * 0.2 +
        this.bill.exceptionRecurrence * 0.3
      ).toFixed(2);
    }
  },
  mounted() {
    this.fetch();
@@ -90,11 +91,11 @@
      let exceedindCriticalDegree = 0;
      // ä¿å­˜å‡ºçŽ°çš„ä¸åŒå¼‚å¸¸ç±»åž‹
      let exception = []
      let exception = [];
      // å¼‚常类型聚集度
      let exceptionTypeAggregation = 0
      exceptionArr.forEach(item => {
      let exceptionTypeAggregation = 0;
      exceptionArr.forEach((item) => {
        // å¼‚常复现率
        if (item.exceptionType == 4) {
          mutationCount++;
@@ -105,12 +106,12 @@
        }
        // å¼‚常类型聚集度
        if(exception.length == 0){
          exception.push(item.exceptionType)
        if (exception.length == 0) {
          exception.push(item.exceptionType);
        }
        // ä¿å­˜æ–°çš„异常类型
        else if(exception.indexOf(item.exceptionType) == -1){
          exception.push(item.exceptionType)
        else if (exception.indexOf(item.exceptionType) == -1) {
          exception.push(item.exceptionType);
        }
      });
@@ -125,9 +126,14 @@
      if (exceedindCriticalDegree > 1) {
        sum = sum + exceedindCriticalDegree - 1;
      }
      console.log('sum:',sum);
      console.log('exception:',exception);
      console.log('其他',mutationCount,exceedindCriticalDegree,exceedindCriticalDegree);
      console.log('sum:', sum);
      console.log('exception:', exception);
      console.log(
        '其他',
        mutationCount,
        exceedindCriticalDegree,
        exceedindCriticalDegree
      );
      switch (sum) {
        case 0:
          exceptionTyprRecurRate = sum / 3;
@@ -143,13 +149,13 @@
          return 'error';
      }
      exceptionTypeAggregation = exception.length / 8
      exceptionTypeAggregation = exception.length / 8;
      let obj = {}
      obj['exceptionRecurrence'] = exceptionTyprRecurRate
      obj['exceptionTypeAggregation'] = exceptionTypeAggregation
      let obj = {};
      obj['exceptionRecurrence'] = exceptionTyprRecurRate;
      obj['exceptionTypeAggregation'] = exceptionTypeAggregation;
      return obj
      return obj;
    },
    /**
     * è®¡ç®—日期相差几天
@@ -158,13 +164,7 @@
     * @returns:
     */
    getDaysDifference(startDate, endDate) {
      // var start = new Date(startDate);
      // var end = new Date(endDate);
      // var timeDiff = Math.abs(end.getTime() - start.getTime());
      // var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
      return dayjs(endDate).diff(startDate,'day') + 1;
      return dayjs(endDate).diff(startDate, 'day') + 1;
    },
    /**
     * ä»Žåˆ†æžæ•°æ®æ•°ç»„中找到最小和大值
@@ -188,7 +188,7 @@
      let begin = dayjs(this.form.beginTime).format('YYYY-MM-DD');
      let end = dayjs(this.form.endTime).format('YYYY-MM-DD');
      let dayDiff = this.getDaysDifference(begin, end);
      console.log('日期间隔',dayDiff);
      console.log('日期间隔', dayDiff);
      let obj = {};
      // è®¡ç®—最小和大值
      arr.forEach((item) => {
@@ -245,14 +245,6 @@
    // ç‚¹å‡»å±•示按钮
    fetchData() {
      if (
        this.form.beginTime >= this.form.endTime &&
        (this.form.beginTime != null || this.form.endTime != null) &&
        (this.form.beginTime != '' || tthis.form.endTime != '')
      ) {
        alert('请输入有效的时间段');
        return;
      }
      let params = {};
      if (this.form.name) {
        params['siteName'] = this.form.name;
@@ -287,8 +279,8 @@
          this.bill.valid = temp['valid'];
          this.bill.exceeding = temp['exceeding'];
          this.begin = this.chartData[0].lst
          this.end = this.chartData[this.chartData.length-1].lst
          this.begin = this.chartData[0].lst;
          this.end = this.chartData[this.chartData.length - 1].lst;
        });
    },
@@ -341,9 +333,9 @@
        })
        .then((res) => {
          console.log('异常:', res.data.data);
          let obj = this.calRecur(res.data.data)
          this.bill.exceptionRecurrence = obj['exceptionRecurrence']
          this.bill.exceptionTypeAggregation = obj['exceptionTypeAggregation']
          let obj = this.calRecur(res.data.data);
          this.bill.exceptionRecurrence = obj['exceptionRecurrence'];
          this.bill.exceptionTypeAggregation = obj['exceptionTypeAggregation'];
        });
    }
  }
@@ -353,15 +345,13 @@
  <div class="search-container">
    <el-container>
      <el-main>
        <el-form :inline="true" :model="form">
          <el-form-item>
            <AreaAndmonitorType></AreaAndmonitorType>
          </el-form-item>
          <el-form-item>
            <InputSearch
              :isNeedDefaultSite="1"
              isNeedDefaultSite="1"
              @submit-value="(n) => (form.name = n)"
            ></InputSearch>
          </el-form-item>
@@ -371,33 +361,103 @@
              @submit-time="giveTime"
            ></TimeSelectWithShortCuts>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="fetch">展示折线图</el-button>
          </el-form-item>
        </el-form>
        <div class="time-text">数据统计时段:{{ begin}} ~ {{ end }}</div>
        <div class="time-text">数据统计时段:{{ begin }} ~ {{ end }}</div>
        <el-row :gutter="20">
          <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="16" >
        <el-card
              shadow="never"
            >
              <DustRadarChart :name="['数据有效率','典型异常复现率','异常类型聚集度','数据超标率','数据在线率']" :yData="[bill.valid,bill.exceptionRecurrence,bill.exceptionTypeAggregation,bill.exceeding,bill.online]" ></DustRadarChart>
          <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="16">
            <el-card shadow="never">
              <DustRadarChart
                :name="[
                  '数据有效率风险',
                  '典型异常复现率风险',
                  '异常类型聚集度风险',
                  '数据超标率风险',
                  '数据在线率风险'
                ]"
                :yData="[
                  bill.valid,
                  bill.exceptionRecurrence,
                  bill.exceptionTypeAggregation,
                  bill.exceeding,
                  bill.online
                ]"
              ></DustRadarChart>
              <div>
                æƒé‡ï¼š
                <span
                  :class="{
                    'weightColor-low': weight < 0.2,
                    'weightColor-medium': weight >= 0.2 && weight < 0.6,
                    'weightColor-heigh': weight >= 0.6
                  }"
                  >{{ weight }}</span
                >
              </div>
              <div></div>
            </el-card>
          </el-col>
          <el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="4">
            <el-card
              shadow="never"
            style="width: 200px;min-width: 200px;"
            >
              <template #header><span class="title-16">风险详情</span></template>
              <el-form >
            <el-card shadow="never" style="width: 200px; min-width: 200px">
              <template #header>
                <h1
                  :class="{
                    'weightColor-low': weight < 0.2,
                    'weightColor-medium': weight >= 0.2 && weight < 0.6,
                    'weightColor-heigh': weight >= 0.6
                  }"
                >
                  é£Žé™©å€¼ï¼š{{ weight }}
                </h1>
              </template>
              <template #default>
                <div class="risk-grade">
                  <h1>风险等级:</h1>
                  <span v-if="weight >= 0.6"> é«˜é£Žé™©</span>
                  <span v-else-if="weight >= 0.2 && weight < 0.6"> ä¸­é£Žé™©</span>
                  <span v-else> ä½Žé£Žé™©</span>
                </div>
                <div class="risk-advice">
                  <h1>管控建议:</h1>
                  <span v-if="weight >= 0.6">
                    å»ºè®®å¯¹è¯¥ç«™ç‚¹è¿›è¡Œçº¿ä¸‹æ‰§æ³•检查,专项数据对比</span
                  >
                  <span v-else-if="weight >= 0.2 && weight < 0.6">
                    å»ºè®®å¼€å±•常态追踪分析</span
                  >
                  <span v-else> å»ºè®®å¼•导企业长态保持</span>
                </div>
                <div class="grade-instance">
                  <div class="container">
                    <div class="block-color heigh"></div>
                    <div>高风险(≥0.6)</div>
                  </div>
                  <div class="container">
                    <div class="block-color medium"></div>
                    <div>中风险(0.2~0.6)</div>
                  </div>
                  <div class="container">
                    <div class="block-color low"></div>
                    <div>低风险(<0.2)</div>
                  </div>
                </div>
              </template>
            </el-card>
          </el-col>
          <el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="4">
            <el-card shadow="never" style="width: 200px; min-width: 200px">
              <template #header
                ><span class="title-16">风险详情</span></template
              >
              <el-form>
                <el-form-item label="最大值:">
                  {{ bill.max }} mg/m³
                </el-form-item>
@@ -414,61 +474,19 @@
                  {{ bill.exceeding }}%
                </el-form-item>
                <el-form-item label="异常类型聚集度:">
                  {{ bill.exceptionTypeAggregation*100  }}%
                  {{ bill.exceptionTypeAggregation * 100 }}%
                </el-form-item>
                <el-form-item label="典型异常复现率:" label-width="auto">
                  {{ bill.exceptionRecurrence*100  }}%
                <el-form-item label="典型异常复现率:">
                  {{ 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>
          <el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="4">
            <el-card
              shadow="never"
            style="width:200px; min-width: 200px;"
            >
              <template #header>
                <span class="title-16">风险等级</span>
              </template>
              <template #default>
                <!-- <el-space direction="vertical" :size="15" > -->
                  <div class="container">
                    <div class="block-color heigh"></div> <div>高风险(≥0.6)</div>
                  </div>
                  <div class="container">
                    <div class="block-color medium" ></div> <div>中风险(0.2~0.6)</div>
                  </div>
                  <div class="container">
                    <div class="block-color low"></div><div>低风险(<0.2)</div>
                  </div>
                <!-- </el-space> -->
              </template>
            </el-card>
          </el-col>
        </el-row>
        <el-row :gutter="24">
          <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="6">
            <el-card
              shadow="never"
            >
            <el-card shadow="never">
              <template #default>
                <LineChart
                  title="日均值"
@@ -482,10 +500,7 @@
          </el-col>
          <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="6">
            <el-card
              shadow="never"
            >
            <el-card shadow="never">
              <template #default>
                <LineChart
                  title="日在线率"
@@ -499,8 +514,7 @@
          </el-col>
          <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="6">
            <el-card shadow="never"
            >
            <el-card shadow="never">
              <template #default>
                <LineChart
                  title="日有效率"
@@ -514,7 +528,7 @@
          </el-col>
          <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="6">
            <el-card shadow="never" >
            <el-card shadow="never">
              <template #default>
                <LineChart
                  title="日超标率"
@@ -527,9 +541,6 @@
            </el-card>
          </el-col>
        </el-row>
      </el-main>
    </el-container>
  </div>
@@ -556,6 +567,9 @@
  display: flex;
  margin-bottom: 10px;
}
.grade-instance {
  margin-top: 40px;
}
.block-color {
  width: 1em;
  height: 1em;
@@ -566,27 +580,36 @@
  background-color: red;
}
.medium {
  background-color: #FADC19;
  background-color: #fadc19;
}
.low {
  background-color: #9FDB1D;
  background-color: #9fdb1d;
}
.el-text {
  align-self: left;
}
.el-form-item {
margin-bottom: 20px;
  margin-bottom: 20px;
}
:deep().el-form-item__content {
  justify-content: flex-end;
}
.title-16 {
  font-size: 16px;
  font-weight: bold;
}
.el-row {
.weightColor-low {
  color: #9fdb1d;
}
.weightColor-medium {
  color: #dabe09;
}
.weightColor-heigh {
  color: red;
}
.risk-grade {
  display: flex;
  margin-bottom: 20px;
}
</style>
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() {
@@ -22,14 +20,8 @@
      tableData: [],
      isNoData: false,
      loading: false,
      // begin: '2023-05-01', //开始时间
      // end: '2023-05-15', //结束时间
      form: {
        // ç«™ç‚¹åç§°
        name: '',
        // è®¾å¤‡ç¼–号
        number: '',
        // å¼€å§‹æ—¶é—´
        beginTime: '',
        // ç»“束时间
@@ -43,14 +35,6 @@
    return {cmpp,exportToExcel} 
  },
  //   watch:{
  //     pageSize(){
  //         this.handleSizeChange()
  //     },
  //     currentPage(){
  //         this.handleCurrentChange()
  //     },
  //   },
  mounted() {
    this.form.name = '';
@@ -174,13 +158,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,8 +176,6 @@
        <el-card>
          <el-empty v-show="isNoData" :image-size="200" />
          <!-- <LineChart :chartData="option"> </LineChart> -->
        </el-card>
        <el-table
          :data="tableData"
@@ -277,6 +257,8 @@
          @update:current-page="handleCurrentChange"
          @update:page-size="handleSizeChange"
        />
      </el-card>
      </el-main>
    </el-container>
  </div>
src/views/line_graph/SiteComprehensiveRskRanking.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,270 @@
<script>
import TimeSelectWithShortCuts from '@/sfc/TimeSelectWithShortCuts.vue';
import InputSearch from '@/sfc/InputSearch.vue';
import AreaAndmonitorType from '@/sfc/AreaAndmonitorType.vue';
import exceptionApi from '@/api/exceptionApi.js';
import {useCommonFunction} from '../../utils/common.js';
import index from '@/utils/risk_estimate_common_function/index.js'
import dayjs from 'dayjs';
export default {
  components: {
    TimeSelectWithShortCuts,
    AreaAndmonitorType,
    InputSearch
  },
  data() {
    return {
        // å½“前页
        currentPage: 1,
      // æ¯é¡µæ¡æ•°
      pageSize: 20,
      total: 0,
      //   è¡¨æ ¼æ•°æ®
      tableData: [],
      isNoData: false,
      loading: false,
      form: {
        // ç«™ç‚¹åç§°
        name: '',
        // å¼€å§‹æ—¶é—´
        beginTime: '',
        // ç»“束时间
        endTime: ''
      },
      bill: {
        min: '',
        max: '',
        avg: '',
        online: '',
        valid: '',
        exceeding: '',
        //  å…¸åž‹å¼‚常复现率
        exceptionRecurrence: '',
        // å¼‚常类型据聚集度
        exceptionTypeAggregation: '',
      },
      // {
      //   siteName:'',
      //   region:'',
      //   monitorType:'',
      //   riskValue:'',
      //   riskGrage:'',
      //   riskAdvice:'',
      //   beginTime:'',
      //   endTime:'',
      // }
      table:[]
    };
  },
  setup(){
     // å¼•å…¥ ç™¾åˆ†å·æ¯”较大小 å¯¼å‡ºåŠŸèƒ½
     const {exportToExcel} = useCommonFunction()
    return {exportToExcel}
  },
  computed: {
    weight() {
      return (
        (100 - this.bill.online) * 0.1 +
        (100 - this.bill.valid) * 0.2 +
        this.bill.exceeding * 0.2 +
        this.bill.exceptionTypeAggregation * 0.2 +
        this.bill.exceptionRecurrence * 0.3
      ).toFixed(2);
    }
  },
  watch:{
    weight(){
      this.table[0].riskValue = this.weight
    }
  },
  methods: {
    /**
     * å°†ä¸­å›½æ ‡å‡†æ—¶é—´è½¬ä¸ºæŒ‡å®šæ ¼å¼
     * @param:
     * @returns:
     */
     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');
    },
    // ç‚¹å‡»å±•示按钮
    fetchData() {
      let params = {};
      if (this.form.name) {
        params['siteName'] = this.form.name;
      }
      if (this.form.beginTime) {
        params['beginTime'] = this.form.beginTime;
      }
      if (this.form.endTime) {
        params['endTime'] = this.form.endTime;
      }
      this.loading = true;
      exceptionApi
        .analysisdata(this.form.name, this.form.beginTime, this.form.endTime)
        .then((response) => {
          this.chartData = response.data.data;
          this.loading = false;
          if (response.data.data.length == 0) {
            this.isNoData = true;
            return;
          }
          // ç§»é™¤ç©ºæ•°æ®çŠ¶æ€
          this.isNoData = false;
          let temp = index.calBillData(this.chartData,this.form.beginTime,this.form.endTime);
          this.bill.min = temp['min'];
          this.bill.max = temp['max'];
          this.bill.avg = temp['avg'];
          this.bill.online = temp['online'];
          this.bill.valid = temp['valid'];
          this.bill.exceeding = temp['exceeding'];
          this.begin = this.chartData[0].lst;
          this.end = this.chartData[this.chartData.length - 1].lst;
        const tempObj = {}
        tempObj.region = '金山区'
        tempObj.monitorType = '扬尘'
        tempObj.siteName = this.form.name
        tempObj.beginTime = this.form.beginTime
        tempObj.endTime = this.form.endTime
        // this.table[0].region = '金山区'
        // this.table[0].monitorType = '扬尘'
        // this.table[0].siteName = this.form.name
        // this.table[0].beginTime = this.form.beginTime
        // this.table[0].endTime = this.form.endTime
        if(this.weight>=0.6){
          tempObj.riskGrage = '高风险'
          tempObj.riskAdvice = '建议对该站点进行线下执法检查,专项数据对比'
          // this.table[0].riskGrage = '高风险'
          // this.table[0].riskAdvice = '建议对该站点进行线下执法检查,专项数据对比'
        }else if(this.weight<0.6 && this.weight>=0.2){
          tempObj.riskGrage = '中风险'
          tempObj.riskAdvice = '建议开展常态追踪分析'
          // this.table[0].riskGrage = '中风险'
          // this.table[0].riskAdvice = '建议开展常态追踪分析'
        }else {
          tempObj.riskGrage = '低风险'
          tempObj.riskAdvice = '建议引导企业长态保持'
          // this.table[0].riskGrage = '低风险'
          // this.table[0].riskAdvice = '建议引导企业长态保持'
        }
        this.table.push(tempObj)
        });
    },
    // ä¼ä¸šå¼‚常详情
    exceptiondataCount() {
      exceptionApi
        .exceptiondata1({
          siteName: this.form.name,
          beginTime: this.form.beginTime,
          endTime: this.form.endTime
        })
        .then((res) => {
          let obj = index.calRecur(res.data.data);
          this.bill.exceptionRecurrence = obj['exceptionRecurrence'];
          this.bill.exceptionTypeAggregation = obj['exceptionTypeAggregation'];
        });
    },
    /**
     * åˆå§‹åŠ è½½å‡½æ•°
     */
     fetch() {
      // åˆ†æžæ•°æ®
      this.fetchData();
      // å¼‚常数据
      this.exceptiondataCount();
    },
    /**
     * å¯¼å‡ºä¸ºExcel
     */
     exportData(){
      if(this.table.length!=0){
        const  tableColumns = ['siteName','region','monitorType','riskValue','riskGrage','riskAdvice','beginTime','endTime']
        const excelColumns = [['A1','站点名称'],
      ['B1','区域'],['C1','监测类型'],['D1','风险值'],
      ['E1','风险等级'],['F1','管控措施'],['G1','开始日期'],
      ['H1','结束日期']]
      this.exportToExcel(this.table,tableColumns,excelColumns,'综合风险排名.xlsx')
      }
    },
  }
};
</script>
<template>
  <el-row>
    <el-row>
      <el-form :inline="true" :model="form">
        <el-form-item>
          <AreaAndmonitorType></AreaAndmonitorType>
        </el-form-item>
        <el-form-item>
            <InputSearch
              isNeedDefaultSite="1"
              @submit-value="(n) => (form.name = n)"
            ></InputSearch>
          </el-form-item>
        <el-form-item>
          <TimeSelectWithShortCuts
            @submit-time="giveTime"
          ></TimeSelectWithShortCuts>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="fetch">风险排名</el-button>
          <el-button type="warning" @click="exportData">导出</el-button>
        </el-form-item>
      </el-form>
    </el-row>
  </el-row>
  <el-table
          :data="table"
          height="600px"
          style="width: 100%"
          v-loading="loading"
          :cell-class-name="tableCellClassName"
        >
        <el-table-column
            type="index"
            prop="name"
            label="序号"
            :index="indexMethod"
            fixed
            show-overflow-tooltip
          />
          <el-table-column prop="siteName" label="站点名称" show-overflow-tooltip />
          <el-table-column prop="region" label="区域" show-overflow-tooltip />
          <el-table-column prop="monitorType" label="检测类型" show-overflow-tooltip />
          <el-table-column prop="riskValue" label="风险值" show-overflow-tooltip />
          <el-table-column prop="riskGrage" label="风险等级" show-overflow-tooltip />
          <el-table-column prop="riskAdvice" label="管控措施" show-overflow-tooltip />
          <el-table-column prop="beginTime" label="开始日期" show-overflow-tooltip />
          <el-table-column prop="endTime" label="结束日期" show-overflow-tooltip />
  </el-table>
  <el-empty v-show="isNoData" :image-size="200" />
</template>
<style scoped>
.el-row,.el-table  {
  margin: 10px 0px 0px 10px
}
.el-table{
}
</style>
src/views/line_graph/components/DustRadarChart.vue
@@ -54,7 +54,7 @@
              color: ['#ddd', '#aaa']
            }
          },
          // shape: 'circle',
          indicator: [
            { name: this.name[0], max: 1 },
            { name: this.name[1], max: 1 },
@@ -62,13 +62,7 @@
            { name: this.name[3], max: 1 },
            { name: this.name[4], max: 1 }
          ],
          //     splitArea: {
          //   areaStyle: {
          //     // color: ['#77EADF', '#26C3BE', '#64AFE9', '#428BD4'],
          //     shadowColor: 'rgba(0, 0, 0, 0.2)',
          //     shadowBlur: 10
          //   }
          // },
          axisName: {
            color: '#428BD4'
          },
@@ -82,11 +76,11 @@
            data: [
              {
                value: [
                  (this.yData[0] / 100).toFixed(4),
                  (1 - (this.yData[0] / 100).toFixed(4)),
                  this.yData[1],
                  this.yData[2],
                  (this.yData[3] / 100).toFixed(4),
                  (this.yData[4] / 100).toFixed(4)
                 (this.yData[3] / 100).toFixed(4),
                  1-((this.yData[4] / 100).toFixed(4))
                ],
                // value: [
                //   this.yData[0],
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>
@@ -30,6 +31,7 @@
</template>
<script lang="ts">
import Cookie from 'js-cookie'
export default {
  data() {
    return {
@@ -42,6 +44,8 @@
      // ç™»å½•逻辑
      if (this.username === 'admin' && this.password === 'admin123') {
         ElMessage.success('登录成功');
         const token = 'abc'
         Cookie.set('token',token)
          // ç™»å½•成功,跳转到对应页面
          this.$router.push('/edata') // å‡è®¾ç™»å½•成功后跳转到 '/dashboard' é¡µé¢
        } else {
src/views/origin_data/BusinessReport.vue
ÎļþÒÑɾ³ý
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,32 +1,73 @@
<script>
// import DustRadarChart from '../../sfc/DustRadarChart.vue';
// import TimeSelectWithShortCuts from '../../sfc/TimeSelectWithShortCuts.vue'
import TimeSelectWithShortCuts from '@/sfc/TimeSelectWithShortCuts.vue';
import settingApi from '@/api/data_access_setting/settingApi.js'
import dayjs from 'dayjs';
  export default {
    components :{
    // DustRadarChart,
    // TimeSelectWithShortCuts
    components: {
    TimeSelectWithShortCuts,
  },
    data() {
      return{
      // åŒºåŸŸ
        radio:0,
        // å®šæ—¶
        radio1:'',
        beginTime:'',
        endTime:'',
      }
    },
    mounted() {
    },
    methods: {
      giveTime(val) {
        //将中国标准时间转为指定格式(该组件返回的标准时间的格式,所以必须的加这个函数)
        this.beginTime = dayjs(val[0]).format('YYYY-MM-DD HH:mm:ss');
        this.endTime = dayjs(val[1]).format('YYYY-MM-DD HH:mm:ss');
      },
      set(){
        const params = {}
        params.user = 'admin'
        params.beginTime = this.beginTime
        params.endTime = this.endTime
        params.region  = '金山'
        params.isRegularTime  = this.radio1
        settingApi.submitSetting(params).then(res => {
          if(res.data.code == 1){
            ElMessage.success('设置成功')
          }else{
            ElMessage('设置失败')
          }
        })
      }
     }
}
</script>
<template>
  <div>
    æ•°æ®æŽ¥å…¥é…ç½®
  </div>
  <div>生成配置文件</div>
  <el-form>
    <el-form-item label="区域">
      <el-radio-group v-model="radio">
    <el-radio :label="0">金山</el-radio>
    <!-- <el-radio :label="6">Option B</el-radio>
    <el-radio :label="9">Option C</el-radio> -->
  </el-radio-group>
    </el-form-item>
    <el-form-item label="选择起始时间">
      <TimeSelectWithShortCuts @submit-time="giveTime"></TimeSelectWithShortCuts>
    </el-form-item>
    <el-form-item label="是否定时">
      <el-radio-group v-model="radio1" >
      <el-radio label="1" size="large">是</el-radio>
      <el-radio label="2" size="large">否</el-radio>
    </el-radio-group>
    </el-form-item>
    <el-form-item> <el-button @click="set">设置</el-button></el-form-item>
  </el-form>
</template>
<style  scoped>