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://llm:fSjFMwyShmcH4GdR@datacenter.dldzxx.cn:27017/llm?authSource=llm
MONGODB_URL=mongodb://localhost:27017/
#
MONGODB_URL=mongodb://localhost:27017/
DB_NAME=llm
DB_NAME=llm
# JWT配置
# JWT配置
...
@@ -9,6 +9,9 @@ SECRET_KEY=your_secret_key_here
...
@@ -9,6 +9,9 @@ SECRET_KEY=your_secret_key_here
ALGORITHM=HS256
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
ACCESS_TOKEN_EXPIRE_MINUTES=30
# 学期配置
TERM_START_DATE=2025-09-01
# Ollama配置
# Ollama配置
OLLAMA_BASE_URL=http://datacenter.dldzxx.cn:11434/
OLLAMA_BASE_URL=http://datacenter.dldzxx.cn:11434/
OLLAMA_MODEL=deepseek-r1:14b
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
pydantic
import
BaseModel
from
typing
import
List
,
Optional
,
Dict
,
Any
from
typing
import
List
,
Optional
,
Dict
,
Any
from
app.api.deps
import
require_edition_for_mode
,
require_role
,
require_binding
from
app.api.deps
import
require_edition_for_mode
,
require_role
,
require_binding
from
app.services.dashboard
import
(
from
app.services.dashboard
import
(
student_today_summary
,
student_today_summary
,
student_week_schedule
,
homeroom_current_summary
,
homeroom_current_summary
,
department_overview
,
department_overview
,
campus_overview
,
campus_overview
,
...
@@ -34,6 +35,21 @@ class StudentTodaySummary(BaseModel):
...
@@ -34,6 +35,21 @@ class StudentTodaySummary(BaseModel):
today_attendance
:
List
[
StudentTodayAttendance
]
today_attendance
:
List
[
StudentTodayAttendance
]
today_conduct
:
Dict
[
str
,
Any
]
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
HomeroomLesson
(
BaseModel
):
class_id
:
Optional
[
str
]
class_id
:
Optional
[
str
]
course_name
:
Optional
[
str
]
course_name
:
Optional
[
str
]
...
@@ -98,6 +114,23 @@ class CampusOverview(BaseModel):
...
@@ -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
:
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
)
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
(
@
router
.
get
(
"/homeroom/current"
,
"/homeroom/current"
,
summary
=
"班主任端:当前节次课程与地点、出勤率、请假、指示"
,
summary
=
"班主任端:当前节次课程与地点、出勤率、请假、指示"
,
...
...
app/core/config.py
View file @
e13c1477
...
@@ -32,5 +32,8 @@ class Settings(BaseSettings):
...
@@ -32,5 +32,8 @@ class Settings(BaseSettings):
CORS_ALLOWED_ORIGINS
:
str
=
os
.
getenv
(
"CORS_ALLOWED_ORIGINS"
,
"*"
)
CORS_ALLOWED_ORIGINS
:
str
=
os
.
getenv
(
"CORS_ALLOWED_ORIGINS"
,
"*"
)
GITHUB_DEFAULT_REPO
:
str
=
os
.
getenv
(
"GITHUB_DEFAULT_REPO"
,
""
)
GITHUB_DEFAULT_REPO
:
str
=
os
.
getenv
(
"GITHUB_DEFAULT_REPO"
,
""
)
GITHUB_TOKEN
:
str
=
os
.
getenv
(
"GITHUB_TOKEN"
,
""
)
GITHUB_TOKEN
:
str
=
os
.
getenv
(
"GITHUB_TOKEN"
,
""
)
# 学期配置
TERM_START_DATE
:
str
=
os
.
getenv
(
"TERM_START_DATE"
,
"2025-09-01"
)
# 默认开学日期
settings
=
Settings
()
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
typing
import
Dict
,
List
,
Any
from
bson
import
ObjectId
from
bson
import
ObjectId
from
fastapi
import
HTTPException
from
fastapi
import
HTTPException
from
app.db.mongodb
import
db
from
app.db.mongodb
import
db
from
app.core.config
import
settings
async
def
_today_iso
()
->
str
:
async
def
_today_iso
()
->
str
:
return
datetime
.
now
()
.
date
()
.
isoformat
()
return
datetime
.
now
()
.
date
()
.
isoformat
()
...
@@ -10,6 +11,34 @@ async def _today_iso() -> str:
...
@@ -10,6 +11,34 @@ async def _today_iso() -> str:
async
def
_weekday
()
->
int
:
async
def
_weekday
()
->
int
:
return
datetime
.
now
()
.
isoweekday
()
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
:
async
def
_current_period
()
->
int
:
h
=
datetime
.
now
()
.
hour
h
=
datetime
.
now
()
.
hour
if
h
<
10
:
if
h
<
10
:
...
@@ -27,13 +56,21 @@ async def _get_primary_binding(account_id: ObjectId) -> Dict[str, Any]:
...
@@ -27,13 +56,21 @@ async def _get_primary_binding(account_id: ObjectId) -> Dict[str, Any]:
return
b
return
b
async
def
_get_student_entity
(
account_id
:
ObjectId
,
binding
:
Dict
[
str
,
Any
])
->
Dict
[
str
,
Any
]:
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
:
if
s
:
return
s
return
s
raise
HTTPException
(
status_code
=
404
,
detail
=
"未找到学生实体"
)
raise
HTTPException
(
status_code
=
404
,
detail
=
"未找到学生实体"
)
async
def
_get_teacher_entity
(
account_id
:
ObjectId
,
binding
:
Dict
[
str
,
Any
])
->
Dict
[
str
,
Any
]:
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
:
if
t
:
return
t
return
t
raise
HTTPException
(
status_code
=
404
,
detail
=
"未找到教师实体"
)
raise
HTTPException
(
status_code
=
404
,
detail
=
"未找到教师实体"
)
...
@@ -97,6 +134,63 @@ async def student_today_summary(current_user: Dict[str, Any]) -> Dict[str, Any]:
...
@@ -97,6 +134,63 @@ async def student_today_summary(current_user: Dict[str, Any]) -> Dict[str, Any]:
"today_conduct"
:
conduct
,
"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
]:
async
def
homeroom_current_summary
(
current_user
:
Dict
[
str
,
Any
])
->
Dict
[
str
,
Any
]:
today
=
await
_today_iso
()
today
=
await
_today_iso
()
weekday
=
await
_weekday
()
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