index.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. <template>
  2. <div class="tableDisplay">
  3. <div class="header">
  4. <el-button style="float:left;" size="small" type="default" icon="el-icon-back" @click="goBack"></el-button>
  5. <span :title="`${name} - ${code}`" class="details-title"><b>{{ name }} - {{ code }}</b></span>
  6. </div>
  7. <div class="content">
  8. <el-scrollbar style="height:100%;">
  9. <div class="content-scrollbar">
  10. <div class="content-left">
  11. <div class="content-keyPoint">
  12. <exhibitionCrux :exhibitionCrux="exhibitionCrux" :type="type" @cruxSuccess="cruxSuccess"/>
  13. </div>
  14. <div class="content-showType">
  15. <selectRadio
  16. :selectRadio="selectRadio"
  17. @changeRadio="changeRadio"
  18. />
  19. </div>
  20. <div class="content-point">
  21. <div class="content-point-left">
  22. <exhibitionBaseInformation :exhibitionBaseInformation="exhibitionBaseInformation"/>
  23. </div>
  24. <div class="content-point-right">
  25. <exhibitionEnergy :exhibitionEnergy="exhibitionEnergy"/>
  26. </div>
  27. </div>
  28. </div>
  29. <div class="content-right">
  30. <div class="content-repair">
  31. <exhibitionMaintain :exhibitionMaintain="exhibitionMaintain"/>
  32. </div>
  33. <div class="content-media">
  34. <exhibitionImage :exhibitionImage="exhibitionImage" v-show="isShowImage"/>
  35. <exhibitionVideo :exhibitionVideo="exhibitionVideo" v-show="isShowVideo"/>
  36. <exhibitionFile :exhibitionFile="exhibitionFile" v-show="isShowFile"/>
  37. </div>
  38. </div>
  39. </div>
  40. </el-scrollbar>
  41. </div>
  42. <div class="footer">
  43. <el-button-group style="float:right;margin:8px 10px 0 0">
  44. <el-button
  45. :disabled="list.findIndex(item => item.value == id) == 0"
  46. @click="handleClickPrev"
  47. size="mini"
  48. icon="el-icon-arrow-left">
  49. 上一页
  50. </el-button>
  51. <el-select size="mini" style="float:left;margin:0 10px;" v-model="id" @change="handleChangeExample"
  52. placeholder="请选择">
  53. <el-option
  54. v-for="item in list"
  55. :key="item.value"
  56. :label="item.label"
  57. :value="item.value">
  58. </el-option>
  59. </el-select>
  60. <el-button
  61. :disabled="list.findIndex(item => item.value == id) == list.length-1"
  62. @click="handleClickNext"
  63. size="mini">
  64. 下一页
  65. <i class="el-icon-arrow-right el-icon--right"></i>
  66. </el-button>
  67. </el-button-group>
  68. </div>
  69. </div>
  70. </template>
  71. <script>
  72. import exhibitionBaseInformation from "@/components/ledger/details/detail/exhibitionBaseInformation";
  73. import exhibitionFile from "@/components/ledger/details/detail/exhibitionFile";
  74. import exhibitionImage from "@/components/ledger/details/detail/exhibitionImage";
  75. import exhibitionVideo from "@/components/ledger/details/detail/exhibitionVideo";
  76. import exhibitionCrux from "@/components/ledger/details/detail/exhibitionCrux";
  77. import exhibitionEnergy from "@/components/ledger/details/detail/exhibitionEnergy";
  78. import exhibitionMaintain from "@/components/ledger/details/detail/exhibitionMaintain";
  79. import selectRadio from "@/components/ledger/details/detail/selectRadio";
  80. import tools from "@/utils/scan/tools"
  81. import { BeatchQueryParam } from "@/api/scan/request";
  82. import { getDataDictionary } from "@/api/dict";
  83. import { queryEquip } from "@/api/object/equip"
  84. import { mapGetters } from "vuex";
  85. export default {
  86. name: "deviceDetails",
  87. components: {
  88. exhibitionBaseInformation,
  89. exhibitionFile,
  90. exhibitionVideo,
  91. exhibitionImage,
  92. exhibitionMaintain,
  93. selectRadio,
  94. exhibitionCrux,
  95. exhibitionEnergy
  96. },
  97. created() {
  98. this.id = this.$route.query.equipId;
  99. this.name = this.$route.query.equipName;
  100. this.code = this.$route.query.equipCode;
  101. this.type = this.$route.query.type;
  102. this.list = this.$route.query.data;
  103. this.getData();
  104. },
  105. computed: {
  106. ...mapGetters("layout", ["projectId", "secret", "userId"])
  107. },
  108. data() {
  109. return {
  110. id: '', //当前设备id
  111. name: '', //当前设备本地名称
  112. code: '', //当前设备的本地编码
  113. type: '', //设备类型
  114. list: [], //设备列表
  115. pointData: [], //信息点数据
  116. exampleData: {}, //实例数据
  117. currentRadio: '1',//当前选中的select
  118. criterias: [], //动态参数
  119. criteriasArray: [],
  120. selectRadio: {
  121. information: '设备信息点',
  122. initRadio: '1',
  123. radioList: [
  124. {
  125. value: '显示需采集信息点',
  126. label: '1'
  127. },
  128. {
  129. value: '显示有值信息点',
  130. label: '2'
  131. },
  132. {
  133. value: '显示全部信息点',
  134. label: '3'
  135. }
  136. ]
  137. },
  138. exhibitionBaseInformation: {
  139. information: {}
  140. },
  141. exhibitionEnergy: {
  142. title: '能耗信息',
  143. firstName: '',
  144. dynamic: [],
  145. list: {}
  146. },
  147. exhibitionMaintain: {
  148. title: '维修/维保记录'
  149. },
  150. exhibitionFile: {
  151. title: '文件',
  152. list: {}
  153. },
  154. exhibitionCrux: {
  155. title: '关键信息点:',
  156. cruxArray: [],
  157. allMessage: [],//全部信息点
  158. },
  159. exhibitionImage: {
  160. title: '图片',
  161. list: {},
  162. arr: []
  163. },
  164. exhibitionVideo: {
  165. title: '视频',
  166. list: []
  167. },
  168. instance: {},//实例信息处理
  169. isShowImage: false,
  170. isShowVideo: false,
  171. isShowFile: false,
  172. }
  173. },
  174. methods: {
  175. deepCopy(obj) {
  176. return JSON.parse(JSON.stringify(obj))
  177. },
  178. cruxSuccess() {
  179. this.getData()
  180. },
  181. // 获取表头和实例数据(动态数据在组件中获取,在此格式化请求参数)
  182. getData() {
  183. let params1 = {
  184. orders: "sort asc",
  185. pageNumber: 1,
  186. pageSize: 1000,
  187. type: this.type
  188. }, params2 = {
  189. filters: `id='${this.id}'`,
  190. };
  191. let promise1 = new Promise((resolve, reject) => {
  192. getDataDictionary(params1, res => {
  193. resolve(res)
  194. })
  195. })
  196. let promise2 = new Promise((resolve, reject) => {
  197. queryEquip(params2, res => {
  198. resolve(res)
  199. })
  200. })
  201. // 数据初始化
  202. this.exhibitionEnergy.dynamic = [];
  203. this.criterias = [];
  204. Promise.all([promise1, promise2]).then(values => {
  205. this.pointData = values[0].content;
  206. this.exampleData = values[1].content[0];
  207. this.name = this.exampleData.localName ? this.exampleData.localName : this.exampleData.name ? this.exampleData.name : '';
  208. this.code = this.exampleData.localId ? this.exampleData.localId : '';
  209. let obj = this.deepCopy(values[1].content[0]);
  210. obj = tools.flattenKeys(obj);
  211. for (let key in obj) { //删除对象中数组为空的项
  212. if (Array.isArray(obj[key]) && !obj[key].length) {
  213. delete obj[key]
  214. }
  215. }
  216. this.instance = obj;
  217. this.pointData.forEach(item => {
  218. if (item.inputMode == "L" || item.inputMode == "L1" || item.inputMode == "L2" || item.inputMode == "M") {
  219. let cur = tools.dataForKey(this.exampleData, item.path);
  220. if (cur) {
  221. this.criterias.push({
  222. objectId: this.exampleData.id,
  223. infoCode: item.code
  224. })
  225. }
  226. }
  227. })
  228. let params = { //获取动态参数
  229. groupCode: "WD",
  230. appId: "datacenter",
  231. projectId: this.projectId,
  232. data: []
  233. }
  234. params.data = this.criterias
  235. if (this.criterias.length) {
  236. BeatchQueryParam(params, res => {
  237. this.criteriasArray = res.data;
  238. res.data.length && res.data.map(child => {
  239. this.pointData.map(head => {
  240. if (head.code == child.infoCode) {
  241. if (head.dataSource) {
  242. head.dataSource.forEach(i => {
  243. if (i.code == child.data) {
  244. this.$set(head, 'data', i.name)
  245. }
  246. })
  247. } else {
  248. this.$set(head, 'data', child.data)
  249. }
  250. // this.$set(head, 'svalue', child.value)
  251. this.$set(head, 'svalue', child.infoValue)
  252. // this.$set(head, 'receivetime', child.receivetime)
  253. this.$set(head, 'receivetime', child.time)
  254. this.$set(head, 'error', child.error)
  255. }
  256. return head
  257. })
  258. })
  259. this.handleRadios(this.currentRadio);
  260. this.handleEnclosure() //处理图片视频文件信息
  261. })
  262. } else {
  263. this.handleRadios(this.currentRadio);
  264. this.handleEnclosure() //处理图片视频文件信息
  265. }
  266. })
  267. },
  268. handleEnclosure() {
  269. //图片文件处理,脱离radio控制
  270. let isList = this.pointData
  271. let isArr = []
  272. isList.map(j => {
  273. if (this.instance.hasOwnProperty(j.path)) {
  274. j.value = this.instance[j.path]
  275. return j
  276. }
  277. })
  278. isArr = isList.filter(k => k.value)
  279. this.handlePicList(isArr)
  280. this.handleFileList(isArr)
  281. },
  282. handleRadios(val) { //判断radio的值显示关键信息,基本信息,图片,文件
  283. let arr = []
  284. //关键信息点
  285. this.exhibitionCrux.cruxArray = this.pointData.filter(i => i.keyWord)
  286. this.exhibitionCrux.cruxArray.map(i => {
  287. if (this.instance.hasOwnProperty(i.path)) {
  288. return {
  289. ...i,
  290. value: this.instance[i.path]
  291. }
  292. }
  293. })
  294. if (val == 1) { //需采集信息
  295. arr = this.pointData.filter(i => i.visible)
  296. // // 图片和的处理
  297. // this.handlePicList(arr)
  298. // // 文件处理
  299. // this.handleFileList(arr)
  300. } else if (val == 2) { //有值信息点
  301. let list = this.pointData
  302. list.map(j => {
  303. if (this.instance.hasOwnProperty(j.path)) {
  304. return {
  305. ...j,
  306. value: this.instance[j.path]
  307. }
  308. }
  309. })
  310. arr = list.filter(k => k.value)
  311. // this.handlePicList(arr, 2)
  312. // this.handleFileList(arr, 2)
  313. } else { //全部信息点
  314. arr = this.pointData
  315. // this.handlePicList(arr)
  316. // this.handleFileList(arr)
  317. }
  318. this.displayData(arr)
  319. },
  320. handlePicList(arr) {
  321. let picObject = {}
  322. //处理数据格式
  323. arr.map(i => {
  324. if (i.inputMode == 'F2') {
  325. switch (i.path) {
  326. case 'infos.drawing':
  327. case 'infos.installPic':
  328. case 'infos.installDrawing':
  329. case 'infos.nameplate':
  330. case 'infos.pic':
  331. case 'pic' :
  332. if (this.instance.hasOwnProperty(i.path)) {
  333. i.PicList = this.instance[i.path]
  334. }
  335. if (picObject[i.name]) {
  336. } else {
  337. picObject[i.name] = []
  338. }
  339. picObject[i.name].push({
  340. ...i,
  341. })
  342. break;
  343. }
  344. }
  345. })
  346. //展示图片
  347. this.exhibitionImage.list = picObject
  348. let isArray = [] //获取图片数组
  349. for (let i in picObject) {
  350. if (Array.isArray(picObject[i])) {
  351. let list = picObject[i]
  352. list.forEach(i => {
  353. if (i.PicList) {
  354. isArray.push(...i.PicList)
  355. }
  356. })
  357. }
  358. }
  359. this.exhibitionImage.arr = isArray
  360. let video = isArray.filter(i => i.Type != 'image' && i.type != 'image')
  361. this.exhibitionVideo.list = video
  362. //判断是否显示图片组件
  363. this.isShowImage = isArray.length ? true : false
  364. //判断是否显示video组件
  365. this.isShowVideo = video.length ? true : false
  366. },
  367. handleFileList(arr) {
  368. let picObject = {}
  369. //处理数据格式
  370. arr.map(i => {
  371. if (i.inputMode == 'F2') {
  372. switch (i.path) {
  373. case 'infos.insuranceFile':
  374. case 'infos.archive':
  375. case 'infos.checkReport':
  376. if (this.instance.hasOwnProperty(i.path)) {
  377. i.fileList = this.instance[i.path]
  378. }
  379. if (picObject[i.name]) {
  380. } else {
  381. picObject[i.name] = []
  382. }
  383. picObject[i.name].push({
  384. ...i,
  385. })
  386. break
  387. }
  388. }
  389. })
  390. //展示文件
  391. this.exhibitionFile.list = picObject
  392. let isArray = [] //获取文件数组
  393. for (let i in picObject) {
  394. if (Array.isArray(picObject[i])) {
  395. let list = picObject[i]
  396. list.forEach(i => {
  397. if (i.fileList) {
  398. isArray.push(...i.fileList)
  399. }
  400. })
  401. }
  402. }
  403. //判断是否显示文件组件
  404. this.isShowFile = isArray.length ? true : false
  405. },
  406. changeRadio(val) { //1,需采集,2,有值,3,全部
  407. this.handleRadios(val)
  408. this.currentRadio = val
  409. },
  410. formatDate(str) {
  411. if (str) {
  412. if (str.includes('-')) {
  413. return str
  414. } else {
  415. return str.substr(0, 4) + "-" + str.substr(4, 2) + "-" + str.substr(6, 2) + " " + str.substr(8, 2) + ":" + str.substr(10, 2) + ":" + str.substr(12, 2)
  416. }
  417. } else {
  418. return '--'
  419. }
  420. },
  421. displayData(arr) {//对数据进行处理传给组件展示
  422. const result = {}
  423. const resultEnergy = {};
  424. arr.map(i => {
  425. if (this.instance.hasOwnProperty(i.path) && this.currentRadio != 2) {
  426. i.value = this.instance[i.path]
  427. }
  428. if (i.inputMode == 'C5') {
  429. if (this.instance.hasOwnProperty(i.path)) {
  430. let time = this.instance[i.path]
  431. i.value = this.formatDate(time)
  432. }
  433. }
  434. if (i.dataSource && i.dataSource.length) {
  435. // let source = JSON.parse(i.dataSource)
  436. let source = i.dataSource
  437. //判断输入类型
  438. if (i.inputMode == 'D1L') {
  439. let d1l = tools.formatDataSource(i.dataSource)
  440. d1l.forEach(k => {
  441. if (k.code == this.instance[i.path]) {
  442. i.value = k.name
  443. }
  444. })
  445. } else if (i.inputMode == 'D2' || i.inputMode == 'C6') {
  446. if (this.instance.hasOwnProperty(i.path)) {
  447. if (!Array.isArray(this.instance[i.path])) {
  448. let transArray = this.instance[i.path].split(',')
  449. i.value = source.filter(item => transArray.includes(item.code)).map(item => item.name).join(',')
  450. }
  451. }
  452. }
  453. source.forEach(j => {
  454. if (j.code == this.instance[i.path]) {
  455. i.value = j.name
  456. }
  457. })
  458. }
  459. // 动态信息点处理
  460. switch (i.inputMode) {
  461. case "L":
  462. case "L1":
  463. case "L2":
  464. case "M":
  465. if (resultEnergy[`${i.firstName}${i.secondName ? '/' + i.secondName : ''}`]) {
  466. resultEnergy[`${i.firstName}${i.secondName ? '/' + i.secondName : ''}`].paths.push({
  467. Path: i.path,
  468. InfoPointName: i.name,
  469. InfoPointCode: i.code,
  470. value: i.svalue,
  471. Visible: i.visible,
  472. KeyWord: i.keyWord,
  473. InputMode: i.inputMode,
  474. data: i.data,
  475. receivetime: i.receivetime,
  476. error: i.error,
  477. Unit: i.unit,
  478. FirstName: i.firstName,
  479. })
  480. } else {
  481. resultEnergy[`${i.firstName}${i.secondName ? '/' + i.secondName : ''}`] = {
  482. paths: [{
  483. Path: i.path,
  484. InfoPointName: i.name,
  485. InfoPointCode: i.code,
  486. value: i.svalue,
  487. Visible: i.visible,
  488. KeyWord: i.keyWord,
  489. InputMode: i.inputMode,
  490. data: i.data,
  491. receivetime: i.receivetime,
  492. error: i.error,
  493. Unit: i.unit,
  494. FirstName: i.firstName,
  495. }]
  496. }
  497. }
  498. break;
  499. default:
  500. if (result[`${i.firstName}${i.secondName ? '/' + i.secondName : ''}`]) {
  501. result[`${i.firstName}${i.secondName ? '/' + i.secondName : ''}`].paths.push({
  502. Path: i.path,
  503. InfoPointName: i.name,
  504. InfoPointCode: i.code,
  505. Value: i.value,
  506. Visible: i.visible,
  507. KeyWord: i.keyWord,
  508. InputMode: i.inputMode,
  509. classCode: i.classCode,
  510. id: i.id,
  511. groupCode: i.groupCode,
  512. type: i.type
  513. })
  514. } else {
  515. result[`${i.firstName}${i.secondName ? '/' + i.secondName : ''}`] = {
  516. paths: [{
  517. Path: i.path,
  518. InfoPointName: i.name,
  519. InfoPointCode: i.code,
  520. Value: i.value,
  521. Visible: i.visible,
  522. KeyWord: i.keyWord,
  523. InputMode: i.inputMode,
  524. classCode: i.classCode,
  525. id: i.id,
  526. groupCode: i.groupCode,
  527. type: i.type
  528. }]
  529. }
  530. }
  531. }
  532. })
  533. this.exhibitionBaseInformation.information = result
  534. this.exhibitionCrux.allMessage = result
  535. this.exhibitionEnergy.list = resultEnergy;
  536. },
  537. goBack() {
  538. this.$router.push({
  539. name: "facilityLedger",
  540. params: {
  541. deviceId: this.type
  542. }
  543. })
  544. },
  545. // 切换实例
  546. handleChangeExample() {
  547. this.selectRadio.initRadio = '1';
  548. this.currentRadio = '1';
  549. this.getData();
  550. },
  551. // 切换上一个实例
  552. handleClickPrev() {
  553. let index = this.list.findIndex(item => item.value == this.id);
  554. this.id = this.list[index - 1].value;
  555. this.handleChangeExample();
  556. },
  557. // 切换下一个实例
  558. handleClickNext() {
  559. let index = this.list.findIndex(item => item.value == this.id);
  560. this.id = this.list[index + 1].value;
  561. this.handleChangeExample();
  562. },
  563. },
  564. watch: {
  565. projectId() {
  566. this.$router.push({ path: "/ledger/facility" })
  567. }
  568. }
  569. }
  570. </script>
  571. <style scoped lang="less">
  572. @bgc: #fff;
  573. .tableDisplay {
  574. .header {
  575. padding-bottom: 10px;
  576. overflow: hidden;
  577. text-overflow: ellipsis;
  578. white-space: nowrap;
  579. .details-title {
  580. color: #333;
  581. font-size: 16px;
  582. margin-left: 20px;
  583. line-height: 32px;
  584. cursor: pointer;
  585. }
  586. }
  587. .content {
  588. height: calc(100% - 77px);
  589. .content-scrollbar {
  590. display: flex;
  591. height: 100%;
  592. flex-direction: row;
  593. box-sizing: border-box;
  594. background-color: #f2f2f2;
  595. .content-left {
  596. display: flex;
  597. flex-direction: column;
  598. flex: 1;
  599. box-sizing: border-box;
  600. .content-keyPoint {
  601. border: 1px solid #ccc;
  602. box-sizing: border-box;
  603. margin-bottom: 10px;
  604. // overflow: hidden;
  605. background: @bgc;
  606. }
  607. .content-showType {
  608. height: 50px;
  609. border: 1px solid #ccc;
  610. border-bottom: none;
  611. box-sizing: border-box;
  612. background: @bgc;
  613. }
  614. .content-point {
  615. display: flex;
  616. flex-direction: row;
  617. border: 1px solid #ccc;
  618. box-sizing: border-box;
  619. background: @bgc;
  620. .content-point-left {
  621. flex: 1;
  622. }
  623. .content-point-right {
  624. width: 300px;
  625. border-left: 1px solid #ccc;
  626. }
  627. }
  628. }
  629. .content-right {
  630. width: 400px;
  631. margin-left: 10px;
  632. box-sizing: border-box;
  633. .content-repair {
  634. height: 50px;
  635. line-height: 50px;
  636. margin-bottom: 10px;
  637. border: 1px solid #ccc;
  638. background: @bgc;
  639. box-sizing: border-box;
  640. }
  641. .content-media {
  642. box-sizing: border-box;
  643. }
  644. }
  645. }
  646. }
  647. .footer {
  648. position: fixed;
  649. bottom: 0;
  650. left: 235px;
  651. width: calc(100% - 235px);
  652. height: 45px;
  653. background-color: #fff;
  654. box-sizing: border-box;
  655. }
  656. }
  657. /deep/ .el-scrollbar__wrap {
  658. overflow-x: hidden;
  659. }
  660. </style>