945 lines
36 KiB
Python
945 lines
36 KiB
Python
from sevice.airtight_service import *
|
||
import threading
|
||
|
||
|
||
class State:
|
||
def __init__(self):
|
||
self.selected_record = None # 存储选中的记录
|
||
self.batch_id = 0
|
||
|
||
|
||
s = State()
|
||
# 创建 BatteryDatabase 实例
|
||
battery_db = BatteryDatabase()
|
||
|
||
|
||
def main(page: ft.Page):
|
||
page.title = "监控系统"
|
||
# 添加这行代码,设置应用为中文本地化
|
||
page.locale = "zh-CN"
|
||
page.padding = 0
|
||
page.bgcolor = ft.Colors.TRANSPARENT
|
||
|
||
# 设置滚动条主题
|
||
page.theme = ft.Theme(
|
||
scrollbar_theme=ft.ScrollbarTheme(
|
||
track_color=ft.Colors.BLACK38,
|
||
track_border_color=ft.Colors.GREY_800,
|
||
thumb_color=ft.Colors.BLUE_700,
|
||
# thumb_border_color=ft.Colors.BLUE_900,
|
||
track_visibility=True,
|
||
thumb_visibility=True,
|
||
thickness=10,
|
||
radius=5,
|
||
main_axis_margin=2,
|
||
cross_axis_margin=2,
|
||
)
|
||
)
|
||
threading.Thread(target=start, args=(page,), daemon=True).start()
|
||
|
||
# 设置窗口大小和禁止调整
|
||
page.window.width = 1000
|
||
page.window.height = 700
|
||
page.window.resizable = False
|
||
# page.window.maximizable = False # 禁止最大化按钮
|
||
# page.window.minimizable = False # 保留最小化
|
||
page.update()
|
||
|
||
# -----------------------------------------------------------------------
|
||
def on_message(data_list):
|
||
print('-------------------------')
|
||
if isinstance(data_list, dict) and 'message_type' in data_list:
|
||
if data_list['message_type'] == 'data_130':
|
||
if data_list['payload']:
|
||
data_table_130_update(data_list['payload'])
|
||
elif data_list['message_type'] == 'real_time':
|
||
if data_list['payload']:
|
||
search_real_data(data_list['payload'])
|
||
else:
|
||
print("未知消息格式:", data_list)
|
||
# if data_list:
|
||
# search_real_data(data_list)
|
||
|
||
page.pubsub.subscribe(on_message)
|
||
|
||
|
||
data_table_130 = ft.DataTable(
|
||
width=980, # 表格最小宽度,确保列不挤压
|
||
columns=[
|
||
ft.DataColumn(ft.Text("序号", color=ft.Colors.WHITE, width=20, size=8, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("箱1", color=ft.Colors.WHITE, width=240, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("上面二维码", color=ft.Colors.WHITE, width=110, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("下面二维码", color=ft.Colors.WHITE, width=110, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("H2", color=ft.Colors.WHITE, width=30, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("O2", color=ft.Colors.WHITE, width=30, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("厚度", color=ft.Colors.WHITE, width=40, size=12, no_wrap=False)),
|
||
],
|
||
rows=[
|
||
ft.DataRow(cells=[
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=20)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=240)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=110)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=110)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=30)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=30)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=40)),
|
||
]),
|
||
],
|
||
)
|
||
data_table_130_1 = ft.DataTable(
|
||
width=980, # 表格最小宽度,确保列不挤压
|
||
columns=[
|
||
ft.DataColumn(ft.Text("序号", color=ft.Colors.WHITE, width=20, size=8, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("箱2", color=ft.Colors.WHITE, width=240, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("上面二维码", color=ft.Colors.WHITE, width=110, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("下面二维码", color=ft.Colors.WHITE, width=110, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("H2", color=ft.Colors.WHITE, width=30, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("O2", color=ft.Colors.WHITE, width=30, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("厚度", color=ft.Colors.WHITE, width=40, size=12, no_wrap=False)),
|
||
],
|
||
rows=[
|
||
ft.DataRow(cells=[
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=20)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=240)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=110)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=110)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=30)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=30)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=40)),
|
||
]),
|
||
],
|
||
)
|
||
# 创建文本控件
|
||
dynamic_text = ft.Text("弹夹码", color=ft.Colors.WHITE, size=14)
|
||
# 创建 Row
|
||
content_row = ft.Row([
|
||
dynamic_text
|
||
], alignment=ft.MainAxisAlignment.START)
|
||
|
||
def data_table_130_update(e):
|
||
data_list_130 = e
|
||
data_table_130.rows = []
|
||
data_table_130_1.rows = []
|
||
# 只更新文本内容,不重新定义布局
|
||
dynamic_text.value = data_list_130.get('cah_no', '未知编号')
|
||
for index, item in enumerate(data_list_130['box_data_1']['battery_data_1']):
|
||
data_table_130.rows.append(
|
||
ft.DataRow([
|
||
ft.DataCell(ft.Text(
|
||
str(index + 1),
|
||
color=ft.Colors.WHITE,
|
||
width=20,
|
||
size=12, # 减小字体大小
|
||
no_wrap=False # 允许自动换行
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
data_list_130['box_data_1']['box_data_1_no'],
|
||
color=ft.Colors.WHITE,
|
||
width=240,
|
||
size=10,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
item.get('Below_QR'),
|
||
color=ft.Colors.WHITE,
|
||
width=110,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
item.get('Up_QR'),
|
||
color=ft.Colors.WHITE,
|
||
width=110,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
item.get('H2'),
|
||
color=ft.Colors.WHITE,
|
||
width=30,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
item.get('02'),
|
||
color=ft.Colors.WHITE,
|
||
width=30,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
str(item.get('thick')),
|
||
color=ft.Colors.WHITE,
|
||
width=40,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
])
|
||
)
|
||
data_table_130_1.rows = []
|
||
for index, item in enumerate(data_list_130['box_data_2']['battery_data_2']):
|
||
data_table_130_1.rows.append(
|
||
ft.DataRow([
|
||
ft.DataCell(ft.Text(
|
||
str(index + 1),
|
||
color=ft.Colors.WHITE,
|
||
width=20,
|
||
size=12, # 减小字体大小
|
||
no_wrap=False # 允许自动换行
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
data_list_130['box_data_2']['box_data_2_no'],
|
||
color=ft.Colors.WHITE,
|
||
width=240,
|
||
size=10,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
item.get('Below_QR'),
|
||
color=ft.Colors.WHITE,
|
||
width=110,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
item.get('Up_QR'),
|
||
color=ft.Colors.WHITE,
|
||
width=110,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
item.get('H2'),
|
||
color=ft.Colors.WHITE,
|
||
width=30,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
item.get('02'),
|
||
color=ft.Colors.WHITE,
|
||
width=30,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
str(item.get('thick')),
|
||
color=ft.Colors.WHITE,
|
||
width=40,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
])
|
||
)
|
||
# 更新所有控件
|
||
dynamic_text.update()
|
||
data_table_130.update()
|
||
data_table_130_1.update()
|
||
page0 = ft.SafeArea(
|
||
ft.Column([
|
||
ft.Container(
|
||
content=content_row,
|
||
padding=20,
|
||
margin=ft.Margin(20, 10, 20, 0),
|
||
border=ft.border.all(0.5, ft.Colors.WHITE),
|
||
bgcolor=ft.Colors.BLACK26,
|
||
),
|
||
ft.Container(
|
||
content=ft.Column([ # 使用 Row 来左右布局
|
||
# 左侧表格
|
||
ft.Container(
|
||
content=ft.ListView(
|
||
width=980, # 宽度减半,留出间距
|
||
height=280,
|
||
spacing=0,
|
||
controls=[
|
||
ft.Row(
|
||
scroll=ft.ScrollMode.ALWAYS,
|
||
controls=[data_table_130]
|
||
)
|
||
]
|
||
),
|
||
bgcolor=ft.Colors.BLACK26,
|
||
),
|
||
# 右侧表格
|
||
ft.Container(
|
||
content=ft.ListView(
|
||
width=980,
|
||
height=280,
|
||
spacing=0,
|
||
controls=[
|
||
ft.Row(
|
||
scroll=ft.ScrollMode.ALWAYS,
|
||
controls=[data_table_130_1] # 可以替换为另一个表格
|
||
)
|
||
]
|
||
),
|
||
bgcolor=ft.Colors.BLACK26,
|
||
)
|
||
], scroll=ft.ScrollMode.AUTO), # 如果需要水平滚动
|
||
width=1000,
|
||
margin=ft.Margin(20, 0, 20, 20),
|
||
border=ft.border.all(0.5, ft.Colors.WHITE),
|
||
bgcolor=ft.Colors.BLACK12,
|
||
)
|
||
])
|
||
)
|
||
data_table = ft.DataTable(
|
||
width=900, # 表格最小宽度,确保列不挤压
|
||
columns=[
|
||
ft.DataColumn(ft.Text("序号", color=ft.Colors.WHITE, width=50, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("上面二维码", color=ft.Colors.WHITE, width=150, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("下面二维码", color=ft.Colors.WHITE, width=150, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("H2", color=ft.Colors.WHITE, width=50, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("O2", color=ft.Colors.WHITE, width=50, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("厚度", color=ft.Colors.WHITE, width=50, size=12, no_wrap=False)),
|
||
],
|
||
rows=[
|
||
ft.DataRow(cells=[
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=50)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=150)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=150)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=50)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=50)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=50)),
|
||
]),
|
||
],
|
||
)
|
||
shen7_table = ft.DataTable(
|
||
width=900, # 表格最小宽度,确保列不挤压
|
||
columns=[
|
||
ft.DataColumn(ft.Text("低压损", color=ft.Colors.WHITE, size=12, width=400, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("H2", color=ft.Colors.WHITE, size=12, width=100, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("O2", color=ft.Colors.WHITE, size=12, width=100, no_wrap=False)),
|
||
],
|
||
rows=[
|
||
ft.DataRow(cells=[
|
||
ft.DataCell(ft.Text("", color=ft.Colors.WHITE, width=400)),
|
||
ft.DataCell(ft.Text("", color=ft.Colors.WHITE, width=100)),
|
||
ft.DataCell(ft.Text("", color=ft.Colors.WHITE, width=100)),
|
||
]),
|
||
],
|
||
)
|
||
|
||
def search_real_data(e):
|
||
search_data = e
|
||
shen7_table.rows = []
|
||
data_table.rows = []
|
||
for item in search_data['shen_7']:
|
||
shen7_table.rows.append(
|
||
ft.DataRow([
|
||
ft.DataCell(ft.Text(
|
||
item,
|
||
color=ft.Colors.WHITE,
|
||
width=400,
|
||
size=12, # 减小字体大小
|
||
no_wrap=False # 允许自动换行
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
item[32:34] + '.' + item[34:36],
|
||
color=ft.Colors.WHITE,
|
||
width=100,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
item[36:38] + '.' + item[38:40],
|
||
color=ft.Colors.WHITE,
|
||
width=100,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
])
|
||
)
|
||
shen7_table.update()
|
||
for index, item in enumerate(search_data['all']):
|
||
data_table.rows.append(
|
||
ft.DataRow([
|
||
ft.DataCell(ft.Text(
|
||
str(index + 1),
|
||
color=ft.Colors.WHITE,
|
||
width=50,
|
||
size=12, # 减小字体大小
|
||
no_wrap=False # 允许自动换行
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
item.get('top_qr_code'),
|
||
color=ft.Colors.WHITE,
|
||
width=150,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
item.get('bottom_qr_code'),
|
||
color=ft.Colors.WHITE,
|
||
width=150,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
str(item.get('h2_value')),
|
||
color=ft.Colors.WHITE,
|
||
width=50,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
str (item.get('o2_value')),
|
||
color=ft.Colors.WHITE,
|
||
width=50,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
str(item.get('thickness')),
|
||
color=ft.Colors.WHITE,
|
||
width=50,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
])
|
||
)
|
||
data_table.update()
|
||
|
||
# 实时监控页面内容
|
||
page1 = ft.SafeArea(
|
||
ft.Column([
|
||
ft.Container(
|
||
content=ft.ListView(
|
||
width=1000,
|
||
height=330,
|
||
spacing=0, # 行之间无间距,模拟表格紧凑样式
|
||
# 内层:水平滚动容器(Row),控制表格列的滚动
|
||
controls=[
|
||
ft.Row(
|
||
scroll=ft.ScrollMode.ALWAYS, # 始终显示水平滚动条
|
||
controls=[
|
||
# 表格内容
|
||
shen7_table
|
||
]
|
||
)
|
||
]
|
||
),
|
||
# padding=20,
|
||
margin=ft.Margin(20, 5, 20, 0),
|
||
border=ft.border.all(0.5, ft.Colors.WHITE),
|
||
bgcolor=ft.Colors.BLACK26, # 半透黑色背景,便于在图片上看清
|
||
),
|
||
# 下方表格区域,带白色边框和外边距,宽度与上方保持一致
|
||
ft.Container(
|
||
content=ft.ListView(
|
||
width=1000,
|
||
height=250,
|
||
spacing=0, # 行之间无间距,模拟表格紧凑样式
|
||
# 内层:水平滚动容器(Row),控制表格列的滚动
|
||
controls=[
|
||
ft.Row(
|
||
scroll=ft.ScrollMode.ALWAYS, # 始终显示水平滚动条
|
||
controls=[
|
||
# 表格内容
|
||
data_table
|
||
]
|
||
)
|
||
]
|
||
),
|
||
# padding=20,
|
||
margin=ft.Margin(20, 5, 20, 20),
|
||
border=ft.border.all(0.5, ft.Colors.WHITE),
|
||
bgcolor=ft.Colors.BLACK26, # 半透黑色背景,便于在图片上看清
|
||
)
|
||
])
|
||
)
|
||
|
||
start_date = ft.ElevatedButton(
|
||
"请选择起始日期",
|
||
icon=ft.Icons.CALENDAR_MONTH,
|
||
width=190,
|
||
on_click=lambda e: page.open(
|
||
ft.DatePicker(
|
||
# first_date=datetime(2000, 10, 1),
|
||
# last_date=datetime(2099, 10, 1),
|
||
on_change=handle_change_start,
|
||
on_dismiss=handle_dismissal,
|
||
)
|
||
),
|
||
)
|
||
end_date = ft.ElevatedButton(
|
||
"请选择结束日期",
|
||
icon=ft.Icons.CALENDAR_MONTH,
|
||
width=185,
|
||
on_click=lambda e: page.open(
|
||
ft.DatePicker(
|
||
# first_date=datetime(2000, 10, 1),
|
||
# last_date=datetime(2099, 10, 1),
|
||
on_change=handle_change_end,
|
||
on_dismiss=handle_dismissal,
|
||
)
|
||
),
|
||
)
|
||
histroy_data_table = ft.DataTable(
|
||
width=900, # 表格最小宽度,确保列不挤压
|
||
columns=[
|
||
ft.DataColumn(ft.Text("序号", color=ft.Colors.WHITE, width=50, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("时间", color=ft.Colors.WHITE, width=50, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("查看详情", color=ft.Colors.WHITE, width=50, size=12, no_wrap=False)),
|
||
],
|
||
rows=[
|
||
ft.DataRow(cells=[
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=50)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.GREEN, width=200)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.GREEN, width=100)),
|
||
]),
|
||
],
|
||
)
|
||
|
||
# 查看详情按钮点击事件
|
||
def view_details(e, record):
|
||
s.selected_record = record
|
||
histroy_search_list(record)
|
||
# 切换到详情页面
|
||
current_page.content = page4
|
||
page.update()
|
||
|
||
def histroy_search(e):
|
||
histroy_data_table.rows = []
|
||
start_time = None
|
||
end_time = None
|
||
if start_date.text != '请选择起始日期':
|
||
start_time = start_date.text
|
||
if end_date.text != '请选择结束日期':
|
||
end_time = end_date.text
|
||
print(start_time, end_time)
|
||
full_start_time = f"{start_time} 00:00:00"
|
||
full_end_time = f"{end_time} 23:59:59"
|
||
batches = battery_db.get_batches_by_time_range_with_daily_sort(full_start_time, full_end_time)
|
||
print('batches',batches)
|
||
for index, item in enumerate(batches):
|
||
# 为每条记录创建查看详情按钮
|
||
view_button = ft.ElevatedButton(
|
||
"查看详情",
|
||
icon=ft.Icons.VISIBILITY,
|
||
width=100,
|
||
height=30,
|
||
style=ft.ButtonStyle(
|
||
color=ft.Colors.WHITE,
|
||
bgcolor=ft.Colors.BLUE_600,
|
||
padding=ft.Padding(5, 5, 5, 5),
|
||
),
|
||
on_click=lambda e, record=item['id']: view_details(e, record)
|
||
)
|
||
histroy_data_table.rows.append(
|
||
ft.DataRow([
|
||
ft.DataCell(ft.Text(
|
||
str(index + 1),
|
||
color=ft.Colors.WHITE,
|
||
width=50,
|
||
size=12, # 减小字体大小
|
||
no_wrap=False # 允许自动换行
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
item['created_time'],
|
||
color=ft.Colors.WHITE,
|
||
width=200,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(view_button) # 添加查看详情按钮
|
||
])
|
||
)
|
||
histroy_data_table.update()
|
||
|
||
def handle_change_start(e):
|
||
page.add(ft.Text(f"Date changed: {e.control.value.strftime('%Y-%m-%d')}"))
|
||
start_date.text = e.control.value.strftime('%Y-%m-%d')
|
||
start_date.update()
|
||
|
||
def handle_change_end(e):
|
||
page.add(ft.Text(f"Date changed: {e.control.value.strftime('%Y-%m-%d')}"))
|
||
end_date.text = e.control.value.strftime('%Y-%m-%d')
|
||
end_date.update()
|
||
|
||
def handle_dismissal(e):
|
||
page.add(ft.Text(f"DatePicker dismissed"))
|
||
|
||
# 历史数据页面
|
||
page3 = ft.SafeArea(
|
||
ft.Column([
|
||
# 上方输入框区域,带白色边框和外边距
|
||
ft.Container(
|
||
content=ft.Column([
|
||
ft.Row([
|
||
ft.Row([
|
||
ft.Text("起始日期:", color=ft.Colors.WHITE, size=14, width=80, ),
|
||
start_date
|
||
]),
|
||
ft.Row([
|
||
ft.Text("结束日期:", color=ft.Colors.WHITE, size=14, width=80, ),
|
||
end_date
|
||
]),
|
||
ft.ElevatedButton("查询", icon=ft.Colors.WHITE, width=150, on_click=histroy_search)
|
||
]),
|
||
], spacing=15),
|
||
padding=20,
|
||
margin=ft.Margin(20, 20, 20, 10),
|
||
border=ft.border.all(0.5, ft.Colors.WHITE),
|
||
bgcolor=ft.Colors.BLACK26,
|
||
),
|
||
|
||
# 下方表格区域
|
||
ft.Container(
|
||
content=ft.ListView(
|
||
width=1000,
|
||
height=400,
|
||
spacing=0,
|
||
controls=[
|
||
ft.Row(
|
||
scroll=ft.ScrollMode.ALWAYS,
|
||
controls=[
|
||
histroy_data_table
|
||
]
|
||
)
|
||
]
|
||
),
|
||
padding=20,
|
||
margin=ft.Margin(20, 10, 20, 20),
|
||
border=ft.border.all(0.5, ft.Colors.WHITE),
|
||
bgcolor=ft.Colors.BLACK26,
|
||
)
|
||
])
|
||
)
|
||
DetectionType = ['低压损'] # 1到70
|
||
DetectionType.extend([int(i) for i in range(1, 71)]) # 添加最后一个元素
|
||
|
||
def get_options():
|
||
options = []
|
||
for i in DetectionType:
|
||
# 确保键是字符串类型
|
||
key = str(i)
|
||
options.append(
|
||
ft.DropdownOption(
|
||
key=key,
|
||
content=ft.Text(
|
||
value=key,
|
||
color=ft.Colors.WHITE,
|
||
),
|
||
)
|
||
)
|
||
return options
|
||
def histroy_search_list(e):
|
||
print(e)
|
||
s.batch_id = e
|
||
|
||
histroy_data_item = ft.DataTable(
|
||
width=900, # 表格最小宽度,确保列不挤压
|
||
columns=[
|
||
ft.DataColumn(ft.Text("序号", color=ft.Colors.WHITE, width=50, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("上面二维码", color=ft.Colors.WHITE, width=150, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("下面二维码", color=ft.Colors.WHITE, width=150, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("H2", color=ft.Colors.WHITE, width=50, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("O2", color=ft.Colors.WHITE, width=50, size=12, no_wrap=False)),
|
||
ft.DataColumn(ft.Text("厚度", color=ft.Colors.WHITE, width=50, size=12, no_wrap=False)),
|
||
],
|
||
rows=[
|
||
ft.DataRow(cells=[
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=50)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=150)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=150)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=50)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.WHITE, width=50)),
|
||
ft.DataCell(ft.Text(" ", color=ft.Colors.GREEN, width=50)),
|
||
]),
|
||
],
|
||
)
|
||
|
||
def dropdown_changed(e=None, group_id=None):
|
||
"""下拉列表选择变化事件处理
|
||
|
||
Args:
|
||
e: 事件对象(可选)
|
||
group_id: 直接指定的组ID(可选)
|
||
"""
|
||
# 确定选择的组ID
|
||
selected_group = None
|
||
|
||
if group_id is not None:
|
||
# 如果直接指定了group_id
|
||
selected_group = group_id
|
||
print(f"通过group_id参数传入: {selected_group}, 类型: {type(selected_group)}")
|
||
elif e is not None and hasattr(e, 'control') and hasattr(e.control, 'value'):
|
||
# 如果是通过下拉列表事件触发
|
||
selected_group = e.control.value
|
||
print(f"通过下拉列表事件传入: {selected_group}, 类型: {type(selected_group)}")
|
||
elif e is not None and isinstance(e, dict) and 'data' in e:
|
||
# 如果是通过字典事件触发
|
||
selected_group = e['data']
|
||
print(f"通过字典事件传入: {selected_group}, 类型: {type(selected_group)}")
|
||
elif e is not None and hasattr(e, 'data'):
|
||
# 如果是其他类型的事件对象
|
||
selected_group = e.data
|
||
print(f"通过其他事件传入: {selected_group}, 类型: {type(selected_group)}")
|
||
|
||
if selected_group is None:
|
||
print("没有选择有效的组")
|
||
return
|
||
|
||
print(f"最终选择的组: {selected_group}, 类型: {type(selected_group)}")
|
||
|
||
histroy_data_item.rows = []
|
||
|
||
# 处理组ID(如果是'低压损'则转换为71)
|
||
actual_group_id = 71 if selected_group == '低压损' else selected_group
|
||
print(f"实际查询的组ID: {actual_group_id}, 类型: {type(actual_group_id)}")
|
||
|
||
# 获取组数据
|
||
group_item = battery_db.get_batch_data(int(s.batch_id), actual_group_id)
|
||
|
||
for index, item in enumerate(group_item):
|
||
histroy_data_item.rows.append(
|
||
ft.DataRow([
|
||
ft.DataCell(ft.Text(
|
||
str(index + 1),
|
||
color=ft.Colors.WHITE,
|
||
width=50,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
item.get('top_qr_code'),
|
||
color=ft.Colors.WHITE,
|
||
width=150,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
item.get('bottom_qr_code'),
|
||
color=ft.Colors.WHITE,
|
||
width=150,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
str(item.get('h2_value')),
|
||
color=ft.Colors.WHITE,
|
||
width=50,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
str(item.get('o2_value')),
|
||
color=ft.Colors.WHITE,
|
||
width=50,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
ft.DataCell(ft.Text(
|
||
str(item.get('thickness')),
|
||
color=ft.Colors.WHITE,
|
||
width=50,
|
||
size=12,
|
||
no_wrap=False
|
||
)),
|
||
])
|
||
)
|
||
histroy_data_item.update()
|
||
print(f"加载了 {len(group_item)} 条数据")
|
||
# 在搜索函数中
|
||
dd.value = actual_group_id
|
||
dd.update()
|
||
|
||
dd = ft.Dropdown(
|
||
editable=True,
|
||
label="组次",
|
||
options=get_options(),
|
||
on_change=dropdown_changed,
|
||
bgcolor=ft.Colors.BLUE,
|
||
hint_style=ft.TextStyle(color=ft.Colors.WHITE, italic=True),
|
||
text_style=ft.TextStyle(
|
||
color=ft.Colors.WHITE,
|
||
weight=ft.FontWeight.BOLD,
|
||
size=14,
|
||
),
|
||
)
|
||
|
||
# 返回历史数据页面的函数
|
||
def back_to_history(e):
|
||
dd.value = None
|
||
dd.update()
|
||
histroy_data_item.rows = []
|
||
current_page.content = page3
|
||
page.update()
|
||
|
||
# 创建输入框控件(在适当的位置定义)
|
||
top_qr_input = ft.TextField(
|
||
width=200,
|
||
height=35,
|
||
text_size=16,
|
||
hint_text="上面二维码",
|
||
color=ft.Colors.WHITE,
|
||
content_padding=ft.Padding(5, 5, 5, 5),
|
||
)
|
||
|
||
bottom_qr_input = ft.TextField(
|
||
width=200,
|
||
height=35,
|
||
text_size=16,
|
||
hint_text="下面二维码",
|
||
color=ft.Colors.WHITE,
|
||
content_padding=ft.Padding(5, 5, 5, 5),
|
||
)
|
||
|
||
# 搜索函数
|
||
def search_by_qr_code(e):
|
||
top_qr = top_qr_input.value
|
||
bottom_qr = bottom_qr_input.value
|
||
|
||
if not top_qr and not bottom_qr:
|
||
# 如果没有输入任何二维码,显示提示
|
||
page.snack_bar = ft.SnackBar(content=ft.Text("请输入上面二维码或下面二维码"))
|
||
page.snack_bar.open = True
|
||
page.update()
|
||
return
|
||
|
||
# 调用数据库方法查找对应的组
|
||
matched_groups = battery_db.get_group_by_qr_codes_exact(s.batch_id, top_qr, bottom_qr)
|
||
|
||
if matched_groups:
|
||
# 如果找到匹配的组,跳转到第一个匹配的组
|
||
first_group = matched_groups[0]['group_id']
|
||
|
||
print(f"找到的组ID: {first_group}, 类型: {type(first_group)}") # 调试信息
|
||
|
||
# 设置下拉列表的值(确保转换为字符串)
|
||
|
||
# 直接调用 dropdown_changed 函数,传入组ID(不传事件对象)
|
||
dropdown_changed(group_id=first_group)
|
||
|
||
# 显示成功消息
|
||
if len(matched_groups) > 1:
|
||
page.snack_bar = ft.SnackBar(
|
||
content=ft.Text(f"找到 {len(matched_groups)} 个匹配的组,已跳转到组 {first_group}")
|
||
)
|
||
else:
|
||
page.snack_bar = ft.SnackBar(
|
||
content=ft.Text(f"已跳转到组 {first_group}")
|
||
)
|
||
page.snack_bar.open = True
|
||
page.update()
|
||
else:
|
||
# 没有找到匹配的组
|
||
page.snack_bar = ft.SnackBar(
|
||
content=ft.Text("未找到匹配的组,请检查二维码是否正确")
|
||
)
|
||
page.snack_bar.open = True
|
||
page.update()
|
||
|
||
# 详情页面 (page4)
|
||
# 修改 page4 中的表格容器
|
||
page4 = ft.SafeArea(
|
||
ft.Column([
|
||
ft.Container(
|
||
content=ft.Row([
|
||
ft.ElevatedButton(
|
||
"返回",
|
||
icon=ft.Icons.ARROW_BACK,
|
||
on_click=back_to_history,
|
||
style=ft.ButtonStyle(
|
||
color=ft.Colors.WHITE,
|
||
bgcolor=ft.Colors.BLUE_600,
|
||
)
|
||
),
|
||
dd,
|
||
# 在同一行添加搜索区域
|
||
ft.Text("上面二维码:", color=ft.Colors.WHITE, size=16),
|
||
top_qr_input,
|
||
ft.Text("下面二维码:", color=ft.Colors.WHITE, size=16),
|
||
bottom_qr_input,
|
||
ft.ElevatedButton(
|
||
"搜索",
|
||
icon=ft.Icons.SEARCH,
|
||
width=80,
|
||
on_click=search_by_qr_code
|
||
)
|
||
], alignment=ft.MainAxisAlignment.START, spacing=10),
|
||
padding=20,
|
||
margin=ft.Margin(20, 20, 20, 10),
|
||
border=ft.border.all(0.5, ft.Colors.WHITE),
|
||
bgcolor=ft.Colors.BLACK26,
|
||
),
|
||
|
||
ft.Container(
|
||
content=ft.ListView( # 使用 ListView 包装表格
|
||
width=1000,
|
||
height=430,
|
||
spacing=0,
|
||
controls=[
|
||
ft.Row(
|
||
scroll=ft.ScrollMode.ALWAYS,
|
||
controls=[
|
||
histroy_data_item
|
||
]
|
||
)
|
||
]
|
||
),
|
||
padding=20,
|
||
margin=ft.Margin(20, 0, 20, 20),
|
||
border=ft.border.all(0.5, ft.Colors.WHITE),
|
||
bgcolor=ft.Colors.BLACK26,
|
||
)
|
||
])
|
||
)
|
||
|
||
pages = [page0, page1, page3, page4] # 添加page4到页面列表
|
||
current_page = ft.Container(content=pages[0])
|
||
|
||
def on_nav_change(e):
|
||
if e.control.selected_index < 3: # 只有前三个页面可以通过导航栏访问
|
||
current_page.content = pages[e.control.selected_index]
|
||
page.update()
|
||
|
||
# 导航栏
|
||
page.navigation_bar = ft.CupertinoNavigationBar(
|
||
bgcolor=ft.Colors.BLUE_50,
|
||
inactive_color=ft.Colors.BLUE_GREY_600,
|
||
active_color=ft.Colors.BLUE_800,
|
||
on_change=on_nav_change,
|
||
destinations=[
|
||
ft.NavigationBarDestination(
|
||
icon=ft.Icons.MONITOR_OUTLINED,
|
||
selected_icon=ft.Icons.MONITOR,
|
||
label="上料"
|
||
),
|
||
ft.NavigationBarDestination(
|
||
icon=ft.Icons.MONITOR_OUTLINED,
|
||
selected_icon=ft.Icons.MONITOR,
|
||
label="实时监控"
|
||
),
|
||
ft.NavigationBarDestination(
|
||
icon=ft.Icons.HISTORY_OUTLINED,
|
||
selected_icon=ft.Icons.HISTORY,
|
||
label="历史数据"
|
||
),
|
||
],
|
||
)
|
||
|
||
background_layout = ft.Stack([
|
||
ft.Image(
|
||
src="1.jpg",
|
||
fit=ft.ImageFit.COVER,
|
||
width=1024,
|
||
height=768,
|
||
),
|
||
ft.Container(
|
||
bgcolor=ft.Colors.BLACK12,
|
||
width=page.width,
|
||
height=page.height,
|
||
),
|
||
current_page
|
||
])
|
||
|
||
page.add(background_layout)
|
||
s.page_initialized = True # 页面构建完成,设置初始化标志
|
||
|
||
# 确保这是唯一的 ft.app 调用
|
||
if __name__ == "__main__":
|
||
ft.app(main)
|