Skip to content

Commit f2463af

Browse files
committed
Merge branch 'master' of https://github.com/SECTL/SecRandom
2 parents 0cb850b + c7fc5ee commit f2463af

23 files changed

Lines changed: 442 additions & 58 deletions

CHANGELOG/v2.3.0-beta.2/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ v2.3 - Shiroko (砂狼白子) beta 2
1515
- 优化 **浮窗**,切换同步收纳显示
1616
- 优化 **计时器**,倒计时页面居中显示,秒表居中与所有时钟字距优化
1717
- 优化 **更新安装**,管理员静默安装并退出
18+
- 优化 **ClassIsland 联动**,现在可以传递更多信息
1819

1920
## 🐛 修复问题
2021

app/common/IPC_URL/csharp_ipc_handler.py

Lines changed: 94 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
import sys
22
import asyncio
33
import threading
4-
from typing import Optional
4+
from typing import Optional, Any, TypedDict
55
from loguru import logger
66

77
from app.tools.path_utils import get_data_path
88

99
CSHARP_AVAILABLE = False
1010

11+
12+
class SelectedStudentNotificationInfo(TypedDict):
13+
student_id: int
14+
student_name: str
15+
display_text: str
16+
exists: bool
17+
group_name: str
18+
lottery_name: str
19+
20+
1121
if sys.platform == "win32":
1222
try:
1323
sys.path.append(str(get_data_path("dlls")))
@@ -31,7 +41,12 @@
3141
GeneratedIpcFactory,
3242
)
3343
from SecRandom4Ci.Interface.Enums import ResultType
34-
from SecRandom4Ci.Interface.Models import CallResult, NotificationData, Student
44+
from SecRandom4Ci.Interface.Models import (
45+
CallResult,
46+
Student,
47+
NotificationData,
48+
NotificationItem,
49+
)
3550
from SecRandom4Ci.Interface.Services import ISecRandomService
3651

3752
CSHARP_AVAILABLE = True
@@ -117,7 +132,7 @@ def stop_ipc_client(self):
117132
def send_notification(
118133
self,
119134
class_name,
120-
selected_students,
135+
selected_students: list[SelectedStudentNotificationInfo],
121136
draw_count=1,
122137
settings=None,
123138
settings_group=None,
@@ -130,6 +145,13 @@ def send_notification(
130145
if not self.is_connected:
131146
return False
132147

148+
coerced_students: list[SelectedStudentNotificationInfo] = []
149+
for student in selected_students or []:
150+
item = self._coerce_student(student)
151+
if item is None:
152+
continue
153+
coerced_students.append(item)
154+
133155
if settings:
134156
display_duration = settings.get("notification_display_duration", 5)
135157
else:
@@ -156,11 +178,11 @@ def send_notification(
156178
result.ClassName = class_name
157179
result.DrawCount = draw_count
158180
result.DisplayDuration = display_duration
159-
for student in selected_students:
181+
for student in coerced_students:
160182
cs_student = Student()
161-
cs_student.StudentId = student[0]
162-
cs_student.StudentName = student[1]
163-
cs_student.Exists = student[2]
183+
cs_student.StudentId = student["student_id"]
184+
cs_student.StudentName = student["display_text"]
185+
cs_student.Exists = student["exists"]
164186
result.SelectedStudents.Add(cs_student)
165187
randomService.NotifyResult(result)
166188

@@ -193,12 +215,16 @@ def send_notification(
193215
data.ClassName = class_name
194216
data.DrawCount = draw_count
195217
data.DisplayDuration = display_duration
196-
for student in selected_students:
197-
cs_student = Student()
198-
cs_student.StudentId = student[0]
199-
cs_student.StudentName = student[1]
200-
cs_student.Exists = student[2]
201-
data.Items.Add(cs_student)
218+
for student in coerced_students:
219+
item = NotificationItem()
220+
item.StudentId = student["student_id"]
221+
item.StudentName = student["student_name"]
222+
item.Exists = student["exists"]
223+
item.HasGroup = bool(student["group_name"])
224+
item.GroupName = student["group_name"]
225+
item.IsLottery = bool(student["lottery_name"])
226+
item.LotteryName = student["lottery_name"]
227+
data.Items.Add(item)
202228

203229
randomService.ShowNotification(data)
204230
return True
@@ -452,6 +478,61 @@ def check_plugin_alive(self) -> bool:
452478
return randomService.IsAlive() == "Yes"
453479
except Exception:
454480
return False
481+
482+
@staticmethod
483+
def _safe_int(value: Any) -> int:
484+
try:
485+
if value is None:
486+
return 0
487+
return int(value)
488+
except Exception:
489+
return 0
490+
491+
def _coerce_student(self, value: Any) -> SelectedStudentNotificationInfo | None:
492+
if isinstance(value, dict):
493+
student_id = self._safe_int(value.get("student_id", value.get("id", 0)))
494+
student_name = str(
495+
value.get("student_name", value.get("name", "")) or ""
496+
)
497+
display_text = str(
498+
value.get(
499+
"display_text", value.get("display", value.get("text", ""))
500+
)
501+
or student_name
502+
)
503+
exists = bool(value.get("exists", value.get("exist", True)))
504+
group_name = str(value.get("group_name", value.get("group", "")) or "")
505+
lottery_name = str(
506+
value.get(
507+
"lottery_name",
508+
value.get(
509+
"lottery",
510+
value.get("prize_name", value.get("prize", "")),
511+
),
512+
)
513+
or ""
514+
)
515+
return {
516+
"student_id": student_id,
517+
"student_name": student_name,
518+
"display_text": display_text,
519+
"exists": exists,
520+
"group_name": group_name,
521+
"lottery_name": lottery_name,
522+
}
523+
524+
if isinstance(value, (list, tuple)) and len(value) >= 3:
525+
student_name = str(value[1] or "")
526+
return {
527+
"student_id": self._safe_int(value[0]),
528+
"student_name": student_name,
529+
"display_text": student_name,
530+
"exists": bool(value[2]),
531+
"group_name": "",
532+
"lottery_name": "",
533+
}
534+
535+
return None
455536
else:
456537

457538
class CSharpIPCHandler:

app/common/lottery/lottery_manager.py

Lines changed: 114 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,16 @@ def get_random_items(self, count):
376376
selected_prizes = [system_random.choice(self.prizes) for _ in range(count)]
377377

378378
if not self.enable_student_assignment or not self.current_class_name:
379-
return selected_prizes
379+
prizes_with_meta = []
380+
for prize in selected_prizes:
381+
prize_copy = dict(prize)
382+
prize_name = prize_copy.get("name", "")
383+
prize_copy["ipc_lottery_name"] = str(prize_name or "")
384+
prize_copy["ipc_group_name"] = ""
385+
prize_copy["ipc_student_name"] = ""
386+
prize_copy["ipc_display_text"] = str(prize_name or "")
387+
prizes_with_meta.append(prize_copy)
388+
return prizes_with_meta
380389

381390
candidates = RollCallUtils._get_filtered_candidates(
382391
self.current_class_name,
@@ -400,6 +409,7 @@ def get_random_items(self, count):
400409
for prize in selected_prizes:
401410
prize_copy = dict(prize)
402411
prize_name = prize_copy.get("name", "")
412+
prize_copy["ipc_lottery_name"] = str(prize_name or "")
403413

404414
group_name = ""
405415
student_name = ""
@@ -422,10 +432,13 @@ def get_random_items(self, count):
422432
else:
423433
student_name = system_random.choice(candidates).get("name", "")
424434

435+
prize_copy["ipc_group_name"] = str(group_name or "")
436+
prize_copy["ipc_student_name"] = str(student_name or "")
425437
if group_name or student_name:
426438
prize_copy["name"] = self._format_prize_student_text(
427439
prize_name, group_name, student_name, show_random
428440
)
441+
prize_copy["ipc_display_text"] = str(prize_copy.get("name", "") or "")
429442

430443
prizes_with_students.append(prize_copy)
431444

@@ -502,6 +515,7 @@ def draw_final_items(self, count):
502515
except Exception:
503516
show_random = 0
504517

518+
include_group = show_random in (0, 1, 2, 5, 6, 7, 8, 9)
505519
from app.common.data.list import get_group_members
506520

507521
for idx, prize in enumerate(selected_prizes_dict):
@@ -522,6 +536,9 @@ def draw_final_items(self, count):
522536
)
523537

524538
display_name = prize_name
539+
ipc_group_name = ""
540+
ipc_student_name = ""
541+
ipc_display_text = str(prize_name or "")
525542
if student_tuple and len(student_tuple) >= 2 and student_tuple[1]:
526543
group_name = ""
527544
student_name = ""
@@ -545,18 +562,29 @@ def draw_final_items(self, count):
545562
else:
546563
student_name = str(student_tuple[1])
547564

565+
ipc_group_name = str(group_name or "")
566+
ipc_student_name = str(student_name or "")
548567
display_name = self._format_prize_student_text(
549568
prize_name, group_name, student_name, show_random
550569
)
570+
ipc_display_text = str(display_name or "")
551571

552572
selected_prizes_with_students.append((prize_id, display_name, prize_exist))
553573

554574
prize_copy = dict(prize)
575+
prize_copy["ipc_lottery_name"] = str(prize_name or "")
576+
prize_copy["ipc_group_name"] = ipc_group_name if include_group else ""
577+
prize_copy["ipc_student_name"] = ipc_student_name
578+
prize_copy["ipc_display_text"] = ipc_display_text
555579
if isinstance(student_dict, dict):
556580
prize_copy["student"] = student_dict
557581
prize_copy["student_id"] = student_dict.get("id", "")
558582
prize_copy["student_name"] = student_dict.get("name", "")
559583
prize_copy["student_exist"] = student_dict.get("exist", True)
584+
if include_group and not prize_copy["ipc_group_name"]:
585+
prize_copy["ipc_group_name"] = str(
586+
student_dict.get("group", "") or ""
587+
)
560588
updated_prizes_dict.append(prize_copy)
561589

562590
result["selected_prizes"] = selected_prizes_with_students
@@ -937,11 +965,65 @@ def stop_animation(widget):
937965

938966
settings = widget.manager.get_notification_settings(refresh=True)
939967
if settings is not None:
968+
settings_for_notify = (
969+
dict(settings) if isinstance(settings, dict) else settings
970+
)
971+
show_random = readme_settings_async("lottery_settings", "show_random")
972+
try:
973+
show_random = int(show_random or 0)
974+
except Exception:
975+
show_random = 0
976+
include_group = show_random in (0, 1, 2, 5, 6, 7, 8, 9)
977+
ipc_selected_students = []
978+
for prize in widget.final_selected_students_dict or []:
979+
if not isinstance(prize, dict):
980+
continue
981+
student = prize.get("student")
982+
if not isinstance(student, dict):
983+
student = None
984+
try:
985+
student_id = int(prize.get("student_id", 0) or 0)
986+
except Exception:
987+
student_id = 0
988+
if not student_id and student is not None:
989+
try:
990+
student_id = int(student.get("id", 0) or 0)
991+
except Exception:
992+
student_id = 0
993+
student_name = str(
994+
prize.get("ipc_student_name", "")
995+
or prize.get("student_name", "")
996+
or ""
997+
)
998+
display_text = str(
999+
prize.get("ipc_display_text", "") or prize.get("name", "") or ""
1000+
)
1001+
group_name = str(prize.get("ipc_group_name", "") or "")
1002+
if not include_group:
1003+
group_name = ""
1004+
lottery_name = str(
1005+
prize.get("ipc_lottery_name", "") or prize.get("name", "") or ""
1006+
)
1007+
exists = bool(prize.get("student_exist", prize.get("exist", True)))
1008+
ipc_selected_students.append(
1009+
{
1010+
"student_id": student_id,
1011+
"student_name": student_name,
1012+
"display_text": display_text,
1013+
"exists": exists,
1014+
"group_name": group_name,
1015+
"lottery_name": lottery_name,
1016+
}
1017+
)
1018+
1019+
if ipc_selected_students and isinstance(settings_for_notify, dict):
1020+
settings_for_notify["ipc_selected_students"] = ipc_selected_students
1021+
9401022
ResultDisplayUtils.show_notification_if_enabled(
9411023
widget.final_pool_name,
9421024
widget.final_selected_students,
9431025
actual_draw_count,
944-
settings,
1026+
settings_for_notify,
9451027
settings_group="lottery_notification_settings",
9461028
)
9471029

@@ -991,13 +1073,32 @@ def draw_random(widget):
9911073
display_count = min(display_count, remaining_count)
9921074

9931075
prizes = widget.manager.get_random_items(display_count)
1076+
ipc_selected_students = []
1077+
for p in prizes or []:
1078+
if not isinstance(p, dict):
1079+
continue
1080+
ipc_selected_students.append(
1081+
{
1082+
"student_id": 0,
1083+
"student_name": str(p.get("ipc_student_name", "") or ""),
1084+
"display_text": str(
1085+
p.get("ipc_display_text", p.get("name", "")) or ""
1086+
),
1087+
"exists": bool(p.get("exist", True)),
1088+
"group_name": str(p.get("ipc_group_name", "") or ""),
1089+
"lottery_name": str(
1090+
p.get("ipc_lottery_name", p.get("name", "")) or ""
1091+
),
1092+
}
1093+
)
9941094
selected_prizes = [(p["id"], p["name"], p.get("exist", True)) for p in prizes]
9951095

9961096
display_result_animated(
9971097
widget,
9981098
selected_prizes,
9991099
widget.manager.current_pool_name,
10001100
draw_count=display_count,
1101+
ipc_selected_students=ipc_selected_students,
10011102
)
10021103

10031104

@@ -1034,7 +1135,9 @@ def display_result(widget, selected_students, pool_name, draw_count=None):
10341135
ResultDisplayUtils.display_results_in_grid(widget.result_grid, student_labels)
10351136

10361137

1037-
def display_result_animated(widget, selected_students, pool_name, draw_count=None):
1138+
def display_result_animated(
1139+
widget, selected_students, pool_name, draw_count=None, ipc_selected_students=None
1140+
):
10381141
render_settings = widget.manager.get_render_settings(refresh=False)
10391142
if draw_count is None:
10401143
draw_count = widget.current_count
@@ -1069,11 +1172,18 @@ def display_result_animated(widget, selected_students, pool_name, draw_count=Non
10691172

10701173
settings = widget.manager.get_notification_settings(refresh=False)
10711174
if settings is not None:
1175+
settings_for_notify = dict(settings) if isinstance(settings, dict) else settings
1176+
if (
1177+
ipc_selected_students
1178+
and isinstance(settings_for_notify, dict)
1179+
and isinstance(ipc_selected_students, list)
1180+
):
1181+
settings_for_notify["ipc_selected_students"] = ipc_selected_students
10721182
ResultDisplayUtils.show_notification_if_enabled(
10731183
pool_name,
10741184
selected_students,
10751185
draw_count,
1076-
settings,
1186+
settings_for_notify,
10771187
settings_group="lottery_notification_settings",
10781188
is_animating=True,
10791189
)

0 commit comments

Comments
 (0)