index.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. <template>
  2. <div>
  3. <div class="statistics">
  4. <div class="building">
  5. <p>建筑模型文件夹:<b>{{ModelFileCount}}</b></p>
  6. </div>
  7. <div class="includefloor">
  8. <p>包含楼层模型文件:<b>{{modelFloorCount}}</b></p>
  9. </div>
  10. <div class="problematic">
  11. <p>检查出问题的楼层模型文件:<b>{{problemCount}}</b></p>
  12. </div>
  13. </div>
  14. <div class="main-content">
  15. <div class="tab-box">
  16. <el-tabs v-model="activeTab" type='card' @tab-click="getData">
  17. <template v-for="(item,index) in tableList">
  18. <el-tab-pane :name="item.Code" :key="index" :label="item.Name">
  19. <span slot="label">
  20. <i :class="item.flag?'msg-icon el-icon-success success-color':'msg-icon el-icon-error error-color'" style="font-size:14px;"></i>
  21. <span>{{ item.Name }}</span>
  22. </span>
  23. </el-tab-pane>
  24. </template>
  25. </el-tabs>
  26. </div>
  27. <div class="content-box">
  28. <div class="button">
  29. <el-link :underline="false" @click="del" v-if="toBeDelCount">需从模型中删除的设备</el-link>
  30. <el-link @click="supplement" :underline="false" v-if="toBeSuppCount">模型待补充的设备</el-link>
  31. <el-button type="info" :loading="load" @click='getExportReport' style="border:1px solid #dcdfe6;color:#606266;background:white;">导出模型问题报告
  32. </el-button>
  33. </div>
  34. <div class="table" :style="tableList&&tableList.length?'width: 100%;height: calc(100% - 47px)':'width: 100%;height: calc(100% - 10px)'">
  35. <el-table ref="multipleTable" :data="tableData" stripe height="100%" :header-cell-style="headerStyle" v-loading='loading'
  36. :row-class-name="tableRowClassName">
  37. <el-table-column prop="FloorName" label="模型楼层" fixed width="150"></el-table-column>
  38. <el-table-column prop="functionNo" label="待删除设备数量" fixed width="150">
  39. <template slot-scope="scope">
  40. <el-badge :value="scope.row.toBeDel" class="item" :type='scope.row.toBeDel?"danger":"success"'>
  41. </el-badge>
  42. </template>
  43. </el-table-column>
  44. <el-table-column prop="toBeSupplement" label="待补充设备数量" fixed width="150">
  45. <template slot-scope="scope">
  46. <el-badge :value="scope.row.toBeSupplement" class="item" :type='scope.row.toBeSupplement?"danger":"success"'>
  47. </el-badge>
  48. </template>
  49. </el-table-column>
  50. <el-table-column prop="questionItem" label="有问题的检查项" fixed width="150">
  51. <template slot-scope="scope">
  52. <el-badge :value="scope.row.questionItem" class="item" :type='scope.row.questionItem?"warning":"success"'>
  53. </el-badge>
  54. </template>
  55. </el-table-column>
  56. <el-table-column prop="ElementRangeCheck" label='构件范围检查' width="200">
  57. <template slot-scope="scope">
  58. <el-badge :value="scope.row.ElementRangeCheck" class="item" type='danger' v-if="scope.row.ElementRangeCheck">
  59. </el-badge>
  60. <i class="msg-icon el-icon-success success-color" style="font-size:20px;" v-if="scope.row.ElementRangeCheck<=0"></i>
  61. </template>
  62. </el-table-column>
  63. <el-table-column prop="FamilyNameCheck" label='设备族编码检查' width="200">
  64. <template slot-scope="scope">
  65. <el-badge :value="scope.row.FamilyNameCheck" class="item" type='danger' v-if="scope.row.FamilyNameCheck">
  66. </el-badge>
  67. <i class="msg-icon el-icon-success success-color" style="font-size:20px;" v-if="scope.row.FamilyNameCheck<=0"></i>
  68. </template>
  69. </el-table-column>
  70. <el-table-column prop="EquipPartLocationCheck" label='部件所在位置检查' width="200">
  71. <template slot-scope="scope">
  72. <el-badge :value="scope.row.EquipPartLocationCheck" class="item" type='danger' v-if="scope.row.EquipPartLocationCheck">
  73. </el-badge>
  74. <i class="msg-icon el-icon-success success-color" style="font-size:20px;" v-if="scope.row.EquipPartLocationCheck<=0"></i>
  75. </template>
  76. </el-table-column>
  77. <el-table-column prop="ColumnCheck" label='柱边界检查' width="200">
  78. <template slot-scope="scope">
  79. <el-badge :value="scope.row.ColumnCheck" class="item" type='danger' v-if="scope.row.ColumnCheck">
  80. </el-badge>
  81. <i class="msg-icon el-icon-success success-color" style="font-size:20px;" v-if="scope.row.ColumnCheck<=0"></i>
  82. </template>
  83. </el-table-column>
  84. <el-table-column prop="ConnectorCheck" label='连接件检查' width="200">
  85. <template slot-scope="scope">
  86. <el-badge :value="scope.row.ConnectorCheck" class="item" type='danger' v-if="scope.row.ConnectorCheck">
  87. </el-badge>
  88. <i class="msg-icon el-icon-success success-color" style="font-size:20px;" v-if="scope.row.ConnectorCheck<=0"></i>
  89. </template>
  90. </el-table-column>
  91. <el-table-column prop="SystemNameCheck" label='系统类型名称检查' width="200">
  92. <template slot-scope="scope">
  93. <el-badge :value="scope.row.SystemNameCheck" class="item" type='danger' v-if="scope.row.SystemNameCheck">
  94. </el-badge>
  95. <i class="msg-icon el-icon-success success-color" style="font-size:20px;" v-if="scope.row.SystemNameCheck<=0"></i>
  96. </template>
  97. </el-table-column>
  98. <el-table-column prop="EquipInSpaceCheck" label='未在空间中的设备' width="200">
  99. <template slot-scope="scope">
  100. <el-badge :value="scope.row.EquipInSpaceCheck" class="item" type='danger' v-if="scope.row.EquipInSpaceCheck">
  101. </el-badge>
  102. <i class="msg-icon el-icon-success success-color" style="font-size:20px;" v-if="scope.row.EquipInSpaceCheck<=0"></i>
  103. </template>
  104. </el-table-column>
  105. <el-table-column prop="PipeCheck" label='管段检查' width="200">
  106. <template slot-scope="scope">
  107. <el-badge :value="scope.row.PipeCheck" class="item" type='danger' v-if="scope.row.PipeCheck">
  108. </el-badge>
  109. <i class="msg-icon el-icon-success success-color" style="font-size:20px;" v-if="scope.row.PipeCheck<=0"></i>
  110. </template>
  111. </el-table-column>
  112. <el-table-column prop="SystemReferEquipCheck" label='管网及相关设备检查' width="200">
  113. <template slot-scope="scope">
  114. <el-badge :value="scope.row.SystemReferEquipCheck" class="item" :type='scope.row.SystemReferEquipCheck?"danger":"success"'
  115. v-if="scope.row.SystemReferEquipCheck">
  116. </el-badge>
  117. <i class="msg-icon el-icon-success success-color" style="font-size:20px;" v-if="scope.row.SystemReferEquipCheck<=0"></i>
  118. </template>
  119. </el-table-column>
  120. <el-table-column prop="ParameterIntegrityCheck" label='Revit族参数完整性检查' width="200">
  121. <template slot-scope="scope">
  122. <el-badge :value="scope.row.ParameterIntegrityCheck" class="item" type='danger' v-if="scope.row.ParameterIntegrityCheck">
  123. </el-badge>
  124. <i class="msg-icon el-icon-success success-color" style="font-size:20px;" v-if="scope.row.ParameterIntegrityCheck<=0"></i>
  125. </template>
  126. </el-table-column>
  127. <el-table-column prop="XyzOverlapCheck" label='xyz坐标重叠检查' width="200">
  128. <template slot-scope="scope">
  129. <el-badge :value="scope.row.XyzOverlapCheck" class="item" type='danger' v-if="scope.row.XyzOverlapCheck">
  130. </el-badge>
  131. <i class="msg-icon el-icon-success success-color" style="font-size:20px;" v-if="scope.row.XyzOverlapCheck<=0"></i>
  132. </template>
  133. </el-table-column>
  134. <template slot="empty">
  135. <div style="height: 60%;transform: translate(-40%,50%);">
  136. <i class="icon-wushuju iconfont"></i>
  137. 数据暂无
  138. </div>
  139. </template>
  140. </el-table>
  141. <el-pagination class="right" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="page.pageNumber"
  142. :page-sizes="page.pageSizes" :page-size="page.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="page.total">
  143. </el-pagination>
  144. </div>
  145. </div>
  146. </div>
  147. </div>
  148. </template>
  149. <script>
  150. import { mapGetters } from "vuex";
  151. import dasBoard from "@/views/dasboard/index";
  152. import request from "@/api/model/file.js";
  153. import { exportReport, queryFloorList, queryModel, queryReportList, queryLostReportList } from "@/api/model/report.js";
  154. import { getToBeDelEquip, getSupplement } from "@/api/scan/request.js";
  155. import axios from 'axios'
  156. import { resolve } from 'q';
  157. export default {
  158. components: {
  159. dasBoard
  160. },
  161. data() {
  162. return {
  163. params: null,
  164. ModelFileCount: null,// 模型文件夹数量
  165. modelFloorCount: null,// 包含楼层模型文件数量
  166. problemCount: 0,// 检查出问题的楼层模型文件数量
  167. tableList: [], // tab数据
  168. tableData: [],// 列表数据
  169. activeTab: '', // tab当前选中项
  170. headerStyle: { // 列表样式
  171. backgroundColor: '#e1e4e5',
  172. color: '#2b2b2b',
  173. lineHeight: '30px'
  174. },
  175. page: {
  176. pageSize: 50,
  177. pageSizes: [10, 20, 50, 100],
  178. pageNumber: 1,
  179. total: 0
  180. },
  181. loading: false,
  182. load: false,
  183. floorIconType: null,
  184. toBeSuppCount: 0,
  185. toBeDelCount: 0
  186. }
  187. },
  188. mounted() { },
  189. created() {
  190. this.params = {
  191. ProjectId: this.projectId
  192. }
  193. this.getModelFileCount();
  194. this.getModelFloorCount();
  195. },
  196. computed: {
  197. ...mapGetters('layout', ['projectId'])
  198. },
  199. methods: {
  200. getModelFloorCount() {// 获取楼层模型文件数量,计算出检查出问题的模型文件
  201. let promise1 = new Promise(resolve => {
  202. queryFloorList(this.params, res => {
  203. resolve(res);
  204. })
  205. })
  206. Promise.all([promise1]).then(response => {
  207. this.problemCount = 0;
  208. let res = response[0];
  209. this.modelFloorCount = res.Total;
  210. this.modelFloor = res.Content;
  211. this.getModelFileIcon();
  212. this.modelFloor.forEach(item => {
  213. if (!item.DataCheckResult) {
  214. this.problemCount++;
  215. }
  216. })
  217. })
  218. },
  219. getModelFileIcon() {// 计算文件夹的图标
  220. this.tableList.forEach(item => {
  221. this.modelFloor.forEach(it => {
  222. if (item.Code === it.FolderId) {
  223. if (!item.DataCheckResult) {
  224. item.flag = false;
  225. }
  226. }
  227. })
  228. })
  229. },
  230. getData(tab) {// 切换tab时执行
  231. this.getModelFloor();
  232. },
  233. getModelFileCount() {// 获取项目下所有模型文件夹
  234. queryModel(this.params, res => {
  235. this.ModelFileCount = res.Content.length;
  236. this.tableList = res.Content;
  237. if (this.tableList && this.tableList.length) {
  238. this.tableList.forEach((item, index) => {
  239. item.Code = item.Id;
  240. })
  241. this.activeTab = this.tableList[0].Code;// 默认选中第一个模型文件夹
  242. }
  243. this.getModelFloor();
  244. });
  245. },
  246. getModelFloor() {// 获取当前楼层下的模型楼层和各个检查项的数据
  247. let params = {
  248. ProjectId: this.projectId,
  249. Id: `${this.activeTab}`,
  250. PageNumber: this.page.pageNumber,
  251. PageSize: this.page.pageSize
  252. }
  253. queryReportList(params, res => {
  254. this.FloorName = res.Content;
  255. this.tableData = [];
  256. if (this.FloorName && this.FloorName.length) {
  257. this.loading = true;
  258. let i = 0;
  259. this.FloorName.forEach(item => {
  260. item.questionItem = 0;
  261. for (let key in item) {
  262. if (item[key] > 0 && key !== "FloorName" && key !== "questionItem") {
  263. i += 1;
  264. item.questionItem += 1;
  265. }
  266. }
  267. })
  268. this.floorIconType = i;
  269. }
  270. this.getLostModelFloor();
  271. })
  272. },
  273. getLostModelFloor() {// 获取缺失楼层
  274. let params = {
  275. ProjectId: this.projectId,
  276. Filters: `FolderId='${this.activeTab}';Status=4`
  277. }
  278. queryLostReportList(params, res => {
  279. this.LostFloorName = res.Content;
  280. this.getToBeCount();
  281. })
  282. },
  283. getToBeCount() {// 根据模型ID获取待删除数量和待补充数量
  284. let equipComDelList = [];
  285. this.equipComDelList = [];
  286. this.LostFloorName.forEach(item => {
  287. if (item.CurrentModelId) {
  288. equipComDelList.push({
  289. ModelId: item.CurrentModelId
  290. });
  291. this.equipComDelList.push(item.CurrentModelId)
  292. } else {
  293. item.flag = 'lost';
  294. item.FloorName = `${item.Note + item.FloorName}`
  295. }
  296. })
  297. let params = {
  298. ProjectId: this.projectId,
  299. data: equipComDelList
  300. }
  301. let promise1 = new Promise(resolve => {
  302. getToBeDelEquip(params, res => {
  303. resolve(res);
  304. })
  305. })
  306. let promise2 = new Promise(resolve => {
  307. getSupplement(params, res => {
  308. resolve(res);
  309. })
  310. })
  311. Promise.all([promise1, promise2]).then(response => {
  312. let res = response[0];
  313. let res1 = response[1];
  314. this.toBeDelCount = 0;
  315. this.toBeSuppCount = 0;
  316. res.Content.forEach(item => {
  317. if (item.Count > 0) {
  318. this.toBeDelCount += 1;
  319. }
  320. this.LostFloorName.forEach(it => {
  321. if (item.ModelId === it.CurrentModelId) {
  322. it.toBeDel = item.Count;
  323. }
  324. })
  325. })
  326. res1.Content.forEach(item => {
  327. if (item.Count > 0) {
  328. this.toBeSuppCount += 1;
  329. }
  330. this.LostFloorName.forEach(it => {
  331. if (item.ModelId === it.CurrentModelId) {
  332. it.toBeSupplement = item.Count;
  333. }
  334. })
  335. })
  336. if (this.LostFloorName && this.LostFloorName.length) {
  337. this.LostFloorName.forEach(item => {
  338. this.FloorName.forEach(it => {
  339. if (item.FloorName === it.FloorName) {
  340. for (let key in it) {
  341. item[key] = it[key];
  342. }
  343. }
  344. })
  345. })
  346. this.tableData = this.LostFloorName;
  347. } else {
  348. this.tableData = [];
  349. }
  350. this.page.total = this.tableData.length;
  351. this.loading = false;
  352. })
  353. },
  354. del() {// 点击需从模型中删除的设备
  355. let equipComDelList = encodeURIComponent(JSON.stringify(this.equipComDelList));
  356. let jumpRouter = this.$router.resolve({ path: '/model/report/deleted', query: { equipComDelList: equipComDelList } })
  357. window.open(jumpRouter.href, '_blank')
  358. },
  359. supplement() {// 点击模型待补充的设备
  360. let equipComDelList = encodeURIComponent(JSON.stringify(this.equipComDelList));
  361. let jumpRouter = this.$router.resolve({ path: '/model/report/supplement', query: { equipComDelList: equipComDelList } })
  362. window.open(jumpRouter.href, '_blank')
  363. },
  364. getExportReport() {// 导出模型问题报告
  365. let that = this;
  366. this.load = true;
  367. axios({
  368. method: 'post',
  369. url: `/modelapi/report/non-blocking`,
  370. data: {
  371. Id: this.activeTab,
  372. ProjectId: this.projectId
  373. },
  374. headers: {
  375. ProjectId: this.projectId
  376. },
  377. responseType: 'blob'
  378. }).then(function (res) {
  379. if (res.data.type == 'application/vnd.ms-excel') {
  380. let blob = new Blob([res.data], { type: 'application/vnd.ms-excel;charset=utf-8' });
  381. let fileName = decodeURI(res.headers['content-disposition']);
  382. if (fileName)
  383. fileName = fileName.substring(fileName.indexOf('=') + 1);
  384. if ('download' in document.createElement('a')) { // 非IE下载
  385. const elink = document.createElement('a')
  386. elink.download = fileName
  387. elink.style.display = 'none'
  388. elink.href = URL.createObjectURL(blob)
  389. document.body.appendChild(elink)
  390. elink.click()
  391. URL.revokeObjectURL(elink.href) // 释放URL 对象
  392. document.body.removeChild(elink)
  393. that.load = false;
  394. } else { // IE10+下载
  395. navigator.msSaveBlob(blob, fileName)
  396. that.load = false;
  397. }
  398. } else {
  399. let reader = new FileReader()
  400. reader.onload = e => {
  401. if (e.target.readyState === 2) {
  402. let res = {}
  403. that.load = false;
  404. res = JSON.parse(e.target.result)
  405. that.$message.error(res.Message);
  406. }
  407. }
  408. reader.readAsText(res.data)
  409. }
  410. })
  411. },
  412. tableRowClassName({ row, rowIndex }) {// 设置缺失楼层所在行的背景色
  413. if (row.flag && row.flag === 'lost') {
  414. return 'warning-row';
  415. }
  416. },
  417. handleSizeChange(val) {// 切换每页显示数量
  418. this.page.pageSize = val;
  419. this.getModelFloor();
  420. },
  421. handleCurrentChange(val) {// 切换页码
  422. this.page.pageNumber = val;
  423. this.getModelFloor();
  424. },
  425. },
  426. watch: {
  427. projectId() {
  428. this.params = {
  429. ProjectId: this.projectId
  430. }
  431. this.getModelFileCount();
  432. this.getModelFloorCount();
  433. }
  434. }
  435. }
  436. </script>
  437. <style lang="less" scoped>
  438. .statistics {
  439. display: flex;
  440. width: 100%;
  441. padding: 20px 0;
  442. background: white;
  443. margin-bottom: 10px;
  444. div {
  445. flex: 1;
  446. text-align: center;
  447. p {
  448. b {
  449. font-size: 20px;
  450. margin-left: 20px;
  451. }
  452. }
  453. }
  454. }
  455. .main-content {
  456. width: 100%;
  457. height: calc(100% - 90px);
  458. background: white;
  459. .content-box {
  460. height: calc(100% - 105px);
  461. .table {
  462. margin-top: 15px;
  463. }
  464. }
  465. }
  466. .button {
  467. padding-left: 10px;
  468. .el-link {
  469. font-size: 12px;
  470. text-decoration: none;
  471. color: #606266 !important;
  472. padding: 4px 15px;
  473. border: 1px solid #dcdfe6;
  474. border-radius: 3px;
  475. margin-right: 10px;
  476. }
  477. }
  478. .success-color {
  479. color: #67c23a;
  480. }
  481. .error-color {
  482. color: #f56c6c;
  483. }
  484. </style>
  485. <style lang="less">
  486. .el-table__row.warning-row {
  487. td {
  488. background: #f3f3f3 !important;
  489. }
  490. }
  491. </style>