device-log.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. <template>
  2. <div class="device-detail-page">
  3. <el-card class="main-card" style="padding: 0" body-style="padding-bottom: 0">
  4. <el-form
  5. :model="queryParams"
  6. ref="queryFormRef"
  7. :inline="true"
  8. v-show="showSearch"
  9. label-width="68px"
  10. >
  11. <el-form-item :label="t('device.device-log798283-0')" prop="logType">
  12. <el-select
  13. v-model="queryParams.logType"
  14. :placeholder="t('device.device-log798283-1')"
  15. clearable
  16. size="small"
  17. >
  18. <el-option
  19. v-for="dict in dict.type.iot_event_type"
  20. :key="dict.value"
  21. :label="dict.label"
  22. :value="dict.value"
  23. />
  24. </el-select>
  25. </el-form-item>
  26. <el-form-item :label="t('device.device-log798283-2')" prop="identity">
  27. <el-input
  28. v-model="queryParams.identity"
  29. :placeholder="t('device.device-log798283-3')"
  30. clearable
  31. size="small"
  32. @keyup.enter="handleQuery"
  33. />
  34. </el-form-item>
  35. <el-form-item :label="t('device.device-log798283-4')">
  36. <el-date-picker
  37. v-model="daterangeTime"
  38. size="small"
  39. style="width: 240px"
  40. value-format="YYYY-MM-DD"
  41. type="daterange"
  42. range-separator="-"
  43. :start-placeholder="t('device.device-log798283-5')"
  44. :end-placeholder="t('device.device-log798283-6')"
  45. />
  46. </el-form-item>
  47. <el-form-item>
  48. <el-button type="primary" icon="Search" size="small" @click="handleQuery">{{
  49. t('device.device-log798283-7')
  50. }}</el-button>
  51. <el-button icon="Refresh" size="small" @click="resetQuery">{{
  52. t('device.device-log798283-8')
  53. }}</el-button>
  54. </el-form-item>
  55. </el-form>
  56. </el-card>
  57. <el-card class="main-card" body-style="padding-top: 0">
  58. <el-table :border="false" v-loading="loading" :data="deviceLogList" size="small">
  59. <el-table-column
  60. :label="t('device.device-log798283-9')"
  61. align="center"
  62. prop="logType"
  63. width="120"
  64. >
  65. <template #default="scope">
  66. <dict-tag :options="dict.type.iot_event_type" :value="scope.row.logType" />
  67. </template>
  68. </el-table-column>
  69. <el-table-column
  70. :label="t('device.device-log798283-10')"
  71. align="center"
  72. prop="logType"
  73. width="120"
  74. >
  75. <template #default="scope">
  76. <el-tag type="primary" v-if="scope.row.mode == 1">{{
  77. t('device.device-log798283-11')
  78. }}</el-tag>
  79. <el-tag type="success" v-else-if="scope.row.mode == 2">{{
  80. t('device.device-log798283-12')
  81. }}</el-tag>
  82. <el-tag type="info" v-else>{{ t('device.device-log798283-13') }}</el-tag>
  83. </template>
  84. </el-table-column>
  85. <el-table-column
  86. :label="t('device.device-log798283-14')"
  87. align="center"
  88. prop="createTime"
  89. width="150"
  90. >
  91. <template #default="scope">
  92. <span>{{ scope.row.createTime }}</span>
  93. </template>
  94. </el-table-column>
  95. <el-table-column :label="t('device.device-log798283-2')" align="center" prop="identity" />
  96. <el-table-column
  97. :label="t('device.device-log798283-15')"
  98. align="left"
  99. header-align="center"
  100. prop="logValue"
  101. >
  102. <template #default="scope">
  103. <div v-html="formatValueDisplay(scope.row)"></div>
  104. </template>
  105. </el-table-column>
  106. <el-table-column
  107. :label="t('device.device-log798283-16')"
  108. header-align="center"
  109. align="left"
  110. prop="remark"
  111. >
  112. <template #default="scope">
  113. {{ scope.row.remark == null ? t('device.device-log798283-17') : scope.row.remark }}
  114. </template>
  115. </el-table-column>
  116. </el-table>
  117. <div style="height: 40px">
  118. <pagination
  119. v-show="total > 0"
  120. :total="total"
  121. v-model:page="queryParams.pageNum"
  122. v-model:limit="queryParams.pageSize"
  123. @pagination="getList"
  124. />
  125. </div>
  126. </el-card>
  127. </div>
  128. </template>
  129. <script setup>
  130. import { ref, reactive, watch, onMounted } from 'vue'
  131. // import { listEventLog } from '@/api/iot/eventLog'
  132. // 定义属性
  133. const props = defineProps({
  134. device: {
  135. type: Object,
  136. default: null
  137. }
  138. })
  139. // 定义组件名称和字典
  140. defineOptions({
  141. name: 'DeviceLog',
  142. dicts: ['iot_event_type', 'iot_yes_no']
  143. })
  144. // Refs
  145. const queryFormRef = ref()
  146. // Reactive data
  147. const thingsModel = reactive({})
  148. const loading = ref(true)
  149. const showSearch = ref(true)
  150. const total = ref(0)
  151. const deviceLogList = ref([])
  152. const daterangeTime = ref([])
  153. const queryParams = reactive({
  154. pageNum: 1,
  155. pageSize: 10,
  156. logType: null,
  157. logValue: null,
  158. deviceId: null,
  159. serialNumber: null,
  160. deviceName: null,
  161. identity: null,
  162. isMonitor: null
  163. })
  164. const deviceInfo = ref({})
  165. // Watch
  166. watch(
  167. () => props.device,
  168. (newVal, oldVal) => {
  169. deviceInfo.value = newVal
  170. if (deviceInfo.value && deviceInfo.value.deviceId != 0) {
  171. queryParams.serialNumber = deviceInfo.value.serialNumber
  172. getList()
  173. // 解析缓存物模型
  174. Object.assign(thingsModel, deviceInfo.value.cacheThingsModel)
  175. }
  176. }
  177. )
  178. // Methods
  179. const getList = () => {
  180. loading.value = true
  181. // 这里需要实现 addDateRange 方法或者使用其他方式处理日期范围
  182. const params = { ...queryParams }
  183. if (daterangeTime.value && daterangeTime.value.length === 2) {
  184. params.beginTime = daterangeTime.value[0]
  185. params.endTime = daterangeTime.value[1]
  186. }
  187. // listEventLog(params).then((response) => {
  188. // deviceLogList.value = response.rows
  189. // total.value = response.total
  190. // loading.value = false
  191. // })
  192. }
  193. const handleQuery = () => {
  194. queryParams.pageNum = 1
  195. getList()
  196. }
  197. const resetQuery = () => {
  198. queryFormRef.value?.resetFields()
  199. daterangeTime.value = []
  200. handleQuery()
  201. }
  202. // 格式化显示数据定义
  203. const formatValueDisplay = (row) => {
  204. // 类型(1=属性上报,2=调用功能,3=事件上报,4=设备升级,5=设备上线,6=设备离线)
  205. if (row.logType == 1) {
  206. let propertyItem = getThingsModelItem(1, row.identity)
  207. if (propertyItem != '') {
  208. return (
  209. (propertyItem.parentName
  210. ? '[' +
  211. propertyItem.parentName +
  212. (propertyItem.arrayIndex ? propertyItem.arrayIndex : '') +
  213. '] '
  214. : '') +
  215. propertyItem.name +
  216. ': <span style="color:#409EFF;">' +
  217. getThingsModelItemValue(propertyItem, row.logValue) +
  218. ' ' +
  219. (propertyItem.datatype.unit != undefined ? propertyItem.datatype.unit : '') +
  220. '</span>'
  221. )
  222. }
  223. } else if (row.logType == 2) {
  224. let functionItem = getThingsModelItem(2, row.identity)
  225. if (functionItem != '') {
  226. return (
  227. (functionItem.parentName
  228. ? '[' +
  229. functionItem.parentName +
  230. (functionItem.arrayIndex ? functionItem.arrayIndex : '') +
  231. '] '
  232. : '') +
  233. functionItem.name +
  234. ': <span style="color:#409EFF">' +
  235. getThingsModelItemValue(functionItem, row.logValue) +
  236. ' ' +
  237. (functionItem.datatype.unit != undefined ? functionItem.datatype.unit : '') +
  238. '</span>'
  239. )
  240. }
  241. } else if (row.logType == 3) {
  242. let eventItem = getThingsModelItem(3, row.identity)
  243. if (eventItem != '') {
  244. return (
  245. (eventItem.parentName
  246. ? '[' + eventItem.parentName + (eventItem.arrayIndex ? eventItem.arrayIndex : '') + '] '
  247. : '') +
  248. eventItem.name +
  249. ': <span style="color:#409EFF">' +
  250. getThingsModelItemValue(eventItem, row.logValue) +
  251. ' ' +
  252. (eventItem.datatype.unit != undefined ? eventItem.datatype.unit : '') +
  253. '</span>'
  254. )
  255. } else {
  256. return row.logValue
  257. }
  258. } else if (row.logType == 4) {
  259. return '<span style="font-weight:bold">设备升级</span>'
  260. } else if (row.logType == 5) {
  261. return '<span style="font-weight:bold">设备上线</span>'
  262. } else if (row.logType == 6) {
  263. return '<span style="font-weight:bold">设备离线</span>'
  264. }
  265. return ''
  266. }
  267. // 获取物模型项中的值
  268. const getThingsModelItemValue = (item, oldValue) => {
  269. // 枚举和布尔转换为文字
  270. if (item.datatype.type == 'bool') {
  271. if (oldValue == '0') {
  272. return item.datatype.falseText
  273. } else if (oldValue == '1') {
  274. return item.datatype.trueText
  275. }
  276. } else if (item.datatype.type == 'enum') {
  277. for (let i = 0; i < item.datatype.enumList.length; i++) {
  278. if (oldValue == item.datatype.enumList[i].value) {
  279. return item.datatype.enumList[i].text
  280. }
  281. }
  282. }
  283. return oldValue
  284. }
  285. // 获取物模型中的项
  286. const getThingsModelItem = (type, identity) => {
  287. if (type == 1 && thingsModel.properties) {
  288. for (let i = 0; i < thingsModel.properties.length; i++) {
  289. //普通类型 integer/decimal/string/emum//bool
  290. if (thingsModel.properties[i].id == identity) {
  291. return thingsModel.properties[i]
  292. }
  293. // 对象 object
  294. if (thingsModel.properties[i].datatype.type == 'object') {
  295. for (let j = 0; j < thingsModel.properties[i].datatype.params.length; j++) {
  296. if (thingsModel.properties[i].datatype.params[j].id == identity) {
  297. thingsModel.properties[i].datatype.params[j].parentName = thingsModel.properties[i].name
  298. return thingsModel.properties[i].datatype.params[j]
  299. }
  300. }
  301. }
  302. // 数组 array
  303. if (
  304. thingsModel.properties[i].datatype.type == 'array' &&
  305. thingsModel.properties[i].datatype.arrayType
  306. ) {
  307. if (thingsModel.properties[i].datatype.arrayType == 'object') {
  308. // 数组元素格式:array_01_parentId_humidity,array_01_前缀终端上报时加上,物模型中没有
  309. let realIdentity = identity
  310. let arrayIndex = 0
  311. if (identity.indexOf('array_') > -1) {
  312. arrayIndex = identity.substring(6, 8)
  313. realIdentity = identity.substring(9)
  314. }
  315. for (let j = 0; j < thingsModel.properties[i].datatype.params.length; j++) {
  316. if (thingsModel.properties[i].datatype.params[j].id == realIdentity) {
  317. // 标注索引和父级名称
  318. thingsModel.properties[i].datatype.params[j].arrayIndex = Number(arrayIndex) + 1
  319. thingsModel.properties[i].datatype.params[j].parentName =
  320. thingsModel.properties[i].name
  321. return thingsModel.properties[i].datatype.params[j]
  322. }
  323. }
  324. } else {
  325. // 普通类型
  326. for (let j = 0; j < thingsModel.properties[i].datatype.arrayCount.length; j++) {
  327. if (thingsModel.properties[i].id == realIdentity) {
  328. thingsModel.properties[i].arrayIndex = Number(arrayIndex) + 1
  329. thingsModel.properties[i].parentName = "t('device.device-log798283-21')"
  330. return thingsModel.properties[i]
  331. }
  332. }
  333. }
  334. }
  335. }
  336. } else if (type == 2 && thingsModel.functions) {
  337. for (let i = 0; i < thingsModel.functions.length; i++) {
  338. //普通类型 integer/decimal/string/emum/bool
  339. if (thingsModel.functions[i].id == identity) {
  340. return thingsModel.functions[i]
  341. }
  342. // 对象 object
  343. if (thingsModel.functions[i].datatype.type == 'object') {
  344. for (let j = 0; j < thingsModel.functions[i].datatype.params.length; j++) {
  345. if (thingsModel.functions[i].datatype.params[j].id == identity) {
  346. thingsModel.functions[i].datatype.params[j].parentName = thingsModel.functions[i].name
  347. return thingsModel.functions[i].datatype.params[j]
  348. }
  349. }
  350. }
  351. // 数组 array
  352. if (
  353. thingsModel.functions[i].datatype.type == 'array' &&
  354. thingsModel.functions[i].datatype.arrayType
  355. ) {
  356. // 数组元素格式:array_01_parentId_humidity,array_01_前缀终端上报时加上,物模型中没有
  357. let realIdentity = identity
  358. let arrayIndex = 0
  359. if (identity.indexOf('array_') > -1) {
  360. arrayIndex = identity.substring(6, 8)
  361. realIdentity = identity.substring(9)
  362. }
  363. if (thingsModel.functions[i].datatype.arrayType == 'object') {
  364. for (let j = 0; j < thingsModel.functions[i].datatype.params.length; j++) {
  365. if (thingsModel.functions[i].datatype.params[j].id == realIdentity) {
  366. // 标注索引和父级名称
  367. thingsModel.functions[i].datatype.params[j].arrayIndex = Number(arrayIndex) + 1
  368. thingsModel.functions[i].datatype.params[j].parentName = thingsModel.functions[i].name
  369. return thingsModel.functions[i].datatype.params[j]
  370. }
  371. }
  372. } else {
  373. // 普通类型
  374. for (let j = 0; j < thingsModel.functions[i].datatype.arrayCount.length; j++) {
  375. if (thingsModel.functions[i].id == realIdentity) {
  376. thingsModel.functions[i].arrayIndex = Number(arrayIndex) + 1
  377. thingsModel.functions[i].parentName = "t('device.device-log798283-21')"
  378. return thingsModel.functions[i]
  379. }
  380. }
  381. }
  382. }
  383. }
  384. } else if (type == 3 && thingsModel.events) {
  385. for (let i = 0; i < thingsModel.events.length; i++) {
  386. if (thingsModel.events[i].id == identity) {
  387. return thingsModel.events[i]
  388. }
  389. }
  390. }
  391. return ''
  392. }
  393. // Lifecycle
  394. onMounted(() => {
  395. if (props.device) {
  396. queryParams.serialNumber = props.device.serialNumber
  397. getList()
  398. }
  399. })
  400. </script>