200 lines
6.5 KiB
C#
200 lines
6.5 KiB
C#
|
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 KTVApp
|
|||
|
{
|
|||
|
/// <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}");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|