소스 검색

Merge remote-tracking branch 'origin/master'

LLL 1 년 전
부모
커밋
744f5c9643

+ 423 - 0
src/views/module_tpm/alarmQuery/alarmQueryList.vue

@@ -0,0 +1,423 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+          <a-col :xl="10" :lg="7" :md="8" :sm="24">
+            <a-form-item label="设备名称">
+              <a-select
+              v-model="queryParam.equipmentid"
+              placeholder="请输入设备名称或设备编号"
+              show-search
+              :filterOption="filterOptions"
+              @search="searchDevice"
+              allowClear>
+              <a-select-option v-for="(item, index) in deviceOptions" :key="index" :value="item.id" :label="item.equipmentname">
+                <span>{{item.equipmentname}}</span>
+                <span style="position: absolute;right: 2%;">{{ item.equipmentcode }}</span>
+              </a-select-option>
+              </a-select>
+            </a-form-item>
+          </a-col>
+          <template v-if="toggleSearchStatus">
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="报警日期">
+                <j-date v-model="queryParam.alarmtime" placeholder="请选择报警日期" style="width:100%;"></j-date>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="报警等级">
+                <j-dict-select-tag v-model="queryParam.alarmlevel" placeholder="请选择报警等级" dictCode="alarm_level"/>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="报警类型">
+                <j-dict-select-tag v-model="queryParam.alarmtype" placeholder="请选择报警类型" dictCode="alarm_type"/>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="处理状态">
+                <j-dict-select-tag v-model="queryParam.status" placeholder="请选择处理状态" dictCode="alarm_status"/>
+              </a-form-item>
+            </a-col>
+          </template>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+              <a @click="handleToggleSearch" style="margin-left: 8px">
+                {{ toggleSearchStatus ? '收起' : '展开' }}
+                <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
+              </a>
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 查询区域-END -->
+
+    <!-- 操作按钮区域 -->
+    <!-- <div class="table-operator">
+      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+      <a-button type="primary" icon="download" @click="handleExportXls('tpm_message_alarm')">导出</a-button>
+      <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
+        <a-button type="primary" icon="import">导入</a-button>
+      </a-upload> -->
+      <!-- 高级查询区域 -->
+      <!-- <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
+      <a-dropdown v-if="selectedRowKeys.length > 0">
+        <a-menu slot="overlay">
+          <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
+        </a-menu>
+        <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
+      </a-dropdown>
+    </div> -->
+
+    <!-- table区域-begin -->
+    <div>
+      <!-- <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+      </div> -->
+
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{x:true}"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        class="j-table-force-nowrap"
+        @change="handleTableChange">
+
+        <template slot="status_dictText" slot-scope="text,record">
+          <!-- <span v-if="text">{{record.status_dictText}}</span> -->
+          <a-button type="dashed" v-if="record.status == 0" size="small">{{record.status_dictText}}</a-button>
+          <!-- 处理中 -->
+          <a-button v-if="record.status == 1" class="yellow" size="small">{{record.status_dictText}}</a-button>
+          <!-- 已处理 -->
+          <a-button v-if="record.status == 2" class="green" size="small">{{record.status_dictText}}</a-button>
+        </template>
+
+        <template slot="htmlSlot" slot-scope="text">
+          <div v-html="text"></div>
+        </template>
+        <template slot="imgSlot" slot-scope="text,record">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
+          <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
+        </template>
+        <template slot="fileSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
+          <a-button
+            v-else
+            :ghost="true"
+            type="primary"
+            icon="download"
+            size="small"
+            @click="downloadFile(text)">
+            下载
+          </a-button>
+        </template>
+
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">处理</a>
+
+          <!-- <a-divider type="vertical" />
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a @click="handleDetail(record)">详情</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown> -->
+        </span>
+
+      </a-table>
+    </div>
+  </a-card>
+</template>
+
+<script>
+
+  import '@/assets/less/TableExpand.less'
+  import { mixinDevice } from '@/utils/mixin'
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import { httpAction, getAction } from '@/api/manage'
+
+  export default {
+    name: 'MessageAlarmList',
+    mixins:[JeecgListMixin, mixinDevice],
+    components: {
+    },
+    data () {
+      return {
+        description: 'tpm_message_alarm管理页面',
+        // 表头
+        columns: [
+          {
+            title: '序号',
+            dataIndex: '',
+            key:'rowIndex',
+            width:60,
+            align:"center",
+            customRender:function (t,r,index) {
+              return parseInt(index)+1;
+            }
+          },
+          {
+            title:'设备',
+            align:"center",
+            dataIndex: 'equipmentid_dictText'
+          },
+          {
+            title:'报警类型',
+            align:"center",
+            dataIndex: 'alarmtype_dictText'
+          },
+          {
+            title:'报警描述',
+            align:"center",
+            dataIndex: 'remark'
+          },
+          {
+            title:'报警时间',
+            align:"center",
+            dataIndex: 'alarmtime',
+            // customRender:function (text) {
+            //   return !text?"":(text.length>10?text.substr(0,10):text)
+            // }
+          },
+          {
+            title:'报警等级',
+            align:"center",
+            dataIndex: 'alarmlevel_dictText'
+          },
+          // {
+          //   title:'消息码',
+          //   align:"center",
+          //   dataIndex: 'msgcode'
+          // },
+          // {
+          //   title:'参数编号',
+          //   align:"center",
+          //   dataIndex: 'paramcode'
+          // },
+          // {
+          //   title:'参数名称',
+          //   align:"center",
+          //   dataIndex: 'paramname'
+          // },
+          {
+            title:'当前值',
+            align:"center",
+            dataIndex: 'nowvalue'
+          },
+          {
+            title:'阈值最小值',
+            align:"center",
+            dataIndex: 'vmin'
+          },
+          {
+            title:'阈值最大值',
+            align:"center",
+            dataIndex: 'vmax'
+          },
+          {
+            title:'处理状态',
+            align:"center",
+            dataIndex: 'status_dictText',
+            scopedSlots: { customRender: 'status_dictText' }
+          },
+          // {
+          //   title:'处理日期',
+          //   align:"center",
+          //   dataIndex: 'handletime',
+          //   customRender:function (text) {
+          //     return !text?"":(text.length>10?text.substr(0,10):text)
+          //   }
+          // },
+          // {
+          //   title:'处理人',
+          //   align:"center",
+          //   dataIndex: 'handleuser'
+          // },
+          // {
+          //   title:'处理信息',
+          //   align:"center",
+          //   dataIndex: 'handleremark'
+          // },
+          // {
+          //   title:'图片地址',
+          //   align:"center",
+          //   dataIndex: 'url'
+          // },
+          // {
+          //   title:'距离(摄像头用)',
+          //   align:"center",
+          //   dataIndex: 'distance'
+          // },
+          // {
+          //   title:'方位(摄像头用)',
+          //   align:"center",
+          //   dataIndex: 'position'
+          // },
+          // {
+          //   title:'所属年',
+          //   align:"center",
+          //   dataIndex: 'year'
+          // },
+          // {
+          //   title:'所属月',
+          //   align:"center",
+          //   dataIndex: 'month'
+          // },
+          // {
+          //   title:'所属周',
+          //   align:"center",
+          //   dataIndex: 'week'
+          // },
+          // {
+          //   title:'日期',
+          //   align:"center",
+          //   dataIndex: 'day'
+          // },
+          // {
+          //   title:'周几',
+          //   align:"center",
+          //   dataIndex: 'dayofweek'
+          // },
+          // {
+          //   title:'所属年月',
+          //   align:"center",
+          //   dataIndex: 'yearmonth'
+          // },
+          // {
+          //   title: '操作',
+          //   dataIndex: 'action',
+          //   align:"center",
+          //   fixed:"right",
+          //   width:147,
+          //   scopedSlots: { customRender: 'action' }
+          // }
+        ],
+        url: {
+          list: "/tpmMessageAlarm/tpmMessageAlarm/list",
+          delete: "/tpmMessageAlarm/tpmMessageAlarm/delete",
+          deleteBatch: "/tpmMessageAlarm/tpmMessageAlarm/deleteBatch",
+          exportXlsUrl: "/tpmMessageAlarm/tpmMessageAlarm/exportXls",
+          importExcelUrl: "tpmMessageAlarm/tpmMessageAlarm/importExcel",
+          
+        },
+        dictOptions:{},
+        superFieldList:[],
+        deviceOptions: [],
+        deviceOptionsAll: [],
+      }
+    },
+    created() {
+    this.getSuperFieldList();
+    this.getDeviceOption();
+    },
+    computed: {
+      importExcelUrl: function(){
+        return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+      },
+    },
+    methods: {
+      // 获取设备下拉列表
+      getDeviceOption(){
+        getAction(`/tpmEquipment/tpmEquipment/selectEquipmentList`).then(res=>{
+          console.log(111,res.result)
+          this.deviceOptions = res.result.map((res) => {
+            return {
+              id: res.id,
+              equipmentname: res.equipmentname,
+              equipmentcode: res.equipmentcode,
+            }
+          })
+          // 存一个完整的设备表
+          this.deviceOptionsAll = this.deviceOptions
+          // console.log(7878,this.deviceOptionsAll)
+        })
+      },
+      // 筛选设备
+      searchDevice(value) {
+        console.log(1212,value,value.trim().length)
+        // 若输入的值删除,则重新赋完整的设备列表
+        if (value.trim().length === 0) {
+          this.deviceOptions = this.deviceOptionsAll
+        }
+        // 通过判断字符串中是数字还是文字进而判断是通过设备名筛选还是设备编号筛选
+        let panDuan = isNaN(parseFloat(value))
+        if (!panDuan) {
+          // 数字
+          // console.log(777)
+          let filteredArray = this.deviceOptionsAll.filter(item => item.equipmentcode.includes(value));
+          this.deviceOptions = filteredArray
+        } else {
+          // console.log(888)
+          let filteredArray = this.deviceOptionsAll.filter(item => item.equipmentname.includes(value));
+          this.deviceOptions = filteredArray
+        }
+        // console.log(999,this.deviceOptions)
+      },
+      // 解决筛选后option不回显问题
+      filterOptions(input, option) {                    
+        return this.deviceOptions
+      },
+      initDictConfig(){
+      },
+      getSuperFieldList(){
+        let fieldList=[];
+        fieldList.push({type:'string',value:'remark',text:'报警描述'})
+        fieldList.push({type:'string',value:'equipmentid',text:'设备id'})
+        fieldList.push({type:'date',value:'alarmtime',text:'报警时间'})
+        fieldList.push({type:'string',value:'alarmtype',text:'报警类型:0通讯状态,1现场报警,2设备故障,3消防报警,4环境报警,5安全报警'})
+        fieldList.push({type:'string',value:'alarmlevel',text:'报警等级:0普通,1严重,2事故'})
+        fieldList.push({type:'string',value:'msgcode',text:'消息码'})
+        fieldList.push({type:'string',value:'paramcode',text:'参数编号'})
+        fieldList.push({type:'string',value:'paramname',text:'参数名称'})
+        fieldList.push({type:'number',value:'nowvalue',text:'当前值'})
+        fieldList.push({type:'number',value:'vmin',text:'阈值最小值'})
+        fieldList.push({type:'number',value:'vmax',text:'阈值最大值'})
+        fieldList.push({type:'int',value:'status',text:'状态:0 报警,1误报 , 2 处理中,3已处理'})
+        fieldList.push({type:'date',value:'handletime',text:'处理日期'})
+        fieldList.push({type:'string',value:'handleuser',text:'处理人'})
+        fieldList.push({type:'string',value:'handleremark',text:'处理信息'})
+        fieldList.push({type:'string',value:'url',text:'图片地址'})
+        fieldList.push({type:'number',value:'distance',text:'距离(摄像头用)'})
+        fieldList.push({type:'number',value:'position',text:'方位(摄像头用)'})
+        fieldList.push({type:'int',value:'year',text:'所属年'})
+        fieldList.push({type:'int',value:'month',text:'所属月'})
+        fieldList.push({type:'int',value:'week',text:'所属周'})
+        fieldList.push({type:'string',value:'day',text:'日期'})
+        fieldList.push({type:'int',value:'dayofweek',text:'周几'})
+        fieldList.push({type:'string',value:'yearmonth',text:'所属年月'})
+        this.superFieldList = fieldList
+      }
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less';
+  .green{
+    background-color: #E7FAF0 !important;
+    border-color: #D0F5E0 !important;
+    color: #13CE66 !important;
+  }
+  .yellow{
+    background-color: #FFF8E6 !important;
+    border-color: #FFF1CC !important;
+    color: #FFBA00 !important;
+  }
+</style>

+ 888 - 0
src/views/module_tpm/alarmScreen/index.vue

@@ -0,0 +1,888 @@
+<template>
+  <a-card :bordered="false">
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="submit">
+        <a-row :gutter="24">
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="年月">
+              <a-month-picker v-model="queryParams.date1" placeholder="选择年月" style="width:100%;" value-format="yyyy-MM"></a-month-picker>
+            </a-form-item>
+          </a-col>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="submit" icon="search">查询</a-button>
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- <a-form :inline="true" class="demo-form-inline">
+      <a-form-item label="年月">
+        <j-date
+          v-model="queryParams.date1"
+          placeholder="选择年月">
+        </j-date>
+      </a-form-item>
+      <a-form-item>
+        <a-button type="primary" @click="submit">查询</a-button>
+      </a-form-item>
+    </a-form> -->
+    <!-- 报警对比图 -->
+    <div class="area-comp">
+      <!-- 上 -->
+      <div class="left-contianer">
+        <div class="common-container top">
+          <div class="common-title">报警统计</div>
+          <div class="common-box box">
+            <div class="num-box">
+              <div class="num">{{alarmStatistics.month}}</div>
+              <div class="text">当月报警数</div>
+            </div>
+            <div class="num-box">
+              <div class="num">{{alarmStatistics.year}}</div>
+              <div class="text">当年报警数</div>
+            </div>
+          </div>
+        </div>
+        <div class="common-container center">
+          <div class="common-title">信息统计</div>
+          <div class="common-box box">
+            <div class="num-box" v-for="(item, index) in chartinfo.levelStatistics" :key="index">
+              <div class="num">{{item.howManyTimes}}</div>
+              <div class="text">{{item.equipmentname}}</div>
+            </div>
+          </div>
+        </div>
+        <div class="common-container ranking">
+          <div class="common-title">报警排名</div>
+          <div class="common-box2" ref="rankingChart" />
+        </div>
+      </div>
+      <div class="right-container">
+        <div class="top">
+          <div class="common-container top-zhe">
+            <div class="common-title">近两年报警对比图</div>
+            <div class="common-box" ref="duibiChart" />
+          </div>
+          <div class="common-container top-bing">
+            <div class="common-title">报警类型占比</div>
+            <div class="common-box" ref="bingChart" />
+          </div>
+        </div>
+        <div class="common-container bottom">
+          <div class="common-title">报警趋势散点图</div>
+          <div class="common-box" ref="qushiChart" />
+        </div>
+      </div>
+    </div>
+  </a-card>
+</template>
+
+<script>
+import * as echarts from 'echarts';
+import { comp } from '@/api/api'
+import { postAction, getAction } from '@/api/manage'
+
+export default {
+  name: 'alarmScreen',
+  data () {
+    return {
+      // 选择器参数接收
+      options: [],
+      // 返回的图表数据
+      chartinfo: [],
+      year: '',
+      month: '',
+      props: { multiple: true, value: "id", label: "label" },
+      // 查询参数
+      queryParams: {
+        date1: '',
+        list:[]
+      },
+      alarmType: [],
+      alarmTypeNum: [],
+      alarmStatistics: {
+        month: 0,
+        year: 0,
+      },
+    }
+  },
+  created () {
+    this.getYearMonth();
+  },
+  mounted () {
+    // echarts自适应
+    window.addEventListener("resize", () =>{
+      this.myChart1.resize();
+      this.myChart2.resize();
+      this.myChart3.resize();
+      this.myChart4.resize();
+    });
+    this.$nextTick(() => {
+    })
+  },
+  methods: {
+    formatYearMonth(year, month){
+      return `${year.toString().padStart(4, '0')}-${month.toString().padStart(2, '0')}`;
+    },
+    getYearMonth() {
+      const currentYear = new Date().getFullYear();
+      const currentMonth = new Date().getMonth() + 1;
+      const yearMonth = this.formatYearMonth(currentYear, currentMonth);
+      this.queryParams.date1 = yearMonth
+      this.getList();
+      // 第一版
+      // yeamonth().then(response => {
+      //   this.queryParams.date1 = response.msg;
+      //   this.getList();
+      // });
+      // 第二版
+      // getAction(`/alarm/statistics/yeamonth`).then(response=>{
+      //   this.queryParams.date1 = response.msg;
+      //   // this.getList();
+      // })
+    },
+    // 查询
+    submit() {
+      if (this.queryParams.date1.length == 0) {
+        this.$message({
+          message: "请先选择年月",
+          type: "warning",
+        });
+        this.option;
+        return false;
+      }
+      console.log(this.queryParams)
+      this.isShow = false;
+      this.getList();
+    },
+    // 获得数据
+    getList(){
+      this.listLoading = true;
+      const newArr = [1,2];
+      let param = {
+        ids: newArr,
+        yearmonth: this.queryParams.date1
+      };
+      postAction(`/tpmMessageAlarm/tpmMessageAlarm/getalarminfo`,param).then(response=>{
+        console.log(66,response)
+        this.chartinfo = response.result;
+
+        // 报警类型
+        this.alarmType = [];
+        this.alarmTypeNum = [];
+        for (let i in this.chartinfo.alarmType){
+          this.alarmType.push(this.chartinfo.alarmType[i].equipmentname);
+          this.alarmTypeNum.push(0);
+        }
+
+        // 报警统计
+        for (let i in this.chartinfo.alarmStatistics) {
+          if (this.chartinfo.alarmStatistics[i].type == "year") {
+            this.alarmStatistics.year = this.chartinfo.alarmStatistics[i].howManyTimes;
+          }
+          else {
+            this.alarmStatistics.month = this.chartinfo.alarmStatistics[i].howManyTimes;
+          }
+        }
+
+        // 图表展示
+        this.initRankingChart()
+        this.initDuibiChartChart()
+        this.initBingChart()
+        this.intiQushiChart()
+      })
+    },
+    // 报警排名
+    initRankingChart(){
+      this.myChart1 = echarts.init(this.$refs.rankingChart)
+      var option;
+      for (let j in this.alarmType) {
+        for (let i in this.chartinfo.alarmRank) {
+          if (this.alarmType[j] == this.chartinfo.alarmRank[i].equipmentname){
+            this.alarmTypeNum[j] = this.chartinfo.alarmRank[i].howManyTimes;
+          }
+        }
+      }
+      option = {
+        grid: {
+          left: "2%",
+          right: "2%",
+          bottom: "0",
+          top: "2%",
+          containLabel: true,
+        },
+        tooltip: {
+          trigger: "axis",
+          axisPointer: {
+            type: "none",
+          },
+          formatter: function (params) {
+            return (
+              params[0].name +
+              "<br/>" +
+              "<span style='display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:rgba(36,207,233,0.9)'></span>" +
+              params[0].seriesName +
+              " : " + params[0].value +
+              " 次<br/>"
+            );
+          },
+        },
+        xAxis: {
+          show: false,
+          type: "value",
+        },
+        yAxis: [
+          {
+            type: "category",
+            inverse: true,
+            axisLabel: {
+              show: true,
+              textStyle: {
+                color: "#333",
+              },
+            },
+            splitLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            axisLine: {
+              show: false,
+            },
+            data: this.alarmType,
+          },
+          {
+            type: "category",
+            inverse: true,
+            axisTick: "none",
+            axisLine: "none",
+            show: true,
+            axisLabel: {
+              textStyle: {
+                color: "#333",
+                fontSize: "12",
+              },
+              formatter: function (value) {
+                  return (value).toLocaleString() + "次";
+              },
+            },
+            data: this.alarmTypeNum,
+          },
+        ],
+        series: [
+          {
+            name: "报警",
+            type: "bar",
+            zlevel: 1,
+            itemStyle: {
+              normal: {
+                barBorderRadius: 30,
+                color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
+                  {
+                    offset: 0,
+                    color: "rgb(92,141,253,1)",
+                    // color: "rgb(57,89,255,1)",
+                  },
+                  {
+                    offset: 1,
+                    color: "rgb(50,189,209,1)",
+                    // color: "rgb(46,200,207,1)",
+                  },
+                ]),
+              },
+            },
+            barWidth: 20,
+            data: this.alarmTypeNum,
+          },
+          {
+            name: "背景",
+            type: "bar",
+            barWidth: 20,
+            barGap: "-100%",
+            // data: [50, 50, 50, 50, 50, 50, 50, 50, 50, 50],
+            itemStyle: {
+              normal: {
+                color: "#eee",
+                barBorderRadius: 30,
+              },
+            },
+          },
+        ],
+      };
+      option && this.myChart1.setOption(option);
+    },
+    // 近两年报警对比图
+    initDuibiChartChart(){
+      this.myChart2 = echarts.init(this.$refs.duibiChart)
+      var option;
+
+      // Generate data
+      var lastData =[];
+      var nowData = [];
+      var allData = [];
+      for (let j in this.alarmType) {
+        lastData.push(0)
+        nowData.push(0)
+        allData.push(0)
+        for (let i in this.chartinfo.alarmTwoYear) {
+          if (this.chartinfo.alarmTwoYear[i].type == "lastyear" &&
+            this.chartinfo.alarmTwoYear[i].equipmentname == this.alarmType[j]) {
+            lastData[j] = this.chartinfo.alarmTwoYear[i].howManyTimes;
+          }
+          else if (this.chartinfo.alarmTwoYear[i].type == "thisyear" &&
+            this.chartinfo.alarmTwoYear[i].equipmentname == this.alarmType[j]) {
+            nowData[j] = this.chartinfo.alarmTwoYear[i].howManyTimes;
+          }
+          else if (this.chartinfo.alarmTwoYear[i].type == "all" &&
+            this.chartinfo.alarmTwoYear[i].equipmentname == this.alarmType[j]) {
+            allData[j] = this.chartinfo.alarmTwoYear[i].howManyTimes;
+          }
+        }
+      }
+      // option
+      option = {
+        tooltip: {
+          trigger: "axis",
+          axisPointer: {
+            type: "shadow",
+            textStyle: {
+              color: "#fff",
+            },
+          },
+        },
+        grid: {
+          left: "6%",
+          right: "6%",
+          bottom: "2%",
+          top: "25%",
+          containLabel: true,
+        },
+        legend: {
+          data: ["去年", "今年", "总量"],
+          textStyle: {
+            color: "#B4B4B4",
+          },
+          top: "7%",
+        },
+        xAxis: {
+          data: this.alarmType,
+          axisLine: {
+            lineStyle: {
+              color: "#B4B4B4",
+            },
+          },
+          axisTick: {
+            show: false,
+          },
+        },
+        yAxis: [
+          {
+            splitLine: { show: false },
+            axisLine: {
+              lineStyle: {
+                color: "#B4B4B4",
+              },
+            },
+            axisLabel: {
+              formatter: "{value} ",
+            },
+          }
+        ],
+
+        series: [
+          {
+            name: "总量",
+            type: "line",
+            smooth: true,
+            // showAllSymbol: true,
+            // symbol: "emptyCircle",
+            symbolSize: 8,
+            // itemStyle: {
+            //   normal: {
+            //     color: "#2EC6D0",
+            //   },
+            // },
+
+            // showAllSymbol: true,
+            symbol: "emptyCircle",
+            symbolSize: 6,
+            lineStyle: {
+              normal: {
+                color: "#8FB3F3", // 线条颜色
+              },
+              borderColor: "#f0f",
+            },
+            label: {
+              show: true,
+              position: "top",
+              textStyle: {
+                color: "#fff",
+              },
+            },
+            itemStyle: {
+              normal: {
+                color: "#8FB3F3",
+              },
+            },
+            tooltip: {
+              show: false,
+            },
+            areaStyle: {
+              //区域填充样式
+              normal: {
+                //线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。
+                color: new echarts.graphic.LinearGradient(
+                  0,
+                  0,
+                  0,
+                  1,
+                  [
+                    {
+                      offset: 0,
+                      color: "rgba(192,208,248,0.3)",
+                    },
+                    {
+                      offset: 1,
+                      color: "rgba(163,186,229, .1)",
+                    },
+                  ],
+                  false
+                ),
+                shadowColor: "rgba(220,226,255,.9)", //阴影颜色
+                shadowBlur: 20, //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
+              },
+            },
+
+            data: allData,
+          },
+
+          {
+            name: "今年",
+            type: "bar",
+            barWidth: 20,
+            itemStyle: {
+              normal: {
+                // barBorderRadius: 10,
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  { offset: 0, color: "rgb(97,114,237)" },
+                  { offset: 1, color: "rgb(143,210,252)" },
+                ]),
+              },
+            },
+            data: nowData,
+          },
+
+          {
+            name: "去年",
+            type: "bar",
+            barGap: "-100%",
+            barWidth: 20,
+            itemStyle: {
+              normal: {
+                // barBorderRadius: 10,
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  { offset: 0, color: "rgba(199,207,253,0.7)" },
+                  { offset: 0.2, color: "rgba(199,207,253,0.5)" },
+                  { offset: 1, color: "rgba(199,207,253,0.2)" },
+                ]),
+              },
+            },
+            z: -12,
+
+            data: lastData,
+          },
+        ],
+      };
+
+
+      option && this.myChart2.setOption(option);
+    },
+    // 报警类型占比
+    initBingChart(){
+      this.myChart3 = echarts.init(this.$refs.bingChart)
+      var option;
+
+      var m2R2Data = [];
+      var allnum = 0;
+      for (let i in this.chartinfo.typeRatio) {
+        allnum += this.chartinfo.typeRatio[i].howManyTimes;
+        m2R2Data.push({
+          value: this.chartinfo.typeRatio[i].howManyTimes,
+          legendname: this.chartinfo.typeRatio[i].equipmentname,
+          name: this.chartinfo.typeRatio[i].equipmentname,
+          // itemStyle: { color: "#8d7fec" },
+        });
+      }
+
+      option = {
+        title: [
+          {
+            text: "合计",
+            subtext: allnum + "个",
+            textStyle: {
+              fontSize: 16,
+              color: "#bbb",
+            },
+            subtextStyle: {
+              fontSize: 12,
+              color: "#333",
+            },
+            textAlign: "center",
+            x: "34.5%",
+            y: "44%",
+          },
+        ],
+        tooltip: {
+          trigger: "item",
+          formatter: function (parms) {
+            var str =
+              parms.seriesName +
+              "</br>" +
+              parms.marker +
+              "" +
+              parms.data.legendname +
+              "</br>" +
+              "数量:" +
+              parms.data.value +
+              "</br>" +
+              "占比:" +
+              parms.percent +
+              "%";
+            return str;
+          },
+        },
+        legend: {
+          type: "scroll",
+          orient: "vertical",
+          left: "70%",
+          align: "left",
+          top: "middle",
+          textStyle: {
+            color: "#8C8C8C",
+          },
+          height: 150,
+        },
+        series: [
+          {
+            name: "标题",
+            type: "pie",
+            center: ["35%", "50%"],
+            radius: ["40%", "65%"],
+            clockwise: false, //饼图的扇区是否是顺时针排布
+            avoidLabelOverlap: false,
+            label: {
+              normal: {
+                show: true,
+                position: "outter",
+                formatter: function (parms) {
+                  return parms.data.legendname;
+                },
+              },
+            },
+            labelLine: {
+              normal: {
+                length: 10,
+                length2: 30,
+                smooth: true,
+              },
+            },
+            data: m2R2Data,
+          },
+        ],
+      };
+
+
+      option && this.myChart3.setOption(option);
+    },
+    // 获取最后一天
+    getLastDay(year,month){
+      var new_year = year;
+      var new_month = month++;//取下一个月的第一天,方便计算(最后一天不固定)
+      if(month>12){//如果当前大于12月,则年份转到下一年
+          new_month -=12;//月份减
+          new_year++;//年份增
+      }
+      // 取当年当月对应的下个月的前一天,即当前月的最后一天
+      var last_date = new Date(new_year,new_month,0).getDate();
+      return last_date;
+    },
+    // 日期加/减几天
+    getNewDayAdd(dateTemp, day) {
+      dateTemp=new Date(dateTemp);
+      dateTemp=+dateTemp +1000*60*60*24*day;
+      dateTemp=new Date(dateTemp);
+      return dateTemp.getFullYear()+"-"+(dateTemp.getMonth()+1)+"-"+dateTemp.getDate();
+    },
+    // 获取起止日期之间的所有日期
+    getdifflist(){
+      var resultTime = [];     // dateArray 起止日期中间的所有日期列表
+      // 必须减几天啊,不然第一天的显示不出来
+      var start = new Date(this.getNewDayAdd(this.queryParams.date1 + "-01", -1));    //起止日期
+      var year = parseInt(this.queryParams.date1.substring(0, 4));
+      var month = parseInt(this.queryParams.date1.substring(5,7));
+      var endday = this.getLastDay(year, month);
+      // 必须加几天啊,不然最后一天的显示不出来
+      var end = new Date(this.getNewDayAdd(this.queryParams.date1 + "-" + endday, 1));       //截止日期
+      //开始日期小于等于结束日期,并循环
+      // 当 开始时间小于结束时间的时候进入循环
+      while (start <= end) {
+        let getDay = start.getDate()
+        // 月份需要加 1
+        let getMonth = start.getMonth() + 1
+        let getYear = start.getFullYear()
+        /**
+         * 拼接时间格式
+         * (getMonth >= 10 ? `${getMonth}` : `0${getMonth}`) 自动给 小于10的时间前面补0
+         */
+        let setTime =
+            `${getYear}-` +
+            (getMonth >= 10 ? `${getMonth}` : `0${getMonth}`) +
+            '-' +
+            (getDay >= 10 ? `${getDay}` : `0${getDay}`)
+
+        resultTime.push(setTime)
+        /**
+         * 重新设置开始时间
+         * 使用 setFullYear() 方法会自动将时间累加,返回的是时间戳格式
+         * 使用 new Date() 将时间重新设置为标准时间
+         * getMonth - 1 将月份时间重新还原
+         */
+        start = new Date(start.setFullYear(getYear, getMonth - 1, getDay + 1))
+      }
+      return resultTime;
+    },
+    // 报警趋势散点图
+    intiQushiChart(){
+      this.myChart4 = echarts.init(this.$refs.qushiChart)
+      var option;
+
+      const schema = [
+        { name: 'date', index: 2, text: '日' },
+        { name: 'num', index: 1, text: '报警数量' }
+      ];
+      const itemStyle = {
+        opacity: 0.8,
+        shadowBlur: 10,
+        shadowOffsetX: 0,
+        shadowOffsetY: 0,
+        shadowColor: 'rgba(0,0,0,0.3)'
+      };
+
+      var dates = this.getdifflist();
+      var series1 = []
+      for (let i in this.alarmType) {
+        var data1 = [];
+        var cycle1 = 0;
+        for (let t in dates) {
+          data1.push([cycle1 + 1, 0, dates[t]]);
+
+          for (let v in this.chartinfo.alarmScatter) {
+            if (this.chartinfo.alarmScatter[v].equipmentname == this.alarmType[i] &&
+              this.chartinfo.alarmScatter[v].day == dates[t]) {
+              data1[cycle1] = [cycle1 + 1, this.chartinfo.alarmScatter[v].howManyTimes, dates[t]];
+            }
+          }
+          cycle1++;
+        }
+        series1.push({
+          name: this.alarmType[i],
+          type: 'scatter',
+          symbolSize: function (val) { // 原来根据数据来确定气泡大小,改成除了数量为0气泡大小为0,其它都是30的大小
+            return val[1] == 0 ? 0 :20;
+          },
+          itemStyle: itemStyle,
+          // symbolSize: function(value) {
+          //   return value / 10;
+          // },
+          data: data1
+        });
+      }
+      option = {
+        // color: ['#638FF5', '#3FAEDF', '#DBE0FE'],
+        legend: {
+          top: 10,
+          data: this.alarmType,
+          textStyle: {
+            fontSize: 16
+          }
+        },
+        grid: {
+          left: '10%',
+          right: 150,
+          top: '20%',
+          bottom: '10%'
+        },
+        tooltip: {
+          formatter: function (param) {
+            var value = param.value;
+            // prettier-ignore
+            return '<div style="border-bottom: 1px solid rgba(255,255,255,.3); font-size: 18px;padding-bottom: 7px;margin-bottom: 7px">'
+                      + param.seriesName + ' ' + value[2]
+                      + '</div>'
+                      + schema[1].text + ':' + value[1] + '<br>';
+          }
+        },
+        dataZoom: [
+          {
+            type: 'inside',
+            start: 0,
+            end: 100
+          }
+        ],
+        xAxis: {
+          type: 'category',
+          boundaryGap: false,
+          data: dates
+        },
+        yAxis: {
+          type: 'value',
+          name: '报警数量',
+          nameLocation: 'end',
+          nameGap: 20,
+          nameTextStyle: {
+            fontSize: 16
+          },
+          splitLine: {
+            show: false
+          }
+        },
+        // visualMap: [
+        //   {
+        //     left: 'right',
+        //     top: '10%',
+        //     dimension: 2,
+        //     min: 0,
+        //     max: 500,
+        //     itemWidth: 30,
+        //     itemHeight: 120,
+        //     calculable: true,
+        //     precision: 0.1,
+        //     text: ['报警数量'],
+        //     textGap: 30,
+        //     inRange: {
+        //       // symbolSize: [5, 50]
+        //     },
+        //     outOfRange: {
+        //       // symbolSize: [5, 50],
+        //       color: ['rgba(255,255,255,0.4)']
+        //     },
+        //     controller: {
+        //       inRange: {
+        //         color: ['#5085F2']
+        //       },
+        //       outOfRange: {
+        //         color: ['#999']
+        //       }
+        //     }
+        //   },
+        // ],
+        series: series1
+      };
+
+      option && this.myChart4.setOption(option,true);
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.common-container{
+  background-color: #fff;
+  border-radius: 4px;
+  box-shadow: 0 4px 12px rgba(62, 90, 119, 0.2);
+  padding: 13px 20px;
+  .common-title{
+    border-bottom: 1px solid #ccc;
+    padding: 10px;
+  }
+  .common-box{
+    width: 100%;
+    height: calc(100% - 40px);
+  }
+  .common-box2{
+    width: 100%;
+    height: calc(100% - 129.5px);
+  }
+}
+.area-comp{
+  height: calc(100vh - 84px);
+  background-color: #F0F7FD;
+  // overflow: auto;
+  padding: 14px 20px;
+  display: flex;
+  justify-content: space-between;
+  .left-contianer{
+    // height: 500px;
+    width: 320px;
+    // flex: 2.2;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+    .top{
+      background-image: linear-gradient(150deg, #5EB3F7, #6680F4);
+      color: #fff;
+    }
+    .box{
+      display: flex;
+      justify-content: space-around;
+    }
+    .num-box{
+      padding: 10px 8px;
+      text-align: center;
+      .num{
+        font-weight: bolder;
+        font-size: 24px;
+
+      }
+      .text{
+        margin-top: 12px;
+        font-size: 14px;
+      }
+    }
+    .center{
+      margin-top: 12px;
+      .num-box{
+        padding: 10px 0 10px 0;
+      }
+      .num{
+        background-image: linear-gradient(150deg, #5EB3F7, #6680F4);
+        background-clip:text;
+        -webkit-background-clip:text;
+        color: transparent;
+      }
+    }
+    .ranking{
+      flex: 1;
+      width: 100%;
+      // height: 500px;
+      margin-top: 10px;
+      box-sizing: border-box;
+    }
+  }
+  .right-container{
+    flex: 1;
+    margin-left: 12px;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+    .top{
+      flex: 1;
+      display: flex;
+      justify-content: space-between;
+      .top-bing{
+        flex: 1;
+        margin-left: 12px;
+      }
+      .top-zhe{
+        flex: 2;
+      }
+    }
+    .bottom{
+      flex: 1.6;
+      margin-top: 12px;
+    }
+  }
+}
+</style>

+ 427 - 0
src/views/module_tpm/messageAlarm/MessageAlarmList.vue

@@ -0,0 +1,427 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+          <a-col :xl="10" :lg="7" :md="8" :sm="24">
+            <a-form-item label="设备名称">
+              <a-select
+              v-model="queryParam.equipmentid"
+              placeholder="请输入设备名称或设备编号"
+              show-search
+              :filterOption="filterOptions"
+              @search="searchDevice"
+              allowClear>
+              <a-select-option v-for="(item, index) in deviceOptions" :key="index" :value="item.id" :label="item.equipmentname">
+                <span>{{item.equipmentname}}</span>
+                <span style="position: absolute;right: 2%;">{{ item.equipmentcode }}</span>
+              </a-select-option>
+              </a-select>
+            </a-form-item>
+          </a-col>
+          <template v-if="toggleSearchStatus">
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="报警日期">
+                <j-date v-model="queryParam.alarmtime" placeholder="请选择报警日期" style="width:100%;"></j-date>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="报警等级">
+                <j-dict-select-tag v-model="queryParam.alarmlevel" placeholder="请选择报警等级" dictCode="alarm_level"/>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="报警类型">
+                <j-dict-select-tag v-model="queryParam.alarmtype" placeholder="请选择报警类型" dictCode="alarm_type"/>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="处理状态">
+                <j-dict-select-tag v-model="queryParam.status" placeholder="请选择处理状态" dictCode="alarm_status"/>
+              </a-form-item>
+            </a-col>
+          </template>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+              <a @click="handleToggleSearch" style="margin-left: 8px">
+                {{ toggleSearchStatus ? '收起' : '展开' }}
+                <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
+              </a>
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 查询区域-END -->
+
+    <!-- 操作按钮区域 -->
+    <!-- <div class="table-operator">
+      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+      <a-button type="primary" icon="download" @click="handleExportXls('tpm_message_alarm')">导出</a-button>
+      <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
+        <a-button type="primary" icon="import">导入</a-button>
+      </a-upload> -->
+      <!-- 高级查询区域 -->
+      <!-- <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
+      <a-dropdown v-if="selectedRowKeys.length > 0">
+        <a-menu slot="overlay">
+          <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
+        </a-menu>
+        <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
+      </a-dropdown>
+    </div> -->
+
+    <!-- table区域-begin -->
+    <div>
+      <!-- <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+      </div> -->
+
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{x:true}"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        class="j-table-force-nowrap"
+        @change="handleTableChange">
+
+        <template slot="status_dictText" slot-scope="text,record">
+          <!-- <span v-if="text">{{record.status_dictText}}</span> -->
+          <a-button type="dashed" v-if="record.status == 0" size="small">{{record.status_dictText}}</a-button>
+          <!-- 处理中 -->
+          <a-button v-if="record.status == 1" class="yellow" size="small">{{record.status_dictText}}</a-button>
+          <!-- 已处理 -->
+          <a-button v-if="record.status == 2" class="green" size="small">{{record.status_dictText}}</a-button>
+        </template>
+
+        <template slot="htmlSlot" slot-scope="text">
+          <div v-html="text"></div>
+        </template>
+        <template slot="imgSlot" slot-scope="text,record">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
+          <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
+        </template>
+        <template slot="fileSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
+          <a-button
+            v-else
+            :ghost="true"
+            type="primary"
+            icon="download"
+            size="small"
+            @click="downloadFile(text)">
+            下载
+          </a-button>
+        </template>
+
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">处理</a>
+
+          <!-- <a-divider type="vertical" />
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a @click="handleDetail(record)">详情</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown> -->
+        </span>
+
+      </a-table>
+    </div>
+
+    <message-alarm-modal ref="modalForm" @ok="modalFormOk"></message-alarm-modal>
+  </a-card>
+</template>
+
+<script>
+
+  import '@/assets/less/TableExpand.less'
+  import { mixinDevice } from '@/utils/mixin'
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import { httpAction, getAction } from '@/api/manage'
+  import MessageAlarmModal from './modules/MessageAlarmModal'
+
+  export default {
+    name: 'MessageAlarmList',
+    mixins:[JeecgListMixin, mixinDevice],
+    components: {
+      MessageAlarmModal
+    },
+    data () {
+      return {
+        description: 'tpm_message_alarm管理页面',
+        // 表头
+        columns: [
+          {
+            title: '序号',
+            dataIndex: '',
+            key:'rowIndex',
+            width:60,
+            align:"center",
+            customRender:function (t,r,index) {
+              return parseInt(index)+1;
+            }
+          },
+          {
+            title:'设备',
+            align:"center",
+            dataIndex: 'equipmentid_dictText'
+          },
+          {
+            title:'报警类型',
+            align:"center",
+            dataIndex: 'alarmtype_dictText'
+          },
+          {
+            title:'报警描述',
+            align:"center",
+            dataIndex: 'remark'
+          },
+          {
+            title:'报警时间',
+            align:"center",
+            dataIndex: 'alarmtime',
+            // customRender:function (text) {
+            //   return !text?"":(text.length>10?text.substr(0,10):text)
+            // }
+          },
+          {
+            title:'报警等级',
+            align:"center",
+            dataIndex: 'alarmlevel_dictText'
+          },
+          // {
+          //   title:'消息码',
+          //   align:"center",
+          //   dataIndex: 'msgcode'
+          // },
+          // {
+          //   title:'参数编号',
+          //   align:"center",
+          //   dataIndex: 'paramcode'
+          // },
+          // {
+          //   title:'参数名称',
+          //   align:"center",
+          //   dataIndex: 'paramname'
+          // },
+          {
+            title:'当前值',
+            align:"center",
+            dataIndex: 'nowvalue'
+          },
+          {
+            title:'阈值最小值',
+            align:"center",
+            dataIndex: 'vmin'
+          },
+          {
+            title:'阈值最大值',
+            align:"center",
+            dataIndex: 'vmax'
+          },
+          {
+            title:'处理状态',
+            align:"center",
+            dataIndex: 'status_dictText',
+            scopedSlots: { customRender: 'status_dictText' }
+          },
+          // {
+          //   title:'处理日期',
+          //   align:"center",
+          //   dataIndex: 'handletime',
+          //   customRender:function (text) {
+          //     return !text?"":(text.length>10?text.substr(0,10):text)
+          //   }
+          // },
+          // {
+          //   title:'处理人',
+          //   align:"center",
+          //   dataIndex: 'handleuser'
+          // },
+          // {
+          //   title:'处理信息',
+          //   align:"center",
+          //   dataIndex: 'handleremark'
+          // },
+          // {
+          //   title:'图片地址',
+          //   align:"center",
+          //   dataIndex: 'url'
+          // },
+          // {
+          //   title:'距离(摄像头用)',
+          //   align:"center",
+          //   dataIndex: 'distance'
+          // },
+          // {
+          //   title:'方位(摄像头用)',
+          //   align:"center",
+          //   dataIndex: 'position'
+          // },
+          // {
+          //   title:'所属年',
+          //   align:"center",
+          //   dataIndex: 'year'
+          // },
+          // {
+          //   title:'所属月',
+          //   align:"center",
+          //   dataIndex: 'month'
+          // },
+          // {
+          //   title:'所属周',
+          //   align:"center",
+          //   dataIndex: 'week'
+          // },
+          // {
+          //   title:'日期',
+          //   align:"center",
+          //   dataIndex: 'day'
+          // },
+          // {
+          //   title:'周几',
+          //   align:"center",
+          //   dataIndex: 'dayofweek'
+          // },
+          // {
+          //   title:'所属年月',
+          //   align:"center",
+          //   dataIndex: 'yearmonth'
+          // },
+          {
+            title: '操作',
+            dataIndex: 'action',
+            align:"center",
+            fixed:"right",
+            width:147,
+            scopedSlots: { customRender: 'action' }
+          }
+        ],
+        url: {
+          list: "/tpmMessageAlarm/tpmMessageAlarm/list",
+          delete: "/tpmMessageAlarm/tpmMessageAlarm/delete",
+          deleteBatch: "/tpmMessageAlarm/tpmMessageAlarm/deleteBatch",
+          exportXlsUrl: "/tpmMessageAlarm/tpmMessageAlarm/exportXls",
+          importExcelUrl: "tpmMessageAlarm/tpmMessageAlarm/importExcel",
+          
+        },
+        dictOptions:{},
+        superFieldList:[],
+        deviceOptions: [],
+        deviceOptionsAll: [],
+      }
+    },
+    created() {
+    this.getSuperFieldList();
+    this.getDeviceOption();
+    },
+    computed: {
+      importExcelUrl: function(){
+        return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+      },
+    },
+    methods: {
+      // 获取设备下拉列表
+      getDeviceOption(){
+        getAction(`/tpmEquipment/tpmEquipment/selectEquipmentList`).then(res=>{
+          console.log(111,res.result)
+          this.deviceOptions = res.result.map((res) => {
+            return {
+              id: res.id,
+              equipmentname: res.equipmentname,
+              equipmentcode: res.equipmentcode,
+            }
+          })
+          // 存一个完整的设备表
+          this.deviceOptionsAll = this.deviceOptions
+          // console.log(7878,this.deviceOptionsAll)
+        })
+      },
+      // 筛选设备
+      searchDevice(value) {
+        console.log(1212,value,value.trim().length)
+        // 若输入的值删除,则重新赋完整的设备列表
+        if (value.trim().length === 0) {
+          this.deviceOptions = this.deviceOptionsAll
+        }
+        // 通过判断字符串中是数字还是文字进而判断是通过设备名筛选还是设备编号筛选
+        let panDuan = isNaN(parseFloat(value))
+        if (!panDuan) {
+          // 数字
+          // console.log(777)
+          let filteredArray = this.deviceOptionsAll.filter(item => item.equipmentcode.includes(value));
+          this.deviceOptions = filteredArray
+        } else {
+          // console.log(888)
+          let filteredArray = this.deviceOptionsAll.filter(item => item.equipmentname.includes(value));
+          this.deviceOptions = filteredArray
+        }
+        // console.log(999,this.deviceOptions)
+      },
+      // 解决筛选后option不回显问题
+      filterOptions(input, option) {                    
+        return this.deviceOptions
+      },
+      initDictConfig(){
+      },
+      getSuperFieldList(){
+        let fieldList=[];
+        fieldList.push({type:'string',value:'remark',text:'报警描述'})
+        fieldList.push({type:'string',value:'equipmentid',text:'设备id'})
+        fieldList.push({type:'date',value:'alarmtime',text:'报警时间'})
+        fieldList.push({type:'string',value:'alarmtype',text:'报警类型:0通讯状态,1现场报警,2设备故障,3消防报警,4环境报警,5安全报警'})
+        fieldList.push({type:'string',value:'alarmlevel',text:'报警等级:0普通,1严重,2事故'})
+        fieldList.push({type:'string',value:'msgcode',text:'消息码'})
+        fieldList.push({type:'string',value:'paramcode',text:'参数编号'})
+        fieldList.push({type:'string',value:'paramname',text:'参数名称'})
+        fieldList.push({type:'number',value:'nowvalue',text:'当前值'})
+        fieldList.push({type:'number',value:'vmin',text:'阈值最小值'})
+        fieldList.push({type:'number',value:'vmax',text:'阈值最大值'})
+        fieldList.push({type:'int',value:'status',text:'状态:0 报警,1误报 , 2 处理中,3已处理'})
+        fieldList.push({type:'date',value:'handletime',text:'处理日期'})
+        fieldList.push({type:'string',value:'handleuser',text:'处理人'})
+        fieldList.push({type:'string',value:'handleremark',text:'处理信息'})
+        fieldList.push({type:'string',value:'url',text:'图片地址'})
+        fieldList.push({type:'number',value:'distance',text:'距离(摄像头用)'})
+        fieldList.push({type:'number',value:'position',text:'方位(摄像头用)'})
+        fieldList.push({type:'int',value:'year',text:'所属年'})
+        fieldList.push({type:'int',value:'month',text:'所属月'})
+        fieldList.push({type:'int',value:'week',text:'所属周'})
+        fieldList.push({type:'string',value:'day',text:'日期'})
+        fieldList.push({type:'int',value:'dayofweek',text:'周几'})
+        fieldList.push({type:'string',value:'yearmonth',text:'所属年月'})
+        this.superFieldList = fieldList
+      }
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less';
+  .green{
+    background-color: #E7FAF0 !important;
+    border-color: #D0F5E0 !important;
+    color: #13CE66 !important;
+  }
+  .yellow{
+    background-color: #FFF8E6 !important;
+    border-color: #FFF1CC !important;
+    color: #FFBA00 !important;
+  }
+</style>

+ 233 - 0
src/views/module_tpm/messageAlarm/modules/MessageAlarmForm.vue

@@ -0,0 +1,233 @@
+<template>
+  <a-spin :spinning="confirmLoading">
+    <j-form-container :disabled="formDisabled">
+      <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
+        <a-row>
+          <a-col :span="24">
+            <a-form-model-item label="报警描述" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="remark">
+              <a-input v-model="model.remark" placeholder="请输入备注" disabled ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <!-- <a-col :span="24">
+            <a-form-model-item label="设备id" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="equipmentid">
+              <a-input v-model="model.equipmentid" placeholder="请输入设备id"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="报警时间" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="alarmtime">
+              <j-date placeholder="请选择报警时间" v-model="model.alarmtime"  style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="报警类型:0通讯状态,1现场报警,2设备故障,3消防报警,4环境报警,5安全报警" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="alarmtype">
+              <a-input v-model="model.alarmtype" placeholder="请输入报警类型:0通讯状态,1现场报警,2设备故障,3消防报警,4环境报警,5安全报警"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="报警等级:0普通,1严重,2事故" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="alarmlevel">
+              <a-input v-model="model.alarmlevel" placeholder="请输入报警等级:0普通,1严重,2事故"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="消息码" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="msgcode">
+              <a-input v-model="model.msgcode" placeholder="请输入消息码"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="参数编号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="paramcode">
+              <a-input v-model="model.paramcode" placeholder="请输入参数编号"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="参数名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="paramname">
+              <a-input v-model="model.paramname" placeholder="请输入参数名称"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="当前值" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="nowvalue">
+              <a-input-number v-model="model.nowvalue" placeholder="请输入当前值" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="阈值最小值" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="vmin">
+              <a-input-number v-model="model.vmin" placeholder="请输入阈值最小值" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="阈值最大值" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="vmax">
+              <a-input-number v-model="model.vmax" placeholder="请输入阈值最大值" style="width: 100%" />
+            </a-form-model-item>
+          </a-col> -->
+          <a-col :span="24">
+            <a-form-model-item label="处理人" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="handleuser">
+              <j-dict-select-tag v-model="model.handleuser" placeholder="请选择处理人" dictCode="sys_user,realname,id"/>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="处理日期" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="handletime">
+              <j-date placeholder="请选择处理日期" showTime dateFormat="YYYY-MM-DD HH:mm:ss" v-model="model.handletime"  style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="处理状态" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="status">
+              <!-- <a-input-number v-model="model.status" placeholder="请输入状态:0待处理,1处理中,2已处理" style="width: 100%" /> -->
+              <a-radio-group v-model="model.status">
+                <a-radio :value="1">
+                  处理中
+                </a-radio>
+                <a-radio :value="2">
+                  已处理
+                </a-radio>
+              </a-radio-group>
+            </a-form-model-item>
+          </a-col> 
+          <a-col :span="24">
+            <a-form-model-item label="处理信息" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="handleremark">
+              <a-textarea v-model="model.handleremark" placeholder="请输入处理信息" :auto-size="{ minRows: 2, maxRows: 3 }"></a-textarea>
+            </a-form-model-item>
+          </a-col>
+          <!-- <a-col :span="24">
+            <a-form-model-item label="图片地址" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="url">
+              <a-input v-model="model.url" placeholder="请输入图片地址"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="距离(摄像头用)" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="distance">
+              <a-input-number v-model="model.distance" placeholder="请输入距离(摄像头用)" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="方位(摄像头用)" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="position">
+              <a-input-number v-model="model.position" placeholder="请输入方位(摄像头用)" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="所属年" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="year">
+              <a-input-number v-model="model.year" placeholder="请输入所属年" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="所属月" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="month">
+              <a-input-number v-model="model.month" placeholder="请输入所属月" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="所属周" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="week">
+              <a-input-number v-model="model.week" placeholder="请输入所属周" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="日期" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="day">
+              <a-input v-model="model.day" placeholder="请输入日期"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="周几" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="dayofweek">
+              <a-input-number v-model="model.dayofweek" placeholder="请输入周几" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="所属年月" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="yearmonth">
+              <a-input v-model="model.yearmonth" placeholder="请输入所属年月"  ></a-input>
+            </a-form-model-item>
+          </a-col> -->
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+  </a-spin>
+</template>
+
+<script>
+
+  import { httpAction, getAction } from '@/api/manage'
+  import { validateDuplicateValue } from '@/utils/util'
+
+  export default {
+    name: 'MessageAlarmForm',
+    components: {
+    },
+    props: {
+      //表单禁用
+      disabled: {
+        type: Boolean,
+        default: false,
+        required: false
+      }
+    },
+    data () {
+      return {
+        model:{
+         },
+        labelCol: {
+          xs: { span: 24 },
+          sm: { span: 5 },
+        },
+        wrapperCol: {
+          xs: { span: 24 },
+          sm: { span: 16 },
+        },
+        confirmLoading: false,
+        validatorRules: {
+           equipmentid: [
+              { required: true, message: '请输入设备id!'},
+           ],
+           alarmtime: [
+              { required: true, message: '请输入报警时间!'},
+           ],
+        },
+        url: {
+          add: "/tpmMessageAlarm/tpmMessageAlarm/add",
+          edit: "/tpmMessageAlarm/tpmMessageAlarm/edit",
+          queryById: "/tpmMessageAlarm/tpmMessageAlarm/queryById"
+        }
+      }
+    },
+    computed: {
+      formDisabled(){
+        return this.disabled
+      },
+    },
+    created () {
+       //备份model原始值
+      this.modelDefault = JSON.parse(JSON.stringify(this.model));
+    },
+    methods: {
+      add () {
+        this.edit(this.modelDefault);
+      },
+      edit (record) {
+        this.model = Object.assign({}, record);
+        this.visible = true;
+      },
+      submitForm () {
+        const that = this;
+        // 触发表单验证
+        this.$refs.form.validate(valid => {
+          if (valid) {
+            that.confirmLoading = true;
+            let httpurl = '';
+            let method = '';
+            if(!this.model.id){
+              httpurl+=this.url.add;
+              method = 'post';
+            }else{
+              httpurl+=this.url.edit;
+               method = 'put';
+            }
+            httpAction(httpurl,this.model,method).then((res)=>{
+              if(res.success){
+                that.$message.success(res.message);
+                that.$emit('ok');
+              }else{
+                that.$message.warning(res.message);
+              }
+            }).finally(() => {
+              that.confirmLoading = false;
+            })
+          }
+         
+        })
+      },
+    }
+  }
+</script>

+ 84 - 0
src/views/module_tpm/messageAlarm/modules/MessageAlarmModal.Style#Drawer.vue

@@ -0,0 +1,84 @@
+<template>
+  <a-drawer
+    :title="title"
+    :width="width"
+    placement="right"
+    :closable="false"
+    @close="close"
+    destroyOnClose
+    :visible="visible">
+    <message-alarm-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit" normal></message-alarm-form>
+    <div class="drawer-footer">
+      <a-button @click="handleCancel" style="margin-bottom: 0;">关闭</a-button>
+      <a-button v-if="!disableSubmit"  @click="handleOk" type="primary" style="margin-bottom: 0;">提交</a-button>
+    </div>
+  </a-drawer>
+</template>
+
+<script>
+
+  import MessageAlarmForm from './MessageAlarmForm'
+
+  export default {
+    name: 'MessageAlarmModal',
+    components: {
+      MessageAlarmForm
+    },
+    data () {
+      return {
+        title:"操作",
+        width:800,
+        visible: false,
+        disableSubmit: false
+      }
+    },
+    methods: {
+      add () {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.add();
+        })
+      },
+      edit (record) {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.edit(record);
+        });
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+      },
+      submitCallback(){
+        this.$emit('ok');
+        this.visible = false;
+      },
+      handleOk () {
+        this.$refs.realForm.submitForm();
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>
+
+<style lang="less" scoped>
+/** Button按钮间距 */
+  .ant-btn {
+    margin-left: 30px;
+    margin-bottom: 30px;
+    float: right;
+  }
+  .drawer-footer{
+    position: absolute;
+    bottom: -8px;
+    width: 100%;
+    border-top: 1px solid #e8e8e8;
+    padding: 10px 16px;
+    text-align: right;
+    left: 0;
+    background: #fff;
+    border-radius: 0 0 2px 2px;
+  }
+</style>

+ 60 - 0
src/views/module_tpm/messageAlarm/modules/MessageAlarmModal.vue

@@ -0,0 +1,60 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <message-alarm-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></message-alarm-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import MessageAlarmForm from './MessageAlarmForm'
+  export default {
+    name: 'MessageAlarmModal',
+    components: {
+      MessageAlarmForm
+    },
+    data () {
+      return {
+        title:'',
+        width:800,
+        visible: false,
+        disableSubmit: false
+      }
+    },
+    methods: {
+      add () {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.add();
+        })
+      },
+      edit (record) {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.edit(record);
+        })
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+      },
+      handleOk () {
+        this.$refs.realForm.submitForm();
+      },
+      submitCallback(){
+        this.$emit('ok');
+        this.visible = false;
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>