From e3e6db2d9974588f91ac1567a58fa4846655ce1b Mon Sep 17 00:00:00 2001
From: yearning <10538594+wangweifeng1999@user.noreply.gitee.com>
Date: 星期三, 30 九月 2026 12:54:55 +0800
Subject: [PATCH] 1.判断题优化;2.新增考评员是否能查看考生隐私开关
---
frontend/src/pages/ScoreQueryPage.tsx | 136 +++++++++++++++++++++++++++++++-------------
1 files changed, 95 insertions(+), 41 deletions(-)
diff --git a/frontend/src/pages/ScoreQueryPage.tsx b/frontend/src/pages/ScoreQueryPage.tsx
index e3f3141..99e9b47 100644
--- a/frontend/src/pages/ScoreQueryPage.tsx
+++ b/frontend/src/pages/ScoreQueryPage.tsx
@@ -1,5 +1,5 @@
import { useEffect, useRef, useState } from "react";
-import { Button, Card, Form, Input, Select, Table } from "antd";
+import { Button, Card, Form, Input, message, Select, Table } from "antd";
import { useNavigate, useSearchParams } from "react-router-dom";
import { api } from "../api";
import {
@@ -8,12 +8,15 @@
writeScoreListQuery,
type ScoreListQuery,
} from "../scoreQueryParams";
+import { useSystemSettings } from "../systemSettings";
+import type { UserMe } from "../App";
import "./ScoreQueryPage.css";
type ScoreRow = {
examinee_id: string;
- name: string;
- id_card: string;
+ student_no: string;
+ name: string | null;
+ id_card: string | null;
subject_name: string;
score: number;
attempt_id: string;
@@ -38,6 +41,18 @@
subject: query.subject,
});
const [tableScrollY, setTableScrollY] = useState(320);
+ const [user, setUser] = useState<UserMe | null>(null);
+ const { settings } = useSystemSettings();
+
+ const hidePrivacy =
+ user?.role === "grader" && !settings.grader_can_see_privacy;
+
+ useEffect(() => {
+ api
+ .get<UserMe>("/api/auth/me")
+ .then((r) => setUser(r.data))
+ .catch(() => setUser(null));
+ }, []);
useEffect(() => {
api.get<{ items: string[] }>("/api/subjects").then((r) => setSubjects(r.data.items));
@@ -56,16 +71,20 @@
}, [searchParams, form]);
const load = async () => {
- const { data: res } = await api.get("/api/scores", {
- params: { page, page_size: pageSize, ...filters },
- });
+ const params: Record<string, string | number> = { page, page_size: pageSize };
+ if (!hidePrivacy) {
+ if (filters.name) params.name = filters.name;
+ if (filters.id_card) params.id_card = filters.id_card;
+ }
+ if (filters.subject) params.subject = filters.subject;
+ const { data: res } = await api.get("/api/scores", { params });
setData(res.items);
setTotal(res.total);
};
useEffect(() => {
load();
- }, [page, pageSize, filters]);
+ }, [page, pageSize, filters, hidePrivacy]);
useEffect(() => {
const el = tableWrapRef.current;
@@ -90,6 +109,52 @@
setSearchParams(writeScoreListQuery(q), { replace: true });
};
+ const [studentNo, setStudentNo] = useState("");
+ const handleLookup = async () => {
+ if (!studentNo.trim()) return;
+ try {
+ const { data } = await api.get<{ attempt_id: string }>(
+ `/api/attempts/lookup/${encodeURIComponent(studentNo.trim().toUpperCase())}`
+ );
+ nav(attemptDetailPath(data.attempt_id, listQuery()));
+ } catch {
+ message.error("鑰冪敓缂栧彿涓嶅瓨鍦�");
+ }
+ };
+
+ const columns = [
+ {
+ title: "搴忓彿",
+ width: 64,
+ fixed: "left" as const,
+ render: (_: unknown, __: unknown, index: number) => (page - 1) * pageSize + index + 1,
+ },
+ { title: "鑰冪敓缂栧彿", dataIndex: "student_no", width: 180, fixed: "left" as const },
+ ...(hidePrivacy
+ ? []
+ : [
+ { title: "濮撳悕", dataIndex: "name", width: 100 },
+ { title: "璇佷欢鍙�", dataIndex: "id_card", width: 180 },
+ ]),
+ { title: "绉戠洰", dataIndex: "subject_name", width: 200, ellipsis: true },
+ { title: "寮�濮嬭�冭瘯鏃堕棿", dataIndex: "start_time", width: 170, render: (v: string | null) => v || "鈥�" },
+ { title: "缁撴潫鑰冭瘯鏃堕棿", dataIndex: "end_time", width: 170, render: (v: string | null) => v || "鈥�" },
+ { title: "鎴愮哗", dataIndex: "score", width: 80 },
+ {
+ title: "鎿嶄綔",
+ width: 80,
+ fixed: "right" as const,
+ render: (_: unknown, row: ScoreRow) => (
+ <Button
+ type="link"
+ onClick={() => nav(attemptDetailPath(row.attempt_id, listQuery()))}
+ >
+ 鏌ョ湅
+ </Button>
+ ),
+ },
+ ];
+
return (
<div className="score-query-page">
<Card bordered className="score-query-page__card">
@@ -101,12 +166,16 @@
pushQuery({ ...v, page: 1, page_size: pageSize });
}}
>
- <Form.Item name="name" label="濮撳悕">
- <Input allowClear style={{ width: 120 }} />
- </Form.Item>
- <Form.Item name="id_card" label="璇佷欢鍙�">
- <Input allowClear style={{ width: 180 }} />
- </Form.Item>
+ {!hidePrivacy && (
+ <>
+ <Form.Item name="name" label="濮撳悕">
+ <Input allowClear style={{ width: 120 }} />
+ </Form.Item>
+ <Form.Item name="id_card" label="璇佷欢鍙�">
+ <Input allowClear style={{ width: 180 }} />
+ </Form.Item>
+ </>
+ )}
<Form.Item name="subject" label="绉戠洰">
<Select
allowClear
@@ -118,10 +187,21 @@
<Button type="primary" htmlType="submit">鏌ヨ</Button>
</Form.Item>
</Form>
+ <div style={{ marginBottom: 12, display: "flex", gap: 8, alignItems: "center" }}>
+ <Input
+ placeholder="杈撳叆鑰冪敓缂栧彿鐩存帴鏌ョ湅绛斿嵎"
+ value={studentNo}
+ onChange={(e) => setStudentNo(e.target.value.toUpperCase())}
+ onPressEnter={handleLookup}
+ style={{ width: 200, fontFamily: "monospace" }}
+ maxLength={10}
+ />
+ <Button onClick={handleLookup} disabled={!studentNo.trim()}>鏌ョ湅绛斿嵎</Button>
+ </div>
<div ref={tableWrapRef} className="score-query-page__table-wrap">
<Table
rowKey="attempt_id"
- scroll={{ x: 1100, y: tableScrollY }}
+ scroll={{ x: hidePrivacy ? 800 : 1100, y: tableScrollY }}
dataSource={data}
pagination={{
current: page,
@@ -134,33 +214,7 @@
pushQuery({ ...filters, page: p, page_size: ps });
},
}}
- columns={[
- {
- title: "搴忓彿",
- width: 64,
- fixed: "left",
- render: (_, __, index) => (page - 1) * pageSize + index + 1,
- },
- { title: "濮撳悕", dataIndex: "name", width: 100 },
- { title: "璇佷欢鍙�", dataIndex: "id_card", width: 180 },
- { title: "绉戠洰", dataIndex: "subject_name", width: 200, ellipsis: true },
- { title: "寮�濮嬭�冭瘯鏃堕棿", dataIndex: "start_time", width: 170, render: (v) => v || "鈥�" },
- { title: "缁撴潫鑰冭瘯鏃堕棿", dataIndex: "end_time", width: 170, render: (v) => v || "鈥�" },
- { title: "鎴愮哗", dataIndex: "score", width: 80 },
- {
- title: "鎿嶄綔",
- width: 80,
- fixed: "right",
- render: (_, row) => (
- <Button
- type="link"
- onClick={() => nav(attemptDetailPath(row.attempt_id, listQuery()))}
- >
- 鏌ョ湅
- </Button>
- ),
- },
- ]}
+ columns={columns}
/>
</div>
</Card>
--
Gitblit v1.8.0