Browse Source

完成关系人档案和日志的记录、搜索,开始完善备份功能

CaptB 5 months ago
parent
commit
7b506f1ed7
3 changed files with 545 additions and 68 deletions
  1. 103 0
      App.xaml.cs
  2. 139 59
      MainWindow.xaml
  3. 303 9
      MainWindow.xaml.cs

+ 103 - 0
App.xaml.cs

@@ -1,5 +1,9 @@
 using System.Configuration;
 using System.Data;
+using System.IO.Compression;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
 using System.Windows;
 
 namespace ArchivesCenter3
@@ -9,6 +13,105 @@ namespace ArchivesCenter3
     /// </summary>
     public partial class App : Application
     {
+        protected override void OnStartup(StartupEventArgs e)
+        {
+            base.OnStartup(e);
+            this.SessionEnding += App_SessionEnding;
+        }
+
+        private void App_SessionEnding(object sender, SessionEndingCancelEventArgs e)
+        {
+            try
+            {
+                // 获取用户文档库路径
+                string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
+                string archivesCenterPath = Path.Combine(documentsPath, "ArchivesCenter");
+                string dataPath = Path.Combine(archivesCenterPath, "data");
+                string configPath = Path.Combine(archivesCenterPath, "config");
+                string backupPath = Path.Combine(archivesCenterPath, "backup");
+
+                // 确保备份文件夹存在
+                Directory.CreateDirectory(backupPath);
+
+                // 获取当前时间作为文件名
+                string timestamp = DateTime.Now.ToString("yyyyMMddHHmmssfff");
+                string backupFileName = Path.Combine(backupPath, $"backup_{timestamp}.zip");
+
+                // 获取加密密码
+                string password = Settings1.Default.Password;
+
+                // 创建压缩包并加密
+                using (FileStream zipToOpen = new FileStream(backupFileName, FileMode.Create))
+                {
+                    using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Create, true))
+                    {
+                        // 添加 data 文件夹
+                        if (Directory.Exists(dataPath))
+                        {
+                            AddDirectoryToArchive(archive, dataPath, "data");
+                        }
+
+                        // 添加 config 文件夹
+                        if (Directory.Exists(configPath))
+                        {
+                            AddDirectoryToArchive(archive, configPath, "config");
+                        }
+                    }
+                }
+
+                // 加密压缩包
+                EncryptFile(backupFileName, backupFileName + ".enc", password);
+
+                // 删除未加密的压缩包
+                File.Delete(backupFileName);
+
+                MessageBox.Show("备份完成,文件已加密并保存到:\n" + backupFileName + ".enc");
+            }
+            catch (Exception ex)
+            {
+                MessageBox.Show("备份失败:" + ex.Message);
+            }
+        }
+
+        private void AddDirectoryToArchive(ZipArchive archive, string directoryPath, string entryName)
+        {
+            foreach (string file in Directory.GetFiles(directoryPath, "*.*", SearchOption.AllDirectories))
+            {
+                string entryFilePath = Path.GetRelativePath(directoryPath, file);
+                ZipArchiveEntry entry = archive.CreateEntry(Path.Combine(entryName, entryFilePath));
+                using (FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read))
+                {
+                    using (Stream entryStream = entry.Open())
+                    {
+                        fileStream.CopyTo(entryStream);
+                    }
+                }
+            }
+        }
+
+        private void EncryptFile(string inputFilePath, string outputFilePath, string password)
+        {
+            byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
+            using (Aes aesAlg = Aes.Create())
+            {
+                aesAlg.Key = passwordBytes;
+                aesAlg.IV = new byte[16]; // IV 长度必须为 16 字节
+
+                using (FileStream inputStream = new FileStream(inputFilePath, FileMode.Open, FileAccess.Read))
+                {
+                    using (FileStream outputStream = new FileStream(outputFilePath, FileMode.Create, FileAccess.Write))
+                    {
+                        using (ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV))
+                        {
+                            using (CryptoStream cryptoStream = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write))
+                            {
+                                inputStream.CopyTo(cryptoStream);
+                            }
+                        }
+                    }
+                }
+            }
+        }
     }
 
 }

+ 139 - 59
MainWindow.xaml

@@ -15,7 +15,7 @@
                             <Grid VerticalAlignment="Top">
                                 <Grid.ColumnDefinitions>
                                     <ColumnDefinition Width="50" />
-                                    <ColumnDefinition Width="Auto" />
+                                    <ColumnDefinition Width="*" />
                                 </Grid.ColumnDefinitions>
                                 <Grid.RowDefinitions>
                                     <RowDefinition Height="Auto" />
@@ -45,9 +45,28 @@
                                 <TextBlock Grid.Column="1" Grid.Row="6" Text="此数据库中所收集之信息皆应由合法渠道取得。注意保密!" VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="18" Foreground="#000000"/>
                             </Grid>
                         </TabItem>
-                        <TabItem Header="备份" IsEnabled="False">
+                        <TabItem Header="备份">
                             <Grid>
-
+                                <Grid.ColumnDefinitions>
+                                    <ColumnDefinition Width="Auto"></ColumnDefinition>
+                                    <ColumnDefinition Width="Auto"></ColumnDefinition>
+                                    <ColumnDefinition Width="Auto"></ColumnDefinition>
+                                    <ColumnDefinition Width="*"></ColumnDefinition>
+                                </Grid.ColumnDefinitions>
+                                <Grid.RowDefinitions>
+                                    <RowDefinition Height="Auto"></RowDefinition>
+                                    <RowDefinition Height="*"></RowDefinition>
+                                </Grid.RowDefinitions>
+                                <Button Grid.Column="0" Grid.Row="0" Height="25" Width="75" Margin="10">创建还原点</Button>
+                                <Button Grid.Column="1" Grid.Row="0" Height="25" Width="75" Margin="10">还原</Button>
+                                <Button Grid.Column="2" Grid.Row="0" Height="25" Width="75" Margin="10">清除还原点</Button>
+                                <DataGrid Grid.ColumnSpan="4" Grid.Row="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" IsReadOnly="True" Margin="10">
+                                    <DataGrid.Columns>
+                                        <DataGridTextColumn Header="创建时间" Width="Auto"/>
+                                        <DataGridTextColumn Header="占用空间" Width="Auto"/>
+                                        <DataGridTextColumn Header="占全部还原点占用空间百分比" Width="Auto"/>
+                                    </DataGrid.Columns>
+                                </DataGrid>
                             </Grid>
                         </TabItem>
                         <TabItem Header="设置">
@@ -55,17 +74,11 @@
                                 <Grid.ColumnDefinitions>
                                     <ColumnDefinition Width="Auto" />
                                     <ColumnDefinition Width="Auto" />
-                                    <ColumnDefinition Width="Auto" />
+                                    <ColumnDefinition Width="*" />
                                 </Grid.ColumnDefinitions>
                                 <Grid.RowDefinitions>
                                     <RowDefinition Height="Auto" />
-                                    <RowDefinition Height="Auto" />
-                                    <RowDefinition Height="Auto" />
-                                    <RowDefinition Height="Auto" />
-                                    <RowDefinition Height="Auto" />
-                                    <RowDefinition Height="Auto" />
-                                    <RowDefinition Height="Auto" />
-                                    <RowDefinition Height="Auto" />
+                                    <RowDefinition Height="*" />
                                 </Grid.RowDefinitions>
                                 <Grid Grid.ColumnSpan="3" Grid.Row="0">
                                     <Grid.ColumnDefinitions>
@@ -80,31 +93,70 @@
                                     <TextBlock Grid.Column="1" Grid.Row="0" Text="设置   " Margin="10" VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="24" Foreground="#0368ba"/>
                                     <Border Grid.ColumnSpan="3" Grid.Row="1" Background="#0368ba" Height="3"/>
                                 </Grid>
-                                <Button x:Name="settingSaveButton0" Grid.Column="0" Grid.Row="1" Content="保存" HorizontalAlignment="Center" VerticalAlignment="Center" Width="50" Height="20" Click="Button_Click" IsEnabled="False"/>
-                                <TextBlock Grid.Column="1" Grid.Row="1" Text="提示:若无更改则留空" Margin="0,10,10,10" Foreground="Gray"/>
-                                <TextBlock Grid.Column="2" Grid.Row="1" Text="当前值" Margin="10"/>
-
-                                <TextBlock Grid.Column="0" Grid.Row="2" Text="数据库名称" Margin="10"/>
-                                <TextBox x:Name="DatabaseNameBox" Grid.Column="1" Grid.Row="2" Height="18" Width="150" TextChanged="TextChanged"/>
-                                <TextBlock x:Name="DatabaseNameCu" Grid.Column="2" Grid.Row="2" Text="DatabaseName" Margin="10"/>
-
-                                <TextBlock Grid.Column="0" Grid.Row="3" Text="数据库副标题" Margin="10"/>
-                                <TextBox x:Name="DatabaseSubtitleBox" Grid.Column="1" Grid.Row="3" Height="18" Width="150" TextChanged="TextChanged"/>
-                                <TextBlock x:Name="DatabaseSubtitleCu" Grid.Column="2" Grid.Row="3" Text="DatabaseSubtitle" Margin="10"/>
-
-                                <TextBlock Grid.Column="0" Grid.Row="4" Text="欢迎标题" Margin="10"/>
-                                <TextBox x:Name="WelcomeTitleBox" Grid.Column="1" Grid.Row="4" Height="18" Width="150" TextChanged="TextChanged"/>
-                                <TextBlock x:Name="WelcomeTitleCu" Grid.Column="2" Grid.Row="4" Text="WelcomeTitle" Margin="10"/>
-
-                                <TextBlock Grid.Column="0" Grid.Row="5" Text="用户名" Margin="10"/>
-                                <TextBox x:Name="UsernameBox" Grid.Column="1" Grid.Row="5" Height="18" Width="150" TextChanged="TextChanged"/>
-                                <TextBlock x:Name="UsernameCu" Grid.Column="2" Grid.Row="5" Text="Username" Margin="10"/>
-
-                                <TextBlock Grid.Column="0" Grid.Row="6" Text="数据库密码★" Margin="10"/>
-                                <TextBox x:Name="PasswordBox" Grid.Column="1" Grid.Row="6" Height="18" Width="150" TextChanged="TextChanged"/>
-                                <TextBlock x:Name="PasswordCu" Grid.Column="2" Grid.Row="6" Text="Password" Margin="10"/>
-
-                                <Button x:Name="settingSaveButton1" Grid.Column="0" Grid.Row="100" Content="保存" HorizontalAlignment="Center" VerticalAlignment="Center" Width="50" Height="20" Click="Button_Click" IsEnabled="False"/>
+                                <ScrollViewer Grid.ColumnSpan="3" Grid.Row="1">
+                                    <Grid>
+                                        <Grid.ColumnDefinitions>
+                                            <ColumnDefinition Width="Auto" />
+                                            <ColumnDefinition Width="Auto" />
+                                            <ColumnDefinition Width="Auto" />
+                                        </Grid.ColumnDefinitions>
+                                        <Grid.RowDefinitions>
+                                            <RowDefinition Height="Auto" />
+                                            <RowDefinition Height="Auto" />
+                                            <RowDefinition Height="Auto" />
+                                            <RowDefinition Height="Auto" />
+                                            <RowDefinition Height="Auto" />
+                                            <RowDefinition Height="Auto" />
+                                            <RowDefinition Height="Auto" />
+                                            <RowDefinition Height="30" />
+                                            <RowDefinition Height="Auto" />
+                                            <RowDefinition Height="Auto" />
+                                            <RowDefinition Height="Auto" />
+                                            <RowDefinition Height="Auto" />
+                                            <RowDefinition Height="Auto" />
+                                            <RowDefinition Height="Auto" />
+                                            <RowDefinition Height="Auto" />
+                                            <RowDefinition Height="Auto" />
+                                        </Grid.RowDefinitions>
+                                        <Button x:Name="settingSaveButton0" Grid.Column="0" Grid.Row="1" Content="保存" HorizontalAlignment="Center" VerticalAlignment="Center" Width="50" Height="20" Click="Button_Click" IsEnabled="False"/>
+                                        <TextBlock Grid.Column="1" Grid.Row="1" Text="提示:若无更改则留空" Margin="10" Foreground="Gray"/>
+                                        <TextBlock Grid.Column="2" Grid.Row="1" Text="当前值" Margin="10"/>
+
+                                        <TextBlock Grid.Column="0" Grid.Row="2" Text="数据库名称" Margin="10" HorizontalAlignment="Right"/>
+                                        <TextBox x:Name="DatabaseNameBox" Grid.Column="1" Grid.Row="2" Height="18" Width="150" TextChanged="TextChanged"/>
+                                        <TextBlock x:Name="DatabaseNameCu" Grid.Column="2" Grid.Row="2" Text="DatabaseName" Margin="10"/>
+
+                                        <TextBlock Grid.Column="0" Grid.Row="3" Text="数据库副标题" Margin="10" HorizontalAlignment="Right"/>
+                                        <TextBox x:Name="DatabaseSubtitleBox" Grid.Column="1" Grid.Row="3" Height="18" Width="150" TextChanged="TextChanged"/>
+                                        <TextBlock x:Name="DatabaseSubtitleCu" Grid.Column="2" Grid.Row="3" Text="DatabaseSubtitle" Margin="10"/>
+
+                                        <TextBlock Grid.Column="0" Grid.Row="4" Text="欢迎标题" Margin="10" HorizontalAlignment="Right"/>
+                                        <TextBox x:Name="WelcomeTitleBox" Grid.Column="1" Grid.Row="4" Height="18" Width="150" TextChanged="TextChanged"/>
+                                        <TextBlock x:Name="WelcomeTitleCu" Grid.Column="2" Grid.Row="4" Text="WelcomeTitle" Margin="10"/>
+
+                                        <TextBlock Grid.Column="0" Grid.Row="5" Text="用户名" Margin="10" HorizontalAlignment="Right"/>
+                                        <TextBox x:Name="UsernameBox" Grid.Column="1" Grid.Row="5" Height="18" Width="150" TextChanged="TextChanged"/>
+                                        <TextBlock x:Name="UsernameCu" Grid.Column="2" Grid.Row="5" Text="Username" Margin="10"/>
+
+                                        <TextBlock Grid.Column="0" Grid.Row="6" Text="★数据库密码" Margin="10" HorizontalAlignment="Right"/>
+                                        <TextBox x:Name="PasswordBox" Grid.Column="1" Grid.Row="6" Height="18" Width="150" TextChanged="TextChanged"/>
+                                        <TextBlock x:Name="PasswordCu" Grid.Column="2" Grid.Row="6" Text="Password" Margin="10"/>
+
+                                        <TextBlock Grid.Column="0" Grid.Row="8" Text="“级别”候选项" Margin="10" HorizontalAlignment="Right"/>
+                                        <TextBox x:Name="LevelConfigBox" Grid.Column="1" Grid.Row="8" Height="60" Width="150" Text="{Binding TextBoxText, UpdateSourceTrigger=PropertyChanged}" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" TextChanged="TextChanged" Margin="10"/>
+
+                                        <TextBlock Grid.Column="0" Grid.Row="9" Text="“标签”候选项" Margin="10" HorizontalAlignment="Right"/>
+                                        <TextBox x:Name="TagConfigBox" Grid.Column="1" Grid.Row="9" Height="60" Width="150" Text="{Binding TextBoxText, UpdateSourceTrigger=PropertyChanged}" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" TextChanged="TextChanged" Margin="10"/>
+
+                                        <TextBlock Grid.Column="0" Grid.Row="10" Text="“相对关系”候选项" Margin="10" HorizontalAlignment="Right"/>
+                                        <TextBox x:Name="RSConfigBox" Grid.Column="1" Grid.Row="10" Height="60" Width="150" Text="{Binding TextBoxText, UpdateSourceTrigger=PropertyChanged}" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" TextChanged="TextChanged" Margin="10"/>
+
+                                        <TextBlock Grid.Column="0" Grid.Row="11" Text="“籍贯”候选项" Margin="10" HorizontalAlignment="Right"/>
+                                        <TextBox x:Name="BPConfigBox" Grid.Column="1" Grid.Row="11" Height="60" Width="150" Text="{Binding TextBoxText, UpdateSourceTrigger=PropertyChanged}" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" TextChanged="TextChanged" Margin="10"/>
+
+                                        <Button x:Name="settingSaveButton1" Grid.Column="0" Grid.Row="100" Content="保存" HorizontalAlignment="Center" VerticalAlignment="Center" Width="50" Height="20" Click="Button_Click" IsEnabled="False"/>
+                                    </Grid>
+                                </ScrollViewer>
                             </Grid>
                         </TabItem>
                         <TabItem Header="关于">
@@ -156,7 +208,7 @@
             </TabItem>
             <TabItem Header="综合查询">
                 <TabControl>
-                    <TabItem Header="关系人" Height="18">
+                    <TabItem Header="关系人">
                         <Grid>
                             <Grid.RowDefinitions>
                                 <RowDefinition Height="Auto" />
@@ -170,7 +222,7 @@
                                 <TextBox x:Name="pSearchBox" Grid.Column="0" Width="150" Height="20" Margin="10" HorizontalAlignment="Left"/>
                                 <Button x:Name="pSearchButton" Grid.Column="1" Width="60" Height="20" Margin="10" Content="搜索" Click="pSearchButton_Click" HorizontalAlignment="Left"/>
                             </Grid>
-                            <DataGrid x:Name="pSearchdataGrid" Grid.Row="1" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible" IsReadOnly="True" Margin="10">
+                            <DataGrid x:Name="pSearchdataGrid" Grid.Row="1" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" IsReadOnly="True" Margin="10">
                                 <DataGrid.Columns>
                                     <DataGridTextColumn Header="姓名" Binding="{Binding Name}" Width="Auto"/>
                                     <DataGridTextColumn Header="性别" Binding="{Binding Gender}" Width="Auto"/>
@@ -202,12 +254,33 @@
                             </DataGrid>
                         </Grid>
                     </TabItem>
+                    <TabItem Header="日志">
+                        <Grid>
+                            <Grid.RowDefinitions>
+                                <RowDefinition Height="Auto" />
+                                <RowDefinition Height="*" />
+                            </Grid.RowDefinitions>
+                            <Grid Grid.Row="0">
+                                <Grid.ColumnDefinitions>
+                                    <ColumnDefinition Width="auto" />
+                                    <ColumnDefinition Width="auto" />
+                                </Grid.ColumnDefinitions>
+                                <TextBox Grid.Column="0" Width="150" Height="20" Margin="10" HorizontalAlignment="Left" Name="SearchTextBox" />
+                                <Button Grid.Column="1" Width="60" Height="20" Margin="10" Content="搜索" Click="SearchButton_Click" HorizontalAlignment="Left" />
+                            </Grid>
+                            <DataGrid Grid.Row="1" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" VerticalScrollBarVisibility="Auto" IsReadOnly="True" Margin="10" Name="ResultDataGrid">
+                                <DataGrid.Columns>
+                                    <DataGridTextColumn Header="日期" Width="*" Binding="{Binding}" />
+                                </DataGrid.Columns>
+                            </DataGrid>
+                        </Grid>
+                    </TabItem>
                 </TabControl>
             </TabItem>
             <TabItem Header="关系人">
                 <TabControl>
                     <TabItem Header="列表">
-                        <DataGrid x:Name="dataGrid" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible" IsReadOnly="True">
+                        <DataGrid x:Name="dataGrid" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" IsReadOnly="True">
                             <DataGrid.Columns>
                                 <DataGridTextColumn Header="姓名" Binding="{Binding Name}" Width="Auto"/>
                                 <DataGridTextColumn Header="性别" Binding="{Binding Gender}" Width="Auto"/>
@@ -315,27 +388,14 @@
                                     <DatePicker x:Name="dpBirthDate" Grid.Column="2" Grid.Row="1" Height="25" Width="156" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5" Text="1900/1/1"/>
 
                                     <TextBlock Grid.Column="1" Grid.Row="3" Text="级别" Margin="5" VerticalAlignment="Center" HorizontalAlignment="Right"/>
-                                    <ComboBox x:Name="cmbLevel" Grid.Column="2" Grid.Row="3" Height="20" Width="156" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5">
-                                        <ComboBoxItem>0x00|陌生人</ComboBoxItem>
-                                        <ComboBoxItem>0x7F|老死不相往来</ComboBoxItem>
-                                        <ComboBoxItem>1x00|认识的人</ComboBoxItem>
-                                        <ComboBoxItem>1x01|亲属</ComboBoxItem>
-                                        <ComboBoxItem>2x00|熟人</ComboBoxItem>
-                                        <ComboBoxItem>2x01|朋友</ComboBoxItem>
-                                        <ComboBoxItem>2x02|好朋友</ComboBoxItem>
-                                        <ComboBoxItem>2x05|近亲属</ComboBoxItem>
-                                        <ComboBoxItem>3x00|直系亲属</ComboBoxItem>
-                                        <ComboBoxItem>3x01|知己</ComboBoxItem>
-                                        <ComboBoxItem>4x00|爱人</ComboBoxItem>
-                                        <ComboBoxItem>4x01|子女</ComboBoxItem>
-                                    </ComboBox>
-                                    <Button Grid.Column="3" Grid.Row="3" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5" Background="White">
+                                    <ComboBox x:Name="cmbLevel" Grid.Column="2" Grid.Row="3" Height="20" Width="156" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5"/>
+                                    <Button Grid.Column="3" Grid.Row="3" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5" Background="White" Click="LoadLevels_Click">
                                         <Image Source="Resources/refresh_16px.png"></Image>
                                     </Button>
 
                                     <TextBlock Grid.Column="5" Grid.Row="3" Text="标签" Margin="5" VerticalAlignment="Center" HorizontalAlignment="Right"/>
                                     <ComboBox x:Name="cmbTag" Grid.Column="6" Grid.Row="3" Height="20" Width="156" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5"/>
-                                    <Button Grid.Column="7" Grid.Row="3" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5" Background="White">
+                                    <Button Grid.Column="7" Grid.Row="3" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5" Background="White" Click="LoadTags_Click">
                                         <Image Source="Resources/refresh_16px.png"></Image>
                                     </Button>
 
@@ -354,7 +414,7 @@
 
                                     <TextBlock Grid.Column="1" Grid.Row="6" Text="籍贯" Margin="5" VerticalAlignment="Center" HorizontalAlignment="Right"/>
                                     <ComboBox x:Name="cmbBirthplace" Grid.Column="2" Grid.Row="6" Height="20" Width="156" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5"/>
-                                    <Button Grid.Column="3" Grid.Row="6" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5" Background="White">
+                                    <Button Grid.Column="3" Grid.Row="6" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5" Background="White" Click="LoadBirthplaces_Click">
                                         <Image Source="Resources/refresh_16px.png"></Image>
                                     </Button>
 
@@ -394,7 +454,7 @@
 
                                     <TextBlock Grid.Column="5" Grid.Row="11" Text="相对身份" Margin="5" VerticalAlignment="Top" HorizontalAlignment="Right"/>
                                     <ComboBox x:Name="cmbRelativeStatus" Grid.Column="6" Grid.Row="11" Height="20" Width="156" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="5"/>
-                                    <Button Grid.Column="7" Grid.Row="11" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="5" Background="White">
+                                    <Button Grid.Column="7" Grid.Row="11" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="5" Background="White" Click="LoadRelativeStatuss_Click">
                                         <Image Source="Resources/refresh_16px.png"></Image>
                                     </Button>
 
@@ -448,9 +508,29 @@
                     </TabItem>
                 </TabControl>
             </TabItem>
-            <TabItem Header="日志" IsEnabled="False">
+            <TabItem Header="日志">
                 <Grid>
-
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition Width="200"/>
+                        <ColumnDefinition Width="*"/>
+                    </Grid.ColumnDefinitions>
+                    <Grid.RowDefinitions>
+                        <RowDefinition Height="*"/>
+                        <RowDefinition Height="Auto"/>
+                    </Grid.RowDefinitions>
+
+                    <Grid Grid.Column="0">
+                        <Grid.RowDefinitions>
+                            <RowDefinition Height="Auto"/>
+                            <RowDefinition Height="Auto"/>
+                        </Grid.RowDefinitions>
+                        <Calendar Grid.Row="0" Name="MyCalendar" SelectedDatesChanged="MyCalendar_DisplayDateChanged"/>
+                        <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right" Margin="10">
+                            <Button Name="SaveButton" Content="保存" Click="LogSaveButton_Click" Width="80" Margin="5"/>
+                            <Button Name="DeleteButton" Content="删除" Click="LogDeleteButton_Click" Width="80" Margin="5"/>
+                        </StackPanel>
+                    </Grid>
+                    <RichTextBox Grid.Column="1" Grid.Row="0" Name="MyRichTextBox" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" />
                 </Grid>
             </TabItem>
         </TabControl>

+ 303 - 9
MainWindow.xaml.cs

@@ -2,6 +2,7 @@
 using System.Reflection;
 using System.Windows;
 using System.Windows.Controls;
+using System.Windows.Documents;
 using System.Windows.Media.Imaging;
 using Microsoft.Win32;
 
@@ -17,8 +18,22 @@ namespace ArchivesCenter3
             InitializeComponent();
             updateinfo();
             LoadFileContent();
+            levelitemupdate();
+            tagitemupdate();
+            Birthplaceitemupdate();
+            RelativeStatusitemupdate();
+            Load4Config();
+            MyCalendar.DisplayDate = DateTime.Today;
+            MyCalendar.SelectedDate = DateTime.Today;
             Version version = Assembly.GetExecutingAssembly().GetName().Version;
-            versionTextBlock.Text = $"版本号:{version.Major}.{version.Minor}.{version.Build}";
+            versionTextBlock.Text = $"版本号:{version.Major}.{version.Minor}.{version.Build}"; 
+            DateTime tomorrow = DateTime.Today.AddDays(1);
+
+            // 创建一个从明天开始到最大日期的不可选日期范围
+            CalendarDateRange blackoutRange = new CalendarDateRange(tomorrow, DateTime.MaxValue);
+
+            // 将该范围添加到 Calendar 的 BlackoutDates 集合中
+            MyCalendar.BlackoutDates.Add(blackoutRange);
         }
 
         private List<string> lines; // 存储文件内容的列表
@@ -27,7 +42,7 @@ namespace ArchivesCenter3
 
         private void updateinfo()
         {
-            welcomeText.Text = "欢迎!" + Settings1.Default.Username + "         ";
+            welcomeText.Text = "欢迎!" + Settings1.Default.Username;
             WelcomeTitle.Text = Settings1.Default.WelcomeTitle;
             DatabaseName.Text = Settings1.Default.DatabaseName;
             DatabaseSubtitle.Text = Settings1.Default.DatabaseSubtitle;
@@ -61,6 +76,17 @@ namespace ArchivesCenter3
                 Settings1.Default.Password = PasswordBox.Text;
             Settings1.Default.Save();
             updateinfo();
+            string baseDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
+            string levelConfigPath = Path.Combine(baseDir, "ArchivesCenter", "config", "level.config");
+            string tagConfigPath = Path.Combine(baseDir, "ArchivesCenter", "config", "tag.config");
+            string relativeStatusConfigPath = Path.Combine(baseDir, "ArchivesCenter", "config", "relativeStatus.config");
+            string birthplaceConfigPath = Path.Combine(baseDir, "ArchivesCenter", "config", "birthplace.config");
+
+            // 保存配置文件内容
+            File.WriteAllText(levelConfigPath, LevelConfigBox.Text);
+            File.WriteAllText(tagConfigPath, TagConfigBox.Text);
+            File.WriteAllText(relativeStatusConfigPath, RSConfigBox.Text);
+            File.WriteAllText(birthplaceConfigPath, BPConfigBox.Text);
         }
 
         private void TextChanged(object sender, TextChangedEventArgs e)
@@ -69,6 +95,10 @@ namespace ArchivesCenter3
                              string.IsNullOrWhiteSpace(DatabaseSubtitleBox.Text) &&
                              string.IsNullOrWhiteSpace(WelcomeTitleBox.Text) &&
                              string.IsNullOrWhiteSpace(UsernameBox.Text) &&
+                             string.IsNullOrWhiteSpace(LevelConfigBox.Text) &&
+                             string.IsNullOrWhiteSpace(TagConfigBox.Text) &&
+                             string.IsNullOrWhiteSpace(RSConfigBox.Text) &&
+                             string.IsNullOrWhiteSpace(BPConfigBox.Text) &&
                              string.IsNullOrWhiteSpace(PasswordBox.Text);
             settingSaveButton0.IsEnabled = !allTextBoxesEmpty;
             settingSaveButton1.IsEnabled = !allTextBoxesEmpty;
@@ -80,7 +110,7 @@ namespace ArchivesCenter3
             // 获取用户文档文件夹路径
             string userDocumentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
             // 构建目标文件路径
-            string filePath = Path.Combine(userDocumentsPath, "ArchivesCenter", "data", "people", "content.txt");
+            string filePath = Path.Combine(userDocumentsPath, "ArchivesCenter", "data", "people", "content.info");
 
             // 检查文件是否存在
             if (File.Exists(filePath))
@@ -304,7 +334,7 @@ namespace ArchivesCenter3
             // 获取用户文档文件夹路径
             string userDocumentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
             // 构建目标文件路径
-            string filePath = Path.Combine(userDocumentsPath, "ArchivesCenter", "data", "people", "content.txt");
+            string filePath = Path.Combine(userDocumentsPath, "ArchivesCenter", "data", "people", "content.info");
 
             // 确保目标文件夹存在
             string directoryPath = Path.GetDirectoryName(filePath);
@@ -385,7 +415,7 @@ namespace ArchivesCenter3
                 bitmap.EndInit();
                 imgPhoto.Source = bitmap;
 
-                // 如果当前行存在,更新文件路径到 content.txt 文件
+                // 如果当前行存在,更新文件路径到 content.info 文件
                 if (currentIndex >= 0 && currentIndex < lines.Count)
                 {
                     string[] parts = lines[currentIndex].Split(new string[] { "**" }, StringSplitOptions.None);
@@ -408,7 +438,7 @@ namespace ArchivesCenter3
             // 获取用户文档文件夹路径
             string userDocumentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
             // 构建目标文件路径
-            string filePath = Path.Combine(userDocumentsPath, "ArchivesCenter", "data", "people", "content.txt");
+            string filePath = Path.Combine(userDocumentsPath, "ArchivesCenter", "data", "people", "content.info");
 
             // 确保目标文件夹存在
             string directoryPath = Path.GetDirectoryName(filePath);
@@ -430,6 +460,17 @@ namespace ArchivesCenter3
 
                 if (result == MessageBoxResult.Yes)
                 {
+                    string[] parts = lines[currentIndex].Split(new string[] { "**" }, StringSplitOptions.None);
+
+                    // 检查是否有图片路径,并删除图片文件
+                    if (parts.Length > 26 && !string.IsNullOrEmpty(parts[26]))
+                    {
+                        string photoPath = parts[26];
+                        if (File.Exists(photoPath))
+                        {
+                            File.Delete(photoPath);
+                        }
+                    }
                     // 如果当前处于编辑状态,删除当前行
                     lines.RemoveAt(currentIndex);
                     // 保存文件内容
@@ -459,14 +500,14 @@ namespace ArchivesCenter3
             string searchContent = pSearchBox.Text.Trim(); // 获取搜索框中的内容
             if (string.IsNullOrEmpty(searchContent))
             {
-                MessageBox.Show("请输入搜索内容!");
+                MessageBox.Show("请输入搜索内容!", "Archives Center", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                 return;
             }
 
             // 获取用户文档文件夹路径
             string userDocumentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
             // 构建目标文件路径
-            string filePath = Path.Combine(userDocumentsPath, "ArchivesCenter", "data", "people", "content.txt");
+            string filePath = Path.Combine(userDocumentsPath, "ArchivesCenter", "data", "people", "content.info");
 
             if (File.Exists(filePath))
             {
@@ -519,7 +560,260 @@ namespace ArchivesCenter3
             }
             else
             {
-                MessageBox.Show("未找到数据文件!");
+                MessageBox.Show("未找到数据文件!", "Archives Center", MessageBoxButton.OK, MessageBoxImage.Error);
+            }
+        }
+
+        private void LoadLevels_Click(object sender, RoutedEventArgs e)
+        {
+            levelitemupdate();
+        }
+
+        private void levelitemupdate()
+        {
+            string userDocumentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
+            string filePath = Path.Combine(userDocumentsPath, "ArchivesCenter", "config", "level.config");
+            string directoryPath = Path.GetDirectoryName(filePath);
+            if (!Directory.Exists(directoryPath))
+            {
+                Directory.CreateDirectory(directoryPath);
+            }
+            if (!File.Exists(filePath))
+                File.Create(filePath).Close();
+            string[] lines = File.ReadAllLines(filePath);
+            cmbLevel.Items.Clear();
+            foreach (string line in lines)
+            {
+                cmbLevel.Items.Add(line);
+            }
+        }
+
+        private void LoadTags_Click(object sender, RoutedEventArgs e)
+        {
+            tagitemupdate();
+        }
+
+        private void tagitemupdate()
+        {
+            string userDocumentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
+            string filePath = Path.Combine(userDocumentsPath, "ArchivesCenter", "config", "tag.config");
+            string directoryPath = Path.GetDirectoryName(filePath);
+            if (!Directory.Exists(directoryPath))
+            {
+                Directory.CreateDirectory(directoryPath);
+            }
+            if (!File.Exists(filePath))
+                File.Create(filePath).Close();
+            string[] lines = File.ReadAllLines(filePath);
+            cmbTag.Items.Clear();
+            foreach (string line in lines)
+            {
+                cmbTag.Items.Add(line);
+            }
+        }
+
+        private void LoadBirthplaces_Click(object sender, RoutedEventArgs e)
+        {
+            Birthplaceitemupdate();
+        }
+
+        private void Birthplaceitemupdate()
+        {
+            string userDocumentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
+            string filePath = Path.Combine(userDocumentsPath, "ArchivesCenter", "config", "birthplace.config");
+            string directoryPath = Path.GetDirectoryName(filePath);
+            if (!Directory.Exists(directoryPath))
+            {
+                Directory.CreateDirectory(directoryPath);
+            }
+            if (!File.Exists(filePath))
+                File.Create(filePath).Close();
+            string[] lines = File.ReadAllLines(filePath);
+            cmbBirthplace.Items.Clear();
+            foreach (string line in lines)
+            {
+                cmbBirthplace.Items.Add(line);
+            }
+        }
+
+        private void LoadRelativeStatuss_Click(object sender, RoutedEventArgs e)
+        {
+            RelativeStatusitemupdate();
+        }
+
+        private void RelativeStatusitemupdate()
+        {
+            string userDocumentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
+            string filePath = Path.Combine(userDocumentsPath, "ArchivesCenter", "config", "relativeStatus.config");
+            string directoryPath = Path.GetDirectoryName(filePath);
+            if (!Directory.Exists(directoryPath))
+            {
+                Directory.CreateDirectory(directoryPath);
+            }
+            if (!File.Exists(filePath))
+                File.Create(filePath).Close();
+            string[] lines = File.ReadAllLines(filePath);
+            cmbRelativeStatus.Items.Clear();
+            foreach (string line in lines)
+            {
+                cmbRelativeStatus.Items.Add(line);
+            }
+        }
+
+        private void Load4Config()
+        {
+            // 定义配置文件路径
+            string baseDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
+            string levelConfigPath = Path.Combine(baseDir, "ArchivesCenter", "config", "level.config");
+            string tagConfigPath = Path.Combine(baseDir, "ArchivesCenter", "config", "tag.config");
+            string relativeStatusConfigPath = Path.Combine(baseDir, "ArchivesCenter", "config", "relativeStatus.config");
+            string birthplaceConfigPath = Path.Combine(baseDir, "ArchivesCenter", "config", "birthplace.config");
+
+            // 读取配置文件内容
+            LevelConfigBox.Text = File.Exists(levelConfigPath) ? File.ReadAllText(levelConfigPath) : string.Empty;
+            TagConfigBox.Text = File.Exists(tagConfigPath) ? File.ReadAllText(tagConfigPath) : string.Empty;
+            RSConfigBox.Text = File.Exists(relativeStatusConfigPath) ? File.ReadAllText(relativeStatusConfigPath) : string.Empty;
+            BPConfigBox.Text = File.Exists(birthplaceConfigPath) ? File.ReadAllText(birthplaceConfigPath) : string.Empty;
+        }
+
+        private void MyCalendar_DisplayDateChanged(object sender, SelectionChangedEventArgs e)
+        {
+            // 获取用户文档库路径
+            string userDocumentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
+            string archivesPath = Path.Combine(userDocumentsPath, "ArchivesCenter", "data", "log");
+
+            // 获取选中的日期
+            DateTime selectedDate = MyCalendar.SelectedDate.Value;
+
+            // 格式化日期为文件夹名称(例如:2025-02-13)
+            string dateFolderName = selectedDate.ToString("yyyy-MM-dd");
+            string dateFolderPath = Path.Combine(archivesPath, dateFolderName);
+
+            // 检查日期文件夹是否存在
+            if (Directory.Exists(dateFolderPath))
+            {
+                // 如果存在,读取content.txt文件
+                string contentFilePath = Path.Combine(dateFolderPath, "content.txt");
+                if (File.Exists(contentFilePath))
+                {
+                    // 读取文件内容到RichTextBox
+                    string content = File.ReadAllText(contentFilePath);
+                    MyRichTextBox.Document.Blocks.Clear();
+                    MyRichTextBox.Document.Blocks.Add(new Paragraph(new Run(content)));
+                }
+            }
+            else
+            {
+                // 如果不存在,创建文件夹和content.txt文件
+                Directory.CreateDirectory(dateFolderPath);
+                string contentFilePath = Path.Combine(dateFolderPath, "content.txt");
+                File.WriteAllText(contentFilePath, ""); // 创建空文件
+                MyRichTextBox.Document.Blocks.Clear();
+            }
+        }
+
+        private void LogSaveButton_Click(object sender, RoutedEventArgs e)
+        {
+            // 获取用户文档库路径
+            string userDocumentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
+            string archivesPath = Path.Combine(userDocumentsPath, "ArchivesCenter", "data", "log");
+
+            // 获取选中的日期
+            DateTime selectedDate = MyCalendar.SelectedDate.Value;
+
+            // 格式化日期为文件夹名称(例如:2025-02-13)
+            string dateFolderName = selectedDate.ToString("yyyy-MM-dd");
+            string dateFolderPath = Path.Combine(archivesPath, dateFolderName);
+
+            // 获取content.txt文件路径
+            string contentFilePath = Path.Combine(dateFolderPath, "content.txt");
+
+            // 获取RichTextBox中的内容
+            TextRange textRange = new TextRange(MyRichTextBox.Document.ContentStart, MyRichTextBox.Document.ContentEnd);
+            string content = textRange.Text;
+
+            // 将内容写入文件
+            File.WriteAllText(contentFilePath, content);
+
+            MessageBox.Show("保存成功!", "Archives Center", MessageBoxButton.OK, MessageBoxImage.Information);
+        }
+
+        private void LogDeleteButton_Click(object sender, RoutedEventArgs e)
+        {
+            // 获取用户文档库路径
+            string userDocumentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
+            string archivesPath = Path.Combine(userDocumentsPath, "ArchivesCenter", "data", "log");
+
+            // 获取选中的日期
+            DateTime selectedDate = MyCalendar.SelectedDate.Value;
+
+            // 格式化日期为文件夹名称(例如:2025-02-13)
+            string dateFolderName = selectedDate.ToString("yyyy-MM-dd");
+            string dateFolderPath = Path.Combine(archivesPath, dateFolderName);
+
+            // 检查文件夹是否存在
+            if (Directory.Exists(dateFolderPath))
+            {
+                // 删除文件夹及其内容
+                Directory.Delete(dateFolderPath, true);
+
+                MessageBox.Show("文件夹已删除!", "Archives Center", MessageBoxButton.OK, MessageBoxImage.Information);
+            }
+            else
+            {
+                MessageBox.Show("该日期文件夹不存在!", "Archives Center", MessageBoxButton.OK, MessageBoxImage.Error);
+            }
+        }
+
+        private void SearchButton_Click(object sender, RoutedEventArgs e)
+        {
+            // 获取用户文档库路径
+            string userDocumentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
+            string archivesPath = Path.Combine(userDocumentsPath, "ArchivesCenter", "Data", "Log");
+
+            // 获取搜索内容
+            string searchText = SearchTextBox.Text.Trim();
+
+            // 清空 DataGrid
+            ResultDataGrid.ItemsSource = null;
+            ResultDataGrid.Items.Clear();
+
+            // 如果搜索内容为空,直接返回
+            if (string.IsNullOrEmpty(searchText))
+            {
+                MessageBox.Show("请输入搜索内容!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
+                return;
+            }
+
+            // 遍历所有日期文件夹
+            try
+            {
+                List<string> matchingDates = new List<string>();
+
+                foreach (var dateFolder in Directory.GetDirectories(archivesPath))
+                {
+                    string contentFilePath = Path.Combine(dateFolder, "content.txt");
+
+                    // 检查文件是否存在
+                    if (File.Exists(contentFilePath))
+                    {
+                        string content = File.ReadAllText(contentFilePath);
+
+                        // 检查内容是否包含搜索文本
+                        if (content.Contains(searchText, StringComparison.OrdinalIgnoreCase))
+                        {
+                            string dateFolderName = Path.GetFileName(dateFolder);
+                            matchingDates.Add(dateFolderName);
+                        }
+                    }
+                }
+
+                // 将匹配的日期显示到 DataGrid
+                ResultDataGrid.ItemsSource = matchingDates;
+            }
+            catch (Exception ex)
+            {
+                MessageBox.Show($"搜索失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
             }
         }
     }