index.vue 34 KB

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