Commit 9a46064f authored by shrabbit's avatar shrabbit
Browse files

上传文件至 /

parent 752b1de9
Loading
Loading
Loading
Loading

Core.cs

0 → 100644
+218 −0
Original line number Diff line number Diff line
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.Design.AxImporter;

namespace OFFchatToJson
{
    public class KeyValuePair
    {
        public string Key { get; set; }
        public string Value { get; set; }
    }

    public class MessagesStructure
    {
        public DateTime Date { get; set; }
        public string Sender { get; set; }
        public string Content { get; set; }
        public MessageType Type { get; set; }
        public string? RefrenceMessage { get; set; } = null;
        public string? ExtraContent { get; set; } = null;
        public KeyValuePair? ExtraKeyValuePair { get; set; } = null;
    }

    public enum MessageType
    {
        Text,
        Video,
        Voice,
        File,
        Image,
        Emoji,
        Others,
        Link
    }

    /// <summary>
    /// 连接到界面
    /// </summary>
    public interface IMessageDataUI
    {
        ListBox MessageList { get; }
        DateTime GetDateTime();
        void SetDateTime(DateTime dateTime);
        string GetMessage();
        void SetMessage(string message);
        MessageType GetMsgType();
        void SetMsgType(MessageType messageType);
        bool TryGetRefrenceContent(out string content);
        void SetRefrenceContent(string content);
        bool TryGetExtraContent(out string content);
        void SetExtraContent(string content);
        bool TryGetKVP(out KeyValuePair content);
        void SetKVP(KeyValuePair content);
        void ClearExtra();
        string GetSender();
        void SetSender(string sender);
        List<string> GetSenderList();
        void SetSenderList(List<string> strings);
    }

    public class MessagesData
    {
        public List<MessagesStructure> Data;

        //public bool DisableSwitchList = false;

        public MessagesData()
        {
            Data = new List<MessagesStructure>(); // 初始化空列表,避免 null  
        }

        private JsonSerializerOptions GetOptions() => new JsonSerializerOptions
        {
            WriteIndented = true, // 格式化输出(带缩进,可读性强)  
            Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping, // 中文不转义  
            // 添加 Enum 转字符串转换器  
            Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) }
            // JsonNamingPolicy.CamelCase:可选,将枚举名称转为驼峰式(如 MessageType.Text → "text")  
            // 若不指定,默认使用 PascalCase(如 "Text")  
        };

        public void Read(string filePath, IMessageDataUI ui)
        {
            try
            {
                Data = new();
                ui.MessageList.SelectedIndex = -1;
                string jsonFromFile = File.ReadAllText(filePath);
                Data = JsonSerializer.Deserialize<List<MessagesStructure>>(jsonFromFile, GetOptions());
                ToListBox(ui);
            }
            catch (Exception)
            {
            }
        }

        public void PrintToOutput(TextBox textBox)
        {
            textBox.Text = JsonSerializer.Serialize(Data, GetOptions());
        }

        public string OutputString() => JsonSerializer.Serialize(Data, GetOptions());

        public void ToListBox(IMessageDataUI ui)
        {
            ui.MessageList.SelectedIndex = -1;
            ui.MessageList.Items.Clear();
            foreach (var item in Data)
            {
                ui.MessageList.Items.Add($"{item.Sender}: {(item.Type != MessageType.Text ? item.Type.ToString() : item.Content)}");
            }
            ui.MessageList.SelectedIndex = 0;
        }

        public void ShowEditData(IMessageDataUI ui)
        {
            try
            {
                MessagesStructure stru = Data[ui.MessageList.SelectedIndex];

                ui.SetDateTime(stru.Date);
                ui.SetMessage(stru.Content);
                ui.SetSender(stru.Sender);
                ui.SetMsgType(stru.Type);

                ui.ClearExtra();

                if (stru.RefrenceMessage != null)
                    ui.SetRefrenceContent(stru.RefrenceMessage);
                if (stru.ExtraContent != null)
                    ui.SetExtraContent(stru.ExtraContent);
                if (stru.ExtraKeyValuePair != null)
                    ui.SetKVP(stru.ExtraKeyValuePair);
            }
            catch (ArgumentOutOfRangeException)
            {
                // 此时列表项可能已无项目,所以直接全部删除
                Data.Clear();
            }
        }

        public void ApplyEditData(IMessageDataUI ui)
        {
            MessagesStructure stru = new();

            stru.Date = ui.GetDateTime();
            stru.Sender = ui.GetSender();
            stru.Content = ui.GetMessage();
            stru.Type = ui.GetMsgType();

            if (ui.TryGetExtraContent(out string extra))
                stru.ExtraContent = extra;
            if (ui.TryGetRefrenceContent(out string refr))
                stru.RefrenceMessage = refr;
            if (ui.TryGetKVP(out KeyValuePair kvp))
                stru.ExtraKeyValuePair = kvp;

            var i = ui.MessageList.SelectedIndex;
            Data[ui.MessageList.SelectedIndex] = stru;

            // Clear ListBox
            ui.MessageList.Items.Clear();
            ToListBox(ui);

            ui.MessageList.SelectedIndex = i;
        }

        public void Save(string filePath)
        {
            try
            {
                // 3. 序列化对象为 JSON 字符串  
                string jsonString = JsonSerializer.Serialize(Data, GetOptions());

                // 4. 保存到本地文件(支持绝对路径或相对路径)  
                string savePath = Path.Combine(filePath);

                // 同步保存(适合小文件)  
                File.WriteAllText(savePath, jsonString);
            }
            catch
            {
            }
        }

        public void Add(IMessageDataUI ui)
        {
            ui.MessageList.Items.Add($"{ui.GetSender()}: {(ui.GetMsgType() != MessageType.Text ? ui.GetMsgType().ToString() : ui.GetMessage())}");
            Data.Add(new());
            ui.MessageList.SelectedIndex = ui.MessageList.Items.Count -1;
            ApplyEditData(ui);
        }

        public void Remove(IMessageDataUI ui)
        {
            if (ui.MessageList.SelectedIndex > 0)
            {
                int i = ui.MessageList.SelectedIndex;
                ui.MessageList.SelectedIndex = 0;
                Data.RemoveAt(i);
                ui.MessageList.Items.RemoveAt(i);

                ShowEditData(ui);
                ui.MessageList.SelectedIndex = ui.MessageList.Items.Count - 1;
            }
            else
            {
                MessageBox.Show("列表已无项目", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
    }
}

Form1.Designer.cs

0 → 100644
+896 −0

File added.

Preview size limit exceeded, changes collapsed.

Form1.cs

0 → 100644
+279 −0
Original line number Diff line number Diff line

using System.ComponentModel;

namespace OFFchatToJson
{
    public partial class Form1 : Form, IMessageDataUI
    {
        public ListBox MessageList => listBox1;

        private MessagesData _data;

        public Form1()
        {
            InitializeComponent();
            Load += Form1_Load;
        }

        private void Form1_Load(object? sender, EventArgs e)
        {
            _data = new MessagesData();
        }

        private void tabPage1_Click(object sender, EventArgs e)
        {

        }

        private void groupBox2_Enter(object sender, EventArgs e)
        {

        }

        private void groupBox4_Enter(object sender, EventArgs e)
        {

        }

        private void splitContainer1_Panel2_Paint(object sender, PaintEventArgs e)
        {

        }

        public DateTime GetDateTime() => new DateTime
        (
            (int)year.Value,
            (int)month.Value,
            (int)day.Value,
            (int)hour.Value,
            (int)minute.Value,
            (int)second.Value
        );

        public void SetDateTime(DateTime dateTime)
        {
            try
            {
                year.Value = dateTime.Year;
                month.Value = dateTime.Month;
                day.Value = dateTime.Day;
                hour.Value = dateTime.Hour;
                minute.Value = dateTime.Minute;
                second.Value = dateTime.Second;
            }
            catch (Exception)
            {
            }
        }

        public string GetMessage() => content.Text;

        public void SetMessage(string message) => content.Text = message;

        public MessageType GetMsgType()
        {
            foreach (Control ctrl in groupBox2.Controls)
            {
                if (ctrl is RadioButton radio && radio.Checked)
                {
                    // 从 Tag 中获取枚举值(需强制转换)  
                    return (MessageType)radio.Tag;
                }
            }
            // 默认选中第一个选项(避免返回 null)  
            return MessageType.Text;
        }

        public void SetMsgType(MessageType messageType)
        {
            foreach (Control ctrl in groupBox2.Controls)
            {
                // 判断是否为单选框,且 Tag 与目标枚举值匹配  
                if (ctrl is RadioButton radio && radio.Tag is MessageType radioType && radioType == messageType)
                {
                    radio.Checked = true; // 选中匹配的单选框  
                    return; // 找到后退出循环,提高效率  
                }
            }
            // 可选:若未找到匹配项,选中默认单选框(如第一个)  
            if (groupBox2.Controls.OfType<RadioButton>().FirstOrDefault() is RadioButton defaultRadio)
            {
                defaultRadio.Checked = true;
            }
        }

        public bool TryGetRefrenceContent(out string content)
        {
            if (enableRefrence.Checked)
            {
                content = refText.Text;
                return true;
            }
            else
            {
                content = string.Empty;
                return false;
            }
        }

        public void SetRefrenceContent(string content)
        {
            enableRefrence.Checked = true;
            refText.Text = content;
        }

        public bool TryGetExtraContent(out string content)
        {
            if (enableExtra.Checked)
            {
                content = extraText.Text;
                return true;
            }
            else
            {
                content = string.Empty;
                return false;
            }
        }

        public void SetExtraContent(string content)
        {
            extraText.Text = content;
            enableExtra.Checked = true;
        }

        public bool TryGetKVP(out KeyValuePair content)
        {
            if (enableKVP.Checked)
            {
                content = new KeyValuePair
                {
                    Key = keyText.Text,
                    Value = valueText.Text
                };
                return true;
            }
            else
            {
                content = new();
                return false;
            }
        }

        public void SetKVP(KeyValuePair content)
        {
            keyText.Text = content.Key;
            valueText.Text = content.Value;

            enableKVP.Checked = true;
        }

        public void ClearExtra()
        {
            keyText.Text = string.Empty;
            valueText.Text = string.Empty;
            extraText.Text = string.Empty;
            refText.Text = string.Empty;

            enableExtra.Checked = false;
            enableKVP.Checked = false;
            enableRefrence.Checked = false;
        }

        public string GetSender() => Sender.Text;

        public void SetSender(string sender) => Sender.Text = sender;

        public List<string> GetSenderList()
        {
            List<string> li = new();
            foreach (var item in Sender.Items)
            {
                li.Add((string)item);
            }
            return li;
        }

        public void SetSenderList(List<string> strings)
        {
            foreach (var item in strings)
            {
                Sender.Items.Add(item);
            }
        }

        bool _disable = false;

        private void addBtn_Click(object sender, EventArgs e)
        {
            _disable = true;
            _data.Add(this);
            _disable = false;
        }

        private void createBtn_Click(object sender, EventArgs e)
        {
            tabControl1.SelectedIndex = 1;
            _data.PrintToOutput(textBox1);
        }

        private void nowBtn_Click(object sender, EventArgs e)
        {
            SetDateTime(DateTime.Now);
        }

        private void listBox1_SelectedValueChanged(object sender, EventArgs e)
        {
            if (!_disable)
                _data.ShowEditData(this);
        }

        private void replete_Click(object sender, EventArgs e)
        {
            _data.ApplyEditData(this);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Sender.Items.Add(Sender.Text);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Sender.Items.Remove(Sender.Text);
        }

        private void delBtn_Click(object sender, EventArgs e)
        {
            _data.Remove(this);
        }

        private void saveBtn_Click(object sender, EventArgs e)
        {
            SaveFileDialog dialog = new();
            dialog.Filter = "JSON文档(*.json)|*.json|文本文件(*.txt)|*.txt|所有文件|*";
            dialog.ShowDialog();
            _data.Save(dialog.FileName);
        }

        private void openBtn_Click(object sender, EventArgs e)
        {
            OpenFileDialog dialog = new();
            dialog.Filter = "JSON文档(*.json)|*.json|文本文件(*.txt)|*.txt|所有文件|*";
            dialog.ShowDialog();
            _data.Read(dialog.FileName, this);
        }

        private void clearAllBtn_Click(object sender, EventArgs e)
        {
            ClearExtra();
            radioButton1.Checked = true;
            content.Text = string.Empty;
        }

        private void Form1_Load_1(object sender, EventArgs e)
        {
            SetDateTime(DateTime.Now);
        }
    }
}

Form1.resx

0 → 100644
+120 −0
Original line number Diff line number Diff line
<?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>
</root>
 No newline at end of file

OFFchatToJson.csproj

0 → 100644
+12 −0
Original line number Diff line number Diff line
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
	<OutputType>WinExe</OutputType>
	<TargetFramework>net9.0-windows</TargetFramework>
	<Nullable>enable</Nullable>
	<UseWindowsForms>true</UseWindowsForms>
	<ImplicitUsings>enable</ImplicitUsings>
	<PlatformTarget>x64</PlatformTarget>
  </PropertyGroup>

</Project>
 No newline at end of file