mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 08:20:25 +08:00 
			
		
		
		
	feat: 新增linux文件上传成功后websocket通知
This commit is contained in:
		
							
								
								
									
										27
									
								
								base/ws/msg.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								base/ws/msg.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
package ws
 | 
			
		||||
 | 
			
		||||
const SuccessMsgType = 1
 | 
			
		||||
const ErrorMsgType = 0
 | 
			
		||||
const InfoMsgType = 2
 | 
			
		||||
 | 
			
		||||
// websocket消息
 | 
			
		||||
type Msg struct {
 | 
			
		||||
	Type  int    `json:"type"`  // 消息类型
 | 
			
		||||
	Title string `json:"title"` // 消息标题
 | 
			
		||||
	Msg   string `json:"msg"`   // 消息内容
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 普通消息
 | 
			
		||||
func NewMsg(title, msg string) *Msg {
 | 
			
		||||
	return &Msg{Type: InfoMsgType, Title: title, Msg: msg}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 成功消息
 | 
			
		||||
func SuccessMsg(title, msg string) *Msg {
 | 
			
		||||
	return &Msg{Type: SuccessMsgType, Title: title, Msg: msg}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 错误消息
 | 
			
		||||
func ErrMsg(title, msg string) *Msg {
 | 
			
		||||
	return &Msg{Type: ErrorMsgType, Title: title, Msg: msg}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										32
									
								
								base/ws/ws.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								base/ws/ws.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
package ws
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	"github.com/gorilla/websocket"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var Upgrader = websocket.Upgrader{
 | 
			
		||||
	ReadBufferSize:  1024,
 | 
			
		||||
	WriteBufferSize: 1024 * 1024 * 10,
 | 
			
		||||
	CheckOrigin: func(r *http.Request) bool {
 | 
			
		||||
		return true
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var conns = make(map[uint64]*websocket.Conn, 100)
 | 
			
		||||
 | 
			
		||||
// 放置ws连接
 | 
			
		||||
func Put(userId uint64, conn *websocket.Conn) {
 | 
			
		||||
	conns[userId] = conn
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 对指定用户发送消息
 | 
			
		||||
func SendMsg(userId uint64, msg *Msg) {
 | 
			
		||||
	conn := conns[userId]
 | 
			
		||||
	if conn != nil {
 | 
			
		||||
		bytes, _ := json.Marshal(msg)
 | 
			
		||||
		conn.WriteMessage(websocket.TextMessage, bytes)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								mayfly_go_web/src/common/SocketBuilder.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								mayfly_go_web/src/common/SocketBuilder.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
class SocketBuilder {
 | 
			
		||||
 | 
			
		||||
    websocket: WebSocket;
 | 
			
		||||
  
 | 
			
		||||
    constructor(url: string) {
 | 
			
		||||
      if (typeof (WebSocket) === "undefined") {
 | 
			
		||||
        throw new Error('不支持websocket');
 | 
			
		||||
      }
 | 
			
		||||
      if (!url) {
 | 
			
		||||
        throw new Error('websocket url不能为空');
 | 
			
		||||
      }
 | 
			
		||||
      console.log(url)
 | 
			
		||||
      this.websocket = new WebSocket(url);
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
    static builder(url: string) {
 | 
			
		||||
      return new SocketBuilder(url);
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
    open(onopen: any) {
 | 
			
		||||
      this.websocket.onopen = onopen;
 | 
			
		||||
      return this;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
    error(onerror: any) {
 | 
			
		||||
      this.websocket.onerror = onerror;
 | 
			
		||||
      return this;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
    message(onmessage: any) {
 | 
			
		||||
      this.websocket.onmessage = onmessage;
 | 
			
		||||
      return this;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
    close(onclose: any) {
 | 
			
		||||
      this.websocket.onclose = onclose;
 | 
			
		||||
      return this;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
    build() {
 | 
			
		||||
      return this.websocket;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  export default SocketBuilder;
 | 
			
		||||
  
 | 
			
		||||
							
								
								
									
										44
									
								
								mayfly_go_web/src/common/sockets.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								mayfly_go_web/src/common/sockets.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
 | 
			
		||||
import Config from './config'
 | 
			
		||||
import { ElNotification } from 'element-plus'
 | 
			
		||||
import SocketBuilder from './SocketBuilder';
 | 
			
		||||
import { getSession } from '@/common/utils/storage.ts';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    /**
 | 
			
		||||
     * 全局系统消息websocket
 | 
			
		||||
     */
 | 
			
		||||
    sysMsgSocket() {
 | 
			
		||||
        const token = getSession('token');
 | 
			
		||||
        if (!token) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        return SocketBuilder.builder(`${Config.baseWsUrl}/sysmsg?token=${token}`)
 | 
			
		||||
            .message((event: { data: string }) => {
 | 
			
		||||
                const message = JSON.parse(event.data);
 | 
			
		||||
                let mtype: string;
 | 
			
		||||
                switch (message.type) {
 | 
			
		||||
                    case 0:
 | 
			
		||||
                        mtype = 'error';
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 2:
 | 
			
		||||
                        mtype = 'info';
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 1:
 | 
			
		||||
                        mtype = 'success';
 | 
			
		||||
                        break;
 | 
			
		||||
                    default:
 | 
			
		||||
                        mtype = 'info';
 | 
			
		||||
                }
 | 
			
		||||
                if (mtype == undefined) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                ElNotification({
 | 
			
		||||
                    title: message.title,
 | 
			
		||||
                    message: message.msg,
 | 
			
		||||
                    type: mtype as any,
 | 
			
		||||
                })
 | 
			
		||||
            })
 | 
			
		||||
            .open((event: any) => console.log(event)).build();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -8,6 +8,7 @@ import { NextLoading } from '@/common/utils/loading.ts';
 | 
			
		||||
import { dynamicRoutes, staticRoutes, pathMatch } from './route.ts'
 | 
			
		||||
import { imports } from './imports';
 | 
			
		||||
import openApi from '@/common/openApi';
 | 
			
		||||
import sockets from '@/common/sockets';
 | 
			
		||||
 | 
			
		||||
// 添加静态路由
 | 
			
		||||
const router = createRouter({
 | 
			
		||||
@@ -203,6 +204,9 @@ if (!isRequestRoutes) {
 | 
			
		||||
    initBackEndControlRoutesFun();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
let SysWs: any;
 | 
			
		||||
 | 
			
		||||
// 路由加载前
 | 
			
		||||
router.beforeEach((to, from, next) => {
 | 
			
		||||
    NProgress.configure({ showSpinner: false });
 | 
			
		||||
@@ -223,10 +227,18 @@ router.beforeEach((to, from, next) => {
 | 
			
		||||
            clearSession();
 | 
			
		||||
            resetRoute();
 | 
			
		||||
            NProgress.done();
 | 
			
		||||
 | 
			
		||||
            if (SysWs) {
 | 
			
		||||
                SysWs.close();
 | 
			
		||||
                SysWs = null;
 | 
			
		||||
            }
 | 
			
		||||
        } else if (token && to.path === '/login') {
 | 
			
		||||
            next('/');
 | 
			
		||||
            NProgress.done();
 | 
			
		||||
        } else {
 | 
			
		||||
            if (!SysWs) {
 | 
			
		||||
                SysWs = sockets.sysMsgSocket();
 | 
			
		||||
            }
 | 
			
		||||
            if (store.state.routesList.routesList.length > 0) next();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -93,9 +93,9 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { toRefs, reactive, onMounted, nextTick, computed, getCurrentInstance } from 'vue';
 | 
			
		||||
import { toRefs, reactive, onMounted, nextTick, computed } from 'vue';
 | 
			
		||||
import { useStore } from '@/store/index.ts';
 | 
			
		||||
import * as echarts from 'echarts';
 | 
			
		||||
// import * as echarts from 'echarts';
 | 
			
		||||
import { CountUp } from 'countup.js';
 | 
			
		||||
import { formatAxis } from '@/common/utils/formatTime.ts';
 | 
			
		||||
import { indexApi } from './api';
 | 
			
		||||
@@ -103,7 +103,7 @@ import { topCardItemList, environmentList, activitiesList } from './mock.ts';
 | 
			
		||||
export default {
 | 
			
		||||
    name: 'Home',
 | 
			
		||||
    setup() {
 | 
			
		||||
        const { proxy } = getCurrentInstance() as any;
 | 
			
		||||
        // const { proxy } = getCurrentInstance() as any;
 | 
			
		||||
        const store = useStore();
 | 
			
		||||
        const state = reactive({
 | 
			
		||||
            topCardItemList,
 | 
			
		||||
@@ -146,104 +146,104 @@ export default {
 | 
			
		||||
            });
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // 实验室使用情况
 | 
			
		||||
        const initHomeLaboratory = () => {
 | 
			
		||||
            const myChart = echarts.init(proxy.$refs.homeLaboratoryRef);
 | 
			
		||||
            const option = {
 | 
			
		||||
                grid: {
 | 
			
		||||
                    top: 50,
 | 
			
		||||
                    right: 20,
 | 
			
		||||
                    bottom: 30,
 | 
			
		||||
                    left: 30,
 | 
			
		||||
                },
 | 
			
		||||
                tooltip: {
 | 
			
		||||
                    trigger: 'axis',
 | 
			
		||||
                },
 | 
			
		||||
                legend: {
 | 
			
		||||
                    data: ['预购队列', '最新成交价'],
 | 
			
		||||
                    right: 13,
 | 
			
		||||
                },
 | 
			
		||||
                xAxis: {
 | 
			
		||||
                    data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'],
 | 
			
		||||
                },
 | 
			
		||||
                yAxis: [
 | 
			
		||||
                    {
 | 
			
		||||
                        type: 'value',
 | 
			
		||||
                        name: '价格',
 | 
			
		||||
                    },
 | 
			
		||||
                ],
 | 
			
		||||
                series: [
 | 
			
		||||
                    {
 | 
			
		||||
                        name: '预购队列',
 | 
			
		||||
                        type: 'bar',
 | 
			
		||||
                        data: [5, 20, 36, 10, 10, 20],
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        name: '最新成交价',
 | 
			
		||||
                        type: 'line',
 | 
			
		||||
                        data: [15, 20, 16, 20, 30, 8],
 | 
			
		||||
                    },
 | 
			
		||||
                ],
 | 
			
		||||
            };
 | 
			
		||||
            myChart.setOption(option);
 | 
			
		||||
            window.addEventListener('resize', () => {
 | 
			
		||||
                myChart.resize();
 | 
			
		||||
            });
 | 
			
		||||
        };
 | 
			
		||||
        // 履约超时预警
 | 
			
		||||
        const initHomeOvertime = () => {
 | 
			
		||||
            const myChart = echarts.init(proxy.$refs.homeOvertimeRef);
 | 
			
		||||
            const option = {
 | 
			
		||||
                grid: {
 | 
			
		||||
                    top: 50,
 | 
			
		||||
                    right: 20,
 | 
			
		||||
                    bottom: 30,
 | 
			
		||||
                    left: 30,
 | 
			
		||||
                },
 | 
			
		||||
                tooltip: {
 | 
			
		||||
                    trigger: 'axis',
 | 
			
		||||
                },
 | 
			
		||||
                legend: {
 | 
			
		||||
                    data: ['订单数量', '超时数量', '在线数量', '预警数量'],
 | 
			
		||||
                    right: 13,
 | 
			
		||||
                },
 | 
			
		||||
                xAxis: {
 | 
			
		||||
                    data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
 | 
			
		||||
                },
 | 
			
		||||
                yAxis: [
 | 
			
		||||
                    {
 | 
			
		||||
                        type: 'value',
 | 
			
		||||
                        name: '数量',
 | 
			
		||||
                    },
 | 
			
		||||
                ],
 | 
			
		||||
                series: [
 | 
			
		||||
                    {
 | 
			
		||||
                        name: '订单数量',
 | 
			
		||||
                        type: 'bar',
 | 
			
		||||
                        data: [5, 20, 36, 10, 10, 20, 11, 13, 10, 9, 17, 19],
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        name: '超时数量',
 | 
			
		||||
                        type: 'bar',
 | 
			
		||||
                        data: [15, 12, 26, 15, 11, 16, 31, 13, 5, 16, 13, 15],
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        name: '在线数量',
 | 
			
		||||
                        type: 'line',
 | 
			
		||||
                        data: [15, 20, 16, 20, 30, 8, 16, 19, 12, 18, 19, 14],
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        name: '预警数量',
 | 
			
		||||
                        type: 'line',
 | 
			
		||||
                        data: [10, 10, 13, 12, 15, 18, 19, 10, 12, 15, 11, 17],
 | 
			
		||||
                    },
 | 
			
		||||
                ],
 | 
			
		||||
            };
 | 
			
		||||
            myChart.setOption(option);
 | 
			
		||||
            window.addEventListener('resize', () => {
 | 
			
		||||
                myChart.resize();
 | 
			
		||||
            });
 | 
			
		||||
        };
 | 
			
		||||
        // // 实验室使用情况
 | 
			
		||||
        // const initHomeLaboratory = () => {
 | 
			
		||||
        //     const myChart = echarts.init(proxy.$refs.homeLaboratoryRef);
 | 
			
		||||
        //     const option = {
 | 
			
		||||
        //         grid: {
 | 
			
		||||
        //             top: 50,
 | 
			
		||||
        //             right: 20,
 | 
			
		||||
        //             bottom: 30,
 | 
			
		||||
        //             left: 30,
 | 
			
		||||
        //         },
 | 
			
		||||
        //         tooltip: {
 | 
			
		||||
        //             trigger: 'axis',
 | 
			
		||||
        //         },
 | 
			
		||||
        //         legend: {
 | 
			
		||||
        //             data: ['预购队列', '最新成交价'],
 | 
			
		||||
        //             right: 13,
 | 
			
		||||
        //         },
 | 
			
		||||
        //         xAxis: {
 | 
			
		||||
        //             data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'],
 | 
			
		||||
        //         },
 | 
			
		||||
        //         yAxis: [
 | 
			
		||||
        //             {
 | 
			
		||||
        //                 type: 'value',
 | 
			
		||||
        //                 name: '价格',
 | 
			
		||||
        //             },
 | 
			
		||||
        //         ],
 | 
			
		||||
        //         series: [
 | 
			
		||||
        //             {
 | 
			
		||||
        //                 name: '预购队列',
 | 
			
		||||
        //                 type: 'bar',
 | 
			
		||||
        //                 data: [5, 20, 36, 10, 10, 20],
 | 
			
		||||
        //             },
 | 
			
		||||
        //             {
 | 
			
		||||
        //                 name: '最新成交价',
 | 
			
		||||
        //                 type: 'line',
 | 
			
		||||
        //                 data: [15, 20, 16, 20, 30, 8],
 | 
			
		||||
        //             },
 | 
			
		||||
        //         ],
 | 
			
		||||
        //     };
 | 
			
		||||
        //     myChart.setOption(option);
 | 
			
		||||
        //     window.addEventListener('resize', () => {
 | 
			
		||||
        //         myChart.resize();
 | 
			
		||||
        //     });
 | 
			
		||||
        // };
 | 
			
		||||
        // // 履约超时预警
 | 
			
		||||
        // const initHomeOvertime = () => {
 | 
			
		||||
        //     const myChart = echarts.init(proxy.$refs.homeOvertimeRef);
 | 
			
		||||
        //     const option = {
 | 
			
		||||
        //         grid: {
 | 
			
		||||
        //             top: 50,
 | 
			
		||||
        //             right: 20,
 | 
			
		||||
        //             bottom: 30,
 | 
			
		||||
        //             left: 30,
 | 
			
		||||
        //         },
 | 
			
		||||
        //         tooltip: {
 | 
			
		||||
        //             trigger: 'axis',
 | 
			
		||||
        //         },
 | 
			
		||||
        //         legend: {
 | 
			
		||||
        //             data: ['订单数量', '超时数量', '在线数量', '预警数量'],
 | 
			
		||||
        //             right: 13,
 | 
			
		||||
        //         },
 | 
			
		||||
        //         xAxis: {
 | 
			
		||||
        //             data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
 | 
			
		||||
        //         },
 | 
			
		||||
        //         yAxis: [
 | 
			
		||||
        //             {
 | 
			
		||||
        //                 type: 'value',
 | 
			
		||||
        //                 name: '数量',
 | 
			
		||||
        //             },
 | 
			
		||||
        //         ],
 | 
			
		||||
        //         series: [
 | 
			
		||||
        //             {
 | 
			
		||||
        //                 name: '订单数量',
 | 
			
		||||
        //                 type: 'bar',
 | 
			
		||||
        //                 data: [5, 20, 36, 10, 10, 20, 11, 13, 10, 9, 17, 19],
 | 
			
		||||
        //             },
 | 
			
		||||
        //             {
 | 
			
		||||
        //                 name: '超时数量',
 | 
			
		||||
        //                 type: 'bar',
 | 
			
		||||
        //                 data: [15, 12, 26, 15, 11, 16, 31, 13, 5, 16, 13, 15],
 | 
			
		||||
        //             },
 | 
			
		||||
        //             {
 | 
			
		||||
        //                 name: '在线数量',
 | 
			
		||||
        //                 type: 'line',
 | 
			
		||||
        //                 data: [15, 20, 16, 20, 30, 8, 16, 19, 12, 18, 19, 14],
 | 
			
		||||
        //             },
 | 
			
		||||
        //             {
 | 
			
		||||
        //                 name: '预警数量',
 | 
			
		||||
        //                 type: 'line',
 | 
			
		||||
        //                 data: [10, 10, 13, 12, 15, 18, 19, 10, 12, 15, 11, 17],
 | 
			
		||||
        //             },
 | 
			
		||||
        //         ],
 | 
			
		||||
        //     };
 | 
			
		||||
        //     myChart.setOption(option);
 | 
			
		||||
        //     window.addEventListener('resize', () => {
 | 
			
		||||
        //         myChart.resize();
 | 
			
		||||
        //     });
 | 
			
		||||
        // };
 | 
			
		||||
        // 页面加载时
 | 
			
		||||
        onMounted(() => {
 | 
			
		||||
            initNumCountUp();
 | 
			
		||||
 
 | 
			
		||||
@@ -451,9 +451,7 @@ export default defineComponent({
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        const uploadSuccess = (res: any) => {
 | 
			
		||||
            if (res.code == 200) {
 | 
			
		||||
                ElMessage.success('文件上传中...');
 | 
			
		||||
            } else {
 | 
			
		||||
            if (res.code !== 200) {
 | 
			
		||||
                ElMessage.error(res.msg);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 
 | 
			
		||||
@@ -217,6 +217,9 @@ export default {
 | 
			
		||||
            if (type == 1) {
 | 
			
		||||
                return '登录';
 | 
			
		||||
            }
 | 
			
		||||
            if (type == 2) {
 | 
			
		||||
                return '通知';
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,26 +5,18 @@ import (
 | 
			
		||||
	"mayfly-go/base/ctx"
 | 
			
		||||
	"mayfly-go/base/ginx"
 | 
			
		||||
	"mayfly-go/base/utils"
 | 
			
		||||
	"mayfly-go/base/ws"
 | 
			
		||||
	"mayfly-go/server/devops/api/form"
 | 
			
		||||
	"mayfly-go/server/devops/api/vo"
 | 
			
		||||
	"mayfly-go/server/devops/application"
 | 
			
		||||
	"mayfly-go/server/devops/domain/entity"
 | 
			
		||||
	"mayfly-go/server/devops/infrastructure/machine"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"github.com/gorilla/websocket"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var WsUpgrader = websocket.Upgrader{
 | 
			
		||||
	ReadBufferSize:  1024,
 | 
			
		||||
	WriteBufferSize: 1024 * 1024 * 10,
 | 
			
		||||
	CheckOrigin: func(r *http.Request) bool {
 | 
			
		||||
		return true
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Machine struct {
 | 
			
		||||
	MachineApp application.Machine
 | 
			
		||||
}
 | 
			
		||||
@@ -62,7 +54,7 @@ func (m *Machine) CloseCli(rc *ctx.ReqCtx) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *Machine) WsSSH(g *gin.Context) {
 | 
			
		||||
	wsConn, err := WsUpgrader.Upgrade(g.Writer, g.Request, nil)
 | 
			
		||||
	wsConn, err := ws.Upgrader.Upgrade(g.Writer, g.Request, nil)
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if err := recover(); err != nil {
 | 
			
		||||
			wsConn.WriteMessage(websocket.TextMessage, []byte(err.(error).Error()))
 | 
			
		||||
@@ -79,9 +71,9 @@ func (m *Machine) WsSSH(g *gin.Context) {
 | 
			
		||||
		panic(biz.NewBizErr("没有权限"))
 | 
			
		||||
	}
 | 
			
		||||
	// 演示环境禁止非admin用户执行
 | 
			
		||||
	if rc.LoginAccount.Username != "admin" {
 | 
			
		||||
		panic(biz.NewBizErrCode(401, "非admin用户无权该操作"))
 | 
			
		||||
	}
 | 
			
		||||
	// if rc.LoginAccount.Username != "admin" {
 | 
			
		||||
	// 	panic(biz.NewBizErrCode(401, "非admin用户无权该操作"))
 | 
			
		||||
	// }
 | 
			
		||||
 | 
			
		||||
	cols := ginx.QueryInt(g, "cols", 80)
 | 
			
		||||
	rows := ginx.QueryInt(g, "rows", 40)
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ import (
 | 
			
		||||
	"mayfly-go/base/ctx"
 | 
			
		||||
	"mayfly-go/base/ginx"
 | 
			
		||||
	"mayfly-go/base/utils"
 | 
			
		||||
	"mayfly-go/base/ws"
 | 
			
		||||
	"mayfly-go/server/devops/api/form"
 | 
			
		||||
	"mayfly-go/server/devops/api/vo"
 | 
			
		||||
	"mayfly-go/server/devops/application"
 | 
			
		||||
@@ -121,10 +122,12 @@ func (m *MachineFile) UploadFile(rc *ctx.ReqCtx) {
 | 
			
		||||
	path := g.PostForm("path")
 | 
			
		||||
	fileheader, err := g.FormFile("file")
 | 
			
		||||
	biz.ErrIsNilAppendErr(err, "读取文件失败: %s")
 | 
			
		||||
	// 通知正在上传
 | 
			
		||||
	ws.SendMsg(rc.LoginAccount.Id, ws.NewMsg("文件上传", "文件上传中..."))
 | 
			
		||||
 | 
			
		||||
	file, _ := fileheader.Open()
 | 
			
		||||
	bytes, err := ioutil.ReadAll(file)
 | 
			
		||||
	go m.MachineFileApp.UploadFile(fid, path, fileheader.Filename, bytes)
 | 
			
		||||
	bytes, _ := ioutil.ReadAll(file)
 | 
			
		||||
	go m.MachineFileApp.UploadFile(rc.LoginAccount, fid, path, fileheader.Filename, bytes)
 | 
			
		||||
 | 
			
		||||
	rc.ReqParam = fmt.Sprintf("path: %s", path)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,17 @@
 | 
			
		||||
package application
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/fs"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"mayfly-go/base/biz"
 | 
			
		||||
	"mayfly-go/base/model"
 | 
			
		||||
	"mayfly-go/base/ws"
 | 
			
		||||
	"mayfly-go/server/devops/domain/entity"
 | 
			
		||||
	"mayfly-go/server/devops/domain/repository"
 | 
			
		||||
	"mayfly-go/server/devops/infrastructure/persistence"
 | 
			
		||||
	sysApplication "mayfly-go/server/sys/application"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
@@ -41,7 +44,7 @@ type MachineFile interface {
 | 
			
		||||
	WriteFileContent(fileId uint64, path string, content []byte)
 | 
			
		||||
 | 
			
		||||
	// 文件上传
 | 
			
		||||
	UploadFile(fileId uint64, path, filename string, content []byte)
 | 
			
		||||
	UploadFile(la *model.LoginAccount, fileId uint64, path, filename string, content []byte)
 | 
			
		||||
 | 
			
		||||
	// 移除文件
 | 
			
		||||
	RemoveFile(fileId uint64, path string)
 | 
			
		||||
@@ -50,12 +53,14 @@ type MachineFile interface {
 | 
			
		||||
type machineFileAppImpl struct {
 | 
			
		||||
	machineFileRepo repository.MachineFile
 | 
			
		||||
	machineRepo     repository.Machine
 | 
			
		||||
	msgApp          sysApplication.Msg
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 实现类单例
 | 
			
		||||
var MachineFileApp MachineFile = &machineFileAppImpl{
 | 
			
		||||
	machineRepo:     persistence.MachineDao,
 | 
			
		||||
	machineFileRepo: persistence.MachineFileDao,
 | 
			
		||||
	msgApp:          sysApplication.MsgApp,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 分页获取机器脚本信息列表
 | 
			
		||||
@@ -133,7 +138,7 @@ func (m *machineFileAppImpl) WriteFileContent(fileId uint64, path string, conten
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 上传文件
 | 
			
		||||
func (m *machineFileAppImpl) UploadFile(fileId uint64, path, filename string, content []byte) {
 | 
			
		||||
func (m *machineFileAppImpl) UploadFile(la *model.LoginAccount, fileId uint64, path, filename string, content []byte) {
 | 
			
		||||
	path, machineId := m.checkAndReturnPathMid(fileId, path)
 | 
			
		||||
	if !strings.HasSuffix(path, "/") {
 | 
			
		||||
		path = path + "/"
 | 
			
		||||
@@ -145,6 +150,9 @@ func (m *machineFileAppImpl) UploadFile(fileId uint64, path, filename string, co
 | 
			
		||||
	defer createfile.Close()
 | 
			
		||||
 | 
			
		||||
	createfile.Write(content)
 | 
			
		||||
	// 保存消息并发送文件上传成功通知
 | 
			
		||||
	m.msgApp.CreateAndSend(la, ws.SuccessMsg("文件上传", fmt.Sprintf("[%s]文件已成功上传至[%s]", filename, path)))
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 删除文件
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package routers
 | 
			
		||||
package router
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"mayfly-go/base/ctx"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package routers
 | 
			
		||||
package router
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"mayfly-go/base/ctx"
 | 
			
		||||
@@ -10,31 +10,31 @@ import (
 | 
			
		||||
 | 
			
		||||
func InitMachineRouter(router *gin.RouterGroup) {
 | 
			
		||||
	m := &api.Machine{MachineApp: application.MachineApp}
 | 
			
		||||
	db := router.Group("machines")
 | 
			
		||||
	machines := router.Group("machines")
 | 
			
		||||
	{
 | 
			
		||||
		db.GET("", func(c *gin.Context) {
 | 
			
		||||
		machines.GET("", func(c *gin.Context) {
 | 
			
		||||
			ctx.NewReqCtxWithGin(c).Handle(m.Machines)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		saveMachine := ctx.NewLogInfo("保存机器信息")
 | 
			
		||||
		db.POST("", func(c *gin.Context) {
 | 
			
		||||
		machines.POST("", func(c *gin.Context) {
 | 
			
		||||
			ctx.NewReqCtxWithGin(c).
 | 
			
		||||
				WithLog(saveMachine).
 | 
			
		||||
				Handle(m.SaveMachine)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		delMachine := ctx.NewLogInfo("删除机器")
 | 
			
		||||
		db.DELETE(":machineId", func(c *gin.Context) {
 | 
			
		||||
		machines.DELETE(":machineId", func(c *gin.Context) {
 | 
			
		||||
			ctx.NewReqCtxWithGin(c).
 | 
			
		||||
				WithLog(delMachine).
 | 
			
		||||
				Handle(m.DeleteMachine)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		closeCli := ctx.NewLogInfo("关闭机器客户端")
 | 
			
		||||
		db.DELETE(":machineId/close-cli", func(c *gin.Context) {
 | 
			
		||||
		machines.DELETE(":machineId/close-cli", func(c *gin.Context) {
 | 
			
		||||
			ctx.NewReqCtxWithGin(c).WithLog(closeCli).Handle(m.CloseCli)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		db.GET(":machineId/terminal", m.WsSSH)
 | 
			
		||||
		machines.GET(":machineId/terminal", m.WsSSH)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package routers
 | 
			
		||||
package router
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"mayfly-go/base/ctx"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package routers
 | 
			
		||||
package router
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"mayfly-go/base/ctx"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package routers
 | 
			
		||||
package router
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"mayfly-go/base/ctx"
 | 
			
		||||
@@ -49,7 +49,7 @@ func InitProjectRouter(router *gin.RouterGroup) {
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		saveProjectEnvLog := ctx.NewLogInfo("新增项目环境信息")
 | 
			
		||||
		savePeP := ctx.NewPermission("project:env:save")
 | 
			
		||||
		savePeP := ctx.NewPermission("project:env:add")
 | 
			
		||||
		// 保存项目下的环境信息
 | 
			
		||||
		project.POST("/:projectId/envs", func(c *gin.Context) {
 | 
			
		||||
			ctx.NewReqCtxWithGin(c).WithLog(saveProjectEnvLog).
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package routers
 | 
			
		||||
package router
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"mayfly-go/base/ctx"
 | 
			
		||||
 
 | 
			
		||||
@@ -53,6 +53,7 @@ func InitRouter() *gin.Engine {
 | 
			
		||||
		sys_router.InitAccountRouter(api) // 注册account路由
 | 
			
		||||
		sys_router.InitResourceRouter(api)
 | 
			
		||||
		sys_router.InitRoleRouter(api)
 | 
			
		||||
		sys_router.InitSystemRouter(api)
 | 
			
		||||
 | 
			
		||||
		devops_router.InitProjectRouter(api)
 | 
			
		||||
		devops_router.InitDbRouter(api)
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,6 @@ import (
 | 
			
		||||
	"mayfly-go/base/captcha"
 | 
			
		||||
	"mayfly-go/base/ctx"
 | 
			
		||||
	"mayfly-go/base/ginx"
 | 
			
		||||
	"mayfly-go/base/global"
 | 
			
		||||
	"mayfly-go/base/httpclient"
 | 
			
		||||
	"mayfly-go/base/utils"
 | 
			
		||||
	"mayfly-go/server/sys/api/form"
 | 
			
		||||
	"mayfly-go/server/sys/api/vo"
 | 
			
		||||
@@ -89,16 +87,16 @@ func (a *Account) saveLogin(account *entity.Account, ip string) {
 | 
			
		||||
	loginMsg.CreatorId = account.Id
 | 
			
		||||
	a.MsgApp.Create(loginMsg)
 | 
			
		||||
 | 
			
		||||
	bodyMap, err := httpclient.NewRequest(fmt.Sprintf("http://ip-api.com/json/%s?lang=zh-CN", ip)).Get().BodyToMap()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		global.Log.Errorf("获取客户端ip地址信息失败:%s", err.Error())
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if bodyMap["status"].(string) == "fail" {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	msg := fmt.Sprintf("%s于%s-%s登录", account.Username, bodyMap["regionName"], bodyMap["city"])
 | 
			
		||||
	global.Log.Info(msg)
 | 
			
		||||
	// bodyMap, err := httpclient.NewRequest(fmt.Sprintf("http://ip-api.com/json/%s?lang=zh-CN", ip)).Get().BodyToMap()
 | 
			
		||||
	// if err != nil {
 | 
			
		||||
	// 	global.Log.Errorf("获取客户端ip地址信息失败:%s", err.Error())
 | 
			
		||||
	// 	return
 | 
			
		||||
	// }
 | 
			
		||||
	// if bodyMap["status"].(string) == "fail" {
 | 
			
		||||
	// 	return
 | 
			
		||||
	// }
 | 
			
		||||
	// msg := fmt.Sprintf("%s于%s-%s登录", account.Username, bodyMap["regionName"], bodyMap["city"])
 | 
			
		||||
	// global.Log.Info(msg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获取个人账号信息
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								server/sys/api/system.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								server/sys/api/system.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
package api
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"mayfly-go/base/biz"
 | 
			
		||||
	"mayfly-go/base/ctx"
 | 
			
		||||
	"mayfly-go/base/ws"
 | 
			
		||||
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"github.com/gorilla/websocket"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type System struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 连接websocket
 | 
			
		||||
func (s *System) ConnectWs(g *gin.Context) {
 | 
			
		||||
	wsConn, err := ws.Upgrader.Upgrade(g.Writer, g.Request, nil)
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if err := recover(); err != nil {
 | 
			
		||||
			wsConn.WriteMessage(websocket.TextMessage, []byte(err.(error).Error()))
 | 
			
		||||
			wsConn.Close()
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(biz.NewBizErr("升级websocket失败"))
 | 
			
		||||
	}
 | 
			
		||||
	// 权限校验
 | 
			
		||||
	rc := ctx.NewReqCtxWithGin(g)
 | 
			
		||||
	if err = ctx.PermissionHandler(rc); err != nil {
 | 
			
		||||
		panic(biz.NewBizErr("没有权限"))
 | 
			
		||||
	}
 | 
			
		||||
	// 登录账号信息
 | 
			
		||||
	la := rc.LoginAccount
 | 
			
		||||
	ws.Put(la.Id, wsConn)
 | 
			
		||||
}
 | 
			
		||||
@@ -2,15 +2,20 @@ package application
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"mayfly-go/base/model"
 | 
			
		||||
	"mayfly-go/base/ws"
 | 
			
		||||
	"mayfly-go/server/sys/domain/entity"
 | 
			
		||||
	"mayfly-go/server/sys/domain/repository"
 | 
			
		||||
	"mayfly-go/server/sys/infrastructure/persistence"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Msg interface {
 | 
			
		||||
	GetPageList(condition *entity.Msg, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
 | 
			
		||||
 | 
			
		||||
	Create(msg *entity.Msg)
 | 
			
		||||
 | 
			
		||||
	// 创建消息,并通过ws发送
 | 
			
		||||
	CreateAndSend(la *model.LoginAccount, msg *ws.Msg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type msgAppImpl struct {
 | 
			
		||||
@@ -28,3 +33,10 @@ func (a *msgAppImpl) GetPageList(condition *entity.Msg, pageParam *model.PagePar
 | 
			
		||||
func (a *msgAppImpl) Create(msg *entity.Msg) {
 | 
			
		||||
	a.msgRepo.Insert(msg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *msgAppImpl) CreateAndSend(la *model.LoginAccount, wmsg *ws.Msg) {
 | 
			
		||||
	now := time.Now()
 | 
			
		||||
	msg := &entity.Msg{Type: 2, Msg: wmsg.Msg, RecipientId: int64(la.Id), CreateTime: &now, CreatorId: la.Id, Creator: la.Username}
 | 
			
		||||
	a.msgRepo.Insert(msg)
 | 
			
		||||
	ws.SendMsg(la.Id, wmsg)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package routers
 | 
			
		||||
package router
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"mayfly-go/base/ctx"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package routers
 | 
			
		||||
package router
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"mayfly-go/base/ctx"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package routers
 | 
			
		||||
package router
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"mayfly-go/base/ctx"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package routers
 | 
			
		||||
package router
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"mayfly-go/base/ctx"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								server/sys/router/system.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								server/sys/router/system.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
package router
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"mayfly-go/server/sys/api"
 | 
			
		||||
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func InitSystemRouter(router *gin.RouterGroup) {
 | 
			
		||||
	s := &api.System{}
 | 
			
		||||
	sys := router.Group("sysmsg")
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		sys.GET("", s.ConnectWs)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user