From 348074670e5e78119e3989deb8fe4fafebfd89a8 Mon Sep 17 00:00:00 2001 From: dushixiang Date: Wed, 23 Dec 2020 21:56:19 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=BD=95=E5=B1=8F=E5=92=8C?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=E9=85=8D=E7=BD=AE=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/api/property.go | 2 +- pkg/api/session.go | 2 +- pkg/api/tunnel.go | 37 +- pkg/guacd/guacd.go | 25 + pkg/handle/runner.go | 102 +++-- pkg/model/property.go | 42 +- pkg/model/session.go | 4 +- web/src/App.js | 4 +- web/src/components/Login.js | 2 +- web/src/components/session/OfflineSession.js | 15 +- web/src/components/session/Playback.js | 258 +++++------ web/src/components/setting/Setting.js | 459 ++++++++++++------- 12 files changed, 569 insertions(+), 383 deletions(-) diff --git a/pkg/api/property.go b/pkg/api/property.go index 264d817..4a0916f 100644 --- a/pkg/api/property.go +++ b/pkg/api/property.go @@ -7,7 +7,7 @@ import ( ) func PropertyGetEndpoint(c echo.Context) error { - properties := model.FindAllTemp() + properties := model.FindAllPropertiesMap() return Success(c, properties) } diff --git a/pkg/api/session.go b/pkg/api/session.go index 9ca563e..ed7282c 100644 --- a/pkg/api/session.go +++ b/pkg/api/session.go @@ -43,7 +43,7 @@ func SessionDeleteEndpoint(c echo.Context) error { split := strings.Split(sessionIds, ",") for i := range split { model.DeleteSessionById(split[i]) - drivePath, err := model.GetDrivePath() + drivePath, err := model.GetRecordingPath() if err != nil { continue } diff --git a/pkg/api/tunnel.go b/pkg/api/tunnel.go index a0d2886..ae68ee4 100644 --- a/pkg/api/tunnel.go +++ b/pkg/api/tunnel.go @@ -1,14 +1,15 @@ package api import ( - "next-terminal/pkg/config" - "next-terminal/pkg/guacd" - "next-terminal/pkg/model" "fmt" "github.com/gorilla/websocket" "github.com/labstack/echo/v4" "github.com/pkg/sftp" "log" + "next-terminal/pkg/config" + "next-terminal/pkg/guacd" + "next-terminal/pkg/model" + "path" "strconv" ) @@ -33,17 +34,6 @@ func TunEndpoint(c echo.Context) error { propertyMap := model.FindAllPropertiesMap() - for name := range propertyMap { - - if name == model.GuacdFontSize { - fontSize, _ := strconv.Atoi(propertyMap[name]) - fontSize = fontSize * 2 - configuration.SetParameter(name, strconv.Itoa(fontSize)) - } else { - configuration.SetParameter(name, propertyMap[name]) - } - } - var session model.Session var sftpClient *sftp.Client @@ -59,6 +49,22 @@ func TunEndpoint(c echo.Context) error { return err } + for name := range propertyMap { + if name == guacd.FontSize { + fontSize, _ := strconv.Atoi(propertyMap[name]) + fontSize = fontSize * 2 + configuration.SetParameter(name, strconv.Itoa(fontSize)) + } else { + configuration.SetParameter(name, propertyMap[name]) + } + } + + if propertyMap[guacd.EnableRecording] == "true" { + configuration.SetParameter(guacd.CreateRecordingPath, path.Join(propertyMap[guacd.CreateRecordingPath], sessionId)) + } else { + configuration.SetParameter(guacd.CreateRecordingPath, "") + } + configuration.Protocol = session.Protocol switch configuration.Protocol { case "rdp": @@ -97,7 +103,7 @@ func TunEndpoint(c echo.Context) error { configuration.SetParameter("port", strconv.Itoa(session.Port)) } - addr := propertyMap[model.GuacdHost] + ":" + propertyMap[model.GuacdPort] + addr := propertyMap[guacd.Host] + ":" + propertyMap[guacd.Port] tunnel, err := guacd.NewTunnel(addr, configuration) if err != nil { return err @@ -118,6 +124,7 @@ func TunEndpoint(c echo.Context) error { session.ConnectionId = tunnel.UUID session.Width = intWidth session.Height = intHeight + session.Recording = configuration.GetParameter(guacd.RecordingPath) model.UpdateSessionById(&session, sessionId) } diff --git a/pkg/guacd/guacd.go b/pkg/guacd/guacd.go index 9f8215e..52a49a3 100644 --- a/pkg/guacd/guacd.go +++ b/pkg/guacd/guacd.go @@ -8,6 +8,31 @@ import ( "strings" ) +const ( + Host = "host" + Port = "port" + EnableRecording = "enable-recording" + RecordingPath = "recording-path" + CreateRecordingPath = "create-recording-path" + + FontName = "font-name" + FontSize = "font-size" + ColorScheme = "color-scheme" + + EnableDrive = "enable-drive" + DriveName = "drive-name" + DrivePath = "drive-path" + EnableWallpaper = "enable-wallpaper" + EnableTheming = "enable-theming" + EnableFontSmoothing = "enable-font-smoothing" + EnableFullWindowDrag = "enable-full-window-drag" + EnableDesktopComposition = "enable-desktop-composition" + EnableMenuAnimations = "enable-menu-animations" + DisableBitmapCaching = "disable-bitmap-caching" + DisableOffscreenCaching = "disable-offscreen-caching" + DisableGlyphCaching = "disable-glyph-caching" +) + const Delimiter = ';' const Version = "VERSION_1_1_0" diff --git a/pkg/handle/runner.go b/pkg/handle/runner.go index 1c27dd2..4772378 100644 --- a/pkg/handle/runner.go +++ b/pkg/handle/runner.go @@ -1,6 +1,7 @@ package handle import ( + "next-terminal/pkg/guacd" "next-terminal/pkg/model" "next-terminal/pkg/utils" "os" @@ -50,148 +51,165 @@ func RunDataFix() { func InitProperties() { propertyMap := model.FindAllPropertiesMap() - if len(propertyMap[model.GuacdHost]) == 0 { + if len(propertyMap[guacd.Host]) == 0 { property := model.Property{ - Name: model.GuacdHost, + Name: guacd.Host, Value: "127.0.0.1", } _ = model.CreateNewProperty(&property) } - if len(propertyMap[model.GuacdPort]) == 0 { + if len(propertyMap[guacd.Port]) == 0 { property := model.Property{ - Name: model.GuacdPort, + Name: guacd.Port, Value: "4822", } _ = model.CreateNewProperty(&property) } - if len(propertyMap[model.GuacdDriveName]) == 0 { + if len(propertyMap[guacd.EnableRecording]) == 0 { property := model.Property{ - Name: model.GuacdDriveName, + Name: guacd.EnableRecording, + Value: "true", + } + _ = model.CreateNewProperty(&property) + } + + if len(propertyMap[guacd.RecordingPath]) == 0 { + path, _ := os.Getwd() + property := model.Property{ + Name: guacd.RecordingPath, + Value: path + "/recording/", + } + _ = model.CreateNewProperty(&property) + } + + if len(propertyMap[guacd.CreateRecordingPath]) == 0 { + property := model.Property{ + Name: guacd.CreateRecordingPath, + Value: "true", + } + _ = model.CreateNewProperty(&property) + } + + if len(propertyMap[guacd.DriveName]) == 0 { + property := model.Property{ + Name: guacd.DriveName, Value: "File-System", } _ = model.CreateNewProperty(&property) } - if len(propertyMap[model.GuacdDrivePath]) == 0 { + if len(propertyMap[guacd.DrivePath]) == 0 { path, _ := os.Getwd() property := model.Property{ - Name: model.GuacdDrivePath, + Name: guacd.DrivePath, Value: path + "/drive/", } _ = model.CreateNewProperty(&property) } - if len(propertyMap[model.GuacdFontName]) == 0 { + if len(propertyMap[guacd.FontName]) == 0 { property := model.Property{ - Name: model.GuacdFontName, + Name: guacd.FontName, Value: "menlo", } _ = model.CreateNewProperty(&property) } - if len(propertyMap[model.GuacdFontSize]) == 0 { + if len(propertyMap[guacd.FontSize]) == 0 { property := model.Property{ - Name: model.GuacdFontSize, + Name: guacd.FontSize, Value: "12", } _ = model.CreateNewProperty(&property) } - if len(propertyMap[model.GuacdColorScheme]) == 0 { + if len(propertyMap[guacd.ColorScheme]) == 0 { property := model.Property{ - Name: model.GuacdColorScheme, + Name: guacd.ColorScheme, Value: "gray-black", } _ = model.CreateNewProperty(&property) } - if len(propertyMap[model.GuacdEnableSftp]) == 0 { + if len(propertyMap[guacd.EnableDrive]) == 0 { property := model.Property{ - Name: model.GuacdEnableSftp, + Name: guacd.EnableDrive, Value: "true", } _ = model.CreateNewProperty(&property) } - if len(propertyMap[model.GuacdEnableDrive]) == 0 { + if len(propertyMap[guacd.EnableWallpaper]) == 0 { property := model.Property{ - Name: model.GuacdEnableDrive, - Value: "true", - } - _ = model.CreateNewProperty(&property) - } - - if len(propertyMap[model.GuacdEnableWallpaper]) == 0 { - property := model.Property{ - Name: model.GuacdEnableWallpaper, + Name: guacd.EnableWallpaper, Value: "false", } _ = model.CreateNewProperty(&property) } - if len(propertyMap[model.GuacdEnableTheming]) == 0 { + if len(propertyMap[guacd.EnableTheming]) == 0 { property := model.Property{ - Name: model.GuacdEnableTheming, + Name: guacd.EnableTheming, Value: "false", } _ = model.CreateNewProperty(&property) } - if len(propertyMap[model.GuacdEnableFontSmoothing]) == 0 { + if len(propertyMap[guacd.EnableFontSmoothing]) == 0 { property := model.Property{ - Name: model.GuacdEnableFontSmoothing, + Name: guacd.EnableFontSmoothing, Value: "false", } _ = model.CreateNewProperty(&property) } - if len(propertyMap[model.GuacdEnableFullWindowDrag]) == 0 { + if len(propertyMap[guacd.EnableFullWindowDrag]) == 0 { property := model.Property{ - Name: model.GuacdEnableFullWindowDrag, + Name: guacd.EnableFullWindowDrag, Value: "false", } _ = model.CreateNewProperty(&property) } - if len(propertyMap[model.GuacdEnableDesktopComposition]) == 0 { + if len(propertyMap[guacd.EnableDesktopComposition]) == 0 { property := model.Property{ - Name: model.GuacdEnableDesktopComposition, + Name: guacd.EnableDesktopComposition, Value: "false", } _ = model.CreateNewProperty(&property) } - if len(propertyMap[model.GuacdEnableMenuAnimations]) == 0 { + if len(propertyMap[guacd.EnableMenuAnimations]) == 0 { property := model.Property{ - Name: model.GuacdEnableMenuAnimations, + Name: guacd.EnableMenuAnimations, Value: "false", } _ = model.CreateNewProperty(&property) } - if len(propertyMap[model.GuacdDisableBitmapCaching]) == 0 { + if len(propertyMap[guacd.DisableBitmapCaching]) == 0 { property := model.Property{ - Name: model.GuacdDisableBitmapCaching, + Name: guacd.DisableBitmapCaching, Value: "false", } _ = model.CreateNewProperty(&property) } - if len(propertyMap[model.GuacdDisableOffscreenCaching]) == 0 { + if len(propertyMap[guacd.DisableOffscreenCaching]) == 0 { property := model.Property{ - Name: model.GuacdDisableOffscreenCaching, + Name: guacd.DisableOffscreenCaching, Value: "false", } _ = model.CreateNewProperty(&property) } - if len(propertyMap[model.GuacdDisableGlyphCaching]) == 0 { + if len(propertyMap[guacd.DisableGlyphCaching]) == 0 { property := model.Property{ - Name: model.GuacdDisableGlyphCaching, + Name: guacd.DisableGlyphCaching, Value: "false", } _ = model.CreateNewProperty(&property) diff --git a/pkg/model/property.go b/pkg/model/property.go index 4f1e48c..bcc2c16 100644 --- a/pkg/model/property.go +++ b/pkg/model/property.go @@ -2,30 +2,7 @@ package model import ( "next-terminal/pkg/config" - "errors" -) - -const ( - GuacdHost = "host" - GuacdPort = "port" - - GuacdFontName = "font-name" - GuacdFontSize = "font-size" - GuacdColorScheme = "color-scheme" - GuacdEnableSftp = "enable-sftp" - - GuacdEnableDrive = "enable-drive" - GuacdDriveName = "drive-name" - GuacdDrivePath = "drive-path" - GuacdEnableWallpaper = "enable-wallpaper" - GuacdEnableTheming = "enable-theming" - GuacdEnableFontSmoothing = "enable-font-smoothing" - GuacdEnableFullWindowDrag = "enable-full-window-drag" - GuacdEnableDesktopComposition = "enable-desktop-composition" - GuacdEnableMenuAnimations = "enable-menu-animations" - GuacdDisableBitmapCaching = "disable-bitmap-caching" - GuacdDisableOffscreenCaching = "disable-offscreen-caching" - GuacdDisableGlyphCaching = "disable-glyph-caching" + "next-terminal/pkg/guacd" ) type Property struct { @@ -69,10 +46,17 @@ func FindAllPropertiesMap() map[string]string { } func GetDrivePath() (string, error) { - propertiesMap := FindAllPropertiesMap() - drivePath := propertiesMap[GuacdDrivePath] - if len(drivePath) == 0 { - return "", errors.New("获取RDP挂载目录失败") + property, err := FindPropertyByName(guacd.DrivePath) + if err != nil { + return "", err } - return drivePath, nil + return property.Value, nil +} + +func GetRecordingPath() (string, error) { + property, err := FindPropertyByName(guacd.RecordingPath) + if err != nil { + return "", err + } + return property.Value, nil } diff --git a/pkg/model/session.go b/pkg/model/session.go index fdcaadd..e5c2cc0 100644 --- a/pkg/model/session.go +++ b/pkg/model/session.go @@ -26,6 +26,7 @@ type Session struct { Width int `json:"width"` Height int `json:"height"` Status string `json:"status"` + Recording string `json:"recording"` ConnectedTime utils.JsonTime `json:"connectedTime"` DisconnectedTime utils.JsonTime `json:"disconnectedTime"` } @@ -47,6 +48,7 @@ type SessionVo struct { Width int `json:"width"` Height int `json:"height"` Status string `json:"status"` + Recording string `json:"recording"` ConnectedTime utils.JsonTime `json:"connectedTime"` DisconnectedTime utils.JsonTime `json:"disconnectedTime"` AssetName string `json:"assetName"` @@ -60,7 +62,7 @@ func FindPageSession(pageIndex, pageSize int, status, userId, clientIp, assetId, params = append(params, status) - itemSql := "SELECT s.id, s.protocol, s.connection_id, s.asset_id, s.creator, s.client_ip, s.width, s.height, s.ip, s.port, s.username, s.status, s.connected_time, s.disconnected_time, a.name AS asset_name, u.nickname AS creator_name FROM sessions s LEFT JOIN assets a ON s.asset_id = a.id LEFT JOIN users u ON s.creator = u.id WHERE s.STATUS = ? " + itemSql := "SELECT s.id, s.protocol,s.recording, s.connection_id, s.asset_id, s.creator, s.client_ip, s.width, s.height, s.ip, s.port, s.username, s.status, s.connected_time, s.disconnected_time, a.name AS asset_name, u.nickname AS creator_name FROM sessions s LEFT JOIN assets a ON s.asset_id = a.id LEFT JOIN users u ON s.creator = u.id WHERE s.STATUS = ? " countSql := "select count(*) from sessions as s where s.status = ? " if len(userId) > 0 { diff --git a/web/src/App.js b/web/src/App.js index 17597ed..6e049fd 100644 --- a/web/src/App.js +++ b/web/src/App.js @@ -135,7 +135,7 @@ class App extends Component { style={{lineHeight: '64px'}}> }> - + 控制面板 @@ -214,7 +214,7 @@ class App extends Component { */} - + diff --git a/web/src/components/Login.js b/web/src/components/Login.js index a5bb725..0295aa3 100644 --- a/web/src/components/Login.js +++ b/web/src/components/Login.js @@ -28,7 +28,7 @@ class LoginForm extends Component { // 跳转登录 sessionStorage.removeItem('current'); sessionStorage.removeItem('openKeys'); - localStorage.setItem('X-Auth-Token', result.data); + localStorage.setItem('X-Auth-Token', result['data']); // this.props.history.push(); window.location.href = "/" diff --git a/web/src/components/session/OfflineSession.js b/web/src/components/session/OfflineSession.js index 6e55cde..a858d08 100644 --- a/web/src/components/session/OfflineSession.js +++ b/web/src/components/session/OfflineSession.js @@ -23,7 +23,8 @@ import {differTime, formatDate, itemRender} from "../../utils/utils"; import Playback from "./Playback"; import {message} from "antd/es"; import { - DeleteOutlined, DeleteTwoTone, + DeleteOutlined, + DeleteTwoTone, ExclamationCircleOutlined, PlaySquareTwoTone, SyncOutlined, @@ -293,11 +294,19 @@ class OfflineSession extends Component { title: '操作', key: 'action', render: (text, record) => { + let disabled = true; + let color = '#d9d9d9' + if (record['recording'] && record['recording'].length > 0) { + disabled = false + color = '' + } return (
- - + + + 00:00 + / + 00:00 +
+ + - - -
- - - 00:00 - / - 00:00 -
- - - - ); - } + ); + } } export default Playback; diff --git a/web/src/components/setting/Setting.js b/web/src/components/setting/Setting.js index 87623e2..c00afee 100644 --- a/web/src/components/setting/Setting.js +++ b/web/src/components/setting/Setting.js @@ -1,12 +1,13 @@ import React, {Component} from 'react'; -import {Layout, PageHeader, Switch, Select} from "antd"; +import {Button, Form, Input, Layout, PageHeader, Select, Switch, Tabs, Typography} from "antd"; import {itemRender} from '../../utils/utils' -import {Form, Input, Button, Checkbox} from "antd"; import request from "../../common/request"; import {message} from "antd/es"; const {Content} = Layout; const {Option} = Select; +const {TabPane} = Tabs; +const {Title} = Typography; const routes = [ { @@ -20,20 +21,24 @@ const routes = [ ]; const formItemLayout = { - labelCol: {span: 3}, - wrapperCol: {span: 9}, + labelCol: {span: 12}, + wrapperCol: {span: 12}, }; const formTailLayout = { - labelCol: {span: 3}, - wrapperCol: {span: 9, offset: 3}, + labelCol: {span: 12}, + wrapperCol: {span: 12}, }; class Setting extends Component { - state = {} + state = { + properties: {} + } - settingFormRef = React.createRef(); + settingFormRef1 = React.createRef(); + settingFormRef2 = React.createRef(); + settingFormRef3 = React.createRef(); componentDidMount() { this.getProperties(); @@ -51,198 +56,259 @@ class Setting extends Component { getProperties = async () => { // eslint-disable-next-line no-extend-native - String.prototype.bool = function() { + String.prototype.bool = function () { return (/^true$/i).test(this); }; let result = await request.get('/properties'); - if (result.code === 1) { - let properties = {} + if (result['code'] === 1) { + let properties = result['data']; - for (let i = 0; i < result.data.length; i++) { - let item = result.data[i]; - if (item['name'].startsWith('enable') || - item['name'].startsWith('disable')) { - properties[item['name']] = item['value'].bool() - }else { - properties[item['name']] = item['value'] + for (let key in properties) { + if(!properties.hasOwnProperty(key)){ + continue; + } + if(key.startsWith('enable') || key.startsWith("disable")){ + properties[key] = properties[key].bool(); } } - this.settingFormRef.current.setFieldsValue(properties) + console.log(properties) + this.setState({ + properties: properties + }) + if (this.settingFormRef1.current) { + this.settingFormRef1.current.setFieldsValue(properties) + } + + if (this.settingFormRef2.current) { + this.settingFormRef2.current.setFieldsValue(properties) + } + + if (this.settingFormRef3.current) { + this.settingFormRef3.current.setFieldsValue(properties) + } } else { - message.error(result.message); + message.error(result['message']); } } + handleOnTabChange = () => { + this.getProperties() + } + render() { return ( - <> - - + <> + + - + -
-

Guacd 服务配置

+ - - - + + - - - + RDP配置(远程桌面) - -

远程桌面(RDP)配置

- - - - - - - - + > + { + this.setState({ + properties: { + ...this.state.properties, + 'enable-drive': checked, + } + }) + }}/> + + { + this.state.properties['enable-drive'] === true ? + <> + + + - - - + + + + : null + } - - - + rules={[ + { + required: true, + }, + ]} + > + + - - - + rules={[ + { + required: true, + }, + ]} + > + + - - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - + rules={[ + { + required: true, + }, + ]} + > + + - - - + rules={[ + { + required: true, + }, + ]} + > + + -

SSH配置

+ + + + +
+ +
- SSH配置 + + - - + > + + - - - + > + + - - - + > + + - + + +
+
+ + Guacd 服务配置 +
+ + + + + + + + + - - + rules={[ + { + required: true, + }, + ]} + > + { + this.setState({ + properties: { + ...this.state.properties, + 'enable-recording': checked, + } + }) + }}/> + + { + this.state.properties['enable-recording'] === true ? + <> - - - - + + + + : null + } -
- + + + + + + + + +
+ ); } }