引入openspec管理

This commit is contained in:
2025-12-22 18:29:23 +08:00
parent 2454e6d23a
commit b765a5d4ed
27 changed files with 1058 additions and 1814 deletions

View File

@@ -41,9 +41,9 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
boxShadowTertiary: '0 1px 2px 0 rgba(0, 0, 0, 0.03), 0 1px 6px -1px rgba(0, 0, 0, 0.02), 0 2px 4px 0 rgba(0, 0, 0, 0.02)',
},
Layout: {
colorBgHeader: '#ffffff',
colorBgSider: '#ffffff',
}
headerBg: '#ffffff',
siderBg: '#ffffff',
},
}
}}
>

View File

@@ -329,7 +329,7 @@ const ExamSubjectPage = () => {
{title: '操作',
key: 'action',
width: 100,
align: 'left',
align: 'left' as const,
render: (_: any, record: ExamSubject) => (
<div className="space-y-2">
<Button
@@ -617,4 +617,4 @@ const ExamSubjectPage = () => {
);
};
export default ExamSubjectPage;
export default ExamSubjectPage;

View File

@@ -63,7 +63,7 @@ const ExamTaskPage = () => {
setTasks(tasksRes.data);
setSubjects(subjectsRes.data);
setUsers(usersRes.data);
setUserGroups(groupsRes);
setUserGroups(groupsRes.data);
} catch (error) {
message.error('获取数据失败');
} finally {
@@ -86,10 +86,11 @@ const ExamTaskPage = () => {
for (const gid of selectedGroupIds) {
if (!groupMembersMap[gid]) {
try {
const members = await userGroupAPI.getMembers(gid);
const membersRes = await userGroupAPI.getMembers(gid);
const members = (membersRes as any).data as any[];
setGroupMembersMap(prev => ({
...prev,
[gid]: members.map((u: any) => u.id)
[gid]: (members || []).map((u: any) => u.id)
}));
} catch (e) {
console.error(`Failed to fetch members for group ${gid}`, e);
@@ -383,10 +384,7 @@ const ExamTaskPage = () => {
placeholder="请选择考试科目"
style={{ width: '100%' }}
showSearch
filterOption={(input, option) => {
const value = option?.children as string;
return value.toLowerCase().includes(input.toLowerCase());
}}
optionFilterProp="children"
dropdownStyle={{ maxHeight: 300, overflow: 'auto' }}
virtual
>
@@ -463,10 +461,9 @@ const ExamTaskPage = () => {
showSearch
optionLabelProp="label"
filterOption={(input, option) => {
const label = option?.label as string;
if (label && label.toLowerCase().includes(input.toLowerCase())) return true;
const children = React.Children.toArray(option?.children).join('');
return children.toLowerCase().includes(input.toLowerCase());
const inputLower = input.toLowerCase();
const labelText = String((option as any)?.label ?? '').toLowerCase();
return labelText.includes(inputLower);
}}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
virtual
@@ -534,4 +531,4 @@ const ExamTaskPage = () => {
);
};
export default ExamTaskPage;
export default ExamTaskPage;

View File

@@ -57,7 +57,7 @@ const QuestionManagePage = () => {
const [searchType, setSearchType] = useState<string>('');
const [searchCategory, setSearchCategory] = useState<string>('');
const [searchKeyword, setSearchKeyword] = useState<string>('');
const [searchDateRange, setSearchDateRange] = useState<[dayjs.Dayjs, dayjs.Dayjs] | null>(null);
const [searchDateRange, setSearchDateRange] = useState<[dayjs.Dayjs | null, dayjs.Dayjs | null] | null>(null);
const [pagination, setPagination] = useState({
current: 1,
pageSize: 10,
@@ -91,9 +91,10 @@ const QuestionManagePage = () => {
}));
// 提取并更新可用的题型和类别列表
const allQuestions = await questionAPI.getQuestions({ limit: 10000 });
const types = [...new Set(allQuestions.data.map((q: any) => q.type))];
const categories = [...new Set(allQuestions.data.map((q: any) => q.category || '通用'))];
const allQuestionsRes = await questionAPI.getQuestions({ limit: 10000 });
const allList = ((allQuestionsRes as any).data as any[]) || [];
const types = [...new Set(allList.map((q: any) => String(q.type)))];
const categories = [...new Set(allList.map((q: any) => String(q.category || '通用')))];
setAvailableTypes(types);
setAvailableCategories(categories);
} catch (error: any) {
@@ -668,4 +669,4 @@ const QuestionManagePage = () => {
);
};
export default QuestionManagePage;
export default QuestionManagePage;

View File

@@ -59,13 +59,13 @@ api.interceptors.response.use(
export const userAPI = {
createUser: (data: { name: string; phone: string; password?: string }) => api.post('/users', data),
getUser: (id: string) => api.get(`/users/${id}`),
validateUserInfo: (data: { name: string; phone: string }) => api.post('/users/validate', data),
validateUserInfo: (data: { name: string; phone: string; password?: string }) => api.post('/users/validate', data),
getUsersByName: (name: string) => api.get(`/users/name/${name}`),
};
// 题目相关API
export const questionAPI = {
getQuestions: (params?: { type?: string; page?: number; limit?: number }) =>
getQuestions: (params?: { type?: string; category?: string; keyword?: string; startDate?: string; endDate?: string; page?: number; limit?: number }) =>
api.get('/questions', { params }),
getQuestion: (id: string) => api.get(`/questions/${id}`),
createQuestion: (data: any) => api.post('/questions', data),