| ").Append(E(Text(subject, "name")))
+ .Append(" | ").Append(E(Text(subject, "date")))
+ .Append(" | ").Append(E(Text(subject, "start"))).Append('—').Append(E(Text(subject, "end")))
+ .Append(" | ").Append(E(First(Text(assignment, "examRoomCode"), "待定")))
+ .Append(" | ").Append(E(First(Text(assignment, "roomName"), Text(assignment, "room"), room?.Name ?? "", "待定")))
+ .Append("场地代码:").Append(E(First(Text(assignment, "roomCode"), room?.Code ?? "", "—")))
+ .Append(" | ").Append(E(First(Text(assignment, "building"), room?.Building ?? "", "—")))
+ .Append("").Append(E(First(Text(assignment, "floor"), room?.Floor ?? "", "楼层待定")))
+ .Append(" | ").Append(E(First(Text(assignment, "seat"), "—"))).Append(" |
");
+ }
+ var center = centers.Centers.FirstOrDefault(item => item.Id == Text(card, "centerId"));
+ var centerCode = First(Text(card, "centerCode"), center?.Code ?? "");
+ var centerAddress = First(
+ Text(card, "centerAddress"),
+ center is null
+ ? ""
+ : string.Join(' ', new[]
+ {
+ center.ProvinceName,
+ center.CityName,
+ center.DistrictName,
+ center.Address
+ }.Where(value => value.Length > 0)));
+ var generatedAt = DateTimeOffset.TryParse(
+ Text(card, "generatedAt"),
+ CultureInfo.InvariantCulture,
+ DateTimeStyles.AssumeUniversal,
+ out var parsed)
+ ? parsed.ToLocalTime().ToString("yyyy/M/d HH:mm:ss", CultureInfo.GetCultureInfo("zh-CN"))
+ : Text(card, "generatedAt");
+ sections.Append("固定考点")
+ .Append(E(Text(card, "testCenter"))).Append("考点代码:").Append(E(First(centerCode, "—")))
+ .Append("
考点详细地址").Append(E(First(centerAddress, "地址待公布")))
+ .Append("
| 科目 | 日期 | 时间 | 考试考场序号 | 考场通用名称 / 场地代码 | 楼栋 / 楼层 | 座位号 |
")
+ .Append(rows)
+ .Append("
编号说明“考试考场序号”是本次考试编排编号;“考场通用名称 / 场地代码”是考点内的物理场地档案,两者不是同一概念。
所有科目均安排在同一考点,但不同科目可能对应不同考试考场序号、物理场地和座位。请逐科核对,并携带本人有效身份证件及本准考证至少提前 40 分钟到达考点。
");
+ }
+ const string styles = "@page{size:A4 landscape;margin:10mm}*{box-sizing:border-box}body{font-family:\"Microsoft YaHei\",sans-serif;color:#182552;margin:0;background:#f2f4f8}.card{max-width:1120px;min-height:720px;margin:24px auto;background:#fff;border:2px solid #182552;padding:26px;box-shadow:0 12px 35px #18255218;break-after:page}.card:last-child{break-after:auto}.head{display:flex;justify-content:space-between;align-items:flex-start;border-bottom:3px double #182552;padding-bottom:14px}.head>div:last-child{text-align:right}.head small{color:#64748b}.brand{font-size:27px;font-weight:800}.head p{margin:6px 0}.code{font:700 22px Consolas,monospace;margin-top:5px}.meta{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin:16px 0}.meta div,.center>div{border:1px solid #d9e0e7;padding:9px 12px}.meta span,.center span{display:block;color:#64748b;font-size:11px;margin-bottom:4px}.center{display:grid;grid-template-columns:1fr 1.5fr;gap:10px;margin-bottom:16px}.center small,td small{display:block;color:#64748b;margin-top:4px}table{width:100%;border-collapse:collapse;font-size:12px}th,td{border:1px solid #b9c5d2;padding:9px;text-align:left;vertical-align:middle}th{background:#eaf1f5}.room-no{font:700 15px Consolas,monospace;text-align:center}.explain,.notice{margin-top:12px;padding:10px 12px;font-size:12px}.explain{background:#eaf4f6;color:#245365}.explain strong{margin-right:8px}.notice{background:#fff7e6;color:#704b12}.footer{display:flex;justify-content:space-between;margin-top:14px;color:#64748b;font-size:11px}@media print{body{background:#fff}.card{margin:0;box-shadow:none}}";
+ return $"