<template>
    <div class="fenceView">
        <div class="fenceView-header">
            <div style="display: flex">
                <div class="fenceView-fastSearch">
                    <span>快速查询：</span>
                    <div class="fenceView-fastSearch-tag">
                        <div :style="{ maxHeight: isFastOpen ? 'none' : '24px', minWidth: '500px' }" class="fenceView-fastSearch-searchList">
                            <div @click="fastQuery(item)" class="fenceView-fastSearch-searchItem marginLeft marginBottom" v-for="(item, index) in fastQueryList" :key="index">
                                <template v-if="item.validTag == 1 && item.width > 80">
                                    <el-tooltip effect="dark" placement="top" :content="item.name">
                                        <span>{{ item.name }}</span>
                                    </el-tooltip>
                                </template>
                                <template v-else>
                                    <span>{{ item.name }}</span>
                                </template>
                                <i v-if="item.validTag == 1" class="el-icon-close" @click.stop="delCollection(item.id, index)"></i>
                            </div>
                        </div>
                        <div class="fenceView-fastSearch-btn" @click="isFastOpen = !isFastOpen">
                            {{ isFastOpen ? '收起' : '展开' }}
                            <i :class="isFastOpen ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i>
                        </div>
                    </div>
                </div>

                <div class="fenceView-custom">
                    <el-select v-if="customDate != 0" size="small" class="marginLeft" style="flex: 1" v-model="customDate" placeholder="请选择" @change="customDateChange">
                        <el-option
                            v-for="item in customDateList"
                            :key="item.value"
                            :label="item.label"
                            :value="item.value"
                        >
                        </el-option>
                    </el-select>
                    <el-date-picker
                        v-else
                        style="flex: 5; max-width: 290px"
                        size="small"
                        v-model="time"
                        ref="datePicker"
                        type="datetimerange"
                        :clearable="false"
                        :picker-options="timeOptions"
                        range-separator="至"
                        start-placeholder="开始日期"
                        end-placeholder="结束日期"
                        @change="datePickerChange"
                    >
                    </el-date-picker>
                    <el-select ref='refresh' style="flex: 1" size="small" class="marginLeft" v-model="refreshValue" placeholder="请选择" @change="refreshChange">
                        <el-option
                            v-for="item in refreshList"
                            :key="item.value"
                            :label="item.label"
                            :value="item.value"
                        >
                        </el-option>
                    </el-select>
                </div>
            </div>

            <div class="marginTop">
                <div class="fenceView-search-wapper">
                    <el-autocomplete
                        style="flex: 2 1 0%; margin-right: 30px"
                        class="autoCompleteQuery"
                        size="small"
                        v-model="querySearchValue"
                        placeholder="关键字之间用空格分隔"
                        :fetch-suggestions="(queryString, callback) => querySearch(querySearchValue, callback)"
                        ref="autoComplete"
                        :popper-append-to-body="false"
                        @click.native="status = 1; $refs.autoComplete.focus()"
                    >
                        <i @click.stop="status = 3; $refs.autoComplete.focus(); $refs.refresh.focus()" slot="suffix" style="font-size: 21px; color: #409EFF; position: absolute; right: -30px; top: 50%; transform: translateY(-50%); cursor: pointer" class="el-icon-warning"></i>
                        <template slot-scope="{ item }">
                            <el-row style="padding: 6px 0">
                                <template v-if="status == 1">
                                    <el-row>{{ item.title }}</el-row>
                                    <el-row type="flex" style="flex-wrap: wrap">
                                        <el-tag
                                            style="margin: 0 5px 10px 0;"
                                            v-for="childItem in item.list"
                                            :key="childItem.dataId"
                                            type="info"
                                            size="small"
                                            @click.stop="fillField(childItem.dataStr)"
                                        >
                                            {{ childItem.dataName }}
                                        </el-tag>
                                    </el-row>
                                </template>
                                <template v-else-if="status == 2">
                                    <div @click.stop="fillQueryVal(item.value)">{{ item.label }}</div>
                                </template>
                                <template v-else>
                                    <div @click.stop v-html="searchHTML"></div>
                                </template>
                            </el-row>
                        </template>
                    </el-autocomplete>

                    <el-row>
                        <el-button type="primary" size="mini" icon="el-icon-search" @click="tableQuery('')">查询</el-button>
                        <el-button type="primary" size="mini" icon="el-icon-refresh-left" @click="resetCondition">重置</el-button>
                    </el-row>
                    <el-divider direction="vertical"></el-divider>
                    <el-button-group>
                        <el-button class="button-star" plain icon="el-icon-star-on" size="mini" @click="addCollectionVisible = true"></el-button>
                        <el-button plain size="mini" @click="btach.visible = true; btach.title = '收藏夹'; btach.type = 'collection'">收藏条件</el-button>
                    </el-button-group>
                    <el-row>
                        <el-button class="marginLeft" plain icon="el-icon-search" size="mini" @click="btach.visible = true; btach.title = '历史记录'; btach.type = 'history'">查询历史</el-button>
                        <!-- <el-button class="marginLeft" plain icon="el-icon-refresh-left" size="mini">白名单</el-button> -->
                    </el-row>
                </div>
            </div>

            <div class="marginTop fenceView-filterConditions-wrapper">
                <div class="filterConditions-btns">
                    <span @click="resetFilterDialog(); addFilterVisible = true">新建过滤条件</span>
                    <span @click="filterConditionList = []; querySearchValue = ''; tableQuery(''); $message.success('过滤条件已清空')" class="marginLeft">清除所有过滤条件</span>
                </div>

                <el-divider></el-divider>

                <div class="filterConditions-list marginTop">
                    <el-tooltip  v-for="(item, index) in filterConditionList" :key="index" effect="dark" placement="top" :content="item.name">
                        <div :class="['filterConditions-list-item',`item--${item.status == 'positive' ? 'positive' : 'back'}`, item.disabled ? 'item--disabled' : '']">
                            <span class="text">
                                {{ item.name }}
                            </span>
                            <el-row class="operations">
                                <el-col @click.native="item.disabled = !item.disabled; tableQuery('');">
                                    <i class="el-icon-circle-close"></i>{{ item.disabled ? '启用' : '禁用' }}
                                </el-col>
                                <el-col @click.native="changeFilterCondition(item)">
                                    <i class="el-icon-zoom-out"></i>{{ item.status == 'positive' ? '反选' : '正选' }}
                                </el-col>
                                <el-col @click.native="filterConditionList.splice(index, 1); tableQuery('')">
                                    <i class="el-icon-delete"></i>删除
                                </el-col>
                                <el-col @click.native="eidtFilterCondition(item, index)">
                                    <i class="el-icon-edit-outline"></i>编辑
                                </el-col>
                            </el-row>
                        </div>
                    </el-tooltip>
                </div>
            </div>
        </div>

        <div class="fenceView-content marginTop">
            <div class="fenceView-searchRecordNum marginTop">
                查询记录
                <span style="color: #ec5759; font-size: 18px">{{ pagination.totalNum }}</span>
                条
            </div>

            <div class="fenceView-charts" style="flex-wrap: nowrap">
                <div class="fenceView-charts-item">
                    <fence-chart
                        v-if="time.length"
                        id="severity"
                        ref="severity"
                        type="pie"
                        title="严重程度分类统计"
                        :time="time"
                        :queryStatements="queryStatements"
                        :colsList="[{label: '威胁等级', prop: 'name'}, {label: '数量', prop: 'value'}]"
                    />
                </div>
                <div class="fenceView-charts-item" style="flex: 2 1 0%">
                    <fence-chart
                        ref="timestamp"
                        id="timestamp"
                        type="bar"
                        title="威胁趋势统计"
                        :time="time"
                        :queryStatements="queryStatements"
                        :isDownload="false"
                        :isShowTable="false"
                    />
                </div>
            </div>
            <!-- <div class="charts-btn marginTop" @click="isChartsOpen = !isChartsOpen">
                {{ isChartsOpen ? '隐藏' : '展开' }}图表
                <i :class="isChartsOpen ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i>
            </div>
            <div v-if="isChartsOpen" class="fenceView-charts">
                <div class="fenceView-charts-item marginBottom" v-for="(item, index) in charts" :key="index">
                    <fence-chart :title="item.name" :type="item.type" :id="item.id" />
                </div>
            </div> -->
        </div>

        <div v-loading="tableLoading" class="fenceView-footer marginTop">
            <div style="display: flex">
                <div class="field-list" :style="{width: isFieldOpen ? '200px' : '0'}">
                    <el-card class="box-card" :body-style="{padding: '.6vw', color: '#000000CC'}">
                        <div slot="header" class="box-card-header">
                            <span>关注字段[{{ focusFields.length }}]</span>
                            <el-tooltip effect="dark" placement="top" content="可切换关注字段的拖拽状态">
                                <i :class="dragDisabled ? 'el-icon-unlock' : 'el-icon-lock'" style="color: #409EFF" @click="dragDisabled = !dragDisabled"></i>
                            </el-tooltip>
                        </div>
                        <transition-group name="flip-list" tag="ul">
                            <li v-for="(item, index) in focusFields" :key="item.dataId" :draggable="dragDisabled" @dragstart="dragstart(item)" @dragover="dragover(item)" class="box-card-content" style="background-color: rgb(240,246,250);padding: 5px 5px 0 10px; list-style: none">
                                <el-row type="flex" justify="space-between" align="center">
                                    <div @click.prevent="addOptionalFields(item, index)" class="field-item">
                                        <el-checkbox :value="true">{{ item.dataName }}</el-checkbox>
                                        <i @click.stop="fields.title = item.dataName; fields.type = item.dataStr; fields.visible = true" class="el-icon-s-data" style="color: #409EFF;"></i>
                                    </div>
                                </el-row>
                            </li>
                        </transition-group>
                        <div class="box-card-btns">
                            <span @click="saveFields">保存</span>
                            <span @click="resetFields">恢复默认</span>
                        </div>
                    </el-card>

                    <el-card class="box-card marginTop" :body-style="{padding: '.6vw', color: '#000000CC'}">
                        <div slot="header" class="box-card-header">
                            <span>可选字段[{{ optionalFieldsLength }}]</span>
                        </div>
                        <el-input class="optional-input" size="small" v-model="optionalFieldSearch" clearable></el-input>
                        <div style="height: 180px;overflow-y: auto; overflow-x: hidden">
                            <el-row v-for="(key, parentIndex) in Object.keys(filterOptionalFields)" :key="key" class="box-card-content" style="flex-direction: column;" type="flex" justify="space-between" align="center">
                                <el-row class="field-title">
                                    <el-checkbox @click.native.prevent="addFocusFieldsMany(key, filterOptionalFields[key])" :value="false">{{ key }}</el-checkbox>
                                </el-row>
                                <el-row v-for="(item, childiIndex) in filterOptionalFields[key]" :key="item.dataId" style="cursor: pointer;padding: 5px 5px 0 20px;">
                                    <div class="field-item" @click.prevent="addFocusFields(item, childiIndex, parentIndex)">
                                        <el-checkbox :value="false">{{ item.dataName }}</el-checkbox>
                                        <i @click.stop="fields.title = item.dataName; fields.type = item.dataStr; fields.visible = true" class="el-icon-s-data" style="color: #409EFF"></i>
                                    </div>
                                </el-row>
                            </el-row>
                        </div>
                    </el-card>
                </div>
                <div :style="{width: isFieldOpen ? 'calc(100% - 200px)' : '100%'}" class="table-wrapper marginLeft">
                    <el-row type="flex" align="middle" class="marginBottom">
                        <el-col>
                            <el-switch v-model="isFieldOpen"></el-switch>
                            {{ isFieldOpen ? '隐藏' : '展示' }}字段列表
                            <span class="marginLeft">是否已读：</span>
                            <el-select style="width: 100px" size="small" v-model="isRead" @change="tableQuery('')">
                                <el-option v-for="(item, index) in readOptions" :key="index" :value="item.value" :label="item.label"></el-option>
                            </el-select>
                            <span class="marginLeft">是否收藏：</span>
                            <el-select style="width: 100px" size="small" v-model="isCollection" @change="tableQuery('')">
                                <el-option v-for="(item, index) in collectOptions" :key="index" :value="item.value" :label="item.label"></el-option>
                            </el-select>
                            <el-link type="primary" class="marginLeft" :underline="false" @click="tableQuery('')">刷新</el-link>
                            <el-link type="primary" class="marginLeft" :underline="false" @click="updHostThreat(tableData, 'read', '1')">当页全部已读</el-link>
                        </el-col>
                        <el-row type="flex" justify="space-between" align="middle">
                            <el-dropdown @command="exportFile(null)">
                                <el-button size="small" type="primary" plain icon="el-icon-download">
                                    导出
                                    <i class="el-icon-arrow-down"></i>
                                </el-button>
                                <el-dropdown-menu slot="dropdown">
                                    <!-- <el-dropdown-item>JSON</el-dropdown-item> -->
                                    <el-dropdown-item>XLSX</el-dropdown-item>
                                </el-dropdown-menu>
                            </el-dropdown>
                            <div class="pagination">
                                <span class="marginLeft">共 {{ pagination.totalNum }} 条，共 {{ pagination.totalPage }} 页</span>
                                <div class="marginLeft">
                                    <i @click="handlePageChange('prev')" :style="{cursor: pagination.start == 1 ? 'not-allowed' : 'pointer'}" class="el-icon-arrow-left"></i>
                                    <span>{{ pagination.start }}</span>
                                    <i @click="handlePageChange('next')" :style="{cursor: pagination.hasNextPage ? 'pointer' : 'not-allowed'}" class="el-icon-arrow-right"></i>
                                </div>
                                <el-select style="width: 100px" class="marginLeft" size="small" v-model="pagination.pageSize" @change="pageSizeChange">
                                    <el-option label="20条/页" :value="20"></el-option>
                                    <el-option label="50条/页" :value="50"></el-option>
                                    <el-option label="100条/页" :value="100"></el-option>
                                </el-select>
                            </div>
                        </el-row>
                    </el-row>

                    <el-row class="table">
                        <el-col>
                            <el-table
                                ref="table"
                                :data="tableData"
                                border
                                :key="tableKey"
                                :cell-style="{fontSize: '12px', color: '#00000099'}"
                                @cell-mouse-enter="cellMouseEnter"
                                @cell-mouse-leave="cellMouseLeave"
                                @expand-change="expandChange"
                            >
                                <el-table-column class-name="expand-cell" type="expand">
                                    <template slot-scope="props">
                                        <expandRow :row="props.row" :fields="allFields" @related-click="showRelatedDialog" @export-click="exportFile" @filter-click="addFilterItem($event)" @toggle-click="toggleTableHead" />
                                    </template>
                                </el-table-column>

                                <el-table-column label="发现时间" min-width="180" sortable sort-by="timestamp">
                                    <template slot-scope="scope">
                                        <div>
                                            <el-badge v-if="scope.row.is_read == 0" style="margin: 11px 5px 0 5px;" type="primary" is-dot></el-badge>
                                            <span>{{ scope.row.find_time }}</span>
                                        </div>
                                    </template>
                                </el-table-column>
                                <el-table-column v-for="(item, index) in colsList" :key="index" :label="item.label" min-width="180" show-overflow-tooltip>
                                    <template slot-scope="scope">
                                        <!-- 源ip 目的ip -->
                                        <template v-if="item.prop == 'src_ip' || item.prop == 'dst_ip'">
                                            <div style="display: flex; align-items: center">
                                                <el-tooltip effect="dark" placement="top" :content="(t(scope.row[item.prop + '_country']) || scope.row[item.prop + '_country']) + '/' + (t(scope.row[item.prop + '_city']) || scope.row[item.prop + '_city'])">
                                                    <template v-if="scope.row[item.prop + '_country_code']">
                                                        <span :class="['icon', 'icon-' + scope.row[item.prop + '_country_code'].toLowerCase()]"></span>
                                                    </template>
                                                </el-tooltip>
                                                <el-tooltip effect="dark"  placement="top" :content="scope.row[item.prop]">
                                                    <span class="marginLeft">{{ scope.row[item.prop] }}</span>
                                                </el-tooltip>
                                            </div>
                                            <div v-if="scope.row.app_proto.indexOf('http') != -1 && item.prop == 'dst_ip' && scope.row.desc && scope.row.desc.indexOf('host:') != -1" style="display: flex">
                                                <span style="min-width: 40px">域名：</span>
                                                <span class="nowrap" style="color: #ec5759">{{ scope.row.desc.split(';').filter(el => el.indexOf('host:') != -1)[0].replace('host:', '') }}</span>
                                            </div>
                                            <template v-if="item.prop == 'src_ip'">
                                                <el-tag v-if="scope.row.src_flag_victim == 1" type='string' effect="plain" size="small">受害者</el-tag>
                                                <el-tag v-else-if="scope.row.src_flag_attacker == 1" type='danger' effect="plain" size="small">攻击者</el-tag>
                                                <el-tag v-else-if="scope.row.src_flag_malicious == 1" type='danger' effect="plain" size="small">恶意</el-tag>
                                            </template>
                                            <template v-else>
                                                <el-tag v-if="scope.row.dst_flag_victim == 1" type='string' effect="plain" size="small">受害者</el-tag>
                                                <el-tag v-else-if="scope.row.dst_flag_attacker == 1" type='danger' effect="plain" size="small">攻击者</el-tag>
                                                <el-tag v-else-if="scope.row.dst_flag_malicious == 1" type='danger' effect="plain" size="small">恶意</el-tag>
                                            </template>

                                        </template>
                                        <template v-else>
                                            {{ t(scope.row[item.prop], item.prop) || scope.row[item.prop] }}
                                        </template>
                                    </template>
                                </el-table-column>

                                <el-table-column label="操作" width="100" fixed="right">
                                    <template slot-scope="scope">
                                        <el-tooltip effect="dark" :content="scope.row.is_collect == 1 ? '取消收藏' : '收藏'" placement="top">
                                            <i @click="updHostThreat([scope.row], 'collect', scope.row.is_collect == 1 ? '0' : '1', scope.$index,)" style="cursor: pointer" :class="scope.row.is_collect == 1 ? 'el-icon-star-on' : 'el-icon-star-off'" :style="{color: scope.row.is_collect == 1 ? 'rgb(253, 203, 61)' : ''}"></i>
                                        </el-tooltip>
                                        <el-divider direction="vertical"></el-divider>
                                        <el-tooltip effect="dark" content="加入白名单" placement="top">
                                            <i style="cursor: pointer" @click="whiteList.row = scope.row; whiteList.visible = true" class="el-icon-document-add"></i>
                                        </el-tooltip>
                                    </template>
                                </el-table-column>

                                <div class="tableBtns" ref="tablebtns">
                                    <el-tag class="success" type="success" @click="addFilterQueryCondition('positive')">
                                        <i class="el-icon-circle-plus-outline"></i>
                                        <span>正选</span>
                                    </el-tag>
                                    <el-tag class="danger" type="danger" @click="addFilterQueryCondition('back')">
                                        <i class="el-icon-remove-outline"></i>
                                        <span>反选</span>
                                    </el-tag>
                                </div>

                            </el-table>
                        </el-col>
                        <el-col :style="{visibility: scrollBarVisible ? 'visible' : 'hidden'}">
                            <div @scroll="customScroll" class="scroll" ref="scroll">
                                <div class="scrollBar" ref="scrollBar" style="height: 10px"></div>
                            </div>
                        </el-col>
                    </el-row>
                    <el-row class="marginTop" type="flex" justify="end">
                        <div class="pagination">
                            <span class="marginLeft">共 {{ pagination.totalNum }} 条，共 {{ pagination.totalPage }} 页</span>
                            <div class="marginLeft">
                                <i @click="handlePageChange('prev')" :style="{cursor: pagination.start == 1 ? 'not-allowed' : 'pointer'}" class="el-icon-arrow-left"></i>
                                <span>{{ pagination.start }}</span>
                                <i @click="handlePageChange('next')" :style="{cursor: pagination.hasNextPage ? 'pointer' : 'not-allowed'}" class="el-icon-arrow-right"></i>
                            </div>
                            <el-select style="width: 100px" class="marginLeft" size="small" v-model="pagination.pageSize" @change="pageSizeChange">
                                <el-option label="20条/页" :value="20"></el-option>
                                <el-option label="50条/页" :value="50"></el-option>
                                <el-option label="100条/页" :value="100"></el-option>
                            </el-select>
                        </div>
                    </el-row>
                </div>
            </div>
        </div>

        <!-- 相关事件查询 -->
        <el-dialog width="500px" :visible.sync="openRelatedDialog" :close-on-click-modal="false">
            <span slot="title">
                <span style="color: #000000CC; font-size: 16px">相关事件查询</span>
            </span>
            <el-row style="color: #606266">
                <el-row>
                    <span style="font-size: 14px">提取以下字段进行搜索:</span>
                </el-row>
                <el-row v-for="(item, index) in relatedForm" :key="index">
                    <el-col :span="12" style="font-size: 12px">
                        <el-checkbox-group
                            v-model="checkAllGroup"
                        >
                            <el-checkbox :label="item.key">{{ item.name }}</el-checkbox>
                        </el-checkbox-group>
                    </el-col>
                    <el-col :span="12" style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis">
                        <el-tooltip effect="dark" placement="top" :content="item.value">
                            <span class="related-value" style="font-size: 12px">
                                {{ item.dataName}}
                            </span>
                        </el-tooltip>
                    </el-col>
                </el-row>

                <el-row style="margin-top: 10px">
                    <el-col :span="12">
                        <span style="font-size: 14px">过滤类型</span>
                    </el-col>
                    <el-radio-group v-model="filterType" >
                        <el-radio label="positive">
                            <span>正选</span>
                        </el-radio>
                        <el-radio label="back">
                            <span>反选</span>
                        </el-radio>
                    </el-radio-group>
                </el-row>

            </el-row>
            <div slot="footer">
                <el-button size="mini" @click="openRelatedDialog = false">关闭</el-button>
                <el-button size="mini" type="primary" @click="confirmRelatedDialog">确定</el-button>
            </div>
        </el-dialog>

        <!-- 新增收藏条件 -->
        <el-dialog :visible.sync="addCollectionVisible" width="500px" title="新增收藏条件">
            <el-form :model="addCollectionModel" ref="addCollectionForm" size="small" label-width="120px" inline>
                <el-form-item prop="name" label="查询条件名称" :rules="{ required: true, message: '请输入查询条件名称', trigger: 'blur' }">
                    <el-input style="width: 300px" type="text" v-model="addCollectionModel.name" show-word-limit maxlength="32" placeholder="请输入查询条件名称"></el-input>
                </el-form-item>
            </el-form>
            <div slot="footer" >
                <el-button size="mini" plain @click="addCollectionVisible = false">关闭</el-button>
                <el-button v-loading="addCollectionLoading" type="primary" size="mini" @click="addCollectionConfig">确定</el-button>
            </div>
        </el-dialog>

        <!-- 新建过滤条件 -->
        <el-dialog :visible.sync="addFilterVisible" width="70%" :title="filterTitle + '过滤条件'">
            <el-tree
                :data="addFilterTreeData"
                node-key="id"
                default-expand-all
                :expand-on-click-node="false">
                <div class="custom-tree-node" slot-scope="{ node, data }">
                    <template v-if="data.id == 0">
                        <el-row class="custom-tree-node-root" type="flex" justify="space-between">
                            <el-select style="max-width: 215px" size="small" v-model="addFilterRootSelect">
                                <el-option label="AND(条件必须同时满足)" value="AND"></el-option>
                                <el-option label="OR(条件满足任意一个)" value="OR"></el-option>
                            </el-select>
                            <el-link type="primary" :underline="false" @click="addCondition">新建条件</el-link>
                        </el-row>
                    </template>
                    <template v-else>
                        <el-row class="custom-tree-node-child" type="flex" justify="space-between" align="middle">
                            <div style="margin-right: 20px">条件{{ data.id }}:</div>
                            <el-autocomplete
                                style="margin-right: 30px; max-width: 215px"
                                class="autoCompleteQuery"
                                size="small"
                                v-model="data.key"
                                placeholder="请输入关键字"
                                :fetch-suggestions="(queryString, callback) => querySearch(data.key || '', callback)"
                                :ref="'dialogAutoComplete' + data.id"
                                :popper-append-to-body="false"
                                @click.native="status = 1; $refs['dialogAutoComplete' + data.id].focus()"
                            >
                                <i @click.stop="status = 3; $refs['dialogAutoComplete' + data.id].focus(); $refs.refresh.focus()" style="font-size: 21px; color: #409EFF; position: absolute; right: -35px; top: 50%; transform: translateY(-50%); cursor: pointer" class="el-icon-warning" slot="suffix"></i>
                                <template slot-scope="{ item }">
                                    <el-row style="padding: 6px 0">
                                        <template v-if="status != 3">
                                            <el-row>{{ item.title }}</el-row>
                                            <el-row type="flex" style="flex-wrap: wrap">
                                                <el-tag
                                                    style="margin: 0 5px 10px 0;"
                                                    v-for="(childItem, index) in item.list"
                                                    :key="index"
                                                    type="info"
                                                    size="small"
                                                    @click.stop="data.key = childItem.dataStr; $refs['dialogAutoComplete' + data.id].focus()"
                                                >
                                                    {{ childItem.dataName }}
                                                </el-tag>
                                            </el-row>
                                        </template>
                                        <template v-else>
                                            <div @click.stop v-html="searchHTML"></div>
                                        </template>
                                    </el-row>
                                </template>
                            </el-autocomplete>
                            <el-select style="margin-right: 30px; max-width: 215px" size="small" v-model="data.symbol" placeholder="请选择">
                                <el-option v-for="(item, index) in conditionType" :key="index" :label="item.label" :value="item.value"></el-option>
                            </el-select>
                            <el-autocomplete
                                :style="{'max-width': '215px', 'visibility': data.symbol != '10' && data.symbol != '11' ? 'visible' : 'hidden'}"
                                style="flex: 1; margin-right: 30px"
                                size="small"
                                v-model="data.value"
                                placeholder="请输入值"
                                :fetch-suggestions="(queryString, callback) => dialogQuerySearch(queryString, callback, data)"
                            >
                            </el-autocomplete>
                            <el-link type="info" :underline="false" @click="delCondition(data.id)">删除</el-link>
                        </el-row>
                    </template>
                </div>
            </el-tree>
            <div slot="footer" >
                <el-button size="mini" plain @click="addFilterVisible = false">关闭</el-button>
                <el-button type="primary" size="mini" @click="addFilterQueryCondition('custom')">确定</el-button>
            </div>
        </el-dialog>

        <!-- 新增白名单 -->
        <add-white-list :visible.sync="whiteList.visible" :row="whiteList.row" />

        <!-- 收藏条件/历史记录 -->
        <btach-table
            :visible.sync="btach.visible"
            :title="btach.title"
            :type="btach.type"
            :allFields="allFields"
            :filterConditionList.sync="filterConditionList"
            @delSuccess="collectionList"
            @query="querySearchValue = $event[0]; time = $event[1]; customDate = 0; tableQuery('', false)"
            @add="addFilterItem($event, false)"
        />

        <fields-table
            v-if="time.length"
            :visible.sync="fields.visible"
            :title="fields.title" :time="time"
            :type="fields.type"
            :queryStatements="queryStatements"
            @add="filterConditionList.push($event); tableQuery('')"
        />
    </div>
</template>

<script>
import { parseTime, spliceSql, debounce } from './utils'
import fenceChart from './components/fenceChart/fenceChart.vue'
import expandRow from './components/table-expand.vue'
import btachTable from './components/dialogTableComponents/btachTableComent.vue'
import fieldsTable from './components/dialogTableComponents/fieldsTableComent.vue'
import addWhiteList from './components/addWhiteList.vue'
import i18n from './i18n'
import {
    addConditionCollect,
    addSearchHistory,
    getAllFields,
    updFieldsType,
    resetFieldsType,
    getQuickSearch,
    getHostThreat,
    updHostThreatById,
    exportHostThreat,
    getConditionCollect,
    delConditionCollect,
    getFieldAggregate
} from './api/fence'
export default {
    components: {
        fenceChart,
        expandRow,
        btachTable,
        addWhiteList,
        fieldsTable
    },
    computed: {
        searchHTML() {
            return `<div class="remark">
                <div>搜索语句查询语法</div>
                <br>
                <p>精确匹配搜索</p>
                <p>对某个字段进行精确匹配搜索，可以使用：<span class="keyword">status : 200（查询所有 status等于 200 的记录）</span> 如果查询的有空格或特殊字符，可以使用引号包裹，例如：<span class="keyword">message : "hello world"</span>，特殊字符包括：+ - = &amp;&amp; || &gt; &lt; ! ( ) { } [ ] ^ " ~ * ? : \ / </p>
                <br>
                <p>模糊匹配搜索</p>
                <p>对某个字段进行模糊匹配搜索，可以使用：<span class="keyword">file.filename : *testfile*</span>（查询所有文件名包含testfile的所有文件） </p>
                <br>
                <p>ip范围查询</p><p>对于src_ip、dst_ip等ip类型的字段支持ip、模糊匹配两种查询方式，例如：<span class="keyword">src_ip : 192.168.1.45</span>，<span class="keyword">src_ip : 192.168.205*</span></p>
                <br>
                <p>取值范围搜索</p>
                <p>可以使用 大于等于(">="),小于等于("<="),大于(">"),小于("<") 进行取值的范围限定（连接符用"AND"），大于等于(">="),小于等于("<=")表示包含边界，大于(">"),小于("<")表示不包含边界。例如： <span class="keyword">reliability : >=1 AND reliability : <=8</span>（查询 reliability在 大于等于1且小于等于8的记录） <span class="keyword">reliability : >=1 AND reliability : <8</span>（查询 reliability在 大于等于1且小于8的记录） <span class="keyword">reliability : >=1</span>（查询 reliability大于等于1的记录） <span class="keyword-yellow">注意: 运算符(>=,<=,>,<)与值之间不能有空格</span></p>
                <br>
                <p>不为空查询</p>
                <p>查询某个字段不为空，例如：<span class="keyword">http.xff :*</span>（查询所有http.xff字段不为空的记录）</p><br><p>更复杂的搜索条件</p><p>指定更复杂的搜索条件，可以使用布尔操作AND, OR, NOT和()，例如：<span class="keyword">reliability : >=1 AND reliability : <=8 AND extension : (php,html) AND NOT severity : 1 </span></p>
            </div>`
        },
        optionalFieldsLength() {
            let sum = 0;
            Object.keys(this.optionalFields).map(el => {
                sum += this.optionalFields[el].length
            })
            return sum
        },
        filterOptionalFields() {
            let filters = {}
            Object.keys(this.optionalFields).map(key => {
                let arr = this.optionalFields[key].filter(el => el.dataName.includes(this.optionalFieldSearch) || el.dataStr.includes(this.optionalFieldSearch))
                if (arr.length) filters[key] = arr
            })
            return filters
        },
        defaultFastQueryList() {
            return this.fastQueryList.filter(el => el.validTag == 2)
        }
    },
    watch: {
        colsList(newVal, oldVal) {
            this.setScrollWidth()
        }
    },
    data() {
        return {
            scrollBarVisible: true,
            tableKey: false,
            appointHeads: [
                'is_read',
                'is_collect',
                'enrichments.src_ip.malicious',
                'enrichments.dst_ip.malicious',
                'reliability',
                'severity',
                'visit_direction',
            ],
            readOptions: [
                { label: '全部', value: '' },
                { label: '未读', value: '0' },
                { label: '已读', value: '1' },
            ],
            collectOptions: [
                { label: '全部', value: '' },
                { label: '未收藏', value: '0' },
                { label: '已收藏', value: '1' },
            ],
            cacheFieldAggregate: {},
            uuid: [''],
            status: 1,
            filterCount: '',
            queryStatements: '',
            querySearchValue: '',
            isFastOpen: false,
            isChartsOpen: false,
            fastQueryList: [],
            time: [],
            timeOptions: {
                shortcuts: [{
                    text: '最近5分钟',
                    onClick(vm) {
                        vm.$emit('pick', [Date.now() - 1000 * 60 * 5 , Date.now(), 1]);
                    }
                }, {
                    text: '最近15分钟',
                    onClick(vm) {
                        vm.$emit('pick', [Date.now() - 1000 * 60 * 15, Date.now(), 2]);
                    }
                }, {
                    text: '最近30分钟',
                    onClick(vm) {
                        vm.$emit('pick', [Date.now() -  1000 * 60 * 30, Date.now(), 3]);
                    }
                }, {
                    text: '最近1小时',
                    onClick(vm) {
                        vm.$emit('pick', [Date.now() -  1000 * 60 * 60, Date.now(), 4]);
                    }
                }, {
                    text: '最近4小时',
                    onClick(vm) {
                        vm.$emit('pick', [Date.now() - 3600 * 1000 * 4, Date.now(), 5]);
                    }
                }, {
                    text: '最近12小时',
                    onClick(vm) {
                        vm.$emit('pick', [Date.now() - 3600 * 1000 * 12, Date.now(), 6]);
                    }
                }, {
                    text: '最近1天',
                    onClick(vm) {
                        vm.$emit('pick', [Date.now() - 3600 * 1000 * 24, Date.now(), 7]);
                    }
                }, {
                    text: '最近1周',
                    onClick(vm) {
                        vm.$emit('pick', [Date.now() - 3600 * 1000 * 24 * 7, Date.now(), 8]);
                    }
                }, {
                    text: '最近1月',
                    onClick(vm) {
                        vm.$emit('pick', [Date.now() - 3600 * 1000 * 24 * 31, Date.now(), 9]);
                    }
                }, {
                    text: '今天',
                    onClick(vm) {
                        vm.$emit('pick', [Date.now() - 3600 * 1000 * 24, Date.now(), 10]);
                    }
                }, {
                    text: '本周',
                    onClick(vm) {
                        vm.$emit('pick', [Date.now() - 3600 * 1000 * 24 * 7, Date.now(), 11]);
                    }
                }, {
                    text: '本月',
                    onClick(vm) {
                        vm.$emit('pick', [Date.now() - 3600 * 1000 * 24 * 7, Date.now(), 12]);
                    }
                }]
            },
            customDate: 10,
            customDateList: [
                { value: 0, label: "自定义" },
                { value: 1, label: "最近5分钟" },
                { value: 2, label: "最近15分钟" },
                { value: 3, label: "最近30分钟" },
                { value: 4, label: "最近1小时" },
                { value: 5, label: "最近4小时" },
                { value: 6, label: "最近12小时" },
                { value: 7, label: "最近1天" },
                { value: 8, label: "最近1周" },
                { value: 9, label: "最近1月" },
                { value: 10, label: "今天" },
                { value: 11, label: "本周" },
                { value: 12, label: "本月" }
            ],
            refreshTimer: null,
            refreshValue: 0,
            refreshList: [
                { value: 0, label: "不自动刷新" },
                { value: 15000, label: "15秒" },
                { value: 30000, label: "30秒" },
                { value: 60000, label: "1分钟" },
                { value: 1000 * 60 * 5, label: "5分钟" },
                { value: 1000 * 60 * 30, label: "30分钟" },
            ],
            chartsRef: ['severity', 'timestamp'],
            charts: [
                { id: '0', type: 'transverseBar', name: '攻击组织', itemBackgroundColor: 'rgb(80,147,225)' },
                { id: '1', type: 'transverseBar', name: '威胁大类统计', itemBackgroundColor: 'rgb(180,204,150)' },
                { id: '2', type: 'transverseBar', ame: '威胁类别统计', itemBackgroundColor: 'rgb(211,145,192)' },
                { id: '3', type: 'transverseBar', name: '威胁IOC', itemBackgroundColor: 'rgb(110,121,160)' },
                { id: '4', type: 'transverseBar', name: '源IP统计', itemBackgroundColor: 'rgb(118,192,106)' },
                { id: '5', type: 'transverseBar', name: '目的IP统计', itemBackgroundColor: 'rgb(33,180,172)' },
            ],
            optionalFieldSearch: '', // 可选字段输入框
            isFieldOpen: true, // 是否展示字段列表
            isRead: '', // 是否已读
            isCollection: '', // 是否收藏
            tableData: [],
            colsList: [],
            checkAllGroup: [],
            openRelatedDialog: false, // 相关事件查询
            relatedForm: [
                { name: '源IP', value: '', key: 'src_ip' },
                { name: '源端口', value: '', key: 'src_port' },
                { name: '目的IP', value: '', key: 'dst_ip' },
                { name: '目的端口', value: '', key: 'dst_port' },
                { name: '传输层协议', value: '', key: 'proto' },
                { name: '应用层协议', value: '', key: 'app_proto' },
                { name: '威胁名称', value: '', key: 'category' },
                { name: '威胁类别', value: '', key: 'classtype' },
                { name: '威胁IOC', value: '', key: 'target' },
                { name: '事件规则ID', value: '', key: 'rid' }
            ],
            filterType: "positive",
            // 新增收藏条件
            addCollectionVisible: false,
            addCollectionLoading: false,
            addCollectionModel: {
                name: ''
            },
            btach: {
                visible: false,
                title: '',
                type: '' // collection收藏条件 history历史记录
            },
            fields: {
                visible: false,
                title: '',
                type: ""
            },
            filterTitle: '新建',
            addFilterModifyIndex: '',
            addFilterVisible: false,
            addFilterRootSelect: 'AND',
            addFilterTreeData: [{
                id: '0',
                children: [
                    { id: '1', key: '', value: '', symbol: '' }
                ]
            }],
            conditionType: [
                { value: '1', label: '等于' },
                { value: '2', label: '不等于' },
                { value: '3', label: '模糊匹配' },
                { value: '4', label: '大于' },
                { value: '5', label: '小于' },
                { value: '6', label: '大于等于' },
                { value: '7', label: '小于等于' },
                { value: '8', label: '包含' },
                { value: '9', label: '不包含' },
                { value: '10', label: '存在' },
                { value: '11', label: '不存在' }
            ],
            focusFields: [], // 关注字段
            optionalFields: {}, // 可选字段
            allFields: [], // 所有字段
            draggingItem: null,
            dragLastItem: null,
            dragDisabled: false,
            whiteList: {
                visible: false,
                row: {}
            },
            pagination: {
                totalNum: 0, // 总条数
                totalPage: 0, // 总页数
                start: 1, // 当前页
                pageSize: 20,// 限制数量
                hasNextPage: false
            },
            filterConditionList: [], // 过滤列表
            lastTimeHoverRow: {},
            lastTimeHoverColumn: {},
            tableLoading: false,
        }
    },
    methods: {
        setScrollWidth() {
            this.$nextTick(() => {
                setTimeout(() => {
                    if (this.$refs['scroll']) this.$refs['scroll'].style.width = document.querySelector('.table .el-table__body-wrapper').clientWidth + 'px'
                    if (this.$refs['scrollBar']) this.$refs['scrollBar'].style.width = document.querySelector('.table .el-table__body').clientWidth + 'px'
                    // this.tableHeadWidth = document.querySelector('.el-table__header').style.width
                }, 0)
            })
        },
        verticalScroll() {
            let childEle = document.querySelectorAll('.pagination')
            if (childEle.length) {
                let childTop = childEle[1].getBoundingClientRect().top
                let bodyHeight = document.documentElement.clientHeight || document.body.clientHeight
                if (childTop <= bodyHeight) this.scrollBarVisible = false
                else this.scrollBarVisible = true
            }
        },
        customScroll(e) {
            let element = document.querySelector('.table .el-table__body-wrapper')
            element.scrollLeft = e.target.scrollLeft
        },
        getTextWidth(str, fontSize) {
            let result = 0;
            let ele = document.createElement("div");
            ele.style.position = "absolute";
            ele.style.whiteSpace = "nowrap";
            ele.style.fontSize = fontSize;
            ele.style.opacity = 0;
            ele.innerText = str;
            document.body.append(ele);
            result = ele.getBoundingClientRect().width;
            document.body.removeChild(ele);
            return result;
        },
        resetFilterDialog() {
            this.addFilterModifyIndex = '';
            this.addFilterRootSelect = 'AND';
            this.filterTitle = '新建';
            this.addFilterTreeData = [
                { id: '0',
                    children: [
                        { id: '1', key: '', value: '', symbol: '' }
                    ]
                }
            ];
        },
        fastQuery(item) {
            this.filterConditionList = []
            this.querySearchValue = item.queryStatements || '';
            if (item.validTag == 1) {
                this.time = [item.startTime, item.endTime];
                this.customDate = 0;
            } else {
                this.getTime()
            }
            if (item.filterCount) {
                let allKeyValue = item.filterCount.split(/\)\sAND\s\(/g).map(el => el.replace(/\(|\)/g, '')).filter(el => el != '')
                allKeyValue.forEach(el => {
                    let arr = null, addFilterRootSelect = 'AND';
                    let key = '',value = '',symbol = '', name = '', query = '';
                    if (el.includes('AND')) {
                        arr = el.split('AND')
                        addFilterRootSelect = 'AND'
                    } else if (el.includes('OR')) {
                        arr = el.split('OR')
                        addFilterRootSelect = 'OR'
                    } else {
                        arr = [el]
                    }

                    for (let i = 0; i < arr.length; i++) {
                        let keyValue = arr[i].split(':')
                        let sy = ''
                        if (!/NOT|\*|\>|\<|\=|\(|\)/.test(arr[i])) {
                            sy = '1'
                        } else if (!/\*|\>|\<|\=|\(|\)/.test(arr[i])) {
                            sy = '2'
                        } else if (/\*/g.test(arr[i]) && keyValue[1] != '*') {
                            sy = '3'
                        } else if (!/NOT|\*|\<|\=|\(|\)/.test(arr[i])) {
                            sy = '4'
                        } else if (!/NOT|\*|\>|\=|\(|\)/.test(arr[i])) {
                            sy = '5'
                        } else if (!/NOT|\*|\<|\(|\)/.test(arr[i])) {
                            sy = '6'
                        } else if (!/NOT|\*|\>|\(|\)/.test(arr[i])) {
                            sy = '7'
                        } else if (!/NOT|\*|\>|\<|\=/.test(arr[i])) {
                            sy = '8'
                        } else if (!/\*|\>|\<|\=/.test(arr[i])) {
                            sy = '9'
                        } else if (keyValue[1] == '*') {
                            sy = '10'
                        } else {
                            sy = '11'
                        }
                        keyValue[0] = keyValue[0].replace(/NOT|\>|\<|\=|\*|\(|\)/g, '').trim()
                        keyValue[1] = keyValue[1].replace(/NOT|\>|\<|\=|\*|\(|\)|\"/g, '').trim()
                        let current = this.allFields.filter(item => item.dataStr == keyValue[0].trim())[0] || keyValue[0]
                        key += (keyValue[0] + ',');
                        symbol += (sy + ',');
                        value += (keyValue[1] + ',');
                        name += (`${spliceSql(current.dataName, sy, keyValue[1]).name} ${arr.length - 1 == i ? '' : addFilterRootSelect} `)
                        query += (`${spliceSql(keyValue[0], sy, keyValue[1]).query} ${arr.length - 1 == i ? '' : addFilterRootSelect} `)
                    }
                    this.addFilterItem({
                        key: key.endsWith(',') ? key.substring(0, key.lastIndexOf(',')) : key,
                        value,
                        symbol,
                        name,
                        query,
                        status: 'positive',
                        disabled: false
                    }, false)
                    // this.addFilterRootSelect = addFilterRootSelect
                })
            }
            this.tableQuery('', false);
        },
        fillField(dataStr) {
            if (this.querySearchValue == '') {
                this.querySearchValue = dataStr + ' '
            } else if (this.querySearchValue.trim().endsWith('NOT')) {
                let val = this.querySearchValue
                this.querySearchValue = val.endsWith(' ') ? `${val.replace(/\s+/g, ' ')}${dataStr} ` : `${val} ${dataStr} `
            } else {
                let allKeyValue = this.querySearchValue.replace(/NOT/g, '').match(/([\w|\u4e00-\u9fa5]+\s*(:\*|:)?\s*"?([^AND|OR])*"?\s*(AND|OR)?)+/g)
                let keyValue = allKeyValue[allKeyValue.length - 1].split(' ').filter(el => el.length)
                if (keyValue.length == 1) {
                    let index = this.querySearchValue.lastIndexOf(keyValue[0])
                    this.querySearchValue = this.querySearchValue.substring(0, index) + dataStr + ' '
                } else {
                    this.querySearchValue = this.querySearchValue + dataStr + ' '
                }
            }
            this.$refs.autoComplete.focus()
        },
        changeFilterCondition(item) {
            item.status = item.status == 'positive' ? 'back' : 'positive';
            let reg = new RegExp(/AND/g.test(item.query) ? /AND/g : /OR/g)
            item.query = item.query.split(reg).map(el => {
                if (/NOT/.test(el)) {
                    return el.replace(/NOT/g, '').trim()
                } else {
                    return 'NOT ' + el
                }
            }).join(` ${/AND/g.test(item.query) ? 'AND' : 'OR'} `)
            this.tableQuery('')
        },
        // 删除条件
        delCondition(id) {
            this.addFilterTreeData[0].children.splice(this.addFilterTreeData[0].children.findIndex(el => el.id == id), 1)
            this.addFilterTreeData[0].children.forEach((el, index) => el.id = index + 1)
        },
        // 新建条件
        addCondition() {
            let len = this.addFilterTreeData[0].children.length - 1
            let id = len == -1 ? 0 : +this.addFilterTreeData[0].children[len].id
            this.addFilterTreeData[0].children.push({
                id: id + 1,
                key: '',
                value: '',
                symbol: ''
            })
        },
        fillQueryVal(val) {
            let whitelist = [':', ':*']
            if (whitelist.includes(val)) {
                this.querySearchValue = this.querySearchValue + `${val} `;
            } else if (val == 'AND' || val == 'OR') {
                let keyValue = this.querySearchValue.replace(/NOT/g, '').match(/([\w|\u4e00-\u9fa5]+\s*(:\*|:)?\s*"?([^AND|OR])*"?\s*(AND|OR)?)+/g).pop().split(' ').filter(el => el.length)
                let handleSearchValue = this.querySearchValue
                if (keyValue[3]) {
                    let lastIndex = this.querySearchValue.lastIndexOf(keyValue[3])
                    handleSearchValue = this.querySearchValue.substring(0, lastIndex)
                }
                this.querySearchValue = handleSearchValue + `${val} `;
            } else {
                let keyValue = this.querySearchValue.replace(/NOT/g, '').match(/([\w|\u4e00-\u9fa5]+\s*(:\*|:)?\s*"?([^AND|OR])*"?\s*(AND|OR)?)+/g).pop().split(' ').filter(el => el.length)
                let handleSearchValue = this.querySearchValue
                if (keyValue[2]) {
                    let lastIndex = this.querySearchValue.lastIndexOf(keyValue[2])
                    handleSearchValue = this.querySearchValue.substring(0, lastIndex)
                }
                this.querySearchValue = handleSearchValue + `"${val}" `;
            }
            this.$refs.autoComplete.focus();
        },
        addFocusFieldsMany(key, arr) {
            let array = JSON.parse(JSON.stringify(arr))
            array.forEach(el => {
                el.dataType = '1'
                el.label = el.dataName
                el.prop = el.dataStr
            })
            this.focusFields = [...this.focusFields, ...array]
            this.colsList = [...this.colsList, ...array]
            this.$delete(this.optionalFields, key)
        },
        toggleTableHead(item) {
            let index = this.focusFields.findIndex(el => el.dataId == item.dataId)
            if (index == -1) {
                this.focusFields.push(item)
                this.colsList.push(Object.assign(item, { dataType: '1', label: item.dataName, prop: item.dataStr }))
                this.optionalFields[item.belong].splice(this.optionalFields[item.belong].findIndex(el => el.dataId == item.dataId), 1)
            } else {
                this.focusFields.splice(index, 1)
                this.colsList.splice(index, 1)
                this.optionalFields[item.belong].push(item)
            }
        },
        getQueryFields(isFilter = false, queryString) {
            let focus = JSON.parse(JSON.stringify(this.focusFields))
            let optional = JSON.parse(JSON.stringify(this.optionalFields))
            focus.forEach(el => {
                if(!optional[el.belong]) optional[el.belong] = []
                optional[el.belong].push(el)
            })
            let keys = Object.keys(optional)
            let uniqueKeys = Array.from(new Set(['基础字段', '常用字段', ...keys]))
            return uniqueKeys.map(key => {
                if (isFilter) {
                    let list = optional[key].filter(el => el.dataStr.includes(queryString) || el.dataName.includes(queryString))
                    if (list.length) return { title: key, list}
                } else {
                    return { title: key, list: optional[key] }
                }
                return {}
            })
        },
        showRelatedDialog(row) {
            this.relatedForm.forEach(el => {
                el.dataName = this.t(row[el.key]) || row[el.key]
                el.value = row[el.key ]
            })
            this.checkAllGroup = ['src_ip', 'dst_ip']
            this.openRelatedDialog = true
        },
        confirmRelatedDialog() {
            let key = '',value = '',symbol = '', name = '', query = '';
            let sy = this.filterType == 'positive' ? '1' : '2'
            this.checkAllGroup.forEach((keyName, index) => {
                let cur = this.relatedForm.filter(el => el.key == keyName)[0]
                key += (keyName + ',');
                value += (cur.value + ',');
                symbol += (sy + ',');
                name += (`${cur.name} == ${cur.value} ${index == this.checkAllGroup.length - 1 ? '' : 'AND '}`)
                query += (`${this.filterType == 'positive' ? '' : 'NOT '}${keyName} : "${cur.value}" ${index == this.checkAllGroup.length - 1 ? '' : 'AND '}`)
            })
            this.addFilterItem({
                key,
                value,
                symbol,
                name,
                query,
                status: this.filterType,
                disabled: false
            })
            this.openRelatedDialog = false
        },
        tableQuery(val = '', updTime = true) {
            if (updTime) this.getTime()
            this.filterCount = ''
            this.queryStatements = val
            if (this.isRead) {
                this.queryStatements += ((this.queryStatements == '' ? '' : ' AND ') + `${this.isRead == '0' ? 'NOT is_read :*' : 'is_read : 1'}`)
            }
            if (this.isCollection) {
                this.queryStatements += ((this.queryStatements == '' ? '' : ' AND ') + `is_collect : ${this.isCollection}`)
            }
            if (this.querySearchValue) {
                this.queryStatements += ((this.queryStatements == '' ? '' : ' AND ') + this.querySearchValue)
            }
            if (this.filterConditionList.length) {
                this.filterConditionList.forEach(el => {
                    if (!el.disabled) this.queryStatements += ((this.queryStatements == '' ? '' : ' AND ') + `${el.query}`)
                    if (!el.disabled) this.filterCount += ((this.filterCount == '' ? '' : ' AND ') + `(${el.query})`)
                })
            }
            // this.queryStatements = this.queryStatements
            //     .replace(/\s*/g, '')
            //         .split('AND').join(' AND ')
            //             .split('OR').join(' OR ')
            //                 .split('NOT').join('NOT ')
            // this.filterCount = this.filterCount
            //     .replace(/\s*/g, '')
            //         .split('AND').join(' AND ')
            //             .split('OR').join(' OR ')
            //                 .split('NOT').join('NOT ')
            this.addHistoryQuery()
            this.getList()
            this.$nextTick(() => {
                this.chartsRef.forEach(el => this.$refs[el].getList(el))
            })
        },
        expandChange(row, expandedRows) {
            if (row.is_read == 0) this.updHostThreat([row], 'read', '1')
            row.is_read = 1
            if (expandedRows.length > 1) {
                this.$refs.table.toggleRowExpansion(expandedRows[0], false)
            }
        },
        customDateChange(val) {
            if (val == 0) {
                this.$nextTick(() => {
                    this.$refs['datePicker'].focus()
                })
                return
            }
            this.cacheFieldAggregate = {}
            this.tableQuery('')
        },
        // 新增收藏条件
        addCollectionConfig() {
            this.$refs['addCollectionForm'].validate((valid) => {
                if (valid) {
                    let params = {
                        name: this.addCollectionModel.name,
                        collectTime: parseTime(Date.now()),
                        queryStatements: this.querySearchValue || '',
                        startTime: parseTime(this.time[0]),
                        endTime: parseTime(this.time[1]),
                        filterCount: this.filterCount,
                        focusFields: ''
                    }
                    this.focusFields.forEach(el => {
                        params.focusFields += (el.dataStr + ',')
                    })
                    this.addCollectionLoading = true
                    addConditionCollect(params).then(res => {
                        if (res.data.returnCode == 0) {
                            this.$message.success('新增收藏条件成功')
                            this.collectionList()
                        }
                        this.addCollectionModel.name = ''
                        this.addCollectionLoading = false
                        this.addCollectionVisible = false
                    }).catch(() => {
                        this.addCollectionLoading = false
                    })
                }
            })
        },
        // 自定义收藏列表
        collectionList() {
            let params = {
                page: {
                    size: 50,
                    current: 1
                }
            }
            getConditionCollect(params).then(res => {
                if (res.data.returnCode == 0) {
                    let { data } = res.data
                    this.fastQueryList = [...this.defaultFastQueryList, ...data.list]

                    this.fastQueryList.forEach(el => {
                        if (el.validTag == 1) {
                            el.width = this.getTextWidth(el.name, '12px')
                        }
                    })
                }
            }).catch(() => {})
        },
        delCollection(id, index) {
          this.$confirm('是否确认删除该收藏条件', '提示', {
                type: 'warning',
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                beforeClose: async (action, instance, done) => {
                    if (action == 'confirm') {
                        instance.confirmButtonLoading = true
                        let params = {
                            ids: [id]
                        }
                        delConditionCollect(params).then(res => {
                            if (res.data.returnCode == 0) {
                                this.$message.success('删除收藏条件成功')
                                this.fastQueryList.splice(index, 1)
                            }
                            instance.confirmButtonLoading = false
                            done()
                        }).catch(() => {
                            instance.confirmButtonLoading = false
                            done()
                        })

                    } else done()
                }
            }).catch(() => {})
        },
        // 新增历史查询
        addHistoryQuery() {
            let params = {
                queryTime: parseTime(Date.now()),
                queryStatements: this.querySearchValue || '',
                filterCount: this.filterCount,
                startTime: parseTime(this.time[0]),
                endTime: parseTime(this.time[1])
            }
            addSearchHistory(params).then(res => {

            }).catch(() => {})
        },
        // 获取关注、可选字段
        getAllFields() {
            return new Promise((resolve, reject) => {
                getAllFields().then(res => {
                    if (res.data.returnCode == 0) {
                        let { data } = res.data
                        this.allFields = data
                        this.focusFields = []
                        this.optionalFields = {}
                        this.colsList = []
                        for (let i = 0; i < data.length; i++) {
                            let list = [
                                "category_cn",
                                "classtype_cn"
                            ]
                            if (list.findIndex(el => el == data[i].dataStr) != -1) continue;

                            if (data[i].dataName == '时间戳') data[i].dataStr = 'ts'
                            if (data[i].dataType == '0') {
                                if (!this.optionalFields[data[i].belong]) {
                                    this.$set(this.optionalFields, data[i].belong, [])
                                }
                                this.optionalFields[data[i].belong].push(data[i])
                            }
                            else {
                                this.focusFields.push(data[i])
                                this.colsList.push(Object.assign(data[i], { label: data[i].dataName, prop: data[i].dataStr }))
                            }
                        }
                        this.focusFields.sort((a, b) => a.position - b.position)
                        this.colsList.sort((a, b) => a.position - b.position)
                        let keys = Object.keys(this.optionalFields)
                        let uniqueKeys = Array.from(new Set(['基础字段', '常用字段', ...keys]))
                        let optionFields = {}
                        uniqueKeys.forEach(key => {
                            if (this.optionalFields[key]) {
                                optionFields[key] = this.optionalFields[key]
                            }
                        })
                        this.optionalFields = optionFields
                    }
                    resolve(res)
                }).catch(err => reject(err))
            })
        },
        // 保存关注字段
        saveFields() {
            let focus = JSON.parse(JSON.stringify(this.focusFields))
            let optional = JSON.parse(JSON.stringify(this.optionalFields))
            focus.forEach((el, index) => {
                el.position = index + 1
            })
            Object.keys(optional).forEach(key => {
                optional[key].forEach(el => {
                    focus.push(el)
                })
            })
            let params = focus
            updFieldsType(params).then(res => {
                if (res.data.returnCode == 0) {
                    this.$message({
                        type: 'success',
                        message: '字段已保存'
                    })
                }
            })
        },
        // 恢复默认字段
        resetFields() {
            resetFieldsType().then(res => {
                if (res.data.returnCode == 0) {
                    this.$message({
                        type: 'success',
                        message: '字段已恢复默认'
                    })
                    this.getAllFields()
                }
            })
        },
        addFocusFields(item, index) {
            this.focusFields.push(Object.assign(item, { dataType: '1'}))
            this.colsList.push(Object.assign(item, { dataType: '1', label: item.dataName, prop: item.dataStr }))
            if (this.optionalFieldSearch != '') {
                index = this.optionalFields[item.belong].findIndex(el => el.dataStr == item.dataStr)
            }
            this.optionalFields[item.belong].splice(index, 1)
            if (this.optionalFields[item.belong].length == 0) delete this.optionalFields[item.belong]
        },
        addOptionalFields(item, index) {
            if (!this.optionalFields[item.belong]) this.$set(this.optionalFields, item.belong, [])
            this.optionalFields[item.belong].push(Object.assign(item, { dataType: '0'}))
            this.focusFields.splice(index, 1)
            this.colsList.splice(index, 1)
        },
        // 快速查询列表
        getFastSearch() {
            return new Promise((resolve, reject) => {
                getQuickSearch().then(res => {
                    if (res.data.returnCode == 0) {
                        let { data } = res.data
                        this.fastQueryList = data
                    }
                    resolve(res)
                }).catch(err => {
                    reject(err)
                })
            })
        },
        refreshChange(val) {
            if (val) {
                this.refreshTimer = setInterval(() => {
                    this.tableQuery('')
                }, val)
            } else clearInterval(this.refreshTimer)
        },
        cellMouseEnter(row, column, cell, event) {
            if (column.label == '操作' || column.type == "expand") return
            this.lastTimeHoverRow = row
            this.lastTimeHoverColumn = column
            this.$nextTick(() => {
                cell.appendChild(this.$refs.tablebtns)
            })
        },
        cellMouseLeave(row, column, cell, event) {
            if (column.label == '操作' || column.type == "expand") return
            this.lastTimeHoverRow = {}
            this.lastTimeHoverColumn = {}
            cell.removeChild(this.$refs.tablebtns)
        },
        dragstart(item) {
            if (!this.dragDisabled) return
            this.draggingItem = item;
        },
        dragover(item) {
            if (!this.dragDisabled) return

            if (item !== this.draggingItem && this.dragLastItem !== item) {
                const fromIndex = this.focusFields.indexOf(this.draggingItem);
                const toIndex = this.focusFields.indexOf(item);
                const temp = this.focusFields[fromIndex];
                this.focusFields[fromIndex] = this.focusFields[toIndex];
                this.focusFields[toIndex] = temp;
                this.focusFields = [...this.focusFields];
                this.colsList = JSON.parse(JSON.stringify(this.focusFields))
                this.tableKey = !this.tableKey
            }
            this.dragLastItem = item;
        },
        datePickerChange(val) {
          console.log(this.time)
            if (val.length == 3) this.customDate = val[2]
            this.cacheFieldAggregate = {}
            this.tableQuery('')
        },
        handlePageChange(order) {
            if ((order != 'prev' && !this.pagination.hasNextPage) || ( order == 'prev' && this.pagination.start == 1)) return
            this.getList(order)
        },
        getList(order = '') {
            let uuid = ''
            if (order == 'prev') {
                uuid = this.uuid[this.uuid.length - 3]
                this.pagination.start--
            } else if (order == 'next') {
                uuid = this.uuid[this.uuid.length - 1]
                this.pagination.start++
            }
            let params = {
                params: {
                    startTime: parseTime(this.time[0]),
                    endTime: parseTime(this.time[1]),
                    sort: 'timestamp',
                    order: 'desc',
                    filterString: this.queryStatements,
                    uuid
                },
                page: {
                    current: this.pagination.start,
                    size: this.pagination.pageSize
                }
            }
            this.tableLoading = true
            getHostThreat(params).then(res => {
                if (res.data.returnCode == '0') {
                    let { list, page } = res.data.data
                    let { current, size, total } = page
                    this.pagination.totalNum = total
                    this.pagination.totalPage = Math.ceil(total / size)
                    this.pagination.hasNextPage = total < current * size ? false : true
                    this.tableData = list
                    this.tableData.forEach(el => {
                        if (!el.is_collect) this.$set(el, 'is_collect', '0')
                        if (!el.is_read) this.$set(el, 'is_read', '0')
                        // el.find_time = parseTime(el.ts)
                    })
                    this.setScrollWidth()
                    if (order === '') {
                        this.uuid = ['']
                        this.uuid.push(list[list.length - 1].timestamp)
                    } else {
                        if (order === 'next') {
                            this.uuid.push(list[list.length - 1].timestamp)
                        } else {
                            this.uuid.pop()
                        }
                    }
                }
                this.tableLoading = false
            }).catch(() => {
                this.tableLoading = false
            })
        },
        pageSizeChange(val) {
            this.pagination.start = 1
            this.pagination.pageSize = val
            this.tableQuery('')
        },
        // 收藏/当前页已读
        updHostThreat(rows, type, val, index) {
            let params = JSON.parse(JSON.stringify(rows))
            params.forEach(el => {
                if (type == 'collect') el.is_collect = val
                else el.is_read = val
            })
            updHostThreatById(params).then(res => {
                if (res.data.returnCode == 0) {
                    this.$message.success(`${type == 'collect' && val == 0 ? '取消' : ''}${type == 'collect' ? '收藏' : '操作'}成功`)
                    if (type == 'collect') {
                        this.tableData[index].is_collect = val
                    } else {
                        rows.forEach(el => el.is_read = 1)
                    }
                }
            }).catch(() => {

            })
        },
        // 导出
        exportFile(row) {
            // let log_time = this.allFields.filter(el => el.dataStr == 'receive_log_time')[0]
            let log_time = { dataName: '发现时间', dataStr: 'find_time' }
            let focus = JSON.parse(JSON.stringify(this.focusFields))
            focus.unshift(log_time)
            let params = {
                startTime: parseTime(this.time[0]),
                endTime: parseTime(this.time[1]),
                uuid: row == null?[]:[row.uuid],
                filterString: this.queryStatements,
                sort: 'timestamp',
                order: 'desc',
                focusFields: focus
            }
            this.$message.info("正在生成导出文件,请稍等");
            exportHostThreat(params).then(res => {
                if (res.data.returnCode == 0) {
                  this.$message.success('已加入离线任务队列，请在离线任务栏进行查看')
                  // window.open(`${this.$util.getAjaxUrl('analyse')}/${res.data.data.url}`, '_blank')
                }

            }).catch(() => {

            })
        },
        getTime() {
            switch(this.customDate) {
                case 1: // 5
                    this.time = [Date.now() - 1000 * 60 * 5 , Date.now()]
                    break
                case 2: // 15
                    this.time = [Date.now() - 1000 * 60 * 15 , Date.now()]
                    break
                case 3: // 30
                    this.time = [Date.now() - 1000 * 60 * 30 , Date.now()]
                    break
                case 4: // 1
                    this.time = [Date.now() - 1000 * 60 * 60 , Date.now()]
                    break
                case 5: // 4
                    this.time = [Date.now() - 3600 * 1000 * 4 , Date.now()]
                    break
                case 6: // 12
                    this.time = [Date.now() - 3600 * 1000 * 12 , Date.now()]
                    break
                case 7: // 1天
                    this.time = [Date.now() - 3600 * 1000 * 24 , Date.now()]
                    break
                case 8: // 1周
                    this.time = [Date.now() - 3600 * 1000 * 24 * 7 , Date.now()]
                    break
                case 9: // 1月
                    this.time = [Date.now() - 3600 * 1000 * 24 * 31 , Date.now()]
                    break
                case 10: {
                    let start = new Date();
                    start.setHours(0)
                    start.setMinutes(0)
                    start.setSeconds(0)
                    this.time = [start.getTime(), Date.now()]
                    break
                }
                case 11: {
                    let { startDay, endDay } = this.getWeekTime(Date.now())
                    this.time = [startDay, endDay]
                    break
                }
                case 12: {
                    let { startDay, endDay } = this.getMonthTime(Date.now())
                    this.time = [startDay, endDay]
                    break
                }
            }
        },
        getWeekTime(time) {
            let dayCode = new Date(time).getDay();
            let dayLong = 24*60*60*1000;
            return {
                startDay: new Date(dayCode === 0 ? time-dayLong*7 : time-dayLong*(dayCode-1)).getTime(),
                endDay: new Date(dayCode === 0 ? time : time+dayLong*(7-dayCode)).getTime()
            }
        },
        getMonthTime(time) {
            let currentDay = new Date(time);
            let currentFullYear = currentDay.getFullYear();
            let currentMonth = currentDay.getMonth();
            return {
                startDay: new Date(currentDay.setDate(1)).getTime(),
                endDay: new Date(new Date(currentFullYear,currentMonth+1,0)).getTime()
            }
        },
        addFilterItem(item, query = true) {
            let i = this.filterConditionList.findIndex(element => element.value == item.value)
            let obj = {
                key: item.key,
                value: item.value,
                symbol: item.symbol,
                name: item.name,
                query: item.query,
                status: item.status || 'positive',
                disabled: item.disabled || false
            }
            if (/\d/g.test(String(this.addFilterModifyIndex))) {
                this.filterConditionList[this.addFilterModifyIndex] = obj
            } else {
                if (i == -1) {
                    this.filterConditionList.push(obj)
                } else {
                    this.filterConditionList[i] = obj
                }
            }
            if (query) this.tableQuery('')
        },
        addFilterQueryCondition(type) {
            let obj = {}
            if (type == 'custom') {
                let { children } = this.addFilterTreeData[0]
                if (children.length == 0) {
                    this.$message.info('请至少填写一个过滤条件')
                }
                else if (children.some(el => !el.key || !el.symbol || ((el.symbol != '10' && el.symbol != '11') && !el.value))) {
                    this.$message.info('请填写完全后，提交保存')
                } else {
                    let len = children.length - 1
                    let key = '',value = '',symbol = '', name = '', query = '';
                    children.forEach((el, index) => {
                        let current = this.allFields.filter(item => item.dataStr == el.key)[0] || el.key
                        key += (el.key + ',');
                        value += (el.value + ',');
                        symbol += (el.symbol + ',');
                        name += (`${spliceSql(current.dataName, el.symbol, el.value).name} ${len == index ? '' : this.addFilterRootSelect} `)
                        query += (`${spliceSql(el.key, el.symbol, el.value).query} ${len == index ? '' : this.addFilterRootSelect} `)
                    })
                    obj = {
                        key,
                        value,
                        symbol,
                        name,
                        query,
                        status: 'positive',
                        disabled: false
                    }
                    this.addFilterItem(obj)
                    this.resetFilterDialog()
                    this.addFilterVisible = false
                }
            } else {
                if (this.lastTimeHoverColumn.label == '发现时间') {
                    obj = {
                        key: "timestamp",
                        value: this.lastTimeHoverRow.timestamp,
                        symbol: type == 'positive' ? '1' : '2',
                        name: `时间戳 == ${this.lastTimeHoverRow.timestamp}`,
                        query: `${type == 'positive' ? '' : 'NOT '}timestamp : "${this.lastTimeHoverRow.timestamp}"`,
                        status: type,
                        disabled: false
                    }
                } else {
                    let cols = this.colsList.filter(el => el.label == this.lastTimeHoverColumn.label)[0]
                    if (!this.lastTimeHoverRow[cols.prop]) {
                        obj = {
                            key: cols.dataStr,
                            value: this.lastTimeHoverRow[cols.prop],
                            symbol: type == 'positive' ? '11' : '10',
                            name: `${cols.label} 不存在`,
                            query: `${type == 'positive' ? 'NOT ' : ''}${cols.dataStr} :*`,
                            status: type,
                            disabled: false
                        }
                    } else {
                        obj = {
                            key: cols.dataStr,
                            value: this.lastTimeHoverRow[cols.prop],
                            symbol: type == 'positive' ? '1' : '2',
                            name: `${cols.label} == ${this.lastTimeHoverRow[cols.prop]}`,
                            query: `${type == 'positive' ? '' : 'NOT '}${cols.dataStr} : "${this.lastTimeHoverRow[cols.prop]}"`,
                            status: type,
                            disabled: false
                        }
                    }

                }
                this.addFilterItem(obj)
            }
        },
        // 重置条件
        resetCondition() {
            this.pagination.start = 1
            this.pagination.pageSize = 20
            this.querySearchValue = ''
            this.isRead = ''
            this.isCollection = ''
            this.tableQuery('')
        },
        // 获取字段聚合
        getFieldAggregate(field) {
            return new Promise((resolve, reject) => {
                let params = {
                    field: field,
                    startTime: parseTime(this.time[0]),
                    endTime: parseTime(this.time[1])
                }
                getFieldAggregate(params).then(res => {
                    if (res.data.returnCode == 0) {
                        resolve(res.data.data.filter(el => el.field != ''))
                    } else {
                        reject([])
                    }
                }).catch(err => {
                    reject(err)
                })
            })
        },
        async dialogQuerySearch(queryString, cb, item) {
            if (item.key == '' || item.symbol == '') {
                cb([])
                return
            }
            if (!this.cacheFieldAggregate[item.key]) {
                let data = await this.getFieldAggregate(item.key)
                this.cacheFieldAggregate[item.key] = data.map(el => {
                    el.label = el.value = el.field
                    return el
                })
            }

            if (queryString) {
                cb(this.cacheFieldAggregate[item.key].filter(el =>  el.field.includes(queryString)))
            } else {
                cb(this.cacheFieldAggregate[item.key])
            }
        },
        querySearch(queryString, cb) {
            if (this.status == 3) {
                cb([{value: ''}])
                return
            }
            this.$nextTick(async () => {
                let result = await this.matchQuery(queryString ? queryString : '')
                cb(result)
            })
        },
        matchQuery(queryString) {
            return new Promise(async (resolve, reject) => {
                let filters = []
                if (queryString.replace(/NOT/g, '').trim() == '' || /^\s*$/.test(queryString)) {
                    this.status = 1
                    resolve(this.getQueryFields())
                    return
                }
                // 匹配key : val AND, key : val AND....
                let allKeyValue = queryString.replace(/NOT/g, '').match(/([\w|\u4e00-\u9fa5]+\s*(:\*|:)?\s*"?([^AND|OR])*"?\s*(AND|OR)?)+/g)
                // [key, :, val]
                let keyValue = allKeyValue[allKeyValue.length - 1].split(' ').filter(el => el.length)
                if (queryString.endsWith(' ')) {
                    if (keyValue[3]) {
                        this.status = 1
                        resolve(this.getQueryFields())
                    } else if (keyValue[2]) {
                        this.status = 2
                        filters = [
                            { label: 'AND(条件必须同时满足)', value: 'AND' },
                            { label: 'OR(条件满足任意一个)', value: 'OR' }
                        ]
                        resolve(filters)
                    } else if (keyValue[1]) {
                        this.status = 2
                        let data = await this.getFieldAggregate(keyValue[0])
                        this.cacheFieldAggregate[keyValue[0]] = data.map(el => {
                            el.label = el.value = el.field
                            return el
                        })
                        resolve(this.cacheFieldAggregate[keyValue[0]])
                    } else if (keyValue[0]) {
                        this.status = 2
                        filters = [
                            { label: ':(等于)', value: ':' },
                            { label: ':*(存在)', value: ':*' },
                        ]
                         resolve(filters)
                    }
                } else {
                    if (keyValue[3]) {
                        this.status = 2
                        filters = [
                            { label: 'AND(条件必须同时满足)', value: 'AND' },
                            { label: 'OR(条件满足任意一个)', value: 'OR' }
                        ]
                        resolve(filters)
                    } else if (keyValue[2]) {
                        this.status = 2
                        if (!this.cacheFieldAggregate[keyValue[0]]) {
                            let data = await this.getFieldAggregate(keyValue[0])
                            this.cacheFieldAggregate[keyValue[0]] = data.map(el => {
                                el.label = el.value = el.field
                                return el
                            })
                        }
                        resolve(this.cacheFieldAggregate[keyValue[0]])
                    } else if (keyValue[1]) {
                        this.status = 2
                         filters = [
                            { label: ':(等于)', value: ':' },
                            { label: ':*(存在)', value: ':*' },
                        ]
                         resolve(filters)
                    } else {
                        this.status = 1
                        resolve(this.getQueryFields(true, keyValue[0]))
                    }
                }

            })
        },
        eidtFilterCondition(item, index) {
            this.filterTitle = '修改'
            this.addFilterTreeData = [{
                id: '0',
                children: [
                    { id: '1', key: '', value: '', symbol: '' }
                ]
            }]
            let key = item.key.split(',').filter(el => el != '')
            let value = (item.value + '').split(',').filter(el => el != '')
            let symbol = item.symbol.split(',').filter(el => el != '')
            for (let i = 0; i < key.length; i++) {
                if (!this.addFilterTreeData[0].children[i]) {
                    this.$set(this.addFilterTreeData[0].children, i, {
                        id: this.addFilterTreeData[0].children[i - 1] ? (+this.addFilterTreeData[0].children[i - 1].id + 1) : '1',
                        key: '',
                        value: '',
                        symbol: ''
                    })
                }
                this.addFilterTreeData[0].children[i].key = key[i];
                this.addFilterTreeData[0].children[i].symbol = symbol[i];
                this.addFilterTreeData[0].children[i].value = value[i];
            }
            this.addFilterModifyIndex = index
            if (item.query.includes('OR')) {
                this.addFilterRootSelect = 'OR'
            } else {
                this.addFilterRootSelect = 'AND'
            }
            this.addFilterVisible = true
        },
        t(val, prop) {
            return this.appointHeads.includes(prop) ? i18n.zh[prop + '_' + val] : i18n.zh[val]
        }
    },
    created() {
      if(this.$route.query.uuid) {
        //告警详情页面跳转过来的查询参数生成
        this.queryStatements = 'uuid : \"'+this.$route.query.uuid+'\"';
        this.querySearchValue = 'uuid : \"'+this.$route.query.uuid+'\"';
      }
      if (this.$route.query.occurTime) {
        this.customDate = 0;
        var date = this.$route.query.occurTime;
        date = date.substring(0,19);
        date = date.replace(/-/g,'/');
        var timestamp = new Date(date).getTime();
        // 根据毫秒数构建 Date 对象
        var startDate = new Date(timestamp-1000*60*60*3);
        var endDate = new Date(timestamp+1000*60*60*3);
        this.time = [startDate , endDate]
        // 格式化日期
      }else if(this.$route.query.timestamp){
        console.log(this.$route.query.timestamp)
        this.customDate = 0;
        // 根据毫秒数构建 Date 对象
        var timestamp = this.$route.query.timestamp;
        var startDate = new Date(timestamp-1000*60*60*3);
        console.log(timestamp)
        console.log(startDate)
        var endDate = new Date(startDate.getTime()+1000*60*60*3*2);
        console.log(endDate)
        this.time = [startDate , endDate]
      } else {
        this.getTime()
      }
    },
    async mounted() {
        this.tableLoading = true
        await this.getFastSearch()
        this.collectionList()
        await this.getAllFields()
        this.getList()

        let mainScrllFn = debounce(this.verticalScroll, 100)
        let resizeFn = debounce(this.setScrollWidth, 10)

        document.querySelector('.app-main').addEventListener('scroll', mainScrllFn)
        document.querySelector('.table .el-table__body-wrapper').addEventListener('scroll', (e) => {
            this.$refs['scroll'].scrollLeft = e.target.scrollLeft
        })
        window.addEventListener('resize', resizeFn)

        this.$once("hook:beforeDestroy", () => document.querySelector('.app-main').removeEventListener('scroll', mainScrllFn))
        this.$once("hook:beforeDestroy", () => window.removeEventListener('resize', resizeFn))
    }
}
</script>

<style lang="scss" scoped>
    @import './styles/sprite.css';
    .fenceView {
        background: rgb(242, 242, 242);
        .marginLeft {
            margin-left: .4vw;
        }
        .marginBottom {
            margin-bottom: .4vw;
        }
        .marginTop {
            margin-top: .4vw;
        }
        &-header {
            padding: .6vw;
            display: flex;
            flex-direction: column;
            background: white;
            .fenceView-fastSearch {
                display: flex;
                flex: 3 1 0%;
                & > span {
                    display: inline-block;
                    font-size: 12px;
                    text-align: right;
                    line-height: 20px;
                    color: #999;
                    white-space: nowrap;
                }
                &-tag {
                    display: flex;
                    justify-content: space-between;
                }
                &-searchList {
                    display: flex;
                    flex-wrap: wrap;
                    overflow-y: hidden;
                }
                &-searchItem {
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    flex-wrap: wrap;
                    height: 20px;
                    line-height: 20px;
                    text-align: center;
                    font-size: 12px;
                    width: 100px;
                    border: 1px solid #409EFF;
                    background: #f0f6fa;
                    color: #409EFF;
                    cursor: pointer;
                    position: relative;
                    & > span {
                        display: inline-block;
                        width: 80px;
                        text-overflow: ellipsis;
                        overflow: hidden;
                        white-space: nowrap;
                    }
                }
                &-btn {
                    font-size: 12px;
                    color: #409EFF;
                    height: 20px;
                    line-height: 20px;
                    min-width: 80px;
                    cursor: pointer;
                    text-align: center;
                }
            }

            .fenceView-custom {
                flex: 1 1 0%;
                display: flex;
                .el-date-editor ::v-deep .el-range-separator {
                    width: auto;
                }
                .el-date-editor {
                    padding: 3px 0 3px 10px;
                }
            }

            .fenceView-search-wapper {
                display: flex;
                .el-divider {
                    height: 30px;
                    margin: 0 20px;
                }
            }

            .fenceView-filterConditions-wrapper {
                .filterConditions-btns {
                    font-size: 12px;
                    font-weight: 500;
                    & > span {
                        cursor: pointer;
                    }
                    & > :nth-child(1) {
                        color: #409EFF;
                    }
                    & > :nth-child(2) {
                        color: #EC5759;
                    }
                }
                .el-divider--horizontal {
                    margin: 12px 0;
                }
                .filterConditions-list {
                    display: flex;
                    flex-wrap: wrap;
                    &-item {
                        width: 180px;
                        height: 20px;
                        margin: 5px;
                        padding: 0 8px;
                        line-height: 20px;
                        text-align: center;
                        text-overflow: ellipsis;
                        overflow: hidden;
                        white-space: nowrap;
                        font-size: 12px;
                        .text {
                            display: block;
                            white-space: nowrap;
                            text-overflow: ellipsis;
                            overflow: hidden;
                        }
                        .operations {
                            display: none;
                            .el-col {
                                cursor: pointer;
                            }
                        }
                        &:hover .text {
                            display: none;
                        }
                        &:hover .operations {
                            display: flex;
                        }
                    }
                    .item--positive {
                        color: #409EFF;
                        border: 1px solid #409EFF;
                        background: #ECF5FF;
                    }
                    .item--back {
                        color: #F56C6C;
                        border: 1px solid #F56C6C;
                        background: #FEF0F0;
                    }
                    .item--disabled {
                        color: #909399;
                        border: 1px solid #909399;
                        background: #F4F5F5;
                    }
                }
            }
        }

        &-content {
            .fenceView-searchRecordNum {
                font-size: 12px;
                color: #303133;
                padding-left: 10px;
            }
            .fenceView-charts {
                display: flex;
                flex-wrap: wrap;
                &-item {
                    flex: 0 0 33%;
                    height: 280px;
                    &:not(:nth-child(1)){
                        margin-left: .4vw;
                    }

                    &:nth-child(4) {
                        margin-left: 0;
                    }
                }
            }
            .charts-btn {
                width: 100%;
                text-align: right;
                font-size: 12px;
                color: #409EFF;
                height: 20px;
                line-height: 20px;
                min-width: 80px;
                cursor: pointer;
            }
        }

        &-footer {
            background: white;
            padding: 20px 20px 20px 0;
            .field-list {
                transition: width .2s linear;
            }
            .box-card {
                box-shadow: none;
                ::-webkit-scrollbar {
                    height: 1px;
                    width: 11px;
                }
                i {
                    cursor: pointer;
                }
                &-header {
                    font-size: 16px;
                    color: #000000CC;
                    display: flex;
                    justify-content: space-between;
                }
                &-btns {
                    padding: 10px;
                    color: #409EFF;
                    text-align: right;
                    font-size: 12px;
                    span {
                        cursor: pointer;
                    }
                    & > :first-child {
                        position: relative;
                        margin-right: 8px;
                        &::after {
                            content: '';
                            display: block;
                            height: 16px;
                            width: 1px;
                            position: absolute;
                            right: -8px;
                            top: 50%;
                            transform: translateY(-50%);
                            background-color: #dcdfe6;
                        }
                    }
                    & > :last-child {
                        margin-left: 8px;
                    }
                }

                .field-title {
                    padding-top: 5px;
                }

                .field-item {
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    width: 100%;
                    font-size: 12px;
                    ::v-deep .el-checkbox__label {
                        font-size: 12px;
                        color: #000000CC;
                    }
                }

                .optional-input {
                    margin: .4vw 0;
                }
            }

            .table-wrapper {
                font-size: 12px;
                .table {
                    position: relative;
                    ::-webkit-scrollbar{
                        height: 11px;
                    }
                    .scroll {
                        position: fixed;
                        bottom: 0;
                        overflow-x: scroll;
                        z-index: 11;
                    }
                }
                .el-link--primary {
                    font-size: 12px;
                }
                .nowrap {
                    text-overflow: ellipsis;
                    overflow: hidden;
                    white-space: nowrap;
                }
                .pagination {
                    display: flex;
                    align-items: center;
                    font-size: 14px;
                    white-space: nowrap;
                }
            }
        }
        .tableBtns {
            display: flex;
            position: absolute;
            top: 0;
            right: 0;
            .el-tag {
                padding: 0 5px;
                border-radius: 15px;
                transform: scale(.8);
                height: 20px;
                line-height: 20px;
                cursor: pointer;
            }
            .success {
                border: 1px solid #67C23A;
            }
            .danger {
                border: 1px solid #F56C6C;
            }
        }
        .el-tree-node {
            width: auto;
        }
        ::v-deep .el-tree-node__content {
            height: 32px;
        }
        ::v-deep .el-tree-node__children .el-tree-node__content {
            height: 40px;
        }
        .custom-tree-node {
            width: 100%;
        }
        .el-icon-info {
            font-size: 20px;
            color: #409EFF;
            position: absolute;
            right: -30px;
            top: 50%;
            transform: translateY(-50%);
            cursor: pointer;
        }

        ::-webkit-scrollbar-thumb {
            border-radius: 2px;
            box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
            background: #dcdee2;
        }
        .flip-list-move {
            transition: transform 0.3s;
        }
        .button-star {
            color: rgb(253, 203, 61);
            &:hover {
                border-color: rgb(253, 203, 61);
            }
        }
    }
</style>

<style>
    .fenceView .el-dialog__header {
        border-bottom: 1px solid #ebeef5;
    }
    .fenceView .el-dialog__body {
        padding: 20px 20px;
    }
    .fenceView .el-dialog__footer {
        border-top: 1px solid #ebeef5;
    }
    .fenceView .el-autocomplete-suggestion li:hover {
        background: white;
        cursor: unset;
    }
    .fenceView .remark {
        font-size: 12px;
    }
    .fenceView .remark > :first-child {
        font-size: 16px;
    }
    .fenceView .remark > div, .fenceView .remark > p {
        line-height: normal;
        white-space: pre-wrap;
    }
    .fenceView .keyword {
        color: #409EFF;
    }
    .fenceView .keyword-yellow {
        color: rgb(253, 203, 61);
    }
    .el-tooltip__popper {
        max-width: 80%;
    }
</style>
