完善录屏和前端配置页面

This commit is contained in:
dushixiang
2020-12-23 21:56:19 +08:00
parent e34243ce68
commit 348074670e
12 changed files with 569 additions and 383 deletions

View File

@ -7,7 +7,7 @@ import (
)
func PropertyGetEndpoint(c echo.Context) error {
properties := model.FindAllTemp()
properties := model.FindAllPropertiesMap()
return Success(c, properties)
}

View File

@ -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
}

View File

@ -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)
}

View File

@ -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"

View File

@ -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)

View File

@ -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
}

View File

@ -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 {

View File

@ -135,7 +135,7 @@ class App extends Component {
style={{lineHeight: '64px'}}>
<Menu.Item key="dashboard" icon={<DashboardOutlined/>}>
<Link to={'/dashboard'}>
<Link to={'/'}>
控制面板
</Link>
</Menu.Item>
@ -214,7 +214,7 @@ class App extends Component {
</Header>*/}
<Route path="/dashboard" component={Dashboard}/>
<Route path="/" exact component={Dashboard}/>
<Route path="/user" component={User}/>
<Route path="/asset" component={Asset}/>
<Route path="/credential" component={Credential}/>

View File

@ -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 = "/"

View File

@ -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 (
<div>
<Button type="link" size='small' icon={<PlaySquareTwoTone />} onClick={() => this.showPlayback(record.id)}>回放</Button>
<Button type="link" size='small' icon={<DeleteTwoTone />} onClick={() => {
<Button type="link" size='small'
disabled={disabled}
icon={<PlaySquareTwoTone twoToneColor={color}/>} onClick={() => this.showPlayback(record.id)}>回放</Button>
<Button type="link" size='small' icon={<DeleteTwoTone/>} onClick={() => {
confirm({
title: '您确定要删除此会话吗?',
content: '',

View File

@ -3,171 +3,171 @@ import Guacamole from "guacamole-common-js";
class Playback extends Component {
componentDidMount() {
let sessionId = this.props.sessionId;
this.initPlayer(sessionId);
}
componentDidMount() {
let sessionId = this.props.sessionId;
this.initPlayer(sessionId);
}
componentWillMount() {
componentWillMount() {
}
}
initPlayer(sessionId) {
var RECORDING_URL = '/recording/' + sessionId + '.guac';
initPlayer(sessionId) {
var RECORDING_URL = '/sessions/' + sessionId + '/recording';
var player = document.getElementById('player');
var display = document.getElementById('display');
var playPause = document.getElementById('play-pause');
var position = document.getElementById('position');
var positionSlider = document.getElementById('position-slider');
var duration = document.getElementById('duration');
var player = document.getElementById('player');
var display = document.getElementById('display');
var playPause = document.getElementById('play-pause');
var position = document.getElementById('position');
var positionSlider = document.getElementById('position-slider');
var duration = document.getElementById('duration');
var tunnel = new Guacamole.StaticHTTPTunnel(RECORDING_URL);
var recording = new Guacamole.SessionRecording(tunnel);
var tunnel = new Guacamole.StaticHTTPTunnel(RECORDING_URL);
var recording = new Guacamole.SessionRecording(tunnel);
var recordingDisplay = recording.getDisplay();
var recordingDisplay = recording.getDisplay();
/**
* Converts the given number to a string, adding leading zeroes as necessary
* to reach a specific minimum length.
*
* @param {Numer} num
* The number to convert to a string.
*
* @param {Number} minLength
* The minimum length of the resulting string, in characters.
*
* @returns {String}
* A string representation of the given number, with leading zeroes
* added as necessary to reach the specified minimum length.
*/
var zeroPad = function zeroPad(num, minLength) {
/**
* Converts the given number to a string, adding leading zeroes as necessary
* to reach a specific minimum length.
*
* @param {Numer} num
* The number to convert to a string.
*
* @param {Number} minLength
* The minimum length of the resulting string, in characters.
*
* @returns {String}
* A string representation of the given number, with leading zeroes
* added as necessary to reach the specified minimum length.
*/
var zeroPad = function zeroPad(num, minLength) {
// Convert provided number to string
var str = num.toString();
// Convert provided number to string
var str = num.toString();
// Add leading zeroes until string is long enough
while (str.length < minLength)
str = '0' + str;
// Add leading zeroes until string is long enough
while (str.length < minLength)
str = '0' + str;
return str;
return str;
};
};
/**
* Converts the given millisecond timestamp into a human-readable string in
* MM:SS format.
*
* @param {Number} millis
* An arbitrary timestamp, in milliseconds.
*
* @returns {String}
* A human-readable string representation of the given timestamp, in
* MM:SS format.
*/
var formatTime = function formatTime(millis) {
/**
* Converts the given millisecond timestamp into a human-readable string in
* MM:SS format.
*
* @param {Number} millis
* An arbitrary timestamp, in milliseconds.
*
* @returns {String}
* A human-readable string representation of the given timestamp, in
* MM:SS format.
*/
var formatTime = function formatTime(millis) {
// Calculate total number of whole seconds
var totalSeconds = Math.floor(millis / 1000);
// Calculate total number of whole seconds
var totalSeconds = Math.floor(millis / 1000);
// Split into seconds and minutes
var seconds = totalSeconds % 60;
var minutes = Math.floor(totalSeconds / 60);
// Split into seconds and minutes
var seconds = totalSeconds % 60;
var minutes = Math.floor(totalSeconds / 60);
// Format seconds and minutes as MM:SS
return zeroPad(minutes, 2) + ':' + zeroPad(seconds, 2);
// Format seconds and minutes as MM:SS
return zeroPad(minutes, 2) + ':' + zeroPad(seconds, 2);
};
};
// Add playback display to DOM
display.appendChild(recordingDisplay.getElement());
// Add playback display to DOM
display.appendChild(recordingDisplay.getElement());
// Begin downloading the recording
recording.connect();
// Begin downloading the recording
recording.connect();
// If playing, the play/pause button should read "Pause"
recording.onplay = function () {
playPause.textContent = 'Pause';
};
// If playing, the play/pause button should read "Pause"
recording.onplay = function () {
playPause.textContent = 'Pause';
};
// If paused, the play/pause button should read "Play"
recording.onpause = function () {
playPause.textContent = 'Play';
};
// If paused, the play/pause button should read "Play"
recording.onpause = function () {
playPause.textContent = 'Play';
};
// Toggle play/pause when display or button are clicked
display.onclick = playPause.onclick = function () {
if (!recording.isPlaying())
recording.play();
else
recording.pause();
};
// Toggle play/pause when display or button are clicked
display.onclick = playPause.onclick = function () {
if (!recording.isPlaying())
recording.play();
else
recording.pause();
};
// Fit display within containing div
recordingDisplay.onresize = function displayResized(width, height) {
// Fit display within containing div
recordingDisplay.onresize = function displayResized(width, height) {
// Do not scale if display has no width
if (!width)
return;
// Do not scale if display has no width
if (!width)
return;
// Scale display to fit width of container
recordingDisplay.scale(display.offsetWidth / width);
// Scale display to fit width of container
recordingDisplay.scale(display.offsetWidth / width);
};
};
// Update slider and status when playback position changes
recording.onseek = function positionChanged(millis) {
position.textContent = formatTime(millis);
positionSlider.value = millis;
};
// Update slider and status when playback position changes
recording.onseek = function positionChanged(millis) {
position.textContent = formatTime(millis);
positionSlider.value = millis;
};
// Update slider and status when duration changes
recording.onprogress = function durationChanged(millis) {
duration.textContent = formatTime(millis);
positionSlider.max = millis;
};
// Update slider and status when duration changes
recording.onprogress = function durationChanged(millis) {
duration.textContent = formatTime(millis);
positionSlider.max = millis;
};
// Seek within recording if slider is moved
positionSlider.onchange = function sliderPositionChanged() {
// Seek within recording if slider is moved
positionSlider.onchange = function sliderPositionChanged() {
// Request seek
recording.seek(positionSlider.value, function seekComplete() {
// Request seek
recording.seek(positionSlider.value, function seekComplete() {
// Seek has completed
player.className = '';
// Seek has completed
player.className = '';
});
});
// Seek is in progress
player.className = 'seeking';
// Seek is in progress
player.className = 'seeking';
};
}
};
}
render() {
return (
<div>
<div id="player">
render() {
return (
<div>
<div id="player">
<div id="display">
<div className="notification-container">
<div className="seek-notification">
</div>
<div id="display">
<div className="notification-container">
<div className="seek-notification">
</div>
</div>
</div>
<div className="controls">
<button id="play-pause">Play</button>
<input id="position-slider" type="range"/>
<span id="position">00:00</span>
<span>/</span>
<span id="duration">00:00</span>
</div>
</div>
</div>
</div>
<div className="controls">
<button id="play-pause">Play</button>
<input id="position-slider" type="range"/>
<span id="position">00:00</span>
<span>/</span>
<span id="duration">00:00</span>
</div>
</div>
</div>
);
}
);
}
}
export default Playback;

View File

@ -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 (
<>
<PageHeader
className="site-page-header-ghost-wrapper page-herder"
title="系统设置"
breadcrumb={{
routes: routes,
itemRender: itemRender
}}
subTitle="系统设置"
>
</PageHeader>
<>
<PageHeader
className="site-page-header-ghost-wrapper page-herder"
title="系统设置"
breadcrumb={{
routes: routes,
itemRender: itemRender
}}
subTitle="系统设置"
>
</PageHeader>
<Content className="site-layout-background page-content">
<Content className="site-layout-background page-content">
<Form ref={this.settingFormRef} name="password" onFinish={this.changeProperties}>
<h3>Guacd 服务配置</h3>
<Tabs tabPosition={'left'} onChange={this.handleOnTabChange} tabBarStyle={{width: 150}}>
<Form.Item
{...formItemLayout}
name="host"
label="监听地址"
rules={[
{
required: true,
message: '监听地址',
},
]}
>
<Input type='text' placeholder="请输入监听地址"/>
</Form.Item>
<TabPane tab="RDP配置" key="1">
<Form ref={this.settingFormRef1} name="password" onFinish={this.changeProperties}
layout="vertical">
<Form.Item
{...formItemLayout}
name="port"
label="监听端口"
rules={[
{
required: true,
message: '监听端口',
min: 1,
max: 65535
},
]}
>
<Input type='number' placeholder="请输入监听端口"/>
</Form.Item>
<Title level={3}>RDP配置(远程桌面)</Title>
<h3>远程桌面RDP配置</h3>
<Form.Item
<Form.Item
{...formItemLayout}
name="enable-drive"
label="启用设备映射"
valuePropName="checked"
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
<Form.Item
{...formItemLayout}
name="drive-name"
label="设备名称"
rules={[
{
required: true,
message: '请输入设备名称',
},
]}
>
<Input type='text' placeholder="请输入设备名称"/>
</Form.Item>
>
<Switch checkedChildren="开启" unCheckedChildren="关闭" onChange={(checked, event) => {
this.setState({
properties: {
...this.state.properties,
'enable-drive': checked,
}
})
}}/>
</Form.Item>
{
this.state.properties['enable-drive'] === true ?
<>
<Form.Item
{...formItemLayout}
name="drive-name"
label="设备名称"
rules={[
{
required: true,
message: '请输入设备名称',
},
]}
>
<Input type='text' placeholder="请输入设备名称"/>
</Form.Item>
<Form.Item
{...formItemLayout}
name="drive-path"
label="设备路径"
rules={[
{
required: true,
message: '请输入设备路径',
},
]}
>
<Input type='text' placeholder="请输入设备路径"/>
</Form.Item>
<Form.Item
{...formItemLayout}
name="drive-path"
label="设备路径"
rules={[
{
required: true,
message: '请输入设备路径',
},
]}
>
<Input type='text' placeholder="请输入设备路径"/>
</Form.Item>
</> : null
}
<Form.Item
<Form.Item
{...formItemLayout}
name="enable-wallpaper"
label="启用桌面墙纸"
valuePropName="checked"
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
rules={[
{
required: true,
},
]}
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
<Form.Item
<Form.Item
{...formItemLayout}
name="enable-theming"
label="启用桌面主题"
valuePropName="checked"
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
rules={[
{
required: true,
},
]}
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
<Form.Item
<Form.Item
{...formItemLayout}
name="enable-font-smoothing"
label="启用字体平滑ClearType"
valuePropName="checked"
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
<Form.Item
rules={[
{
required: true,
},
]}
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
<Form.Item
{...formItemLayout}
name="enable-full-window-drag"
label="启用全窗口拖拽"
valuePropName="checked"
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
<Form.Item
rules={[
{
required: true,
},
]}
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
<Form.Item
{...formItemLayout}
name="enable-desktop-composition"
label="启用桌面合成效果Aero"
valuePropName="checked"
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
<Form.Item
rules={[
{
required: true,
},
]}
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
<Form.Item
{...formItemLayout}
name="enable-menu-animations"
label="启用菜单动画"
valuePropName="checked"
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
<Form.Item
rules={[
{
required: true,
},
]}
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
<Form.Item
{...formItemLayout}
name="disable-bitmap-caching"
label="禁用位图缓存"
valuePropName="checked"
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
<Form.Item
rules={[
{
required: true,
},
]}
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
<Form.Item
{...formItemLayout}
name="disable-offscreen-caching"
label="禁用离屏缓存"
valuePropName="checked"
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
rules={[
{
required: true,
},
]}
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
<Form.Item
<Form.Item
{...formItemLayout}
name="disable-glyph-caching"
label="禁用字形缓存"
valuePropName="checked"
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
rules={[
{
required: true,
},
]}
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
<h3>SSH配置</h3>
<Form.Item {...formTailLayout}>
<Button type="primary" htmlType="submit">
更新
</Button>
</Form.Item>
</Form>
</TabPane>
<TabPane tab="SSH配置" key="2">
<Form ref={this.settingFormRef2} name="password" onFinish={this.changeProperties}
layout="vertical">
<Form.Item
<Title level={3}>SSH配置</Title>
<Form.Item
{...formItemLayout}
name="font-name"
label="字体名称"
@ -252,11 +318,11 @@ class Setting extends Component {
message: '字体名称',
},
]}
>
<Input type='text' placeholder="请输入字体名称"/>
</Form.Item>
>
<Input type='text' placeholder="请输入字体名称"/>
</Form.Item>
<Form.Item
<Form.Item
{...formItemLayout}
name="font-size"
label="字体大小"
@ -266,11 +332,11 @@ class Setting extends Component {
message: '字体大小',
},
]}
>
<Input type='number' placeholder="请输入字体大小"/>
</Form.Item>
>
<Input type='number' placeholder="请输入字体大小"/>
</Form.Item>
<Form.Item
<Form.Item
{...formItemLayout}
name="color-scheme"
label="颜色主题"
@ -281,33 +347,108 @@ class Setting extends Component {
},
]}
initialValue="gray-black"
>
<Select style={{width: 120}} onChange={null}>
<Option value="gray-black">黑底灰字</Option>
<Option value="green-black">黑底绿字</Option>
<Option value="white-black">黑底白字</Option>
<Option value="black-white">白底黑字</Option>
</Select>
</Form.Item>
>
<Select style={{width: 120}} onChange={null}>
<Option value="gray-black">黑底灰字</Option>
<Option value="green-black">黑底绿字</Option>
<Option value="white-black">黑底白字</Option>
<Option value="black-white">白底黑字</Option>
</Select>
</Form.Item>
<Form.Item
<Form.Item {...formTailLayout}>
<Button type="primary" htmlType="submit">
更新
</Button>
</Form.Item>
</Form>
</TabPane>
<TabPane tab="其他配置" key="3">
<Title level={3}>Guacd 服务配置</Title>
<Form ref={this.settingFormRef3} name="password" onFinish={this.changeProperties}
layout="vertical">
<Form.Item
{...formItemLayout}
name="enable-sftp"
label="启用SFTP"
name="host"
label="Guacd监听地址"
rules={[
{
required: true,
message: 'Guacd监听地址',
},
]}
>
<Input type='text' placeholder="请输入Guacd监听地址"/>
</Form.Item>
<Form.Item
{...formItemLayout}
name="port"
label="Guacd监听端口"
rules={[
{
required: true,
message: 'Guacd监听端口',
min: 1,
max: 65535
},
]}
>
<Input type='number' placeholder="请输入Guacd监听端口"/>
</Form.Item>
<Form.Item
{...formItemLayout}
name="enable-recording"
label="开启录屏"
valuePropName="checked"
>
<Switch checkedChildren="开启" unCheckedChildren="关闭"/>
</Form.Item>
rules={[
{
required: true,
},
]}
>
<Switch checkedChildren="开启" unCheckedChildren="关闭" onChange={(checked, event) => {
this.setState({
properties: {
...this.state.properties,
'enable-recording': checked,
}
})
}}/>
</Form.Item>
{
this.state.properties['enable-recording'] === true ?
<>
<Form.Item {...formTailLayout}>
<Button type="primary" htmlType="submit">
提交
</Button>
</Form.Item>
</Form>
<Form.Item
{...formItemLayout}
name="recording-path"
label="录屏存放路径"
rules={[
{
required: true,
message: '请输入录屏存放路径',
},
]}
>
<Input type='text' placeholder="请输入录屏存放路径"/>
</Form.Item>
</> : null
}
</Content>
</>
<Form.Item {...formTailLayout}>
<Button type="primary" htmlType="submit">
更新
</Button>
</Form.Item>
</Form>
</TabPane>
</Tabs>
</Content>
</>
);
}
}