TorqueWrench/frontend/admin_panel.py

161 lines
6.2 KiB
Python
Raw Normal View History

2026-03-06 15:27:09 +08:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
管理员面板 - 管理异常工单
"""
import tkinter as tk
from tkinter import ttk, messagebox
import requests
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
class AdminPanel:
"""管理员面板"""
2026-03-18 17:13:20 +08:00
@staticmethod
def translate_status(status):
"""将英文状态转换为中文"""
status_map = {
'pending': '待处理',
'claimed': '已认领',
'completed': '已完成'
}
return status_map.get(status, status)
2026-03-06 15:27:09 +08:00
def __init__(self, root, api_base_url):
self.root = root
self.root.title("管理员面板 - 工单管理")
self.root.geometry("900x600")
if isinstance(root, tk.Toplevel):
self.root.transient(root.master)
self.api_base_url = api_base_url
self.claimed_orders = []
self._create_widgets()
self.load_claimed_orders()
def _create_widgets(self):
"""创建界面"""
# 标题
title_frame = tk.Frame(self.root, bg="#2c3e50", height=60)
title_frame.pack(fill=tk.X)
title_frame.pack_propagate(False)
tk.Label(title_frame, text="管理员面板 - 已认领工单管理", font=("微软雅黑", 18, "bold"), fg="white", bg="#2c3e50").pack(pady=15)
# 工单列表
list_frame = tk.LabelFrame(self.root, text="已认领工单列表", font=("微软雅黑", 12), padx=10, pady=10)
list_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
columns = ("追溯号", "工序号", "工序名称", "操作员", "认领时间", "状态")
self.tree = ttk.Treeview(list_frame, columns=columns, show="headings")
for col in columns:
self.tree.heading(col, text=col)
self.tree.column(col, width=150, anchor=tk.CENTER)
scrollbar = ttk.Scrollbar(list_frame, orient=tk.VERTICAL, command=self.tree.yview)
self.tree.configure(yscrollcommand=scrollbar.set)
self.tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
# 按钮
button_frame = tk.Frame(self.root, padx=10, pady=10)
button_frame.pack(fill=tk.X)
tk.Button(button_frame, text="刷新列表", font=("微软雅黑", 10), bg="#3498db", fg="white", width=12, command=self.load_claimed_orders).pack(side=tk.LEFT, padx=5)
tk.Button(button_frame, text="退领选中工单", font=("微软雅黑", 10), bg="#e67e22", fg="white", width=12, command=self.unclaim_selected).pack(side=tk.LEFT, padx=5)
tk.Button(button_frame, text="批量退领", font=("微软雅黑", 10), bg="#e74c3c", fg="white", width=12, command=self.unclaim_all).pack(side=tk.LEFT, padx=5)
def load_claimed_orders(self):
"""加载已认领工单"""
try:
response = requests.get(f"{self.api_base_url}/work-orders/claimed", timeout=2)
if response.status_code == 200:
data = response.json()
if data.get("success"):
self.claimed_orders = data.get("data", [])
self.update_list()
except Exception as e:
messagebox.showerror("错误", f"加载失败: {e}")
def update_list(self):
"""更新列表"""
self.tree.delete(*self.tree.get_children())
for order in self.claimed_orders:
2026-03-18 17:13:20 +08:00
status = order.get('status', 'claimed')
status_cn = self.translate_status(status)
2026-03-06 15:27:09 +08:00
self.tree.insert("", tk.END, values=(
order.get('trace_id'), order.get('process_id'), order.get('process_name', '--'),
2026-03-18 17:13:20 +08:00
order.get('operator', '--'), order.get('claimed_at', '--'), status_cn
2026-03-06 15:27:09 +08:00
))
def unclaim_selected(self):
"""退领选中工单"""
selected = self.tree.selection()
if not selected:
messagebox.showwarning("警告", "请选择要退领的工单")
return
item = self.tree.item(selected[0])
values = item['values']
trace_id, process_id = values[0], values[1]
if not messagebox.askyesno("确认", f"确定退领工单 {trace_id} - {process_id}"):
return
try:
response = requests.post(f"{self.api_base_url}/work-orders/unclaim", json={"trace_id": trace_id, "process_id": process_id}, timeout=2)
if response.status_code == 200 and response.json().get("success"):
messagebox.showinfo("成功", "退领成功")
self.load_claimed_orders()
except Exception as e:
messagebox.showerror("错误", f"退领失败: {e}")
def unclaim_all(self):
"""批量退领所有工单"""
if not self.claimed_orders:
messagebox.showinfo("提示", "没有需要退领的工单")
return
if not messagebox.askyesno("确认", f"确定退领所有 {len(self.claimed_orders)} 个工单?"):
return
success_count = 0
for order in self.claimed_orders:
try:
requests.post(f"{self.api_base_url}/work-orders/unclaim", json={"trace_id": order['trace_id'], "process_id": order['process_id']}, timeout=2)
success_count += 1
except:
pass
messagebox.showinfo("完成", f"成功退领 {success_count}/{len(self.claimed_orders)} 个工单")
self.load_claimed_orders()
def main():
import json
api_url = "http://localhost:5000/api"
try:
config_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "config.json")
if os.path.exists(config_path):
with open(config_path, "r", encoding="utf-8") as f:
config = json.load(f)
api_url = config.get("api", {}).get("base_url", api_url)
if not api_url.endswith("/api"):
api_url = api_url.rstrip("/") + "/api"
except:
pass
root = tk.Tk()
AdminPanel(root, api_url)
root.mainloop()
if __name__ == "__main__":
main()