mirror of
https://github.com/snltty/linker.git
synced 2025-11-01 13:04:00 +08:00
同步
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -117,4 +117,287 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
|
<data name="label15.Text" xml:space="preserve">
|
||||||
|
<value>每项1024长度,0项保留不可用</value>
|
||||||
|
</data>
|
||||||
|
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
|
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>
|
||||||
|
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
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -32,6 +32,7 @@ namespace cmonitor.libs
|
|||||||
this.length = length;
|
this.length = length;
|
||||||
this.itemSize = itemSize;
|
this.itemSize = itemSize;
|
||||||
bytes = new byte[length * itemSize];
|
bytes = new byte[length * itemSize];
|
||||||
|
states = new ShareMemoryState[length];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitLocal()
|
public void InitLocal()
|
||||||
@@ -100,6 +101,7 @@ namespace cmonitor.libs
|
|||||||
|
|
||||||
byte[] valuesBytes;
|
byte[] valuesBytes;
|
||||||
byte[] gloablBytes;
|
byte[] gloablBytes;
|
||||||
|
ShareMemoryState[] states = Array.Empty<ShareMemoryState>();
|
||||||
private void InitStateValues()
|
private void InitStateValues()
|
||||||
{
|
{
|
||||||
gloablBytes = new byte[bytes.Length];
|
gloablBytes = new byte[bytes.Length];
|
||||||
@@ -118,18 +120,15 @@ namespace cmonitor.libs
|
|||||||
{
|
{
|
||||||
for (int index = 0; index < length; index++)
|
for (int index = 0; index < length; index++)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < valuesBytes.Length; i++)
|
ShareMemoryState state = ReadState(accessorLocal, index);
|
||||||
{
|
if (state != states[index])
|
||||||
ShareMemoryState state = (ShareMemoryState)valuesBytes[i];
|
|
||||||
bool result = ReadState(accessorLocal, index, state);
|
|
||||||
if (result)
|
|
||||||
{
|
{
|
||||||
|
states[index] = state;
|
||||||
stateAction(index, state);
|
stateAction(index, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
private void SyncMemory()
|
private void SyncMemory()
|
||||||
{
|
{
|
||||||
if (accessorGlobal != null && accessorLocal != null)
|
if (accessorGlobal != null && accessorLocal != null)
|
||||||
@@ -141,7 +140,7 @@ namespace cmonitor.libs
|
|||||||
for (int index = 0; index < length; index++)
|
for (int index = 0; index < length; index++)
|
||||||
{
|
{
|
||||||
//检查更新状态
|
//检查更新状态
|
||||||
if (ReadState(accessorGlobal, index, ShareMemoryState.Updated) == false)
|
if (ReadStateIf(accessorGlobal, index, ShareMemoryState.Updated) == false)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -152,7 +151,7 @@ namespace cmonitor.libs
|
|||||||
{
|
{
|
||||||
accessorLocal.WriteArray(_index, gloablBytes, _index, itemSize);
|
accessorLocal.WriteArray(_index, gloablBytes, _index, itemSize);
|
||||||
}
|
}
|
||||||
WriteState(accessorGlobal, index, ShareMemoryState.Updated, false);
|
WriteStateIf(accessorGlobal, index, ShareMemoryState.Updated, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,13 +171,13 @@ namespace cmonitor.libs
|
|||||||
for (int index = 0; index < length; index++)
|
for (int index = 0; index < length; index++)
|
||||||
{
|
{
|
||||||
//state
|
//state
|
||||||
bool _updated = ReadState(accessorLocal, index, ShareMemoryState.Updated);
|
bool _updated = ReadStateIf(accessorLocal, index, ShareMemoryState.Updated);
|
||||||
if (_updated == false)
|
if (_updated == false)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteState(accessorLocal, index, ShareMemoryState.Updated, false);
|
WriteStateIf(accessorLocal, index, ShareMemoryState.Updated, false);
|
||||||
updated |= _updated;
|
updated |= _updated;
|
||||||
|
|
||||||
//key length
|
//key length
|
||||||
@@ -310,7 +309,14 @@ namespace cmonitor.libs
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ReadState(IShareMemory accessor, int index, ShareMemoryState state)
|
private ShareMemoryState ReadState(IShareMemory accessor, int index)
|
||||||
|
{
|
||||||
|
if (accessor == null) return ShareMemoryState.None;
|
||||||
|
|
||||||
|
ShareMemoryState stateByte = (ShareMemoryState)accessor.ReadByte(index * itemSize);
|
||||||
|
return stateByte;
|
||||||
|
}
|
||||||
|
private bool ReadStateIf(IShareMemory accessor, int index, ShareMemoryState state)
|
||||||
{
|
{
|
||||||
if (accessor == null) return false;
|
if (accessor == null) return false;
|
||||||
|
|
||||||
@@ -320,29 +326,35 @@ namespace cmonitor.libs
|
|||||||
public bool ReadUpdated(int index)
|
public bool ReadUpdated(int index)
|
||||||
{
|
{
|
||||||
if (accessorLocal != null)
|
if (accessorLocal != null)
|
||||||
return ReadState(accessorLocal, index, ShareMemoryState.Updated);
|
return ReadStateIf(accessorLocal, index, ShareMemoryState.Updated);
|
||||||
if (accessorGlobal != null)
|
if (accessorGlobal != null)
|
||||||
return ReadState(accessorGlobal, index, ShareMemoryState.Updated);
|
return ReadStateIf(accessorGlobal, index, ShareMemoryState.Updated);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public bool ReadClosed(int index)
|
public bool ReadClosed(int index)
|
||||||
{
|
{
|
||||||
if (accessorLocal != null)
|
if (accessorLocal != null)
|
||||||
return ReadState(accessorLocal, index, ShareMemoryState.Closed);
|
return ReadStateIf(accessorLocal, index, ShareMemoryState.Closed);
|
||||||
if (accessorGlobal != null)
|
if (accessorGlobal != null)
|
||||||
return ReadState(accessorGlobal, index, ShareMemoryState.Closed);
|
return ReadStateIf(accessorGlobal, index, ShareMemoryState.Closed);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public bool ReadRunning(int index)
|
public bool ReadRunning(int index)
|
||||||
{
|
{
|
||||||
if (accessorLocal != null)
|
if (accessorLocal != null)
|
||||||
return ReadState(accessorLocal, index, ShareMemoryState.Running);
|
return ReadStateIf(accessorLocal, index, ShareMemoryState.Running);
|
||||||
if (accessorGlobal != null)
|
if (accessorGlobal != null)
|
||||||
return ReadState(accessorGlobal, index, ShareMemoryState.Running);
|
return ReadStateIf(accessorGlobal, index, ShareMemoryState.Running);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteState(IShareMemory accessor, int index, ShareMemoryState state, bool value)
|
private void WriteState(IShareMemory accessor, int index, ShareMemoryState state)
|
||||||
|
{
|
||||||
|
if (accessor == null) return;
|
||||||
|
byte stateByte = (byte)state;
|
||||||
|
accessor.WriteByte(index * itemSize, stateByte);
|
||||||
|
}
|
||||||
|
private void WriteStateIf(IShareMemory accessor, int index, ShareMemoryState state, bool value)
|
||||||
{
|
{
|
||||||
if (accessor == null) return;
|
if (accessor == null) return;
|
||||||
byte stateValue = accessor.ReadByte(index * itemSize);
|
byte stateValue = accessor.ReadByte(index * itemSize);
|
||||||
@@ -359,19 +371,19 @@ namespace cmonitor.libs
|
|||||||
}
|
}
|
||||||
public void WriteUpdated(int index, bool updated = true)
|
public void WriteUpdated(int index, bool updated = true)
|
||||||
{
|
{
|
||||||
WriteState(accessorLocal, index, ShareMemoryState.Updated, updated);
|
WriteStateIf(accessorLocal, index, ShareMemoryState.Updated, updated);
|
||||||
WriteState(accessorGlobal, index, ShareMemoryState.Updated, updated);
|
WriteStateIf(accessorGlobal, index, ShareMemoryState.Updated, updated);
|
||||||
}
|
}
|
||||||
public void WriteClosed(int index, bool closed = true)
|
public void WriteClosed(int index, bool closed = true)
|
||||||
{
|
{
|
||||||
WriteState(accessorLocal, index, ShareMemoryState.Closed, closed);
|
WriteStateIf(accessorLocal, index, ShareMemoryState.Closed, closed);
|
||||||
WriteState(accessorGlobal, index, ShareMemoryState.Closed, closed);
|
WriteStateIf(accessorGlobal, index, ShareMemoryState.Closed, closed);
|
||||||
WriteUpdated(index, true);
|
WriteUpdated(index, true);
|
||||||
}
|
}
|
||||||
public void WriteRunning(int index, bool running = true)
|
public void WriteRunning(int index, bool running = true)
|
||||||
{
|
{
|
||||||
WriteState(accessorLocal, index, ShareMemoryState.Running, running);
|
WriteStateIf(accessorLocal, index, ShareMemoryState.Running, running);
|
||||||
WriteState(accessorGlobal, index, ShareMemoryState.Running, running);
|
WriteStateIf(accessorGlobal, index, ShareMemoryState.Running, running);
|
||||||
WriteUpdated(index, true);
|
WriteUpdated(index, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -387,6 +399,7 @@ namespace cmonitor.libs
|
|||||||
|
|
||||||
public enum ShareMemoryState : byte
|
public enum ShareMemoryState : byte
|
||||||
{
|
{
|
||||||
|
None = 0,
|
||||||
Updated = 0b0000_0001,
|
Updated = 0b0000_0001,
|
||||||
Closed = 0b0000_0010,
|
Closed = 0b0000_0010,
|
||||||
Running = 0b0000_0100,
|
Running = 0b0000_0100,
|
||||||
|
|||||||
34
cmonitor.sln
34
cmonitor.sln
@@ -7,19 +7,21 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "cmonitor", "cmonitor\cmonit
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "common.libs", "common.libs\common.libs.csproj", "{00EECF97-99EB-4B12-AAEF-ED2363914275}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "common.libs", "common.libs\common.libs.csproj", "{00EECF97-99EB-4B12-AAEF-ED2363914275}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cmonitor.sas.service", "cmonitor.sas.service\cmonitor.sas.service.csproj", "{0ED28F51-04B0-4B2D-B47E-EB1715F0CE57}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "cmonitor.sas.service", "cmonitor.sas.service\cmonitor.sas.service.csproj", "{0ED28F51-04B0-4B2D-B47E-EB1715F0CE57}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cmonitor.libs", "cmonitor.libs\cmonitor.libs.csproj", "{9080618D-367F-474E-AACA-A3C2F294448F}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "cmonitor.libs", "cmonitor.libs\cmonitor.libs.csproj", "{9080618D-367F-474E-AACA-A3C2F294448F}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cmonitor.install.win", "cmonitor.install.win\cmonitor.install.win.csproj", "{4EB9FFB0-B05C-4C4E-BD44-796715E47585}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "cmonitor.install.win", "cmonitor.install.win\cmonitor.install.win.csproj", "{4EB9FFB0-B05C-4C4E-BD44-796715E47585}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "llock.win", "llock.win\llock.win.csproj", "{6F2602B3-221D-475D-B643-D54987605644}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "llock.win", "llock.win\llock.win.csproj", "{6F2602B3-221D-475D-B643-D54987605644}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wallpaper.win", "wallpaper.win\wallpaper.win.csproj", "{41C61263-4F73-4C62-BD78-8C3612C8F98B}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "wallpaper.win", "wallpaper.win\wallpaper.win.csproj", "{41C61263-4F73-4C62-BD78-8C3612C8F98B}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "notify.win", "notify.win\notify.win.csproj", "{886D781B-9A41-4DD1-8B94-490AE6476E67}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "notify.win", "notify.win\notify.win.csproj", "{886D781B-9A41-4DD1-8B94-490AE6476E67}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "message.win", "message.win\message.win.csproj", "{BCA983E7-928F-4353-BF98-4ACCBB1B173E}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "message.win", "message.win\message.win.csproj", "{BCA983E7-928F-4353-BF98-4ACCBB1B173E}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cmonitor.snatch.win", "cmonitor.snatch.win\cmonitor.snatch.win.csproj", "{5267B401-6818-407C-8323-E6C8A3CC01D6}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@@ -196,6 +198,24 @@ Global
|
|||||||
{BCA983E7-928F-4353-BF98-4ACCBB1B173E}.ReleaseLinux|x64.Build.0 = Release|Any CPU
|
{BCA983E7-928F-4353-BF98-4ACCBB1B173E}.ReleaseLinux|x64.Build.0 = Release|Any CPU
|
||||||
{BCA983E7-928F-4353-BF98-4ACCBB1B173E}.ReleaseLinux|x86.ActiveCfg = Release|Any CPU
|
{BCA983E7-928F-4353-BF98-4ACCBB1B173E}.ReleaseLinux|x86.ActiveCfg = Release|Any CPU
|
||||||
{BCA983E7-928F-4353-BF98-4ACCBB1B173E}.ReleaseLinux|x86.Build.0 = Release|Any CPU
|
{BCA983E7-928F-4353-BF98-4ACCBB1B173E}.ReleaseLinux|x86.Build.0 = Release|Any CPU
|
||||||
|
{5267B401-6818-407C-8323-E6C8A3CC01D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{5267B401-6818-407C-8323-E6C8A3CC01D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{5267B401-6818-407C-8323-E6C8A3CC01D6}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{5267B401-6818-407C-8323-E6C8A3CC01D6}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{5267B401-6818-407C-8323-E6C8A3CC01D6}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{5267B401-6818-407C-8323-E6C8A3CC01D6}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{5267B401-6818-407C-8323-E6C8A3CC01D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{5267B401-6818-407C-8323-E6C8A3CC01D6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{5267B401-6818-407C-8323-E6C8A3CC01D6}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{5267B401-6818-407C-8323-E6C8A3CC01D6}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{5267B401-6818-407C-8323-E6C8A3CC01D6}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{5267B401-6818-407C-8323-E6C8A3CC01D6}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{5267B401-6818-407C-8323-E6C8A3CC01D6}.ReleaseLinux|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{5267B401-6818-407C-8323-E6C8A3CC01D6}.ReleaseLinux|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{5267B401-6818-407C-8323-E6C8A3CC01D6}.ReleaseLinux|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{5267B401-6818-407C-8323-E6C8A3CC01D6}.ReleaseLinux|x64.Build.0 = Release|Any CPU
|
||||||
|
{5267B401-6818-407C-8323-E6C8A3CC01D6}.ReleaseLinux|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{5267B401-6818-407C-8323-E6C8A3CC01D6}.ReleaseLinux|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
303
cmonitor.snatch.win/MainForm.Designer.cs
generated
Normal file
303
cmonitor.snatch.win/MainForm.Designer.cs
generated
Normal file
@@ -0,0 +1,303 @@
|
|||||||
|
namespace cmonitor.snatch.win
|
||||||
|
{
|
||||||
|
partial class MainForm
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
|
||||||
|
groupTypeQuestion = new GroupBox();
|
||||||
|
groupResult = new GroupBox();
|
||||||
|
inputWrong = new TextBox();
|
||||||
|
label3 = new Label();
|
||||||
|
inputRight = new TextBox();
|
||||||
|
label2 = new Label();
|
||||||
|
inputJoin = new TextBox();
|
||||||
|
label1 = new Label();
|
||||||
|
groupTypeInput = new GroupBox();
|
||||||
|
inputAnswer = new TextBox();
|
||||||
|
groupTypeSelect = new GroupBox();
|
||||||
|
checkB = new CheckBox();
|
||||||
|
checkF = new CheckBox();
|
||||||
|
checkA = new CheckBox();
|
||||||
|
checkC = new CheckBox();
|
||||||
|
checkE = new CheckBox();
|
||||||
|
checkD = new CheckBox();
|
||||||
|
btnConfirm = new Button();
|
||||||
|
panel1 = new Panel();
|
||||||
|
inputQuestion = new TextBox();
|
||||||
|
groupTypeQuestion.SuspendLayout();
|
||||||
|
groupResult.SuspendLayout();
|
||||||
|
groupTypeInput.SuspendLayout();
|
||||||
|
groupTypeSelect.SuspendLayout();
|
||||||
|
panel1.SuspendLayout();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// groupTypeQuestion
|
||||||
|
//
|
||||||
|
groupTypeQuestion.Controls.Add(groupResult);
|
||||||
|
groupTypeQuestion.Controls.Add(groupTypeInput);
|
||||||
|
groupTypeQuestion.Controls.Add(groupTypeSelect);
|
||||||
|
groupTypeQuestion.Controls.Add(btnConfirm);
|
||||||
|
groupTypeQuestion.Controls.Add(panel1);
|
||||||
|
groupTypeQuestion.Location = new Point(12, 3);
|
||||||
|
groupTypeQuestion.Name = "groupTypeQuestion";
|
||||||
|
groupTypeQuestion.Size = new Size(350, 433);
|
||||||
|
groupTypeQuestion.TabIndex = 1;
|
||||||
|
groupTypeQuestion.TabStop = false;
|
||||||
|
groupTypeQuestion.Text = "看题";
|
||||||
|
//
|
||||||
|
// groupResult
|
||||||
|
//
|
||||||
|
groupResult.Controls.Add(inputWrong);
|
||||||
|
groupResult.Controls.Add(label3);
|
||||||
|
groupResult.Controls.Add(inputRight);
|
||||||
|
groupResult.Controls.Add(label2);
|
||||||
|
groupResult.Controls.Add(inputJoin);
|
||||||
|
groupResult.Controls.Add(label1);
|
||||||
|
groupResult.Location = new Point(15, 252);
|
||||||
|
groupResult.Name = "groupResult";
|
||||||
|
groupResult.Size = new Size(320, 59);
|
||||||
|
groupResult.TabIndex = 12;
|
||||||
|
groupResult.TabStop = false;
|
||||||
|
groupResult.Text = "答题结果";
|
||||||
|
//
|
||||||
|
// inputWrong
|
||||||
|
//
|
||||||
|
inputWrong.ForeColor = Color.Red;
|
||||||
|
inputWrong.Location = new Point(252, 24);
|
||||||
|
inputWrong.Name = "inputWrong";
|
||||||
|
inputWrong.Size = new Size(58, 23);
|
||||||
|
inputWrong.TabIndex = 5;
|
||||||
|
//
|
||||||
|
// label3
|
||||||
|
//
|
||||||
|
label3.AutoSize = true;
|
||||||
|
label3.ForeColor = Color.Red;
|
||||||
|
label3.Location = new Point(218, 27);
|
||||||
|
label3.Name = "label3";
|
||||||
|
label3.Size = new Size(32, 17);
|
||||||
|
label3.TabIndex = 4;
|
||||||
|
label3.Text = "错误";
|
||||||
|
//
|
||||||
|
// inputRight
|
||||||
|
//
|
||||||
|
inputRight.ForeColor = Color.Green;
|
||||||
|
inputRight.Location = new Point(146, 24);
|
||||||
|
inputRight.Name = "inputRight";
|
||||||
|
inputRight.Size = new Size(62, 23);
|
||||||
|
inputRight.TabIndex = 3;
|
||||||
|
//
|
||||||
|
// label2
|
||||||
|
//
|
||||||
|
label2.AutoSize = true;
|
||||||
|
label2.ForeColor = Color.Green;
|
||||||
|
label2.Location = new Point(110, 27);
|
||||||
|
label2.Name = "label2";
|
||||||
|
label2.Size = new Size(32, 17);
|
||||||
|
label2.TabIndex = 2;
|
||||||
|
label2.Text = "正确";
|
||||||
|
//
|
||||||
|
// inputJoin
|
||||||
|
//
|
||||||
|
inputJoin.Location = new Point(39, 24);
|
||||||
|
inputJoin.Name = "inputJoin";
|
||||||
|
inputJoin.Size = new Size(60, 23);
|
||||||
|
inputJoin.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
label1.AutoSize = true;
|
||||||
|
label1.Location = new Point(4, 27);
|
||||||
|
label1.Name = "label1";
|
||||||
|
label1.Size = new Size(32, 17);
|
||||||
|
label1.TabIndex = 0;
|
||||||
|
label1.Text = "参与";
|
||||||
|
//
|
||||||
|
// groupTypeInput
|
||||||
|
//
|
||||||
|
groupTypeInput.Controls.Add(inputAnswer);
|
||||||
|
groupTypeInput.Location = new Point(15, 320);
|
||||||
|
groupTypeInput.Name = "groupTypeInput";
|
||||||
|
groupTypeInput.Size = new Size(320, 56);
|
||||||
|
groupTypeInput.TabIndex = 11;
|
||||||
|
groupTypeInput.TabStop = false;
|
||||||
|
groupTypeInput.Text = "输入你的答案";
|
||||||
|
//
|
||||||
|
// inputAnswer
|
||||||
|
//
|
||||||
|
inputAnswer.Location = new Point(12, 22);
|
||||||
|
inputAnswer.Name = "inputAnswer";
|
||||||
|
inputAnswer.Size = new Size(298, 23);
|
||||||
|
inputAnswer.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// groupTypeSelect
|
||||||
|
//
|
||||||
|
groupTypeSelect.Controls.Add(checkB);
|
||||||
|
groupTypeSelect.Controls.Add(checkF);
|
||||||
|
groupTypeSelect.Controls.Add(checkA);
|
||||||
|
groupTypeSelect.Controls.Add(checkC);
|
||||||
|
groupTypeSelect.Controls.Add(checkE);
|
||||||
|
groupTypeSelect.Controls.Add(checkD);
|
||||||
|
groupTypeSelect.Location = new Point(15, 317);
|
||||||
|
groupTypeSelect.Name = "groupTypeSelect";
|
||||||
|
groupTypeSelect.Size = new Size(320, 56);
|
||||||
|
groupTypeSelect.TabIndex = 10;
|
||||||
|
groupTypeSelect.TabStop = false;
|
||||||
|
groupTypeSelect.Text = "选择你的答案";
|
||||||
|
//
|
||||||
|
// checkB
|
||||||
|
//
|
||||||
|
checkB.AutoSize = true;
|
||||||
|
checkB.Location = new Point(65, 25);
|
||||||
|
checkB.Name = "checkB";
|
||||||
|
checkB.Size = new Size(35, 21);
|
||||||
|
checkB.TabIndex = 5;
|
||||||
|
checkB.Text = "B";
|
||||||
|
checkB.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// checkF
|
||||||
|
//
|
||||||
|
checkF.AutoSize = true;
|
||||||
|
checkF.Location = new Point(277, 25);
|
||||||
|
checkF.Name = "checkF";
|
||||||
|
checkF.Size = new Size(33, 21);
|
||||||
|
checkF.TabIndex = 9;
|
||||||
|
checkF.Text = "F";
|
||||||
|
checkF.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// checkA
|
||||||
|
//
|
||||||
|
checkA.AutoSize = true;
|
||||||
|
checkA.Location = new Point(12, 25);
|
||||||
|
checkA.Name = "checkA";
|
||||||
|
checkA.Size = new Size(35, 21);
|
||||||
|
checkA.TabIndex = 4;
|
||||||
|
checkA.Text = "A";
|
||||||
|
checkA.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// checkC
|
||||||
|
//
|
||||||
|
checkC.AutoSize = true;
|
||||||
|
checkC.Location = new Point(118, 25);
|
||||||
|
checkC.Name = "checkC";
|
||||||
|
checkC.Size = new Size(35, 21);
|
||||||
|
checkC.TabIndex = 8;
|
||||||
|
checkC.Text = "C";
|
||||||
|
checkC.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// checkE
|
||||||
|
//
|
||||||
|
checkE.AutoSize = true;
|
||||||
|
checkE.Location = new Point(225, 25);
|
||||||
|
checkE.Name = "checkE";
|
||||||
|
checkE.Size = new Size(34, 21);
|
||||||
|
checkE.TabIndex = 6;
|
||||||
|
checkE.Text = "E";
|
||||||
|
checkE.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// checkD
|
||||||
|
//
|
||||||
|
checkD.AutoSize = true;
|
||||||
|
checkD.Location = new Point(170, 25);
|
||||||
|
checkD.Name = "checkD";
|
||||||
|
checkD.Size = new Size(36, 21);
|
||||||
|
checkD.TabIndex = 7;
|
||||||
|
checkD.Text = "D";
|
||||||
|
checkD.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// btnConfirm
|
||||||
|
//
|
||||||
|
btnConfirm.Location = new Point(125, 387);
|
||||||
|
btnConfirm.Name = "btnConfirm";
|
||||||
|
btnConfirm.Size = new Size(99, 32);
|
||||||
|
btnConfirm.TabIndex = 2;
|
||||||
|
btnConfirm.Text = "确定提交";
|
||||||
|
btnConfirm.UseVisualStyleBackColor = true;
|
||||||
|
btnConfirm.Click += OnConfirm;
|
||||||
|
//
|
||||||
|
// panel1
|
||||||
|
//
|
||||||
|
panel1.Controls.Add(inputQuestion);
|
||||||
|
panel1.Location = new Point(15, 28);
|
||||||
|
panel1.Name = "panel1";
|
||||||
|
panel1.Size = new Size(320, 218);
|
||||||
|
panel1.TabIndex = 3;
|
||||||
|
//
|
||||||
|
// inputQuestion
|
||||||
|
//
|
||||||
|
inputQuestion.Dock = DockStyle.Fill;
|
||||||
|
inputQuestion.Location = new Point(0, 0);
|
||||||
|
inputQuestion.Multiline = true;
|
||||||
|
inputQuestion.Name = "inputQuestion";
|
||||||
|
inputQuestion.Size = new Size(320, 218);
|
||||||
|
inputQuestion.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// MainForm
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 17F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
ClientSize = new Size(374, 448);
|
||||||
|
Controls.Add(groupTypeQuestion);
|
||||||
|
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||||
|
Name = "MainForm";
|
||||||
|
Text = "互动答题";
|
||||||
|
Load += OnLoad;
|
||||||
|
groupTypeQuestion.ResumeLayout(false);
|
||||||
|
groupResult.ResumeLayout(false);
|
||||||
|
groupResult.PerformLayout();
|
||||||
|
groupTypeInput.ResumeLayout(false);
|
||||||
|
groupTypeInput.PerformLayout();
|
||||||
|
groupTypeSelect.ResumeLayout(false);
|
||||||
|
groupTypeSelect.PerformLayout();
|
||||||
|
panel1.ResumeLayout(false);
|
||||||
|
panel1.PerformLayout();
|
||||||
|
ResumeLayout(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
private GroupBox groupTypeQuestion;
|
||||||
|
private Button btnConfirm;
|
||||||
|
private Panel panel1;
|
||||||
|
private TextBox inputQuestion;
|
||||||
|
private CheckBox checkA;
|
||||||
|
private CheckBox checkB;
|
||||||
|
private CheckBox checkC;
|
||||||
|
private CheckBox checkD;
|
||||||
|
private CheckBox checkE;
|
||||||
|
private CheckBox checkF;
|
||||||
|
private GroupBox groupTypeSelect;
|
||||||
|
private GroupBox groupTypeInput;
|
||||||
|
private TextBox inputAnswer;
|
||||||
|
private GroupBox groupResult;
|
||||||
|
private Label label1;
|
||||||
|
private TextBox inputWrong;
|
||||||
|
private Label label3;
|
||||||
|
private TextBox inputRight;
|
||||||
|
private Label label2;
|
||||||
|
private TextBox inputJoin;
|
||||||
|
}
|
||||||
|
}
|
||||||
349
cmonitor.snatch.win/MainForm.cs
Normal file
349
cmonitor.snatch.win/MainForm.cs
Normal file
@@ -0,0 +1,349 @@
|
|||||||
|
using cmonitor.libs;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace cmonitor.snatch.win
|
||||||
|
{
|
||||||
|
public partial class MainForm : Form
|
||||||
|
{
|
||||||
|
protected override CreateParams CreateParams
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
const int WS_EX_APPWINDOW = 0x40000;
|
||||||
|
const int WS_EX_TOOLWINDOW = 0x80;
|
||||||
|
CreateParams cp = base.CreateParams;
|
||||||
|
cp.ExStyle &= (~WS_EX_APPWINDOW);
|
||||||
|
cp.ExStyle |= WS_EX_TOOLWINDOW;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SnatchQuestionInfo snatchQuesionInfo;
|
||||||
|
SnatchAnswerInfo snatchAnswerInfo;
|
||||||
|
private readonly ShareMemory shareMemory;
|
||||||
|
private int shareQuestionIndex;
|
||||||
|
private int shareAnswerIndex;
|
||||||
|
private string key = "SnatchAnswer";
|
||||||
|
private DateTime startTime = new DateTime(1970, 1, 1);
|
||||||
|
|
||||||
|
public MainForm(string shareMkey, int shareMLength, int shareItemMLength, int shareQuestionIndex, int shareAnswerIndex)
|
||||||
|
{
|
||||||
|
StartPosition = FormStartPosition.CenterScreen;
|
||||||
|
MaximizeBox = false;
|
||||||
|
MinimizeBox = false;
|
||||||
|
ControlBox = false;
|
||||||
|
ShowInTaskbar = false;
|
||||||
|
TopMost = true;
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
this.shareQuestionIndex = shareQuestionIndex;
|
||||||
|
this.shareAnswerIndex = shareAnswerIndex;
|
||||||
|
this.shareMemory = new ShareMemory(shareMkey, shareMLength, shareItemMLength);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckBox[] options = Array.Empty<CheckBox>();
|
||||||
|
private void OnLoad(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
options = new CheckBox[] { checkA, checkB, checkC, checkD, checkE, checkF };
|
||||||
|
|
||||||
|
shareMemory.InitLocal();
|
||||||
|
shareMemory.WriteRunning(shareQuestionIndex, true);
|
||||||
|
shareMemory.WriteClosed(shareQuestionIndex, false);
|
||||||
|
shareMemory.WriteRunning(shareAnswerIndex, true);
|
||||||
|
shareMemory.WriteClosed(shareAnswerIndex, false);
|
||||||
|
shareMemory.StateAction((index, state) =>
|
||||||
|
{
|
||||||
|
if (shareQuestionIndex == index)
|
||||||
|
{
|
||||||
|
if ((state & ShareMemoryState.Updated) == ShareMemoryState.Updated)
|
||||||
|
{
|
||||||
|
ReadQuestionMemory();
|
||||||
|
CheckState();
|
||||||
|
}
|
||||||
|
if ((state & ShareMemoryState.Closed) == ShareMemoryState.Closed)
|
||||||
|
{
|
||||||
|
WriteAnswerConfirmIfState(SnatchState.Ask, false, string.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (shareAnswerIndex == index)
|
||||||
|
{
|
||||||
|
if ((state & ShareMemoryState.Updated) == ShareMemoryState.Updated)
|
||||||
|
{
|
||||||
|
ReadAnswerMemory();
|
||||||
|
CheckState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
shareMemory.Loop();
|
||||||
|
ReadMemory();
|
||||||
|
CheckState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetAnswer()
|
||||||
|
{
|
||||||
|
if (snatchQuesionInfo.Type == SnatchType.Select)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < snatchQuesionInfo.Option; i++)
|
||||||
|
{
|
||||||
|
if (options[i].Checked)
|
||||||
|
sb.Append((char)(i + 65));
|
||||||
|
}
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
else if (snatchQuesionInfo.Type == SnatchType.Input)
|
||||||
|
{
|
||||||
|
return inputAnswer.Text.Trim();
|
||||||
|
}
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
private void OnConfirm(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (snatchQuesionInfo.End)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"答题已结束");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (snatchAnswerInfo.State == SnatchState.Confirm && snatchQuesionInfo.Repeat == false)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"已答题,不可重复作答");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (snatchAnswerInfo.Times > snatchQuesionInfo.Max)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"超过重复答题次数上线");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string answer = GetAnswer();
|
||||||
|
if (string.IsNullOrWhiteSpace(answer))
|
||||||
|
{
|
||||||
|
MessageBox.Show($"请给出你的答案");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loading = true;
|
||||||
|
Task.Run(() =>
|
||||||
|
{
|
||||||
|
CheckBtn();
|
||||||
|
WriteAnswerConfirm(answer == snatchQuesionInfo.Correct, answer);
|
||||||
|
|
||||||
|
loading = false;
|
||||||
|
CheckState();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private void CloseClear()
|
||||||
|
{
|
||||||
|
shareMemory.WriteRunning(shareQuestionIndex, false);
|
||||||
|
shareMemory.WriteClosed(shareQuestionIndex, true);
|
||||||
|
shareMemory.WriteRunning(shareAnswerIndex, false);
|
||||||
|
shareMemory.WriteClosed(shareAnswerIndex, true);
|
||||||
|
|
||||||
|
Application.ExitThread();
|
||||||
|
Application.Exit();
|
||||||
|
Process.GetCurrentProcess().Kill();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReadQuestionMemory()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string result = shareMemory.GetItemValue(shareQuestionIndex);
|
||||||
|
if (string.IsNullOrWhiteSpace(result))
|
||||||
|
{
|
||||||
|
snatchQuesionInfo = new SnatchQuestionInfo { Question = "测试测试", Correct = "ABC", Option = 5, Type = SnatchType.Select };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snatchQuesionInfo = JsonSerializer.Deserialize<SnatchQuestionInfo>(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
CloseClear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void ReadAnswerMemory()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string result = shareMemory.GetItemValue(shareAnswerIndex);
|
||||||
|
if (string.IsNullOrWhiteSpace(result))
|
||||||
|
{
|
||||||
|
snatchAnswerInfo = new SnatchAnswerInfo { Result = false, ResultStr = "ABC", State = SnatchState.Ask, };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snatchAnswerInfo = JsonSerializer.Deserialize<SnatchAnswerInfo>(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
CloseClear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void ReadMemory()
|
||||||
|
{
|
||||||
|
ReadQuestionMemory();
|
||||||
|
ReadAnswerMemory();
|
||||||
|
}
|
||||||
|
private void WriteAnswerConfirmIfState(SnatchState state, bool result, string resultStr)
|
||||||
|
{
|
||||||
|
if (snatchAnswerInfo.State == state)
|
||||||
|
{
|
||||||
|
WriteAnswerConfirm(result, resultStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void WriteAnswerConfirm(bool result, string resultStr)
|
||||||
|
{
|
||||||
|
snatchAnswerInfo.State = SnatchState.Confirm;
|
||||||
|
snatchAnswerInfo.Result = result;
|
||||||
|
snatchAnswerInfo.ResultStr = resultStr;
|
||||||
|
snatchAnswerInfo.Time = (long)(DateTime.UtcNow.Subtract(startTime)).TotalMilliseconds;
|
||||||
|
snatchAnswerInfo.Times++;
|
||||||
|
shareMemory.Update(shareAnswerIndex, key, JsonSerializer.Serialize(snatchAnswerInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool loading = false;
|
||||||
|
private void EnableBtn(string text)
|
||||||
|
{
|
||||||
|
this.Invoke(() =>
|
||||||
|
{
|
||||||
|
btnConfirm.Text = text;
|
||||||
|
btnConfirm.Enabled = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private void DisableBtn(string text)
|
||||||
|
{
|
||||||
|
this.Invoke(() =>
|
||||||
|
{
|
||||||
|
btnConfirm.Text = text;
|
||||||
|
btnConfirm.Enabled = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckOptions()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < options.Length; i++)
|
||||||
|
{
|
||||||
|
options[i].Visible = i < snatchQuesionInfo.Option;
|
||||||
|
options[i].Checked = false;
|
||||||
|
}
|
||||||
|
if (string.IsNullOrWhiteSpace(snatchAnswerInfo.ResultStr) == false && snatchAnswerInfo.ResultStr.Length <= snatchQuesionInfo.Option)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < snatchAnswerInfo.ResultStr.Length; i++)
|
||||||
|
{
|
||||||
|
char option = snatchAnswerInfo.ResultStr[i];
|
||||||
|
if (option >= 'A' && option <= 'Z' && option - 'A' < options.Length)
|
||||||
|
{
|
||||||
|
options[(option - 'A')].Checked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void CheckBtn()
|
||||||
|
{
|
||||||
|
if (loading)
|
||||||
|
{
|
||||||
|
DisableBtn("操作中..");
|
||||||
|
}
|
||||||
|
else if (snatchAnswerInfo.State == SnatchState.Confirm)
|
||||||
|
{
|
||||||
|
btnConfirm.ForeColor = (snatchAnswerInfo.Result ? Color.Green : Color.Red);
|
||||||
|
EnableBtn(snatchAnswerInfo.Result ? "答题正确" : "答题错误");
|
||||||
|
}
|
||||||
|
else if (snatchQuesionInfo.End)
|
||||||
|
{
|
||||||
|
EnableBtn("已结束");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EnableBtn("确定提交");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void CheckState()
|
||||||
|
{
|
||||||
|
this.Invoke(() =>
|
||||||
|
{
|
||||||
|
CheckOptions();
|
||||||
|
|
||||||
|
CheckBtn();
|
||||||
|
|
||||||
|
groupTypeSelect.Visible = false;
|
||||||
|
groupTypeInput.Visible = false;
|
||||||
|
if (snatchQuesionInfo.Type == SnatchType.Select)
|
||||||
|
{
|
||||||
|
groupTypeSelect.Visible = true;
|
||||||
|
}
|
||||||
|
else if (snatchQuesionInfo.Type == SnatchType.Input)
|
||||||
|
{
|
||||||
|
groupTypeInput.Visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inputQuestion.Text = snatchQuesionInfo.Question;
|
||||||
|
|
||||||
|
|
||||||
|
inputJoin.Text = snatchQuesionInfo.Join.ToString();
|
||||||
|
inputRight.Text = snatchQuesionInfo.Right.ToString();
|
||||||
|
inputWrong.Text = snatchQuesionInfo.Wrong.ToString();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class SnatchQuestionInfo
|
||||||
|
{
|
||||||
|
public SnatchType Type { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 问题
|
||||||
|
/// </summary>
|
||||||
|
public string Question { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 正确答案
|
||||||
|
/// </summary>
|
||||||
|
public string Correct { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 选项数
|
||||||
|
/// </summary>
|
||||||
|
public int Option { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 最多答题数
|
||||||
|
/// </summary>
|
||||||
|
public int Max { get; set; } = int.MaxValue;
|
||||||
|
/// <summary>
|
||||||
|
/// 已结束
|
||||||
|
/// </summary>
|
||||||
|
public bool End { get; set; } = false;
|
||||||
|
/// <summary>
|
||||||
|
/// 重复答题
|
||||||
|
/// </summary>
|
||||||
|
public bool Repeat { get; set; } = true;
|
||||||
|
public int Join { get; set; } = 0;
|
||||||
|
public int Right { get; set; } = 0;
|
||||||
|
public int Wrong { get; set; } = 0;
|
||||||
|
}
|
||||||
|
sealed class SnatchAnswerInfo
|
||||||
|
{
|
||||||
|
public SnatchState State { get; set; }
|
||||||
|
public bool Result { get; set; }
|
||||||
|
public long Time { get; set; }
|
||||||
|
public int Times { get; set; }
|
||||||
|
public string ResultStr { get; set; }
|
||||||
|
}
|
||||||
|
enum SnatchState : byte
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Ask = 1,
|
||||||
|
Confirm = 2,
|
||||||
|
}
|
||||||
|
enum SnatchType : byte
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Select = 1,
|
||||||
|
Input = 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
400
cmonitor.snatch.win/MainForm.resx
Normal file
400
cmonitor.snatch.win/MainForm.resx
Normal file
@@ -0,0 +1,400 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
|
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>
|
||||||
|
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
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
32
cmonitor.snatch.win/Program.cs
Normal file
32
cmonitor.snatch.win/Program.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
namespace cmonitor.snatch.win
|
||||||
|
{
|
||||||
|
internal static class Program
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The main entry point for the application.
|
||||||
|
/// </summary>
|
||||||
|
[STAThread]
|
||||||
|
static void Main(string[] arg)
|
||||||
|
{
|
||||||
|
string shareMkey = "cmonitor/share";
|
||||||
|
int shareMLength = 10;
|
||||||
|
int shareItemMLength = 1024;
|
||||||
|
int shareQuestionIndex = 5;
|
||||||
|
int shareAnswerIndex = 6;
|
||||||
|
if (arg.Length > 0)
|
||||||
|
{
|
||||||
|
shareMkey = arg[0];
|
||||||
|
shareMLength = int.Parse(arg[1]);
|
||||||
|
shareItemMLength = int.Parse(arg[2]);
|
||||||
|
shareQuestionIndex = int.Parse(arg[3]);
|
||||||
|
shareAnswerIndex = int.Parse(arg[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// To customize application configuration such as set high DPI settings or default font,
|
||||||
|
// see https://aka.ms/applicationconfiguration.
|
||||||
|
ApplicationConfiguration.Initialize();
|
||||||
|
Application.Run(new MainForm(shareMkey, shareMLength, shareItemMLength, shareQuestionIndex, shareAnswerIndex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
79
cmonitor.snatch.win/app.manifest
Normal file
79
cmonitor.snatch.win/app.manifest
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
|
||||||
|
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||||
|
<security>
|
||||||
|
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<!-- UAC 清单选项
|
||||||
|
如果想要更改 Windows 用户帐户控制级别,请使用
|
||||||
|
以下节点之一替换 requestedExecutionLevel 节点。
|
||||||
|
|
||||||
|
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||||
|
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||||
|
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||||
|
|
||||||
|
指定 requestedExecutionLevel 元素将禁用文件和注册表虚拟化。
|
||||||
|
如果你的应用程序需要此虚拟化来实现向后兼容性,则移除此
|
||||||
|
元素。
|
||||||
|
-->
|
||||||
|
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||||
|
</requestedPrivileges>
|
||||||
|
</security>
|
||||||
|
</trustInfo>
|
||||||
|
|
||||||
|
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||||
|
<application>
|
||||||
|
<!-- 设计此应用程序与其一起工作且已针对此应用程序进行测试的
|
||||||
|
Windows 版本的列表。取消评论适当的元素,
|
||||||
|
Windows 将自动选择最兼容的环境。 -->
|
||||||
|
|
||||||
|
<!-- Windows Vista -->
|
||||||
|
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
|
||||||
|
|
||||||
|
<!-- Windows 7 -->
|
||||||
|
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
|
||||||
|
|
||||||
|
<!-- Windows 8 -->
|
||||||
|
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
|
||||||
|
|
||||||
|
<!-- Windows 8.1 -->
|
||||||
|
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
|
||||||
|
|
||||||
|
<!-- Windows 10 -->
|
||||||
|
<!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
|
||||||
|
|
||||||
|
</application>
|
||||||
|
</compatibility>
|
||||||
|
|
||||||
|
<!-- 指示该应用程序可感知 DPI 且 Windows 在 DPI 较高时将不会对其进行
|
||||||
|
自动缩放。Windows Presentation Foundation (WPF)应用程序自动感知 DPI,无需
|
||||||
|
选择加入。选择加入此设置的 Windows 窗体应用程序(面向 .NET Framework 4.6)还应
|
||||||
|
在其 app.config 中将 "EnableWindowsFormsHighDpiAutoResizing" 设置设置为 "true"。
|
||||||
|
|
||||||
|
将应用程序设为感知长路径。请参阅 https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation -->
|
||||||
|
<!--
|
||||||
|
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<windowsSettings>
|
||||||
|
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||||
|
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
|
||||||
|
</windowsSettings>
|
||||||
|
</application>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- 启用 Windows 公共控件和对话框的主题(Windows XP 和更高版本) -->
|
||||||
|
<!--
|
||||||
|
<dependency>
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity
|
||||||
|
type="win32"
|
||||||
|
name="Microsoft.Windows.Common-Controls"
|
||||||
|
version="6.0.0.0"
|
||||||
|
processorArchitecture="*"
|
||||||
|
publicKeyToken="6595b64144ccf1df"
|
||||||
|
language="*"
|
||||||
|
/>
|
||||||
|
</dependentAssembly>
|
||||||
|
</dependency>
|
||||||
|
-->
|
||||||
|
|
||||||
|
</assembly>
|
||||||
22
cmonitor.snatch.win/cmonitor.snatch.win.csproj
Normal file
22
cmonitor.snatch.win/cmonitor.snatch.win.csproj
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<TargetFrameworks>net7.0-windows;net8.0-windows</TargetFrameworks>
|
||||||
|
<Nullable>disable</Nullable>
|
||||||
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Configurations>Debug;Release;ReleaseLinux</Configurations>
|
||||||
|
<ApplicationIcon>favicon.ico</ApplicationIcon>
|
||||||
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="favicon.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\cmonitor.libs\cmonitor.libs.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
8
cmonitor.snatch.win/cmonitor.snatch.win.csproj.user
Normal file
8
cmonitor.snatch.win/cmonitor.snatch.win.csproj.user
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Update="MainForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
BIN
cmonitor.snatch.win/favicon.ico
Normal file
BIN
cmonitor.snatch.win/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
@@ -1,7 +1,7 @@
|
|||||||
import { sendWebsocketMsg } from './request'
|
import { sendWebsocketMsg } from './request'
|
||||||
|
|
||||||
export const shareUpdate = (name, item) => {
|
export const shareUpdate = (names, item) => {
|
||||||
return sendWebsocketMsg('share/update', {
|
return sendWebsocketMsg('share/update', {
|
||||||
name, item
|
names, item
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
26
cmonitor.web/src/apis/snatch.js
Normal file
26
cmonitor.web/src/apis/snatch.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { sendWebsocketMsg } from './request'
|
||||||
|
|
||||||
|
|
||||||
|
export const addGroup = (data) => {
|
||||||
|
return sendWebsocketMsg('snatch/AddGroup', data);
|
||||||
|
}
|
||||||
|
export const delGroup = (username, id) => {
|
||||||
|
return sendWebsocketMsg('snatch/DeleteGroup', {
|
||||||
|
username, id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export const add = (data) => {
|
||||||
|
return sendWebsocketMsg('snatch/add', data);
|
||||||
|
}
|
||||||
|
export const del = (username, groupid, id) => {
|
||||||
|
return sendWebsocketMsg('snatch/del', {
|
||||||
|
username, groupid, id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export const update = (names, question) => {
|
||||||
|
return sendWebsocketMsg('snatch/update', {
|
||||||
|
names, item: question
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -34,9 +34,16 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
|
// @media (min-width: 768px) {
|
||||||
|
// .main-wrap {
|
||||||
|
// background-color: #1c77ac !important;
|
||||||
|
// background-image: none !important;
|
||||||
|
// // background-image: url('../assets/bg.jpg') !important;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
.main-wrap {
|
.main-wrap {
|
||||||
background-image: url('../assets/bg.jpg') !important;
|
max-width: 39rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="device-list-wrap absolute flex flex-column flex-nowarp" id="device-list-wrap">
|
<div class="device-list-wrap absolute flex flex-column flex-nowarp" id="device-list-wrap">
|
||||||
<div class="content flex-1 flex">
|
<div class="content flex-1 flex flex-column">
|
||||||
<div class="items flex-1 relative scrollbar-1">
|
<div class="head" v-if="globalData.pc">
|
||||||
<Items></Items>
|
|
||||||
</div>
|
|
||||||
<div class="active-device flex flex-column" v-if="globalData.pc">
|
|
||||||
<div class="head">
|
|
||||||
|
|
||||||
<Head></Head>
|
<Head></Head>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="items flex-1 relative scrollbar-1">
|
||||||
|
<Items></Items>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="active-device flex flex-column" v-if="globalData.pc">
|
||||||
|
|
||||||
|
|
||||||
<div class="flex-1 prev">
|
<div class="flex-1 prev">
|
||||||
|
|
||||||
@@ -19,7 +20,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="foot" v-if="!globalData.pc">
|
<div class="foot" v-if="!globalData.pc">
|
||||||
<div class="foot-options">
|
<div class="foot-options">
|
||||||
@@ -68,24 +69,35 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
@media (min-width: 768px) {
|
// @media (min-width: 768px) {
|
||||||
.active-device {
|
// .active-device {
|
||||||
width: calc(100% - 41rem) !important;
|
// // width: calc(100% - 41rem) !important;
|
||||||
}
|
// }
|
||||||
|
|
||||||
.items {
|
// .items {
|
||||||
height: 100%;
|
// padding: 1rem 1rem 0 1rem !important;
|
||||||
padding: 1rem 0 !important;
|
// height: auto;
|
||||||
box-sizing: border-box;
|
// width: 80.6rem;
|
||||||
border-right: 1px solid #999;
|
// // padding: 1rem 0 !important;
|
||||||
background-color: rgba(255, 255, 255, 0.3);
|
// box-sizing: border-box;
|
||||||
}
|
// // border-right: 1px solid #999;
|
||||||
|
// // background-color: rgba(255, 255, 255, 0.3);
|
||||||
.foot {
|
// display: flex;
|
||||||
display: none;
|
// display: -ms-flex;
|
||||||
}
|
// display: -o-flex;
|
||||||
}
|
// flex-wrap: wrap;
|
||||||
|
// justify-content: space-between;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .foot {
|
||||||
|
// display: none;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// @media (min-width: 768px) {
|
||||||
|
// .items {
|
||||||
|
// max-width: 39rem;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
.device-list-wrap {
|
.device-list-wrap {
|
||||||
.content {
|
.content {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export default {
|
|||||||
showEdit: false,
|
showEdit: false,
|
||||||
list: computed(() => {
|
list: computed(() => {
|
||||||
let user = globalData.value.usernames[globalData.value.username];
|
let user = globalData.value.usernames[globalData.value.username];
|
||||||
if (user) {
|
if (user && user.Windows) {
|
||||||
if (state.group == 0 && user.Windows.length > 0) {
|
if (state.group == 0 && user.Windows.length > 0) {
|
||||||
state.group = user.Windows[0].ID;
|
state.group = user.Windows[0].ID;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export default {
|
|||||||
showEdit: false,
|
showEdit: false,
|
||||||
groups: computed(() => {
|
groups: computed(() => {
|
||||||
let user = globalData.value.usernames[globalData.value.username];
|
let user = globalData.value.usernames[globalData.value.username];
|
||||||
if (user) {
|
if (user && user.Windows) {
|
||||||
if (state.group == 0 && user.Windows.length > 0) {
|
if (state.group == 0 && user.Windows.length > 0) {
|
||||||
state.group = user.Windows[0].ID;
|
state.group = user.Windows[0].ID;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,14 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inner {
|
||||||
|
padding: 0.6rem;
|
||||||
|
|
||||||
|
&>div {
|
||||||
|
padding: 0.6rem 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export default {
|
|||||||
showEdit: false,
|
showEdit: false,
|
||||||
list: computed(() => {
|
list: computed(() => {
|
||||||
let user = globalData.value.usernames[globalData.value.username];
|
let user = globalData.value.usernames[globalData.value.username];
|
||||||
if (user) {
|
if (user && user.Processs) {
|
||||||
if (state.group == 0 && user.Processs.length > 0) {
|
if (state.group == 0 && user.Processs.length > 0) {
|
||||||
state.group = user.Processs[0].ID;
|
state.group = user.Processs[0].ID;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export default {
|
|||||||
showEdit: false,
|
showEdit: false,
|
||||||
groups: computed(() => {
|
groups: computed(() => {
|
||||||
let user = globalData.value.usernames[globalData.value.username];
|
let user = globalData.value.usernames[globalData.value.username];
|
||||||
if (user) {
|
if (user && user.Processs) {
|
||||||
if (state.group == 0 && user.Processs.length > 0) {
|
if (state.group == 0 && user.Processs.length > 0) {
|
||||||
state.group = user.Processs[0].ID;
|
state.group = user.Processs[0].ID;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export default {
|
|||||||
showEdit: false,
|
showEdit: false,
|
||||||
list: computed(() => {
|
list: computed(() => {
|
||||||
let user = globalData.value.usernames[globalData.value.username];
|
let user = globalData.value.usernames[globalData.value.username];
|
||||||
if (user) {
|
if (user && user.Rules) {
|
||||||
if (state.group == 0 && user.Rules.length > 0) {
|
if (state.group == 0 && user.Rules.length > 0) {
|
||||||
state.group = user.Rules[0].ID;
|
state.group = user.Rules[0].ID;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export default {
|
|||||||
loading: false,
|
loading: false,
|
||||||
group: 0,
|
group: 0,
|
||||||
groups: computed(() => {
|
groups: computed(() => {
|
||||||
if (user.value) {
|
if (user.value && user.value.Rules) {
|
||||||
if (state.group == 0 && user.value.Rules.length > 0) {
|
if (state.group == 0 && user.value.Rules.length > 0) {
|
||||||
state.group = user.value.Rules[0].ID;
|
state.group = user.value.Rules[0].ID;
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ export default {
|
|||||||
return [];
|
return [];
|
||||||
}),
|
}),
|
||||||
rule: computed(() => {
|
rule: computed(() => {
|
||||||
if (user) {
|
if (user && user.value.Rules) {
|
||||||
let rule = user.value.Rules.filter(c => c.ID == state.group)[0];
|
let rule = user.value.Rules.filter(c => c.ID == state.group)[0];
|
||||||
if (rule) {
|
if (rule) {
|
||||||
return rule;
|
return rule;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog class="options" title="设置" destroy-on-close v-model="state.show" center :close-on-click-modal="false" align-center width="94%">
|
<el-dialog class="options-center" title="设置" destroy-on-close v-model="state.show" center :close-on-click-modal="false" align-center width="94%">
|
||||||
<div class="setting-wrap">
|
<div class="setting-wrap">
|
||||||
<el-form ref="ruleFormRef" :model="state.form" :rules="state.rules" label-width="100px">
|
<el-form ref="ruleFormRef" :model="state.form" :rules="state.rules" label-width="100px">
|
||||||
<el-form-item label="报告延迟(ms)" prop="ReportDelay">
|
<el-form-item label="报告延迟(ms)" prop="ReportDelay">
|
||||||
|
|||||||
19
cmonitor.web/src/views/device/plugins/share/Index.vue
Normal file
19
cmonitor.web/src/views/device/plugins/share/Index.vue
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- <ChooseDig v-if="pluginState.setting.showSetting" v-model="pluginState.setting.showSetting"></ChooseDig> -->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { injectPluginState } from '../../provide';
|
||||||
|
// import ChooseDig from './ChooseDig.vue'
|
||||||
|
export default {
|
||||||
|
components: {},
|
||||||
|
setup() {
|
||||||
|
const pluginState = injectPluginState();
|
||||||
|
return { pluginState }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped></style>
|
||||||
@@ -52,7 +52,7 @@ export default {
|
|||||||
state.loading = true;
|
state.loading = true;
|
||||||
let value = JSON.parse(JSON.stringify(props.data.Share.Lock.Value));
|
let value = JSON.parse(JSON.stringify(props.data.Share.Lock.Value));
|
||||||
value.val = 'reject';
|
value.val = 'reject';
|
||||||
shareUpdate(props.data.MachineName, {
|
shareUpdate([props.data.MachineName], {
|
||||||
index: props.data.Share.Lock.Index,
|
index: props.data.Share.Lock.Index,
|
||||||
value: JSON.stringify(value)
|
value: JSON.stringify(value)
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
@@ -72,7 +72,7 @@ export default {
|
|||||||
let value = JSON.parse(JSON.stringify(props.data.Share.Lock.Value));
|
let value = JSON.parse(JSON.stringify(props.data.Share.Lock.Value));
|
||||||
value.val = 'confirm';
|
value.val = 'confirm';
|
||||||
props.data.Share.Lock.Value.notify = false;
|
props.data.Share.Lock.Value.notify = false;
|
||||||
shareUpdate(props.data.MachineName, {
|
shareUpdate([props.data.MachineName], {
|
||||||
index: props.data.Share.Lock.Index,
|
index: props.data.Share.Lock.Index,
|
||||||
value: JSON.stringify(value)
|
value: JSON.stringify(value)
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
@@ -94,7 +94,7 @@ export default {
|
|||||||
const handleStarChange = () => {
|
const handleStarChange = () => {
|
||||||
state.loading = true;
|
state.loading = true;
|
||||||
let value = JSON.parse(JSON.stringify(props.data.Share.Lock.Value));
|
let value = JSON.parse(JSON.stringify(props.data.Share.Lock.Value));
|
||||||
shareUpdate(props.data.MachineName, {
|
shareUpdate([props.data.MachineName], {
|
||||||
index: props.data.Share.Lock.Index,
|
index: props.data.Share.Lock.Index,
|
||||||
value: JSON.stringify(value)
|
value: JSON.stringify(value)
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ export default {
|
|||||||
},
|
},
|
||||||
init() {
|
init() {
|
||||||
},
|
},
|
||||||
lockTypes: { code: '代码', lock: '锁屏', cmonitor: '班长', flag: '学习目标', class: '课程', 'remark-block': '图形化点评', 'remark-cpp': 'C++点评' },
|
|
||||||
update(item, report) {
|
update(item, report) {
|
||||||
if (!report.Share) return;
|
if (!report.Share) return;
|
||||||
|
|
||||||
@@ -64,7 +63,7 @@ export default {
|
|||||||
item.Share.Lock.Value.star1 = json.star1 || 0;
|
item.Share.Lock.Value.star1 = json.star1 || 0;
|
||||||
item.Share.Lock.Value.star2 = json.star2 || 0;
|
item.Share.Lock.Value.star2 = json.star2 || 0;
|
||||||
item.Share.Lock.Value.star3 = json.star3 || 0;
|
item.Share.Lock.Value.star3 = json.star3 || 0;
|
||||||
item.Share.Lock.TypeText = this.lockTypes[json.type];
|
item.Share.Lock.TypeText = json.typeText;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (report.Share.KeyBoard) {
|
if (report.Share.KeyBoard) {
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<template>
|
||||||
|
<div class="item">
|
||||||
|
<div class="subitem">
|
||||||
|
<span class="label">互动抢答</span>
|
||||||
|
<el-button @click="handleSnatchUse">开始</el-button>
|
||||||
|
<el-button @click="handleSnatchQuestion">录题</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<SnatchTemplate v-if="pluginState.shareSnatch.showTemplate" v-model="pluginState.shareSnatch.showTemplate"></SnatchTemplate>
|
||||||
|
<SnatchUse v-if="pluginState.shareSnatch.showUse" v-model="pluginState.shareSnatch.showUse"></SnatchUse>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { injectPluginState } from '@/views/device/provide';
|
||||||
|
import SnatchTemplate from './template/Template.vue'
|
||||||
|
import SnatchUse from './use/Use.vue'
|
||||||
|
export default {
|
||||||
|
components: { SnatchTemplate, SnatchUse },
|
||||||
|
setup() {
|
||||||
|
|
||||||
|
const pluginState = injectPluginState();
|
||||||
|
|
||||||
|
|
||||||
|
const handleSnatchQuestion = () => {
|
||||||
|
pluginState.value.shareSnatch.showTemplate = true;
|
||||||
|
}
|
||||||
|
const handleSnatchUse = () => {
|
||||||
|
pluginState.value.shareSnatch.showUse = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { pluginState, handleSnatchUse, handleSnatchQuestion }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped></style>
|
||||||
41
cmonitor.web/src/views/device/plugins/share/snatch/index.js
Normal file
41
cmonitor.web/src/views/device/plugins/share/snatch/index.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
export default {
|
||||||
|
field() {
|
||||||
|
return {
|
||||||
|
ShareSnatch: {
|
||||||
|
Question: { Index: 0, Value: { Type: 1, Question: '', Correct: '', Option: 0, Max: 0, End: false, Repeat: false, Join: 0, Right: 0, Wrong: 0 } },
|
||||||
|
Answer: { Index: 0 },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
shareSnatch: {
|
||||||
|
showTemplate: false,
|
||||||
|
showUse: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
},
|
||||||
|
update(item, report) {
|
||||||
|
if (!report.Share) return;
|
||||||
|
|
||||||
|
console.log(report.Share);
|
||||||
|
|
||||||
|
if (report.Share.SnatchQuestion) {
|
||||||
|
item.ShareSnatch.Question.Index = report.Share.SnatchQuestion.Index;
|
||||||
|
const json = JSON.parse(report.Share.SnatchQuestion.Value);
|
||||||
|
item.ShareSnatch.Question.Value.Type = json.Type;
|
||||||
|
item.ShareSnatch.Question.Value.Question = json.Question;
|
||||||
|
item.ShareSnatch.Question.Value.Correct = json.Correct;
|
||||||
|
item.ShareSnatch.Question.Value.Option = json.Option;
|
||||||
|
item.ShareSnatch.Question.Value.Max = json.Max;
|
||||||
|
item.ShareSnatch.Question.Value.End = json.End;
|
||||||
|
item.ShareSnatch.Question.Value.Repeat = json.Repeat;
|
||||||
|
item.ShareSnatch.Question.Value.Join = json.Join;
|
||||||
|
item.ShareSnatch.Question.Value.Right = json.Right;
|
||||||
|
item.ShareSnatch.Question.Value.Wrong = json.Wrong;
|
||||||
|
}
|
||||||
|
if (report.Share.SnatchAnswer) {
|
||||||
|
item.ShareSnatch.Answer.Index = report.Share.SnatchAnswer.Index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
<template>
|
||||||
|
<div class="snatchs-items-wrap flex flex-nowrap flex-column">
|
||||||
|
<div class="head t-c flex">
|
||||||
|
<el-button @click="handleAdd()">添加项</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1">
|
||||||
|
<div class="prevs-wrap">
|
||||||
|
<el-table :data="state.list" size="small" border stripe style="width: 100%" height="50vh">
|
||||||
|
<el-table-column prop="Name" label="名称" />
|
||||||
|
<el-table-column label="操作" width="110">
|
||||||
|
<template #default="scope">
|
||||||
|
<template v-if="scope.row.ID > 1">
|
||||||
|
<el-button size="small" @click="handleAdd(scope.row)">
|
||||||
|
<el-icon>
|
||||||
|
<EditPen />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
<el-popconfirm title="删除不可逆,是否确定?" @confirm="handleDel(scope.row)">
|
||||||
|
<template #reference>
|
||||||
|
<el-button size="small" type="danger">
|
||||||
|
<el-icon>
|
||||||
|
<Delete />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-popconfirm>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-dialog :title="`${state.currentItem.ID==0?'添加项':'修改项'}`" destroy-on-close v-model="state.showEdit" center :close-on-click-modal="false" align-center width="80%">
|
||||||
|
<div>
|
||||||
|
<el-input v-model="state.currentItem.Name" size="large" placeholder="分组名称" />
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="handleEditCancel">取 消</el-button>
|
||||||
|
<el-button type="success" plain :loading="state.loading" @click="handleEditSubmit">确 定</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { reactive } from '@vue/reactivity';
|
||||||
|
import { computed } from '@vue/runtime-core';
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
import { addGroup, delGroup } from '@/apis/snatch'
|
||||||
|
import { injectGlobalData } from '@/views/provide';
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
|
||||||
|
const globalData = injectGlobalData();;
|
||||||
|
const state = reactive({
|
||||||
|
loading: false,
|
||||||
|
currentItem: { ID: 0, Name: '' },
|
||||||
|
showEdit: false,
|
||||||
|
list: computed(() => {
|
||||||
|
let user = globalData.value.usernames[globalData.value.username];
|
||||||
|
if (user && user.Snatchs) {
|
||||||
|
if (state.group == 0 && user.Snatchs.length > 0) {
|
||||||
|
state.group = user.Snatchs[0].ID;
|
||||||
|
}
|
||||||
|
return user.Snatchs;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleAdd = (item) => {
|
||||||
|
item = item || { Name: '', ID: 0 };
|
||||||
|
state.currentItem.Name = item.Name;
|
||||||
|
state.currentItem.ID = item.ID;
|
||||||
|
state.showEdit = true;
|
||||||
|
}
|
||||||
|
const handleDel = (item) => {
|
||||||
|
state.loading = true;
|
||||||
|
delGroup(globalData.value.username, item.ID).then((error) => {
|
||||||
|
state.loading = false;
|
||||||
|
if (error) {
|
||||||
|
ElMessage.error(error);
|
||||||
|
} else {
|
||||||
|
ElMessage.success('操作成功!');
|
||||||
|
globalData.value.updateRuleFlag = Date.now();
|
||||||
|
}
|
||||||
|
}).catch((e) => {
|
||||||
|
state.loading = false;
|
||||||
|
ElMessage.error('操作失败!');
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const handleEditCancel = () => {
|
||||||
|
state.showEdit = false;
|
||||||
|
}
|
||||||
|
const handleEditSubmit = () => {
|
||||||
|
state.currentItem.Name = state.currentItem.Name.replace(/^\s|\s$/g, '');
|
||||||
|
if (!state.currentItem.Name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state.loading = true;
|
||||||
|
addGroup({
|
||||||
|
UserName: globalData.value.username,
|
||||||
|
Group: state.currentItem
|
||||||
|
}).then((error) => {
|
||||||
|
state.loading = false;
|
||||||
|
if (error) {
|
||||||
|
ElMessage.error(error);
|
||||||
|
} else {
|
||||||
|
ElMessage.success('操作成功!');
|
||||||
|
state.showEdit = false;
|
||||||
|
globalData.value.updateRuleFlag = Date.now();
|
||||||
|
}
|
||||||
|
}).catch((e) => {
|
||||||
|
state.loading = false;
|
||||||
|
ElMessage.error('操作失败!');
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return { state, handleAdd, handleDel, handleEditCancel, handleEditSubmit }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.snatchs-items-wrap {
|
||||||
|
.head {
|
||||||
|
width: 100%;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prevs-wrap {
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,229 @@
|
|||||||
|
<template>
|
||||||
|
<div class="snatchs-items-wrap flex flex-nowrap flex-column">
|
||||||
|
<div class="head t-c flex">
|
||||||
|
<el-select v-model="state.group" placeholder="选择一个分组" style="width:13rem">
|
||||||
|
<el-option v-for="item in state.groups" :key="item.ID" :label="item.Name" :value="item.ID" />
|
||||||
|
</el-select>
|
||||||
|
<span class="flex-1"></span>
|
||||||
|
<el-button @click="handleAdd()">添加项</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1">
|
||||||
|
<div class="prevs-wrap">
|
||||||
|
<el-table :data="state.list" size="small" border stripe style="width: 100%" height="50vh">
|
||||||
|
<el-table-column prop="Name" label="名称"></el-table-column>
|
||||||
|
<el-table-column label="操作" width="110">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button size="small" @click="handleAdd(scope.row)">
|
||||||
|
<el-icon>
|
||||||
|
<EditPen />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
<el-popconfirm title="删除不可逆,是否确定?" @confirm="handleDel(scope.row)">
|
||||||
|
<template #reference>
|
||||||
|
<el-button size="small" type="danger">
|
||||||
|
<el-icon>
|
||||||
|
<Delete />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-popconfirm>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-dialog :title="`${state.currentItem.ID==0?'添加项':'修改项'}`" destroy-on-close v-model="state.showEdit" center :close-on-click-modal="false" align-center width="94%">
|
||||||
|
<div>
|
||||||
|
<el-form ref="formDom" :rules="state.rules" :model="state.currentItem" label-width="0">
|
||||||
|
<el-form-item prop="Name">
|
||||||
|
<el-input v-model="state.currentItem.Name" placeholder="名称" maxlength="30" show-word-limit />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="Question">
|
||||||
|
<el-input type="textarea" resize="none" rows="6" v-model="state.currentItem.Question" placeholder="题目内容" maxlength="250" show-word-limit />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item prop="Type">
|
||||||
|
<el-select style="width:90%;" v-model="state.currentItem.Type" placeholder="类别">
|
||||||
|
<el-option v-for="item in state.types" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label-width="0" prop="Repeat">
|
||||||
|
<el-checkbox v-model="state.currentItem.Repeat" label="重复答题" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="上限" label-width="4rem" prop="Max">
|
||||||
|
<el-input v-model="state.currentItem.Max" placeholder="最多答题多少次" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
</el-row>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="state.currentItem.Type == 1">
|
||||||
|
<ul style="width:100%;">
|
||||||
|
<template v-for="(item,index) in state.currentItem.Options" :key="index">
|
||||||
|
<li class="flex" style="margin-bottom:.6rem">
|
||||||
|
<span>{{String.fromCharCode(index+65)}}、</span>
|
||||||
|
<el-input style="width:12rem;" v-model="item.Text" placeholder="" />
|
||||||
|
<span class="flex-1"></span>
|
||||||
|
<div>
|
||||||
|
<el-checkbox size="small" v-model="item.Value" label="答案" style="margin-right:.6rem" />
|
||||||
|
<el-button size="small" @click="handleAddOption(index)">添加</el-button>
|
||||||
|
<el-button size="small" @click="handleDelOption(index)">删除</el-button>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
</ul>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="state.currentItem.Type == 2">
|
||||||
|
<el-input v-model="state.currentItem.Correct" placeholder="简答题答案" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="handleEditCancel">取 消</el-button>
|
||||||
|
<el-button type="success" plain :loading="state.loading" @click="handleEditSubmit">确 定</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { reactive, ref } from '@vue/reactivity';
|
||||||
|
import { computed } from '@vue/runtime-core';
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
import { add, del } from '@/apis/snatch'
|
||||||
|
import { injectGlobalData } from '@/views/provide';
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
const globalData = injectGlobalData();;
|
||||||
|
const state = reactive({
|
||||||
|
loading: false,
|
||||||
|
group: 0,
|
||||||
|
currentItem: { ID: 0, Name: '', Type: 1, Question: '', Options: [{ Text: '', Value: false }], Correct: '', Max: 65535, Repeat: true },
|
||||||
|
rules: {
|
||||||
|
Name: [
|
||||||
|
{ required: true, message: '名称必填', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
Question: [
|
||||||
|
{ required: true, message: '内容必填', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
},
|
||||||
|
types: [
|
||||||
|
{ label: '选择题', value: 1 },
|
||||||
|
{ label: '简答题', value: 2 },
|
||||||
|
],
|
||||||
|
showEdit: false,
|
||||||
|
groups: computed(() => {
|
||||||
|
let user = globalData.value.usernames[globalData.value.username];
|
||||||
|
if (user && user.Snatchs) {
|
||||||
|
if (state.group == 0 && user.Snatchs.length > 0) {
|
||||||
|
state.group = user.Snatchs[0].ID;
|
||||||
|
}
|
||||||
|
return user.Snatchs;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}),
|
||||||
|
list: computed(() => {
|
||||||
|
let group = state.groups.filter(c => c.ID == state.group)[0];
|
||||||
|
if (group) return group.List;
|
||||||
|
return [];
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleAdd = (item) => {
|
||||||
|
item = item || { ID: 0, Name: '', Type: 1, Question: '', Options: [{ Text: '', Value: false }], Correct: '', Max: 65535, Repeat: true };
|
||||||
|
state.currentItem.Name = item.Name;
|
||||||
|
state.currentItem.Type = item.Type;
|
||||||
|
state.currentItem.ID = item.ID;
|
||||||
|
state.currentItem.Question = item.Question;
|
||||||
|
state.currentItem.Options = item.Options;
|
||||||
|
state.currentItem.Correct = item.Correct;
|
||||||
|
state.currentItem.Max = item.Max;
|
||||||
|
state.currentItem.Repeat = item.Repeat;
|
||||||
|
state.showEdit = true;
|
||||||
|
}
|
||||||
|
const handleDel = (item) => {
|
||||||
|
state.loading = true;
|
||||||
|
del(globalData.value.username, state.group, item.ID).then((error) => {
|
||||||
|
state.loading = false;
|
||||||
|
if (error) {
|
||||||
|
ElMessage.error(error);
|
||||||
|
} else {
|
||||||
|
ElMessage.success('操作成功!');
|
||||||
|
globalData.value.updateRuleFlag = Date.now();
|
||||||
|
}
|
||||||
|
}).catch((e) => {
|
||||||
|
state.loading = false;
|
||||||
|
ElMessage.error('操作失败!');
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const handleEditCancel = () => {
|
||||||
|
state.showEdit = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formDom = ref(null);
|
||||||
|
const handleEditSubmit = () => {
|
||||||
|
formDom.value.validate((valid) => {
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
|
state.loading = true;
|
||||||
|
const json = JSON.parse(JSON.stringify(state.currentItem));
|
||||||
|
json.Max = +json.Max;
|
||||||
|
json.Type = +json.Type;
|
||||||
|
json.Name = json.Name.replace(/^\s|\s$/g, '');
|
||||||
|
json.Correct = json.Correct.replace(/^\s|\s$/g, '');
|
||||||
|
if (json.Type == 2 && !json.Correct) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
add({
|
||||||
|
UserName: globalData.value.username,
|
||||||
|
GroupID: state.group,
|
||||||
|
Item: json
|
||||||
|
}).then((error) => {
|
||||||
|
state.loading = false;
|
||||||
|
if (error) {
|
||||||
|
ElMessage.error(error);
|
||||||
|
} else {
|
||||||
|
ElMessage.success('操作成功!');
|
||||||
|
state.showEdit = false;
|
||||||
|
globalData.value.updateRuleFlag = Date.now();
|
||||||
|
}
|
||||||
|
}).catch((e) => {
|
||||||
|
state.loading = false;
|
||||||
|
ElMessage.error('操作失败!');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAddOption = (index) => {
|
||||||
|
if (state.currentItem.Options.length >= 6) return;
|
||||||
|
state.currentItem.Options.splice(index + 1, 0, { Text: '', Value: false });
|
||||||
|
}
|
||||||
|
const handleDelOption = (index) => {
|
||||||
|
if (state.currentItem.Options.length <= 1) return;
|
||||||
|
state.currentItem.Options.splice(index, 1);
|
||||||
|
}
|
||||||
|
return { state, formDom, handleAdd, handleDel, handleEditCancel, handleEditSubmit, handleAddOption, handleDelOption }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.snatchs-items-wrap {
|
||||||
|
.head {
|
||||||
|
width: 100%;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prevs-wrap {
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog class="options" title="互动抢答模板" destroy-on-close v-model="state.show" center :close-on-click-modal="false" align-center width="94%">
|
||||||
|
<el-tabs type="border-card">
|
||||||
|
<el-tab-pane label="模板分组">
|
||||||
|
<Groups></Groups>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="模板列表">
|
||||||
|
<Items></Items>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="handleCancel">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { reactive } from '@vue/reactivity';
|
||||||
|
import { watch } from '@vue/runtime-core';
|
||||||
|
import Groups from './Groups.vue'
|
||||||
|
import Items from './Items.vue'
|
||||||
|
export default {
|
||||||
|
props: ['modelValue'],
|
||||||
|
emits: ['update:modelValue'],
|
||||||
|
components: { Groups, Items },
|
||||||
|
setup(props, { emit }) {
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
show: props.modelValue,
|
||||||
|
loading: false,
|
||||||
|
});
|
||||||
|
watch(() => state.show, (val) => {
|
||||||
|
if (!val) {
|
||||||
|
setTimeout(() => {
|
||||||
|
emit('update:modelValue', val);
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const handleCancel = () => {
|
||||||
|
state.show = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
state, handleCancel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="stylus" scoped></style>
|
||||||
232
cmonitor.web/src/views/device/plugins/share/snatch/use/Info.vue
Normal file
232
cmonitor.web/src/views/device/plugins/share/snatch/use/Info.vue
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
<template>
|
||||||
|
<div class="snatchs-items-wrap flex flex-nowrap flex-column">
|
||||||
|
<div class="flex-1">
|
||||||
|
<div class="prevs-wrap">
|
||||||
|
<el-form ref="formDom" :rules="state.rules" :model="state.currentItem" label-width="0">
|
||||||
|
<el-form-item>
|
||||||
|
<el-row class="w-100">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item>
|
||||||
|
<el-select v-model="state.group" placeholder="选择一个分组" style="width:13rem">
|
||||||
|
<el-option v-for="item in state.groups" :key="item.ID" :label="item.Name" :value="item.ID" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item>
|
||||||
|
<el-select @change="handleItemChange" v-model="state.item" placeholder="选择一个模板" style="width:13rem">
|
||||||
|
<el-option v-for="item in state.list" :key="item.ID" :label="item.Name" :value="item.ID" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="Name">
|
||||||
|
<el-input v-model="state.currentItem.Name" placeholder="名称" maxlength="30" show-word-limit />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="Question">
|
||||||
|
<el-input type="textarea" resize="none" rows="4" v-model="state.currentItem.Question" placeholder="题目内容" maxlength="250" show-word-limit />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-row class="w-100">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item prop="Type">
|
||||||
|
<el-select style="width:90%;" v-model="state.currentItem.Type" placeholder="类别">
|
||||||
|
<el-option v-for="item in state.types" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label-width="0" prop="Repeat">
|
||||||
|
<el-checkbox v-model="state.currentItem.Repeat" label="重复答题" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="上限" label-width="4rem" prop="Max">
|
||||||
|
<el-input v-model="state.currentItem.Max" placeholder="最多答题多少次" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
</el-row>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="state.currentItem.Type == 1">
|
||||||
|
<ul class="w-100">
|
||||||
|
<template v-for="(item,index) in state.currentItem.Options" :key="index">
|
||||||
|
<li class="flex" style="margin-bottom:.6rem">
|
||||||
|
<span>{{String.fromCharCode(index+65)}}、</span>
|
||||||
|
<el-input style="width:11rem;" v-model="item.Text" placeholder="" />
|
||||||
|
<span class="flex-1"></span>
|
||||||
|
<div>
|
||||||
|
<el-checkbox size="small" v-model="item.Value" label="答案" style="margin-right:.6rem" />
|
||||||
|
<el-button size="small" @click="handleAddOption(index)">添加</el-button>
|
||||||
|
<el-button size="small" @click="handleDelOption(index)">删除</el-button>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
</ul>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="state.currentItem.Type == 2">
|
||||||
|
<el-input v-model="state.currentItem.Correct" placeholder="简答题答案" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<div class="t-c w-100">
|
||||||
|
<el-button type="success" :loading="state.loading" @click="handleEditSubmit">确定开始</el-button>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { reactive, ref } from '@vue/reactivity';
|
||||||
|
import { computed, onMounted } from '@vue/runtime-core';
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
import { update } from '@/apis/snatch'
|
||||||
|
import { injectGlobalData } from '@/views/provide';
|
||||||
|
import { injectPluginState } from '@/views/device/provide';
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
const globalData = injectGlobalData();
|
||||||
|
const pluginState = injectPluginState();
|
||||||
|
const state = reactive({
|
||||||
|
loading: false,
|
||||||
|
group: 0,
|
||||||
|
item: 0,
|
||||||
|
currentItem: { ID: 0, Name: '', Type: 1, Question: '', Options: [{ Text: '', Value: false }], Correct: '', Max: 65535, Repeat: true },
|
||||||
|
rules: {
|
||||||
|
Name: [
|
||||||
|
{ required: true, message: '名称必填', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
Question: [
|
||||||
|
{ required: true, message: '内容必填', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
},
|
||||||
|
types: [
|
||||||
|
{ label: '选择题', value: 1 },
|
||||||
|
{ label: '简答题', value: 2 },
|
||||||
|
],
|
||||||
|
groups: computed(() => {
|
||||||
|
let user = globalData.value.usernames[globalData.value.username];
|
||||||
|
if (user && user.Snatchs) {
|
||||||
|
if (state.group == 0 && user.Snatchs.length > 0) {
|
||||||
|
state.group = user.Snatchs[0].ID;
|
||||||
|
}
|
||||||
|
return user.Snatchs;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}),
|
||||||
|
list: computed(() => {
|
||||||
|
let group = state.groups.filter(c => c.ID == state.group)[0];
|
||||||
|
if (group) {
|
||||||
|
if (state.item == 0 && group.List.length > 0) {
|
||||||
|
state.item = group.List[0].ID;
|
||||||
|
}
|
||||||
|
return group.List;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleItemChange = () => {
|
||||||
|
const item = state.list.filter(c => c.ID == state.item)[0] || { ID: 0, Name: '', Type: 1, Question: '', Options: [{ Text: '', Value: false }], Correct: '', Max: 65535, Repeat: true };
|
||||||
|
state.currentItem.Type = item.Type;
|
||||||
|
state.currentItem.ID = item.ID;
|
||||||
|
state.currentItem.Name = item.Name;
|
||||||
|
state.currentItem.Question = item.Question;
|
||||||
|
state.currentItem.Options = item.Options;
|
||||||
|
state.currentItem.Correct = item.Correct;
|
||||||
|
state.currentItem.Max = item.Max;
|
||||||
|
state.currentItem.Repeat = item.Repeat;
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
handleItemChange();
|
||||||
|
});
|
||||||
|
|
||||||
|
const formDom = ref(null);
|
||||||
|
const handleEditSubmit = () => {
|
||||||
|
formDom.value.validate((valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const names = pluginState.value.command.devices.map(c => c.MachineName);
|
||||||
|
if (names.length == 0) {
|
||||||
|
ElMessage.error('请至少选择一个设备');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const json = JSON.parse(JSON.stringify(state.currentItem));
|
||||||
|
json.Max = +json.Max;
|
||||||
|
json.Type = +json.Type;
|
||||||
|
json.Name = json.Name.replace(/^\s|\s$/g, '');
|
||||||
|
json.Correct = json.Correct.replace(/^\s|\s$/g, '');
|
||||||
|
const corrects = json.Options.reduce((arr, value, index) => {
|
||||||
|
if (value.Value) arr.push(String.fromCharCode(index + 65));
|
||||||
|
return arr;
|
||||||
|
}, []).join('');
|
||||||
|
|
||||||
|
if (json.Type == 1 && corrects.length <= 0) {
|
||||||
|
ElMessage.error('至少有一个正确答案');
|
||||||
|
return;
|
||||||
|
} else if (json.Type == 2 && !json.Correct) {
|
||||||
|
ElMessage.error('请输入正确答案');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const question = {
|
||||||
|
Type: json.Type,
|
||||||
|
Question: json.Question,
|
||||||
|
Correct: json.Type == 1 ? corrects : json.Correct,
|
||||||
|
Option: json.Options.length,
|
||||||
|
Max: json.Max,
|
||||||
|
End: false,
|
||||||
|
Repeat: json.Repeat,
|
||||||
|
Join: names.length,
|
||||||
|
Right: 0,
|
||||||
|
Wrong: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
state.loading = true;
|
||||||
|
update(names, question).then((res) => {
|
||||||
|
state.loading = false;
|
||||||
|
if (res) {
|
||||||
|
ElMessage.success('操作成功!');
|
||||||
|
} else {
|
||||||
|
ElMessage.error('操作失败!');
|
||||||
|
}
|
||||||
|
}).catch((e) => {
|
||||||
|
state.loading = false;
|
||||||
|
ElMessage.error('操作失败!');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAddOption = (index) => {
|
||||||
|
if (state.currentItem.Options.length >= 6) return;
|
||||||
|
state.currentItem.Options.splice(index + 1, 0, { Text: '', Value: false });
|
||||||
|
}
|
||||||
|
const handleDelOption = (index) => {
|
||||||
|
if (state.currentItem.Options.length <= 1) return;
|
||||||
|
state.currentItem.Options.splice(index, 1);
|
||||||
|
}
|
||||||
|
return { state, formDom, handleEditSubmit, handleItemChange, handleAddOption, handleDelOption }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.snatchs-items-wrap {
|
||||||
|
.head {
|
||||||
|
width: 100%;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prevs-wrap {
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
232
cmonitor.web/src/views/device/plugins/share/snatch/use/Item.vue
Normal file
232
cmonitor.web/src/views/device/plugins/share/snatch/use/Item.vue
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
<template>
|
||||||
|
<div class="snatchs-items-wrap flex flex-nowrap flex-column">
|
||||||
|
<div class="flex-1">
|
||||||
|
<div class="prevs-wrap">
|
||||||
|
<el-form ref="formDom" :rules="state.rules" :model="state.currentItem" label-width="0">
|
||||||
|
<el-form-item>
|
||||||
|
<el-row class="w-100">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item>
|
||||||
|
<el-select v-model="state.group" placeholder="选择一个分组" style="width:13rem">
|
||||||
|
<el-option v-for="item in state.groups" :key="item.ID" :label="item.Name" :value="item.ID" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item>
|
||||||
|
<el-select @change="handleItemChange" v-model="state.item" placeholder="选择一个模板" style="width:13rem">
|
||||||
|
<el-option v-for="item in state.list" :key="item.ID" :label="item.Name" :value="item.ID" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="Name">
|
||||||
|
<el-input v-model="state.currentItem.Name" placeholder="名称" maxlength="30" show-word-limit />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="Question">
|
||||||
|
<el-input type="textarea" resize="none" rows="4" v-model="state.currentItem.Question" placeholder="题目内容" maxlength="250" show-word-limit />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-row class="w-100">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item prop="Type">
|
||||||
|
<el-select style="width:90%;" v-model="state.currentItem.Type" placeholder="类别">
|
||||||
|
<el-option v-for="item in state.types" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label-width="0" prop="Repeat">
|
||||||
|
<el-checkbox v-model="state.currentItem.Repeat" label="重复答题" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="上限" label-width="4rem" prop="Max">
|
||||||
|
<el-input v-model="state.currentItem.Max" placeholder="最多答题多少次" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
</el-row>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="state.currentItem.Type == 1">
|
||||||
|
<ul class="w-100">
|
||||||
|
<template v-for="(item,index) in state.currentItem.Options" :key="index">
|
||||||
|
<li class="flex" style="margin-bottom:.6rem">
|
||||||
|
<span>{{String.fromCharCode(index+65)}}、</span>
|
||||||
|
<el-input style="width:11rem;" v-model="item.Text" placeholder="" />
|
||||||
|
<span class="flex-1"></span>
|
||||||
|
<div>
|
||||||
|
<el-checkbox size="small" v-model="item.Value" label="答案" style="margin-right:.6rem" />
|
||||||
|
<el-button size="small" @click="handleAddOption(index)">添加</el-button>
|
||||||
|
<el-button size="small" @click="handleDelOption(index)">删除</el-button>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
</ul>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="state.currentItem.Type == 2">
|
||||||
|
<el-input v-model="state.currentItem.Correct" placeholder="简答题答案" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<div class="t-c w-100">
|
||||||
|
<el-button type="success" :loading="state.loading" @click="handleEditSubmit">确定开始</el-button>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { reactive, ref } from '@vue/reactivity';
|
||||||
|
import { computed, onMounted } from '@vue/runtime-core';
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
import { update } from '@/apis/snatch'
|
||||||
|
import { injectGlobalData } from '@/views/provide';
|
||||||
|
import { injectPluginState } from '@/views/device/provide';
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
const globalData = injectGlobalData();
|
||||||
|
const pluginState = injectPluginState();
|
||||||
|
const state = reactive({
|
||||||
|
loading: false,
|
||||||
|
group: 0,
|
||||||
|
item: 0,
|
||||||
|
currentItem: { ID: 0, Name: '', Type: 1, Question: '', Options: [{ Text: '', Value: false }], Correct: '', Max: 65535, Repeat: true },
|
||||||
|
rules: {
|
||||||
|
Name: [
|
||||||
|
{ required: true, message: '名称必填', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
Question: [
|
||||||
|
{ required: true, message: '内容必填', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
},
|
||||||
|
types: [
|
||||||
|
{ label: '选择题', value: 1 },
|
||||||
|
{ label: '简答题', value: 2 },
|
||||||
|
],
|
||||||
|
groups: computed(() => {
|
||||||
|
let user = globalData.value.usernames[globalData.value.username];
|
||||||
|
if (user && user.Snatchs) {
|
||||||
|
if (state.group == 0 && user.Snatchs.length > 0) {
|
||||||
|
state.group = user.Snatchs[0].ID;
|
||||||
|
}
|
||||||
|
return user.Snatchs;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}),
|
||||||
|
list: computed(() => {
|
||||||
|
let group = state.groups.filter(c => c.ID == state.group)[0];
|
||||||
|
if (group) {
|
||||||
|
if (state.item == 0 && group.List.length > 0) {
|
||||||
|
state.item = group.List[0].ID;
|
||||||
|
}
|
||||||
|
return group.List;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleItemChange = () => {
|
||||||
|
const item = state.list.filter(c => c.ID == state.item)[0] || { ID: 0, Name: '', Type: 1, Question: '', Options: [{ Text: '', Value: false }], Correct: '', Max: 65535, Repeat: true };
|
||||||
|
state.currentItem.Type = item.Type;
|
||||||
|
state.currentItem.ID = item.ID;
|
||||||
|
state.currentItem.Name = item.Name;
|
||||||
|
state.currentItem.Question = item.Question;
|
||||||
|
state.currentItem.Options = item.Options;
|
||||||
|
state.currentItem.Correct = item.Correct;
|
||||||
|
state.currentItem.Max = item.Max;
|
||||||
|
state.currentItem.Repeat = item.Repeat;
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
handleItemChange();
|
||||||
|
});
|
||||||
|
|
||||||
|
const formDom = ref(null);
|
||||||
|
const handleEditSubmit = () => {
|
||||||
|
formDom.value.validate((valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const names = pluginState.value.command.devices.map(c => c.MachineName);
|
||||||
|
if (names.length == 0) {
|
||||||
|
ElMessage.error('请至少选择一个设备');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const json = JSON.parse(JSON.stringify(state.currentItem));
|
||||||
|
json.Max = +json.Max;
|
||||||
|
json.Type = +json.Type;
|
||||||
|
json.Name = json.Name.replace(/^\s|\s$/g, '');
|
||||||
|
json.Correct = json.Correct.replace(/^\s|\s$/g, '');
|
||||||
|
const corrects = json.Options.reduce((arr, value, index) => {
|
||||||
|
if (value.Value) arr.push(String.fromCharCode(index + 65));
|
||||||
|
return arr;
|
||||||
|
}, []).join('');
|
||||||
|
|
||||||
|
if (json.Type == 1 && corrects.length <= 0) {
|
||||||
|
ElMessage.error('至少有一个正确答案');
|
||||||
|
return;
|
||||||
|
} else if (json.Type == 2 && !json.Correct) {
|
||||||
|
ElMessage.error('请输入正确答案');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const question = {
|
||||||
|
Type: json.Type,
|
||||||
|
Question: json.Question,
|
||||||
|
Correct: json.Type == 1 ? corrects : json.Correct,
|
||||||
|
Option: json.Options.length,
|
||||||
|
Max: json.Max,
|
||||||
|
End: false,
|
||||||
|
Repeat: json.Repeat,
|
||||||
|
Join: names.length,
|
||||||
|
Right: 0,
|
||||||
|
Wrong: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
state.loading = true;
|
||||||
|
update(names, question).then((res) => {
|
||||||
|
state.loading = false;
|
||||||
|
if (res) {
|
||||||
|
ElMessage.success('操作成功!');
|
||||||
|
} else {
|
||||||
|
ElMessage.error('操作失败!');
|
||||||
|
}
|
||||||
|
}).catch((e) => {
|
||||||
|
state.loading = false;
|
||||||
|
ElMessage.error('操作失败!');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAddOption = (index) => {
|
||||||
|
if (state.currentItem.Options.length >= 6) return;
|
||||||
|
state.currentItem.Options.splice(index + 1, 0, { Text: '', Value: false });
|
||||||
|
}
|
||||||
|
const handleDelOption = (index) => {
|
||||||
|
if (state.currentItem.Options.length <= 1) return;
|
||||||
|
state.currentItem.Options.splice(index, 1);
|
||||||
|
}
|
||||||
|
return { state, formDom, handleEditSubmit, handleItemChange, handleAddOption, handleDelOption }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.snatchs-items-wrap {
|
||||||
|
.head {
|
||||||
|
width: 100%;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prevs-wrap {
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog class="options" title="使用互动答题" destroy-on-close v-model="state.show" center :close-on-click-modal="false" align-center width="94%">
|
||||||
|
<div style="border:1px solid #ddd;padding:.6rem">
|
||||||
|
<Info v-if="running"></Info>
|
||||||
|
<Item v-else></Item>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="handleCancel">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { reactive } from '@vue/reactivity';
|
||||||
|
import { computed, watch } from '@vue/runtime-core';
|
||||||
|
import Item from './Item.vue'
|
||||||
|
import Info from './Info.vue'
|
||||||
|
import { injectPluginState } from '@/views/device/provide';
|
||||||
|
export default {
|
||||||
|
props: ['modelValue'],
|
||||||
|
emits: ['update:modelValue'],
|
||||||
|
components: { Item, Info },
|
||||||
|
setup(props, { emit }) {
|
||||||
|
|
||||||
|
const pluginState = injectPluginState();
|
||||||
|
console.log(pluginState.value);
|
||||||
|
const running = computed(() => pluginState.value.ShareSnatch.Question.End == false);
|
||||||
|
const state = reactive({
|
||||||
|
show: props.modelValue,
|
||||||
|
loading: false,
|
||||||
|
});
|
||||||
|
watch(() => state.show, (val) => {
|
||||||
|
if (!val) {
|
||||||
|
setTimeout(() => {
|
||||||
|
emit('update:modelValue', val);
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const handleCancel = () => {
|
||||||
|
state.show = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
running, state, handleCancel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="stylus" scoped></style>
|
||||||
@@ -115,13 +115,13 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
@media (min-width: 768px) {
|
// @media (min-width: 768px) {
|
||||||
.device-item {
|
// .device-item {
|
||||||
width: 39rem !important;
|
// width: 39rem !important;
|
||||||
background-color: rgba(255, 255, 255, 1) !important;
|
// background-color: rgba(255, 255, 255, 1) !important;
|
||||||
}
|
// margin: 0 0 0.6rem 0 !important;
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
.device-item {
|
.device-item {
|
||||||
// border: 1px solid #ddd;
|
// border: 1px solid #ddd;
|
||||||
font-size: 1.6rem;
|
font-size: 1.6rem;
|
||||||
|
|||||||
@@ -112,6 +112,9 @@ export default {
|
|||||||
globalData.value.currentDevice = globalData.value.devices[middleItem.index];
|
globalData.value.currentDevice = globalData.value.devices[middleItem.index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (globalData.value.pc) {
|
||||||
|
|
||||||
|
} else {
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
let style = 'z-index:9;background-color:rgba(255,255,255,1);';
|
let style = 'z-index:9;background-color:rgba(255,255,255,1);';
|
||||||
const dist = Math.abs((middleItem.index - i));
|
const dist = Math.abs((middleItem.index - i));
|
||||||
@@ -126,6 +129,8 @@ export default {
|
|||||||
}
|
}
|
||||||
items[i].style = style;
|
items[i].style = style;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//有哪些需要报告
|
//有哪些需要报告
|
||||||
const reportDoms = doms.filter(item => item.index >= middleItem.index - 2 && item.index <= middleItem.index + 2).map(c => c.index);
|
const reportDoms = doms.filter(item => item.index >= middleItem.index - 2 && item.index <= middleItem.index + 2).map(c => c.index);
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ export const provideGlobalData = () => {
|
|||||||
}),
|
}),
|
||||||
currentDevice: { MachineName: '' },
|
currentDevice: { MachineName: '' },
|
||||||
reportNames: [],
|
reportNames: [],
|
||||||
pc: window.innerWidth > 768
|
pc: false,//window.innerWidth > 768
|
||||||
});
|
});
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
globalData.value.pc = window.innerWidth > 768;
|
globalData.value.pc = false;// window.innerWidth > 768;
|
||||||
});
|
});
|
||||||
|
|
||||||
provide(globalDataSymbol, globalData);
|
provide(globalDataSymbol, globalData);
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ using System.Text.Json.Serialization;
|
|||||||
using cmonitor.server.client.reports.keyboard;
|
using cmonitor.server.client.reports.keyboard;
|
||||||
using cmonitor.server.client.reports.wallpaper;
|
using cmonitor.server.client.reports.wallpaper;
|
||||||
using common.libs.winapis;
|
using common.libs.winapis;
|
||||||
|
using cmonitor.server.client.reports.snatch;
|
||||||
|
using cmonitor.server.service.messengers.snatch;
|
||||||
|
|
||||||
|
|
||||||
namespace cmonitor
|
namespace cmonitor
|
||||||
@@ -198,6 +200,11 @@ namespace cmonitor
|
|||||||
else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton<ISystem, SystemLinux>();
|
else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton<ISystem, SystemLinux>();
|
||||||
else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton<ISystem, SystemMacOS>();
|
else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton<ISystem, SystemMacOS>();
|
||||||
|
|
||||||
|
serviceCollection.AddSingleton<SnatchReport>();
|
||||||
|
if (OperatingSystem.IsWindows()) serviceCollection.AddSingleton<ISnatch, SnatchWindows>();
|
||||||
|
else if (OperatingSystem.IsLinux()) serviceCollection.AddSingleton<ISnatch, SnatchLinux>();
|
||||||
|
else if (OperatingSystem.IsMacOS()) serviceCollection.AddSingleton<ISnatch, SnatchMacOS>();
|
||||||
|
|
||||||
serviceCollection.AddSingleton<ShareReport>();
|
serviceCollection.AddSingleton<ShareReport>();
|
||||||
serviceCollection.AddSingleton<CommandReport>();
|
serviceCollection.AddSingleton<CommandReport>();
|
||||||
|
|
||||||
@@ -223,6 +230,7 @@ namespace cmonitor
|
|||||||
serviceCollection.AddSingleton<SettingMessenger>();
|
serviceCollection.AddSingleton<SettingMessenger>();
|
||||||
serviceCollection.AddSingleton<KeyboardMessenger>();
|
serviceCollection.AddSingleton<KeyboardMessenger>();
|
||||||
serviceCollection.AddSingleton<SystemMessenger>();
|
serviceCollection.AddSingleton<SystemMessenger>();
|
||||||
|
serviceCollection.AddSingleton<SnatchMessenger>();
|
||||||
|
|
||||||
//api
|
//api
|
||||||
serviceCollection.AddSingleton<RuleConfig>();
|
serviceCollection.AddSingleton<RuleConfig>();
|
||||||
@@ -242,6 +250,7 @@ namespace cmonitor
|
|||||||
serviceCollection.AddSingleton<SettingClientService>();
|
serviceCollection.AddSingleton<SettingClientService>();
|
||||||
serviceCollection.AddSingleton<SystemClientService>();
|
serviceCollection.AddSingleton<SystemClientService>();
|
||||||
serviceCollection.AddSingleton<KeyboardClientService>();
|
serviceCollection.AddSingleton<KeyboardClientService>();
|
||||||
|
serviceCollection.AddSingleton<SnatchClientService>();
|
||||||
|
|
||||||
|
|
||||||
//web
|
//web
|
||||||
@@ -265,7 +274,7 @@ namespace cmonitor
|
|||||||
config.ScreenDelay = int.Parse(dic["screen-delay"]);
|
config.ScreenDelay = int.Parse(dic["screen-delay"]);
|
||||||
config.Elevated = dic.ContainsKey("elevated");
|
config.Elevated = dic.ContainsKey("elevated");
|
||||||
|
|
||||||
Logger.Instance.Debug($"config:{config.ToJson()}");
|
Logger.Instance.Debug($"config:{config.ToJsonFormat()}");
|
||||||
//Logger.Instance.Debug($"args:{string.Join(" ", args)}");
|
//Logger.Instance.Debug($"args:{string.Join(" ", args)}");
|
||||||
|
|
||||||
config.IsCLient = dic.ContainsKey("mode") && dic["mode"].Contains("client");
|
config.IsCLient = dic.ContainsKey("mode") && dic["mode"].Contains("client");
|
||||||
@@ -371,6 +380,9 @@ namespace cmonitor
|
|||||||
public const int ShareMemoryLLockIndex = 3;
|
public const int ShareMemoryLLockIndex = 3;
|
||||||
//SAS
|
//SAS
|
||||||
public const int ShareMemorySASIndex = 4;
|
public const int ShareMemorySASIndex = 4;
|
||||||
|
//抢答,问题,和回答分开存,为了保证数据安全性
|
||||||
|
public const int ShareSnatchQuestionIndex = 5;
|
||||||
|
public const int ShareSnatchAnswerIndex = 6;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using common.libs.database;
|
using cmonitor.server.client.reports.snatch;
|
||||||
|
using common.libs.database;
|
||||||
|
using MemoryPack;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace cmonitor.server.api
|
namespace cmonitor.server.api
|
||||||
@@ -16,8 +18,9 @@ namespace cmonitor.server.api
|
|||||||
{
|
{
|
||||||
UserNames = new Dictionary<string, UserNameInfo> { { "snltty", new UserNameInfo {
|
UserNames = new Dictionary<string, UserNameInfo> { { "snltty", new UserNameInfo {
|
||||||
Rules = new List<RulesInfo>{ new RulesInfo { ID = 1, Name = "默认" } },
|
Rules = new List<RulesInfo>{ new RulesInfo { ID = 1, Name = "默认" } },
|
||||||
Processs = new List<GroupInfo>{ new GroupInfo { ID = 1, Name = "默认" } },
|
Processs = new List<GroupInfo>{ new GroupInfo { ID = 2, Name = "默认" } },
|
||||||
Windows = new List<WindowGroupInfo> { new WindowGroupInfo { ID = 1, Name = "默认" } },
|
Windows = new List<WindowGroupInfo> { new WindowGroupInfo { ID = 3, Name = "默认" } },
|
||||||
|
Snatchs = new List<SnatchGroupInfo>{ new SnatchGroupInfo { ID=4, Name="默认" } }
|
||||||
} } }
|
} } }
|
||||||
};
|
};
|
||||||
UserNames = config.UserNames;
|
UserNames = config.UserNames;
|
||||||
@@ -26,7 +29,7 @@ namespace cmonitor.server.api
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Dictionary<string, UserNameInfo> UserNames { get; set; } = new Dictionary<string, UserNameInfo>();
|
public Dictionary<string, UserNameInfo> UserNames { get; set; } = new Dictionary<string, UserNameInfo>();
|
||||||
private uint maxid = 0;
|
private uint maxid = 100;
|
||||||
public uint MaxID
|
public uint MaxID
|
||||||
{
|
{
|
||||||
get => maxid; set
|
get => maxid; set
|
||||||
@@ -341,6 +344,122 @@ namespace cmonitor.server.api
|
|||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public string AddSnatchGroup(UpdateSnatchGroupInfo updateGroupInfo)
|
||||||
|
{
|
||||||
|
lock (lockObj)
|
||||||
|
{
|
||||||
|
if (UserNames.TryGetValue(updateGroupInfo.UserName, out UserNameInfo userNameInfo) == false)
|
||||||
|
{
|
||||||
|
return "不存在此管理用户";
|
||||||
|
}
|
||||||
|
if (userNameInfo.Windows.FirstOrDefault(c => c.Name == updateGroupInfo.Group.Name && c.ID != updateGroupInfo.Group.ID) != null)
|
||||||
|
{
|
||||||
|
return "已存在同名记录";
|
||||||
|
}
|
||||||
|
|
||||||
|
//添加
|
||||||
|
if (updateGroupInfo.Group.ID == 0)
|
||||||
|
{
|
||||||
|
updateGroupInfo.Group.ID = Interlocked.Increment(ref maxid);
|
||||||
|
userNameInfo.Snatchs.Add(updateGroupInfo.Group);
|
||||||
|
Save();
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
//修改
|
||||||
|
SnatchGroupInfo old = userNameInfo.Snatchs.FirstOrDefault(c => c.ID == updateGroupInfo.Group.ID);
|
||||||
|
if (old == null)
|
||||||
|
{
|
||||||
|
return "不存在记录,无法修改";
|
||||||
|
}
|
||||||
|
old.Name = updateGroupInfo.Group.Name;
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
public string DeleteSnatchGroup(DeleteSnatchGroupInfo deleteGroupInfo)
|
||||||
|
{
|
||||||
|
lock (lockObj)
|
||||||
|
{
|
||||||
|
if (UserNames.TryGetValue(deleteGroupInfo.UserName, out UserNameInfo userNameInfo) == false)
|
||||||
|
{
|
||||||
|
return "不存在此管理用户";
|
||||||
|
}
|
||||||
|
|
||||||
|
userNameInfo.Snatchs.Remove(userNameInfo.Snatchs.FirstOrDefault(c => c.ID == deleteGroupInfo.ID));
|
||||||
|
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
public string AddSnatch(AddSnatchItemInfo updateItem)
|
||||||
|
{
|
||||||
|
lock (lockObj)
|
||||||
|
{
|
||||||
|
if (UserNames.TryGetValue(updateItem.UserName, out UserNameInfo userNameInfo) == false)
|
||||||
|
{
|
||||||
|
return "不存在此管理用户";
|
||||||
|
}
|
||||||
|
SnatchGroupInfo group = userNameInfo.Snatchs.FirstOrDefault(c => c.ID == updateItem.GroupID);
|
||||||
|
if (group == null)
|
||||||
|
{
|
||||||
|
return "不存在此分组";
|
||||||
|
}
|
||||||
|
if (group.List.FirstOrDefault(c => c.Name == updateItem.Item.Name && c.ID != updateItem.Item.ID) != null)
|
||||||
|
{
|
||||||
|
return "已存在同名记录";
|
||||||
|
}
|
||||||
|
|
||||||
|
//添加
|
||||||
|
if (updateItem.Item.ID == 0)
|
||||||
|
{
|
||||||
|
updateItem.Item.ID = Interlocked.Increment(ref maxid);
|
||||||
|
group.List.Add(updateItem.Item);
|
||||||
|
Save();
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
//修改
|
||||||
|
SnatchItemInfo old = group.List.FirstOrDefault(c => c.ID == updateItem.Item.ID);
|
||||||
|
if (old == null)
|
||||||
|
{
|
||||||
|
return "不存在记录,无法修改";
|
||||||
|
}
|
||||||
|
old.Type = updateItem.Item.Type;
|
||||||
|
old.Name = updateItem.Item.Name;
|
||||||
|
old.Question = updateItem.Item.Question;
|
||||||
|
old.Options = updateItem.Item.Options;
|
||||||
|
old.Correct = updateItem.Item.Correct;
|
||||||
|
old.Max = updateItem.Item.Max;
|
||||||
|
old.Repeat = updateItem.Item.Repeat;
|
||||||
|
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
public string DelSnatch(DeletedSnatchItemInfo deletedFileNameInfo)
|
||||||
|
{
|
||||||
|
lock (lockObj)
|
||||||
|
{
|
||||||
|
if (UserNames.TryGetValue(deletedFileNameInfo.UserName, out UserNameInfo userNameInfo) == false)
|
||||||
|
{
|
||||||
|
return "不存在此管理用户";
|
||||||
|
}
|
||||||
|
SnatchGroupInfo group = userNameInfo.Snatchs.FirstOrDefault(c => c.ID == deletedFileNameInfo.GroupID);
|
||||||
|
if (group == null)
|
||||||
|
{
|
||||||
|
return "不存在此分组";
|
||||||
|
}
|
||||||
|
|
||||||
|
group.List.Remove(group.List.FirstOrDefault(c => c.ID == deletedFileNameInfo.ID));
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
public void Save()
|
public void Save()
|
||||||
{
|
{
|
||||||
configDataProvider.Save(this).Wait();
|
configDataProvider.Save(this).Wait();
|
||||||
@@ -353,6 +472,7 @@ namespace cmonitor.server.api
|
|||||||
public List<GroupInfo> Processs { get; set; } = new List<GroupInfo>();
|
public List<GroupInfo> Processs { get; set; } = new List<GroupInfo>();
|
||||||
public List<string> Devices { get; set; } = new List<string>();
|
public List<string> Devices { get; set; } = new List<string>();
|
||||||
public List<WindowGroupInfo> Windows { get; set; } = new List<WindowGroupInfo>();
|
public List<WindowGroupInfo> Windows { get; set; } = new List<WindowGroupInfo>();
|
||||||
|
public List<SnatchGroupInfo> Snatchs { get; set; } = new List<SnatchGroupInfo>();
|
||||||
}
|
}
|
||||||
public sealed class UpdateDevicesInfo
|
public sealed class UpdateDevicesInfo
|
||||||
{
|
{
|
||||||
@@ -464,4 +584,69 @@ namespace cmonitor.server.api
|
|||||||
public uint GroupID { get; set; }
|
public uint GroupID { get; set; }
|
||||||
public uint ID { get; set; }
|
public uint ID { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public sealed class SnatchGroupInfo
|
||||||
|
{
|
||||||
|
public uint ID { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public List<SnatchItemInfo> List { get; set; } = new List<SnatchItemInfo>();
|
||||||
|
}
|
||||||
|
public sealed class UpdateSnatchGroupInfo
|
||||||
|
{
|
||||||
|
public string UserName { get; set; }
|
||||||
|
public SnatchGroupInfo Group { get; set; }
|
||||||
|
}
|
||||||
|
public sealed class DeleteSnatchGroupInfo
|
||||||
|
{
|
||||||
|
public string UserName { get; set; }
|
||||||
|
public uint ID { get; set; }
|
||||||
|
}
|
||||||
|
public sealed class AddSnatchItemInfo
|
||||||
|
{
|
||||||
|
public string UserName { get; set; }
|
||||||
|
public uint GroupID { get; set; }
|
||||||
|
public SnatchItemInfo Item { get; set; }
|
||||||
|
}
|
||||||
|
public sealed class DeletedSnatchItemInfo
|
||||||
|
{
|
||||||
|
public string UserName { get; set; }
|
||||||
|
public uint GroupID { get; set; }
|
||||||
|
public uint ID { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public sealed class SnatchItemInfo
|
||||||
|
{
|
||||||
|
public uint ID { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public SnatchType Type { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 问题
|
||||||
|
/// </summary>
|
||||||
|
public string Question { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 选项数
|
||||||
|
/// </summary>
|
||||||
|
public List<SnatchItemOptionInfo> Options { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 答案
|
||||||
|
/// </summary>
|
||||||
|
public string Correct { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 最多答题次数
|
||||||
|
/// </summary>
|
||||||
|
public int Max { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 重复答题
|
||||||
|
/// </summary>
|
||||||
|
public bool Repeat { get; set; }
|
||||||
|
}
|
||||||
|
public sealed class SnatchItemOptionInfo
|
||||||
|
{
|
||||||
|
public string Text { get; set;}
|
||||||
|
public bool Value { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,24 +19,28 @@ namespace cmonitor.server.api.services
|
|||||||
public async Task<bool> Update(ClientServiceParamsInfo param)
|
public async Task<bool> Update(ClientServiceParamsInfo param)
|
||||||
{
|
{
|
||||||
ShareUpdateInfo info = param.Content.DeJson<ShareUpdateInfo>();
|
ShareUpdateInfo info = param.Content.DeJson<ShareUpdateInfo>();
|
||||||
if(signCaching.Get(info.Name,out SignCacheInfo cache))
|
byte[] bytes = MemoryPackSerializer.Serialize(info.Item);
|
||||||
|
for (int i = 0; i < info.Names.Length; i++)
|
||||||
{
|
{
|
||||||
return await messengerSender.SendOnly(new MessageRequestWrap
|
if (signCaching.Get(info.Names[i], out SignCacheInfo cache))
|
||||||
|
{
|
||||||
|
await messengerSender.SendOnly(new MessageRequestWrap
|
||||||
{
|
{
|
||||||
Connection = cache.Connection,
|
Connection = cache.Connection,
|
||||||
MessengerId = (ushort)ShareMessengerIds.Update,
|
MessengerId = (ushort)ShareMessengerIds.Update,
|
||||||
Payload = MemoryPackSerializer.Serialize(info.Item)
|
Payload = bytes
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class ShareUpdateInfo
|
public sealed class ShareUpdateInfo
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string[] Names { get; set; }
|
||||||
public ShareItemInfo Item { get; set; }
|
public ShareItemInfo Item { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
65
cmonitor/server/api/services/SnatchClientService.cs
Normal file
65
cmonitor/server/api/services/SnatchClientService.cs
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
using cmonitor.server.client.reports.snatch;
|
||||||
|
using cmonitor.server.service;
|
||||||
|
using cmonitor.server.service.messengers.sign;
|
||||||
|
using cmonitor.server.service.messengers.snatch;
|
||||||
|
using common.libs.extends;
|
||||||
|
using MemoryPack;
|
||||||
|
|
||||||
|
namespace cmonitor.server.api.services
|
||||||
|
{
|
||||||
|
public sealed class SnatchClientService : IClientService
|
||||||
|
{
|
||||||
|
private readonly MessengerSender messengerSender;
|
||||||
|
private readonly RuleConfig ruleConfig;
|
||||||
|
private readonly SignCaching signCaching;
|
||||||
|
public SnatchClientService(RuleConfig ruleConfig, MessengerSender messengerSender, SignCaching signCaching)
|
||||||
|
{
|
||||||
|
this.ruleConfig = ruleConfig;
|
||||||
|
this.messengerSender = messengerSender;
|
||||||
|
this.signCaching = signCaching;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string AddGroup(ClientServiceParamsInfo param)
|
||||||
|
{
|
||||||
|
return ruleConfig.AddSnatchGroup(param.Content.DeJson<UpdateSnatchGroupInfo>());
|
||||||
|
}
|
||||||
|
public string DeleteGroup(ClientServiceParamsInfo param)
|
||||||
|
{
|
||||||
|
return ruleConfig.DeleteSnatchGroup(param.Content.DeJson<DeleteSnatchGroupInfo>());
|
||||||
|
}
|
||||||
|
public string Add(ClientServiceParamsInfo param)
|
||||||
|
{
|
||||||
|
return ruleConfig.AddSnatch(param.Content.DeJson<AddSnatchItemInfo>());
|
||||||
|
}
|
||||||
|
public string Del(ClientServiceParamsInfo param)
|
||||||
|
{
|
||||||
|
return ruleConfig.DelSnatch(param.Content.DeJson<DeletedSnatchItemInfo>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> Update(ClientServiceParamsInfo param)
|
||||||
|
{
|
||||||
|
SnatchUpdateInfo info = param.Content.DeJson<SnatchUpdateInfo>();
|
||||||
|
byte[] bytes = MemoryPackSerializer.Serialize(info.Item);
|
||||||
|
for (int i = 0; i < info.Names.Length; i++)
|
||||||
|
{
|
||||||
|
if (signCaching.Get(info.Names[i], out SignCacheInfo cache))
|
||||||
|
{
|
||||||
|
await messengerSender.SendOnly(new MessageRequestWrap
|
||||||
|
{
|
||||||
|
Connection = cache.Connection,
|
||||||
|
MessengerId = (ushort)SnatchMessengerIds.Update,
|
||||||
|
Payload = bytes
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class SnatchUpdateInfo
|
||||||
|
{
|
||||||
|
public string[] Names { get; set; }
|
||||||
|
public SnatchQuestionInfo Item { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -55,7 +55,7 @@ namespace cmonitor.server.client
|
|||||||
IPAddress[] ips = new IPAddress[] { config.Server };
|
IPAddress[] ips = new IPAddress[] { config.Server };
|
||||||
|
|
||||||
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||||
Logger.Instance.Info($"get ip:{ips.ToJson()}");
|
Logger.Instance.Info($"get ip:{ips.ToJsonFormat()}");
|
||||||
|
|
||||||
if (ips.Length == 0) return;
|
if (ips.Length == 0) return;
|
||||||
foreach (IPAddress ip in ips)
|
foreach (IPAddress ip in ips)
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ namespace cmonitor.server.client.reports
|
|||||||
if (reportObj.Count > 0)
|
if (reportObj.Count > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
string json = reportObj.ToJsonDefault();
|
string json = reportObj.ToJson();
|
||||||
byte[] res = MemoryPackSerializer.Serialize(json);
|
byte[] res = MemoryPackSerializer.Serialize(json);
|
||||||
await messengerSender.SendOnly(new MessageRequestWrap
|
await messengerSender.SendOnly(new MessageRequestWrap
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ namespace cmonitor.server.client.reports.active
|
|||||||
}
|
}
|
||||||
|
|
||||||
activeWindowInfo.Title = buff.ToString();
|
activeWindowInfo.Title = buff.ToString();
|
||||||
activeWindowInfo.FileName = filename;
|
activeWindowInfo.FileName = Path.GetFileName(filename);
|
||||||
activeWindowInfo.Desc = desc;
|
activeWindowInfo.Desc = desc;
|
||||||
activeWindowInfo.Pid = id;
|
activeWindowInfo.Pid = id;
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ using common.libs.helpers;
|
|||||||
|
|
||||||
namespace cmonitor.server.client.reports.screen
|
namespace cmonitor.server.client.reports.screen
|
||||||
{
|
{
|
||||||
public sealed class ScreenWIndowsDxgi
|
public sealed class ScreenWindowsDxgi
|
||||||
{
|
{
|
||||||
private Adapter1 adapter;
|
private Adapter1 adapter;
|
||||||
private Device mDevice;
|
private Device mDevice;
|
||||||
@@ -37,10 +37,10 @@ namespace cmonitor.server.client.reports.screen
|
|||||||
|
|
||||||
private readonly Config config;
|
private readonly Config config;
|
||||||
|
|
||||||
public ScreenWIndowsDxgi(int whichMonitor, Config config)
|
public ScreenWindowsDxgi(int whichMonitor, Config config)
|
||||||
: this(0, whichMonitor, config) { }
|
: this(0, whichMonitor, config) { }
|
||||||
|
|
||||||
public ScreenWIndowsDxgi(int whichGraphicsCardAdapter, int whichOutputDevice, Config config)
|
public ScreenWindowsDxgi(int whichGraphicsCardAdapter, int whichOutputDevice, Config config)
|
||||||
{
|
{
|
||||||
this.whichGraphicsCardAdapter = whichGraphicsCardAdapter;
|
this.whichGraphicsCardAdapter = whichGraphicsCardAdapter;
|
||||||
this.whichOutputDevice = whichOutputDevice;
|
this.whichOutputDevice = whichOutputDevice;
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ namespace cmonitor.server.client.reports.screen
|
|||||||
{
|
{
|
||||||
public sealed class ScreenWindows : IScreen
|
public sealed class ScreenWindows : IScreen
|
||||||
{
|
{
|
||||||
private readonly ScreenWIndowsDxgi dxgiDesktop;
|
private readonly ScreenWindowsDxgi dxgiDesktop;
|
||||||
private readonly ScreenWindowsGdi gdiDesktop;
|
private readonly ScreenWindowsGdi gdiDesktop;
|
||||||
public ScreenWindows(Config config)
|
public ScreenWindows(Config config)
|
||||||
{
|
{
|
||||||
dxgiDesktop = new ScreenWIndowsDxgi(0, config);
|
dxgiDesktop = new ScreenWindowsDxgi(0, config);
|
||||||
gdiDesktop = new ScreenWindowsGdi(config);
|
gdiDesktop = new ScreenWindowsGdi(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,10 @@ namespace cmonitor.server.client.reports.share
|
|||||||
{
|
{
|
||||||
return dic.TryGetValue(key, out item);
|
return dic.TryGetValue(key, out item);
|
||||||
}
|
}
|
||||||
|
public bool GetShareRunning(int index)
|
||||||
|
{
|
||||||
|
return shareMemory.ReadRunning(index);
|
||||||
|
}
|
||||||
public void UpdateShare(ShareItemInfo shareItemInfo)
|
public void UpdateShare(ShareItemInfo shareItemInfo)
|
||||||
{
|
{
|
||||||
if (shareMemory != null)
|
if (shareMemory != null)
|
||||||
@@ -78,7 +82,7 @@ namespace cmonitor.server.client.reports.share
|
|||||||
|
|
||||||
private void ShareMemoryStateChanged(int index, ShareMemoryState state)
|
private void ShareMemoryStateChanged(int index, ShareMemoryState state)
|
||||||
{
|
{
|
||||||
if (index == 0 && state == ShareMemoryState.Closed)
|
if (index == 0 && (state & ShareMemoryState.Closed) == ShareMemoryState.Closed)
|
||||||
{
|
{
|
||||||
shareMemory.WriteClosed(0, false);
|
shareMemory.WriteClosed(0, false);
|
||||||
shareMemory.WriteRunning(0, false);
|
shareMemory.WriteRunning(0, false);
|
||||||
|
|||||||
62
cmonitor/server/client/reports/snatch/ISnatch.cs
Normal file
62
cmonitor/server/client/reports/snatch/ISnatch.cs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
using MemoryPack;
|
||||||
|
|
||||||
|
namespace cmonitor.server.client.reports.snatch
|
||||||
|
{
|
||||||
|
public interface ISnatch
|
||||||
|
{
|
||||||
|
public void Set(SnatchQuestionInfo snatchQuestionInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MemoryPackable]
|
||||||
|
public sealed partial class SnatchQuestionInfo
|
||||||
|
{
|
||||||
|
public SnatchType Type { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 问题
|
||||||
|
/// </summary>
|
||||||
|
public string Question { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 正确答案
|
||||||
|
/// </summary>
|
||||||
|
public string Correct { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 选项数
|
||||||
|
/// </summary>
|
||||||
|
public int Option { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 最多答题次数
|
||||||
|
/// </summary>
|
||||||
|
public int Max { get; set; } = int.MaxValue;
|
||||||
|
/// <summary>
|
||||||
|
/// 已结束
|
||||||
|
/// </summary>
|
||||||
|
public bool End { get; set; } = false;
|
||||||
|
/// <summary>
|
||||||
|
/// 重复答题
|
||||||
|
/// </summary>
|
||||||
|
public bool Repeat { get; set; } = true;
|
||||||
|
public int Join { get; set; } = 0;
|
||||||
|
public int Right { get; set; } = 0;
|
||||||
|
public int Wrong { get; set; } = 0;
|
||||||
|
}
|
||||||
|
public sealed class SnatchAnswerInfo
|
||||||
|
{
|
||||||
|
public SnatchState State { get; set; }
|
||||||
|
public bool Result { get; set; }
|
||||||
|
public long Time { get; set; }
|
||||||
|
public string ResultStr { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SnatchState : byte
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Ask = 1,
|
||||||
|
Confirm = 2,
|
||||||
|
}
|
||||||
|
public enum SnatchType : byte
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Select = 1,
|
||||||
|
Input = 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
9
cmonitor/server/client/reports/snatch/SnatchLinux.cs
Normal file
9
cmonitor/server/client/reports/snatch/SnatchLinux.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace cmonitor.server.client.reports.snatch
|
||||||
|
{
|
||||||
|
public sealed class SnatchLinux : ISnatch
|
||||||
|
{
|
||||||
|
public void Set(SnatchQuestionInfo snatchQuestionInfo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
cmonitor/server/client/reports/snatch/SnatchMacOS.cs
Normal file
9
cmonitor/server/client/reports/snatch/SnatchMacOS.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace cmonitor.server.client.reports.snatch
|
||||||
|
{
|
||||||
|
public sealed class SnatchMacOS : ISnatch
|
||||||
|
{
|
||||||
|
public void Set(SnatchQuestionInfo snatchQuestionInfo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
cmonitor/server/client/reports/snatch/SnatchReport.cs
Normal file
25
cmonitor/server/client/reports/snatch/SnatchReport.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
namespace cmonitor.server.client.reports.snatch
|
||||||
|
{
|
||||||
|
public sealed class SnatchReport : IReport
|
||||||
|
{
|
||||||
|
public string Name => "Snatch";
|
||||||
|
|
||||||
|
private readonly ISnatch snatch;
|
||||||
|
|
||||||
|
public SnatchReport(ISnatch snatch)
|
||||||
|
{
|
||||||
|
this.snatch = snatch;
|
||||||
|
snatch.Set(new SnatchQuestionInfo { Correct = string.Empty, End = true, Join=0, Max=0, Option=0, Question=string.Empty, Repeat=false, Right=0, Type= SnatchType.Select,Wrong=0});
|
||||||
|
}
|
||||||
|
|
||||||
|
public object GetReports(ReportType reportType)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(SnatchQuestionInfo snatchQuestionInfo)
|
||||||
|
{
|
||||||
|
snatch.Set(snatchQuestionInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
49
cmonitor/server/client/reports/snatch/SnatchWindows.cs
Normal file
49
cmonitor/server/client/reports/snatch/SnatchWindows.cs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
using cmonitor.server.client.reports.share;
|
||||||
|
using common.libs;
|
||||||
|
using common.libs.extends;
|
||||||
|
|
||||||
|
namespace cmonitor.server.client.reports.snatch
|
||||||
|
{
|
||||||
|
public sealed class SnatchWindows : ISnatch
|
||||||
|
{
|
||||||
|
private readonly Config config;
|
||||||
|
private readonly ShareReport shareReport;
|
||||||
|
public SnatchWindows(Config config, ShareReport shareReport)
|
||||||
|
{
|
||||||
|
this.config = config;
|
||||||
|
this.shareReport = shareReport;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Set(SnatchQuestionInfo snatchQuestionInfo)
|
||||||
|
{
|
||||||
|
bool running = shareReport.GetShareRunning(Config.ShareSnatchQuestionIndex);
|
||||||
|
//更新问题
|
||||||
|
shareReport.UpdateShare(new ShareItemInfo
|
||||||
|
{
|
||||||
|
Index = Config.ShareSnatchQuestionIndex,
|
||||||
|
Key = "SnatchQuestion",
|
||||||
|
Value = snatchQuestionInfo.ToJson()
|
||||||
|
});
|
||||||
|
//未启动,并且未结束
|
||||||
|
if (running == false && snatchQuestionInfo.End == false)
|
||||||
|
{
|
||||||
|
//启动
|
||||||
|
shareReport.UpdateShare(new ShareItemInfo
|
||||||
|
{
|
||||||
|
Index = Config.ShareSnatchAnswerIndex,
|
||||||
|
Key = "SnatchAnswer",
|
||||||
|
Value = new SnatchAnswerInfo
|
||||||
|
{
|
||||||
|
Result = false,
|
||||||
|
ResultStr = string.Empty,
|
||||||
|
State = SnatchState.Ask,
|
||||||
|
Time = 0,
|
||||||
|
}.ToJson()
|
||||||
|
});
|
||||||
|
CommandHelper.Windows(string.Empty, new string[] {
|
||||||
|
$"start cmonitor.snatch.win.exe {config.ShareMemoryKey} {config.ShareMemoryLength} {config.ShareMemoryItemSize} {Config.ShareSnatchQuestionIndex} {Config.ShareSnatchAnswerIndex}"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
cmonitor/server/service/messengers/snatch/SnatchMessenger.cs
Normal file
23
cmonitor/server/service/messengers/snatch/SnatchMessenger.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using cmonitor.server.client.reports.snatch;
|
||||||
|
using MemoryPack;
|
||||||
|
|
||||||
|
namespace cmonitor.server.service.messengers.snatch
|
||||||
|
{
|
||||||
|
public sealed class SnatchMessenger : IMessenger
|
||||||
|
{
|
||||||
|
private readonly SnatchReport snatchReport;
|
||||||
|
|
||||||
|
public SnatchMessenger(SnatchReport snatchReport)
|
||||||
|
{
|
||||||
|
this.snatchReport = snatchReport;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MessengerId((ushort)SnatchMessengerIds.Update)]
|
||||||
|
public void Update(IConnection connection)
|
||||||
|
{
|
||||||
|
SnatchQuestionInfo question = MemoryPackSerializer.Deserialize<SnatchQuestionInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||||
|
snatchReport.Update(question);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace cmonitor.server.service.messengers.snatch
|
||||||
|
{
|
||||||
|
public enum SnatchMessengerIds : ushort
|
||||||
|
{
|
||||||
|
Update = 1600,
|
||||||
|
|
||||||
|
None = 1699
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -85,7 +85,7 @@ namespace common.libs.database
|
|||||||
//Logger.Instance.Error($"save:{fileName}");
|
//Logger.Instance.Error($"save:{fileName}");
|
||||||
//Logger.Instance.Error(model.ToJsonIndented());
|
//Logger.Instance.Error(model.ToJsonIndented());
|
||||||
|
|
||||||
await File.WriteAllTextAsync(fileName, model.ToJsonIndented(), Encoding.UTF8).ConfigureAwait(false);
|
await File.WriteAllTextAsync(fileName, model.ToJsonFormat(), Encoding.UTF8).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,18 +24,14 @@ namespace common.libs.extends
|
|||||||
WriteIndented = true,
|
WriteIndented = true,
|
||||||
Converters = { new IPAddressJsonConverter(), new IPEndpointJsonConverter(), new DateTimeConverter() }
|
Converters = { new IPAddressJsonConverter(), new IPEndpointJsonConverter(), new DateTimeConverter() }
|
||||||
};
|
};
|
||||||
public static string ToJsonDefault(this object obj)
|
public static string ToJson(this object obj)
|
||||||
{
|
{
|
||||||
return JsonSerializer.Serialize(obj);
|
return JsonSerializer.Serialize(obj);
|
||||||
}
|
}
|
||||||
public static string ToJson(this object obj)
|
public static string ToJsonFormat(this object obj)
|
||||||
{
|
{
|
||||||
return JsonSerializer.Serialize(obj, jsonSerializerOptions);
|
return JsonSerializer.Serialize(obj, jsonSerializerOptions);
|
||||||
}
|
}
|
||||||
public static string ToJsonIndented(this object obj)
|
|
||||||
{
|
|
||||||
return JsonSerializer.Serialize(obj, jsonSerializerOptionsIndented);
|
|
||||||
}
|
|
||||||
public static T DeJson<T>(this string json)
|
public static T DeJson<T>(this string json)
|
||||||
{
|
{
|
||||||
return JsonSerializer.Deserialize<T>(json, options: jsonSerializerOptions);
|
return JsonSerializer.Deserialize<T>(json, options: jsonSerializerOptions);
|
||||||
|
|||||||
Reference in New Issue
Block a user