Quellcode durchsuchen

feat: remote log

Casper Dai vor 2 Jahren
Ursprung
Commit
2e8f0319ae
3 geänderte Dateien mit 329 neuen und 0 gelöschten Zeilen
  1. 5 0
      src/router/index.js
  2. 76 0
      src/views/platform/remote-log/api.js
  3. 248 0
      src/views/platform/remote-log/index.vue

+ 5 - 0
src/router/index.js

@@ -447,6 +447,11 @@ export const asyncRoutes = [
         component: () => import('@/views/platform/simulator/index'),
         meta: { title: '模拟器' }
       },
+      {
+        path: 'remote/log',
+        component: () => import('@/views/platform/remote-log/index'),
+        meta: { title: '日志抓取' }
+      },
       {
         path: 'cooperation',
         component: () => import('@/views/platform/cooperation/index'),

+ 76 - 0
src/views/platform/remote-log/api.js

@@ -0,0 +1,76 @@
+import request from '@/utils/request'
+import {
+  send,
+  messageSend,
+  addTenant
+} from '@/api/base'
+
+// 设置日志抓取配置
+export function setRemoteLogConfig (data) {
+  return request({
+    url: `/device/remoteLog`,
+    method: 'POST',
+    data: addTenant(data)
+  })
+}
+
+// 获取日志配置
+export function getRemoteLogConfig (deviceId) {
+  return send({
+    url: '/device/remoteLog',
+    method: 'GET',
+    params: { deviceId }
+  })
+}
+
+// 开启下发日志配置
+export function startRemoteLog (deviceId) {
+  return messageSend({
+    url: '/device/remoteLog/switch',
+    method: 'PUT',
+    data: {
+      activate: true,
+      deviceId
+    }
+  }, '开启')
+}
+
+// 停止下发日志配置
+export function stopRemoteLog (deviceId) {
+  return messageSend({
+    url: '/device/remoteLog/switch',
+    method: 'PUT',
+    data: {
+      activate: false,
+      deviceId
+    }
+  }, '停止')
+}
+
+// 设备上报记录查询
+export function getRemoteLogs (query) {
+  const { pageNum: pageIndex, pageSize, ...params } = query
+  return request({
+    url: '/device/remoteLog/record/pageQuery',
+    method: 'GET',
+    params: addTenant({
+      pageIndex, pageSize,
+      ...params
+    })
+  })
+}
+
+// 获取心跳
+export function getHeartbeats (sn) {
+  if (sn) {
+    return request({
+      url: '/device/remoteLog/singleHeartbeat',
+      method: 'GET',
+      params: { sn }
+    })
+  }
+  return request({
+    url: '/device/remoteLog/heartbeat',
+    method: 'GET'
+  })
+}

+ 248 - 0
src/views/platform/remote-log/index.vue

@@ -0,0 +1,248 @@
+<template>
+  <wrapper
+    fill
+    margin
+    padding
+    background
+  >
+    <platform-page
+      class="l-flex__fill"
+      @change="onTenantChanged"
+    >
+      <schema-table
+        ref="table"
+        :schema="schema"
+      />
+    </platform-page>
+    <confirm-dialog
+      ref="editDialog"
+      title="日志抓取配置"
+      @confirm="onConfirm"
+    >
+      <div class="c-sibling-item--v c-grid-form u-align-self--center">
+        <div class="c-grid-form__row u-font-size--xs u-bold">
+          当前状态:{{ logSetting.activate ? '已下发配置' : '未下发配置' }}
+        </div>
+        <span class="c-grid-form__label u-required">抓取时长</span>
+        <div class="l-flex--row">
+          <el-input-number
+            v-model="logSetting.duration"
+            :min="60"
+            :max="86400"
+            step-strictly
+          />&nbsp;秒
+        </div>
+        <span class="c-grid-form__label u-required">抓取指令</span>
+        <div
+          class="has-info"
+          data-info="多条指令以分号分隔"
+        >
+          <el-input
+            v-model="logSetting.commands"
+            type="textarea"
+            :rows="5"
+          />
+        </div>
+        <span class="c-grid-form__label u-required">是否重启</span>
+        <el-switch
+          v-model="logSetting.reboot"
+          class="c-grid-form__option"
+          active-color="#13ce66"
+          inactive-color="#ff4949"
+        />
+      </div>
+      <template #footer="{ confirm, cancel }">
+        <button
+          class="c-sibling-item o-button"
+          @click="confirm"
+        >
+          开启抓取
+        </button>
+        <button
+          class="c-sibling-item o-button o-button--cancel"
+          @click="cancel"
+        >
+          取消
+        </button>
+      </template>
+    </confirm-dialog>
+    <table-dialog
+      ref="resultDialog"
+      size="lg"
+      title="抓取结果"
+      :schema="resultSchema"
+    />
+    <table-dialog
+      ref="heartbeatDialog"
+      size="lg fixed"
+      title="心跳记录"
+      :schema="heartbeatSchema"
+    />
+  </wrapper>
+</template>
+
+<script>
+import { parseTime } from '@/utils'
+import { getDevicesByTenant } from '@/api/device'
+import {
+  getRemoteLogConfig,
+  setRemoteLogConfig,
+  startRemoteLog,
+  stopRemoteLog,
+  getRemoteLogs,
+  getHeartbeats
+} from './api'
+
+const defaultLogSettingForm = {
+  activate: false,
+  duration: 60,
+  commands: 'logcat -vtime | grep -i -E "MqttClient|PushCallback|MqttService"',
+  reboot: false
+}
+
+export default {
+  name: 'DeviceLog',
+  data () {
+    return {
+      logSetting: {},
+      schema: {
+        list: this.getDevicesByTenant,
+        buttons: [
+          { label: '心跳记录', on: this.onHeartbeats }
+        ],
+        filters: [
+          { key: 'name', type: 'search', placeholder: '设备名称' }
+        ],
+        cols: [
+          { type: 'refresh' },
+          { prop: 'name', label: '设备名称' },
+          { prop: 'serialNumber', label: '序列号' },
+          { prop: 'mac', label: 'MAC' },
+          { type: 'tag', render: ({ activate, onlineStatus }) => activate
+            ? onlineStatus === 0
+              ? { type: 'primary', label: '已启用' }
+              : onlineStatus === 1
+                ? { type: 'success', label: '在线' }
+                : { type: 'danger', label: '离线' }
+            : { type: 'warning', label: '未激活' } },
+          { type: 'invoke', render: [
+            { label: '开始抓取', on: this.onStart },
+            { label: '停止抓取', on: this.onStop },
+            { label: '抓取结果', on: this.onResult },
+            { label: '心跳记录', on: this.onHeartbeat }
+          ], width: 300 }
+        ]
+      },
+      heartbeatSchema: {
+        nonPagination: true,
+        list: this.getheartbeatData,
+        cols: [
+          { type: 'refresh' },
+          { prop: 'sn', label: '序列号' },
+          { prop: 'mac', label: 'MAC', width: 140 },
+          { prop: 'ip', label: 'ip', width: 140 },
+          { prop: 'settingId', label: '当前事件' },
+          { label: '上报时间', render: ({ timestamp }) => parseTime(timestamp), width: 160 }
+        ]
+      },
+      curDeviceId: null
+    }
+  },
+  computed: {
+    resultSchema () {
+      return {
+        list: getRemoteLogs,
+        condition: { deviceId: this.curDeviceId },
+        cols: [
+          { type: 'refresh' },
+          { prop: 'settingId', label: '事件' },
+          { label: '执行状态', type: 'tag', render: ({ status }) => {
+            return {
+              type: status ? 'success' : 'danger',
+              label: status ? '成功' : '失败'
+            }
+          } },
+          { prop: 'message', label: '备注', width: 320 },
+          { prop: 'createTime', label: '上传时间', width: 180 }
+        ]
+      }
+    }
+  },
+  methods: {
+    onTenantChanged (tenant) {
+      this.$tenant = tenant
+      this.$refs.table?.pageTo(1)
+    },
+    getDevicesByTenant (params) {
+      if (!this.$tenant) {
+        return Promise.resolve({ data: [] })
+      }
+      return getDevicesByTenant(this.$tenant.path, params)
+    },
+    onStart (device) {
+      getRemoteLogConfig(device.id).then(({ data }) => {
+        if (data) {
+          const { activate, duration, commands, reboot } = data
+          this.logSetting = {
+            activate,
+            duration,
+            commands: commands ? commands.join(';') : [],
+            reboot
+          }
+        } else {
+          this.logSetting = { ...defaultLogSettingForm }
+        }
+        this.curDeviceId = device.id
+        this.$refs.editDialog.show()
+      })
+    },
+    async onConfirm (done) {
+      const { activate, duration, commands, reboot } = this.logSetting
+      if (~commands.indexOf(';')) {
+        this.$message({
+          type: 'warning',
+          message: '请使用英文输入下的【;】符号'
+        })
+        return
+      }
+      if (activate) {
+        await stopRemoteLog(this.curDeviceId)
+      }
+      await setRemoteLogConfig({
+        deviceId: this.curDeviceId,
+        duration,
+        commands: commands.split(';'),
+        reboot
+      })
+      await startRemoteLog(this.curDeviceId)
+      done()
+    },
+    onStop (device) {
+      stopRemoteLog(device.id)
+    },
+    onResult (device) {
+      this.curDeviceId = device.id
+      this.$refs.resultDialog.show()
+    },
+    getheartbeatData () {
+      return getHeartbeats(this.$sn).then(({ data }) => {
+        if (!data) {
+          return { data: [] }
+        }
+        if (Array.isArray(data)) {
+          return { data: data.filter(i => i).map(i => JSON.parse(i)) }
+        }
+        return { data: [JSON.parse(data)] }
+      })
+    },
+    onHeartbeats () {
+      this.$sn = null
+      this.$refs.heartbeatDialog.show()
+    },
+    onHeartbeat (device) {
+      this.$sn = device.serialNumber
+      this.$refs.heartbeatDialog.show()
+    }
+  }
+}
+</script>