index.vue 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. <template>
  2. <div class="app-container">
  3. <el-row :gutter="20">
  4. <el-col :span="4" :xs="24">
  5. <div class="head-container">
  6. <el-input v-model="areaName" placeholder="请输入区域名称" clearable size="small" prefix-icon="el-icon-search"
  7. style="margin-bottom: 20px"
  8. />
  9. </div>
  10. <div class="head-container" style="height: 100vh; overflow: hidden; position: relative;">
  11. <el-tree :data="treeAreaOptions" :props="defaultProps" :expand-on-click-node="false"
  12. :filter-node-method="filterNode" ref="tree" node-key="id" default-expand-all highlight-current
  13. @node-click="handleNodeClick" style="height: calc(100vh - 50px); overflow-y: auto;"
  14. />
  15. </div>
  16. </el-col>
  17. <el-col :span="20" :xs="24">
  18. <el-tabs v-model="queryParams.deviceCategory" @tab-click="deviceCategoryChange">
  19. <el-tab-pane label="产能设备" name="E"></el-tab-pane>
  20. <el-tab-pane label="储能设备" name="C"></el-tab-pane>
  21. <el-tab-pane label="输配设备" name="W"></el-tab-pane>
  22. <el-tab-pane label="用能设备" name="Z"></el-tab-pane>
  23. </el-tabs>
  24. <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"
  25. label-width="68px"
  26. >
  27. <el-form-item label="设备分类" prop="deviceSubCategory">
  28. <el-select v-model="queryParams.deviceSubCategory">
  29. <el-option v-for="item in subCategoryOptions" placeholder="设备分类" :label="item.name" :value="item.code"
  30. :key="item.code"
  31. />
  32. </el-select>
  33. </el-form-item>
  34. <el-form-item label="归属设施" prop="refFacs">
  35. <el-select v-model="queryParams.refFacs">
  36. <el-option v-for="item in facsOptions" :label="item.facsName" :value="item.facsCode"
  37. :key="item.facsCode"
  38. />
  39. </el-select>
  40. </el-form-item>
  41. <el-form-item label="子系统" prop="subsystemCode">
  42. <el-select v-model="queryParams.subsystemCode">
  43. <el-option v-for="item in subsystemOptions" :label="item.systemName" :value="item.systemCode"
  44. :key="item.systemCode"
  45. />
  46. </el-select>
  47. </el-form-item>
  48. <el-form-item>
  49. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  50. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  51. </el-form-item>
  52. </el-form>
  53. <el-table v-loading="loading" :data="deviceList">
  54. <el-table-column label="设备名称" align="left" prop="deviceName"/>
  55. <el-table-column label="归属区域" align="left" prop="areaPath" width="280px"/>
  56. <el-table-column label="设备分类" align="center" prop="deviceCategoryName"/>
  57. <el-table-column label="归属设施" align="center" prop="refFacsName"/>
  58. <el-table-column label="子系统" align="center" prop="subsystemName"/>
  59. <el-table-column label="设备状态" align="center" prop="deviceStatus">
  60. <template slot-scope="scope">
  61. <span :style="{
  62. padding: '6px 12px',
  63. borderRadius: '4px',
  64. display: 'inline-block',
  65. textAlign: 'center',
  66. cursor: 'pointer',
  67. color: getDeviceStatusTextColor(scope.row.deviceStatus),
  68. backgroundColor: getDeviceStatusBgColor(scope.row.deviceStatus),
  69. minWidth: '70px',
  70. height: '35px',
  71. textAlign: 'center'
  72. }"
  73. >
  74. {{ getDeviceStatusText(scope.row.deviceStatus) }}
  75. </span>
  76. </template>
  77. </el-table-column>
  78. <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  79. <template slot-scope="scope">
  80. <el-button size="mini" type="text" icon="el-icon-info" @click="handleDetail(scope.row)">详情</el-button>
  81. <!-- 下拉菜单 -->
  82. <el-dropdown trigger="click">
  83. <el-button type="text" size="mini" @click="loadAbilities(scope.row)">
  84. 操作<i class="el-icon-arrow-down el-icon--right"></i>
  85. </el-button>
  86. <el-dropdown-menu slot="dropdown">
  87. <el-dropdown-item
  88. v-for="ability in abilityDevice"
  89. :key="ability.abilityKey"
  90. @click.native="handleDeviceOperate(ability,scope.row)"
  91. >
  92. {{ ability.abilityName }}
  93. </el-dropdown-item>
  94. <el-dropdown-item @click.native="showCallLog(scope.row)">调用日志</el-dropdown-item>
  95. <el-dropdown-item @click.native="showReportLog(scope.row)">设备日志</el-dropdown-item>
  96. </el-dropdown-menu>
  97. </el-dropdown>
  98. </template>
  99. </el-table-column>
  100. </el-table>
  101. <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
  102. :limit.sync="queryParams.pageSize" @pagination="getList"
  103. />
  104. <!-- 调用日志弹窗 -->
  105. <el-dialog :visible.sync="callLog" title="调用日志" width="60%">
  106. <el-form inline>
  107. <el-form-item label="记录时间">
  108. <el-date-picker
  109. v-model="callDaterangeTime"
  110. style="width: 240px"
  111. value-format="yyyy-MM-dd HH:mm"
  112. type="datetimerange"
  113. range-separator="-"
  114. start-placeholder="开始日期"
  115. end-placeholder="结束日期"
  116. ></el-date-picker>
  117. </el-form-item>
  118. <el-form-item label="能力标识">
  119. <el-select v-model="callLogQueryParams.abilityKey" placeholder="请选择能力标识" clearable>
  120. <el-option
  121. v-for="item in abilityDevice"
  122. :key="item.abilityKey"
  123. :label="item.abilityName"
  124. :value="item.abilityKey"
  125. ></el-option>
  126. </el-select>
  127. </el-form-item>
  128. <el-form-item label="调用状态">
  129. <el-select v-model="callLogQueryParams.callStatus" placeholder="请选择调用状态" clearable>
  130. <el-option
  131. v-for="(value, key) in callStatusOptions"
  132. :key="key"
  133. :label="value"
  134. :value="key"
  135. ></el-option>
  136. </el-select>
  137. </el-form-item>
  138. <el-form-item>
  139. <el-button type="primary" @click="handleCallLogQuery">查询</el-button>
  140. <el-button @click="resetCallLogQuery">重置</el-button>
  141. </el-form-item>
  142. </el-form>
  143. <el-table :data="callLogData" style="width: 100%" :show-header="true" :empty-text="'暂无数据'">
  144. <el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
  145. <el-table-column label="对象代码" prop="objCode"></el-table-column>
  146. <el-table-column label="模型代码" prop="modelCode"></el-table-column>
  147. <el-table-column label="能力标识" prop="abilityKey"></el-table-column>
  148. <el-table-column label="调用时间" prop="callTime"></el-table-column>
  149. <el-table-column label="操作" align="center" width="100">
  150. <template slot-scope="scope">
  151. <el-button type="text" size="mini" icon="el-icon-info" @click="handleCallLogDetail(scope.row)">详情
  152. </el-button>
  153. </template>
  154. </el-table-column>
  155. </el-table>
  156. <pagination
  157. v-show="callLogQueryTotal > 0"
  158. :total="callLogQueryTotal"
  159. :page.sync="callLogQueryParams.pageNum"
  160. :limit.sync="callLogQueryParams.pageSize"
  161. @pagination="handleCallLogQuery"
  162. />
  163. </el-dialog>
  164. <!-- 调用日志详情弹窗 -->
  165. <el-dialog :visible.sync="callLogDetailDialog" title="调用日志详情" width="50%">
  166. <div v-if="callLogDetailData">
  167. <p><strong>对象代码:</strong>{{ callLogDetailData.objCode }}</p>
  168. <p><strong>对象类型:</strong>{{ formatObjType(callLogDetailData.objType) }}</p>
  169. <p><strong>模型代码:</strong>{{ callLogDetailData.modelCode }}</p>
  170. <p><strong>能力标识:</strong>{{ callLogDetailData.abilityKey }}</p>
  171. <p><strong>调用时间:</strong>{{ callLogDetailData.callTime }}</p>
  172. <p><strong>响应时间:</strong>{{ callLogDetailData.resTime }}</p>
  173. <p><strong>调用结果:</strong>{{ formatCallStatus(callLogDetailData.callStatus) }}</p>
  174. <p><strong>调用载体:</strong></p>
  175. <pre style="white-space: pre-wrap; background-color: #f5f5f5; padding: 10px; border-radius: 4px;"
  176. >{{ callLogDetailData.callPayload }}</pre>
  177. <p><strong>响应载体:</strong></p>
  178. <pre style="white-space: pre-wrap; background-color: #f5f5f5; padding: 10px; border-radius: 4px;"
  179. >{{ callLogDetailData.resPayload }}</pre>
  180. </div>
  181. </el-dialog>
  182. <!-- 设备日志弹窗 -->
  183. <el-dialog :visible.sync="reportLog" title="设备日志" width="60%">
  184. <el-form inline>
  185. <el-form-item label="记录时间">
  186. <el-date-picker
  187. v-model="logDaterangeTime"
  188. style="width: 240px"
  189. value-format="yyyy-MM-dd HH:mm"
  190. type="datetimerange"
  191. range-separator="-"
  192. start-placeholder="开始日期"
  193. end-placeholder="结束日期"
  194. ></el-date-picker>
  195. </el-form-item>
  196. <el-form-item>
  197. <el-button type="primary" @click="handleLogQuery">查询</el-button>
  198. <el-button @click="resetLogQuery">重置</el-button>
  199. </el-form-item>
  200. </el-form>
  201. <el-table :data="reportLogData" style="width: 100%" :show-header="true" :empty-text="'暂无数据'">
  202. <el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
  203. <el-table-column label="对象代码" prop="objCode"></el-table-column>
  204. <el-table-column label="消息描述" prop="msgDesc"></el-table-column>
  205. <el-table-column label="上报时间" prop="reportTime" width="180"></el-table-column>
  206. <el-table-column label="操作" align="center" width="100">
  207. <template slot-scope="scope">
  208. <el-button type="text" size="mini" icon="el-icon-info" @click="handleReportLogDetail(scope.row)">详情
  209. </el-button>
  210. </template>
  211. </el-table-column>
  212. </el-table>
  213. <pagination
  214. v-show="logQueryTotal > 0"
  215. :total="logQueryTotal"
  216. :page.sync="logQueryParams.pageNum"
  217. :limit.sync="logQueryParams.pageSize"
  218. @pagination="handleLogQuery"
  219. />
  220. </el-dialog>
  221. <!-- 设备日志详情弹窗 -->
  222. <el-dialog :visible.sync="reportDetailDialog" title="设备日志详情" width="50%">
  223. <div v-if="reportDetailData">
  224. <p><strong>对象代码:</strong>{{ reportDetailData.objCode }}</p>
  225. <p><strong>对象类型:</strong>{{ formatObjType(reportDetailData.objType) }}</p>
  226. <p><strong>消息描述:</strong>{{ reportDetailData.msgDesc }}</p>
  227. <p><strong>上报时间:</strong>{{ reportDetailData.reportTime }}</p>
  228. <p><strong>上报载体:</strong></p>
  229. <pre style="white-space: pre-wrap; background-color: #f5f5f5; padding: 10px; border-radius: 4px;"
  230. >{{ reportDetailData.reportPayload }}</pre>
  231. </div>
  232. </el-dialog>
  233. <el-dialog :visible.sync="open" title="设备状态详情" custom-class="detail-dialog">
  234. <div v-if="curRow">
  235. <!--分页导航 @tab-click="handleTabClick"-->
  236. <el-tabs v-model="activeTab">
  237. <el-tab-pane label="设备基本信息" name="basic"></el-tab-pane>
  238. <el-tab-pane label="设备参数" name="attr"></el-tab-pane>
  239. <el-tab-pane label="设备事件" name="event"></el-tab-pane>
  240. <el-tab-pane label="设备能力" name="ability"></el-tab-pane>
  241. </el-tabs>
  242. <!-- 设备基本信息 -->
  243. <div v-if="activeTab === 'basic'">
  244. <el-card class="box-card">
  245. <div>
  246. <p><span class="bold">设备名称:</span>{{ curRow.deviceName }}</p>
  247. <p><span class="bold">设备代码:</span>{{ curRow.deviceCode }}</p>
  248. <p><span class="bold">设备分类:</span>{{ curRow.deviceCategoryName + getPsName(curRow.psName)}}</p>
  249. <p><span class="bold">归属设施:</span>{{ curRow.refFacsName }}</p>
  250. <p><span class="bold">归属区域:</span>{{ buildRefAreaName(curRow) }}</p>
  251. <p><span class="bold">安装位置:</span>{{ curRow.location === null ? '无' : curRow.location }}</p>
  252. <p><span class="bold">归属系统:</span>{{ curRow.subsystemName === null ? '无' : curRow.subsystemName}}</p>
  253. <p>
  254. <span class="bold">设备状态:</span>
  255. <span :class="getDeviceStatusClass(curRow.deviceStatus)">
  256. {{ getDeviceStatus(curRow.deviceStatus) }}
  257. </span>
  258. </p>
  259. </div>
  260. </el-card>
  261. </div>
  262. <!-- 属性信息 -->
  263. <div v-if="activeTab === 'attr'">
  264. <el-card class="box-card">
  265. <div v-for="(tableData, tableName) in attrTables" :key="tableName">
  266. <p class="section-title">{{ tableData.title }}</p>
  267. <el-table :data="tableData.data" style="width: 100%" :show-header="true" :empty-text="'暂无数据'">
  268. <el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
  269. <el-table-column label="属性名称" prop="attrName"></el-table-column>
  270. <el-table-column label="属性标识" prop="attrKey"></el-table-column>
  271. <!-- 动态显示属性值 -->
  272. <el-table-column label="属性值" align="center">
  273. <template slot-scope="scope">
  274. <span v-if="tableData.title === '状态属性'">
  275. {{ scope.row.attrValueName || getAttrValueText(scope.row.attrValue) }}
  276. <span v-if="scope.row.attrUnit">{{ scope.row.attrUnit }}</span>
  277. </span>
  278. <span v-else>
  279. {{ scope.row.attrValue }}
  280. </span>
  281. </template>
  282. </el-table-column>
  283. </el-table>
  284. </div>
  285. </el-card>
  286. </div>
  287. <!--设备能力-->
  288. <div v-if="activeTab === 'ability'">
  289. <el-card class="box-card">
  290. <el-table :data="abilityData" style="width: 100%" :show-header="true" :empty-text="'暂无数据'">
  291. <el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
  292. <el-table-column label="能力名称" prop="abilityName"></el-table-column>
  293. <el-table-column label="能力描述" prop="abilityDesc"></el-table-column>
  294. <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  295. <template slot-scope="scope">
  296. <el-button size="mini" type="text" icon="el-icon-info" @click="handleOperate(scope.row)">执行
  297. </el-button>
  298. </template>
  299. </el-table-column>
  300. </el-table>
  301. </el-card>
  302. </div>
  303. <!--设备事件-->
  304. <div v-if="activeTab === 'event'">
  305. <el-card class="box-card">
  306. <el-table :data="eventData" style="width: 100%" :show-header="true" :empty-text="'暂无数据'">
  307. <el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
  308. <el-table-column label="事件名称" prop="eventKey"></el-table-column>
  309. <el-table-column label="事件类型" prop="eventType" :formatter="formatEventType"></el-table-column>
  310. <el-table-column label="事件代码" prop="eventCode"></el-table-column>
  311. <el-table-column label="外部事件代码" prop="extEventCode"></el-table-column>
  312. </el-table>
  313. </el-card>
  314. </div>
  315. </div>
  316. </el-dialog>
  317. </el-col>
  318. </el-row>
  319. </div>
  320. </template>
  321. <script>
  322. import { listDevRecursionByArea } from '@/api/device/device'
  323. import { areaTreeSelect } from '@/api/basecfg/area'
  324. import { getFacsCategorygetByCode, listAllFacs } from '@/api/basecfg/emsfacs'
  325. import { listSubsystemAll } from '@/api/adapter/subsystem'
  326. import { getModelByCode } from '@/api/basecfg/objModel'
  327. import Treeselect from '@riophae/vue-treeselect'
  328. import '@riophae/vue-treeselect/dist/vue-treeselect.css'
  329. import { listcallAbility } from '@/api/basecfg/objAbility'
  330. import { getObjAttr } from '@/api/basecfg/objAttribute'
  331. import { listReportLog, getReportLog, listCallLog, getCallLog } from '@/api/basecfg/objLog'
  332. export default {
  333. name: 'Device',
  334. dicts: ['sys_device_stat'],
  335. components: { Treeselect },
  336. data() {
  337. return {
  338. activeTab: 'basic',
  339. // 遮罩层
  340. loading: true,
  341. // 选中数组
  342. ids: [],
  343. // 非单个禁用
  344. single: true,
  345. // 非多个禁用
  346. multiple: true,
  347. // 显示搜索条件
  348. showSearch: true,
  349. // 总条数
  350. total: 0,
  351. // 能源设备表格数据
  352. deviceList: [],
  353. // 弹出层标题
  354. title: '',
  355. // 是否显示弹出层
  356. open: false,
  357. // 区域名称
  358. areaName: undefined,
  359. // 区域树选项
  360. treeAreaOptions: undefined,
  361. // 设施选项
  362. facsOptions: undefined,
  363. // 设备分类
  364. devcTypeOptions: undefined,
  365. subsystemOptions: undefined,
  366. subCategoryOptions: undefined,
  367. defaultProps: {
  368. children: 'children',
  369. label: 'label'
  370. },
  371. curRow: {},
  372. attrData: [],
  373. abilityData: [],
  374. abilityDevice: [],
  375. eventData: [],
  376. BaseData: [],
  377. ProtocolData: [],
  378. StateData: [],
  379. MeasureData: [],
  380. attrTables: {
  381. Base: { title: '基础属性', data: [] },
  382. Protocol: { title: '协议属性', data: [] },
  383. State: { title: '状态属性', data: [] },
  384. Measure: { title: '计量属性', data: [] }
  385. },
  386. // 查询参数
  387. queryParams: {
  388. pageNum: 1,
  389. pageSize: 10,
  390. deviceSubCategory: '',
  391. deviceCategory: 'E',
  392. locationRef: null,
  393. refFacs: null,
  394. subsystemCode: null
  395. },
  396. callDaterangeTime: [],
  397. logDaterangeTime: [],
  398. logQueryParams: {
  399. startTime: '',
  400. endTime: '',
  401. pageNum: 1,
  402. pageSize: 10
  403. },
  404. logQueryTotal: 0,
  405. callLogQueryParams: {
  406. abilityKey: '',
  407. callStatus: '',
  408. startTime: '',
  409. endTime: '',
  410. pageNum: 1,
  411. pageSize: 10
  412. },
  413. callLogQueryTotal: 0,
  414. callStatusOptions: {
  415. 0: '成功',
  416. 1: '进行中',
  417. 2: '失败'
  418. },
  419. callLogDetailDialog: false,
  420. callLogDetailData: {},
  421. reportDetailDialog: false,
  422. reportDetailData: {},
  423. callLog: false,
  424. reportLog: false,
  425. callLogData: [],
  426. reportLogData: []
  427. }
  428. },
  429. created() {
  430. this.getList()
  431. this.getAreaTree('0', 2)
  432. this.getFacsOptions()
  433. this.getSubsystem()
  434. this.getSubCategorygetByCode()
  435. const now = new Date()
  436. const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0)
  437. const endOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59)
  438. this.logQueryParams.startTime = this.formatDate(startOfDay)
  439. this.logQueryParams.endTime = this.formatDate(endOfDay)
  440. this.callLogQueryParams.startTime = this.formatDate(startOfDay)
  441. this.callLogQueryParams.endTime = this.formatDate(endOfDay)
  442. // 设置默认日期范围
  443. this.callDaterangeTime = [this.formatDate(startOfDay), this.formatDate(endOfDay)]
  444. this.logDaterangeTime = [this.formatDate(startOfDay), this.formatDate(endOfDay)]
  445. },
  446. methods: {
  447. formatDate(date) {
  448. if (!date) return ''
  449. const year = date.getFullYear()
  450. const month = (date.getMonth() + 1).toString().padStart(2, '0')
  451. const day = date.getDate().toString().padStart(2, '0')
  452. const hours = date.getHours().toString().padStart(2, '0')
  453. const minutes = date.getMinutes().toString().padStart(2, '0')
  454. const seconds = date.getSeconds().toString().padStart(2, '0')
  455. return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
  456. },
  457. formatObjType(value) {
  458. const objTypeMap = {
  459. 2: '设备'
  460. }
  461. return objTypeMap[value] || '未知类型'
  462. },
  463. formatCallStatus(status) {
  464. const statusMap = {
  465. 0: '成功',
  466. 1: '进行中',
  467. 2: '失败'
  468. }
  469. return statusMap[status] || '未知状态'
  470. },
  471. /**日志*/
  472. showCallLog(row) {
  473. this.curRow = row
  474. this.getCallLog(row.deviceCode, this.callLogQueryParams.startTime, this.callLogQueryParams.endTime)
  475. this.callLog = true
  476. },
  477. showReportLog(row) {
  478. this.curRow = row
  479. this.getReportLog(row.deviceCode, this.logQueryParams.startTime, this.logQueryParams.endTime) // 加载设备日志数据
  480. this.reportLog = true
  481. },
  482. /**重置调用日志*/
  483. resetCallLogQuery() {
  484. this.callDaterangeTime = []
  485. this.callLogQueryParams.pageNum = 1
  486. this.callLogQueryParams.pageSize = 10
  487. this.callLogQueryParams.abilityKey = ''
  488. this.callLogQueryParams.callStatus = ''
  489. this.handleCallLogQuery()
  490. },
  491. /**查询调用日志*/
  492. handleCallLogQuery() {
  493. if (this.curRow) {
  494. const startTime = this.callDaterangeTime[0]
  495. const endTime = this.callDaterangeTime[1]
  496. const abilityKey = this.callLogQueryParams.abilityKey
  497. const callStatus = this.callLogQueryParams.callStatus
  498. this.getCallLog(this.curRow.deviceCode, startTime, endTime, abilityKey, callStatus)
  499. }
  500. },
  501. /**调用日志表格*/
  502. getCallLog(deviceCode, startTime, endTime, abilityKey, callStatus) {
  503. const query = {
  504. obj_code: deviceCode,
  505. objType: '2',
  506. startRecTime: startTime,
  507. endRecTime: endTime,
  508. abilityKey: abilityKey,
  509. callStatus: callStatus,
  510. pageNum: this.callLogQueryParams.pageNum,
  511. pageSize: this.callLogQueryParams.pageSize
  512. }
  513. listCallLog(query).then(response => {
  514. this.callLogData = response.rows || []
  515. this.callLogQueryTotal = response.total
  516. })
  517. },
  518. /**调用日志详情*/
  519. handleCallLogDetail(row) {
  520. getCallLog(row.id).then(response => {
  521. this.callLogDetailData = response.data || {}
  522. this.callLogDetailDialog = true
  523. })
  524. },
  525. /**重置设备日志*/
  526. resetLogQuery() {
  527. this.logDaterangeTime = []
  528. this.logQueryParams.pageNum = 1
  529. this.logQueryParams.pageSize = 10
  530. this.handleLogQuery() // 重新查询
  531. },
  532. /** 查询设备日志*/
  533. handleLogQuery() {
  534. if (this.curRow) {
  535. const startTime = this.logDaterangeTime[0]
  536. const endTime = this.logDaterangeTime[1]
  537. this.getReportLog(this.curRow.deviceCode, startTime, endTime)
  538. }
  539. },
  540. /**设备日志表格*/
  541. getReportLog(deviceCode, startTime, endTime) {
  542. const query = {
  543. objCode: deviceCode,
  544. objType: '2',
  545. startRecTime: startTime,
  546. endRecTime: endTime,
  547. pageNum: this.logQueryParams.pageNum,
  548. pageSize: this.logQueryParams.pageSize
  549. }
  550. listReportLog(query).then(response => {
  551. this.reportLogData = response.rows || []
  552. this.logQueryTotal = response.total
  553. })
  554. },
  555. /**设备日志详情*/
  556. handleReportLogDetail(row) {
  557. getReportLog(row.id).then(response => {
  558. this.reportDetailData = response.data || {}
  559. this.reportDetailDialog = true
  560. })
  561. },
  562. loadAbilities(row) {
  563. if (!this.curRow) {
  564. this.$message.warning('请选择一条设备记录')
  565. return
  566. }
  567. getModelByCode(row.deviceModel).then(response => {
  568. this.abilityDevice = response.data?.abilityList.filter(item => item.hiddenFlag === 1) || []
  569. })
  570. },
  571. /**设备能力-执行按钮*/
  572. handleDeviceOperate(row, curRow) {
  573. listcallAbility({
  574. abilityKey: row.abilityKey,
  575. objCode: curRow.deviceCode,
  576. objType: '2',
  577. modeCode: row.modeCode,
  578. abilityParam: row.abilityParam
  579. }).then(response => {
  580. this.$message({ message: '设备能力执行成功', type: 'success' })
  581. })
  582. },
  583. // 根据区域代码获取区域名称
  584. buildRefAreaName(curRow) {
  585. const area = this.treeAreaOptions.find(a => a.id === curRow.areaCode);
  586. const areaName = area ? area.label : '未知区域';
  587. if (curRow.locationRef !== curRow.areaCode) {
  588. return areaName + ' - ' + curRow.locationRefName;
  589. }
  590. return areaName;
  591. },
  592. handleOperate(row) {
  593. listcallAbility({
  594. abilityKey: row.abilityKey,
  595. objCode: this.curRow.deviceCode,
  596. objType: '2',
  597. modeCode: row.modeCode,
  598. abilityParam: row.abilityParam
  599. }).then(response => {
  600. this.$message({ message: '设备能力执行成功', type: 'success' })
  601. })
  602. },
  603. getPsName(psName) {
  604. return psName === null ? '' : ' - '+psName;
  605. },
  606. getDeviceStatus(status) {
  607. return status === 1 ? '在线' : '离线'
  608. },
  609. getDeviceStatusClass(status) {
  610. return status === 1 ? 'status-online' : 'status-offline'
  611. },
  612. formatEventType(row, column, cellValue) {
  613. return cellValue === 1 ? '消息上报' : '异常告警'
  614. },
  615. getDeviceStatusText(status) {
  616. const statusMap = {
  617. 0: '离线',
  618. 1: '在线'
  619. }
  620. return statusMap[status] || ''
  621. },
  622. getAttrValueText(attrValue) {
  623. const valueMap = {
  624. 0: '关闭',
  625. 1: '开启',
  626. 2: '通电'
  627. }
  628. return valueMap[attrValue] || attrValue
  629. },
  630. getDeviceStatusTextColor(status) {
  631. if (status === 0) return '#FF0000'
  632. if (status === 1) return '#00FF00'
  633. return '#000000' // 默认黑色文字
  634. },
  635. getDeviceStatusBgColor(status) {
  636. if (status === 0) return '#FFDDDD'
  637. if (status === 1) return '#DDFFDD'
  638. return 'transparent' // 默认无背景色
  639. },
  640. /** 查询能源设备列表 */
  641. getList() {
  642. this.loading = true
  643. listDevRecursionByArea(this.queryParams).then(response => {
  644. this.deviceList = response.rows
  645. console.log('this.deviceList', this.deviceList)
  646. this.total = response.total
  647. this.loading = false
  648. })
  649. },
  650. /** 查询区域树结构 */
  651. getAreaTree(areaCode, layer) {
  652. areaTreeSelect(areaCode, layer).then(response => {
  653. this.treeAreaOptions = [{
  654. id: null,
  655. label: '全部',
  656. children: []
  657. }].concat(response.data)
  658. })
  659. },
  660. // 筛选节点
  661. filterNode(value, data) {
  662. if (!value) return true
  663. return data.label.indexOf(value) !== -1
  664. },
  665. // 节点单击事件
  666. handleNodeClick(data) {
  667. this.queryParams.locationRef = data.id
  668. this.handleQuery()
  669. },
  670. cancel() {
  671. this.open = false
  672. this.reset()
  673. },
  674. /** 搜索按钮操作 */
  675. handleQuery() {
  676. this.queryParams.pageNum = 1
  677. this.getList()
  678. },
  679. /** 重置按钮操作 */
  680. resetQuery() {
  681. this.queryParams.locationRef = null
  682. this.resetForm('queryForm')
  683. this.handleQuery()
  684. },
  685. // 设备状态详情
  686. handleDetail(row) {
  687. this.reset()
  688. this.curRow = row
  689. console.log('设备this.curRow', this.curRow)
  690. getModelByCode(this.curRow.deviceModel).then(response => {
  691. this.open = true
  692. const code = response.data
  693. console.log('code', code)
  694. this.eventData = response.data?.eventList || []
  695. // 过滤
  696. this.abilityData = response.data?.abilityList.filter(item => item.hiddenFlag === 1) || []
  697. this.attrData = response.data?.attrList || []
  698. })
  699. getObjAttr(2, this.curRow.deviceCode).then(response => {
  700. this.attrTables.Base.data = response.data?.Base || []
  701. this.attrTables.Protocol.data = response.data?.Protocol || []
  702. this.attrTables.State.data = response.data?.State || []
  703. this.attrTables.Measure.data = response.data?.Measure || []
  704. })
  705. this.activeTab = 'basic'
  706. },
  707. getFacsOptions() {
  708. const getFacsParams = {
  709. facsCategory: this.queryParams.deviceCategory,
  710. subCategory: this.queryParams.deviceSubCategory
  711. }
  712. listAllFacs(getFacsParams).then(response => {
  713. this.facsOptions = response.data
  714. })
  715. },
  716. getSubsystem() {
  717. listSubsystemAll().then(response => {
  718. this.subsystemOptions = response.data
  719. })
  720. },
  721. getSubCategorygetByCode() {
  722. getFacsCategorygetByCode(this.queryParams.deviceCategory).then(response => {
  723. this.subCategoryOptions = response.data.subtypeList || []
  724. })
  725. },
  726. deviceCategoryChange() {
  727. this.reset()
  728. this.getAreaTree('0', 2)
  729. this.getSubCategorygetByCode()
  730. this.getFacsOptions()
  731. this.handleQuery()
  732. },
  733. reset() {
  734. this.queryParams.pageNum = 1
  735. this.queryParams.pageSize = 10
  736. this.queryParams.deviceSubCategory = ''
  737. this.queryParams.refFacs = null
  738. this.queryParams.subsystemCode = null
  739. }
  740. }
  741. }
  742. </script>
  743. <style lang="scss" scoped>
  744. .detail-dialog .el-dialog {
  745. width: 80%;
  746. }
  747. .section-title {
  748. font-size: 18px;
  749. font-weight: bold;
  750. margin-top: 20px;
  751. margin-bottom: 10px;
  752. }
  753. .status-highlight {
  754. font-size: 16px;
  755. font-weight: bold;
  756. margin-top: 10px;
  757. margin-bottom: 10px;
  758. }
  759. .status-online {
  760. color: #00FF00; /* 在线状态颜色 */
  761. background-color: #DDFFDD;
  762. padding: 2px 6px;
  763. border-radius: 4px;
  764. }
  765. .status-offline {
  766. color: #FF0000; /* 离线状态颜色 */
  767. background-color: #FFDDDD;
  768. padding: 2px 6px;
  769. border-radius: 4px;
  770. }
  771. </style>