框架优化
This commit is contained in:
@@ -1,47 +0,0 @@
|
|||||||
using BaseFrame.ViewModels;
|
|
||||||
using BaseFrame.ViewModels.Dialogs;
|
|
||||||
using BaseFrame.Views;
|
|
||||||
using BaseFrame.Views.Dialogs;
|
|
||||||
using Castle.DynamicProxy;
|
|
||||||
using ECCS.Views;
|
|
||||||
using System.Configuration;
|
|
||||||
using System.Data;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Windows;
|
|
||||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
|
||||||
|
|
||||||
namespace BaseFrame
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Interaction logic for App.xaml
|
|
||||||
/// </summary>
|
|
||||||
public partial class App : PrismApplication
|
|
||||||
{
|
|
||||||
protected override Window CreateShell()
|
|
||||||
{
|
|
||||||
return Container.Resolve<ShellView>();
|
|
||||||
}
|
|
||||||
protected override void OnInitialized()
|
|
||||||
{
|
|
||||||
base.OnInitialized();
|
|
||||||
|
|
||||||
var regionManager = Container.Resolve<IRegionManager>();
|
|
||||||
regionManager.RequestNavigate("ShellViewManager", "MonitorView");
|
|
||||||
}
|
|
||||||
protected override void RegisterTypes(IContainerRegistry containerRegistry)
|
|
||||||
{
|
|
||||||
//注册视图
|
|
||||||
containerRegistry.RegisterForNavigation<MonitorView>("MonitorView");
|
|
||||||
containerRegistry.RegisterForNavigation<SettingView>("SettingView");
|
|
||||||
containerRegistry.RegisterForNavigation<UpdateInfoView>("UpdateInfoView");
|
|
||||||
//注册弹窗
|
|
||||||
containerRegistry.RegisterDialog<MessageBoxView, MessageBoxViewModel>("MessageBox");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
using Newtonsoft.Json;
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace ECCS
|
|
||||||
{
|
|
||||||
public sealed class MultidimensionalTableConfig
|
|
||||||
{
|
|
||||||
private static readonly object _lock = new();
|
|
||||||
private static MultidimensionalTableConfig? _instance;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 单例实例(首次访问自动从文件加载)
|
|
||||||
/// </summary>
|
|
||||||
public static MultidimensionalTableConfig Instance
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
if (_instance == null)
|
|
||||||
{
|
|
||||||
_instance = Load();
|
|
||||||
}
|
|
||||||
return _instance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// exe 目录下的 config.json
|
|
||||||
/// </summary>
|
|
||||||
[JsonIgnore]
|
|
||||||
private static string ConfigFilePath =>
|
|
||||||
Path.Combine(AppContext.BaseDirectory, "config.json");
|
|
||||||
|
|
||||||
// ===== 配置项 =====
|
|
||||||
public string AppToken { get; set; }
|
|
||||||
public string DefaultTableId { get; set; }
|
|
||||||
public bool DefaultTableIsDeleted { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 保存到 config.json
|
|
||||||
/// </summary>
|
|
||||||
public void Save()
|
|
||||||
{
|
|
||||||
var json = JsonConvert.SerializeObject(this, Formatting.Indented);
|
|
||||||
File.WriteAllText(ConfigFilePath, json);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 从 config.json 加载
|
|
||||||
/// </summary>
|
|
||||||
private static MultidimensionalTableConfig Load()
|
|
||||||
{
|
|
||||||
if (!File.Exists(ConfigFilePath))
|
|
||||||
{
|
|
||||||
return new MultidimensionalTableConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
var json = File.ReadAllText(ConfigFilePath);
|
|
||||||
return JsonConvert.DeserializeObject<MultidimensionalTableConfig>(json)
|
|
||||||
?? new MultidimensionalTableConfig();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
|
|
||||||
namespace Common.DTOS
|
|
||||||
{
|
|
||||||
public class FeishuResponse<T>
|
|
||||||
{
|
|
||||||
[JsonProperty("code")]
|
|
||||||
public int Code { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("msg")]
|
|
||||||
public string Msg { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("data")]
|
|
||||||
public T Data { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#region 创建多维表格返回数据
|
|
||||||
public class CreateBitableAppData
|
|
||||||
{
|
|
||||||
[JsonProperty("app")]
|
|
||||||
public AppInfo App { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AppInfo
|
|
||||||
{
|
|
||||||
[JsonProperty("app_token")]
|
|
||||||
public string AppToken { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("default_table_id")]
|
|
||||||
public string DefaultTableId { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("folder_token")]
|
|
||||||
public string FolderToken { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("name")]
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("url")]
|
|
||||||
public string Url { get; set; }
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 新增数据表返回数据
|
|
||||||
public class CreateTableData
|
|
||||||
{
|
|
||||||
[JsonProperty("default_view_id")]
|
|
||||||
public string DefaultViewId { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("field_id_list")]
|
|
||||||
public List<string> FieldIdList { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("table_id")]
|
|
||||||
public string TableId { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 查询数据表列表返回数据
|
|
||||||
|
|
||||||
public class QueryTableListData
|
|
||||||
{
|
|
||||||
[JsonProperty("has_more")]
|
|
||||||
public bool HasMore { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("items")]
|
|
||||||
public List<TableItem> Items { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("page_token")]
|
|
||||||
public string PageToken { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("total")]
|
|
||||||
public int Total { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TableItem
|
|
||||||
{
|
|
||||||
[JsonProperty("name")]
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("revision")]
|
|
||||||
public int Revision { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("table_id")]
|
|
||||||
public string TableId { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 更新或新增记录返回数据
|
|
||||||
|
|
||||||
public class CreateRecordData
|
|
||||||
{
|
|
||||||
[JsonProperty("record")]
|
|
||||||
public RecordInfo Record { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RecordInfo
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 字段数据(字段名 -> 值)
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("fields")]
|
|
||||||
public Dictionary<string, object> Fields { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("id")]
|
|
||||||
public string Id { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("record_id")]
|
|
||||||
public string RecordId { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 查询记录返回数据
|
|
||||||
public class QueryRecordListData
|
|
||||||
{
|
|
||||||
[JsonProperty("has_more")]
|
|
||||||
public bool HasMore { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("items")]
|
|
||||||
public List<RecordItem> Items { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("total")]
|
|
||||||
public int Total { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RecordItem
|
|
||||||
{
|
|
||||||
[JsonProperty("record_id")]
|
|
||||||
public string RecordId { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("fields")]
|
|
||||||
public Dictionary<string, object> Fields { get; set; }
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 多行创建返回数据
|
|
||||||
public class CreateRecordsRequest
|
|
||||||
{
|
|
||||||
[JsonProperty("records")]
|
|
||||||
public List<CreateRecordItem> Records { get; set; }
|
|
||||||
}
|
|
||||||
public class CreateRecordItem
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 字段数据(字段名 -> 值)
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("fields")]
|
|
||||||
public Dictionary<string, object> Fields { get; set; }
|
|
||||||
[JsonProperty("id")]
|
|
||||||
public string Id { get; set; }
|
|
||||||
|
|
||||||
[JsonProperty("record_id")]
|
|
||||||
public string RecordId { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
112
Common/MiniDump.cs
Normal file
112
Common/MiniDump.cs
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Common
|
||||||
|
{
|
||||||
|
public static class MiniDump
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
public enum Option : uint
|
||||||
|
{
|
||||||
|
Normal = 0x00000000,
|
||||||
|
WithDataSegs = 0x00000001,
|
||||||
|
WithFullMemory = 0x00000002,
|
||||||
|
WithHandleData = 0x00000004,
|
||||||
|
FilterMemory = 0x00000008,
|
||||||
|
ScanMemory = 0x00000010,
|
||||||
|
WithUnloadedModules = 0x00000020,
|
||||||
|
WithIndirectlyReferencedMemory = 0x00000040,
|
||||||
|
FilterModulePaths = 0x00000080,
|
||||||
|
WithProcessThreadData = 0x00000100,
|
||||||
|
WithPrivateReadWriteMemory = 0x00000200,
|
||||||
|
WithoutOptionalData = 0x00000400,
|
||||||
|
WithFullMemoryInfo = 0x00000800,
|
||||||
|
WithThreadInfo = 0x00001000,
|
||||||
|
WithCodeSegs = 0x00002000,
|
||||||
|
WithoutAuxiliaryState = 0x00004000,
|
||||||
|
WithFullAuxiliaryState = 0x00008000,
|
||||||
|
WithPrivateWriteCopyMemory = 0x00010000,
|
||||||
|
IgnoreInaccessibleMemory = 0x00020000,
|
||||||
|
ValidTypeFlags = 0x0003ffff,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ExceptionInfo
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Present
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 4)] // Pack=4 is important! So it works also for x64!
|
||||||
|
struct MiniDumpExceptionInformation
|
||||||
|
{
|
||||||
|
public uint ThreadId;
|
||||||
|
public IntPtr ExceptionPointers;
|
||||||
|
[MarshalAs(UnmanagedType.Bool)]
|
||||||
|
public bool ClientPointers;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MiniDumpWriteDump function declarations
|
||||||
|
[DllImport("dbghelp.dll", EntryPoint = "MiniDumpWriteDump", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||||
|
static extern bool MiniDumpWriteDump(IntPtr hProcess, uint processId, SafeHandle hFile, uint dumpType, ref MiniDumpExceptionInformation expParam, IntPtr userStreamParam, IntPtr callbackParam);
|
||||||
|
|
||||||
|
[DllImport("dbghelp.dll", EntryPoint = "MiniDumpWriteDump", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
|
||||||
|
static extern bool MiniDumpWriteDump(IntPtr hProcess, uint processId, SafeHandle hFile, uint dumpType, IntPtr expParam, IntPtr userStreamParam, IntPtr callbackParam);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
|
||||||
|
static extern uint GetCurrentThreadId();
|
||||||
|
|
||||||
|
static bool Write(SafeHandle fileHandle, Option options, ExceptionInfo exceptionInfo, Exception exception = null)
|
||||||
|
{
|
||||||
|
Process currentProcess = Process.GetCurrentProcess();
|
||||||
|
IntPtr currentProcessHandle = currentProcess.Handle;
|
||||||
|
uint currentProcessId = (uint)currentProcess.Id;
|
||||||
|
|
||||||
|
MiniDumpExceptionInformation exp;
|
||||||
|
exp.ThreadId = GetCurrentThreadId();
|
||||||
|
exp.ClientPointers = false;
|
||||||
|
exp.ExceptionPointers = IntPtr.Zero;
|
||||||
|
|
||||||
|
if (exceptionInfo == ExceptionInfo.Present && exception != null)
|
||||||
|
{
|
||||||
|
// Get exception pointers
|
||||||
|
exp.ExceptionPointers = Marshal.GetExceptionPointers();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write dump
|
||||||
|
bool result = exp.ExceptionPointers == IntPtr.Zero
|
||||||
|
? MiniDumpWriteDump(currentProcessHandle, currentProcessId, fileHandle, (uint)options, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero)
|
||||||
|
: MiniDumpWriteDump(currentProcessHandle, currentProcessId, fileHandle, (uint)options, ref exp, IntPtr.Zero, IntPtr.Zero);
|
||||||
|
|
||||||
|
if (exception != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static Boolean TryDump(String dmpPath, Option dmpType = Option.Normal, Exception exception = null)
|
||||||
|
{
|
||||||
|
var path = Path.Combine(Environment.CurrentDirectory, dmpPath);
|
||||||
|
var dir = Path.GetDirectoryName(path);
|
||||||
|
if (dir != null && !Directory.Exists(dir))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var fs = new FileStream(path, FileMode.Create))
|
||||||
|
{
|
||||||
|
return Write(fs.SafeFileHandle, dmpType, exception == null ? ExceptionInfo.None : ExceptionInfo.Present, exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.14.36221.1
|
VisualStudioVersion = 17.14.36221.1
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ECCS", "BaseFrame\ECCS.csproj", "{FC10E4D4-0AA3-487B-B023-F8D2949E45ED}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Model", "Model\Model.csproj", "{6D9764D9-B4DA-43E2-A9D7-40A6C871A6B3}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Model", "Model\Model.csproj", "{6D9764D9-B4DA-43E2-A9D7-40A6C871A6B3}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logger", "Logger\Logger.csproj", "{9150C6A9-AE8D-42C9-8B2D-9DD04A3E7E74}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logger", "Logger\Logger.csproj", "{9150C6A9-AE8D-42C9-8B2D-9DD04A3E7E74}"
|
||||||
@@ -15,16 +13,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Service", "Service\Service.
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "Common\Common.csproj", "{C769E6C6-55E9-40C3-A611-9EFAB101BE6A}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "Common\Common.csproj", "{C769E6C6-55E9-40C3-A611-9EFAB101BE6A}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LAEPS", "LAEPS\LAEPS.csproj", "{5EC9A233-D154-4B77-6911-063269A883E9}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{FC10E4D4-0AA3-487B-B023-F8D2949E45ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{FC10E4D4-0AA3-487B-B023-F8D2949E45ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{FC10E4D4-0AA3-487B-B023-F8D2949E45ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{FC10E4D4-0AA3-487B-B023-F8D2949E45ED}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{6D9764D9-B4DA-43E2-A9D7-40A6C871A6B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{6D9764D9-B4DA-43E2-A9D7-40A6C871A6B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{6D9764D9-B4DA-43E2-A9D7-40A6C871A6B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{6D9764D9-B4DA-43E2-A9D7-40A6C871A6B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{6D9764D9-B4DA-43E2-A9D7-40A6C871A6B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{6D9764D9-B4DA-43E2-A9D7-40A6C871A6B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@@ -45,6 +41,10 @@ Global
|
|||||||
{C769E6C6-55E9-40C3-A611-9EFAB101BE6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{C769E6C6-55E9-40C3-A611-9EFAB101BE6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{C769E6C6-55E9-40C3-A611-9EFAB101BE6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{C769E6C6-55E9-40C3-A611-9EFAB101BE6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{C769E6C6-55E9-40C3-A611-9EFAB101BE6A}.Release|Any CPU.Build.0 = Release|Any CPU
|
{C769E6C6-55E9-40C3-A611-9EFAB101BE6A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{5EC9A233-D154-4B77-6911-063269A883E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{5EC9A233-D154-4B77-6911-063269A883E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{5EC9A233-D154-4B77-6911-063269A883E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{5EC9A233-D154-4B77-6911-063269A883E9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<prism:PrismApplication x:Class="BaseFrame.App"
|
<prism:PrismApplication x:Class="LAEPS.App"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:local="clr-namespace:BaseFrame"
|
xmlns:local="clr-namespace:LAEPS"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:prism="http://prismlibrary.com/">
|
xmlns:prism="http://prismlibrary.com/">
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
69
LAEPS/App.xaml.cs
Normal file
69
LAEPS/App.xaml.cs
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
using LAEPS.ViewModels;
|
||||||
|
using LAEPS.ViewModels.Dialogs;
|
||||||
|
using LAEPS.Views;
|
||||||
|
using LAEPS.Views.Dialogs;
|
||||||
|
using Castle.DynamicProxy;
|
||||||
|
using LAEPS.Views;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Data;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Windows;
|
||||||
|
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||||
|
using LAEPS.PubEvent;
|
||||||
|
using Notifications.Wpf.Core;
|
||||||
|
using Logger;
|
||||||
|
using Common;
|
||||||
|
|
||||||
|
namespace LAEPS
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for App.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class App : PrismApplication
|
||||||
|
{
|
||||||
|
protected override Window CreateShell()
|
||||||
|
{
|
||||||
|
//UI线程未捕获异常处理事件
|
||||||
|
this.DispatcherUnhandledException += OnDispatcherUnhandledException;
|
||||||
|
//Task线程内未捕获异常处理事件
|
||||||
|
TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
|
||||||
|
////多线程异常
|
||||||
|
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
|
||||||
|
return Container.Resolve<ShellView>();
|
||||||
|
}
|
||||||
|
private void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
|
||||||
|
{
|
||||||
|
//通常全局异常捕捉的都是致命信息
|
||||||
|
LoggerHelper.Error(e.Exception.Message,e.Exception.StackTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
|
||||||
|
{
|
||||||
|
LoggerHelper.Error(e.Exception.Message, e.Exception.StackTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||||
|
{
|
||||||
|
//记录dump文件
|
||||||
|
Exception ex = e.ExceptionObject as Exception;
|
||||||
|
MiniDump.TryDump($"dumps\\Error_{DateTime.Now:yyyy-MM-dd HH-mm-ss-ms}.dmp", MiniDump.Option.WithFullMemory, ex);
|
||||||
|
}
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
var login=Container.Resolve<LoginView>();
|
||||||
|
login.Show();
|
||||||
|
}
|
||||||
|
protected override void RegisterTypes(IContainerRegistry containerRegistry)
|
||||||
|
{
|
||||||
|
//注册视图
|
||||||
|
containerRegistry.RegisterForNavigation<MainView>("MainView");
|
||||||
|
containerRegistry.RegisterForNavigation<SettingView>("SettingView");
|
||||||
|
containerRegistry.RegisterForNavigation<UpdateInfoView>("UpdateInfoView");
|
||||||
|
//注册弹窗
|
||||||
|
containerRegistry.RegisterDialog<MessageBoxView, MessageBoxViewModel>("MessageBox");
|
||||||
|
// 注册通知管理器
|
||||||
|
INotificationManager NotificationManager = new NotificationManager();
|
||||||
|
containerRegistry.RegisterInstance<INotificationManager>(NotificationManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
|
|
||||||
namespace BaseFrame.Converters
|
namespace LAEPS.Converters
|
||||||
{
|
{
|
||||||
public class BooleanToVisibilityConverter : IValueConverter
|
public class BooleanToVisibilityConverter : IValueConverter
|
||||||
{
|
{
|
||||||
52
LAEPS/Helpers/PasswordBoxHelper.cs
Normal file
52
LAEPS/Helpers/PasswordBoxHelper.cs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace LAEPS.Helpers
|
||||||
|
{
|
||||||
|
public static class PasswordBoxHelper
|
||||||
|
{
|
||||||
|
public static readonly DependencyProperty PasswordProperty =
|
||||||
|
DependencyProperty.RegisterAttached(
|
||||||
|
"Password",
|
||||||
|
typeof(string),
|
||||||
|
typeof(PasswordBoxHelper),
|
||||||
|
new FrameworkPropertyMetadata(
|
||||||
|
string.Empty,
|
||||||
|
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
|
||||||
|
OnPasswordPropertyChanged));
|
||||||
|
|
||||||
|
public static void SetPassword(DependencyObject d, string value)
|
||||||
|
=> d.SetValue(PasswordProperty, value);
|
||||||
|
|
||||||
|
public static string GetPassword(DependencyObject d)
|
||||||
|
=> (string)d.GetValue(PasswordProperty);
|
||||||
|
|
||||||
|
private static void OnPasswordPropertyChanged(
|
||||||
|
DependencyObject d,
|
||||||
|
DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (d is PasswordBox pb)
|
||||||
|
{
|
||||||
|
pb.PasswordChanged -= PasswordChanged;
|
||||||
|
if (pb.Password != (string)e.NewValue)
|
||||||
|
{
|
||||||
|
pb.Password = (string)e.NewValue;
|
||||||
|
}
|
||||||
|
pb.PasswordChanged += PasswordChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void PasswordChanged(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is PasswordBox pb)
|
||||||
|
{
|
||||||
|
SetPassword(pb, pb.Password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,6 +38,7 @@
|
|||||||
<PackageReference Include="MaterialDesignThemes" Version="5.3.0" />
|
<PackageReference Include="MaterialDesignThemes" Version="5.3.0" />
|
||||||
<PackageReference Include="MaterialDesignThemes.MahApps" Version="5.3.0" />
|
<PackageReference Include="MaterialDesignThemes.MahApps" Version="5.3.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||||
|
<PackageReference Include="Notifications.Wpf.Core" Version="2.0.1" />
|
||||||
<PackageReference Include="Prism.Unity" Version="9.0.537" />
|
<PackageReference Include="Prism.Unity" Version="9.0.537" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
12
LAEPS/PubEvent/LoginSuccessEvent.cs
Normal file
12
LAEPS/PubEvent/LoginSuccessEvent.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace LAEPS.PubEvent
|
||||||
|
{
|
||||||
|
public class LoginSuccessEvent:PubSubEvent
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace BaseFrame.PubEvent
|
namespace LAEPS.PubEvent
|
||||||
{
|
{
|
||||||
public class OverlayEvent : PubSubEvent<bool>
|
public class OverlayEvent : PubSubEvent<bool>
|
||||||
{
|
{
|
||||||
@@ -4,7 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace BaseFrame.PubEvent
|
namespace LAEPS.PubEvent
|
||||||
{
|
{
|
||||||
public class WaitingEvent : PubSubEvent<bool>
|
public class WaitingEvent : PubSubEvent<bool>
|
||||||
{
|
{
|
||||||
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
@@ -1,11 +1,11 @@
|
|||||||
using BaseFrame.PubEvent;
|
using LAEPS.PubEvent;
|
||||||
using ControlzEx.Standard;
|
using ControlzEx.Standard;
|
||||||
using ECCS.ViewModels;
|
using LAEPS.ViewModels;
|
||||||
using Prism.Commands;
|
using Prism.Commands;
|
||||||
using Prism.Mvvm;
|
using Prism.Mvvm;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace BaseFrame.ViewModels.Dialogs
|
namespace LAEPS.ViewModels.Dialogs
|
||||||
{
|
{
|
||||||
public class MessageBoxViewModel : DialogViewModelBase
|
public class MessageBoxViewModel : DialogViewModelBase
|
||||||
{
|
{
|
||||||
40
LAEPS/ViewModels/LoginViewModel.cs
Normal file
40
LAEPS/ViewModels/LoginViewModel.cs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
using LAEPS.PubEvent;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Input;
|
||||||
|
|
||||||
|
namespace LAEPS.ViewModels
|
||||||
|
{
|
||||||
|
public class LoginViewModel:BindableBase
|
||||||
|
{
|
||||||
|
#region 属性
|
||||||
|
private string _Password;
|
||||||
|
public string Password
|
||||||
|
{
|
||||||
|
get => _Password;
|
||||||
|
set => SetProperty(ref _Password, value);
|
||||||
|
}
|
||||||
|
private string _Account;
|
||||||
|
public string Account
|
||||||
|
{
|
||||||
|
get => _Account;
|
||||||
|
set => SetProperty(ref _Account, value);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
public ICommand LoginCommand { get; set; }
|
||||||
|
private IEventAggregator _eventAggregator;
|
||||||
|
public LoginViewModel(IContainerProvider containerProvider)
|
||||||
|
{
|
||||||
|
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||||
|
LoginCommand = new AsyncDelegateCommand(OnLogin);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OnLogin()
|
||||||
|
{
|
||||||
|
_eventAggregator.GetEvent<LoginSuccessEvent>().Publish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using BaseFrame.PubEvent;
|
using LAEPS.PubEvent;
|
||||||
using ECCS.ViewModels;
|
using LAEPS.ViewModels;
|
||||||
|
using Logger;
|
||||||
using NLog;
|
using NLog;
|
||||||
using Prism.Dialogs;
|
using Prism.Dialogs;
|
||||||
using Prism.Events;
|
using Prism.Events;
|
||||||
@@ -11,9 +12,9 @@ using System.Text.RegularExpressions;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace BaseFrame.ViewModels
|
namespace LAEPS.ViewModels
|
||||||
{
|
{
|
||||||
public class MonitorViewModel : NavigateViewModelBase
|
public class MainViewModel : NavigateViewModelBase
|
||||||
{
|
{
|
||||||
#region 属性
|
#region 属性
|
||||||
|
|
||||||
@@ -24,11 +25,14 @@ namespace BaseFrame.ViewModels
|
|||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
public MonitorViewModel(IContainerProvider containerProvider) : base(containerProvider)
|
|
||||||
|
public MainViewModel(IContainerProvider containerProvider) : base(containerProvider)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region 命令处理
|
#region 命令处理
|
||||||
|
|
||||||
|
|
||||||
@@ -4,7 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace ECCS.ViewModels
|
namespace LAEPS.ViewModels
|
||||||
{
|
{
|
||||||
public class SettingViewModel : NavigateViewModelBase
|
public class SettingViewModel : NavigateViewModelBase
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
using BaseFrame.Views;
|
using LAEPS.PubEvent;
|
||||||
|
using LAEPS.Views;
|
||||||
using MaterialDesignThemes.Wpf;
|
using MaterialDesignThemes.Wpf;
|
||||||
|
using Notifications.Wpf.Core;
|
||||||
|
using Prism.Events;
|
||||||
|
using Prism.Ioc;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -9,7 +12,7 @@ using System.Threading.Tasks;
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace BaseFrame.ViewModels
|
namespace LAEPS.ViewModels
|
||||||
{
|
{
|
||||||
public class ShellViewModel : BindableBase
|
public class ShellViewModel : BindableBase
|
||||||
{
|
{
|
||||||
@@ -29,29 +32,45 @@ namespace BaseFrame.ViewModels
|
|||||||
public ICommand MaximizeCommand { get; set; }
|
public ICommand MaximizeCommand { get; set; }
|
||||||
public ICommand CloseCommand { get; set; }
|
public ICommand CloseCommand { get; set; }
|
||||||
public ICommand NavigateCommand { get; set; }
|
public ICommand NavigateCommand { get; set; }
|
||||||
|
public ICommand LoadCommand { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private IEventAggregator _eventAggregator;
|
private IEventAggregator _eventAggregator;
|
||||||
private IRegionManager _regionManager;
|
private IRegionManager _regionManager;
|
||||||
|
private IContainerProvider _containerProvider;
|
||||||
|
private INotificationManager _notificationManager;
|
||||||
public ShellViewModel( IContainerProvider containerProvider)
|
public ShellViewModel( IContainerProvider containerProvider)
|
||||||
{
|
{
|
||||||
|
_containerProvider= containerProvider;
|
||||||
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||||
_regionManager = containerProvider.Resolve<IRegionManager>();
|
_regionManager = containerProvider.Resolve<IRegionManager>();
|
||||||
|
_notificationManager = containerProvider.Resolve<INotificationManager>();
|
||||||
LeftDrawerOpenCommand = new DelegateCommand(LeftDrawerOpen);
|
LeftDrawerOpenCommand = new DelegateCommand(LeftDrawerOpen);
|
||||||
MinimizeCommand = new DelegateCommand<Window>(MinimizeWindow);
|
MinimizeCommand = new DelegateCommand<Window>(MinimizeWindow);
|
||||||
MaximizeCommand = new DelegateCommand<Window>(MaximizeWindow);
|
MaximizeCommand = new DelegateCommand<Window>(MaximizeWindow);
|
||||||
CloseCommand = new DelegateCommand<Window>(CloseWindow);
|
CloseCommand = new DelegateCommand<Window>(CloseWindow);
|
||||||
NavigateCommand = new DelegateCommand<string>(Navigate);
|
NavigateCommand = new DelegateCommand<string>(Navigate);
|
||||||
|
LoadCommand = new DelegateCommand(Load);
|
||||||
|
//订阅登录成功事件
|
||||||
|
_eventAggregator.GetEvent<LoginSuccessEvent>().Subscribe(() =>
|
||||||
|
{
|
||||||
|
Application.Current.MainWindow.Show();
|
||||||
|
_regionManager.RequestNavigate("ShellViewManager", "MainView");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#region 命令处理
|
#region 命令处理
|
||||||
|
private void Load()
|
||||||
|
{
|
||||||
|
_notificationManager.ShowAsync(new NotificationContent { Title = "登录成功", Message = "", Type = NotificationType.Success });
|
||||||
|
}
|
||||||
private void Navigate(string content)
|
private void Navigate(string content)
|
||||||
{
|
{
|
||||||
switch (content)
|
switch (content)
|
||||||
{
|
{
|
||||||
case "监控界面":
|
case "主界面":
|
||||||
_regionManager.RequestNavigate("ShellViewManager", "MonitorView");
|
_regionManager.RequestNavigate("ShellViewManager", "MainView");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "设置界面":
|
case "设置界面":
|
||||||
@@ -6,7 +6,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace ECCS.ViewModels
|
namespace LAEPS.ViewModels
|
||||||
{
|
{
|
||||||
public class UpdateInfoViewModel : NavigateViewModelBase
|
public class UpdateInfoViewModel : NavigateViewModelBase
|
||||||
{
|
{
|
||||||
@@ -1,18 +1,21 @@
|
|||||||
using System;
|
using Notifications.Wpf.Core;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace ECCS.ViewModels
|
namespace LAEPS.ViewModels
|
||||||
{
|
{
|
||||||
public abstract class DialogViewModelBase : BindableBase,IDialogAware
|
public abstract class DialogViewModelBase : BindableBase,IDialogAware
|
||||||
{
|
{
|
||||||
public IEventAggregator _eventAggregator;
|
|
||||||
public DialogCloseListener RequestClose { get; set; }
|
public DialogCloseListener RequestClose { get; set; }
|
||||||
|
public IEventAggregator _eventAggregator;
|
||||||
|
private INotificationManager _notificationManager;
|
||||||
public DialogViewModelBase(IContainerProvider containerProvider)
|
public DialogViewModelBase(IContainerProvider containerProvider)
|
||||||
{
|
{
|
||||||
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||||
|
_notificationManager = containerProvider.Resolve<INotificationManager>();
|
||||||
}
|
}
|
||||||
#region Dialog
|
#region Dialog
|
||||||
|
|
||||||
@@ -1,21 +1,23 @@
|
|||||||
using System;
|
using Notifications.Wpf.Core;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace ECCS.ViewModels
|
namespace LAEPS.ViewModels
|
||||||
{
|
{
|
||||||
public abstract class NavigateViewModelBase : BindableBase, INavigationAware
|
public abstract class NavigateViewModelBase : BindableBase, INavigationAware
|
||||||
{
|
{
|
||||||
public DialogCloseListener RequestClose { get; set; }
|
public DialogCloseListener RequestClose { get; set; }
|
||||||
public IEventAggregator _eventAggregator;
|
public IEventAggregator _eventAggregator;
|
||||||
public IDialogService _dialogService;
|
public IDialogService _dialogService;
|
||||||
|
private INotificationManager _notificationManager;
|
||||||
public NavigateViewModelBase(IContainerProvider containerProvider)
|
public NavigateViewModelBase(IContainerProvider containerProvider)
|
||||||
{
|
{
|
||||||
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||||
_dialogService = containerProvider.Resolve<IDialogService>();
|
_dialogService = containerProvider.Resolve<IDialogService>();
|
||||||
|
_notificationManager = containerProvider.Resolve<INotificationManager>();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Navigation
|
#region Navigation
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
<UserControl x:Class="BaseFrame.Views.Dialogs.MessageBoxView"
|
<UserControl x:Class="LAEPS.Views.Dialogs.MessageBoxView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="clr-namespace:BaseFrame.Views.Dialogs"
|
xmlns:local="clr-namespace:LAEPS.Views.Dialogs"
|
||||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
xmlns:prism="http://prismlibrary.com/"
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
@@ -13,7 +13,7 @@ using System.Windows.Media.Imaging;
|
|||||||
using System.Windows.Navigation;
|
using System.Windows.Navigation;
|
||||||
using System.Windows.Shapes;
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
namespace BaseFrame.Views.Dialogs
|
namespace LAEPS.Views.Dialogs
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// MessageBoxView.xaml 的交互逻辑
|
/// MessageBoxView.xaml 的交互逻辑
|
||||||
151
LAEPS/Views/LoginView.xaml
Normal file
151
LAEPS/Views/LoginView.xaml
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
<mah:MetroWindow xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:helpers="clr-namespace:LAEPS.Helpers"
|
||||||
|
x:Class="LAEPS.Views.LoginView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||||
|
xmlns:local="clr-namespace:LAEPS.Views"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Title="学习交流平台"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Height="315"
|
||||||
|
Width="420"
|
||||||
|
ResizeMode="NoResize">
|
||||||
|
|
||||||
|
<Window.Resources>
|
||||||
|
<Style TargetType="TextBox"
|
||||||
|
BasedOn="{StaticResource MahApps.Styles.TextBox}">
|
||||||
|
<Setter Property="FontSize"
|
||||||
|
Value="14" />
|
||||||
|
<Setter Property="BorderThickness"
|
||||||
|
Value="0,0,0,2" />
|
||||||
|
<Setter Property="BorderBrush"
|
||||||
|
Value="#E0E0E0" />
|
||||||
|
<Setter Property="Padding"
|
||||||
|
Value="5,8" />
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="Transparent" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style TargetType="PasswordBox"
|
||||||
|
BasedOn="{StaticResource MahApps.Styles.PasswordBox}">
|
||||||
|
<Setter Property="FontSize"
|
||||||
|
Value="14" />
|
||||||
|
<Setter Property="BorderThickness"
|
||||||
|
Value="0,0,0,2" />
|
||||||
|
<Setter Property="BorderBrush"
|
||||||
|
Value="#E0E0E0" />
|
||||||
|
<Setter Property="Padding"
|
||||||
|
Value="5,8" />
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="Transparent" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style TargetType="Button"
|
||||||
|
BasedOn="{StaticResource MahApps.Styles.Button.Flat}">
|
||||||
|
<Setter Property="FontSize"
|
||||||
|
Value="15" />
|
||||||
|
<Setter Property="FontWeight"
|
||||||
|
Value="SemiBold" />
|
||||||
|
<Setter Property="Foreground"
|
||||||
|
Value="White" />
|
||||||
|
<Setter Property="Background"
|
||||||
|
Value="#2196F3" />
|
||||||
|
<Setter Property="BorderThickness"
|
||||||
|
Value="0" />
|
||||||
|
<Setter Property="Margin"
|
||||||
|
Value="0,20,0,0" />
|
||||||
|
</Style>
|
||||||
|
</Window.Resources>
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="40" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<!-- 表单区域 -->
|
||||||
|
<Border Grid.Row="0"
|
||||||
|
Background="White"
|
||||||
|
Margin="20,20,20,0"
|
||||||
|
CornerRadius="5"
|
||||||
|
BorderThickness="1"
|
||||||
|
BorderBrush="#E0E0E0"
|
||||||
|
Padding="30,20">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
|
||||||
|
<Label Content="用户登录"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
FontSize="15"
|
||||||
|
Padding="3" />
|
||||||
|
<StackPanel Grid.Row="1">
|
||||||
|
|
||||||
|
<!-- 用户名输入 -->
|
||||||
|
<StackPanel Orientation="Vertical"
|
||||||
|
HorizontalAlignment="Center">
|
||||||
|
<StackPanel Orientation="Horizontal"
|
||||||
|
Margin="17">
|
||||||
|
<materialDesign:PackIcon Kind="Account" VerticalAlignment="Center"/>
|
||||||
|
<TextBox Text="{Binding Account}"
|
||||||
|
mah:TextBoxHelper.Watermark="请输入账号"
|
||||||
|
mah:TextBoxHelper.ClearTextButton="True"
|
||||||
|
VerticalContentAlignment="Center"
|
||||||
|
Width="180"
|
||||||
|
Height="30"
|
||||||
|
Padding="0" />
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- 密码输入 -->
|
||||||
|
<StackPanel Orientation="Vertical"
|
||||||
|
HorizontalAlignment="Center">
|
||||||
|
<StackPanel Orientation="Horizontal"
|
||||||
|
Margin="7">
|
||||||
|
<materialDesign:PackIcon Kind="Lock"
|
||||||
|
VerticalAlignment="Center" />
|
||||||
|
<PasswordBox helpers:PasswordBoxHelper.Password="{Binding Password, Mode=TwoWay}"
|
||||||
|
mah:TextBoxHelper.Watermark="请输入密码"
|
||||||
|
mah:TextBoxHelper.ClearTextButton="True"
|
||||||
|
VerticalContentAlignment="Center"
|
||||||
|
Width="180"
|
||||||
|
Height="30"
|
||||||
|
Padding="0" />
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- 登录按钮 -->
|
||||||
|
<Button Grid.Row="2"
|
||||||
|
Command="{Binding LoginCommand}"
|
||||||
|
Content="登 录"
|
||||||
|
Width="120"
|
||||||
|
Height="33"
|
||||||
|
mah:ControlsHelper.CornerRadius="5">
|
||||||
|
<Button.Effect>
|
||||||
|
<DropShadowEffect BlurRadius="8"
|
||||||
|
ShadowDepth="3"
|
||||||
|
Opacity="0.5" />
|
||||||
|
</Button.Effect>
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<!-- 底部版权信息 -->
|
||||||
|
<TextBlock Grid.Row="2"
|
||||||
|
Text="© 2025 大学生学习交流平台"
|
||||||
|
Foreground="#777"
|
||||||
|
FontSize="12"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Margin="0,10" />
|
||||||
|
</Grid>
|
||||||
|
</mah:MetroWindow>
|
||||||
38
LAEPS/Views/LoginView.xaml.cs
Normal file
38
LAEPS/Views/LoginView.xaml.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
using LAEPS.PubEvent;
|
||||||
|
using MahApps.Metro.Controls;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
using Path = System.IO.Path;
|
||||||
|
|
||||||
|
namespace LAEPS.Views
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Login.xaml 的交互逻辑
|
||||||
|
/// </summary>
|
||||||
|
public partial class LoginView : MetroWindow
|
||||||
|
{
|
||||||
|
public LoginView(IEventAggregator eventAggregator)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
//订阅登录成功事件
|
||||||
|
eventAggregator.GetEvent<LoginSuccessEvent>().Subscribe(() =>
|
||||||
|
{
|
||||||
|
this.Close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<UserControl x:Class="BaseFrame.Views.MonitorView"
|
<UserControl x:Class="LAEPS.Views.MainView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
@@ -10,6 +10,6 @@
|
|||||||
d:DesignHeight="1080"
|
d:DesignHeight="1080"
|
||||||
d:DesignWidth="1920">
|
d:DesignWidth="1920">
|
||||||
<Grid Background="Red">
|
<Grid Background="Red">
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
@@ -13,14 +13,14 @@ using System.Windows.Media.Imaging;
|
|||||||
using System.Windows.Navigation;
|
using System.Windows.Navigation;
|
||||||
using System.Windows.Shapes;
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
namespace BaseFrame.Views
|
namespace LAEPS.Views
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// MainView.xaml 的交互逻辑
|
/// MainView.xaml 的交互逻辑
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class MonitorView : UserControl
|
public partial class MainView : UserControl
|
||||||
{
|
{
|
||||||
public MonitorView()
|
public MainView()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<UserControl x:Class="ECCS.Views.SettingView"
|
<UserControl x:Class="LAEPS.Views.SettingView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
@@ -13,7 +13,7 @@ using System.Windows.Media.Imaging;
|
|||||||
using System.Windows.Navigation;
|
using System.Windows.Navigation;
|
||||||
using System.Windows.Shapes;
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
namespace ECCS.Views
|
namespace LAEPS.Views
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SettingView.xaml 的交互逻辑
|
/// SettingView.xaml 的交互逻辑
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<Window x:Class="BaseFrame.Views.ShellView"
|
<Window x:Class="LAEPS.Views.ShellView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
@@ -17,7 +17,11 @@
|
|||||||
<WindowChrome.WindowChrome>
|
<WindowChrome.WindowChrome>
|
||||||
<WindowChrome GlassFrameThickness="-1" />
|
<WindowChrome GlassFrameThickness="-1" />
|
||||||
</WindowChrome.WindowChrome>
|
</WindowChrome.WindowChrome>
|
||||||
|
<i:Interaction.Triggers>
|
||||||
|
<i:EventTrigger EventName="Loaded">
|
||||||
|
<i:InvokeCommandAction Command="{Binding LoadCommand}" />
|
||||||
|
</i:EventTrigger>
|
||||||
|
</i:Interaction.Triggers>
|
||||||
<materialDesign:DrawerHost x:Name="MainDrawerHost"
|
<materialDesign:DrawerHost x:Name="MainDrawerHost"
|
||||||
IsLeftDrawerOpen="{Binding IsLeftDrawerOpen, Mode=TwoWay}">
|
IsLeftDrawerOpen="{Binding IsLeftDrawerOpen, Mode=TwoWay}">
|
||||||
|
|
||||||
@@ -30,7 +34,7 @@
|
|||||||
Margin="16"
|
Margin="16"
|
||||||
Foreground="{DynamicResource PrimaryHueMidBrush}" />
|
Foreground="{DynamicResource PrimaryHueMidBrush}" />
|
||||||
<Separator Margin="0,0,0,8" />
|
<Separator Margin="0,0,0,8" />
|
||||||
<Button Content="监控界面"
|
<Button Content="主界面"
|
||||||
Command="{Binding NavigateCommand}"
|
Command="{Binding NavigateCommand}"
|
||||||
CommandParameter="{Binding Content, RelativeSource={RelativeSource Self}}"
|
CommandParameter="{Binding Content, RelativeSource={RelativeSource Self}}"
|
||||||
Style="{StaticResource MaterialDesignFlatButton}"
|
Style="{StaticResource MaterialDesignFlatButton}"
|
||||||
@@ -87,29 +91,9 @@
|
|||||||
<materialDesign:PackIcon Kind="Tools"
|
<materialDesign:PackIcon Kind="Tools"
|
||||||
Foreground="White" />
|
Foreground="White" />
|
||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
<MenuItem Header="系统设置"
|
<MenuItem Header="注销登录"
|
||||||
|
|
||||||
Foreground="Black" />
|
Foreground="Black" />
|
||||||
<MenuItem Header="数据"
|
|
||||||
Foreground="Black">
|
|
||||||
<MenuItem Header="数据查询"
|
|
||||||
Foreground="Black" />
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem Header="同星CAN"
|
|
||||||
Foreground="Black">
|
|
||||||
<MenuItem Header="连接/断开"
|
|
||||||
Foreground="Black" />
|
|
||||||
<MenuItem Header="通道映射"
|
|
||||||
Foreground="Black" />
|
|
||||||
<MenuItem Header="加载数据库"
|
|
||||||
Foreground="Black" />
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem Header="调试"
|
|
||||||
Foreground="Black">
|
|
||||||
<MenuItem Header="自动运行"
|
|
||||||
Foreground="Black" />
|
|
||||||
<MenuItem Header="清空数据库"
|
|
||||||
Foreground="Black" />
|
|
||||||
</MenuItem>
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
||||||
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using BaseFrame.PubEvent;
|
using LAEPS.PubEvent;
|
||||||
|
|
||||||
using Prism.Events;
|
using Prism.Events;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -15,7 +14,7 @@ using System.Windows.Media;
|
|||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
using System.Windows.Shapes;
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
namespace BaseFrame.Views
|
namespace LAEPS.Views
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ShellView.xaml 的交互逻辑
|
/// ShellView.xaml 的交互逻辑
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<UserControl x:Class="ECCS.Views.UpdateInfoView"
|
<UserControl x:Class="LAEPS.Views.UpdateInfoView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
@@ -13,7 +13,7 @@ using System.Windows.Media.Imaging;
|
|||||||
using System.Windows.Navigation;
|
using System.Windows.Navigation;
|
||||||
using System.Windows.Shapes;
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
namespace ECCS.Views
|
namespace LAEPS.Views
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// UpdateInfoView.xaml 的交互逻辑
|
/// UpdateInfoView.xaml 的交互逻辑
|
||||||
@@ -13,6 +13,16 @@ namespace Logger
|
|||||||
public static readonly ILogger Logger = LogManager.GetLogger("InfoLogger");
|
public static readonly ILogger Logger = LogManager.GetLogger("InfoLogger");
|
||||||
public static readonly ILogger sqlLogger = LogManager.GetLogger("SqlLogger");
|
public static readonly ILogger sqlLogger = LogManager.GetLogger("SqlLogger");
|
||||||
|
|
||||||
|
public static void Error(string message, string stackTrace)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(stackTrace))
|
||||||
|
{
|
||||||
|
string location = GetProjectStackLine(stackTrace);
|
||||||
|
message = $"{message} ({location})";
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Error(message);
|
||||||
|
}
|
||||||
// 解析堆栈,找到项目文件路径和行号
|
// 解析堆栈,找到项目文件路径和行号
|
||||||
public static string GetProjectStackLine(string stackTrace)
|
public static string GetProjectStackLine(string stackTrace)
|
||||||
{
|
{
|
||||||
@@ -24,7 +34,7 @@ namespace Logger
|
|||||||
foreach (var line in lines)
|
foreach (var line in lines)
|
||||||
{
|
{
|
||||||
// 匹配你项目的命名空间路径
|
// 匹配你项目的命名空间路径
|
||||||
if (line.Contains("BaseFrame"))
|
if (line.Contains("BOB"))
|
||||||
{
|
{
|
||||||
// 提取 "in 文件路径:line 行号"
|
// 提取 "in 文件路径:line 行号"
|
||||||
var match = Regex.Match(line, @"in (.+?):line (\d+)");
|
var match = Regex.Match(line, @"in (.+?):line (\d+)");
|
||||||
@@ -38,5 +48,6 @@ namespace Logger
|
|||||||
|
|
||||||
return lines[0].Trim(); // 如果找不到就返回第一条
|
return lines[0].Trim(); // 如果找不到就返回第一条
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
27
Model/Entity/BaseEntity.cs
Normal file
27
Model/Entity/BaseEntity.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using SqlSugar;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Model.Entity
|
||||||
|
{
|
||||||
|
public class BaseEntity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主键Id
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "id", ColumnDescription = "主键Id", IsPrimaryKey = true, CreateTableFieldSort = 0)]
|
||||||
|
public virtual long Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除状态
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnName = "IsDel", ColumnDescription = "删除状态(0、未删除;1、已删除)", ColumnDataType = "tinyint", DefaultValue = "0", CreateTableFieldSort = 106)]
|
||||||
|
public virtual byte IsDel { get; set; }
|
||||||
|
|
||||||
|
[SugarColumn(ColumnName = "CreateTime")]
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,4 +6,12 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="SqlSugarCore" Version="5.1.4.210" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="DTOS\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,97 +1,132 @@
|
|||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Security.Cryptography;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace ORM
|
namespace ORM
|
||||||
{
|
{
|
||||||
public static class DatabaseConfig
|
public class DatabaseConfig
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前数据库类型
|
/// 数据库连接类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static DbType DbConnectionType { get; private set; }
|
public static DbType DbConnectionType { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 数据库连接字符串
|
/// SQLite 数据库文件路径
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string DbConnectionString { get; private set; }
|
public static string DbConnectionString { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 默认 SQLite 文件路径(仅记录,不自动启用)
|
/// 数据租户Id
|
||||||
/// </summary>
|
|
||||||
public static string DefaultDbFilePath { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 租户 Id
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static int TenantId { get; private set; }
|
public static int TenantId { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 雪花算法DatacenterId,值范围:0至31
|
||||||
|
/// </summary>
|
||||||
public static int SnowFlakeDatacenterId { get; private set; }
|
public static int SnowFlakeDatacenterId { get; private set; }
|
||||||
public static int SnowFlakeWorkId { get; private set; }
|
|
||||||
|
|
||||||
static DatabaseConfig()
|
|
||||||
{
|
|
||||||
InitDefaultDbPath(); // 只生成路径,不指定 DB 类型/连接
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 生成默认 DB 路径 EXE目录/SQLDB/Data.db
|
/// 雪花算法WorkID,值范围:0至31
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static void InitDefaultDbPath()
|
public static int SnowFlakeWorkId { get; private set; }
|
||||||
{
|
|
||||||
string baseDir = AppDomain.CurrentDomain.BaseDirectory;
|
|
||||||
|
|
||||||
|
#region 不同数据库初始化方法
|
||||||
|
private static void InitSqlite()
|
||||||
|
{
|
||||||
|
DbConnectionType = DbType.Sqlite;
|
||||||
|
// 获取程序运行目录
|
||||||
|
string baseDir = AppDomain.CurrentDomain.BaseDirectory;
|
||||||
|
// 确保 SQLDB 文件夹存在
|
||||||
string folder = Path.Combine(baseDir, "SQLDB");
|
string folder = Path.Combine(baseDir, "SQLDB");
|
||||||
if (!Directory.Exists(folder))
|
if (!Directory.Exists(folder))
|
||||||
Directory.CreateDirectory(folder);
|
Directory.CreateDirectory(folder);
|
||||||
|
|
||||||
DefaultDbFilePath = Path.Combine(folder, "Data.db");
|
// 拼接数据库文件路径
|
||||||
|
string DBPath = Path.Combine(folder, "SQL.db");
|
||||||
|
DbConnectionString = $"Data Source={DBPath};Version=3;";
|
||||||
}
|
}
|
||||||
|
private static void InitMySql(string Server, int Port, string Database, string Uid,string Pwd)
|
||||||
/// <summary>
|
|
||||||
/// 手动设置数据库连接
|
|
||||||
/// </summary>
|
|
||||||
public static void SetConnection(string conn, DbType dbType)
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(conn))
|
DbConnectionType = DbType.MySql;
|
||||||
throw new Exception("数据库连接字符串为空");
|
DbConnectionString =
|
||||||
|
$"Server={Server};Port={Port};Database={Database};Uid={Uid};Pwd={Pwd};";
|
||||||
DbConnectionString = conn;
|
|
||||||
DbConnectionType = dbType;
|
|
||||||
}
|
}
|
||||||
|
private static void InitSqlServer(string server,int port,string database,string user,string password)
|
||||||
/// <summary>
|
|
||||||
/// 如果未 SetConnection,默认使用 SQLite + 默认路径
|
|
||||||
/// </summary>
|
|
||||||
public static void EnsureConnection()
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(DbConnectionString))
|
DbConnectionType = DbType.SqlServer;
|
||||||
|
|
||||||
|
DbConnectionString =
|
||||||
|
$"Data Source={server},{port};Initial Catalog={database};user={user};Password={password};";
|
||||||
|
}
|
||||||
|
private static void InitSqlServerLocalDb()
|
||||||
|
{
|
||||||
|
DbConnectionType = DbType.SqlServer;
|
||||||
|
string baseDir = AppDomain.CurrentDomain.BaseDirectory;
|
||||||
|
// 确保 SQLDB 文件夹存在
|
||||||
|
string folder = Path.Combine(baseDir, "SQLDB");
|
||||||
|
if (!Directory.Exists(folder))
|
||||||
|
Directory.CreateDirectory(folder);
|
||||||
|
|
||||||
|
// 拼接数据库文件路径
|
||||||
|
string DBPath = Path.Combine(folder, "SQL.db");
|
||||||
|
DbConnectionString =$@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog={DBPath};Integrated Security=True;";
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
/// <summary>
|
||||||
|
/// 设置数据库连接字符串(可手动覆盖)
|
||||||
|
/// </summary>
|
||||||
|
public static void SetDbConnection(string strConnection)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(strConnection))
|
||||||
{
|
{
|
||||||
DbConnectionString = $"Data Source={DefaultDbFilePath};";
|
throw new Exception("数据库连接字符串为空");
|
||||||
DbConnectionType = DbType.Sqlite;
|
|
||||||
}
|
}
|
||||||
|
DbConnectionString = strConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置租户并计算雪花算法节点
|
/// 设置数据租户Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void SetTenant(int tenantId)
|
public static void SetTenant(int nTenantId)
|
||||||
{
|
{
|
||||||
if (tenantId <= 10000)
|
if (nTenantId <= 10000)
|
||||||
|
{
|
||||||
throw new Exception("数据租户Id值需大于10000");
|
throw new Exception("数据租户Id值需大于10000");
|
||||||
|
}
|
||||||
|
TenantId = nTenantId;
|
||||||
|
SetSnowFlake((nTenantId - 10000) % 1024);
|
||||||
|
}
|
||||||
|
|
||||||
TenantId = tenantId;
|
/// <summary>
|
||||||
|
/// 将指定数字转换为雪花算法DatacenterId和WorkID
|
||||||
int snowId = (tenantId - 10000) % 1024;
|
/// </summary>
|
||||||
|
private static void SetSnowFlake(int nSnowFlakeId)
|
||||||
if (snowId is < 0 or > 1023)
|
{
|
||||||
|
if (nSnowFlakeId > 1023 || nSnowFlakeId < 0)
|
||||||
|
{
|
||||||
throw new Exception("雪花算法机器码值范围0至1023");
|
throw new Exception("雪花算法机器码值范围0至1023");
|
||||||
|
}
|
||||||
SnowFlakeDatacenterId = snowId >> 5;
|
SnowFlakeDatacenterId = nSnowFlakeId >> 5;
|
||||||
SnowFlakeWorkId = snowId & 31;
|
SnowFlakeWorkId = nSnowFlakeId & 31;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 检测数据库连接
|
||||||
|
/// </summary>
|
||||||
|
public static void CreateDatabaseAndCheckConnection(bool createDatabase = false, bool checkConnection = false)
|
||||||
|
{
|
||||||
|
//数据库不存在则创建数据库
|
||||||
|
if (createDatabase)
|
||||||
|
{
|
||||||
|
SqlSugarContext.DbContext.DbMaintenance.CreateDatabase();
|
||||||
|
}
|
||||||
|
// 检查数据库连接
|
||||||
|
if (checkConnection && !SqlSugarContext.DbContext.Ado.IsValidConnection())
|
||||||
|
{
|
||||||
|
throw new Exception("连接数据库失败");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,7 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.206" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Logger\Logger.csproj" />
|
<ProjectReference Include="..\Logger\Logger.csproj" />
|
||||||
|
|||||||
85
ORM/SqlSugarContext.cs
Normal file
85
ORM/SqlSugarContext.cs
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
using Logger;
|
||||||
|
using SqlSugar;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace ORM
|
||||||
|
{
|
||||||
|
public class SqlSugarContext
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// SqlSugarScope单例模式
|
||||||
|
/// </summary>
|
||||||
|
public static readonly SqlSugarScope DbContext = new SqlSugarScope(
|
||||||
|
new ConnectionConfig()
|
||||||
|
{
|
||||||
|
DbType = DatabaseConfig.DbConnectionType,
|
||||||
|
ConnectionString = DatabaseConfig.DbConnectionString, // 连接符字串
|
||||||
|
//ConfigId = "Db1",//管理多个数据库
|
||||||
|
IsAutoCloseConnection = true, // 自动关闭连接
|
||||||
|
InitKeyType = InitKeyType.Attribute // 通过实体类上的特性初始化
|
||||||
|
},
|
||||||
|
db =>
|
||||||
|
{
|
||||||
|
// 执行超时时间,单位秒
|
||||||
|
db.Ado.CommandTimeOut = 30;
|
||||||
|
|
||||||
|
// 每次SQL执行前事件
|
||||||
|
db.Aop.OnLogExecuting = (sql, pars) =>
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
// 确保 SQL 只通过 sqlLogger 记录
|
||||||
|
LoggerHelper.sqlLogger.Info("Executing SQL: {0} with parameters: {1}", sql, pars); // 使用 NLog 记录 SQL
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
// SQL执行完
|
||||||
|
db.Aop.OnLogExecuted = (sql, pars) =>
|
||||||
|
{
|
||||||
|
// 执行时间超过1秒记录慢日志
|
||||||
|
if (db.Ado.SqlExecutionTime.TotalSeconds > 1)
|
||||||
|
{
|
||||||
|
LoggerHelper.sqlLogger.Warn("SQL Slow Execution. Time: {0}, File: {1}, Line: {2}, Method: {3}, SQL: {4}",
|
||||||
|
db.Ado.SqlExecutionTime.ToString(), // SQL 执行时间
|
||||||
|
db.Ado.SqlStackTrace.FirstFileName, // 代码 CS 文件名
|
||||||
|
db.Ado.SqlStackTrace.FirstLine, // 代码行数
|
||||||
|
db.Ado.SqlStackTrace.FirstMethodName, // 代码方法名
|
||||||
|
sql); // 使用 NLog 记录慢 SQL 日志
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// SQL 报错
|
||||||
|
db.Aop.OnError = (exp) =>
|
||||||
|
{
|
||||||
|
// 确保 SQL 错误日志仅通过 sqlLogger 记录
|
||||||
|
LoggerHelper.sqlLogger.Error(exp, "SQL Error: {0}", exp.Sql); // 使用 NLog 记录 SQL 错误日志
|
||||||
|
};
|
||||||
|
|
||||||
|
// 数据过滤器:例如在新增数据时生成雪花 Id
|
||||||
|
db.Aop.DataExecuting = (oldValue, entityInfo) =>
|
||||||
|
{
|
||||||
|
// 新增操作
|
||||||
|
if (entityInfo.OperationType == DataFilterType.InsertByObject)
|
||||||
|
{
|
||||||
|
// 主键(long)赋值雪花 Id
|
||||||
|
if (entityInfo.EntityColumnInfo.IsPrimarykey && entityInfo.EntityColumnInfo.PropertyInfo.PropertyType == typeof(long))
|
||||||
|
{
|
||||||
|
var id = ((dynamic)entityInfo.EntityValue).Id;
|
||||||
|
if (id == null || id == 0)
|
||||||
|
{
|
||||||
|
SnowFlakeSingle.WorkId = DatabaseConfig.SnowFlakeWorkId;
|
||||||
|
SnowFlakeSingle.DatacenterId = DatabaseConfig.SnowFlakeDatacenterId;
|
||||||
|
entityInfo.SetValue(SnowFlakeSingle.Instance.NextId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
396
ORM/SqlSugarRepository.cs
Normal file
396
ORM/SqlSugarRepository.cs
Normal file
@@ -0,0 +1,396 @@
|
|||||||
|
using SqlSugar;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace ORM
|
||||||
|
{
|
||||||
|
public partial class SqlSugarRepository<TEntity> : SimpleClient<TEntity> where TEntity : class, new()
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 实体集合
|
||||||
|
/// </summary>
|
||||||
|
public ISugarQueryable<TEntity> Entities => Context.Queryable<TEntity>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
|
public SqlSugarRepository(ISqlSugarClient context = null) : base(context)
|
||||||
|
{
|
||||||
|
// 绑定数据库操作对象
|
||||||
|
Context = SqlSugarContext.DbContext;
|
||||||
|
// 备忘:GetConnectionScopeWithAttr会导致不能触发Aop.OnLogExecuting、Aop.OnLogExecuted等事件
|
||||||
|
// 详见:https://www.donet5.com/Home/Doc?typeId=2405(之2.1、方法说明)
|
||||||
|
// 详见:https://www.donet5.com/Home/Doc?typeId=2246(之2.2、根据特性获取)和(之4、多租户设置AOP)
|
||||||
|
// base.Context = SqlSugarContext.DbContext.GetConnectionScopeWithAttr<TEntity>();
|
||||||
|
// 根据特性获取,适合一个实体和库是一对一的情况
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region 查询
|
||||||
|
/// <summary>
|
||||||
|
/// 检查是否存在
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="whereExpression"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool IsExists(Expression<Func<TEntity, bool>> whereExpression)
|
||||||
|
{
|
||||||
|
return Entities.Any(whereExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查是否存在
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="whereExpression"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<bool> IsExistsAsync(Expression<Func<TEntity, bool>> whereExpression)
|
||||||
|
{
|
||||||
|
return await Entities.AnyAsync(whereExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 通过主键获取实体
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Id"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public TEntity Single(dynamic Id)
|
||||||
|
{
|
||||||
|
return Entities.InSingle(Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个实体
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="whereExpression"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public TEntity Single(Expression<Func<TEntity, bool>> whereExpression)
|
||||||
|
{
|
||||||
|
return Entities.Single(whereExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个实体
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="whereExpression"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Task<TEntity> SingleAsync(Expression<Func<TEntity, bool>> whereExpression)
|
||||||
|
{
|
||||||
|
return Entities.SingleAsync(whereExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个实体
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="whereExpression"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public TEntity FirstOrDefault(Expression<Func<TEntity, bool>> whereExpression)
|
||||||
|
{
|
||||||
|
return Entities.First(whereExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个实体
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="whereExpression"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> whereExpression)
|
||||||
|
{
|
||||||
|
return await Entities.FirstAsync(whereExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取列表
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public List<TEntity> ToList()
|
||||||
|
{
|
||||||
|
return Entities.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取列表
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Task<List<TEntity>> ToListAsync()
|
||||||
|
{
|
||||||
|
return Entities.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取列表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="whereExpression"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public List<TEntity> ToList(Expression<Func<TEntity, bool>> whereExpression)
|
||||||
|
{
|
||||||
|
return Entities.Where(whereExpression).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取列表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="whereExpression"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Task<List<TEntity>> ToListAsync(Expression<Func<TEntity, bool>> whereExpression)
|
||||||
|
{
|
||||||
|
return Entities.Where(whereExpression).ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取列表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="whereExpression"></param>
|
||||||
|
/// <param name="orderByExpression"></param>
|
||||||
|
/// <param name="orderByType"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public List<TEntity> ToList(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression = null, OrderByType orderByType = OrderByType.Asc)
|
||||||
|
{
|
||||||
|
return Entities.OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(whereExpression).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取列表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="whereExpression"></param>
|
||||||
|
/// <param name="orderByExpression"></param>
|
||||||
|
/// <param name="orderByType"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Task<List<TEntity>> ToListAsync(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression = null, OrderByType orderByType = OrderByType.Asc)
|
||||||
|
{
|
||||||
|
return Entities.OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(whereExpression).ToListAsync();
|
||||||
|
}
|
||||||
|
#endregion 查询
|
||||||
|
|
||||||
|
|
||||||
|
#region 新增
|
||||||
|
/// <summary>
|
||||||
|
/// 新增多条记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entities"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int Insert(TEntity[] entities)
|
||||||
|
{
|
||||||
|
return Context.Insertable(entities).ExecuteCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新增多条记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entities"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Task<int> InsertAsync(TEntity[] entities)
|
||||||
|
{
|
||||||
|
return Context.Insertable(entities).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新增多条记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entities"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int Insert(IEnumerable<TEntity> entities)
|
||||||
|
{
|
||||||
|
return Context.Insertable(entities.ToArray()).ExecuteCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新增多条记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entities"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Task<int> InsertAsync(IEnumerable<TEntity> entities)
|
||||||
|
{
|
||||||
|
if (entities != null && entities.Any())
|
||||||
|
{
|
||||||
|
return Context.Insertable(entities.ToArray()).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}
|
||||||
|
#endregion 新增
|
||||||
|
|
||||||
|
|
||||||
|
#region 更新
|
||||||
|
/// <summary>
|
||||||
|
/// 更新单条记录指定列
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity"></param>
|
||||||
|
/// <param name="updateColumn"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int Update(TEntity entity, object updateColumn)
|
||||||
|
{
|
||||||
|
return Context.Updateable(entity).UpdateColumns(MergeUpdateColumns(updateColumn)).ExecuteCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新单条记录指定列
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity"></param>
|
||||||
|
/// <param name="updateColumn"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Task<int> UpdateAsync(TEntity entity, object updateColumn)
|
||||||
|
{
|
||||||
|
return Context.Updateable(entity).UpdateColumns(MergeUpdateColumns(updateColumn)).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新单条记录指定列
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity"></param>
|
||||||
|
/// <param name="updateColumn"></param>
|
||||||
|
/// <param name="whereExpression"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int Update(TEntity entity, object updateColumn, Expression<Func<TEntity, bool>> whereExpression)
|
||||||
|
{
|
||||||
|
return Context.Updateable(entity).UpdateColumns(MergeUpdateColumns(updateColumn)).Where(whereExpression).ExecuteCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新单条记录指定列
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity"></param>
|
||||||
|
/// <param name="updateColumn"></param>
|
||||||
|
/// <param name="whereExpression"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Task<int> UpdateAsync(TEntity entity, object updateColumn, Expression<Func<TEntity, bool>> whereExpression)
|
||||||
|
{
|
||||||
|
return Context.Updateable(entity).UpdateColumns(MergeUpdateColumns(updateColumn)).Where(whereExpression).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新多条记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entities"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int Update(TEntity[] entities)
|
||||||
|
{
|
||||||
|
return Context.Updateable(entities).ExecuteCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新多条记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entities"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Task<int> UpdateAsync(TEntity[] entities)
|
||||||
|
{
|
||||||
|
return Context.Updateable(entities).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新多条记录指定列
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entities"></param>
|
||||||
|
/// <param name="updateColumn"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int Update(TEntity[] entities, object updateColumn)
|
||||||
|
{
|
||||||
|
return Context.Updateable(entities).UpdateColumns(MergeUpdateColumns(updateColumn)).ExecuteCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新多条记录指定列
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entities"></param>
|
||||||
|
/// <param name="updateColumn"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Task<int> UpdateAsync(TEntity[] entities, object updateColumn)
|
||||||
|
{
|
||||||
|
return Context.Updateable(entities).UpdateColumns(MergeUpdateColumns(updateColumn)).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 合并指定更新列和附加更新列
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="updateColumn"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private string[] MergeUpdateColumns(object updateColumn)
|
||||||
|
{
|
||||||
|
List<string> columnList = new List<string>();
|
||||||
|
if (updateColumn.GetType() == typeof(string))
|
||||||
|
{
|
||||||
|
columnList.Add((string)updateColumn);
|
||||||
|
}
|
||||||
|
else if (updateColumn.GetType() == typeof(string[]))
|
||||||
|
{
|
||||||
|
columnList.AddRange((string[])updateColumn);
|
||||||
|
}
|
||||||
|
return columnList.ToArray();
|
||||||
|
}
|
||||||
|
#endregion 更新
|
||||||
|
|
||||||
|
|
||||||
|
#region 删除
|
||||||
|
/// <summary>
|
||||||
|
/// 删除一条记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int Delete(object key)
|
||||||
|
{
|
||||||
|
return Context.Deleteable<TEntity>().In(key).ExecuteCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除一条记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Task<int> DeleteAsync(object key)
|
||||||
|
{
|
||||||
|
return Context.Deleteable<TEntity>().In(key).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除多条记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="keys"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int Delete(object[] keys)
|
||||||
|
{
|
||||||
|
return Context.Deleteable<TEntity>().In(keys).ExecuteCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除多条记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="keys"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Task<int> DeleteAsync(object[] keys)
|
||||||
|
{
|
||||||
|
return Context.Deleteable<TEntity>().In(keys).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
#endregion 删除
|
||||||
|
|
||||||
|
|
||||||
|
#region 事务
|
||||||
|
/// <summary>
|
||||||
|
/// 开启事务
|
||||||
|
/// </summary>
|
||||||
|
public void BeginTran()
|
||||||
|
{
|
||||||
|
Context.Ado.BeginTran();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 提交事务
|
||||||
|
/// </summary>
|
||||||
|
public void CommitTran()
|
||||||
|
{
|
||||||
|
Context.Ado.CommitTran();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回滚事务
|
||||||
|
/// </summary>
|
||||||
|
public void RollbackTran()
|
||||||
|
{
|
||||||
|
Context.Ado.RollbackTran();
|
||||||
|
}
|
||||||
|
#endregion 事务
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,388 +0,0 @@
|
|||||||
using Common.DTOS;
|
|
||||||
using NetTaste;
|
|
||||||
using RestSharp;
|
|
||||||
using SqlSugar;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Service
|
|
||||||
{
|
|
||||||
public class APIService
|
|
||||||
{
|
|
||||||
|
|
||||||
private static string Token = "Bearer u-cVaGe.hv160U5.zqxeyRKx11ifIR04iPjoayYQC00EXF";
|
|
||||||
#region 表处理
|
|
||||||
/// <summary>
|
|
||||||
/// 初始化多维表格
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="FormName">表格名称</param>
|
|
||||||
public static FeishuResponse<CreateBitableAppData> InitForm(string FormName)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var client = new RestClient("https://open.feishu.cn/open-apis/bitable/v1/apps");
|
|
||||||
client.Timeout = -1;
|
|
||||||
var request = new RestRequest(Method.POST);
|
|
||||||
request.AddHeader("Content-Type", "application/json");
|
|
||||||
request.AddHeader("Authorization", Token);
|
|
||||||
request.AddParameter("application/json", ParameterType.RequestBody);
|
|
||||||
request.AddJsonBody(new
|
|
||||||
{
|
|
||||||
folder_token = "",
|
|
||||||
name = FormName
|
|
||||||
});
|
|
||||||
IRestResponse response = client.Execute(request);
|
|
||||||
return Newtonsoft.Json.JsonConvert.DeserializeObject<FeishuResponse<CreateBitableAppData>>(response.Content);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// 创建表
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="FormName">多维表格ID</param>
|
|
||||||
/// <param name="FormName">表名称</param>
|
|
||||||
public static FeishuResponse<CreateTableData> AddTable(string FormID, string TableName)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var client = new RestClient($"https://open.feishu.cn/open-apis/bitable/v1/apps/{FormID}/tables");
|
|
||||||
client.Timeout = -1;
|
|
||||||
var request = new RestRequest(Method.POST);
|
|
||||||
request.AddHeader("Content-Type", "application/json");
|
|
||||||
request.AddHeader("Authorization", Token);
|
|
||||||
request.AddJsonBody(new
|
|
||||||
{
|
|
||||||
table = new
|
|
||||||
{
|
|
||||||
default_view_name = "默认的表格视图",
|
|
||||||
name = TableName,
|
|
||||||
fields = new object[]
|
|
||||||
{
|
|
||||||
new
|
|
||||||
{
|
|
||||||
field_name = "索引字段",
|
|
||||||
type = 1
|
|
||||||
},
|
|
||||||
new
|
|
||||||
{
|
|
||||||
field_name = "单选",
|
|
||||||
type = 3,
|
|
||||||
ui_type = "SingleSelect",
|
|
||||||
property = new
|
|
||||||
{
|
|
||||||
options = new[]
|
|
||||||
{
|
|
||||||
new { color = 0, name = "Enabled" },
|
|
||||||
new { color = 1, name = "Disabled" },
|
|
||||||
new { color = 2, name = "Draft" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
request.AddParameter("application/json", ParameterType.RequestBody);
|
|
||||||
IRestResponse response = client.Execute(request);
|
|
||||||
return Newtonsoft.Json.JsonConvert.DeserializeObject<FeishuResponse<CreateTableData>>(response.Content);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// 删除表
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="FormID">多维表格ID</param>
|
|
||||||
/// <param name="TabelID">表ID</param>
|
|
||||||
public static FeishuResponse<object> DeleteTable(string FormID, string TabelID)
|
|
||||||
{
|
|
||||||
var client = new RestClient($"https://open.feishu.cn/open-apis/bitable/v1/apps/{FormID}/tables/{TabelID}");
|
|
||||||
client.Timeout = -1;
|
|
||||||
var request = new RestRequest(Method.DELETE);
|
|
||||||
request.AddHeader("Authorization", Token);
|
|
||||||
IRestResponse response = client.Execute(request);
|
|
||||||
return Newtonsoft.Json.JsonConvert.DeserializeObject<FeishuResponse<object>>(response.Content);
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// 获得表列表
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="FormName">多维表格ID</param>
|
|
||||||
/// <param name="FormName">分页数</param>
|
|
||||||
/// <param name="FormName">表ID</param>
|
|
||||||
public static FeishuResponse<QueryTableListData> GetTableList(string FormID, int PageSize, string TabelID = "")
|
|
||||||
{
|
|
||||||
RestClient client;
|
|
||||||
if (TabelID == "")
|
|
||||||
{
|
|
||||||
client = new RestClient($"https://open.feishu.cn/open-apis/bitable/v1/apps/{FormID}/tables?page_size={PageSize}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
client = new RestClient($"https://open.feishu.cn/open-apis/bitable/v1/apps/{FormID}/tables?page_size={PageSize}&page_token={TabelID}");
|
|
||||||
}
|
|
||||||
client.Timeout = -1;
|
|
||||||
var request = new RestRequest(Method.GET);
|
|
||||||
request.AddHeader("Authorization", Token);
|
|
||||||
IRestResponse response = client.Execute(request);
|
|
||||||
return Newtonsoft.Json.JsonConvert.DeserializeObject<FeishuResponse<QueryTableListData>>(response.Content);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
#region 行处理
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 添加一行记录
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="FormID">多维表格ID</param>
|
|
||||||
/// <param name="TabelID">表ID</param>
|
|
||||||
public static FeishuResponse<CreateRecordData> AddRecord(string FormID, string TableID)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var client = new RestClient($"https://open.feishu.cn/open-apis/bitable/v1/apps/{FormID}/tables/{TableID}/records");
|
|
||||||
client.Timeout = -1;
|
|
||||||
var request = new RestRequest(Method.POST);
|
|
||||||
request.AddHeader("Content-Type", "application/json");
|
|
||||||
request.AddHeader("Authorization", Token);
|
|
||||||
request.AddJsonBody(new
|
|
||||||
{
|
|
||||||
fields = new
|
|
||||||
{
|
|
||||||
单选 = "333",
|
|
||||||
索引字段 = "拜访潜在客户"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
request.AddParameter("application/json", ParameterType.RequestBody);
|
|
||||||
IRestResponse response = client.Execute(request);
|
|
||||||
return Newtonsoft.Json.JsonConvert.DeserializeObject<FeishuResponse<CreateRecordData>>(response.Content);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// 更新一行记录
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="FormID">多维表格ID</param>
|
|
||||||
/// <param name="TabelID">表ID</param>
|
|
||||||
/// <param name="TabelID">记录ID</param>
|
|
||||||
public static FeishuResponse<CreateRecordData> UpdateRecord(string FormID, string TableID, string RecordID)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var client = new RestClient($"https://open.feishu.cn/open-apis/bitable/v1/apps/{FormID}/tables/{TableID}/records/{RecordID}");
|
|
||||||
client.Timeout = -1;
|
|
||||||
var request = new RestRequest(Method.PUT);
|
|
||||||
request.AddHeader("Content-Type", "application/json");
|
|
||||||
request.AddHeader("Authorization", Token);
|
|
||||||
request.AddJsonBody(new
|
|
||||||
{
|
|
||||||
fields = new
|
|
||||||
{
|
|
||||||
单选 = "99",
|
|
||||||
索引字段 = "mike"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
request.AddParameter("application/json", ParameterType.RequestBody);
|
|
||||||
IRestResponse response = client.Execute(request);
|
|
||||||
return Newtonsoft.Json.JsonConvert.DeserializeObject<FeishuResponse<CreateRecordData>>(response.Content);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// 删除记录
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="FormID">多维表格ID</param>
|
|
||||||
/// <param name="TabelID">表ID</param>
|
|
||||||
/// <param name="TabelID">记录ID</param>
|
|
||||||
public static FeishuResponse<object> DeleteRecord(string FormID, string TableID, string RecordID)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var client = new RestClient($"https://open.feishu.cn/open-apis/bitable/v1/apps/{FormID}/tables/{TableID}/records/{RecordID}");
|
|
||||||
client.Timeout = -1;
|
|
||||||
var request = new RestRequest(Method.DELETE);
|
|
||||||
request.AddHeader("Authorization", Token);
|
|
||||||
var body = "";
|
|
||||||
request.AddParameter("", body, ParameterType.RequestBody);
|
|
||||||
IRestResponse response = client.Execute(request);
|
|
||||||
return Newtonsoft.Json.JsonConvert.DeserializeObject<FeishuResponse<object>>(response.Content);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// 获取记录
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="FormID">多维表格ID</param>
|
|
||||||
/// <param name="TabelID">表ID</param>
|
|
||||||
/// <param name="TabelID">分页数量</param>
|
|
||||||
public static FeishuResponse<QueryRecordListData> GetRecord(string FormID, string TableID, int PageSize)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var client = new RestClient($"https://open.feishu.cn/open-apis/bitable/v1/apps/{FormID}/tables/{TableID}/records/search?page_size={PageSize}");
|
|
||||||
client.Timeout = -1;
|
|
||||||
var request = new RestRequest(Method.POST);
|
|
||||||
request.AddHeader("Content-Type", "application/json");
|
|
||||||
request.AddHeader("Authorization", "Bearer u-dSpI1fRVp2jWi4Nyz0lIkal5i0n504UVMUaaYNy021um");
|
|
||||||
var body = "{}";
|
|
||||||
request.AddParameter("application/json", body, ParameterType.RequestBody);
|
|
||||||
IRestResponse response = client.Execute(request);
|
|
||||||
return Newtonsoft.Json.JsonConvert.DeserializeObject<FeishuResponse<QueryRecordListData>>(response.Content);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
#region 多行处理
|
|
||||||
/// <summary>
|
|
||||||
/// 添加多行记录
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="FormID">多维表格ID</param>
|
|
||||||
/// <param name="TabelID">表ID</param>
|
|
||||||
public static FeishuResponse<CreateRecordsRequest> AddMutipulRecords(string FormID, string TableID)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var client = new RestClient($"https://open.feishu.cn/open-apis/bitable/v1/apps/{FormID}/tables/{TableID}/records/batch_create");
|
|
||||||
client.Timeout = -1;
|
|
||||||
var request = new RestRequest(Method.POST);
|
|
||||||
request.AddHeader("Content-Type", "application/json");
|
|
||||||
request.AddHeader("Authorization", Token);
|
|
||||||
request.AddJsonBody(new
|
|
||||||
{
|
|
||||||
records = new[]
|
|
||||||
{
|
|
||||||
new
|
|
||||||
{
|
|
||||||
fields = new
|
|
||||||
{
|
|
||||||
单选 = "333",
|
|
||||||
索引字段 = "拜访潜在客户1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new
|
|
||||||
{
|
|
||||||
fields = new
|
|
||||||
{
|
|
||||||
单选 = "333",
|
|
||||||
索引字段 = "拜访潜在客户2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
request.AddParameter("application/json", ParameterType.RequestBody);
|
|
||||||
IRestResponse response = client.Execute(request);
|
|
||||||
return Newtonsoft.Json.JsonConvert.DeserializeObject<FeishuResponse<CreateRecordsRequest>>(response.Content);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// 更新多行记录
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="FormID">多维表格ID</param>
|
|
||||||
/// <param name="TabelID">表ID</param>
|
|
||||||
/// <param name="FieldIDs">记录ID列表</param>
|
|
||||||
public static FeishuResponse<CreateRecordsRequest> UpdateRecords(string FormID, string TableID, string[] FieldIDs)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var client = new RestClient($"https://open.feishu.cn/open-apis/bitable/v1/apps/{FormID}/tables/{TableID}/records/batch_update");
|
|
||||||
client.Timeout = -1;
|
|
||||||
var request = new RestRequest(Method.POST);
|
|
||||||
request.AddHeader("Content-Type", "application/json");
|
|
||||||
request.AddHeader("Authorization", Token);
|
|
||||||
request.AddJsonBody(new
|
|
||||||
{
|
|
||||||
records = new[]
|
|
||||||
{
|
|
||||||
new
|
|
||||||
{
|
|
||||||
record_id=FieldIDs[0],
|
|
||||||
fields = new
|
|
||||||
{
|
|
||||||
单选 = "333",
|
|
||||||
索引字段 = "改拜访潜在客户1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new
|
|
||||||
{
|
|
||||||
record_id=FieldIDs[1],
|
|
||||||
fields = new
|
|
||||||
{
|
|
||||||
单选 = "333",
|
|
||||||
索引字段 = "改拜访潜在客户2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
request.AddParameter("application/json", ParameterType.RequestBody);
|
|
||||||
IRestResponse response = client.Execute(request);
|
|
||||||
return Newtonsoft.Json.JsonConvert.DeserializeObject<FeishuResponse<CreateRecordsRequest>>(response.Content);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// 删除多行记录
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="FormID">多维表格ID</param>
|
|
||||||
/// <param name="TabelID">表ID</param>
|
|
||||||
/// <param name="FieldIDs">记录ID列表</param>
|
|
||||||
public static FeishuResponse<object> DeleteRecords(string FormID, string TableID, string[] FieldIDs)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var client = new RestClient($"https://open.feishu.cn/open-apis/bitable/v1/apps/{FormID}/tables/{TableID}/records/batch_delete");
|
|
||||||
client.Timeout = -1;
|
|
||||||
var request = new RestRequest(Method.POST);
|
|
||||||
request.AddHeader("Content-Type", "application/json");
|
|
||||||
request.AddHeader("Authorization", Token);
|
|
||||||
request.AddJsonBody(new
|
|
||||||
{
|
|
||||||
records = FieldIDs
|
|
||||||
});
|
|
||||||
request.AddParameter("application/json", ParameterType.RequestBody);
|
|
||||||
IRestResponse response = client.Execute(request);
|
|
||||||
return Newtonsoft.Json.JsonConvert.DeserializeObject<FeishuResponse<object>>(response.Content);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user