調整主體架構 20250324
This commit is contained in:
parent
32d47bcf20
commit
7c86f3b6e3
4
App.xaml
4
App.xaml
@ -1,7 +1,7 @@
|
||||
<Application x:Class="Karaoke_Kingpin.App"
|
||||
<Application x:Class="Karaoke_Kingpin.Controller.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:Karaoke_Kingpin"
|
||||
xmlns:local="clr-namespace:Karaoke_Kingpin.Controller"
|
||||
xmlns:converters="clr-namespace:Karaoke_Kingpin.Converters"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
@ -6,7 +6,7 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace Karaoke_Kingpin
|
||||
namespace Karaoke_Kingpin.Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// App.xaml 的互動邏輯
|
@ -34,8 +34,9 @@ using ExcelDataReader;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Karaoke_Kingpin
|
||||
using Karaoke_Kingpin.Models;
|
||||
using Karaoke_Kingpin.Converters;
|
||||
namespace Karaoke_Kingpin.Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// Index.xaml 的互動邏輯
|
@ -9,7 +9,7 @@ using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Karaoke_Kingpin
|
||||
namespace Karaoke_Kingpin.Controller
|
||||
{
|
||||
public class MainViewModel : INotifyPropertyChanged
|
||||
{
|
@ -16,7 +16,7 @@ using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Karaoke_Kingpin
|
||||
namespace Karaoke_Kingpin.Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// MainWindow.xaml 的互動邏輯
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Karaoke_Kingpin
|
||||
namespace Karaoke_Kingpin.Converters
|
||||
{
|
||||
public class ImagePathConverter : IValueConverter
|
||||
{
|
@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Karaoke_Kingpin
|
||||
namespace Karaoke_Kingpin.Converters
|
||||
{
|
||||
public static class PinyinToZhuyinConverter
|
||||
{
|
36
Index.xaml
36
Index.xaml
@ -1,9 +1,10 @@
|
||||
<Window x:Class="Karaoke_Kingpin.Index"
|
||||
<Window x:Class="Karaoke_Kingpin.Controller.Index"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:Karaoke_Kingpin"
|
||||
xmlns:local="clr-namespace:Karaoke_Kingpin.Controller"
|
||||
xmlns:converters="clr-namespace:Karaoke_Kingpin.Converters"
|
||||
xmlns:properties="clr-namespace:Karaoke_Kingpin.Properties"
|
||||
mc:Ignorable="d"
|
||||
Title="Index" Height="800" Width="950"
|
||||
@ -70,7 +71,7 @@
|
||||
<Rectangle Width="16" Height="16" Fill="{Binding}" />
|
||||
</DataTemplate>
|
||||
|
||||
<local:ImagePathConverter x:Key="ImagePathConverter"/>
|
||||
<converters:ImagePathConverter x:Key="ImagePathConverter"/>
|
||||
</Window.Resources>
|
||||
<!-- 资源定义结束 -->
|
||||
|
||||
@ -378,35 +379,6 @@
|
||||
</Grid>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
<TabItem Header="包廂設定" Height="19" VerticalAlignment="Top">
|
||||
<Grid Background="#F4EAD5">
|
||||
<ItemsControl ItemsSource="{Binding Rooms}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border BorderBrush="Black" BorderThickness="1" Margin="5">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Text="{Binding RoomNumber}" FontWeight="Bold" FontSize="16" HorizontalAlignment="Left" Margin="5,0"/>
|
||||
<TextBlock Text="{Binding Status}" Foreground="Blue" FontSize="14" HorizontalAlignment="Center" Grid.Row="1"/>
|
||||
<TextBlock Text="{Binding TimeRange}" FontSize="14" HorizontalAlignment="Center" Grid.Row="2"/>
|
||||
<Rectangle Fill="Transparent" MouseDown="Rectangle_MouseDown" Grid.Row="0" Grid.RowSpan="3"/>
|
||||
<Rectangle Width="20" Height="10" HorizontalAlignment="Right" VerticalAlignment="Center" Style="{StaticResource StatusRectangleStyle}" Grid.Row="1"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<UniformGrid Columns="5"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
<TabItem Header="歌庫目錄" Height="19" VerticalAlignment="Top">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
|
@ -265,8 +265,8 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Compile Include="ImagePathConverter.cs" />
|
||||
<Compile Include="SongData.cs" />
|
||||
<Compile Include="Converters\ImagePathConverter.cs" />
|
||||
<Compile Include="Models\SongData.cs" />
|
||||
<Page Include="Index.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
@ -275,22 +275,22 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Compile Include="App.xaml.cs">
|
||||
<Compile Include="Controller\App.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="BitmapToImageSourceConverter.cs" />
|
||||
<Compile Include="Index.xaml.cs">
|
||||
<Compile Include="Converters\BitmapToImageSourceConverter.cs" />
|
||||
<Compile Include="Controller\Index.cs">
|
||||
<DependentUpon>Index.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="MainViewModel.cs" />
|
||||
<Compile Include="MainWindow.xaml.cs">
|
||||
<Compile Include="Controller\MainViewModel.cs" />
|
||||
<Compile Include="Controller\MainWindow.cs">
|
||||
<DependentUpon>MainWindow.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="PinyinToZhuyinConverter.cs" />
|
||||
<Compile Include="Converters\PinyinToZhuyinConverter.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<Window x:Class="Karaoke_Kingpin.MainWindow"
|
||||
<Window x:Class="Karaoke_Kingpin.Controller.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:Karaoke_Kingpin"
|
||||
xmlns:local="clr-namespace:Karaoke_Kingpin.Controller"
|
||||
mc:Ignorable="d"
|
||||
Title="卡拉OK後台管理系統設定" Height="600" Width="900">
|
||||
|
||||
|
@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Karaoke_Kingpin
|
||||
namespace Karaoke_Kingpin.Models
|
||||
{
|
||||
public class SongData
|
||||
{
|
@ -1,37 +0,0 @@
|
||||
<Window x:Class="Karaoke_Kingpin.RoomDetailsWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:Karaoke_Kingpin"
|
||||
mc:Ignorable="d"
|
||||
Title="RoomDetailsWindow" Height="200" Width="400">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="70"/>
|
||||
<RowDefinition Height="70"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<StackPanel Grid.Row="0" Grid.ColumnSpan="6" Background="DarkGray">
|
||||
<TextBlock Text="{Binding RoomNumber}" FontSize="20" FontWeight="Bold" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 第一行按钮 -->
|
||||
<Button Content="開機" Margin="10" Click="Start_Click" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"/>
|
||||
<Button Content="關機" Margin="10" Click="Shutdown_Click" Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="2"/>
|
||||
<Button Content="取消" Margin="10" Click="Cancel_Click" Grid.Row="1" Grid.Column="4" Grid.ColumnSpan="2"/>
|
||||
|
||||
<!-- 第二行按钮 -->
|
||||
<Button Content="包廂開帳" Margin="10" Click="OpenAccount_Click" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3"/>
|
||||
<Button Content="包廂關帳" Margin="10" Click="CloseAccount_Click" Grid.Row="2" Grid.Column="3" Grid.ColumnSpan="3"/>
|
||||
</Grid>
|
||||
</Window>
|
@ -1,199 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using System.IO;
|
||||
|
||||
namespace Karaoke_Kingpin
|
||||
{
|
||||
/// <summary>
|
||||
/// RoomDetailsWindow.xaml 的互動邏輯
|
||||
/// </summary>
|
||||
public partial class RoomDetailsWindow : Window
|
||||
{
|
||||
private readonly Room _room;
|
||||
|
||||
private readonly TcpServer _tcpServer;
|
||||
|
||||
public RoomDetailsWindow(Room room, TcpServer tcpServer)
|
||||
{
|
||||
InitializeComponent();
|
||||
_room = room;
|
||||
_tcpServer = tcpServer;
|
||||
DataContext = _room;
|
||||
CenterWindowOnMainWindow();
|
||||
|
||||
// 訂閱 TCP 服務器的命令接收事件
|
||||
_tcpServer.CommandReceived += HandleCommand;
|
||||
}
|
||||
|
||||
|
||||
private void CenterWindowOnMainWindow()
|
||||
{
|
||||
if (Application.Current.MainWindow != null)
|
||||
{
|
||||
this.Owner = Application.Current.MainWindow;
|
||||
this.WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||
}
|
||||
}
|
||||
|
||||
public async void Start_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Console.WriteLine($"=== 開始執行開機操作 ===");
|
||||
string roomNumber = _room.RoomNumber.Substring(1);
|
||||
Console.WriteLine($"房間號碼: {roomNumber}");
|
||||
|
||||
// 保存原始的時間範圍
|
||||
string originalTimeRange = _room.TimeRange;
|
||||
|
||||
await SendTcpSignal(roomNumber, "O");
|
||||
|
||||
// 發送完成後,更新房間狀態
|
||||
_room.Status = "已占用";
|
||||
_room.TimeRange = originalTimeRange;
|
||||
|
||||
// 保存狀態到文件
|
||||
if (Application.Current.MainWindow is MainWindow mainWindow)
|
||||
{
|
||||
mainWindow.SaveRoomsToFile("roomstates.txt");
|
||||
}
|
||||
|
||||
Console.WriteLine($"傳送開機信號 -> 房號: {roomNumber}, 指令: O");
|
||||
Console.WriteLine($"時間範圍: {_room.TimeRange}");
|
||||
Console.WriteLine("=== 開機操作完成 ===\n");
|
||||
}
|
||||
|
||||
public async void Shutdown_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Console.WriteLine($"=== 開始執行關機操作 ===");
|
||||
string roomNumber = _room.RoomNumber.Substring(1);
|
||||
Console.WriteLine($"房間號碼: {roomNumber}");
|
||||
|
||||
await SendTcpSignal(roomNumber, "X");
|
||||
|
||||
// 手動關機時更新狀態
|
||||
_room.Status = "可用";
|
||||
_room.TimeRange = "Not Set";
|
||||
|
||||
// 保存狀態到文件
|
||||
if (Application.Current.MainWindow is MainWindow mainWindow)
|
||||
{
|
||||
mainWindow.SaveRoomsToFile("roomstates.txt");
|
||||
}
|
||||
|
||||
Console.WriteLine($"傳送關機信號 -> 房號: {roomNumber}, 指令: X");
|
||||
Console.WriteLine("=== 關機操作完成 ===\n");
|
||||
}
|
||||
|
||||
// 添加新的方法來處理 TCP 命令
|
||||
private async void HandleCommand(string roomNumber, string command)
|
||||
{
|
||||
await Dispatcher.InvokeAsync(async () =>
|
||||
{
|
||||
if (roomNumber == _room.RoomNumber.Substring(1))
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case "O":
|
||||
await SendTcpSignal(roomNumber, "O");
|
||||
break;
|
||||
case "X":
|
||||
await SendTcpSignal(roomNumber, "X");
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 在窗口關閉時取消訂閱事件
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
base.OnClosed(e);
|
||||
if (_tcpServer != null)
|
||||
{
|
||||
_tcpServer.CommandReceived -= HandleCommand;
|
||||
}
|
||||
}
|
||||
|
||||
private void Cancel_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
MessageBox.Show("取消");
|
||||
}
|
||||
|
||||
private void OpenAccount_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
MessageBox.Show("包廂開帳");
|
||||
}
|
||||
|
||||
private void CloseAccount_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
MessageBox.Show("包廂關帳");
|
||||
}
|
||||
|
||||
private async Task SendTcpSignal(string roomNumber, string command)
|
||||
{
|
||||
int retryInterval = 10000; // 10秒
|
||||
int maxDuration = 20 * 60 * 1000; // 20分鐘
|
||||
int elapsedTime = 0;
|
||||
bool success = false;
|
||||
|
||||
while (elapsedTime < maxDuration && !success)
|
||||
{
|
||||
try
|
||||
{
|
||||
string message = $"{roomNumber},{command}";
|
||||
LogToFile($"嘗試發送: {message}");
|
||||
|
||||
using (TcpClient client = new TcpClient(_room.RoomPC, 1000))
|
||||
{
|
||||
NetworkStream stream = client.GetStream();
|
||||
byte[] data = Encoding.ASCII.GetBytes(message);
|
||||
await stream.WriteAsync(data, 0, data.Length);
|
||||
Console.WriteLine($"房間 {roomNumber} 發送指令: {command}");
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"發送失敗,10秒後重試");
|
||||
if (!success)
|
||||
{
|
||||
await Task.Delay(retryInterval);
|
||||
elapsedTime += retryInterval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
Console.WriteLine($"房間 {roomNumber} 發送指令失敗: 超過20分鐘重試時間");
|
||||
}
|
||||
}
|
||||
|
||||
private void LogToFile(string logMessage)
|
||||
{
|
||||
string logFilePath = "log.txt"; // 你可以根據需要更改文件路徑
|
||||
try
|
||||
{
|
||||
using (StreamWriter writer = new StreamWriter(logFilePath, true))
|
||||
{
|
||||
writer.WriteLine($"{DateTime.Now}: {logMessage}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"寫入日誌失敗: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user