Browse Source

Merge branch 'master' of http://39.106.8.246:3003/web/wanda-adm

YaolongHan 3 years ago
parent
commit
b8b00a74a9

+ 4 - 0
.gitattributes

@@ -0,0 +1,4 @@
+*.eot binary
+*.ttf binary
+*.woff binary
+*.woff2 binary

+ 1 - 0
public/index.html

@@ -11,6 +11,7 @@
     <meta http-equiv="Pragma" content="no-cache"/>
     <meta http-equiv="Expires" content="0"/>
     <title><%= htmlWebpackPlugin.options.title %></title>
+    <script src="<%= BASE_URL %>systemConf.js"></script>
 </head>
 <body>
 <noscript>

+ 13 - 0
public/systemConf.js

@@ -0,0 +1,13 @@
+/**
+ * @author 张宇
+ * @description 项目配置文件
+ *
+ */
+
+ var __systemConf = {
+    // 平面图跳转地址
+    planJumpUrl: "http://192.168.64.18:9989/persagyPlan/home",
+    // 拓扑图跳转地址
+    topoJumpUrl: "http://192.168.64.18:9989/persagyTopo/home",
+}
+window.__systemConf = __systemConf

+ 5 - 0
src/api/datacenter.ts

@@ -72,6 +72,11 @@ export function updateEquip(postParams: any): any {
     return httputils.postJson(`${baseApi}/object/equip/update`, postParams)
 }
 
+// 导出设备
+export function exportEquip(getParams: any): any {
+    return httputils.getDownload(`${baseApi}/object/equip/export`, getParams)
+}
+
 // 查询系统信息
 export function querySystem(postParams: any): any {
     return httputils.postJson(`${baseApi}/object/system/query`, postParams)

+ 30 - 1
src/api/httputils.ts

@@ -138,7 +138,36 @@ export default {
             throw err;
         }
     },
-    download(url: string, requestData: any) {
+    getDownload(url: string, requestData: any) {
+        // 响应类型:arraybuffer, blob
+        axiosservice
+            .get(url, {params: requestData, responseType: 'blob'})
+            .then((resp) => {
+                const headers = resp.headers;
+                const contentType = headers["content-type"];
+
+                console.log("响应头信息", headers);
+                if (!resp.data) {
+                    console.error("响应异常:", resp);
+                    return false;
+                } else {
+                    console.log("下载文件:", resp);
+                    const blob = new Blob([resp.data], { type: contentType });
+
+                    const contentDisposition = resp.headers["content-disposition"];
+                    let fileName = "unknown";
+                    if (contentDisposition) {
+                        fileName = window.decodeURI(resp.headers["content-disposition"].split("=")[1]);
+                    }
+                    console.log("文件名称:", fileName);
+                    downFile(blob, fileName);
+                }
+            })
+            .catch(function (error) {
+                console.log(error);
+            });
+    },
+    postDownload(url: string, requestData: any) {
         // 响应类型:arraybuffer, blob
         axiosservice
             .post(url, requestData, { responseType: "blob" })

+ 29 - 17
src/components/business/baseDataForm.vue

@@ -3,13 +3,14 @@
         <el-form label-position="top" label-width="300px" :model="form" :rules="rules" ref="form">
             <template v-if="Object.keys(infoHeaders).length > 0">
                 <div v-for="obj in infoHeaders" :key="obj.name">
-                    <p class="title"> {{ obj.name }}</p>
+                    <p v-if="obj.data.length" class="title"> {{ obj.name }}</p>
                     <el-row :gutter="18">
                         <el-col :span="item.dataType == 'ATTACHMENT'? 24:8"
                                 :key="item.path"
                                 v-for="item in obj.data"
                                 :style="{ 'height': item.dataType == 'ATTACHMENT'? 'auto':'93px' }">
-                            <el-form-item :label="item.name" :prop="item.code">
+                            <el-form-item :label="item.unit ? item.aliasName + ' (' + item.unit + ')' : item.aliasName"
+                                          :prop="item.code">
                                 <!-- 动态数据按输入框输入 -->
                                 <el-input
                                     v-if="item.category !== 'STATIC'"
@@ -85,7 +86,7 @@
 
 <script lang="ts">
 
-import { Component, Prop, Vue, Watch } from 'vue-property-decorator'
+import {Component, Prop, Vue, Watch} from 'vue-property-decorator'
 import uploadFiles from "@/components/public/uploadFiles.vue";
 import uploadImgs from "@/components/public/uploadImgs.vue";
 
@@ -98,7 +99,7 @@ function flattenKeys(obj: any) {
 
     function digKeys(prev: any, obj: any) {
         Object.entries(obj).forEach(([key, value]) => {
-            const currentKey = prev ? `${ prev }.${ key }` : key
+            const currentKey = prev ? `${prev}.${key}` : key
             if (isObject(value)) {
                 digKeys(currentKey, value)
             } else {
@@ -114,30 +115,34 @@ function flattenKeys(obj: any) {
 
 @Component({
     name: "baseDataForm",
-    components: { uploadFiles, uploadImgs }
+    components: {uploadFiles, uploadImgs}
 })
 export default class extends Vue {
     rules = {
-        'localName': [{ required: true, message: '请填写本地名称', trigger: 'blur' }],
-        'localId': [{ required: true, message: '请填写本地编码', trigger: 'blur' }],
-        'buildingSign': [{ required: true, message: '请填写建筑', trigger: 'blur' }],
-        'floorSign': [{ required: true, message: '请填写本地楼层', trigger: 'blur' }]
+        'localName': [{required: true, message: '请填写本地名称', trigger: 'blur'}],
+        'localId': [{required: true, message: '请填写本地编码', trigger: 'blur'}],
+        'buildingSign': [{required: true, message: '请填写建筑', trigger: 'blur'}],
+        'floorSign': [{required: true, message: '请填写本地楼层', trigger: 'blur'}]
     }
     header = {}
-    form = {}
-    @Prop({ default: Object }) objectHeaders ?: any
-    @Prop({ default: Object }) currRowContent ?: any
+    form: any = {}
+    @Prop({default: Object}) objectHeaders ?: any
+    @Prop({default: Object}) currRowContent ?: any
 
     private get infoHeaders(): any {
-        if (this.objectHeaders?.dictStages?.data?.length && this.objectHeaders?.basicInfos) {
-            const base: any[] = [], enclosure: any[] = []; 
+        if (this.objectHeaders?.dictStages?.data && this.objectHeaders?.basicInfos) {
+            const base: any[] = [], enclosure: any[] = [];
             this.objectHeaders.dictStages.data.forEach((item: any) => {
+                this.addFormData(item);
                 if (item.dataType === 'ATTACHMENT') {
                     enclosure.push(item);
                 } else {
                     base.push(item);
                 }
             })
+            this.objectHeaders.basicInfos.data.forEach((item: any) => {
+                this.addFormData(item);
+            })
             return {
                 basicInfos: this.objectHeaders.basicInfos,
                 dictStages: {
@@ -150,7 +155,7 @@ export default class extends Vue {
         }
     }
 
-    @Watch('currRowContent', { immediate: true, deep: true })
+    @Watch('currRowContent', {immediate: true, deep: true})
     handleRow() {
         this.$nextTick(() => {
             // string =>array key
@@ -160,6 +165,13 @@ export default class extends Vue {
 
     }
 
+    private addFormData(headerItem: any) {
+        if (headerItem.render) {
+            const val = headerItem.render(this.currRowContent);
+            this.form[headerItem.path] = val;
+        }
+    }
+
     changeItem(val) {
         console.log(val)
         let _key = Object.keys(val)[0] + '';
@@ -206,10 +218,10 @@ $border: 1px solid #E1E7EA;
 input::-webkit-outer-spin-button,
 input::-webkit-inner-spin-button {
     -webkit-appearance: none !important;
-    margin: 0; 
+    margin: 0;
 }
 
 input[type="number"] {
     -moz-appearance: textfield;
 }
-</style>
+</style>

+ 26 - 14
src/components/business/dataForm.vue

@@ -7,8 +7,8 @@
                     <el-col :span="8" :key="item.path" v-for="item in header.basicInfos.data">
                         <el-form-item
                             :prop="item.path"
-                            :label="item.name">
-                            <el-input v-model="form[item.path]"/>
+                            :label="item.aliasName">
+                            <el-input v-model="form[item.path]" :disabled="!item.editable"/>
                         </el-form-item>
                     </el-col>
                 </el-row>
@@ -25,7 +25,8 @@
                                     v-for="item in header.dictStages.data"
                                     :style="{ 'height':item.dataType == 'ATTACHMENT'? 'auto':'93px' }"
                             >
-                                <el-form-item :label="item.name">
+                                <el-form-item
+                                    :label="item.unit ? item.aliasName + ' (' + item.unit + ')' : item.aliasName">
                                     <el-input
                                         :disabled="!item.editable"
                                         v-if="item.dataType == 'STRING'"
@@ -95,7 +96,7 @@
 
 <script lang="ts">
 
-import { Component, Prop, Vue, Watch } from 'vue-property-decorator'
+import {Component, Prop, Vue, Watch} from 'vue-property-decorator'
 import uploadFiles from "@/components/public/uploadFiles.vue";
 import uploadImgs from "@/components/public/uploadImgs.vue";
 
@@ -108,7 +109,7 @@ function flattenKeys(obj: any) {
 
     function digKeys(prev: any, obj: any) {
         Object.entries(obj).forEach(([key, value]) => {
-            const currentKey = prev ? `${ prev }.${ key }` : key
+            const currentKey = prev ? `${prev}.${key}` : key
             if (isObject(value)) {
                 digKeys(currentKey, value)
             } else {
@@ -124,14 +125,14 @@ function flattenKeys(obj: any) {
 
 @Component({
     name: "dataForm",
-    components: { uploadFiles, uploadImgs }
+    components: {uploadFiles, uploadImgs}
 })
 export default class extends Vue {
     rules = {
-        bimTypeId: [{ required: true, message: "请填写BIM构件编码", trigger: 'blur' }],
-        systemCategory: [{ required: true, message: "请填写系统分类", trigger: 'blur' }],
-        codeName: [{ required: true, message: "请填写设备类型名称", trigger: 'blur' }],
-        localId: [{ required: true, message: "请填写本地编码", trigger: 'blur' }],
+        bimTypeId: [{required: true, message: "请填写BIM构件编码", trigger: 'blur'}],
+        systemCategory: [{required: true, message: "请填写系统分类", trigger: 'blur'}],
+        codeName: [{required: true, message: "请填写设备类型名称", trigger: 'blur'}],
+        localId: [{required: true, message: "请填写本地编码", trigger: 'blur'}],
     }
     // tabs数据
     activeName = 0
@@ -140,10 +141,10 @@ export default class extends Vue {
     paneMsg = []
     // 默认当前阶段
     currentHeader = ''
-    @Prop({ default: Object }) deviceHeaders ?: {}
-    @Prop({ default: Object }) currRowContent ?: {}
+    @Prop({default: Object}) deviceHeaders ?: {}
+    @Prop({default: Object}) currRowContent ?: {}
 
-    @Watch('currRowContent', { immediate: true, deep: true })
+    @Watch('currRowContent', {immediate: true, deep: true})
     handleRow() {
         this.$nextTick(() => {
             // string =>array key
@@ -153,7 +154,7 @@ export default class extends Vue {
 
     }
 
-    @Watch('deviceHeaders', { immediate: true, deep: true })
+    @Watch('deviceHeaders', {immediate: true, deep: true})
     changeHeaders() {
         this.$nextTick(() => {
             let pic = [], base = []
@@ -164,6 +165,7 @@ export default class extends Vue {
                 this.deviceHeaders.dictStages.length > 0 && this.deviceHeaders.dictStages.forEach(item => {
                     if (this.currentHeader == item.name) {
                         item.infos && item.infos.forEach(val => {
+                            this.addFormData(val);
                             if (val.dataType == 'ATTACHMENT') {
                                 pic.push(val)
                             } else {
@@ -172,6 +174,9 @@ export default class extends Vue {
                         })
                     }
                 })
+                this.deviceHeaders.basicInfos.length > 0 && this.deviceHeaders.basicInfos.forEach(item => {
+                    this.addFormData(item)
+                })
             }
             this.header = {
                 basicInfos: {
@@ -186,6 +191,13 @@ export default class extends Vue {
         })
     }
 
+    addFormData(headerItem: any) {
+        if (headerItem.render) {
+            const val = headerItem.render(this.currRowContent)
+            this.form[headerItem.path] = val
+        }
+    }
+
     changeItem(val) {
         console.log(val)
         let _key = Object.keys(val)[0] + '';

+ 10 - 9
src/components/public/adm-multi-table.vue

@@ -58,15 +58,12 @@ export default class extends Vue {
     }
 
     get headerInfoMap() {
-        if (this.headersStage?.dictStages?.data?.length) {
-            const headerInfoMap: any = {};
-            this.headersStage.dictStages.data.forEach((item: any) => {
-                headerInfoMap[item.path] = item;
-            });
-            return headerInfoMap;
-        } else {
-            return {};
-        }
+        const arr = [...this.headersStage?.basicInfos?.data ?? [], ...this.headersStage?.dictStages?.data ?? []]
+        const headerInfoMap: any = {};
+        arr.forEach((item: any) => {
+            headerInfoMap[item.path] = item;
+        });
+        return headerInfoMap;
     }
 
     /**
@@ -74,6 +71,10 @@ export default class extends Vue {
      */
     private formatContent(row: any, column: any, cellValue: any) {
         const info = this.headerInfoMap[column.property];
+        // 对有render函数的信息点特殊处理
+        if (info && info.render) {
+            return info.render(row);
+        }
         // 有值且获取到表头信息
         if (info && cellValue) {
             // 动态类型且值不需要做转换

+ 7 - 0
src/store/modules/user.ts

@@ -16,6 +16,7 @@ export interface IUserState {
     userId: string;
     group: string;
     projectId: string;
+    projectName: string;
     projects: any[];
     avatar: string;
     introduction: string;
@@ -30,6 +31,7 @@ class User extends VuexModule implements IUserState {
     public userId = "06328a53c69a41bb8f5bb1a552c6e8d6";
     public group = "WD";// 集团
     public projectId = "Pj4403070003";// 深圳龙岗万达广场
+    public projectName = "深圳龙岗万达广场";// 深圳龙岗万达广场
     public projects: any[] = [{
         id: "Pj4403070003",
         name: "深圳龙岗万达广场"
@@ -59,6 +61,11 @@ class User extends VuexModule implements IUserState {
     }
 
     @Mutation
+    private SET_PROJECTNAME(projectName: string) {
+        this.projectName = projectName;
+    }
+
+    @Mutation
     private SET_PROJECTS(projects: any[]) {
         this.projects = projects;
     }

+ 63 - 21
src/views/maintain/device/index.vue

@@ -17,7 +17,6 @@
                 <template v-if="deviceType.length > 0">
                     <admMultiTable :currentHeader="currentHeader"
                                    @handleCurrentEdit="handleCurrentEdit"
-
                                    :tableData="tableData" :headersStage="headersStage"/>
                     <Pagination v-if="tableData.length > 0" :paginationList="paginationList"
                                 @handleCurrentChange="handleCurrentChange"
@@ -95,24 +94,24 @@
     </div>
 </template>
 <script lang="ts">
-import { Component, Vue, Watch } from "vue-property-decorator";
-import { AdmMultiTable, AdmSearch, dataForm, Pagination, Statistics } from '../components/index'
-import { allDevice, BeatchQueryParam, dictInfo } from "@/api/equipComponent";
-import { createEquip, queryCount, queryEquip, updateEquip, deleteEquip } from "@/api/datacenter";
-import { UserModule } from "@/store/modules/user";
+import {Component, Vue, Watch} from "vue-property-decorator";
+import {AdmMultiTable, AdmSearch, dataForm, Pagination, Statistics} from '../components/index'
+import {allDevice, BeatchQueryParam, dictInfo} from "@/api/equipComponent";
+import {createEquip, queryCount, queryEquip, updateEquip, deleteEquip} from "@/api/datacenter";
+import {UserModule} from "@/store/modules/user";
 import deviceGraph from "./components/deviceGraph.vue"
 import tools from "@/utils/maintain"
 
 
 @Component({
     name: 'adm-device',
-    components: { Statistics, AdmSearch, AdmMultiTable, Pagination, dataForm, deviceGraph }
+    components: {Statistics, AdmSearch, AdmMultiTable, Pagination, dataForm, deviceGraph}
 })
 export default class extends Vue {
 
     optionProps = {
         value: 'code',
-        label: 'name',
+        label: 'aliasName',
         children: 'children'
     }
 
@@ -205,14 +204,15 @@ export default class extends Vue {
                 category: this.deviceType[1]
             }
             let param2 = {
-                filters: this.deviceType[1] ? `classCode='${ this.deviceType[1] }'` : undefined,
+                filters: this.deviceType[1] ? `classCode='${this.deviceType[1]}'` : undefined,
                 pageNumber: this.paginationList.page,
                 pageSize: this.paginationList.size,
                 orders: "createTime desc, id asc",
-                projectId: this.projectId
+                projectId: this.projectId,
+                cascade: [{"name": "floor",}, {"name": "objectInfo"}]
             }
             if (this.inputSearch != '') {
-                param2.filters += `;codeName contain '${ this.inputSearch }' or systemCategory contain '${ this.inputSearch }' or bimTypeId contain '${ this.inputSearch }' or localId contain '${ this.inputSearch }'`
+                param2.filters += `;codeName contain '${this.inputSearch}' or systemCategory contain '${this.inputSearch}' or bimTypeId contain '${this.inputSearch}' or localId contain '${this.inputSearch}'`
             }
             let promise = new Promise(resolve => {
                 dictInfo(param).then((res: []) => {
@@ -228,7 +228,8 @@ export default class extends Vue {
                 this.loading = false
                 // 类型下信息点,默认设计阶段
                 this.headerInformation = res[0] // 获取表头
-                this.tableData = res[1].content // 主体数据
+                // this.tableData = res[1].content // 主体数据
+                this.tableData = res[1].content
                 this.paneMsg = res[0].dictStages.map(i => i.name)
                 this.currentHeader = this.paneMsg[this.activeName]
                 this.headerStage()
@@ -247,7 +248,23 @@ export default class extends Vue {
                 category: this.deviceVal[1]
             }
             await dictInfo(param).then(res => {
-                this.deviceHeaders = res
+                const basicInfos = [{path: 'bimTypeName', aliasName: '构件分类名称', category: "STATIC", editable: true},
+                    {path: 'localId', aliasName: '本地编码', category: "STATIC", editable: true},
+                    {path: 'floor.localName', editable: false, aliasName: '所属楼层', category: "STATIC"},
+                    {
+                        path: 'onSpace',
+                        editable: false,
+                        aliasName: '所在空间',
+                        dataType: 'STRING',
+                        category: "STATIC",
+                        render: (obj: any) => {
+                            return obj?.objectInfo && obj.objectInfo.map((item: any) => item.localName).join(',') || ''
+                        }
+                    }]
+                this.deviceHeaders = {
+                    basicInfos,
+                    dictStages: res.dictStages
+                }
             })
         } else {
             console.log(5)
@@ -269,10 +286,35 @@ export default class extends Vue {
                 }
             })
         }
+        // this.headersStage = {
+        //     basicInfos: {
+        //         name: '基础信息台账',
+        //         data: this.headerInformation.basicInfos
+        //     },
+        //     dictStages: {
+        //         name: this.currentHeader,
+        //         data: pic.length > 0 ? [...base, ...pic] : [...base]
+        //     }
+        // }
+        // todo 固定写死基础信息台账
         this.headersStage = {
             basicInfos: {
                 name: '基础信息台账',
-                data: this.headerInformation.basicInfos
+                data: [
+                    {path: 'bimTypeName', aliasName: '构件分类名称', category: "STATIC"},
+                    {path: 'localId', aliasName: '本地编码', category: "STATIC"},
+                    {path: 'floor.localName', editable: false, aliasName: '所属楼层', category: "STATIC"},
+                    {
+                        path: 'onSpace',
+                        editable: false,
+                        aliasName: '所在空间',
+                        dataType: 'STRING',
+                        category: "STATIC",
+                        render: (obj: any) => {
+                            return obj?.objectInfo && obj.objectInfo.map((item: any) => item.localName).join(',') || ''
+                        }
+                    }
+                ],
             },
             dictStages: {
                 name: this.currentHeader,
@@ -407,7 +449,7 @@ export default class extends Vue {
 
     // 删除设备
     deleteDevice() {
-        deleteEquip([{ id: this.currRowContent.id }]).then(res => {
+        deleteEquip([{id: this.currRowContent.id}]).then(res => {
             if (res.result == 'success') {
                 this.$message.success('删除成功')
                 this.handleChangeDevice()
@@ -460,7 +502,7 @@ export default class extends Vue {
         // @ts-ignore
         const data = this.$refs.deviceGraph.getLocation()
         if (data) {
-            this.curEquip.bimLocation = `${ data.x },${ data.y },${ data.z }`;
+            this.curEquip.bimLocation = `${data.x},${data.y},${data.z}`;
             this.curEquip.buildingId = data.buildingId;
             this.curEquip.floorId = data.floorId;
         }
@@ -478,9 +520,9 @@ export default class extends Vue {
     handleUpdateEquip(obj) {
         let pa;
         if (Array.isArray(obj)) {
-            pa = { content: obj }
+            pa = {content: obj}
         } else {
-            pa = { content: [obj] }
+            pa = {content: [obj]}
         }
         updateEquip(pa).then(res => {
             if (res.result == 'success') {
@@ -495,9 +537,9 @@ export default class extends Vue {
     handleCreateEquip(obj: any) {
         let pa;
         if (Array.isArray(obj)) {
-            pa = { content: obj }
+            pa = {content: obj}
         } else {
-            pa = { content: [obj] }
+            pa = {content: [obj]}
         }
         createEquip(pa).then(res => {
             if (res.result == 'success') {
@@ -521,7 +563,7 @@ export default class extends Vue {
         this.currRowContent = this.currentRow
     }
 
-    @Watch("deviceType", { immediate: true, deep: true })
+    @Watch("deviceType", {immediate: true, deep: true})
     handleDeviceMsg() {
         this.deviceVal = this.deviceType
     }

+ 88 - 71
src/views/maintain/space/index.vue

@@ -15,6 +15,7 @@
                                      @change="changeCascader" style="margin-right: 12px"
                         ></el-cascader>
                         <el-cascader v-model="zoneTypeValue" :options="zoneTypeOption" placeholder="请选择分区"
+                                     ref="cascaderZone"
                                      @change="changeZoneTypes"
                                      class="item"></el-cascader>
                         <admSearch @SearchValue="searchValue" class="item"/>
@@ -379,8 +380,7 @@ export default class spaceIndex extends Vue {
                     {name: "building"},
                     {name: "floor", orders: "floorSequenceId desc"},
                 ],
-                // zoneType: "FunctionZone",
-                zoneType: this.zoneTypeValue[this.zoneTypeValue.length - 1],
+                classCode: this.zoneTypeValue[this.zoneTypeValue.length - 1],
                 pageNumber: this.paginationList.page,
                 pageSize: this.paginationList.size,
                 orders: "createTime desc, localName asc, localId desc, id asc",
@@ -431,78 +431,95 @@ export default class spaceIndex extends Vue {
                 let basicInfos = [],
                     dictStages = [];
                 this.all = res[0].content;
-                res[0].content.forEach((item) => {
-                    let i = ["localName", "localId", "building", "floor"];
-                    if (i.includes(item.path)) {
-                        basicInfos.push(item);
-                    } else {
-                        dictStages.push(item);
-                    }
-                });
-                dictStages.map((val, index) => {
-                    if (val.path == "outline") {
-                        dictStages.splice(index, 1);
-                    }
-                    return val;
-                });
-                basicInfos.map((item) => {
-                    if (item.path == "building") {
-                        item.path = "buildingSign";
-                    }
-                    if (item.path == "floor") {
-                        item.path = "floorSign";
-                    }
-                    return item;
-                });
+                if (this.zoneTypeValue[0] != "FunctionZone") {
+                    // todo 列表只展示 分区 / 包含的功能空间
+                    const currentZone = this.$refs['cascaderZone'].getCheckedNodes()[0].label
+
+                    this.headersStage = {
+                        basicInfos: {
+                            name: "基础信息台账",
+                            data: [
+                                {path: 'localName', editable: false, aliasName: currentZone},
+                                {path: 'defaultSpace', editable: false, aliasName: '包含的功能分区'}
+                            ],
+                        },
+                    };
+                    this.paginationList.total = res[1].total;
+                    tableData = res[1].content.map(i => i.path == 'localName'); // 主体数据
+                } else {
+                    res[0].content.forEach((item) => {
+                        let i = ["localName", "localId", "building", "floor"];
+                        if (i.includes(item.path)) {
+                            basicInfos.push(item);
+                        } else {
+                            dictStages.push(item);
+                        }
+                    });
+                    dictStages.map((val, index) => {
+                        if (val.path == "outline") {
+                            dictStages.splice(index, 1);
+                        }
+                        return val;
+                    });
+                    basicInfos.map((item) => {
+                        if (item.path == "building") {
+                            item.path = "buildingSign";
+                        }
+                        if (item.path == "floor") {
+                            item.path = "floorSign";
+                        }
+                        return item;
+                    });
 
-                this.headersStage = {
-                    basicInfos: {
-                        name: "基础信息台账",
-                        data: basicInfos,
-                    },
-                    dictStages: {
-                        name: "租赁系统",
-                        data: dictStages,
-                    },
-                };
-                this.paginationList.total = res[1].total;
-                tableData = res[1].content; // 主体数据
-                // 处理 outline BIM模型中轮廓坐标 展示
-                // 添加建筑,楼层展示(从下拉框获取)
-                this.tableData = tableData.map((item) => {
-                    if (item.building) {
-                        item.buildingSign = item.building.localName;
-                    }
-                    if (item.floor) {
-                        item.floorSign = item.floor.localName;
-                    }
-                    // 删除轮廓线
-                    if (item.outline) {
-                        delete item.outline;
-                    }
-                    // item = {
-                    //     ...item,
-                    //     outline: JSON.stringify(item.outline),
-                    // };
+                    this.headersStage = {
+                        basicInfos: {
+                            name: "基础信息台账",
+                            data: basicInfos,
+                        },
+                        dictStages: {
+                            name: "租赁系统",
+                            data: dictStages,
+                        },
+                    };
+                    this.paginationList.total = res[1].total;
+                    tableData = res[1].content; // 主体数据
+                    // 处理 outline BIM模型中轮廓坐标 展示
+                    // 添加建筑,楼层展示(从下拉框获取)
+                    this.tableData = tableData.map((item) => {
+                        if (item.building) {
+                            item.buildingSign = item.building.localName;
+                        }
+                        if (item.floor) {
+                            item.floorSign = item.floor.localName;
+                        }
+                        // 删除轮廓线
+                        if (item.outline) {
+                            delete item.outline;
+                        }
+                        // item = {
+                        //     ...item,
+                        //     outline: JSON.stringify(item.outline),
+                        // };
 
-                    return item;
-                });
-                //  列表信息展示,获取动态数据
-                this.codeToDataSource = {};
-                this.all.forEach((item) => {
-                    if (item.dataSource) {
-                        try {
-                            this.codeToDataSource[item.code] = {};
-                            item.dataSource.forEach((dic) => {
-                                this.codeToDataSource[item.code][dic.code] =
-                                    dic.name;
-                            });
-                        } catch (e) {
-                            console.log(e);
+                        return item;
+                    });
+                    //  列表信息展示,获取动态数据
+                    this.codeToDataSource = {};
+                    this.all.forEach((item) => {
+                        if (item.dataSource) {
+                            try {
+                                this.codeToDataSource[item.code] = {};
+                                item.dataSource.forEach((dic) => {
+                                    this.codeToDataSource[item.code][dic.code] =
+                                        dic.name;
+                                });
+                            } catch (e) {
+                                console.log(e);
+                            }
                         }
-                    }
-                });
-                this.getBatch(this.tableData);
+                    });
+                    this.getBatch(this.tableData);
+                }
             });
         } else {
             console.log("void");

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

@@ -78,7 +78,7 @@ import { allSystem, BeatchQueryParam } from "@/api/equipComponent";
 export default class extends Vue {
     optionProps = {
         value: 'code',
-        label: 'name',
+        label: 'aliasName',
         children: 'children'
     }
     // 设置高度

+ 28 - 5
src/views/scene/plane/index.vue

@@ -1,12 +1,35 @@
 <template>
-    <div>平面图</div>
+    <div></div>
 </template>
 
-<script>
-export default {
-    name: "平面图"
+<script lang="ts">
+import { Vue, Component } from "vue-property-decorator";
+import { UserModule } from "@/store/modules/user";
+
+// 平面图跳转地址
+// @ts-ignore
+const planJumpUrl = window.__systemConf.planJumpUrl;
+
+@Component({
+    name: "system",
+    components: {},
+})
+export default class extends Vue {
+    // 项目id
+    private get projectId(): string {
+        return UserModule.projectId;
+    }
+
+    // 项目名称
+    private get projectName(): string {
+        return UserModule.projectName;
+    }
+
+    created() {
+        window.open(`${planJumpUrl}?projectId=${this.projectId}&projectName=${this.projectName}`);
+    }
 }
 </script>
 
-<style scoped>
+<style lang="scss" scoped>
 </style>

+ 28 - 5
src/views/scene/system/index.vue

@@ -1,12 +1,35 @@
 <template>
-    <div>系统</div>
+    <div></div>
 </template>
 
-<script>
-export default {
-    name: "index"
+<script lang="ts">
+import { Vue, Component } from "vue-property-decorator";
+import { UserModule } from "@/store/modules/user";
+
+// 系统图跳转地址
+// @ts-ignore
+const topoJumpUrl = window.__systemConf.topoJumpUrl;
+
+@Component({
+    name: "system",
+    components: {},
+})
+export default class extends Vue {
+    // 项目id
+    private get projectId(): string {
+        return UserModule.projectId;
+    }
+
+    // 项目名称
+    private get projectName(): string {
+        return UserModule.projectName;
+    }
+
+    created() {
+        window.open(`${topoJumpUrl}?projectId=${this.projectId}&projectName=${this.projectName}`);
+    }
 }
 </script>
 
-<style scoped>
+<style lang="scss" scoped>
 </style>

+ 35 - 7
src/views/scene/tiepoint/components/equipTab/index.vue

@@ -12,13 +12,18 @@
             <admSearch @SearchValue="searchValue" class="item"/>
             <el-upload
                 style="float: right"
-                action="https://jsonplaceholder.typicode.com/posts/"
+                action="/datacenter/object/equip/import"
+                :disabled="true"
+                :headers="{ projectId: projectId, groupCode: 'WD' }"
+                :data="{ projectId: projectId, classCode: deviceType }"
                 :show-file-list="false"
                 multiple
             >
-                <el-button>上传Excle</el-button>
+                <el-button :disabled="!deviceType">上传Excle</el-button>
             </el-upload>
-            <el-button style="float: right; margin-right: 12px" @click="handleClickDownload">下载模板</el-button>
+            <el-tooltip effect="dark" content="请选择设备类型" placement="top">
+                <el-button style="float: right; margin-right: 12px" :disabled="!deviceType" @click="handleClickDownload">下载模板</el-button>
+            </el-tooltip>
         </div>
         <div v-loading="loading" style="height: calc(100% - 100px); padding: 0 12px; position: relative">
             <template style="height: 100%" v-if="tableData.length">
@@ -58,7 +63,7 @@
 <script lang="ts">
 import { Vue, Component, Ref } from "vue-property-decorator";
 import { allDevice, dictInfo } from "@/api/equipComponent";
-import { queryEquip, updateEquip } from "@/api/datacenter";
+import { queryEquip, updateEquip, exportEquip } from "@/api/datacenter";
 import { AdmMultiTable, AdmSearch, Pagination, baseDataForm } from "@/views/maintain/components/index";
 import { UserModule } from "@/store/modules/user";
 import tools from "@/utils/maintain";
@@ -149,6 +154,7 @@ export default class EquipTab extends Vue {
             };
             let param2 = {
                 filters: `classCode='${ this.deviceType }'`,
+                cascade: [{"name": "floor",}, {"name": "objectInfo"}],
                 pageNumber: this.paginationList.page,
                 pageSize: this.paginationList.size,
                 orders: "createTime desc, id asc",
@@ -217,6 +223,14 @@ export default class EquipTab extends Vue {
     private informationArrangement(data: any): any {
         if (data?.basicInfos && data?.dictStages) {
             const base: any[] = [];
+            const basicInfos: any[] = [
+                {path: 'bimTypeName', editable: true, aliasName: '构件分类名称', dataType: 'STRING', category: "STATIC"},
+                {path: 'localId', editable: true, aliasName: '本地编码', dataType: 'STRING', category: "STATIC"},
+                {path: 'floor.localName', editable: false, aliasName: '所属楼层', dataType: 'STRING', category: "STATIC"},
+                {path: 'onSpace', editable: false, aliasName: '所在空间', dataType: 'STRING', category: "STATIC", render: (obj: any) => {
+                    return obj?.objectInfo && obj.objectInfo.map((item: any) => item.localName).join(',') || ''
+                }}
+            ]
             data.dictStages.forEach((item: any) => {
                 if (this.currentHeader === item.name) {
                     item?.infos.forEach((val: any) => {
@@ -225,7 +239,7 @@ export default class EquipTab extends Vue {
                 }
             });
             // 信息点集合
-            this.all = [...data.basicInfos, ...base];
+            this.all = [...basicInfos, ...data.basicInfos, ...base];
             this.codeToDataSource = {};
             this.all.forEach((item: any) => {
                 if (item.dataSource) {
@@ -242,7 +256,7 @@ export default class EquipTab extends Vue {
             return {
                 basicInfos: {
                     name: "基础信息台账",
-                    data: data.basicInfos,
+                    data: basicInfos,
                 },
                 dictStages: {
                     name: this.currentHeader,
@@ -274,8 +288,22 @@ export default class EquipTab extends Vue {
     /**
      * 下载模板
      */
-    private handleClickDownload() {
+    private async handleClickDownload() {
         console.log("下载模板");
+        /**
+         * TODO:下载模板代码
+         */
+        // if (!this.projectId) {
+        //     this.$message.info("请选择项目");
+        // } else if (!this.deviceType) {
+        //     this.$message.info("请选择设备类型");
+        // } else {
+        //     const getParams = {
+        //         projectId: this.projectId,
+        //         classCode: this.deviceType
+        //     }
+        //     exportEquip(getParams);
+        // }
     }
 
     /**

+ 1 - 1
src/views/scene/tiepoint/index.vue

@@ -1,5 +1,5 @@
 <template>
-    <div class="adm-tiepoint"style="display: none">
+    <div class="adm-tiepoint">
         <div class="tabs">
             <el-tabs v-model="activeName" type="card" @tab-click="tabChange">
                 <el-tab-pane label="设备" name="equip">

+ 40 - 3
vue.config.js

@@ -4,12 +4,35 @@ const devServerPort = 28888;
 const stageServerPort = 28889;
 module.exports = {
     // TODO: 更改 publicPath 打包静态文件目录的配置
-    publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
+    publicPath: process.env.NODE_ENV === "production" ? "/" : "/wanda-adm/",
     // TODO:打包名称
     outputDir: "wanda-adm",
+
+    configureWebpack: {
+        module: {
+            rules: [{
+                test: /\.(ttf|otf|eot|woff|woff2)$/,
+                use: {
+                    loader: "file-loader",
+                    options: {
+                        name: "fonts/[name].[ext]",
+                    },
+                },
+            },
+                {
+                    test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
+                    loader: 'url-loader',
+                    options: {
+                        limit: 10000,
+                        name: ('fonts/[name].[ext]')
+                    }
+                }]
+        }
+    },
     //TODO: eslint 是否在保存时检查
+    // assetsDir:'/',
     lintOnSave: process.env.NODE_ENV === "development",
-    productionSourceMap: false,
+    productionSourceMap: true,
     devServer: {
         port: devServerPort,
         open: true,
@@ -20,7 +43,7 @@ module.exports = {
         progress: false,
         proxy: {
             [process.env.VUE_APP_BASE_API]: {
-                target: `http://127.0.0.1:${stageServerPort}/mock-api/v1`,
+                target: `http://127.0.0.1:${ stageServerPort }/mock-api/v1`,
                 changeOrigin: true, // needed for virtual hosted sites
                 ws: true, // proxy websockets
                 pathRewrite: {
@@ -79,6 +102,7 @@ module.exports = {
     pluginOptions: {
         "style-resources-loader": {
             preProcessor: "scss",
+            // sourceMap: true,
             patterns: [
                 path.resolve(__dirname, "src/styles/_variables.scss"),
                 path.resolve(__dirname, "src/styles/_mixins.scss")
@@ -87,6 +111,19 @@ module.exports = {
     },
     // 高级配置
     chainWebpack(config) {
+        config.module
+            .rule("fonts")
+            .test(/\.(ttf|otf|eot|woff|woff2)$/)
+            .use("file-loader")
+            .loader("file-loader")
+            .tap(options => {
+                options = {
+                    // limit: 10000,
+                    name: 'fonts/[name].[ext]',
+                }
+                return options
+            })
+            .end()
         //在html网页包插件的选项列表中提供应用程序的标题,以便
         //可以在中访问索引.html插入正确的标题。
         // https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-plugin