zhangyu 4 éve
szülő
commit
3cd13a5833

+ 27 - 18
src/components/public/adm-multi-table.vue

@@ -12,8 +12,7 @@
         >
             <el-table-column prop="date" label="编辑" width="80" align="center" fixed>
                 <template slot-scope="scope">
-                    <span class="el-icon-edit el-input__icon" style="cursor: pointer"
-                          @click="handleEdit(scope.$index, scope.row)"> </span>
+                    <span class="el-icon-edit el-input__icon" style="cursor: pointer" @click="handleEdit(scope.$index, scope.row)"> </span>
                 </template>
             </el-table-column>
             <el-table-column v-for="item in headersStage" :key="item.name" :label="item.name" align="center">
@@ -46,6 +45,8 @@ export default class extends Vue {
     @Prop({ default: Object }) headersStage?: any;
     // 当前页头文字
     @Prop({ default: "" }) currentHeader?: string;
+    // 动态数据是否对表号-功能号做枚举转换
+    @Prop({ default: true }) isDynamicMap?: boolean;
 
     @Emit("handleCurrentEdit")
     handleEdit(index: number, row: any) {
@@ -69,26 +70,35 @@ export default class extends Vue {
      */
     private formatContent(row: any, column: any, cellValue: any) {
         const info = this.headerInfoMap[column.property];
-        if (info && cellValue) { //有值且获取到表头信息
+        // 有值且获取到表头信息
+        if (info && cellValue) {
+            // 动态类型且值不需要做转换
+            if (!this.isDynamicMap && info.category !== "STATIC") {
+                return cellValue;
+            }
             const dataSource = info?.dataSource ? info.dataSource : [];
-            if (info.dataType === "ENUM" || info.dataType === "BOOLEAN") { //内容为单选枚举和布尔类型
+            // 内容为单选枚举和布尔类型
+            if (info.dataType === "ENUM" || info.dataType === "BOOLEAN") {
                 const text = dataSource.find((item: any) => {
                     return item.code === cellValue;
                 })?.name;
-                return text;
+                return text ? text : cellValue;
             } else if (info.dataType === "MENUM" && cellValue instanceof Array && cellValue.length) { //内容为多选枚举且值为数组
-                const textList = dataSource.map((item: any) => {
-                    if (
-                        cellValue.find((value: string) => {
-                            return item?.code === value;
-                        })
-                    ) {
-                        return item?.name;
-                    }
-                }).filter((item: any) => item).join(",");
-                return textList;
-            } else if (info.dataType === "ATTACHMENT") { // 内容为附件类型
-                return cellValue.length + '个' || ''
+                const textList = dataSource
+                    .map((item: any) => {
+                        if (
+                            cellValue.find((value: string) => {
+                                return item?.code === value;
+                            })
+                        ) {
+                            return item?.name;
+                        }
+                    })
+                    .filter((item: any) => item)
+                    .join(",");
+                return textList ? textList : cellValue;
+            } else if (info.dataType === "ATTACHMENT") { //内容为附件类型
+                return cellValue.length + "个" || "";
             } else {
                 return cellValue;
             }
@@ -102,7 +112,6 @@ export default class extends Vue {
             if (this.tableDom?.doLayout) this.tableDom.doLayout();
         });
     }
-
 }
 </script>
 

+ 7 - 0
src/components/public/adm-search.vue

@@ -22,6 +22,13 @@ export default class extends Vue {
     private handleSearch() {
         return this.input
     }
+
+    /**
+     * 修改数据框内容
+     */
+    setInput(val: string) {
+        this.input = val;
+    }
 }
 </script>
 

+ 1 - 1
src/layout/components/Navbar/index.vue

@@ -76,7 +76,7 @@ export default class extends Vue {
     position: relative;
     background-color: #2b3643;
     box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
-    z-index: 1002;
+    z-index: 999;
 
     .title {
         float: left;

+ 1 - 0
src/layout/index.vue

@@ -75,6 +75,7 @@ export default class extends mixins(ResizeMixin) {
     position: relative;
     overflow-y: hidden;
     padding: 0 10px 10px;
+    margin-right: 10px;
     background: #F1F2F3;
 }
 

+ 11 - 1
src/views/maintain/system/index.vue

@@ -84,7 +84,7 @@ export default class extends Vue {
     list = [];
     // 信息点集合(表头)
     all = [];
-    codeToDataSource = {};
+    codeToDataSource: any = {};
     // 系统类值
     systemType = "";
     // 系统名称 label值
@@ -282,6 +282,16 @@ export default class extends Vue {
         this.all = arr;
         arr.forEach((item: any) => {
             let i = ["localName", "localId"];
+            if (item.dataSource) {
+                try {
+                    this.codeToDataSource[item.code] = {}
+                    item.dataSource.forEach((dic: any) => {
+                        this.codeToDataSource[item.code][dic.code] = dic.name;
+                    })
+                } catch (e) {
+                    console.log(e);
+                }
+            }
             if (i.includes(item.path)) {
                 basicInfos.push(item);
             } else {

+ 283 - 0
src/views/scene/tiepoint/components/equipTab/index.vue

@@ -0,0 +1,283 @@
+<template>
+    <div class="tab-content">
+        <div class="search">
+            <el-cascader
+                :options="deviceOptions"
+                clearable
+                v-model="deviceList"
+                :props="optionProps"
+                @change="handleChangeDevice"
+                class="item"
+            ></el-cascader>
+            <admSearch @SearchValue="searchValue" class="item" />
+        </div>
+        <div v-loading="loading" style="height: calc(100% - 100px); padding: 0 12px; position: relative">
+            <template style="height: 100%" v-if="tableData.length">
+                <admMultiTable
+                    @handleCurrentEdit="handleCurrentEdit"
+                    :isDynamicMap="false"
+                    :currentHeader="currentHeader"
+                    :headersStage="headersStage"
+                    :tableData="tableData"
+                />
+                <Pagination
+                    v-if="tableData.length"
+                    :paginationList="paginationList"
+                    @handleCurrentChange="handleCurrentChange"
+                    @handleSizeChange="handleSizeChange"
+                />
+            </template>
+            <div v-else class="void align">
+                <svg-icon name="void" :width="String(120)" :height="String(123)" />
+                <p class="void-title">暂无内容</p>
+                <p class="void-tips">可点击左上角筛选</p>
+            </div>
+        </div>
+    </div>
+</template>
+<script lang="ts">
+import { Vue, Component } from "vue-property-decorator";
+import { allDevice, dictInfo } from "@/api/equipComponent";
+import { queryEquip, updateEquip } from "@/api/datacenter";
+import { AdmMultiTable, AdmSearch, Pagination } from "@/views/maintain/components/index";
+import { UserModule } from "@/store/modules/user";
+
+@Component({
+    name: "EquipTab",
+    components: {
+        AdmMultiTable,
+        AdmSearch,
+        Pagination,
+    },
+})
+export default class EquipTab extends Vue {
+    // 项目id
+    private get projectId(): string {
+        return UserModule.projectId;
+    }
+
+    // 设备类型
+    private get deviceType(): string {
+        const length = this.deviceList.length;
+        return length ? this.deviceList[length - 1] : "";
+    }
+
+    // 设备关键字
+    private keyWord = "";
+    // 设备类下拉绑定值
+    private deviceList: any = [];
+    // 设备筛选
+    private deviceOptions: any[] = [];
+    // 下拉框映射
+    private optionProps: any = {
+        value: "code",
+        label: "name",
+        children: "children",
+    };
+    // 表格数据加载loading
+    private loading = false;
+    // 表格数据
+    private tableData: any[] = [];
+    // 阶段信息
+    private currentHeader = "运维阶段维护";
+    // 表头阶段信息结合
+    private headersStage: any = {};
+    // 信息点集合(表头)
+    private all: any = [];
+    // 输入类型选项
+    private codeToDataSource: any = {};
+    // 分页
+    private paginationList = {
+        page: 1,
+        size: 50,
+        sizes: [10, 30, 50, 100, 150, 200],
+        total: 0,
+    };
+
+    // created钩子
+    created() {
+        this.getDeviceOptions();
+    }
+
+    /**
+     * 设备类数据
+     */
+    private async getDeviceOptions() {
+        const res = await allDevice({});
+        if (res.result === "success") {
+            this.deviceOptions = res.content;
+        }
+    }
+
+    /**
+     * 获取设备数据(信息点和实例数据)
+     */
+    private getEquipData() {
+        if (this.deviceType) {
+            this.loading = true;
+            let param = {
+                category: this.deviceType,
+            };
+            let param2 = {
+                filters: `classCode='${this.deviceType}'`,
+                pageNumber: this.paginationList.page,
+                pageSize: this.paginationList.size,
+                orders: "createTime desc, id asc",
+                projectId: this.projectId,
+            };
+            if (this.keyWord != "") {
+                param2.filters += `;codeName contain '${this.keyWord}' or systemCategory contain '${this.keyWord}' or bimTypeId contain '${this.keyWord}' or localId contain '${this.keyWord}'`;
+            }
+            let promise = new Promise((resolve) => {
+                dictInfo(param).then((res: any) => {
+                    resolve(res);
+                });
+            });
+            let promise2 = new Promise((resolve) => {
+                queryEquip(param2).then((res: any) => {
+                    resolve(res);
+                });
+            });
+            Promise.all([promise, promise2]).then((res: any[]) => {
+                this.loading = false;
+                // 获取运维阶段名称
+                this.currentHeader = res[0]?.dictStages.find((item: any) => {
+                    return item.code === "moms";
+                })?.name;
+                this.headersStage = this.informationArrangement(res[0]); // 重组表头数据
+                this.tableData = res[1]?.content ? res[1].content : []; // 主体数据
+                this.paginationList.total = res[1]?.total ? res[1].total : 0;
+            });
+        } else {
+            this.tableData = [];
+        }
+    }
+
+    /**
+     * 获取系统实例数据
+     */
+    private async getExampleData() {
+        if (this.deviceType) {
+            this.loading = true;
+            let params = {
+                filters: `classCode='${this.deviceType}'`,
+                pageNumber: this.paginationList.page,
+                pageSize: this.paginationList.size,
+                orders: "createTime desc, id asc",
+                projectId: this.projectId,
+            };
+            if (this.keyWord != "") {
+                params.filters += `;codeName contain '${this.keyWord}' or systemCategory contain '${this.keyWord}' or bimTypeId contain '${this.keyWord}' or localId contain '${this.keyWord}'`;
+            }
+            const res = await queryEquip(params);
+            if (res.result === "success") {
+                this.tableData = res?.content ? res.content : []; // 主体数据
+                this.paginationList.total = res?.total ? res.total : 0;
+                this.loading = false;
+            }
+        } else {
+            this.tableData = [];
+        }
+    }
+
+    /**
+     * 信息点重组
+     */
+    private informationArrangement(data: any): any {
+        if (data?.basicInfos && data?.dictStages) {
+            const base: any[] = [];
+            data.dictStages.forEach((item: any) => {
+                if (this.currentHeader === item.name) {
+                    item?.infos.forEach((val: any) => {
+                        base.push(val);
+                    });
+                }
+            });
+            // 信息点集合
+            this.all = [...data.basicInfos, ...base];
+            this.codeToDataSource = {};
+            this.all.forEach((item: any) => {
+                if (item.dataSource) {
+                    try {
+                        this.codeToDataSource[item.code] = {};
+                        item.dataSource.forEach((dic: any) => {
+                            this.codeToDataSource[item.code][dic.code] = dic.name;
+                        });
+                    } catch (e) {
+                        console.log(e);
+                    }
+                }
+            });
+            return {
+                basicInfos: {
+                    name: "基础信息台账",
+                    data: data.basicInfos,
+                },
+                dictStages: {
+                    name: this.currentHeader,
+                    data: base,
+                },
+            };
+        } else {
+            return {};
+        }
+    }
+
+    /**
+     * 切换设备类型
+     */
+    private handleChangeDevice() {
+        this.getEquipData();
+    }
+
+    /**
+     * 检索设备关键字
+     */
+    private searchValue(val: string) {
+        this.keyWord = val;
+        this.getExampleData();
+    }
+
+    /**
+     * 切换页码
+     */
+    private handleCurrentChange(val: number) {
+        this.paginationList.page = val;
+        this.getExampleData();
+    }
+
+    /**
+     * 切换每页显示数量
+     */
+    private handleSizeChange(val: number) {
+        this.paginationList.size = val;
+        this.getExampleData();
+    }
+}
+</script>
+<style lang="scss" scoped>
+.tab-content {
+    height: 100%;
+    border: 1px solid #e1e7ea;
+    border-top: none;
+    padding-bottom: 12px;
+
+    .search {
+        padding: 12px;
+        & > .item {
+            margin-right: 12px;
+        }
+    }
+}
+// 数据暂未
+.void {
+    margin-top: 200px;
+}
+.align {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    flex-direction: column;
+    flex-wrap: wrap;
+}
+</style>

+ 307 - 0
src/views/scene/tiepoint/components/systemTab/index.vue

@@ -0,0 +1,307 @@
+<template>
+    <div class="tab-content">
+        <div class="search">
+            <el-cascader
+                :options="systemOptions"
+                ref="systemCascader"
+                clearable
+                v-model="systemList"
+                :props="optionProps"
+                @change="handleChangeSystem"
+                class="item"
+            ></el-cascader>
+            <admSearch @SearchValue="searchValue" class="item" />
+        </div>
+        <div v-loading="loading" style="height: calc(100% - 100px); padding: 0 12px; position: relative;">
+            <template style="height: 100%" v-if="tableData.length">
+                <admMultiTable
+                    @handleCurrentEdit="handleCurrentEdit"
+                    :isDynamicMap="false"
+                    :currentHeader="currentHeader"
+                    :headersStage="headersStage"
+                    :tableData="tableData"
+                />
+                <Pagination
+                    v-if="tableData.length"
+                    :paginationList="paginationList"
+                    @handleCurrentChange="handleCurrentChange"
+                    @handleSizeChange="handleSizeChange"
+                />
+            </template>
+            <div v-else class="void align">
+                <svg-icon name="void" :width="String(120)" :height="String(123)" />
+                <p class="void-title">暂无内容</p>
+                <p class="void-tips">可点击左上角筛选</p>
+            </div>
+        </div>
+    </div>
+</template>
+<script lang="ts">
+import { Vue, Component, Ref } from "vue-property-decorator";
+import { allSystem } from "@/api/equipComponent";
+import { dictQuery, querySystem } from "@/api/datacenter";
+import { AdmMultiTable, AdmSearch, Pagination } from "@/views/maintain/components/index";
+import { UserModule } from "@/store/modules/user";
+import { ElCascader } from "element-ui/types/cascader";
+
+@Component({
+    name: "SystemTab",
+    components: {
+        AdmMultiTable,
+        AdmSearch,
+        Pagination,
+    },
+})
+export default class SystemTab extends Vue {
+    // 系统类筛选框
+    @Ref("systemCascader") readonly systemCascader!: ElCascader;
+
+    // 项目id
+    private get projectId(): string {
+        return UserModule.projectId;
+    }
+
+    // 系统类型
+    private get systemType(): string {
+        const length = this.systemList.length;
+        return length ? this.systemList[length - 1] : "";
+    }
+
+    // 系统关键字
+    private keyWord = "";
+    // 系统类下拉绑定值
+    private systemList: any = [];
+    // 系统类名称
+    private systemLabel = "";
+    // 系统筛选
+    private systemOptions: any[] = [];
+    // 下拉框映射
+    private optionProps: any = {
+        value: "code",
+        label: "name",
+        children: "children",
+    };
+    // 表格数据加载loading
+    private loading = false;
+    // 表格数据
+    private tableData: any[] = [];
+    // 阶段信息
+    private currentHeader = "运维阶段";
+    // 表头阶段信息结合
+    private headersStage: any = {};
+    // 信息点集合(表头)
+    private all: any = [];
+    // 输入类型选项
+    private codeToDataSource: any = {};
+
+    // 分页
+    private paginationList = {
+        page: 1,
+        size: 50,
+        sizes: [10, 30, 50, 100, 150, 200],
+        total: 0,
+    };
+
+    // created钩子
+    created() {
+        this.getSystemOptions();
+    }
+
+    /**
+     * 系统类数据
+     */
+    private async getSystemOptions() {
+        const res = await allSystem({});
+        if (res.result === "success") {
+            this.systemOptions = res.content;
+        }
+    }
+
+    /**
+     * 获取系统数据(信息点和系统实例)
+     */
+    private getSystemData() {
+        if (this.systemType) {
+            //系统类型不为空
+            // @ts-ignore
+            const systemLabel = this.systemCascader.getCheckedNodes()[0].pathLabels;
+            this.systemLabel = systemLabel[1];
+            this.loading = true;
+            let param = {
+                type: this.systemType,
+                orders: "sort asc, name desc",
+            };
+            let param2 = {
+                filters: `classCode='${this.systemType}'`,
+                pageNumber: this.paginationList.page,
+                pageSize: this.paginationList.size,
+                orders: "createTime asc, id asc",
+                projectId: this.projectId,
+            };
+            if (this.keyWord != "") {
+                param2.filters += `;localName contain '${this.keyWord}' or localId contain '${this.keyWord}'`;
+            }
+            let promise = new Promise((resolve) => {
+                dictQuery(param).then((res: any) => {
+                    resolve(res);
+                });
+            });
+            let promise2 = new Promise((resolve) => {
+                querySystem(param2).then((res: any) => {
+                    resolve(res);
+                });
+            });
+            Promise.all([promise, promise2]).then((res: any[]) => {
+                let tableData = [];
+                this.loading = false;
+                // 类型下信息点,重组数据
+                const { basicInfos, dictStages } = this.informationArrangement(res[0].content);
+                this.headersStage = {
+                    basicInfos: {
+                        name: "基础信息台账",
+                        data: basicInfos,
+                    },
+                    dictStages: {
+                        name: "运维阶段",
+                        data: dictStages,
+                    },
+                };
+                this.paginationList.total = res[1]?.total ? res[1].total : 0;
+                tableData = res[1]?.content ? res[1].content : []; // 主体数据
+                // 添加系统分类
+                this.tableData = tableData.map((item: any) => {
+                    item = { ...item, classification: this.systemLabel };
+                    return item;
+                });
+            });
+        } else {
+            //系统类型为空
+            this.tableData = [];
+        }
+    }
+
+    /**
+     * 获取系统实例数据
+     */
+    private async getExampleData() {
+        if (this.systemType) {
+            //系统类型不为空
+            this.loading = true;
+            let params = {
+                filters: `classCode='${this.systemType}'`,
+                pageNumber: this.paginationList.page,
+                pageSize: this.paginationList.size,
+                orders: "createTime asc, id asc",
+                projectId: this.projectId,
+            };
+            if (this.keyWord != "") {
+                params.filters = `${params.filters};localName contain '${this.keyWord}' or localId contain '${this.keyWord}'`;
+            }
+
+            const res = await querySystem(params);
+            if (res.result === "success") {
+                let tableData: any[] = [];
+                this.loading = false;
+                this.paginationList.total = res?.total ? res.total : 0;
+                tableData = res?.content ? res.content : []; // 主体数据
+                // 添加系统分类
+                this.tableData = tableData.map((item: any) => {
+                    item = { ...item, classification: this.systemLabel };
+                    return item;
+                });
+            }
+        } else {
+            //系统类型为空
+            this.tableData = [];
+        }
+    }
+
+    /**
+     * 信息点重组
+     */
+    private informationArrangement(arr: []): any {
+        let basicInfos = [{ path: "classification", name: "系统分类" }],
+            dictStages: any[] = [];
+        this.all = arr;
+        arr.forEach((item: any) => {
+            let i = ["localName", "localId"];
+            if (item?.dataSource) {
+                try {
+                    this.codeToDataSource[item.code] = {};
+                    item.dataSource.forEach((dic: any) => {
+                        this.codeToDataSource[item.code][dic.code] = dic.name;
+                    });
+                } catch (e) {
+                    console.log(e);
+                }
+            }
+            if (i.includes(item.path)) {
+                basicInfos.push(item);
+            } else {
+                dictStages.push(item);
+            }
+        });
+        return {
+            basicInfos,
+            dictStages,
+        };
+    }
+
+    /**
+     * 切换系统类型
+     */
+    private handleChangeSystem() {
+        this.getSystemData();
+    }
+
+    /**
+     * 检索系统关键字
+     */
+    private searchValue(val: string) {
+        this.keyWord = val;
+        this.getExampleData();
+    }
+
+    /**
+     * 切换页码
+     */
+    private handleCurrentChange(val: number) {
+        this.paginationList.page = val;
+        this.getExampleData();
+    }
+
+    /**
+     * 切换每页显示数量
+     */
+    private handleSizeChange(val: number) {
+        this.paginationList.size = val;
+        this.getExampleData();
+    }
+}
+</script>
+<style lang="scss" scoped>
+.tab-content {
+    height: 100%;
+    border: 1px solid #e1e7ea;
+    border-top: none;
+    padding-bottom: 12px;
+
+    .search {
+        padding: 12px;
+        & > .item {
+            margin-right: 12px;
+        }
+    }
+}
+// 数据暂未
+.void {
+    margin-top: 200px;
+}
+.align {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    flex-direction: column;
+    flex-wrap: wrap;
+}
+</style>

+ 66 - 6
src/views/scene/tiepoint/index.vue

@@ -1,12 +1,72 @@
 <template>
-    <div>绑点</div>
+    <div class="adm-tiepoint">
+        <div class="tabs">
+            <el-tabs v-model="activeName" type="card" @tab-click="tabChange">
+                <el-tab-pane label="设备" name="equip">
+                    <equip-tab></equip-tab>
+                </el-tab-pane>
+                <el-tab-pane label="系统" name="system">
+                    <system-tab></system-tab>
+                </el-tab-pane>
+            </el-tabs>
+        </div>
+    </div>
 </template>
+<script lang="ts">
+import { Vue, Component } from "vue-property-decorator";
+import EquipTab from "./components/equipTab/index.vue";
+import SystemTab from "./components/systemTab/index.vue";
+import { UserModule } from "@/store/modules/user";
 
-<script>
-export default {
-    name: "index"
+@Component({
+    name: "TiePoint",
+    components: {
+        EquipTab,
+        SystemTab,
+    },
+})
+export default class tiePoint extends Vue {
+    // 项目id
+    private get projectId(): string {
+        return UserModule.projectId;
+    }
+
+    // 当前选中的tab
+    private activeName = "equip";
+
+    /**
+     * 切换Tab(设备/系统),初始化数据
+     */
+    private tabChange() {
+        console.log(this.activeName);
+    }
 }
 </script>
-
-<style scoped>
+<style lang="scss" scoped>
+.adm-tiepoint {
+    background: #fff;
+    padding: 12px;
+    height: 100%;
+    .tabs {
+        position: relative;
+        height: 100%;
+        ::v-deep .el-tabs {
+            height: 100%;
+        }
+        ::v-deep .el-tabs__header {
+            margin: 0;
+        }
+        ::v-deep .el-tabs__content {
+            height: calc(100% - 41px);
+        }
+        ::v-deep .el-tab-pane {
+            height: 100%;
+        }
+    }
+    ::v-deep .adm-pagination {
+        right: 10px;
+        position: absolute;
+        bottom: -45px;
+    }
+}
 </style>