add:Dlass联动
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
using Ink_Canvas.Helpers;
|
using Ink_Canvas.Helpers;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@@ -343,6 +345,86 @@ namespace Ink_Canvas.Helpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 上传笔记文件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="endpoint">上传端点</param>
|
||||||
|
/// <param name="filePath">文件路径</param>
|
||||||
|
/// <param name="boardId">白板ID</param>
|
||||||
|
/// <param name="secretKey">白板密钥</param>
|
||||||
|
/// <param name="title">笔记标题(可选)</param>
|
||||||
|
/// <param name="description">笔记描述(可选)</param>
|
||||||
|
/// <param name="tags">笔记标签(可选)</param>
|
||||||
|
public async Task<T> UploadNoteAsync<T>(string endpoint, string filePath, string boardId, string secretKey, string title = null, string description = null, string tags = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException($"文件不存在: {filePath}");
|
||||||
|
}
|
||||||
|
|
||||||
|
var request = new HttpRequestMessage(HttpMethod.Post, endpoint);
|
||||||
|
|
||||||
|
// 设置白板认证头
|
||||||
|
request.Headers.Add("X-Board-ID", boardId);
|
||||||
|
request.Headers.Add("X-Secret-Key", secretKey);
|
||||||
|
|
||||||
|
// 创建multipart/form-data内容
|
||||||
|
var content = new MultipartFormDataContent();
|
||||||
|
|
||||||
|
// 添加文件
|
||||||
|
var fileContent = new ByteArrayContent(File.ReadAllBytes(filePath));
|
||||||
|
var fileName = Path.GetFileName(filePath);
|
||||||
|
fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
|
||||||
|
content.Add(fileContent, "file", fileName);
|
||||||
|
|
||||||
|
// 添加可选参数
|
||||||
|
if (!string.IsNullOrEmpty(title))
|
||||||
|
{
|
||||||
|
content.Add(new StringContent(title), "title");
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(description))
|
||||||
|
{
|
||||||
|
content.Add(new StringContent(description), "description");
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(tags))
|
||||||
|
{
|
||||||
|
content.Add(new StringContent(tags), "tags");
|
||||||
|
}
|
||||||
|
|
||||||
|
request.Content = content;
|
||||||
|
|
||||||
|
var response = await _httpClient.SendAsync(request);
|
||||||
|
var responseContent = await response.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(responseContent))
|
||||||
|
{
|
||||||
|
return default(T);
|
||||||
|
}
|
||||||
|
return JsonConvert.DeserializeObject<T>(responseContent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception($"上传文件失败: {response.StatusCode} - {responseContent}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (HttpRequestException httpEx)
|
||||||
|
{
|
||||||
|
throw new Exception($"上传文件时网络错误: {httpEx.Message}", httpEx);
|
||||||
|
}
|
||||||
|
catch (TaskCanceledException timeoutEx)
|
||||||
|
{
|
||||||
|
throw new Exception($"上传文件超时: {endpoint}", timeoutEx);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new Exception($"上传文件时出错: {ex.Message}", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 释放资源
|
/// 释放资源
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -0,0 +1,200 @@
|
|||||||
|
using Ink_Canvas.Helpers;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Ink_Canvas.Helpers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Dlass笔记自动上传辅助类
|
||||||
|
/// </summary>
|
||||||
|
public class DlassNoteUploader
|
||||||
|
{
|
||||||
|
private const string APP_ID = "app_WkjocWqsrVY7T6zQV2CfiA";
|
||||||
|
private const string APP_SECRET = "o7dx5b5ASGUMcM72PCpmRQYAhSijqaOVHoGyBK0IxbA";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 上传笔记响应模型
|
||||||
|
/// </summary>
|
||||||
|
public class UploadNoteResponse
|
||||||
|
{
|
||||||
|
[JsonProperty("success")]
|
||||||
|
public bool Success { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("message")]
|
||||||
|
public string Message { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("note_id")]
|
||||||
|
public int? NoteId { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("filename")]
|
||||||
|
public string Filename { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("file_path")]
|
||||||
|
public string FilePath { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("file_url")]
|
||||||
|
public string FileUrl { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 白板信息模型(用于查找白板)
|
||||||
|
/// </summary>
|
||||||
|
private class WhiteboardInfo
|
||||||
|
{
|
||||||
|
[JsonProperty("id")]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("name")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("board_id")]
|
||||||
|
public string BoardId { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("secret_key")]
|
||||||
|
public string SecretKey { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("class_name")]
|
||||||
|
public string ClassName { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("class_id")]
|
||||||
|
public int ClassId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 认证响应模型
|
||||||
|
/// </summary>
|
||||||
|
private class AuthWithTokenResponse
|
||||||
|
{
|
||||||
|
[JsonProperty("success")]
|
||||||
|
public bool Success { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("whiteboards")]
|
||||||
|
public List<WhiteboardInfo> Whiteboards { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步上传PNG文件到Dlass
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pngFilePath">PNG文件路径</param>
|
||||||
|
/// <returns>是否上传成功</returns>
|
||||||
|
public static async Task<bool> UploadPngNoteAsync(string pngFilePath)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 检查是否启用自动上传
|
||||||
|
if (MainWindow.Settings?.Dlass?.IsAutoUploadNotes != true)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查文件是否存在
|
||||||
|
if (!File.Exists(pngFilePath))
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"上传失败:文件不存在 - {pngFilePath}", LogHelper.LogType.Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查文件大小(最大10MB)
|
||||||
|
var fileInfo = new FileInfo(pngFilePath);
|
||||||
|
if (fileInfo.Length > 10 * 1024 * 1024)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"上传失败:文件过大({fileInfo.Length / 1024 / 1024}MB),超过10MB限制", LogHelper.LogType.Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取设置的班级名称
|
||||||
|
var selectedClassName = MainWindow.Settings?.Dlass?.SelectedClassName;
|
||||||
|
if (string.IsNullOrEmpty(selectedClassName))
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile("上传失败:未选择班级", LogHelper.LogType.Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取用户Token
|
||||||
|
var userToken = MainWindow.Settings?.Dlass?.UserToken;
|
||||||
|
if (string.IsNullOrEmpty(userToken))
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile("上传失败:未设置用户Token", LogHelper.LogType.Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取API基础URL
|
||||||
|
var apiBaseUrl = MainWindow.Settings?.Dlass?.ApiBaseUrl ?? "https://dlass.tech";
|
||||||
|
|
||||||
|
// 创建API客户端并获取白板信息
|
||||||
|
DlassApiClient apiClient = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
apiClient = new DlassApiClient(APP_ID, APP_SECRET, apiBaseUrl, userToken);
|
||||||
|
|
||||||
|
// 调用认证接口获取白板列表
|
||||||
|
var authData = new
|
||||||
|
{
|
||||||
|
app_id = APP_ID,
|
||||||
|
app_secret = APP_SECRET,
|
||||||
|
user_token = userToken
|
||||||
|
};
|
||||||
|
|
||||||
|
var authResult = await apiClient.PostAsync<AuthWithTokenResponse>("/api/whiteboard/framework/auth-with-token", authData, requireAuth: false);
|
||||||
|
|
||||||
|
if (authResult == null || !authResult.Success || authResult.Whiteboards == null)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile("上传失败:无法获取白板信息", LogHelper.LogType.Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查找匹配班级的白板
|
||||||
|
var whiteboard = authResult.Whiteboards
|
||||||
|
.FirstOrDefault(w => !string.IsNullOrEmpty(w.ClassName) && w.ClassName == selectedClassName);
|
||||||
|
|
||||||
|
if (whiteboard == null || string.IsNullOrEmpty(whiteboard.BoardId) || string.IsNullOrEmpty(whiteboard.SecretKey))
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"上传失败:未找到班级'{selectedClassName}'对应的白板", LogHelper.LogType.Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 准备上传参数
|
||||||
|
var fileName = Path.GetFileNameWithoutExtension(pngFilePath);
|
||||||
|
var title = fileName;
|
||||||
|
var description = $"自动上传的笔记 - {DateTime.Now:yyyy-MM-dd HH:mm:ss}";
|
||||||
|
var tags = "自动上传,笔记";
|
||||||
|
|
||||||
|
// 上传文件
|
||||||
|
var uploadResult = await apiClient.UploadNoteAsync<UploadNoteResponse>(
|
||||||
|
"/api/whiteboard/upload_note",
|
||||||
|
pngFilePath,
|
||||||
|
whiteboard.BoardId,
|
||||||
|
whiteboard.SecretKey,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
tags);
|
||||||
|
|
||||||
|
if (uploadResult != null && uploadResult.Success)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"笔记上传成功:{fileName} -> {uploadResult.FileUrl}", LogHelper.LogType.Event);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"上传失败:服务器响应失败 - {uploadResult?.Message ?? "未知错误"}", LogHelper.LogType.Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
apiClient?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"上传笔记时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -7,6 +7,7 @@ using System.Drawing.Imaging;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
@@ -310,6 +311,23 @@ namespace Ink_Canvas
|
|||||||
var fs = new FileStream(savePathWithName, FileMode.Create);
|
var fs = new FileStream(savePathWithName, FileMode.Create);
|
||||||
inkCanvas.Strokes.Save(fs);
|
inkCanvas.Strokes.Save(fs);
|
||||||
fs.Close();
|
fs.Close();
|
||||||
|
|
||||||
|
_ = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var delayMinutes = Settings?.Dlass?.AutoUploadDelayMinutes ?? 0;
|
||||||
|
if (delayMinutes > 0)
|
||||||
|
{
|
||||||
|
await Task.Delay(TimeSpan.FromMinutes(delayMinutes));
|
||||||
|
}
|
||||||
|
|
||||||
|
await Helpers.DlassNoteUploader.UploadPngNoteAsync(imagePathWithName);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Drawing;
|
|||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
@@ -65,6 +66,29 @@ namespace Ink_Canvas
|
|||||||
{
|
{
|
||||||
ShowNotification($"截图成功保存至 {savePath}");
|
ShowNotification($"截图成功保存至 {savePath}");
|
||||||
}
|
}
|
||||||
|
_ = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var delayMinutes = Settings?.Dlass?.AutoUploadDelayMinutes ?? 0;
|
||||||
|
if (delayMinutes > 0)
|
||||||
|
{
|
||||||
|
await Task.Delay(TimeSpan.FromMinutes(delayMinutes));
|
||||||
|
}
|
||||||
|
|
||||||
|
var uploaded = await Helpers.DlassNoteUploader.UploadPngNoteAsync(savePath);
|
||||||
|
if (uploaded && !isHideNotification)
|
||||||
|
{
|
||||||
|
Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
ShowNotification($"笔记已自动上传到Dlass");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取日期文件夹路径
|
// 获取日期文件夹路径
|
||||||
|
|||||||
@@ -740,5 +740,11 @@ namespace Ink_Canvas
|
|||||||
|
|
||||||
[JsonProperty("apiBaseUrl")]
|
[JsonProperty("apiBaseUrl")]
|
||||||
public string ApiBaseUrl { get; set; } = "https://dlass.tech";
|
public string ApiBaseUrl { get; set; } = "https://dlass.tech";
|
||||||
|
|
||||||
|
[JsonProperty("isAutoUploadNotes")]
|
||||||
|
public bool IsAutoUploadNotes { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty("autoUploadDelayMinutes")]
|
||||||
|
public int AutoUploadDelayMinutes { get; set; } = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,22 +106,22 @@
|
|||||||
X1="0" Y1="0" X2="1" Y2="0"
|
X1="0" Y1="0" X2="1" Y2="0"
|
||||||
Stroke="{StaticResource BorderBrush}"
|
Stroke="{StaticResource BorderBrush}"
|
||||||
StrokeThickness="1"
|
StrokeThickness="1"
|
||||||
Margin="0,8,0,12"/>
|
Margin="0,2,0,2"/>
|
||||||
|
|
||||||
<!-- 用户Token设置 -->
|
<!-- 用户Token设置 -->
|
||||||
<TextBlock Text="用户Token"
|
<TextBlock Text="用户Token"
|
||||||
FontSize="16"
|
FontSize="16"
|
||||||
FontWeight="SemiBold"
|
FontWeight="SemiBold"
|
||||||
Foreground="{StaticResource TextForeground}"
|
Foreground="{StaticResource TextForeground}"
|
||||||
Margin="0,0,0,8"/>
|
Margin="0,0,0,1"/>
|
||||||
|
|
||||||
<TextBlock Text="设置您的用户Token以访问Dlass服务端功能。您可以从Dlass平台获取您的用户Token。"
|
<TextBlock Text="设置您的用户Token以访问Dlass服务端功能。您可以从Dlass平台获取您的用户Token。"
|
||||||
FontSize="12"
|
FontSize="12"
|
||||||
Foreground="{StaticResource TextSecondary}"
|
Foreground="{StaticResource TextSecondary}"
|
||||||
TextWrapping="Wrap"
|
TextWrapping="Wrap"
|
||||||
Margin="0,0,0,12"/>
|
Margin="0,0,0,2"/>
|
||||||
|
|
||||||
<ui:SimpleStackPanel Orientation="Vertical" Spacing="8">
|
<ui:SimpleStackPanel Orientation="Vertical" Spacing="4">
|
||||||
<ComboBox x:Name="CmbSavedTokens"
|
<ComboBox x:Name="CmbSavedTokens"
|
||||||
FontSize="14"
|
FontSize="14"
|
||||||
Padding="12,8"
|
Padding="12,8"
|
||||||
@@ -137,7 +137,7 @@
|
|||||||
|
|
||||||
<TextBox x:Name="TxtNewToken"
|
<TextBox x:Name="TxtNewToken"
|
||||||
FontSize="14"
|
FontSize="14"
|
||||||
Padding="12,8"
|
Padding="12,4"
|
||||||
Background="#18181b"
|
Background="#18181b"
|
||||||
Foreground="{StaticResource TextForeground}"
|
Foreground="{StaticResource TextForeground}"
|
||||||
BorderBrush="{StaticResource BorderBrush}"
|
BorderBrush="{StaticResource BorderBrush}"
|
||||||
@@ -280,24 +280,38 @@
|
|||||||
Margin="0,4,0,0"/>
|
Margin="0,4,0,0"/>
|
||||||
</ui:SimpleStackPanel>
|
</ui:SimpleStackPanel>
|
||||||
|
|
||||||
|
<!-- 连接状态 -->
|
||||||
|
<ui:SimpleStackPanel Orientation="Horizontal" Spacing="12" Margin="0,4,0,0">
|
||||||
|
<TextBlock Text="连接状态:"
|
||||||
|
FontSize="14"
|
||||||
|
Foreground="{StaticResource TextForeground}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Width="100"/>
|
||||||
|
<TextBlock x:Name="TxtConnectionStatus"
|
||||||
|
Text="未连接"
|
||||||
|
FontSize="14"
|
||||||
|
Foreground="{StaticResource TextSecondary}"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
</ui:SimpleStackPanel>
|
||||||
|
|
||||||
<Line HorizontalAlignment="Stretch"
|
<Line HorizontalAlignment="Stretch"
|
||||||
X1="0" Y1="0" X2="1" Y2="0"
|
X1="0" Y1="0" X2="1" Y2="0"
|
||||||
Stroke="{StaticResource BorderBrush}"
|
Stroke="{StaticResource BorderBrush}"
|
||||||
StrokeThickness="1"
|
StrokeThickness="1"
|
||||||
Margin="0,12,0,8"/>
|
Margin="0,2,0,1"/>
|
||||||
|
|
||||||
<!-- 班级选择 -->
|
<!-- 班级选择 -->
|
||||||
<TextBlock Text="班级选择"
|
<TextBlock Text="班级选择"
|
||||||
FontSize="16"
|
FontSize="16"
|
||||||
FontWeight="SemiBold"
|
FontWeight="SemiBold"
|
||||||
Foreground="{StaticResource TextForeground}"
|
Foreground="{StaticResource TextForeground}"
|
||||||
Margin="0,0,0,8"/>
|
Margin="0,0,0,1"/>
|
||||||
|
|
||||||
<TextBlock Text="连接成功后,将自动加载可用班级列表。"
|
<TextBlock Text="连接成功后,将自动加载可用班级列表。"
|
||||||
FontSize="12"
|
FontSize="12"
|
||||||
Foreground="{StaticResource TextSecondary}"
|
Foreground="{StaticResource TextSecondary}"
|
||||||
TextWrapping="Wrap"
|
TextWrapping="Wrap"
|
||||||
Margin="0,0,0,8"/>
|
Margin="0,0,0,2"/>
|
||||||
|
|
||||||
<ComboBox x:Name="CmbClassSelection"
|
<ComboBox x:Name="CmbClassSelection"
|
||||||
FontSize="14"
|
FontSize="14"
|
||||||
@@ -316,27 +330,87 @@
|
|||||||
X1="0" Y1="0" X2="1" Y2="0"
|
X1="0" Y1="0" X2="1" Y2="0"
|
||||||
Stroke="{StaticResource BorderBrush}"
|
Stroke="{StaticResource BorderBrush}"
|
||||||
StrokeThickness="1"
|
StrokeThickness="1"
|
||||||
Margin="0,12,0,8"/>
|
Margin="0,2,0,1"/>
|
||||||
|
|
||||||
<!-- 连接状态 -->
|
<!-- 自动上传设置 -->
|
||||||
<ui:SimpleStackPanel Orientation="Horizontal" Spacing="12">
|
<TextBlock Text="自动上传设置"
|
||||||
<TextBlock Text="连接状态:"
|
FontSize="16"
|
||||||
FontSize="14"
|
FontWeight="SemiBold"
|
||||||
Foreground="{StaticResource TextForeground}"
|
Foreground="{StaticResource TextForeground}"
|
||||||
VerticalAlignment="Center"
|
Margin="0,0,0,1"/>
|
||||||
Width="100"/>
|
|
||||||
<TextBlock x:Name="TxtConnectionStatus"
|
<ui:SimpleStackPanel Orientation="Vertical" Spacing="4">
|
||||||
Text="未连接"
|
<ui:ToggleSwitch x:Name="ToggleSwitchAutoUploadNotes"
|
||||||
FontSize="14"
|
Header="自动上传PNG笔记"
|
||||||
|
FontSize="14"
|
||||||
|
Foreground="{StaticResource TextForeground}"
|
||||||
|
Toggled="ToggleSwitchAutoUploadNotes_Toggled">
|
||||||
|
</ui:ToggleSwitch>
|
||||||
|
|
||||||
|
<TextBlock Text="启用后,保存的PNG截图将自动上传到所选班级的白板。"
|
||||||
|
FontSize="12"
|
||||||
Foreground="{StaticResource TextSecondary}"
|
Foreground="{StaticResource TextSecondary}"
|
||||||
VerticalAlignment="Center"/>
|
TextWrapping="Wrap"
|
||||||
|
Margin="0,0,0,2"/>
|
||||||
|
|
||||||
|
<ui:SimpleStackPanel Orientation="Horizontal" Spacing="12"
|
||||||
|
IsEnabled="{Binding ElementName=ToggleSwitchAutoUploadNotes, Path=IsOn}">
|
||||||
|
<TextBlock Text="上传延迟时间:"
|
||||||
|
FontSize="14"
|
||||||
|
Foreground="{StaticResource TextForeground}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Width="120"/>
|
||||||
|
<TextBox x:Name="TxtUploadDelayMinutes"
|
||||||
|
FontSize="14"
|
||||||
|
Background="#18181b"
|
||||||
|
Foreground="{StaticResource TextForeground}"
|
||||||
|
BorderBrush="{StaticResource BorderBrush}"
|
||||||
|
BorderThickness="1"
|
||||||
|
MinWidth="100"
|
||||||
|
Height="32"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
VerticalContentAlignment="Center"
|
||||||
|
HorizontalContentAlignment="Left"
|
||||||
|
TextChanged="TxtUploadDelayMinutes_TextChanged"
|
||||||
|
PreviewTextInput="TxtUploadDelayMinutes_PreviewTextInput">
|
||||||
|
<TextBox.Style>
|
||||||
|
<Style TargetType="TextBox">
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="TextBox">
|
||||||
|
<Border Background="{TemplateBinding Background}"
|
||||||
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
CornerRadius="6">
|
||||||
|
<ScrollViewer x:Name="PART_ContentHost"
|
||||||
|
Margin="12,0"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
</TextBox.Style>
|
||||||
|
</TextBox>
|
||||||
|
<TextBlock Text="分钟"
|
||||||
|
FontSize="14"
|
||||||
|
Foreground="{StaticResource TextSecondary}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="0,0,0,0"/>
|
||||||
|
</ui:SimpleStackPanel>
|
||||||
|
|
||||||
|
<TextBlock Text="设置上传延迟时间(0-60分钟),可以在保存后等待一段时间再上传。"
|
||||||
|
FontSize="12"
|
||||||
|
Foreground="{StaticResource TextSecondary}"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Margin="0,2,0,0"/>
|
||||||
</ui:SimpleStackPanel>
|
</ui:SimpleStackPanel>
|
||||||
|
|
||||||
<Line HorizontalAlignment="Stretch"
|
<Line HorizontalAlignment="Stretch"
|
||||||
X1="0" Y1="0" X2="1" Y2="0"
|
X1="0" Y1="0" X2="1" Y2="0"
|
||||||
Stroke="{StaticResource BorderBrush}"
|
Stroke="{StaticResource BorderBrush}"
|
||||||
StrokeThickness="1"
|
StrokeThickness="1"
|
||||||
Margin="0,8,0,12"/>
|
Margin="0,2,0,1"/>
|
||||||
|
|
||||||
<!-- 操作按钮 -->
|
<!-- 操作按钮 -->
|
||||||
<ui:SimpleStackPanel Orientation="Horizontal" Spacing="12" Margin="0,8,0,0">
|
<ui:SimpleStackPanel Orientation="Horizontal" Spacing="12" Margin="0,8,0,0">
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using Ink_Canvas.Helpers;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
@@ -34,6 +35,9 @@ namespace Ink_Canvas.Windows
|
|||||||
// 加载保存的token
|
// 加载保存的token
|
||||||
LoadUserToken();
|
LoadUserToken();
|
||||||
|
|
||||||
|
// 加载自动上传设置
|
||||||
|
LoadAutoUploadSettings();
|
||||||
|
|
||||||
// 初始化API客户端(优先使用用户token)
|
// 初始化API客户端(优先使用用户token)
|
||||||
InitializeApiClient();
|
InitializeApiClient();
|
||||||
|
|
||||||
@@ -272,6 +276,98 @@ namespace Ink_Canvas.Windows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加载自动上传设置
|
||||||
|
/// </summary>
|
||||||
|
private void LoadAutoUploadSettings()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (MainWindow.Settings?.Dlass != null)
|
||||||
|
{
|
||||||
|
ToggleSwitchAutoUploadNotes.IsOn = MainWindow.Settings.Dlass.IsAutoUploadNotes;
|
||||||
|
var delayMinutes = MainWindow.Settings.Dlass.AutoUploadDelayMinutes;
|
||||||
|
if (delayMinutes < 0 || delayMinutes > 60)
|
||||||
|
{
|
||||||
|
delayMinutes = 0;
|
||||||
|
}
|
||||||
|
TxtUploadDelayMinutes.Text = delayMinutes.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"加载自动上传设置时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自动上传开关切换事件
|
||||||
|
/// </summary>
|
||||||
|
private void ToggleSwitchAutoUploadNotes_Toggled(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (MainWindow.Settings?.Dlass != null)
|
||||||
|
{
|
||||||
|
MainWindow.Settings.Dlass.IsAutoUploadNotes = ToggleSwitchAutoUploadNotes.IsOn;
|
||||||
|
MainWindow.SaveSettingsToFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"保存自动上传设置时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 上传延迟时间输入框文本改变事件
|
||||||
|
/// </summary>
|
||||||
|
private void TxtUploadDelayMinutes_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (MainWindow.Settings?.Dlass != null && int.TryParse(TxtUploadDelayMinutes.Text, out int delayMinutes))
|
||||||
|
{
|
||||||
|
// 限制范围在0-60分钟
|
||||||
|
if (delayMinutes < 0)
|
||||||
|
{
|
||||||
|
delayMinutes = 0;
|
||||||
|
TxtUploadDelayMinutes.Text = "0";
|
||||||
|
}
|
||||||
|
else if (delayMinutes > 60)
|
||||||
|
{
|
||||||
|
delayMinutes = 60;
|
||||||
|
TxtUploadDelayMinutes.Text = "60";
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow.Settings.Dlass.AutoUploadDelayMinutes = delayMinutes;
|
||||||
|
MainWindow.SaveSettingsToFile();
|
||||||
|
}
|
||||||
|
else if (string.IsNullOrWhiteSpace(TxtUploadDelayMinutes.Text))
|
||||||
|
{
|
||||||
|
// 空文本时设置为0
|
||||||
|
if (MainWindow.Settings?.Dlass != null)
|
||||||
|
{
|
||||||
|
MainWindow.Settings.Dlass.AutoUploadDelayMinutes = 0;
|
||||||
|
MainWindow.SaveSettingsToFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"保存上传延迟时间时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 上传延迟时间输入框预览文本输入事件(只允许数字)
|
||||||
|
/// </summary>
|
||||||
|
private void TxtUploadDelayMinutes_PreviewTextInput(object sender, TextCompositionEventArgs e)
|
||||||
|
{
|
||||||
|
Regex regex = new Regex("[^0-9]+");
|
||||||
|
e.Handled = regex.IsMatch(e.Text);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 标题栏拖动事件
|
/// 标题栏拖动事件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user