diff --git a/CalendarNotepad.sln b/CalendarNotepad.sln
index 758505f..c837b44 100644
--- a/CalendarNotepad.sln
+++ b/CalendarNotepad.sln
@@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.6.33829.357
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalendarNotepad", "CalendarNotepad\CalendarNotepad.csproj", "{875F30C8-8B0B-43B6-A4A4-4ED9870E2021}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CalendarNotepad", "CalendarNotepad\CalendarNotepad.csproj", "{875F30C8-8B0B-43B6-A4A4-4ED9870E2021}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharkingTest", "SharkingTest\SharkingTest.csproj", "{60DC4219-39A6-4B9B-9172-934C3427E859}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -15,6 +17,10 @@ Global
{875F30C8-8B0B-43B6-A4A4-4ED9870E2021}.Debug|Any CPU.Build.0 = Debug|Any CPU
{875F30C8-8B0B-43B6-A4A4-4ED9870E2021}.Release|Any CPU.ActiveCfg = Release|Any CPU
{875F30C8-8B0B-43B6-A4A4-4ED9870E2021}.Release|Any CPU.Build.0 = Release|Any CPU
+ {60DC4219-39A6-4B9B-9172-934C3427E859}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {60DC4219-39A6-4B9B-9172-934C3427E859}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {60DC4219-39A6-4B9B-9172-934C3427E859}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {60DC4219-39A6-4B9B-9172-934C3427E859}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/CalendarNotepad/App.config b/CalendarNotepad/App.config
new file mode 100644
index 0000000..406ac6c
--- /dev/null
+++ b/CalendarNotepad/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CalendarNotepad/Extends/Shaking.cs b/CalendarNotepad/Extends/Shaking.cs
new file mode 100644
index 0000000..f1fbcfc
--- /dev/null
+++ b/CalendarNotepad/Extends/Shaking.cs
@@ -0,0 +1,92 @@
+
+namespace CalendarNotepad.Extends
+{
+ ///
+ /// 防止抖动执行任务
+ ///
+ public class Shaking:IDisposable
+ {
+ ///
+ /// 下一个要执行的任务
+ ///
+ protected Task? Next { get; set; }
+ ///
+ /// 执行计时器
+ ///
+ protected System.Timers.Timer Timer { get; set; }
+ ///
+ /// 等待执行时间
+ ///
+ public int TimespanSeconds { get; set; }
+ ///
+ /// 使用默认方式实例化
+ ///
+ public Shaking() : this(5) { }
+ ///
+ /// 实例化,默认抖动执行间隔5秒
+ ///
+ /// 抖动执行时间间隔。秒
+ public Shaking(int timeSpanSeconds) {
+ this.TimespanSeconds = timeSpanSeconds * 1000;
+ this.Timer = new System.Timers.Timer {
+ Interval = this.TimespanSeconds
+ };
+ this.Timer.Elapsed += Timer_Tick;
+ this.Timer.Stop();
+ }
+
+ protected void Timer_Tick(object? sender,EventArgs e) {
+ this.Timer.Stop();
+ this.Timer.Dispose();
+ if(this.Next == null) {
+ return;
+ }
+ var n = this.Next;
+ this.Next = null;
+ n.Start();
+ }
+ ///
+ /// 防抖执行任务
+ ///
+ /// 要执行的任务
+ public void Run(Task task) {
+ this.Next = task;
+ if(this.Timer != null) {
+ this.Timer.Stop();
+ this.Timer.Dispose();
+ }
+ this.Timer = new System.Timers.Timer {
+ Interval = this.TimespanSeconds,
+ };
+ this.Timer.Elapsed += Timer_Tick;
+ this.Timer.Start();
+ }
+ ///
+ /// 防抖执行委托
+ ///
+ /// 要执行的委托
+ public void Run(Action action) => Run(new Task(action));
+
+ public void Dispose() {
+ if(this.Timer != null) {
+ this.Timer.Stop();
+ this.Timer.Dispose();
+ }
+ this.Next = null;
+ GC.SuppressFinalize(this);
+ }
+
+ public void RunNow() {
+ var n = this.Next;
+ this.Next = null;
+ if(n == null) {
+ return;
+ }
+ if(this.Timer != null) {
+ this.Timer.Stop();
+ this.Timer.Dispose();
+ }
+ n.Start();
+ }
+ }
+}
diff --git a/CalendarNotepad/Extends/StringExtend.cs b/CalendarNotepad/Extends/StringExtend.cs
new file mode 100644
index 0000000..cee8a29
--- /dev/null
+++ b/CalendarNotepad/Extends/StringExtend.cs
@@ -0,0 +1,9 @@
+namespace CalendarNotepad.Extends
+{
+ public static class StringExtend
+ {
+ public static bool IsNullOrEmpty(this string? str) => str == null || string.IsNullOrEmpty(str);
+
+ public static bool IsNotNullOrEmpty(this string? str) => !str.IsNullOrEmpty();
+ }
+}
diff --git a/CalendarNotepad/Extends/ZipExtend.cs b/CalendarNotepad/Extends/ZipExtend.cs
new file mode 100644
index 0000000..13879a6
--- /dev/null
+++ b/CalendarNotepad/Extends/ZipExtend.cs
@@ -0,0 +1,62 @@
+using CalendarNotepad.Models;
+using System.IO.Compression;
+using System.Text;
+
+namespace CalendarNotepad.Extends
+{
+ ///
+ /// 压缩文件帮助类
+ ///
+ public static class ZipExtend
+ {
+ ///
+ /// 压缩文件名
+ ///
+ public static string ZipFileName { get; set; } = CNOptions.GetSaveFileName;
+ ///
+ /// 某个文件保存到压缩文件内
+ ///
+ /// 内容
+ /// 压缩文件内容文件名
+ public static void SaveToFile(string str,string entryName) {
+ using var fs = new FileStream(ZipFileName,FileMode.OpenOrCreate);
+ using var archive = new ZipArchive(fs,ZipArchiveMode.Create);
+ var entry = archive.CreateEntry(entryName);
+ using var es = entry.Open();
+ using var sw = new StreamWriter(es,Encoding.UTF8);
+ sw.Write(str);
+ sw.Flush();
+ }
+ ///
+ /// 读取压缩文件中文件内容
+ ///
+ /// 压缩文件内容文件名
+ /// 内容
+ public static string GetFormFile(string entryName) {
+ if(!File.Exists(ZipFileName)) {
+ ZipFile.Open(ZipFileName,ZipArchiveMode.Create).Dispose();
+ return "";
+ }
+ using var zipfile = ZipFile.OpenRead(ZipFileName);
+ var entry = zipfile.GetEntry(entryName);
+ if(entry == null) {
+ return "";
+ }
+ var st = entry.Open();
+ var sr = new StreamReader(st,Encoding.UTF8);
+ var str = sr.ReadToEnd();
+ return str;
+ }
+
+ ///
+ /// 获取压缩库中所有文件名
+ ///
+ /// 文件名列表
+ public static IEnumerable GetFiles() {
+ using var zipfile = ZipFile.OpenRead(ZipFileName);
+ foreach(var en in zipfile.Entries) {
+ yield return en.Name;
+ }
+ }
+ }
+}
diff --git a/CalendarNotepad/Form1.Designer.cs b/CalendarNotepad/Form1.Designer.cs
deleted file mode 100644
index cb57f20..0000000
--- a/CalendarNotepad/Form1.Designer.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-namespace CalendarNotepad
-{
- partial class Form1
- {
- ///
- /// Required designer variable.
- ///
- private System.ComponentModel.IContainer components = null;
-
- ///
- /// Clean up any resources being used.
- ///
- /// true if managed resources should be disposed; otherwise, false.
- protected override void Dispose(bool disposing) {
- if(disposing && (components != null)) {
- components.Dispose();
- }
- base.Dispose(disposing);
- }
-
- #region Windows Form Designer generated code
-
- ///
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- ///
- private void InitializeComponent() {
- toolStrip1 = new ToolStrip();
- tscbYear = new ToolStripComboBox();
- tscbMonth = new ToolStripComboBox();
- tabPanel = new TableLayoutPanel();
- label1 = new Label();
- toolStrip1.SuspendLayout();
- tabPanel.SuspendLayout();
- SuspendLayout();
- //
- // toolStrip1
- //
- toolStrip1.Items.AddRange(new ToolStripItem[] { tscbYear,tscbMonth });
- toolStrip1.Location = new Point(0,0);
- toolStrip1.Name = "toolStrip1";
- toolStrip1.Size = new Size(465,25);
- toolStrip1.TabIndex = 0;
- toolStrip1.Text = "toolStrip1";
- //
- // tscbYear
- //
- tscbYear.DropDownStyle = ComboBoxStyle.DropDownList;
- tscbYear.Items.AddRange(new object[] { "2024","2025" });
- tscbYear.Name = "tscbYear";
- tscbYear.Size = new Size(121,25);
- //
- // tscbMonth
- //
- tscbMonth.DropDownStyle = ComboBoxStyle.DropDownList;
- tscbMonth.Name = "tscbMonth";
- tscbMonth.Size = new Size(121,25);
- //
- // tabPanel
- //
- tabPanel.CellBorderStyle = TableLayoutPanelCellBorderStyle.InsetDouble;
- tabPanel.ColumnCount = 2;
- tabPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent,50F));
- tabPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent,50F));
- tabPanel.Controls.Add(label1,1,0);
- tabPanel.Dock = DockStyle.Fill;
- tabPanel.Location = new Point(0,25);
- tabPanel.Name = "tabPanel";
- tabPanel.Padding = new Padding(10);
- tabPanel.RowCount = 2;
- tabPanel.RowStyles.Add(new RowStyle(SizeType.Percent,50F));
- tabPanel.RowStyles.Add(new RowStyle(SizeType.Percent,50F));
- tabPanel.Size = new Size(465,225);
- tabPanel.TabIndex = 1;
- //
- // label1
- //
- label1.AutoSize = true;
- label1.Location = new Point(237,13);
- label1.Name = "label1";
- label1.Size = new Size(15,17);
- label1.TabIndex = 0;
- label1.Text = "1";
- //
- // Form1
- //
- AutoScaleDimensions = new SizeF(7F,17F);
- AutoScaleMode = AutoScaleMode.Font;
- ClientSize = new Size(465,250);
- Controls.Add(tabPanel);
- Controls.Add(toolStrip1);
- Name = "Form1";
- Text = "Form1";
- Load += Form1_Load;
- toolStrip1.ResumeLayout(false);
- toolStrip1.PerformLayout();
- tabPanel.ResumeLayout(false);
- tabPanel.PerformLayout();
- ResumeLayout(false);
- PerformLayout();
- }
-
- #endregion
-
- private ToolStrip toolStrip1;
- private ToolStripComboBox tscbYear;
- private ToolStripComboBox tscbMonth;
- private TableLayoutPanel tabPanel;
- private Label label1;
- }
-}
\ No newline at end of file
diff --git a/CalendarNotepad/Form1.cs b/CalendarNotepad/Form1.cs
deleted file mode 100644
index f1c52c7..0000000
--- a/CalendarNotepad/Form1.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-namespace CalendarNotepad
-{
- public partial class Form1:Form
- {
- public Form1() {
- InitializeComponent();
- }
-
- private void Form1_Load(object sender,EventArgs e) {
- var year1 = 2024;
- do {
- this.tscbYear.Items.Add(year1);
- year1++;
- } while(year1 > DateTime.Now.Year + 1);
- this.tscbYear.Text = DateTime.Now.Year.ToString();
- for(int i = 0;i < 12;i++) {
- this.tscbMonth.Items.Add((i + 1) + "");
- }
- this.tscbMonth.Text = DateTime.Now.Month.ToString() + "";
-
- this.tabPanel.RowStyles.Clear();
- this.tabPanel.ColumnStyles.Clear();
- this.tabPanel.RowCount = 7;
- this.tabPanel.ColumnCount = 7;
- for(int i = 0;i < 7;i++) {
- this.tabPanel.RowStyles.Add(new RowStyle(SizeType.Percent,100 / 7));
- this.tabPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent,100 / 7));
- }
-
- this.tabPanel.Controls.Clear();
- int d = 1;
- for(int x = 0;x < 7;x++) {
- for(int y = 0;y < 7;y++) {
- var lab = new Label();
- lab.Text = d++.ToString();
- this.tabPanel.Controls.Add(lab,y,x);
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/CalendarNotepad/Main.Designer.cs b/CalendarNotepad/Main.Designer.cs
new file mode 100644
index 0000000..6b0a9ad
--- /dev/null
+++ b/CalendarNotepad/Main.Designer.cs
@@ -0,0 +1,170 @@
+namespace CalendarNotepad
+{
+ partial class Main
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing) {
+ if(disposing && (components != null)) {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent() {
+ mcWorkDay = new MonthCalendar();
+ splitContainer1 = new SplitContainer();
+ groupBox1 = new GroupBox();
+ rbAllDay = new RadioButton();
+ rbAfternoon = new RadioButton();
+ rbMorning = new RadioButton();
+ label1 = new Label();
+ rtbMsg = new RichTextBox();
+ ((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit();
+ splitContainer1.Panel1.SuspendLayout();
+ splitContainer1.Panel2.SuspendLayout();
+ splitContainer1.SuspendLayout();
+ groupBox1.SuspendLayout();
+ SuspendLayout();
+ //
+ // mcWorkDay
+ //
+ mcWorkDay.FirstDayOfWeek = Day.Monday;
+ mcWorkDay.Location = new Point(9,9);
+ mcWorkDay.MaxSelectionCount = 1;
+ mcWorkDay.MinDate = new DateTime(2000,1,1,0,0,0,0);
+ mcWorkDay.Name = "mcWorkDay";
+ mcWorkDay.ShowTodayCircle = false;
+ mcWorkDay.TabIndex = 0;
+ mcWorkDay.DateChanged += monthCalendar1_DateChanged;
+ mcWorkDay.DateSelected += monthCalendar1_DateSelected;
+ //
+ // splitContainer1
+ //
+ splitContainer1.Dock = DockStyle.Fill;
+ splitContainer1.FixedPanel = FixedPanel.Panel1;
+ splitContainer1.Location = new Point(0,0);
+ splitContainer1.Name = "splitContainer1";
+ //
+ // splitContainer1.Panel1
+ //
+ splitContainer1.Panel1.Controls.Add(groupBox1);
+ splitContainer1.Panel1.Controls.Add(mcWorkDay);
+ //
+ // splitContainer1.Panel2
+ //
+ splitContainer1.Panel2.Controls.Add(label1);
+ splitContainer1.Panel2.Controls.Add(rtbMsg);
+ splitContainer1.Size = new Size(642,400);
+ splitContainer1.SplitterDistance = 234;
+ splitContainer1.TabIndex = 1;
+ //
+ // groupBox1
+ //
+ groupBox1.Controls.Add(rbAllDay);
+ groupBox1.Controls.Add(rbAfternoon);
+ groupBox1.Controls.Add(rbMorning);
+ groupBox1.Location = new Point(12,201);
+ groupBox1.Name = "groupBox1";
+ groupBox1.Size = new Size(201,51);
+ groupBox1.TabIndex = 5;
+ groupBox1.TabStop = false;
+ groupBox1.Text = "时间段";
+ //
+ // rbAllDay
+ //
+ rbAllDay.AutoSize = true;
+ rbAllDay.Checked = true;
+ rbAllDay.Location = new Point(6,22);
+ rbAllDay.Name = "rbAllDay";
+ rbAllDay.Size = new Size(50,21);
+ rbAllDay.TabIndex = 1;
+ rbAllDay.TabStop = true;
+ rbAllDay.Text = "全天";
+ rbAllDay.UseVisualStyleBackColor = true;
+ //
+ // rbAfternoon
+ //
+ rbAfternoon.AutoSize = true;
+ rbAfternoon.Location = new Point(118,22);
+ rbAfternoon.Name = "rbAfternoon";
+ rbAfternoon.Size = new Size(50,21);
+ rbAfternoon.TabIndex = 3;
+ rbAfternoon.Text = "下午";
+ rbAfternoon.UseVisualStyleBackColor = true;
+ //
+ // rbMorning
+ //
+ rbMorning.AutoSize = true;
+ rbMorning.Location = new Point(62,22);
+ rbMorning.Name = "rbMorning";
+ rbMorning.Size = new Size(50,21);
+ rbMorning.TabIndex = 2;
+ rbMorning.Text = "上午";
+ rbMorning.UseVisualStyleBackColor = true;
+ //
+ // label1
+ //
+ label1.AutoSize = true;
+ label1.Location = new Point(3,9);
+ label1.Name = "label1";
+ label1.Size = new Size(56,17);
+ label1.TabIndex = 1;
+ label1.Text = "信息记录";
+ //
+ // rtbMsg
+ //
+ rtbMsg.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
+ rtbMsg.EnableAutoDragDrop = true;
+ rtbMsg.Location = new Point(3,35);
+ rtbMsg.Name = "rtbMsg";
+ rtbMsg.Size = new Size(389,353);
+ rtbMsg.TabIndex = 0;
+ rtbMsg.Text = "";
+ rtbMsg.TextChanged += rtbMsg_TextChanged;
+ //
+ // Main
+ //
+ AutoScaleDimensions = new SizeF(7F,17F);
+ AutoScaleMode = AutoScaleMode.Font;
+ ClientSize = new Size(642,400);
+ Controls.Add(splitContainer1);
+ Name = "Main";
+ Text = "工作记录";
+ FormClosing += Main_FormClosing;
+ Load += Main_Load;
+ splitContainer1.Panel1.ResumeLayout(false);
+ splitContainer1.Panel2.ResumeLayout(false);
+ splitContainer1.Panel2.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)splitContainer1).EndInit();
+ splitContainer1.ResumeLayout(false);
+ groupBox1.ResumeLayout(false);
+ groupBox1.PerformLayout();
+ ResumeLayout(false);
+ }
+
+ #endregion
+
+ private MonthCalendar mcWorkDay;
+ private SplitContainer splitContainer1;
+ private RadioButton rbAllDay;
+ private RadioButton rbAfternoon;
+ private RadioButton rbMorning;
+ private RichTextBox rtbMsg;
+ private Label label1;
+ private GroupBox groupBox1;
+ }
+}
\ No newline at end of file
diff --git a/CalendarNotepad/Main.cs b/CalendarNotepad/Main.cs
new file mode 100644
index 0000000..d569742
--- /dev/null
+++ b/CalendarNotepad/Main.cs
@@ -0,0 +1,87 @@
+using CalendarNotepad.Extends;
+using CalendarNotepad.Models;
+
+namespace CalendarNotepad
+{
+ public partial class Main:Form
+ {
+ public WorkContext Context { get; set; }
+ public Shaking SaveFileShaking { get; set; } = new Shaking(5);
+
+ public Main() {
+ this.Context = new WorkContext();
+
+ InitializeComponent();
+
+ //this.Context.LoadFromFile();
+ this.Context.GetWorkListFormZipFile();
+ var today = DateTime.Now.ToString("yyyyMMdd");
+ this.mcWorkDay.TodayDate = DateTime.Now;
+ this.rbAllDay.Checked = true;
+ var unit = this.Context.GetUnit(today,GetDateRange());
+ this.rtbMsg.Text = unit.WorkMessage;
+ }
+
+ private void monthCalendar1_DateChanged(object sender,DateRangeEventArgs e) {
+ var selectedDate = e.Start.ToString("yyyyMMdd");
+ var selectedRange = GetDateRange();
+ var unit = this.Context.GetUnit(selectedDate,selectedRange);
+ this.rtbMsg.Text = unit.WorkMessage;
+ }
+
+ private void monthCalendar1_DateSelected(object sender,DateRangeEventArgs e) {
+ //MessageBox.Show("monthCalendar1_DateSelected");
+ }
+
+ ///
+ /// 返回当前选择的时间段
+ ///
+ /// 时间段
+ private string GetDateRange() =>
+ this.rbAllDay.Checked ? "全天" :
+ this.rbMorning.Checked ? "上午" :
+ this.rbAfternoon.Checked ? "下午" :
+ "";
+
+ private void rtbMsg_TextChanged(object sender,EventArgs e) {
+ var data = new WorkUnit {
+ DayRange = GetDateRange(),
+ WorkDay = this.mcWorkDay.SelectionStart.ToString("yyyyMMdd"),
+ WorkMessage = this.rtbMsg.Text,
+ };
+ this.Context.AddOrReplace(data);
+
+ //this.SaveFileShaking.Run(this.Context.SaveToFile);
+ this.SaveFileShaking.Run(this.Context.SaveWorkListToZipFile);
+ }
+
+ private void Main_FormClosing(object sender,FormClosingEventArgs e) {
+ this.SaveFileShaking.RunNow();
+ }
+
+ private void Main_Load(object sender,EventArgs e) {
+ Task.Factory.StartNew(async () => {
+ while(true) {
+ if(this.Context == null) {
+ continue;
+ }
+ var days = new List();
+ var curD = this.mcWorkDay.SelectionStart;
+ var year = curD.Year;
+ var month = curD.Month;
+ for(DateTime i = new DateTime(year,month,1);i.Month == curD.Month;i = i.AddDays(1)) {
+ var df = i.ToString("yyyyMMdd");
+ var m = this.Context.GetUnit(df,GetDateRange());
+ if(m.WorkMessage.IsNotNullOrEmpty()) {
+ days.Add(i);
+ }
+ }
+ this.Invoke(() => {
+ this.mcWorkDay.BoldedDates = days.ToArray();
+ });
+ await Task.Delay(5 * 1000);
+ }
+ });
+ }
+ }
+}
diff --git a/CalendarNotepad/Form1.resx b/CalendarNotepad/Main.resx
similarity index 73%
rename from CalendarNotepad/Form1.resx
rename to CalendarNotepad/Main.resx
index 40524cc..f51a8ab 100644
--- a/CalendarNotepad/Form1.resx
+++ b/CalendarNotepad/Main.resx
@@ -117,7 +117,40 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- 17, 17
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
\ No newline at end of file
diff --git a/CalendarNotepad/Models/CNOptions.cs b/CalendarNotepad/Models/CNOptions.cs
new file mode 100644
index 0000000..a5da615
--- /dev/null
+++ b/CalendarNotepad/Models/CNOptions.cs
@@ -0,0 +1,23 @@
+using System.Configuration;
+
+namespace CalendarNotepad.Models
+{
+ ///
+ /// 应用配置
+ ///
+ public static class CNOptions
+ {
+ ///
+ /// 获取配置的值
+ ///
+ /// 键
+ /// 值
+ public static string? GetValue(string key) => ConfigurationManager.AppSettings[key];
+
+ ///
+ /// 保存的文件名
+ ///
+ ///
+ public static string GetSaveFileName => GetValue("saveFileName") ?? "";
+ }
+}
diff --git a/CalendarNotepad/Models/SaveFileModel.cs b/CalendarNotepad/Models/SaveFileModel.cs
new file mode 100644
index 0000000..cd161f3
--- /dev/null
+++ b/CalendarNotepad/Models/SaveFileModel.cs
@@ -0,0 +1,15 @@
+namespace CalendarNotepad.Models
+{
+ public class SaveFileModel
+ {
+ ///
+ /// 数据版本
+ ///
+ public int Ver { get; set; } = 1;
+ ///
+ /// 工作列表
+ ///
+ public WorkUnitList WorkList { get; set; } = new WorkUnitList();
+
+ }
+}
diff --git a/CalendarNotepad/Models/WorkContext.cs b/CalendarNotepad/Models/WorkContext.cs
new file mode 100644
index 0000000..ac59bd9
--- /dev/null
+++ b/CalendarNotepad/Models/WorkContext.cs
@@ -0,0 +1,125 @@
+using CalendarNotepad.Extends;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using System.Threading.Tasks;
+
+namespace CalendarNotepad.Models
+{
+ ///
+ /// 上下文
+ ///
+ public class WorkContext
+ {
+ ///
+ /// 数据版本
+ ///
+ public int Ver { get; set; } = 1;
+ ///
+ /// 工作列表
+ ///
+ private WorkUnitList WorkList { get; set; } = new WorkUnitList();
+
+ private static object _lockObj = new object();
+
+ public void AddOrReplace(WorkUnit unit) {
+ lock(_lockObj) {
+ var qu = this.WorkList.Where(a => a.WorkDay == unit.WorkDay && a.DayRange == unit.DayRange);
+ if(qu.Any() && unit.WorkMessage.IsNullOrEmpty()) {
+ qu.ToList().ForEach(a => this.WorkList.Remove(a));
+ return;
+ }
+ if(qu.Any() && unit.WorkMessage.IsNotNullOrEmpty()) {
+ qu.ToList().ForEach(a => a.WorkMessage = unit.WorkMessage);
+ return;
+ }
+ if(!qu.Any() && unit.WorkMessage.IsNullOrEmpty()) {
+ return;
+ }
+ if(!qu.Any() && unit.WorkMessage.IsNotNullOrEmpty()) {
+ this.WorkList.Add(unit);
+ return;
+ }
+ }
+ }
+
+ ///
+ /// 获取工作单元
+ ///
+ /// 工作日期
+ /// 工作范围
+ ///
+ public WorkUnit GetUnit(string workDay,string workRange) {
+ var qu = this.WorkList.Where(a => a.WorkDay == workDay && a.DayRange == workRange);
+ return qu.Any() ? qu.First() : new WorkUnit { DayRange = workRange,WorkDay = workDay,WorkMessage = "" };
+ }
+
+ public void SaveToFile() {
+ var file = CNOptions.GetSaveFileName;
+ if(file.IsNullOrEmpty()) {
+ MessageBox.Show("没有配置数据保存文件!");
+ return;
+ }
+ if(!Path.IsPathFullyQualified(file)) {
+ file = Path.Combine(Application.StartupPath,file);
+ }
+ var path = Path.GetDirectoryName(file);
+ if(!Directory.Exists(path)) {
+ Directory.CreateDirectory(path);
+ }
+ if(File.Exists(file)) {
+ File.Delete(file);
+ }
+ var jsonModel = new SaveFileModel {
+ Ver = this.Ver,WorkList = this.WorkList,
+ };
+ var str = JsonSerializer.Serialize(jsonModel);
+ File.WriteAllText(file,str,Encoding.UTF8);
+ }
+
+ public void SaveWorkListToZipFile() {
+ var str = JsonSerializer.Serialize(this.WorkList);
+ ZipExtend.SaveToFile(str,"WorkContext.json");
+ }
+
+ public void GetWorkListFormZipFile() {
+ var str = ZipExtend.GetFormFile("WorkContext.json");
+ if(str.IsNullOrEmpty()) {
+ return;
+ }
+ this.WorkList = JsonSerializer.Deserialize(str) ?? new WorkUnitList();
+ }
+
+ public void LoadFromFile() {
+ var file = CNOptions.GetSaveFileName;
+ if(file.IsNullOrEmpty()) {
+ MessageBox.Show("没有配置数据保存文件!");
+ return;
+ }
+ if(!Path.IsPathFullyQualified(file)) {
+ file = Path.Combine(Application.StartupPath,file);
+ }
+ if(!File.Exists(file)) {
+ MessageBox.Show("没有找到数据文件!");
+ return;
+ }
+ try {
+ var str = File.ReadAllText(file);
+ var obj = JsonSerializer.Deserialize(str);
+ if(obj == null) {
+ MessageBox.Show("保存数据格式错误!");
+ }
+ if(obj?.Ver == 1) {
+ this.WorkList = obj.WorkList;
+ }
+ }
+ catch(Exception ex) {
+ MessageBox.Show(ex.ToString());
+ return;
+ }
+ }
+ }
+}
diff --git a/CalendarNotepad/Models/WorkUnit.cs b/CalendarNotepad/Models/WorkUnit.cs
new file mode 100644
index 0000000..913097c
--- /dev/null
+++ b/CalendarNotepad/Models/WorkUnit.cs
@@ -0,0 +1,21 @@
+namespace CalendarNotepad.Models
+{
+ ///
+ /// 工作记录单元
+ ///
+ public class WorkUnit
+ {
+ ///
+ /// 工作日期
+ ///
+ public string? WorkDay { get; set; }
+ ///
+ /// 时间段
+ ///
+ public string? DayRange { get; set; }
+ ///
+ /// 内容
+ ///
+ public string? WorkMessage { get; set; }
+ }
+}
diff --git a/CalendarNotepad/Models/WorkUnitList.cs b/CalendarNotepad/Models/WorkUnitList.cs
new file mode 100644
index 0000000..4165061
--- /dev/null
+++ b/CalendarNotepad/Models/WorkUnitList.cs
@@ -0,0 +1,7 @@
+namespace CalendarNotepad.Models
+{
+ ///
+ /// 工作记录列表。不要直接使用此类,通过Workcontext进行操作
+ ///
+ public class WorkUnitList:List { }
+}
diff --git a/CalendarNotepad/Program.cs b/CalendarNotepad/Program.cs
index 5b4cdf2..56a1791 100644
--- a/CalendarNotepad/Program.cs
+++ b/CalendarNotepad/Program.cs
@@ -10,7 +10,7 @@ namespace CalendarNotepad
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
- Application.Run(new Form1());
+ Application.Run(new Main());
}
}
}
\ No newline at end of file
diff --git a/SharkingTest/Program.cs b/SharkingTest/Program.cs
new file mode 100644
index 0000000..c301723
--- /dev/null
+++ b/SharkingTest/Program.cs
@@ -0,0 +1,23 @@
+// See https://aka.ms/new-console-template for more information
+using CalendarNotepad.Extends;
+
+Console.WriteLine("Hello, World!");
+
+var showMsg = () => Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")} show message!");
+
+var reMsg = () => $"{DateTime.Now.ToString("HH:mm:ss")} show message!";
+
+var task = new Task(reMsg);
+
+var shaking = new Shaking(10);
+
+//showMsg();
+//await Task.Delay(5 * 1000);
+//shaking.Run(showMsg);
+
+shaking.Run(task);
+shaking.Run(task);
+Console.WriteLine(task.Result);
+
+
+Console.ReadKey();
diff --git a/SharkingTest/Shaking.cs b/SharkingTest/Shaking.cs
new file mode 100644
index 0000000..8231b76
--- /dev/null
+++ b/SharkingTest/Shaking.cs
@@ -0,0 +1,70 @@
+
+namespace CalendarNotepad.Extends
+{
+ ///
+ /// 防止抖动执行任务
+ ///
+ public class Shaking
+ {
+ ///
+ /// 下一个要执行的任务
+ ///
+ protected Task? Next { get; set; }
+ ///
+ /// 执行计时器
+ ///
+ protected System.Timers.Timer Timer { get; set; }
+ ///
+ /// 等待执行时间
+ ///
+ public int TimespanSeconds { get; set; }
+ ///
+ /// 使用默认方式实例化
+ ///
+ public Shaking() : this(5) { }
+ ///
+ /// 实例化,默认抖动执行间隔5秒
+ ///
+ /// 抖动执行时间间隔。秒
+ public Shaking(int timeSpanSeconds) {
+ this.TimespanSeconds = timeSpanSeconds * 1000;
+ this.Timer = new System.Timers.Timer {
+ Interval = this.TimespanSeconds
+ };
+ this.Timer.Elapsed += Timer_Tick;
+ this.Timer.Stop();
+ }
+
+ protected void Timer_Tick(object? sender,EventArgs e) {
+ this.Timer.Stop();
+ this.Timer.Dispose();
+ if(this.Next == null) {
+ return;
+ }
+ var n = this.Next;
+ this.Next = null;
+ n.Start();
+ }
+ ///
+ /// 防抖执行任务
+ ///
+ /// 要执行的任务
+ public void Run(Task task) {
+ this.Next = task;
+ if(this.Timer != null) {
+ this.Timer.Stop();
+ this.Timer.Dispose();
+ }
+ this.Timer = new System.Timers.Timer {
+ Interval = this.TimespanSeconds,
+ };
+ this.Timer.Elapsed += Timer_Tick;
+ this.Timer.Start();
+ }
+ ///
+ /// 防抖执行委托
+ ///
+ /// 要执行的委托
+ public void Run(Action action) => Run(new Task(action));
+ }
+}
diff --git a/SharkingTest/SharkingTest.csproj b/SharkingTest/SharkingTest.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/SharkingTest/SharkingTest.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+