Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
LLM-Filter
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
2026_NGIT
LLM-Filter
Commits
e13c1477
Commit
e13c1477
authored
Dec 13, 2025
by
uuo00_n
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(仪表盘): 添加学生周课表查询功能
添加 TERM_START_DATE 配置项用于学期开始日期计算 实现学生周课表查询接口,支持按周次查询课表 完善学生实体查询的 ObjectId 处理逻辑
parent
76324c68
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
139 additions
and
6 deletions
+139
-6
.env
.env
+5
-2
dashboard.py
app/api/v1/dashboard.py
+34
-1
config.py
app/core/config.py
+3
-0
dashboard.py
app/services/dashboard.py
+97
-3
No files found.
.env
View file @
e13c1477
# 数据库配置
# 注意:生产环境请通过安全的环境变量管理传递凭据,避免将敏感信息提交到版本库
#
MONGODB_URL=mongodb://llm:fSjFMwyShmcH4GdR@datacenter.dldzxx.cn:27017/llm?authSource=llm
MONGODB_URL=mongodb://localhost:27017/
MONGODB_URL=mongodb://llm:fSjFMwyShmcH4GdR@datacenter.dldzxx.cn:27017/llm?authSource=llm
#
MONGODB_URL=mongodb://localhost:27017/
DB_NAME=llm
# JWT配置
...
...
@@ -9,6 +9,9 @@ SECRET_KEY=your_secret_key_here
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
# 学期配置
TERM_START_DATE=2025-09-01
# Ollama配置
OLLAMA_BASE_URL=http://datacenter.dldzxx.cn:11434/
OLLAMA_MODEL=deepseek-r1:14b
\ No newline at end of file
app/api/v1/dashboard.py
View file @
e13c1477
from
fastapi
import
APIRouter
,
Depends
from
fastapi
import
APIRouter
,
Depends
,
Query
from
pydantic
import
BaseModel
from
typing
import
List
,
Optional
,
Dict
,
Any
from
app.api.deps
import
require_edition_for_mode
,
require_role
,
require_binding
from
app.services.dashboard
import
(
student_today_summary
,
student_week_schedule
,
homeroom_current_summary
,
department_overview
,
campus_overview
,
...
...
@@ -34,6 +35,21 @@ class StudentTodaySummary(BaseModel):
today_attendance
:
List
[
StudentTodayAttendance
]
today_conduct
:
Dict
[
str
,
Any
]
class
StudentWeekScheduleItem
(
BaseModel
):
lesson_id
:
Optional
[
str
]
=
None
period
:
Optional
[
int
]
=
None
course_name
:
Optional
[
str
]
=
None
location
:
Optional
[
str
]
=
None
start_time
:
Optional
[
str
]
=
None
end_time
:
Optional
[
str
]
=
None
teacher_person_id
:
Optional
[
str
]
=
None
class
StudentWeekSummary
(
BaseModel
):
student
:
Dict
[
str
,
Optional
[
str
]]
current_week
:
int
week_dates
:
Dict
[
int
,
str
]
schedule
:
Dict
[
str
,
List
[
StudentWeekScheduleItem
]]
class
HomeroomLesson
(
BaseModel
):
class_id
:
Optional
[
str
]
course_name
:
Optional
[
str
]
...
...
@@ -98,6 +114,23 @@ class CampusOverview(BaseModel):
async
def
student_today
(
current_user
:
dict
=
Depends
(
require_role
(
1
)),
_b
:
dict
=
Depends
(
require_binding
(
"student"
)))
->
StudentTodaySummary
:
return
await
student_today_summary
(
current_user
)
@
router
.
get
(
"/student/week"
,
summary
=
"学生端:周课表查询"
,
description
=
"需角色等级≥1且主绑定为学生;返回指定周次(默认当前周)的完整课表,支持 'week' 参数查询下一周。"
,
response_model
=
StudentWeekSummary
,
responses
=
{
401
:
{
"description"
:
"未认证"
,
"content"
:
{
"application/json"
:
{
"example"
:
{
"detail"
:
"无效的认证凭据"
}}}},
403
:
{
"description"
:
"权限不足或未绑定学生"
,
"content"
:
{
"application/json"
:
{
"example"
:
{
"detail"
:
"实体绑定不存在或类型不匹配"
}}}},
}
)
async
def
student_week
(
week
:
Optional
[
int
]
=
Query
(
None
,
description
=
"周次(如 1, 2, ...),不传则默认为当前周"
),
current_user
:
dict
=
Depends
(
require_role
(
1
)),
_b
:
dict
=
Depends
(
require_binding
(
"student"
))
)
->
StudentWeekSummary
:
return
await
student_week_schedule
(
current_user
,
week
)
@
router
.
get
(
"/homeroom/current"
,
summary
=
"班主任端:当前节次课程与地点、出勤率、请假、指示"
,
...
...
app/core/config.py
View file @
e13c1477
...
...
@@ -32,5 +32,8 @@ class Settings(BaseSettings):
CORS_ALLOWED_ORIGINS
:
str
=
os
.
getenv
(
"CORS_ALLOWED_ORIGINS"
,
"*"
)
GITHUB_DEFAULT_REPO
:
str
=
os
.
getenv
(
"GITHUB_DEFAULT_REPO"
,
""
)
GITHUB_TOKEN
:
str
=
os
.
getenv
(
"GITHUB_TOKEN"
,
""
)
# 学期配置
TERM_START_DATE
:
str
=
os
.
getenv
(
"TERM_START_DATE"
,
"2025-09-01"
)
# 默认开学日期
settings
=
Settings
()
app/services/dashboard.py
View file @
e13c1477
from
datetime
import
datetime
from
datetime
import
datetime
,
timedelta
from
typing
import
Dict
,
List
,
Any
from
bson
import
ObjectId
from
fastapi
import
HTTPException
from
app.db.mongodb
import
db
from
app.core.config
import
settings
async
def
_today_iso
()
->
str
:
return
datetime
.
now
()
.
date
()
.
isoformat
()
...
...
@@ -10,6 +11,34 @@ async def _today_iso() -> str:
async
def
_weekday
()
->
int
:
return
datetime
.
now
()
.
isoweekday
()
async
def
_get_current_week
()
->
int
:
try
:
start_date
=
datetime
.
strptime
(
settings
.
TERM_START_DATE
,
"
%
Y-
%
m-
%
d"
)
.
date
()
today
=
datetime
.
now
()
.
date
()
delta
=
today
-
start_date
if
delta
.
days
<
0
:
return
1
return
(
delta
.
days
//
7
)
+
1
except
Exception
:
return
1
def
_is_week_valid
(
week
:
int
,
week_range
:
str
)
->
bool
:
if
not
week_range
:
return
True
try
:
parts
=
week_range
.
split
(
','
)
for
part
in
parts
:
if
'-'
in
part
:
start
,
end
=
map
(
int
,
part
.
split
(
'-'
))
if
start
<=
week
<=
end
:
return
True
else
:
if
int
(
part
)
==
week
:
return
True
except
:
pass
return
False
async
def
_current_period
()
->
int
:
h
=
datetime
.
now
()
.
hour
if
h
<
10
:
...
...
@@ -27,13 +56,21 @@ async def _get_primary_binding(account_id: ObjectId) -> Dict[str, Any]:
return
b
async
def
_get_student_entity
(
account_id
:
ObjectId
,
binding
:
Dict
[
str
,
Any
])
->
Dict
[
str
,
Any
]:
s
=
await
db
.
db
.
students
.
find_one
({
"person_id"
:
binding
.
get
(
"person_id"
)})
pid
=
binding
.
get
(
"person_id"
)
if
isinstance
(
pid
,
str
)
and
ObjectId
.
is_valid
(
pid
):
pid
=
ObjectId
(
pid
)
s
=
await
db
.
db
.
students
.
find_one
({
"person_id"
:
pid
})
if
s
:
return
s
raise
HTTPException
(
status_code
=
404
,
detail
=
"未找到学生实体"
)
async
def
_get_teacher_entity
(
account_id
:
ObjectId
,
binding
:
Dict
[
str
,
Any
])
->
Dict
[
str
,
Any
]:
t
=
await
db
.
db
.
teachers
.
find_one
({
"person_id"
:
binding
.
get
(
"person_id"
)})
pid
=
binding
.
get
(
"person_id"
)
if
isinstance
(
pid
,
str
)
and
ObjectId
.
is_valid
(
pid
):
pid
=
ObjectId
(
pid
)
t
=
await
db
.
db
.
teachers
.
find_one
({
"person_id"
:
pid
})
if
t
:
return
t
raise
HTTPException
(
status_code
=
404
,
detail
=
"未找到教师实体"
)
...
...
@@ -97,6 +134,63 @@ async def student_today_summary(current_user: Dict[str, Any]) -> Dict[str, Any]:
"today_conduct"
:
conduct
,
}
async
def
student_week_schedule
(
current_user
:
Dict
[
str
,
Any
],
week
:
int
=
None
)
->
Dict
[
str
,
Any
]:
if
week
is
None
:
week
=
await
_get_current_week
()
student
=
await
_get_student_by_user
(
current_user
[
"_id"
])
class_id
=
student
.
get
(
"class_id"
)
if
student
else
None
try
:
start_date
=
datetime
.
strptime
(
settings
.
TERM_START_DATE
,
"
%
Y-
%
m-
%
d"
)
.
date
()
monday_of_week
=
start_date
+
timedelta
(
weeks
=
week
-
1
)
except
:
monday_of_week
=
datetime
.
now
()
.
date
()
week_dates
=
{}
for
i
in
range
(
1
,
8
):
d
=
monday_of_week
+
timedelta
(
days
=
i
-
1
)
week_dates
[
i
]
=
d
.
isoformat
()
schedules_by_day
=
{
str
(
i
):
[]
for
i
in
range
(
1
,
8
)}
if
class_id
:
cursor
=
db
.
db
.
schedules
.
find
({
"classes.class_id"
:
class_id
})
.
sort
(
"period"
,
1
)
async
for
doc
in
cursor
:
w_range
=
doc
.
get
(
"week_range"
,
""
)
if
not
_is_week_valid
(
week
,
w_range
):
continue
wd
=
doc
.
get
(
"weekday"
)
loc
=
None
for
c
in
doc
.
get
(
"classes"
,
[]):
if
c
.
get
(
"class_id"
)
==
class_id
:
loc
=
c
.
get
(
"location"
)
break
item
=
{
"lesson_id"
:
doc
.
get
(
"lesson_id"
),
"period"
:
doc
.
get
(
"period"
),
"course_name"
:
doc
.
get
(
"course_name"
),
"location"
:
loc
,
"start_time"
:
doc
.
get
(
"start_time"
),
"end_time"
:
doc
.
get
(
"end_time"
),
"teacher_person_id"
:
str
(
doc
.
get
(
"teacher_person_id"
))
if
doc
.
get
(
"teacher_person_id"
)
else
None
}
if
str
(
wd
)
in
schedules_by_day
:
schedules_by_day
[
str
(
wd
)]
.
append
(
item
)
return
{
"student"
:
{
"student_id"
:
student
.
get
(
"student_id"
)
if
student
else
None
,
"name"
:
student
.
get
(
"name"
)
if
student
else
None
,
"class_id"
:
class_id
,
},
"current_week"
:
week
,
"week_dates"
:
week_dates
,
"schedule"
:
schedules_by_day
}
async
def
homeroom_current_summary
(
current_user
:
Dict
[
str
,
Any
])
->
Dict
[
str
,
Any
]:
today
=
await
_today_iso
()
weekday
=
await
_weekday
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment