|
|
@@ -0,0 +1,372 @@
|
|
|
+<template>
|
|
|
+ <div class="PbsTreeManagement">
|
|
|
+ <el-tabs v-model="activeName">
|
|
|
+ <el-tab-pane label="设计" name="design">
|
|
|
+ <div class="designSearch">
|
|
|
+ <div class="designItem">
|
|
|
+ <el-select size="mini" v-model="searchType" @change="searchTypeChange">
|
|
|
+ <el-option label="工程名称" value="2"></el-option>
|
|
|
+ <el-option label="PBS编码" value="0"></el-option>
|
|
|
+ <el-option label="部件标识码" value="1"></el-option>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ <div class="designItem">
|
|
|
+ <el-input size="mini" v-model="searchInput" clearable @clear="clearInput"> </el-input>
|
|
|
+ </div>
|
|
|
+ <div class="designItem">
|
|
|
+ <el-button size="mini" type="primary" icon="el-icon-search" @click="searchOperation"></el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="designTree">
|
|
|
+ <el-tree
|
|
|
+ :data="treeData"
|
|
|
+ :props="props"
|
|
|
+ :load="loadNode"
|
|
|
+ lazy
|
|
|
+ node-key="id"
|
|
|
+ highlight-current
|
|
|
+ :default-expanded-keys="[1]"
|
|
|
+ :render-content="renderContent"
|
|
|
+ @node-click="handleNodeClick"
|
|
|
+ @node-contextmenu="exportQRCode"
|
|
|
+ ></el-tree>
|
|
|
+ <div class="tip" :style="{ left: optionCardX + 'px', top: optionCardY + 'px' }" v-show="tipShow">
|
|
|
+ <el-button type="primary" size="mini" @click="exportCurrent">导出二维码</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane label="竣工" name="completed">暂无</el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { pbsTreeList_api, pbsTreeSearch_api, pbsTreeMinimum_api, createPdfByType_api } from '@/api/APIs.ts'
|
|
|
+// import Vue from "vue";
|
|
|
+// import PipeUnitInfo from "@/views/widgets/PipeUnitInfo/index.vue";
|
|
|
+export default {
|
|
|
+ name: 'PbsTreeManagement',
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ activeName: 'design',
|
|
|
+ searchType: '2', //默认为工程名称
|
|
|
+ searchInput: '',
|
|
|
+ choke: false, //节流
|
|
|
+ //设计模块的数据
|
|
|
+ originalData: '', //设计模块请求来的原始数据,用于项目名称搜索功能
|
|
|
+ fatherNodesData: [], //第一次请求来处理后的父节点数据
|
|
|
+ treeData: [],
|
|
|
+ tipShow: false,
|
|
|
+ optionCardX: '',
|
|
|
+ optionCardY: '',
|
|
|
+ treeNodeId: '',
|
|
|
+ //设计模块的elm绑定属性
|
|
|
+ props: {
|
|
|
+ label: 'name',
|
|
|
+ children: 'children',
|
|
|
+ isLeaf: 'leaf'
|
|
|
+ },
|
|
|
+ viewer: window.viewer,
|
|
|
+ pipeInfo: null
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ //懒加载树状下层
|
|
|
+ async loadNode(node, resolve) {
|
|
|
+ // if (node.level == 0) {
|
|
|
+ // return this.loadtreeData(resolve)
|
|
|
+ // }
|
|
|
+ // if (node.level >= 1 && node.data) {
|
|
|
+ // if (node.data.levelname == '部件类型') {
|
|
|
+ // let id = node.data.id
|
|
|
+ // let res = await this.minimumNodesResult(id)
|
|
|
+ // if (res) {
|
|
|
+ // return resolve(res)
|
|
|
+ // }
|
|
|
+ // } else {
|
|
|
+ // return resolve(node.data.children)
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ },
|
|
|
+ // 获取树状结构列表
|
|
|
+ async loadtreeData(resolve) {
|
|
|
+ let res = await pbsTreeList_api()
|
|
|
+ let { result } = res.data
|
|
|
+ this.fatherNodesData = this.getPbsTree(result)
|
|
|
+ resolve(this.fatherNodesData)
|
|
|
+ this.originalData = result
|
|
|
+ },
|
|
|
+ //结构树最小单元
|
|
|
+ async minimumNodesResult(id) {
|
|
|
+ let minimumTree = await this.getTreeMinimum(id)
|
|
|
+ return minimumTree
|
|
|
+ },
|
|
|
+ //获取树状结构列表的最小单元
|
|
|
+ async getTreeMinimum(val) {
|
|
|
+ let res = await pbsTreeMinimum_api({ id: val })
|
|
|
+ let { result } = res.data
|
|
|
+ result.forEach((item) => {
|
|
|
+ item.value = item.code
|
|
|
+ item.name = `${item.code}(${item.pipeId})`
|
|
|
+ item.leaf = true
|
|
|
+ })
|
|
|
+ return result
|
|
|
+ },
|
|
|
+ //对后台返回的列表结构处理分类成PBS分支树所需的树状数据
|
|
|
+ getPbsTree(results) {
|
|
|
+ let that = this
|
|
|
+ let dep = 0
|
|
|
+ let curPid = []
|
|
|
+ function arr2tree(data, parent) {
|
|
|
+ let tree = [] // 定义最终输出
|
|
|
+ let temp = [] // 定义中间存储用变量
|
|
|
+ const usedParent = that.$_.find(curPid, function (item) {
|
|
|
+ return item.pid === parent
|
|
|
+ })
|
|
|
+ if (!usedParent) {
|
|
|
+ dep += 1
|
|
|
+ curPid.push({ pid: parent, dep: dep })
|
|
|
+ }
|
|
|
+ for (let i = 0; i < data.length; i++) {
|
|
|
+ if (data[i].pid == parent) {
|
|
|
+ // 找到父级
|
|
|
+ let obj = data[i] // 保存父级
|
|
|
+ obj.originname = obj.name
|
|
|
+ obj.name = `${obj.name}_${obj.code}`
|
|
|
+ obj.leaf = false //用于elementUI的渲染
|
|
|
+ obj.prjId = obj.prjid
|
|
|
+ obj.prjName = obj.prjname
|
|
|
+ const curparent = that.$_.find(curPid, function (item) {
|
|
|
+ return item.pid === parent
|
|
|
+ })
|
|
|
+ let open = true
|
|
|
+ if (curparent) {
|
|
|
+ dep = curparent.dep
|
|
|
+ if (curparent.dep >= 2) open = false
|
|
|
+ }
|
|
|
+ if (obj.levelname !== '部件类型') {
|
|
|
+ temp = arr2tree(data, data[i].id) // 递归调用
|
|
|
+ }
|
|
|
+ if (temp.length > 0) {
|
|
|
+ // 如果找到了
|
|
|
+ obj.children = temp // 父级的子集就等于刚才递归的结果
|
|
|
+ obj.open = open
|
|
|
+ } else {
|
|
|
+ obj.children = [] // 没有子集就把这个父级的children字段改成null 防止出现收起展开的图标
|
|
|
+ }
|
|
|
+ tree.push(obj) // 把父级和子集放到最终输出
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return tree
|
|
|
+ }
|
|
|
+ let treeData = arr2tree(results[0].structures, null)
|
|
|
+ return treeData
|
|
|
+ },
|
|
|
+ renderContent(h, { node, data, store }) {
|
|
|
+ if (data.pressureType == '1') {
|
|
|
+ return <span style="font-size:14px;">{node.label}</span>
|
|
|
+ } else if (data.pressureType == '2') {
|
|
|
+ return <span style="color:#0076FF;font-size:14px;">{node.label}</span>
|
|
|
+ } else if (data.pressureType == '3') {
|
|
|
+ return <span style="color:#009100;font-size:14px;">{node.label}</span>
|
|
|
+ } else {
|
|
|
+ return <span style="font-size:14px;">{node.label}</span>
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 树结构子项点击调用
|
|
|
+ handleNodeClick(data) {
|
|
|
+ this.tipShow = false
|
|
|
+ if (!this.viewer) return
|
|
|
+ if (data !== null && data.layerName) {
|
|
|
+ let lyName = '',
|
|
|
+ code = data.value
|
|
|
+ if (data.layerName.indexOf(',') > -1) {
|
|
|
+ lyName = data.layerName.split(',')[1]
|
|
|
+ } else {
|
|
|
+ lyName = data.layerName
|
|
|
+ }
|
|
|
+ const pipeInfoConstructor = Vue.extend(PipeUnitInfo)
|
|
|
+ // if(!this.pipeInfo){
|
|
|
+ const pipeInfo = new pipeInfoConstructor({
|
|
|
+ data: {
|
|
|
+ pickType: 'point',
|
|
|
+ isInteractive: false,
|
|
|
+ locateUnit: {
|
|
|
+ name: lyName,
|
|
|
+ id: code
|
|
|
+ }
|
|
|
+ },
|
|
|
+ store: this.$store
|
|
|
+ }).$mount()
|
|
|
+ // }else{
|
|
|
+ // this.pipeInfo.$set(this.pipeInfo.locateUnit,"name",lyName)
|
|
|
+ // this.pipeInfo.$set(this.pipeInfo.locateUnit,"id",code)
|
|
|
+ // }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //右键点击显示导出按钮
|
|
|
+ exportQRCode(e, data) {
|
|
|
+ this.treeNodeId = ''
|
|
|
+ if (data !== null && data.levelname === '部件类型') {
|
|
|
+ this.tipShow = false
|
|
|
+ this.optionCardX = e.x
|
|
|
+ this.optionCardY = e.y
|
|
|
+ this.treeNodeId = data.id
|
|
|
+ this.tipShow = true
|
|
|
+ } else {
|
|
|
+ this.tipShow = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //点击导出二维码
|
|
|
+ async exportCurrent() {
|
|
|
+ const downloadUrl = '/tofly-sxgk/commonFile/download'
|
|
|
+ const data = { stdId: this.treeNodeId }
|
|
|
+ let res = await createPdfByType_api(data)
|
|
|
+ const { code, result } = res.data
|
|
|
+ if (code === 1) {
|
|
|
+ const pdf = this.$store.state.apiRoot + downloadUrl + '?fileName=' + result
|
|
|
+ window.open(pdf)
|
|
|
+ this.tipShow = false
|
|
|
+ } else {
|
|
|
+ this.$message.error('获取二维码信息失败')
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //设计模块的搜索
|
|
|
+ searchOperation() {
|
|
|
+ if (this.choke) return
|
|
|
+ this.choke = true
|
|
|
+ const code = this.searchInput.toString().trim()
|
|
|
+ if (code === '') {
|
|
|
+ this.$notify.error({
|
|
|
+ title: '提示',
|
|
|
+ message: '请输入查询内容',
|
|
|
+ duration: 2500
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const searchType = this.searchType.toString()
|
|
|
+ switch (searchType) {
|
|
|
+ case '0':
|
|
|
+ this.searchOnline(code)
|
|
|
+ break
|
|
|
+ case '1':
|
|
|
+ this.searchOnline(code)
|
|
|
+ break
|
|
|
+ case '2':
|
|
|
+ this.searchLocal(code, true)
|
|
|
+ break
|
|
|
+ }
|
|
|
+ setTimeout(() => {
|
|
|
+ this.choke = false
|
|
|
+ }, 4000)
|
|
|
+ },
|
|
|
+ //在线搜索,除工程名称外的2个选项使用
|
|
|
+ searchOnline(value) {
|
|
|
+ if (!value) return
|
|
|
+ const size = 50 //每次最大搜索条数
|
|
|
+ this.searchPBS(value, size)
|
|
|
+ },
|
|
|
+ //搜索功能
|
|
|
+ async searchPBS(value, size) {
|
|
|
+ let res = await pbsTreeSearch_api({
|
|
|
+ pbs: value,
|
|
|
+ pageSize: size
|
|
|
+ })
|
|
|
+ let { result, code } = res.data
|
|
|
+ if (code === 1 && result) {
|
|
|
+ if (result.length >= size) {
|
|
|
+ this.$notify({
|
|
|
+ title: '提示',
|
|
|
+ message: `查询结果过多!当前显示匹配的${size}条结果`,
|
|
|
+ type: 'warning',
|
|
|
+ duration: 2000
|
|
|
+ })
|
|
|
+ }
|
|
|
+ // 对搜索结果进行处理,让elementUI可以渲染
|
|
|
+ const nodes = result.map((item) => {
|
|
|
+ item.value = item.code
|
|
|
+ item.name = `${item.code}(${item.pipeId})`
|
|
|
+ item.leaf = true
|
|
|
+ return item
|
|
|
+ })
|
|
|
+ this.treeData = nodes
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 工程名称选项本地搜索
|
|
|
+ * code 模糊查询字符串
|
|
|
+ * vague 是否模糊查询
|
|
|
+ */
|
|
|
+ searchLocal(code, vague) {
|
|
|
+ let nodes = []
|
|
|
+ let allNodes = this.originalData[0].structures //服务器原始数据目录
|
|
|
+ let filterNodes = []
|
|
|
+ if (vague) {
|
|
|
+ //查找包含字符
|
|
|
+ for (let i of allNodes) {
|
|
|
+ if (i.originname) {
|
|
|
+ if (i.originname.indexOf(code) != -1) {
|
|
|
+ filterNodes.push(i)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //判断父子节点
|
|
|
+ for (let i = 0; i < filterNodes.length; i++) {
|
|
|
+ const item = filterNodes[i]
|
|
|
+ const parentNode = _.find(filterNodes, (node) => {
|
|
|
+ return node.id === item.pid
|
|
|
+ })
|
|
|
+ if (!parentNode) {
|
|
|
+ nodes.push(item)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //显示查找结果
|
|
|
+ this.treeData = nodes
|
|
|
+ },
|
|
|
+ //搜索类型改变时清空输入
|
|
|
+ searchTypeChange() {
|
|
|
+ this.searchInput = ''
|
|
|
+ },
|
|
|
+ //清除搜索结果
|
|
|
+ clearInput() {
|
|
|
+ this.treeData = this.fatherNodesData
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.PbsTreeManagement {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ padding: 0 !important;
|
|
|
+ .designSearch {
|
|
|
+ display: flex;
|
|
|
+ .designItem {
|
|
|
+ margin: 0 5px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .designTree {
|
|
|
+ height: 700px;
|
|
|
+ overflow-y: auto;
|
|
|
+ margin-top: 10px;
|
|
|
+ position: relative;
|
|
|
+ .tip {
|
|
|
+ position: fixed;
|
|
|
+ z-index: 999;
|
|
|
+ width: 50px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /deep/ .el-tab-pane {
|
|
|
+ color: #eee;
|
|
|
+ }
|
|
|
+ /deep/ .el-tree {
|
|
|
+ background: transparent;
|
|
|
+ .el-tree-node > .el-tree-node__children {
|
|
|
+ overflow: unset;
|
|
|
+ background-color: transparent;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|