index.vue 35 KB

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