Преглед на файлове

增加事件日志`Tab`页

mxd преди 3 години
родител
ревизия
e4419212dd

+ 25 - 1
magic-editor/src/console/src/assets/iconfont/iconfont.css

@@ -1,6 +1,6 @@
 @font-face {
   font-family: "magic-iconfont"; /* Project id 1928593 */
-  src: url('iconfont.ttf?t=1626489914543') format('truetype');
+  src: url('iconfont.ttf?t=1628077606269') format('truetype');
 }
 
 .ma-icon {
@@ -11,6 +11,30 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.ma-icon-mysql:before {
+  content: "\e61e";
+}
+
+.ma-icon-postgresql:before {
+  content: "\e603";
+}
+
+.ma-icon-oracle:before {
+  content: "\e7c8";
+}
+
+.ma-icon-event:before {
+  content: "\e664";
+}
+
+.ma-icon-sql-server:before {
+  content: "\e605";
+}
+
+.ma-icon-clickhouse:before {
+  content: "\ec35";
+}
+
 .ma-icon-todo:before {
   content: "\e602";
 }

BIN
magic-editor/src/console/src/assets/iconfont/iconfont.ttf


+ 1 - 1
magic-editor/src/console/src/components/layout/magic-debug.vue

@@ -16,7 +16,7 @@
         </tr>
         </thead>
         <tbody>
-        <tr v-if="variables.length == 0">
+        <tr v-if="variables.length === 0">
           <td align="center" colspan="3">no message.</td>
         </tr>
         <tr v-for="(item,key) in variables" :key="'debug_var_' + key">

+ 93 - 0
magic-editor/src/console/src/components/layout/magic-event.vue

@@ -0,0 +1,93 @@
+<template>
+  <div class="ma-event">
+    <div class="ma-layout">
+      <div class="not-select ma-sider">
+        <div @click="clearLog"><i class="ma-icon ma-icon-clear" /></div>
+      </div>
+      <div class="ma-layout-container">
+        <div class="ma-header ma-table-row">
+          <div>时间</div>
+          <div>事件内容</div>
+        </div>
+        <div class="ma-content">
+          <div v-for="(item, key) in eventList" :key="'event_' + key" class="ma-table-row content-bg">
+            <div>{{ item.timestamp }}</div>
+            <div>{{ item.content }}</div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import bus from '@/scripts/bus.js'
+export default {
+  name: 'MagicEvent',
+  data() {
+    return {
+      eventList: [],
+    }
+  },
+  mounted() {
+    this.init()
+  },
+  methods: {
+    init(){
+      this.eventList = bus.$getStatusLog();
+      bus.$on('status', ()=>{
+        this.$nextTick(()=> {
+          this.eventList = bus.$getStatusLog();
+        })
+      })
+      this.$forceUpdate()
+    },
+    clearLog(){
+      bus.$clearStatusLog()
+      this.$nextTick(()=> this.init())
+    }
+  }
+}
+</script>
+
+<style scoped>
+.ma-event {
+  background: var(--background);
+  height: 100%;
+  width: 100%;
+  position: relative;
+  outline: 0;
+}
+
+.ma-event .ma-layout {
+  height: 100%;
+}
+
+.ma-event .ma-layout .ma-content .content-bg span {
+  color: var(--toolbox-list-span-color);
+}
+
+.ma-event .ma-layout .ma-content .content-bg:nth-child(even) {
+  background: var(--table-even-background);
+}
+.ma-event .ma-layout .ma-content .content-bg:hover {
+  background: var(--toolbox-list-hover-background);
+}
+.ma-layout .ma-sider {
+  border: none;
+  border-right: 1px solid var(--tab-bar-border-color);
+}
+.ma-layout .ma-table-row{
+  display: flex;
+}
+.ma-layout .ma-table-row > * {
+  width: 150px !important;
+  background: none;
+  padding:0 2px;
+}
+
+.ma-layout .ma-table-row > *:last-child {
+  flex: 1;
+  width: auto;
+}
+</style>

+ 2 - 1
magic-editor/src/console/src/components/layout/magic-group.vue

@@ -160,10 +160,11 @@ export default {
       let saveObj = {...this.info}
       saveObj.paths =  saveObj.paths.filter(it => it.name)
       saveObj.options =  saveObj.options.filter(it => it.name)
+      bus.$emit('status', `准备保存分组「${saveObj.name}」`)
       requestGroup('group/update', saveObj).success(data => {
         bus.$emit('update-group')
         bus.$emit('report', 'group_update')
-        bus.$emit('status', '保存分组成功!')
+        bus.$emit('status', `保存分组「${saveObj.name}」成功!`)
       })
     },
     addRow() {

+ 7 - 0
magic-editor/src/console/src/components/layout/magic-header.vue

@@ -143,6 +143,7 @@ export default {
     doExport() {
       let selected = this.$refs.resourceExport.getSelected()
       if (selected.length > 0) {
+        bus.$emit('status', `准备导出全部数据`)
         request.send('/download', JSON.stringify(selected), {
           method: 'post',
           headers: {
@@ -152,6 +153,7 @@ export default {
           responseType: 'blob'
         }).success(blob => {
           downloadFile(blob, 'magic-api.zip')
+          bus.$emit('status', `全部数据已导出完毕`)
         });
       }
     },
@@ -169,6 +171,7 @@ export default {
     doPush(mode) {
       let selected = 'full' === mode ? [] : this.$refs.resourcePush.getSelected()
       let _push = () => {
+        bus.$emit('status', `准备${mode === 'full' ? '全量': '增量'}推送`)
         request.send('/push', JSON.stringify(selected), {
           method: 'post',
           headers: {
@@ -182,6 +185,7 @@ export default {
           this.$magicAlert({
             content: '推送成功!'
           })
+          bus.$emit('status', `${mode === 'full' ? '全量': '增量'}推送成功`)
           this.showPushDialog = false;
         })
       }
@@ -207,6 +211,7 @@ export default {
         formData.append('mode', mode);
         let _upload = () => {
           this.showUploadDialog = false;
+          bus.$emit('status', `准备${mode === 'full' ? '全量': '增量'}上传`)
           request.send('/upload', formData, {
             method: 'post',
             headers: {
@@ -216,6 +221,7 @@ export default {
             this.$magicAlert({
               content: '上传成功!'
             })
+            bus.$emit('status', `${mode === 'full' ? '全量': '增量'}上传成功`)
             bus.$emit('refresh-resource')
           })
           this.filename = '';
@@ -248,6 +254,7 @@ export default {
       this.$emit('update:themeStyle', this.themeStyle)
     },
     refresh() {
+      bus.$emit('status', `准备刷新资源`)
       request.send('refresh').success(() => {
         bus.$emit('refresh-resource')
         bus.$emit('status', `刷新资源成功`)

+ 3 - 0
magic-editor/src/console/src/components/layout/magic-login.vue

@@ -19,6 +19,7 @@ import MagicDialog from '@/components/common/modal/magic-dialog'
 import request from '@/api/request.js'
 import contants from '@/scripts/contants.js'
 import store from '@/scripts/store.js'
+import bus from "@/scripts/bus.js";
 
 export default {
   name: 'MagicLogin',
@@ -42,10 +43,12 @@ export default {
         password: this.password
       }).success((res, response) => {
         if (res) {
+          bus.$emit('status', '登录成功')
           contants.HEADER_MAGIC_TOKEN_VALUE = response.headers[contants.HEADER_MAGIC_TOKEN];
           store.set(contants.HEADER_MAGIC_TOKEN, contants.HEADER_MAGIC_TOKEN_VALUE);
           this.onLogin();
         } else {
+          bus.$emit('status', '登录失败')
           this.$magicAlert({
             title: '登录',
             content: '登录失败,用户名或密码不正确'

+ 9 - 7
magic-editor/src/console/src/components/layout/magic-options.vue

@@ -9,11 +9,8 @@
       </magic-bottom-panel>
     </div>
     <ul class="ma-bottom-tab not-select">
-      <li v-for="item in tabs" :key="'bottom_tab_' + item.id" :class="{ selected: selectedTab === item.id }"
-          @click="selectedTab = selectedTab === item.id ? null : item.id"><i :class="'ma-icon ma-icon-' + item.icon"/>{{
-          item.name
-        }}
-      </li>
+      <li v-for="item in tabs" :key="'bottom_tab_' + item.id" :class="{ selected: selectedTab === item.id, 'float-right': item.right }"
+          @click="selectedTab = selectedTab === item.id ? null : item.id"><i :class="'ma-icon ma-icon-' + item.icon"/>{{item.name}}</li>
     </ul>
   </div>
 </template>
@@ -29,6 +26,7 @@ import MagicLog from './magic-log.vue'
 import MagicSettings from './magic-settings.vue'
 import MagicFunction from './magic-function.vue'
 import MagicTodo from './magic-todo.vue'
+import MagicEvent from './magic-event.vue'
 import bus from '@/scripts/bus.js'
 
 export default {
@@ -55,7 +53,8 @@ export default {
       commonTabs: [
         {id: 'log', name: '运行日志', icon: 'log', component: MagicLog},
         {id: 'setting', name: '全局参数', icon: 'settings', component: MagicSettings},
-        {id: 'todo', name: 'TODO', icon: 'todo', component: MagicTodo}
+        {id: 'todo', name: 'TODO', icon: 'todo', component: MagicTodo},
+        {id: 'event', name: '事件', icon: 'event', component: MagicEvent, right: true}
       ]
     }
   },
@@ -157,11 +156,14 @@ export default {
 .ma-bottom-tab li {
   float: left;
   cursor: pointer;
-  padding: 0 10px;
+  padding: 0 8px;
   height: 24px;
   line-height: 24px;
   color: var(--color);
 }
+.ma-bottom-tab li.float-right{
+  float: right;
+}
 
 .ma-bottom-tab li i {
   color: var(--icon-color);

+ 3 - 0
magic-editor/src/console/src/components/layout/magic-status-bar.vue

@@ -45,6 +45,7 @@ export default {
   mounted() {
     bus.$on('status', (message) => this.message = message)
     bus.$on('login',() => {
+      bus.$emit('status', '获取当前登录用户信息')
       request.send('/user').success(user => this.user = user)
     })
   },
@@ -53,6 +54,7 @@ export default {
       window.open(url)
     },
     logout(){
+      bus.$emit('status', '准备注销登录')
       this.$magicConfirm({
         title: '注销登录',
         content: `是否要注销登录「${this.user.username}」`,
@@ -62,6 +64,7 @@ export default {
             contants.HEADER_MAGIC_TOKEN_VALUE = 'unauthorization';
             store.remove(contants.HEADER_MAGIC_TOKEN);
             bus.$emit('logout')
+            bus.$emit('status', '成功注销登录')
           })
         }
       })

+ 2 - 0
magic-editor/src/console/src/components/magic-editor.vue

@@ -264,8 +264,10 @@ export default {
     },
     async login() {
       contants.HEADER_MAGIC_TOKEN_VALUE = store.get(contants.HEADER_MAGIC_TOKEN) || contants.HEADER_MAGIC_TOKEN_VALUE
+      bus.$emit('status', '尝试自动登录')
       request.send('/login').success(isLogin => {
         if (isLogin) {
+          bus.$emit('status', '自动登录成功')
           this.onLogin()
         } else {
           this.showLogin = true

+ 16 - 1
magic-editor/src/console/src/components/resources/magic-api-list.vue

@@ -156,21 +156,25 @@ export default {
       this.changeForceUpdate()
     },
     open(item) {
+      bus.$emit('status', `查看接口「${item.name}(${item.path})」详情`)
       bus.$emit('open', item)
       this.currentFileItem = item
     },
     // 初始化数据
     initData() {
+      bus.$emit('status', '正在初始化接口列表')
       this.showLoading = true
       this.tree = []
       return new Promise((resolve) => {
         request.send('group/list?type=1').success(data => {
           this.listGroupData = data
+          bus.$emit('status', '接口分组加载完毕')
           request.send('list').success(data => {
             this.listChildrenData = data
             this.initTreeData()
             this.openItemById()
             this.showLoading = false
+            bus.$emit('status', '接口信息加载完毕')
             resolve()
           })
         })
@@ -365,6 +369,7 @@ export default {
             icon: 'ma-icon-move',
             onClick: () => {
               item.parentId = '0'
+              bus.$emit('status', `准备移动接口分组「${item.name}」至根节点`)
               requestGroup('group/update', item).success(data => {
                 bus.$emit('report', 'group_update')
                 // 先删除移动前的分组
@@ -374,6 +379,7 @@ export default {
                 this.rebuildTree()
                 this.initCreateGroupObj()
                 this.changeForceUpdate()
+                bus.$emit('status', `接口分组「${item.name}」已移动至根节点`)
               })
             }
           },
@@ -381,12 +387,16 @@ export default {
             label: '导出',
             icon: 'ma-icon-download',
             onClick: () => {
+              bus.$emit('status', `准备导出接口分组「${item.name}」相关接口`)
               request.send(`/download?groupId=${item.id}`,null,{
                 headers: {
                   'Content-Type': 'application/json'
                 },
                 responseType: 'blob'
-              }).success(blob => downloadFile(blob,`${item.name}.zip`))
+              }).success(blob => {
+                downloadFile(blob,`${item.name}.zip`)
+                bus.$emit('status', `接口分组「${item.name}」相关接口已导出`)
+              })
             }
           }
         ],
@@ -411,6 +421,7 @@ export default {
                 this.$magicAlert({content: '请先保存在复制!'})
                 return
               }
+              bus.$emit('status', `复制接口「${item.name}」`)
               let newItem = {
                 ...deepClone(item),
                 copy: true
@@ -722,6 +733,7 @@ export default {
               if (checkChildrenFolder(this.draggableItem.children) === false) {
                 let params = JSON.parse(JSON.stringify(this.draggableItem))
                 params.parentId = this.draggableTargetItem.id
+                bus.$emit('status', `准备移动接口分组「${params.name}」`)
                 requestGroup('group/update', params).success(data => {
                   bus.$emit('report', 'group_update')
                   // 先删除移动前的分组
@@ -731,6 +743,7 @@ export default {
                   this.rebuildTree()
                   this.initCreateGroupObj()
                   this.changeForceUpdate()
+                  bus.$emit('status', `接口分组「${params.name}」移动成功`)
                 })
               } else {
                 this.$magicAlert({content: `不能移到${this.draggableTargetItem.name}`})
@@ -739,6 +752,7 @@ export default {
               // 移动接口
               // 接口不能在目标分组的第一级children里
               if (this.draggableTargetItem.children.some(item => item.id === this.draggableItem.id) === false) {
+                bus.$emit('status', `准备移动接口「${this.draggableItem.name}」`)
                 request.send('api/move', {
                   id: this.draggableItem.id,
                   groupId: this.draggableTargetItem.id
@@ -751,6 +765,7 @@ export default {
                   this.rebuildTree()
                   this.initCreateGroupObj()
                   this.changeForceUpdate()
+                  bus.$emit('status', `接口「${this.draggableItem.name}」移动成功`)
                 })
               }
             }

+ 8 - 4
magic-editor/src/console/src/components/resources/magic-datasource-list.vue

@@ -17,7 +17,7 @@
       </div>
       <ul v-show="!showLoading">
         <template v-for="(item,index) in datasources" >
-        <li v-if="item._searchShow === true || item._searchShow === undefined" :key="index" @click="showDetail(item.id)" @contextmenu.prevent="e => datasourceContextMenu(e, item)">
+        <li v-if="item._searchShow === true || item._searchShow === undefined" :key="index" @click="showDetail(item)" @contextmenu.prevent="e => datasourceContextMenu(e, item)">
           <i class="ma-icon ma-icon-datasource"/>
           <label>{{item.name || '主数据源'}}</label>
           <span>({{item.key || 'default'}})</span>
@@ -165,6 +165,7 @@ export default {
     initData() {
       this.showLoading = true
       this.datasources = []
+      bus.$emit('status', '正在初始化数据源列表')
       return new Promise((resolve) => {
         request.send('datasource/list').success(data => {
           this.datasources = data;
@@ -178,19 +179,22 @@ export default {
           setTimeout(() => {
             this.showLoading = false
           }, 500)
+          bus.$emit('status', '数据源初始化完毕')
           resolve()
         })
       })
     },
-    showDetail(id){
-      if(!id){
+    showDetail(item){
+      if(!item.id){
         this.$magicAlert({
           content : '该数据源不能被修改'
         })
       }else{
-        request.send('datasource/detail',{id : id}).success(res => {
+        bus.$emit('status', `加载数据源「${item.name}」详情`)
+        request.send('datasource/detail',{id : item.id}).success(res => {
           this.datasourceObj = res;
           this.toogleDialog(true)
+          bus.$emit('status', `数据源「${item.name}」详情加载完毕`)
         });
       }
     },

+ 7 - 0
magic-editor/src/console/src/components/resources/magic-function-list.vue

@@ -160,20 +160,24 @@ export default {
     },
     open(item) {
       bus.$emit('open', item)
+      bus.$emit('status', `查看函数「${item.name}(${item.path})」详情`)
       this.currentFileItem = item
     },
     // 初始化数据
     initData() {
       this.showLoading = true
       this.tree = []
+      bus.$emit('status', '正在初始化函数列表')
       return new Promise((resolve) => {
         request.send('group/list?type=2').success(data => {
           this.listGroupData = data;
+          bus.$emit('status', '函数分组加载完毕')
           request.send('function/list').success(data => {
             this.listChildrenData = data
             this.initTreeData()
             this.openItemById()
             this.showLoading = false
+            bus.$emit('status', '函数信息加载完毕')
             resolve()
           })
         })
@@ -361,6 +365,7 @@ export default {
             icon: 'ma-icon-move',
             onClick: () => {
               item.parentId = '0'
+              bus.$emit('status', `准备移动函数分组「${item.name}」至根节点`)
               requestGroup('group/update', item).success(data => {
                 bus.$emit('report', 'group_update')
                 // 先删除移动前的分组
@@ -370,6 +375,7 @@ export default {
                 this.rebuildTree()
                 this.initCreateGroupObj()
                 this.changeForceUpdate()
+                bus.$emit('status', `函数分组「${item.name}」已移动至根节点`)
               })
             }
           }
@@ -395,6 +401,7 @@ export default {
                 this.$magicAlert({content: '请先保存在复制!'})
                 return
               }
+              bus.$emit('status', `复制函数「${item.name}」`)
               let newItem = {
                 ...deepClone(item),
                 copy: true

+ 10 - 1
magic-editor/src/console/src/scripts/bus.js

@@ -1,6 +1,7 @@
 import Vue from 'vue'
 import contants from './contants.js'
-
+import {formatDate} from "@/scripts/utils.js";
+const statusLog = [];
 const bus = new Vue()
 try {
     let element = document.createElement("script");
@@ -22,4 +23,12 @@ bus.$on('report', (eventId) => {
 
     }
 })
+bus.$on('status', (content) => {
+    statusLog.push({
+        timestamp: formatDate(new Date()),
+        content
+    })
+})
+bus.$getStatusLog = () => statusLog;
+bus.$clearStatusLog = () => statusLog.length = 0
 export default bus