elementui table實現動態將列固定到左側(fixed)

前言

這個功能是是elementui表格的列拖拽及動態顯示列實現基礎上進行的功能增強

在開始之前請自行查詢v-contextmenu 組件的安裝以及全局引用
注:後端開發前端實現並不規範,主要講個思路,代碼優化看你了(如果有可以私信或者評論告訴我,跪謝)

正文

  1. 創建下拉菜單
   <div v-show="menuVisible">
            <v-contextmenu ref="contextmenu" id="menu">
                <v-contextmenu-item @click="lock">鎖定</v-contextmenu-item>
                <v-contextmenu-item @click="unlock">解鎖</v-contextmenu-item>
            </v-contextmenu>
        </div>

2.綁定table的header右鍵事件:

 <el-table
                v-loading="listLoading"
                :data="list"
                border
                fit
                size="mini"
                :row-class-name="rowClassName"
                :cell-class-name="cellClassName"
                highlight-current-row
                style="width: 100%;margin-top: 20px"
                @selection-change="handleSelectionChange"
                @sort-change="changeSort"
                @header-contextmenu="rightClick"
                ref="filterTable"
        >
            <el-table-column
                    type="selection"
                    fixed="left"
                    width="55">
            </el-table-column>
            <el-table-column type="index" align="center" width="50"   fixed="left">
            </el-table-column>
            <el-table-column v-for="(item, index) in col"
                             v-if="col[index].prop!=='select'&&col[index].prop!=='index'"
                             align="center"
                             :index="index"
                             :sortable="dropCol[index].sort"
                             show-overflow-tooltip
                             :width="dropCol[index].width?dropCol[index].width:'200px'"
                             :key="`col_${index}`"
                             :fixed="dropCol[index].fixed"
                             :prop="dropCol[index].prop"
                             :label="item.label">
                <template slot-scope="scope">
                    <span>{{ !dropCol[index].type?scope.row[dropCol[index].prop]:getValue(scope.row,dropCol[index].type),dropCol[index].prop }}</span>
                </template>
            </el-table-column>
            <el-table-column label="操作" align="center" fixed="right" width="200" class-name="small-padding fixed-width">
                <template slot-scope="scope">
                    <el-dropdown trigger="hover">
            <span class="el-dropdown-link">
              操作菜單<i class="el-icon-arrow-down el-icon--right"></i>
            </span>
                        <el-dropdown-menu slot="dropdown">
                            <el-dropdown-item class="el-dropdown-link" @click.native="cpuInfo(scope.row)">硬件信息
                            </el-dropdown-item>
                            <!--              <el-dropdown-item class="el-dropdown-link" @click.native="memoryInfo(scope.row)">內存信息</el-dropdown-item>-->
                            <!--              <el-dropdown-item class="el-dropdown-link" @click.native="nicInfo(scope.row)">網卡信息</el-dropdown-item>-->
                            <!--              <el-dropdown-item class="el-dropdown-link" @click.native="diskInfo(scope.row)">硬盤信息</el-dropdown-item>-->
                            <el-dropdown-item class="el-dropdown-link" @click.native="historyInfo(scope.row)">歷史變更
                            </el-dropdown-item>
                            <el-dropdown-item class="el-dropdown-link" @click.native="editDevice(scope.row)">編輯資產
                            </el-dropdown-item>
                            <el-dropdown-item class="el-dropdown-link" @click.native="deleteDevice(scope.row)">刪除資產
                            </el-dropdown-item>
                        </el-dropdown-menu>
                    </el-dropdown>
                </template>
            </el-table-column>
        </el-table>
  1. 禁用原有的右鍵事件
document.oncontextmenu = function(){
                return false;
            }
  1. 配置列表信息
 let allCols = [
                    {prop: "select", label: "選擇", sort: true},
                    {prop: "index", label: "序號", sort: true},
                    {prop: "name", label: "設備型號", sort: true,fixed:false},
                    {prop: "cluster.name", label: "集羣", type: "cluster", sort: false,fixed:false},
                    {prop: "type", label: "服務器分類", sort: true,fixed:false},
                    {prop: "sn", label: "設備序列號", sort: true,fixed:false},
                    {prop: "manageIp", label: "管理網", sort: true,fixed:false},
                    {prop: "illoIp", label: "ILLO地址", sort: true,fixed:false},
                    {prop: "period", label: "期數", sort: true,fixed:false},
                    {prop: "position", label: "機架位置", sort: true,fixed:false},
                    {prop: "publicIp", label: "公網", sort: true,fixed:false},
                    {prop: "cn2Ip", label: "CN2", sort: true,fixed:false},
                    {prop: "status", label: "狀態", type: "status", sort: true,fixed:false},
                    {prop: "outIp", label: "存儲外網", sort: true,fixed:false},
                    {prop: "systemVersion", label: "系統版本", sort: true,fixed:false},
                    {prop: "osVersion", label: "內核版本", sort: true,fixed:false},
                    {prop: "use", label: "用途", sort: true,fixed:false},
                    {prop: "deliveryDate", label: "交付日期", type: "date", sort: true,fixed:false},
                    {prop: "resourcePool", label: "資源池", type: "resourcePool", sort: true,fixed:false},
                    {prop: "useUser", label: "申請人", sort: true,fixed:false},
                    {prop: "tag", label: "項目名稱", sort: true,fixed:false},
                    {prop: "remarks", label: "備註", sort: true,fixed:false},
                    {prop: "computerPosition", label: "機房位置", sort: true,fixed:false},
                    {prop: "desc", label: "硬件信息", width: "700px", sort: false,fixed:false},
                ]
  1. 右鍵事件處理方法
//右鍵點擊
            rightClick(column, event) { // 鼠標右擊觸發事件
                this.menuVisible = false // 先把模態框關死,目的是 第二次或者第n次右鍵鼠標的時候 它默認的是true
                this.menuVisible = true  // 顯示模態窗口,跳出自定義菜單欄
                let menu = document.querySelector('#menu')
                document.addEventListener('click', this.foo) // 給整個document添加監聽鼠標事件,點擊任何位置執行foo方法
                menu.style.display = "block";
                menu.style.left = event.clientX + 'px'
                menu.style.top = event.clientY + 'px'
                this.index=column.index

            },
            lock(){
                this.dropCol[this.index].fixed="left"

            },
            unlock(){
                this.dropCol[this.index].fixed=false
            },
            foo() { // 取消鼠標監聽事件 菜單欄
                let menu = document.querySelector('#menu')
                this.menuVisible = false
                menu.style.display = "none";

                document.removeEventListener('click', this.foo) // 要及時關掉監聽,不關掉的是一個坑,不信你試試,雖然前臺顯示的時候沒有啥毛病,加一個alert你就知道了
            },

和上篇博客一樣,這裏附上完整代碼,如果拆開看不太懂可以參考完整代碼

<template>
    <d2-container>
        <template slot="header">
            <el-form :inline="true" :model="listQuery" ref="searchForm" size="mini" style="margin-bottom: -18px;">
                <el-form-item>
                    <el-button @click="search" size="mini">
                        <d2-icon name="search"/>
                        搜索
                    </el-button>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" size="mini" icon="el-icon-circle-plus" @click="createDevice">創建資產
                    </el-button>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" size="mini" icon="el-icon-circle-plus" @click="changeCols">修改顯示列
                    </el-button>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" size="mini" icon="el-icon-circle-plus" @click="addHs">添加歷史變更</el-button>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" size="mini" icon="el-icon-circle-plus" @click="saveOrder">保存顯示順序
                    </el-button>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" size="mini" icon="el-icon-circle-plus" @click="exportRepair">導出設備信息
                    </el-button>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" size="mini" icon="el-icon-circle-plus" @click="addTag">增加標籤</el-button>
                </el-form-item>
                <el-form-item>
                    <el-upload
                            :action="deviceUrl"
                            :show-file-list=false
                            :on-success="handleAvatarSuccess"
                    >
                        <el-button size="mini" type="primary" icon="el-icon-circle-plus">

                            導入
                        </el-button>
                    </el-upload>
                </el-form-item>
            </el-form>
        </template>
<!--        //@header-contextmenu="rightClick"-->
        <el-table
                v-loading="listLoading"
                :data="list"
                border
                fit
                size="mini"
                :row-class-name="rowClassName"
                :cell-class-name="cellClassName"
                highlight-current-row
                style="width: 100%;margin-top: 20px"
                @selection-change="handleSelectionChange"
                @sort-change="changeSort"
                @header-contextmenu="rightClick"
                ref="filterTable"
        >
            <el-table-column
                    type="selection"
                    fixed="left"
                    width="55">
            </el-table-column>
            <el-table-column type="index" align="center" width="50"   fixed="left">
            </el-table-column>
            <el-table-column v-for="(item, index) in col"
                             v-if="col[index].prop!=='select'&&col[index].prop!=='index'"
                             align="center"
                             :index="index"
                             :sortable="dropCol[index].sort"
                             show-overflow-tooltip
                             :width="dropCol[index].width?dropCol[index].width:'200px'"
                             :key="`col_${index}`"
                             :fixed="dropCol[index].fixed"
                             :prop="dropCol[index].prop"
                             :label="item.label">
                <template slot-scope="scope">
                    <span>{{ !dropCol[index].type?scope.row[dropCol[index].prop]:getValue(scope.row,dropCol[index].type),dropCol[index].prop }}</span>
                </template>
            </el-table-column>
            <el-table-column label="操作" align="center" fixed="right" width="200" class-name="small-padding fixed-width">
                <template slot-scope="scope">
                    <el-dropdown trigger="hover">
            <span class="el-dropdown-link">
              操作菜單<i class="el-icon-arrow-down el-icon--right"></i>
            </span>
                        <el-dropdown-menu slot="dropdown">
                            <el-dropdown-item class="el-dropdown-link" @click.native="cpuInfo(scope.row)">硬件信息
                            </el-dropdown-item>
                            <!--              <el-dropdown-item class="el-dropdown-link" @click.native="memoryInfo(scope.row)">內存信息</el-dropdown-item>-->
                            <!--              <el-dropdown-item class="el-dropdown-link" @click.native="nicInfo(scope.row)">網卡信息</el-dropdown-item>-->
                            <!--              <el-dropdown-item class="el-dropdown-link" @click.native="diskInfo(scope.row)">硬盤信息</el-dropdown-item>-->
                            <el-dropdown-item class="el-dropdown-link" @click.native="historyInfo(scope.row)">歷史變更
                            </el-dropdown-item>
                            <el-dropdown-item class="el-dropdown-link" @click.native="editDevice(scope.row)">編輯資產
                            </el-dropdown-item>
                            <el-dropdown-item class="el-dropdown-link" @click.native="deleteDevice(scope.row)">刪除資產
                            </el-dropdown-item>
                        </el-dropdown-menu>
                    </el-dropdown>
                </template>
            </el-table-column>
        </el-table>
        <template slot="footer">
            <el-pagination
                    :current-page="page.current"
                    :page-size="page.size"
                    :total="page.total"
                    :page-sizes="[1,100, 200, 300, 400]"
                    layout="total, sizes, prev, pager, next, jumper"
                    style="margin: -10px;"
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
            >
            </el-pagination>
        </template>
        <el-dialog title="Device管理" :visible.sync="dialogFormVisible" :close-on-click-modal=false>
            <el-form :model="temp" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
                <el-form-item label="集羣" prop="cluster">
                    <el-select v-model="temp.clusterId" placeholder="請選擇">
                        <el-option
                                v-for="item in clusterList"
                                :key="item.id"
                                :label="item.name"
                                :value="item.id">
                        </el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="設備型號" prop="name">
                    <el-input v-model="temp.name"></el-input>
                </el-form-item>
                <el-form-item label="期數" prop="period">
                    <el-input v-model="temp.period"></el-input>
                </el-form-item>
                <el-form-item label="管理網" prop="manageIp">
                    <el-input v-model="temp.manageIp"></el-input>
                </el-form-item>
                <el-form-item label="ILLO地址" prop="cluster">
                    <el-input v-model="temp.illoIp"></el-input>
                </el-form-item>
                <el-form-item label="交付日期" prop="deliveryDate">
                    <el-date-picker
                            v-model="temp.deliveryDate"
                            type="date"
                            placeholder="選擇日期">
                    </el-date-picker>
                </el-form-item>
                <el-form-item label="服務器分類" prop="type">
                    <el-input v-model="temp.type"></el-input>
                </el-form-item>
                <el-form-item label="設備類型" prop="deviceType">
                    <el-select v-model="temp.deviceType" placeholder="請選擇">
                        <el-option
                                v-for="item in deviceTypeList"
                                :key="item.deviceType"
                                :label="item.nameZh"
                                :value="item.deviceType">
                        </el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="所屬資源池" prop="resourcePool">
                    <el-select v-model="temp.resourcePool" filterable placeholder="請選擇">
                        <el-option
                                v-for="item in allRp"
                                :key="item.id"
                                :label="item.name"
                                :value="item.id">
                        </el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="設備序列號" prop="sn">
                    <el-input v-model="temp.sn"></el-input>
                </el-form-item>
                <el-form-item label="項目名稱" prop="tag">
                    <tag-select type="program" :value.sync="temp.tag"></tag-select>
                </el-form-item>
                <el-form-item label="機架位置" prop="position">
                    <el-input v-model="temp.position"></el-input>
                </el-form-item>
                <el-form-item label="機房位置" prop="computerPosition">
                    <el-input v-model="temp.computerPosition"></el-input>
                </el-form-item>
                <el-form-item label="公網" prop="publicIp">
                    <el-input v-model="temp.publicIp"></el-input>
                </el-form-item>
                <el-form-item label="存儲外網" prop="inIp">
                    <el-input v-model="temp.outIp"></el-input>
                </el-form-item>
                <el-form-item label="CN2" prop="cn2Ip">
                    <el-input v-model="temp.cn2Ip"></el-input>
                </el-form-item>
                <el-form-item label="系統版本" prop="systemVersion">
                    <el-input v-model="temp.systemVersion"></el-input>
                </el-form-item>
                <el-form-item label="內核版本" prop="osVersion">
                    <el-input v-model="temp.osVersion"></el-input>
                </el-form-item>
                <el-form-item label="用途" prop="use">
                    <el-input v-model="temp.use"></el-input>
                </el-form-item>
                <el-form-item label="備註" prop="remarks">
                    <el-input v-model="temp.remarks"></el-input>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button type="primary" @click="saveDevice('ruleForm')">提交</el-button>
                <el-button @click="resetDeviceForm('ruleForm')">取消</el-button>
            </div>
        </el-dialog>
        <el-dialog title="硬件信息" :visible.sync="CPUVisible" width="80%">
            <el-collapse v-model="collapse">
                <el-collapse-item title="CPU信息" name="1">
                    <cpu :device_type.sync="deviceType"></cpu>
                </el-collapse-item>
                <el-collapse-item title="內存信息" name="2">
                    <memory :device_type.sync="deviceType"></memory>
                </el-collapse-item>
                <el-collapse-item title="硬盤信息" name="3">
                    <disk :device_type.sync="deviceType"></disk>
                </el-collapse-item>
                <el-collapse-item title="網卡信息" name="4">
                    <nic :device_type.sync="deviceType"></nic>
                </el-collapse-item>
            </el-collapse>
        </el-dialog>
        <!--    <el-dialog title="內存信息" :visible.sync="MemoryVisible"  width="80%">-->
        <!--      <memory :device_type.sync="deviceType"></memory>-->
        <!--    </el-dialog>-->
        <!--    <el-dialog title="硬盤信息" :visible.sync="DiskVisible"  width="80%">-->
        <!--      <disk :device_type.sync="deviceType"></disk>-->
        <!--    </el-dialog>-->
        <!--    <el-dialog title="網卡信息" :visible.sync="NicVisible"  width="80%">-->
        <!--      <nic :device_type.sync="deviceType"></nic>-->
        <!--    </el-dialog>-->
        <el-dialog title="歷史變更" :visible.sync="HistoryVisible" width="80%">
            <el-button type="primary" @click="addHistory" style="margin-bottom: 5px">添加歷史變更</el-button>
            <el-timeline>
                <el-timeline-item v-for="item in history"
                                  :key="item.id"
                                  :timestamp="getDateTime(item.createDate)" placement="top">
                    <el-card>
                        <h4>{{item.message}}</h4>
                        <p>XXX 提交於 {{getDateTime(item.createDate)}}</p>
                    </el-card>
                </el-timeline-item>
            </el-timeline>
        </el-dialog>

        <el-dialog title="顯示列編輯" :visible.sync="changeVisible" width="80%">
            <el-transfer v-model="colsList" :data="changeData" :titles="['所有列', '顯示列']"
                         :props="{key: 'value',label: 'desc'}"
            ></el-transfer>
            <div slot="footer" class="dialog-footer">
                <el-button type="primary" @click="saveCols()">提交</el-button>
                <el-button @click="changeVisible=false">取消</el-button>
            </div>
        </el-dialog>
        <el-drawer
                title="搜索條件"
                :visible.sync="searchVisible"
                direction="rtl"
                size="60%"
                :before-close="handleClose">
            <el-form :model="searchForm" label-width="100px" class="demo-ruleForm">
                <el-row>
                    <el-col :offset="20">
                        <el-button @click="handleSearchFormReset" size="mini">
                            <d2-icon name="refresh"/>
                            重置
                        </el-button>
                    </el-col>
                </el-row>

                <el-row v-for="(search,index) in searchForm">
                    <el-col :span="8">
                        <el-form-item label="搜索字段">
                            <el-select v-model="search.key" filterable placeholder="請選擇">
                                <el-option
                                        v-for="item in searchData"
                                        :key="item.value"
                                        :label="item.desc"
                                        :value="item.value">
                                </el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :span="8">
                        <el-form-item label="搜索值">
                            <el-select v-model="search.value" v-if="search.key==='resourcePool'" filterable
                                       placeholder="請選擇">
                                <el-option
                                        v-for="item in allRp"
                                        :key="item.id"
                                        :label="item.name"
                                        :value="item.id">
                                </el-option>
                            </el-select>
                            <el-select v-model="search.value" v-else-if="search.key==='deviceType'" filterable
                                       placeholder="請選擇">
                                <el-option
                                        v-for="item in deviceTypeList"
                                        :key="item.deviceType"
                                        :label="item.nameZh"
                                        :value="item.deviceType">
                                </el-option>
                            </el-select>
                            <el-date-picker
                                    v-else-if="search.key==='deliveryDate'"
                                    v-model="search.value"
                                    type="date"
                                    placeholder="選擇日期">
                            </el-date-picker>
                            <el-select v-model="search.value" v-else-if="search.key==='cluster'" filterable
                                       placeholder="請選擇">
                                <el-option
                                        v-for="item in clusterList"
                                        :key="item.id"
                                        :label="item.name"
                                        :value="item.id">
                                </el-option>
                            </el-select>

                            <el-input v-else v-model="search.value"></el-input>
                        </el-form-item>
                    </el-col>
                    <el-col :span="2" :offset="1">
                        <el-button type="primary" icon="el-icon-plus" @click="addSearchInfo" circle></el-button>
                    </el-col>
                    <el-col :span="2">
                        <el-button v-if="index!==0" type="danger" @click="deleteSearchInfo(index)" icon="el-icon-minus"
                                   circle></el-button>
                    </el-col>
                </el-row>
                <el-form-item>
                    <el-button type="primary" @click="onSearch">立即搜索</el-button>
                    <el-button @click="searchVisible=false">取消</el-button>
                </el-form-item>

            </el-form>
        </el-drawer>

        <el-dialog title="添加標籤" :visible.sync="tagVisible" width="80%">
            <el-form :model="tagList" status-icon ref="ruleForm" label-width="100px" class="demo-ruleForm">
                <el-form-item label="標籤類型" prop="name">
                    <el-select v-model="tagList.type" @change="changeType"
                               placeholder="請選擇">
                        <el-option label="狀態" value="status"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="賦予的值" prop="rpId">
                    <el-select v-model="tagList.id" filterable placeholder="請選擇">
                        <el-option
                                v-for="item in tags"
                                :key="item.id"
                                :label="item.value"
                                :value="item.id">
                        </el-option>
                    </el-select>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button type="primary" @click="saveTag()">提交</el-button>
                <el-button @click="tagVisible=false">取消</el-button>
            </div>
        </el-dialog>
        <div v-show="menuVisible">
            <v-contextmenu ref="contextmenu" id="menu">
                <v-contextmenu-item @click="lock">鎖定</v-contextmenu-item>
                <v-contextmenu-item @click="unlock">解鎖</v-contextmenu-item>
            </v-contextmenu>
        </div>

    </d2-container>
</template>

<script>
    import Sortable from 'sortablejs'
    import Pagination from '@/components/Pagination'
    import {
        fetchList,
        createDevice,
        modifyDevice,
        deleteDevice,
        addHistory,
        addHistories,
        exportRepairInfo,
        addTag
    } from '@/api/device/device' // Secondary package based on el-pagination
    import {findAllDeviceType} from '@/api/device/devicetype'
    import {findAllCluster} from '@/api/device/cluster'
    import {saveColsInfo, saveOrders} from '@/api/device/userInfo'
    import cpu from '@/components/cpu'
    import Memory from "@/components/memory";
    import Disk from "@/components/disk";
    import Nic from "@/components/nic";
    import TagSelect from "@/components/TagSelect";
    import moment from "moment"
    import {mapState} from 'vuex'

    export default {
        name: "device",
        computed: {
            ...mapState('d2admin/permission', [
                'ownRp', 'cols', 'orders', 'allRp'
            ]),
            ...mapState('d2admin/basedata', [
                'tagType', 'allTags'
            ])

        },
        components: {Disk, Memory, Pagination, cpu, Nic, TagSelect},
        data() {
            return {
                menuVisible:false,
                tags: [],
                tagList: {
                    type: null,
                    id: null
                },
                tagVisible: false,
                page: {
                    current: 1,
                    size: 100,
                    total: 0
                },
                searchForm: [{
                    key: null,
                    value: null
                }],
                searchVisible: false,
                col: [],
                dropCol: [],
                rowClassName: "rowClass",
                cellClassName: "cellClass",
                deviceUrl: process.env.VUE_APP_API + "/excel/device",
                collapse: ["1", "2", "3", "4"],
                CPUVisible: false,
                MemoryVisible: false,
                DiskVisible: false,
                NicVisible: false,
                HistoryVisible: false,
                changeVisible: false,
                colsList: [],
                history: [],
                history_deviceId: null,
                deviceType: null,
                temp: {
                    id: null,
                    name: null,
                    clusterId: null,
                    use: null,
                    deliveryDate: null,
                    type: null,
                    manageIp: null,
                    illoIp: null,
                    period: null,
                    remarks: null,
                    deviceType: null,
                    resourcePool: null,
                    sn: null,
                    tag: null,
                    position: null,
                    useUser: null,
                    startDate: null,
                    systemVersion: null,
                    osVersion: null,
                    outIp: null,
                    publicIp: null,
                    cn2Ip: null,
                    computerPosition: null
                },
                list: null,
                total: 0,
                listLoading: true,
                listQuery: {
                    page: 1,
                    limit: 20,
                    searchForm: [],
                    sortForm: null
                },
                dialogFormVisible: false,
                editFlag: 0,
                rules: {
                    // cn2Ip: [
                    //     {required: true, message: '請輸入cn2ip', trigger: 'blur'}
                    // ],
                },
                deviceTypeList: [],
                clusterList: [],
                searchData: [
                    {value: "resourcePool", desc: "資源池"},
                    {value: "cluster", desc: "集羣"},
                    {value: "use", desc: "用途"},
                    {value: "deliveryDate", desc: "交付日期"},
                    {value: "type", desc: "服務器分類"},
                    {value: "sn", desc: "設備序列號"},
                    {value: "deviceType", desc: "設備類型"},
                    {value: "name", desc: "設備型號"},
                    {value: "status", desc: "狀態"},
                    {value: "manageIp", desc: "管理網"},
                    {value: "illoIp", desc: "ILLO地址"},
                    {value: "period", desc: "期數"},
                    {value: "position", desc: "機架位置"},
                    {value: "publicIp", desc: "公網"},
                    {value: "cn2Ip", desc: "CN2"},
                    {value: "outIp", desc: "存儲外網"},
                    {value: "systemVersion", desc: "系統版本"},
                    {value: "osVersion", desc: "內核版本"},
                    {value: "useUser", desc: "申請人"},
                    {value: "tag", desc: "項目名稱"},
                    {value: "remarks", desc: "備註"},
                    {value: "computerPosition", desc: "機房位置"},
                    {value: "desc", desc: "硬件信息"},
                ],
                changeData: [
                    {value: "name", desc: "設備類型"},
                    {value: "cluster.name", desc: "集羣"},
                    {value: "type", desc: "服務器分類"},
                    {value: "sn", desc: "設備序列號"},
                    {value: "resourcePool", desc: "資源池"},
                    {value: "manageIp", desc: "管理網"},
                    {value: "illoIp", desc: "ILLO地址"},
                    {value: "period", desc: "期數"},
                    {value: "position", desc: "機架位置"},
                    {value: "publicIp", desc: "公網"},
                    {value: "cn2Ip", desc: "CN2"},
                    {value: "status", desc: "狀態"},
                    {value: "outIp", desc: "存儲外網"},
                    {value: "systemVersion", desc: "系統版本"},
                    {value: "osVersion", desc: "內核版本"},
                    {value: "use", desc: "用途"},
                    {value: "deliveryDate", desc: "交付日期"},
                    {value: "useUser", desc: "申請人"},
                    {value: "tag", desc: "項目名稱"},
                    {value: "remarks", desc: "備註"},
                    {value: "computerPosition", desc: "機房位置"},
                    {value: "desc", desc: "硬件信息"},
                ],
                multipleSelection: [],
                sortMap: null,
                column:null,
                index:null
            }
        },
        created() {
            this.getList()
            findAllDeviceType().then(response => {
                this.deviceTypeList = response;
            })
            findAllCluster().then(response => {
                this.clusterList = response;
            })
            document.oncontextmenu = function(){
                return false;
            }
        },
        mounted() {
            this.columnDrop()
            this.col = this.getDropCol();
            this.dropCol = this.getDropCol();
        },
        methods: {
            changeSort(row) {
                this.sortMap = new Map();
                let prop = row.prop;
                let order = row.order;
                if (this.sortMap.has(prop)) {
                    if (!order) {
                        this.sortMap.delete(prop)
                    } else if (order === "ascending") {
                        this.sortMap.set(prop, "ASC")
                    } else {
                        this.sortMap.set(prop, "DESC")
                    }
                } else {
                    if (!order) {
                    } else if (order === "ascending") {
                        this.sortMap.set(prop, "ASC")
                    } else {
                        this.sortMap.set(prop, "DESC")
                    }
                }
                this.getList()
            },
            changeType(val) {
                if (val) {
                    this.tags = this.allTags[val]
                }
            },
            addTag() {
                this.tagList = {
                    type: null,
                    id: null
                }
                this.tagVisible = true

            },
            handleSearchFormReset() {
                this.listQuery.searchForm = []
                this.searchForm = [{
                    key: null,
                    value: null
                }]
                this.getList();
            },
            onSearch() {
                this.getList();
                this.searchVisible = false;
            },
            addSearchInfo() {
                this.searchForm.push({
                    key: null,
                    value: null
                })
            },
            deleteSearchInfo(index) {
                this.searchForm.splice(index, 1);
            },
            search() {
                this.searchVisible = true;
            },
            handleClose(done) {
                this.$confirm('確認關閉?')
                    .then(_ => {
                        done();
                    })
                    .catch(_ => {
                    });
            },
            handleSizeChange(val) {
                this.page.size = val;
                this.getList();
            },
            handleCurrentChange(val) {
                this.page.current = val;
                this.getList();
            },
            saveTag() {
                if (this.multipleSelection.length === 0) {
                    this.$message({
                        type: 'warning',
                        message: '請先選擇要修改的機器'
                    });
                    return
                }
                addTag({
                    ids: this.multipleSelection,
                    tagId: this.tagList.id
                }).then(res => {

                    this.$message({
                        type: 'success',
                        message: '添加成功'
                    });
                    this.tagVisible = false;
                    this.getList()
                })

            },
            exportRepair() {
                if (this.multipleSelection.length === 0) {
                    this.$message({
                        type: 'warning',
                        message: '請先選擇要導出的機器'
                    });
                    return
                }
                exportRepairInfo(this.multipleSelection).then(res => {
                    let data = res;
                    const textarea = document.createElement("textarea");
                    textarea.setAttribute("readonly", true);
                    textarea.value = data;
                    document.body.appendChild(textarea);
                    textarea.setSelectionRange(0, textarea.value.length);
                    textarea.select();
                    if (document.execCommand("copy")) {
                        this.$message({
                            type: 'success',
                            message: '複製成功'
                        });
                    } else {
                        this.$message({
                            type: 'error',
                            message: '複製失敗'
                        });
                    }
                    document.body.removeChild(textarea);

                })
            },
            getValue(row, type, prop) {
                switch (type) {
                    case 'cluster':
                        return row.cluster.name
                    case 'date':
                        return this.getDate(row[prop])
                    case "resourcePool":
                        return this.transRP(row.resourcePool)
                    case "status":
                        return this.getStatus(row.tags)

                }
            },
            getStatus(status) {
                for (let i = 0; i < status.length; i++) {
                    let data = status[i]
                    if (data.type === "status") {
                        return data.value
                    }
                }
                return "暫無狀態"
            },
            transRP(id) {
                for (let i = 0; i < this.allRp.length; i++) {
                    if (this.allRp[i].id === id) {
                        return this.allRp[i].name;
                    }
                }
                return "未知"
            },
            saveOrder() {
                let result = JSON.stringify(this.dropCol);
                let data = {
                    orders: result,
                    type: "device"
                }
                saveOrders(data).then(res => {
                    this.$message({
                        type: 'success',
                        message: '保存成功 '
                    });
                    this.$store.dispatch('SetOrders', result)
                })
            },
            getDropCol() {
                if (this.orders && this.orders.hasOwnProperty('device') && this.orders['device'] !== null && this.orders['device'] !== '') {
                    let data = JSON.parse(this.orders['device'])
                    return data
                }
                return this.getCol()
            },
            getCol() {
                let allCols = [
                    {prop: "select", label: "選擇", sort: true},
                    {prop: "index", label: "序號", sort: true},
                    {prop: "name", label: "設備型號", sort: true,fixed:false},
                    {prop: "cluster.name", label: "集羣", type: "cluster", sort: false,fixed:false},
                    {prop: "type", label: "服務器分類", sort: true,fixed:false},
                    {prop: "sn", label: "設備序列號", sort: true,fixed:false},
                    {prop: "manageIp", label: "管理網", sort: true,fixed:false},
                    {prop: "illoIp", label: "ILLO地址", sort: true,fixed:false},
                    {prop: "period", label: "期數", sort: true,fixed:false},
                    {prop: "position", label: "機架位置", sort: true,fixed:false},
                    {prop: "publicIp", label: "公網", sort: true,fixed:false},
                    {prop: "cn2Ip", label: "CN2", sort: true,fixed:false},
                    {prop: "status", label: "狀態", type: "status", sort: true,fixed:false},
                    {prop: "outIp", label: "存儲外網", sort: true,fixed:false},
                    {prop: "systemVersion", label: "系統版本", sort: true,fixed:false},
                    {prop: "osVersion", label: "內核版本", sort: true,fixed:false},
                    {prop: "use", label: "用途", sort: true,fixed:false},
                    {prop: "deliveryDate", label: "交付日期", type: "date", sort: true,fixed:false},
                    {prop: "resourcePool", label: "資源池", type: "resourcePool", sort: true,fixed:false},
                    {prop: "useUser", label: "申請人", sort: true,fixed:false},
                    {prop: "tag", label: "項目名稱", sort: true,fixed:false},
                    {prop: "remarks", label: "備註", sort: true,fixed:false},
                    {prop: "computerPosition", label: "機房位置", sort: true,fixed:false},
                    {prop: "desc", label: "硬件信息", width: "700px", sort: false,fixed:false},
                ]
                if (this.cols && this.cols.hasOwnProperty('device')) {
                    if (!this.cols['device']) {
                        return allCols;
                    }
                    let str = this.cols['device'];
                    let data = this.utils.str2Arr(str);

                    let result = []
                    result.push({prop: "select", label: "選擇"})
                    result.push({prop: "index", label: "序號"})
                    data.forEach(function (item) {
                        allCols.forEach(function (col) {
                            if (col.prop === item) {
                                result.push(col);
                            }
                        })
                    })
                    return result;
                } else {
                    return allCols;
                }

            },
            addHs() {
                this.$prompt('請輸入變更記錄', '提示', {
                    confirmButtonText: '確定',
                    cancelButtonText: '取消',
                }).then(({value}) => {
                    addHistories({
                        deviceId: this.multipleSelection,
                        message: value
                    }).then(response => {
                        this.$message({
                            type: 'success',
                            message: '添加變更成功 '
                        });
                        this.HistoryVisible = false;
                        this.getList();

                    })
                }).catch(() => {
                    this.$message({
                        type: 'info',
                        message: '取消添加'
                    });
                });

            },
            handleSelectionChange(rows) {
                let data = [];
                rows.forEach(function (item) {
                    data.push(item.id)
                })
                this.multipleSelection = data
            },
            changeCols() {
                if (this.cols && this.cols.hasOwnProperty('device')) {
                    if (!this.cols['device']) {
                        this.colsList = []
                        this.changeVisible = true;
                        return
                    }
                    let str = this.cols['device'];
                    let data = this.utils.str2Arr(str);
                    this.colsList = data;
                } else {
                    this.colsList = [];
                }
                this.changeVisible = true;
            },
            saveCols() {
                let result = this.utils.arr2Str(this.colsList);
                let data = {
                    cols: result,
                    type: "device"
                }
                saveColsInfo(data).then(res => {
                    this.changeVisible = false;
                    this.$message({
                        type: 'success',
                        message: '變更成功 '
                    });
                    this.$store.dispatch('SetCols', result)
                    location.reload()
                })
            },
            getDate(time) {
                return moment(time).format('YYYY-MM-DD')
            },
            getDateTime(time) {
                return moment(time).format('YYYY-MM-DD HH:mm:ss')
            },
            addHistory() {
                this.$prompt('請輸入變更記錄', '提示', {
                    confirmButtonText: '確定',
                    cancelButtonText: '取消',
                }).then(({value}) => {
                    addHistory({
                        deviceId: this.history_deviceId,
                        message: value
                    }).then(response => {
                        this.$message({
                            type: 'success',
                            message: '添加變更成功 '
                        });
                        this.HistoryVisible = false;
                        this.getList();

                    })
                }).catch(() => {
                    this.$message({
                        type: 'info',
                        message: '取消添加'
                    });
                });
            },
            historyInfo(row) {
                this.history = row.histories;
                this.HistoryVisible = true;
                this.history_deviceId = row.id
            },
            handleFilter() {
                this.listQuery.page = 1
                this.getList()
            },
            cpuInfo(row) {
                this.deviceType = row.deviceType
                this.CPUVisible = true;
            },
            memoryInfo(row) {
                this.deviceType = row.deviceType
                this.MemoryVisible = true;
            },
            nicInfo(row) {
                this.deviceType = row.deviceType
                this.NicVisible = true;
            },
            diskInfo(row) {
                this.deviceType = row.deviceType
                this.DiskVisible = true;
            },
            saveDevice(formName) {
                this.$refs[formName].validate((valid) => {
                    if (valid) {
                        if (this.editFlag === 0) {
                            createDevice(
                                this.temp
                            ).then(response => {
                                this.$message({
                                    message: '保存成功',
                                    type: 'success'
                                });
                                this.getList();
                                this.resetDeviceForm('ruleForm')
                            })
                        } else {
                            modifyDevice(
                                this.temp
                            ).then(response => {
                                this.$message({
                                    message: '保存成功',
                                    type: 'success'
                                });
                                this.getList();
                                this.resetDeviceForm('ruleForm')
                            })

                        }


                    } else {
                        this.$message.error('保存失敗,請重試');
                        return false;
                    }
                });
            },
            handleAvatarSuccess(res, file) {
                if (res.code != 200) {
                    this.$message({
                        message: res.msg,
                        type: 'error'
                    });
                    return
                }
                this.$message({
                    message: '上傳成功',
                    type: 'success'
                });
                this.getList()
            },
            resetDeviceForm(formName) {
                this.$refs[formName].resetFields();
                this.dialogFormVisible = false;
            },
            getList() {
                this.listLoading = true
                this.listQuery.page = this.page.current
                this.listQuery.limit = this.page.size
                this.listQuery.searchForm = this.searchForm
                if (this.sortMap) {
                    this.listQuery.sortForm = this.strMapToObj(this.sortMap)
                } else {
                    this.listQuery.sortForm = null
                }
                fetchList(this.listQuery).then(response => {
                    this.list = response.content;
                    this.page.total = response.totalElements;
                    this.listLoading = false
                })
            },
            strMapToObj(strMap) {
                let obj = Object.create(null);
                for (let [k, v] of strMap) {
                    obj[k] = v;
                }
                return obj;
            },
            createDevice() {
                this.resetTemp()
                this.dialogFormVisible = true;
                this.editFlag = 0;
            },
            editDevice(item) {
                this.resetTemp()
                this.temp.id = item.id;
                this.temp.clusterId = item.cluster.id;
                this.temp.name = item.name;
                this.temp.use = item.use;
                this.temp.deliveryDate = item.deliveryDate;
                this.temp.type = item.type;
                this.temp.period = item.period;
                this.temp.manageIp = item.manageIp;
                this.temp.illoIp = item.illoIp;
                this.temp.remarks = item.remarks;
                this.temp.deviceType = item.deviceType;
                this.temp.sn = item.sn;
                this.temp.tag = item.tag;
                this.temp.resourcePool = item.resourcePool;
                this.temp.position = item.position;
                this.temp.systemVersion = item.systemVersion;
                this.temp.osVersion = item.osVersion;
                this.temp.publicIp = item.publicIp;
                this.temp.outIp = item.outIp;
                this.temp.cn2Ip = item.cn2Ip;
                this.temp.computerPosition = item.computerPosition
                this.dialogFormVisible = true;
                this.editFlag = 1;
            },

            resetTemp() {
                this.temp = {
                    id: null,
                    name: null,
                    clusterId: null,
                    use: null,
                    deliveryDate: null,
                    type: null,
                    manageIp: null,
                    illoIp: null,
                    period: null,
                    remarks: null,
                    deviceType: null,
                    sn: null,
                    tag: null,
                    resourcePool: null,
                    position: null,
                    useUser: null,
                    startDate: null,
                    systemVersion: null,
                    osVersion: null,
                    outIp: null,
                    publicIp: null,
                    cn2Ip: null,
                }
            },
            deleteDevice(row) {
                this.$confirm('此操作將刪除該資產, 是否繼續?', '提示', {
                    confirmButtonText: '確定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    deleteDevice(row.id).then(response => {
                        this.getList();
                        this.$message({
                            type: 'success',
                            message: '刪除成功!'
                        });
                    })

                }).catch(() => {
                    this.$message({
                        type: 'info',
                        message: '已取消刪除'
                    });
                });
            },
            //列拖拽
            columnDrop() {
                const wrapperTr = document.querySelector('.el-table__header-wrapper tr')
                this.sortable = Sortable.create(wrapperTr, {
                    animation: 180,
                    delay: 0,
                    onEnd: evt => {
                        const oldItem = this.dropCol[evt.oldIndex]
                        this.dropCol.splice(evt.oldIndex, 1)
                        this.dropCol.splice(evt.newIndex, 0, oldItem)
                    }
                })
            },
            //右鍵點擊
            rightClick(column, event) { // 鼠標右擊觸發事件
                this.menuVisible = false // 先把模態框關死,目的是 第二次或者第n次右鍵鼠標的時候 它默認的是true
                this.menuVisible = true  // 顯示模態窗口,跳出自定義菜單欄
                let menu = document.querySelector('#menu')
                document.addEventListener('click', this.foo) // 給整個document添加監聽鼠標事件,點擊任何位置執行foo方法
                menu.style.display = "block";
                menu.style.left = event.clientX + 'px'
                menu.style.top = event.clientY + 'px'
                this.index=column.index

            },
            lock(){
                this.dropCol[this.index].fixed="left"

            },
            unlock(){
                this.dropCol[this.index].fixed=false
            },
            foo() { // 取消鼠標監聽事件 菜單欄
                let menu = document.querySelector('#menu')
                this.menuVisible = false
                menu.style.display = "none";

                document.removeEventListener('click', this.foo) // 要及時關掉監聽,不關掉的是一個坑,不信你試試,雖然前臺顯示的時候沒有啥毛病,加一個alert你就知道了
            },




        }
    }
</script>

<style>

    .el-dropdown-link {
        cursor: pointer;
        color: #409EFF;
    }

    .demo-table-expand {
        font-size: 0;
    }

    .demo-table-expand label {
        width: 90px;
        color: #99a9bf;
    }

    .demo-table-expand .el-form-item {
        margin-right: 0;
        margin-bottom: 0;
        width: 50%;
    }

    .rowClass {
        height: 30px;
        padding: 0 !important;

    }

    .cellClass {
        padding: 2px !important;
    }

    .el-table--striped .el-table__body tr.el-table__row--striped.current-row td,
    .el-table__body tr.current-row > td {
        background-color: #a0cfff;
    }

    .el-table--striped .el-table__body tr.hover-row.el-table__row--striped > td,
    .el-table__body tr.hover-row > td {
        background-color: #d9ecff !important;
    }
</style>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章