瀏覽代碼

日志查看增加类型区分,ota批次默认只有不是主动推送

Xiahai 1 年之前
父節點
當前提交
c1f7f277c2

+ 2 - 1
src/api/system/index.ts

@@ -184,7 +184,8 @@ export default {
   lastLinesLog: {
     getList: (params: object) => get('/system/monitor/listLogs', params),
     detail: (params: object) => get('/system/monitor/lastLinesLog', params),
-    down: (params: object) => file('system/monitor/downloadLog', params),
+    down: (params: object) => file('/system/monitor/downloadLog', params),
+    delete: (params: object) => del('/system/monitor/lastLinesLog/delete', params),
   },
   getInfoByKey: (params: object) => get('/common/config/getInfoByKey', params)
 }

+ 2 - 4
src/views/iot/ota-update/update/component/batch.vue

@@ -73,10 +73,8 @@
 <!--              <span>查看</span>-->
 <!--            </router-link>-->
             <el-button size="small" text type="primary" @click="getDeviceList(scope.row)">查看</el-button>
-            <!--            <el-button size="small" text type="warning" v-auth="'edit'" @click="CheckUpdate(scope.row)">编辑</el-button>-->
-            <!--            <el-button size="small" text type="danger" v-auth="'del'" @click="del(scope.row)">删除</el-button>-->
-<!--            <el-button size="small" text type="success" v-if="scope.row.active != 1" @click="activation(scope.row)">激活</el-button>-->
-<!--            <el-button size="small" text type="danger" v-else @click="activation(scope.row)">禁用</el-button>-->
+<!--            <el-button size="small" text type="warning" v-auth="'edit'" @click="CheckUpdate(scope.row)">编辑</el-button>-->
+<!--            <el-button size="small" text type="danger" v-auth="'del'" @click="del(scope.row)">删除</el-button>-->
           </template>
         </el-table-column>
       </el-table>

+ 10 - 5
src/views/iot/ota-update/update/component/check.vue

@@ -165,13 +165,18 @@ export default defineComponent({
     // 获取协议方式
     const getMethod = () => {
       // 如果是http、https协议则主动推送为否
-      if (state.ruleForm.method === '1' || state.ruleForm.method === '2') {
+      // if (state.ruleForm.method === '1') {
         state.ruleForm.push = '2';
         state.ruleForm.pushDisabled = true;
-      } else {
-        state.ruleForm.pushDisabled = false;
-        state.ruleForm.push = '';
-      }
+      // }
+      // if (state.ruleForm.method === '2') {
+      //   state.ruleForm.push = '2';
+      //   state.ruleForm.pushDisabled = true;
+      // }
+      // if (state.ruleForm.method === '3'){
+      //   state.ruleForm.pushDisabled = false;
+      //   state.ruleForm.push = '1';
+      // }
     };
     const getProductList = () => {
       api.batch.getDeviceList({ productId: state.ruleForm.productId}).then((res: any) => {

+ 182 - 42
src/views/system/monitor/lastLinesLog/index.vue

@@ -1,63 +1,203 @@
 <template>
-	<div>
-	<el-card shadow="hover">
-
-		<el-table :data="tableData" style="width: 100%" row-key="id" v-loading="loading">
-			<el-table-column prop="name" label="文件名" show-overflow-tooltip></el-table-column>
-			<el-table-column prop="size" label="大小" show-overflow-tooltip></el-table-column>
-			<el-table-column prop="changeAt" label="修改时间" min-width="100" align="center"></el-table-column>
-			<el-table-column label="操作" width="200" align="center">
-				<template #default="scope">
-					<el-button size="small" text type="primary" v-if="!scope.row.folderName"
-						@click="view(scope.row)">详情</el-button>
-					<el-button size="small" text type="primary" v-auth="'del'" @click="down(scope.row)">下载</el-button>
-				</template>
-			</el-table-column>
-		</el-table>
-		<pagination v-if="params.total" :total="params.total" v-model:page="params.pageNum" v-model:limit="params.pageSize"
-			@pagination="getList()" />
-	</el-card>
-
-	<el-dialog v-model="dialogVisible" title="查看详情">
-		<div v-for="line in topmsg" :key="line" class="error-line">{{ line }}</div>
-
-		<div v-for="line in errorMessage" :key="line" class="error-line">{{ line }}</div>
-	</el-dialog>
-
-</div>
+  <div>
+    <div class="content-box chatdoom">
+      <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
+
+        <!-- 日志列表 -->
+        <el-tab-pane label="服务日志" name="1">
+          <el-card shadow="hover">
+            <el-table ref="table" :data="tableData" style="width: 100%" row-key="id" v-loading="loading">
+              <el-table-column prop="name" label="文件名" show-overflow-tooltip></el-table-column>
+              <el-table-column prop="size" label="大小" show-overflow-tooltip></el-table-column>
+              <el-table-column prop="changeAt" label="修改时间" min-width="100" align="center"></el-table-column>
+              <el-table-column label="操作" width="200" align="center">
+                <template #default="scope">
+                  <el-button size="small" text type="primary" v-if="!scope.row.folderName"
+                             @click="view(scope.row)">详情
+                  </el-button>
+                  <el-button size="small" text type="info" v-auth="'download'" @click="down(scope.row)">下载</el-button>
+                  <el-button size="small" text type="danger" v-auth="'del'" @click="onRowDel(scope.row)">删除</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-card>
+
+          <el-dialog v-model="dialogVisible" title="查看详情">
+            <div v-for="line in topMsg" :key="line" class="error-line">{{ line }}</div>
+            <div v-for="line in errorMessage" :key="line" class="error-line">{{ line }}</div>
+          </el-dialog>
+        </el-tab-pane>
+
+        <!-- 数据库日志 -->
+        <el-tab-pane label="数据库日志" name="2">
+          <el-card shadow="hover">
+            <el-table :data="tableData" style="width: 100%" row-key="id" v-loading="loading">
+              <el-table-column prop="name" label="文件名" show-overflow-tooltip></el-table-column>
+              <el-table-column prop="size" label="大小" show-overflow-tooltip></el-table-column>
+              <el-table-column prop="changeAt" label="修改时间" min-width="100" align="center"></el-table-column>
+              <el-table-column label="操作" width="200" align="center">
+                <template #default="scope">
+                  <el-button size="small" text type="primary" v-if="!scope.row.folderName"
+                             @click="view(scope.row)">详情
+                  </el-button>
+                  <el-button size="small" text type="info" v-auth="'download'" @click="down(scope.row)">下载</el-button>
+                  <el-button size="small" text type="danger" v-auth="'del'" @click="onRowDel(scope.row)">删除</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-card>
+
+          <el-dialog v-model="dialogVisible" title="查看详情">
+            <div v-for="line in topMsg" :key="line" class="error-line">{{ line }}</div>
+
+            <div v-for="line in errorMessage" :key="line" class="error-line">{{ line }}</div>
+          </el-dialog>
+        </el-tab-pane>
+
+        <!-- 运行日志 -->
+        <el-tab-pane label="运行日志" name="3" class="runMessage">
+          <!-- 运行日志 -->
+          <div v-if="runButtonShow" v-loading="runLoading" v-for="line in runMessage" :key="line" class="error-line">{{ line }}</div>
+          <div v-else class="error-line">暂无数据</div>
+
+          <div class="run-button" v-if="runButtonShow">
+            <el-button size="small" text type="info" v-auth="'download'" @click="down">下载</el-button>
+            <el-button size="small" text type="danger" v-auth="'del'" @click="onRowDel">删除</el-button>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+  </div>
 </template>
 
 <script lang="ts" setup>
 import api from '/@/api/system';
-import { useSearch } from '/@/hooks/useCommon';
+import {useSearch} from '/@/hooks/useCommon';
 import getOrigin from '/@/utils/origin'
 import downloadFile from '/@/utils/download';
-import { ref } from 'vue';
-const { params, tableData, getList, loading } = useSearch<any[]>(api.lastLinesLog.getList, 'list', { keyWord: '' });
+import {ref, getCurrentInstance, nextTick, onMounted} from 'vue';
+import {ElMessage, ElMessageBox} from "element-plus";
+
+const dialogVisible = ref(false);
+const errorMessage = ref([]);
+const runMessage = ref([]);
+const topMsg = ref([]);
+const activeName = '1';
+const typo = ref('service');
+const runLoading = ref(false);
+const { proxy } = getCurrentInstance() as any;
+const isScrolling = ref(false);
+const chatContent: any = ref(null);
+const runButtonShow = ref(false);
+
+const {params, tableData, getList, loading} = useSearch<any[]>(api.lastLinesLog.getList, 'list', {typo: typo.value});
+
 getList();
 
-const dialogVisible=ref(false);
-const errorMessage=ref([]);
-const topmsg=ref([]);
+onMounted(() => {
+  chatContent.value = document.getElementsByClassName('chatdoom')[0]
+  scrollBottom()
+})
+
+const scrollBottom = () => {
+  nextTick(() => {
+    //注意要使用nextick以免获取不到dom
+    if (!isScrolling.value) {
+      // chatContent.value.scrollTop = chatContent.value.scrollHeight - chatContent.value.offsetHeight
+      chatContent.value.scrollTop = chatContent.value.offsetHeight
+      console.log(chatContent.value.scrollTop);
+    }
+  })
+}
 
 const view = (row: any) => {
-	const es = new EventSource(getOrigin(import.meta.env.VITE_SERVER_URL + "/subscribe/logInfo?name="+row.name));
-	es.addEventListener('log', ({ data }) => {
-		topmsg.value.unshift(data);
-	});
-	api.lastLinesLog.detail({name:row.name}).then((res: any) => {
-		errorMessage.value=res.list;
-		dialogVisible.value=true;
-    });
+  const es = new EventSource(getOrigin(import.meta.env.VITE_SERVER_URL + "/subscribe/logInfo?name=" + row.name + '&typo=' + typo.value));
+  es.addEventListener('log', ({data}) => {
+    topMsg.value.unshift(data);
+  });
+  api.lastLinesLog.detail({name: row.name, typo: typo.value}).then((res: any) => {
+    errorMessage.value = res.list;
+    dialogVisible.value = true;
+  });
 };
 const down = (row: any) => {
-	// window.open(getOrigin(import.meta.env.VITE_SERVER_URL + "system/monitor/downloadLog?name="+row.name));
-	api.lastLinesLog.down({ name: row.name }).then((res: any) => downloadFile(res,row.name))
+  if (typo.value == 'run') {
+    row.name = 'sagoo-admin.log'
+  }
+  api.lastLinesLog.down({name: row.name, typo: typo.value}).then((res: any) => downloadFile(res, row.name))
+};
+
+const onRowDel = (row: any) => {
+  if (typo.value == 'run') {
+    row.name = 'sagoo-admin.log'
+  }
+  let msg = '你确定要删除所选数据?';
+  ElMessageBox.confirm(msg, '提示', {
+    confirmButtonText: '确认',
+    cancelButtonText: '取消',
+    type: 'warning',
+  }).then(() => {
+    api.lastLinesLog.delete({name: row.name, typo: typo.value}).then(() => {
+      params.typo = typo.value;
+      if (typo.value == 'run') {
+        runButtonShow.value = false;
+      } else {
+        getList()
+      }
+      ElMessage.success('删除成功');
+    });
+  }).catch(() => { });
 };
 
+// 切换tab
+const handleClick = (tab: any, event: Event) => {
+  if (tab.props.name == 1) {
+    typo.value = 'service';
+    // 获取日志列表
+    params.typo = typo.value;
+    getList()
+  } else if (tab.props.name == 2) {
+    typo.value = 'mysql'
+    params.typo = typo.value;
+    getList();
+  } else if (tab.props.name == 3) {
+    runLoading.value = true;
+    typo.value = 'run'
+    params.type = typo.value
+    api.lastLinesLog.detail({name: 'sagoo-admin.log', typo: typo.value}).then((res: any) => {
+      if (res.list.length > 0) {
+        runButtonShow.value = true;
+        runMessage.value = res.list;
+      }
+      runLoading.value = false;
+    });
+  }
+}
 </script>
 <style scoped>
+.run-button {
+  position: fixed;
+  bottom: 150px;
+  right: 60px;
+}
+.runMessage {
+  height: 500px;
+}
+.content-box {
+  background: #fff;
+  width: 100%;
+  padding: 5px 20px 20px 20px;
+}
 .error-line {
   white-space: pre-line; /* 保留换行符 */
 }
+.el-tabs--card {
+  height: calc(100vh - 110px);
+  overflow-y: auto;
+}
+.el-tab-pane {
+  position: relative;
+  //height: calc(100vh - 110px);
+  overflow-y: auto;
+}
 </style>