学生端选课进课闭环
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
from flask import current_app
|
||||
import requests
|
||||
|
||||
def upload_file(rb_file, file_name):
|
||||
if file_name is not None and "/" in file_name:
|
||||
@@ -21,3 +22,21 @@ def delete_file(file_name):
|
||||
Key=file_name,
|
||||
)
|
||||
return True
|
||||
|
||||
def get_text_file(file_name):
|
||||
response = requests.get(file_name)
|
||||
|
||||
if response.status_code == 200:
|
||||
print(file_name)
|
||||
# print(f"get_text_file: {response.text}")
|
||||
|
||||
return response.text
|
||||
else:
|
||||
return None
|
||||
|
||||
return response.text
|
||||
# if file_name is not None and "/" in file_name:
|
||||
# file_name = file_name.split("/")[-1]
|
||||
# cos_client = current_app.extensions["cos_client"]
|
||||
# print(f"get_text_file: {file_name}")
|
||||
# return cos_client.get_object(Bucket=current_app.config["TENCENT_COS"]["bucket"], Key=file_name)["Body"].read()
|
||||
@@ -10,21 +10,43 @@ from ..services.cos_service import upload_file, delete_file
|
||||
|
||||
from ..models.material import Material
|
||||
|
||||
# 假设你已有这两个 loader
|
||||
from db.course import load_course_from_json
|
||||
|
||||
def load_course(course_id: str):
|
||||
return load_course_from_json(
|
||||
course_id, course_data_dir=current_app.config["COURSE_DATA_DIR"]
|
||||
)
|
||||
def get_new_edit_materials(num: int)->List[Material]:
|
||||
mongo = current_app.extensions["mongo"]
|
||||
materials = mongo.db.materials.find().sort("updated_at", -1).limit(num)
|
||||
returnCode = []
|
||||
for material in materials:
|
||||
returnCode.append(Material(**material))
|
||||
returnCode[-1]._id = str(material['_id'])
|
||||
return returnCode
|
||||
|
||||
def user_selected_course(user_obj):
|
||||
briefs = []
|
||||
for cid in getattr(user_obj, "select_course", []):
|
||||
course_obj = load_material(cid)
|
||||
brief={}
|
||||
brief["_id"] = cid
|
||||
brief["name"] = course_obj.name
|
||||
brief["description"] = course_obj.description
|
||||
brief["image_url"] = course_obj.image_url
|
||||
brief["created_at"] = course_obj.created_at.strftime("%Y-%m-%d %H:%M:%S")
|
||||
brief["updated_at"] = course_obj.updated_at.strftime("%Y-%m-%d %H:%M:%S")
|
||||
brief["chapters"] = [chapter.model_dump() for chapter in course_obj.chapters]
|
||||
briefs.append(brief)
|
||||
return briefs
|
||||
|
||||
def user_selected_course_briefs(user_obj):
|
||||
"""根据用户对象的选课列表,拼装课程简要信息数组"""
|
||||
course_list = current_app.extensions["course_list"]
|
||||
briefs = []
|
||||
for cid in getattr(user_obj, "select_course", []):
|
||||
course_obj = load_course(cid)
|
||||
brief = course_list.get_course_brief_info(cid, course_obj)
|
||||
course_obj = load_material(cid)
|
||||
brief={}
|
||||
brief["_id"] = cid
|
||||
brief["name"] = course_obj.name
|
||||
brief["description"] = course_obj.description
|
||||
brief["image_url"] = course_obj.image_url
|
||||
brief["created_at"] = course_obj.created_at.strftime("%Y-%m-%d %H:%M:%S")
|
||||
brief["updated_at"] = course_obj.updated_at.strftime("%Y-%m-%d %H:%M:%S")
|
||||
briefs.append(brief)
|
||||
return briefs
|
||||
|
||||
@@ -45,6 +67,7 @@ def create_material(teacher_id, material_name, description, chapters, image_url)
|
||||
def load_material(material_id):
|
||||
mongo = current_app.extensions["mongo"]
|
||||
material = mongo.db.materials.find_one({"_id": ObjectId(material_id)})
|
||||
material['_id'] = material_id
|
||||
return Material(**material)
|
||||
|
||||
def update_material(material_id, chapters):
|
||||
|
||||
@@ -1,10 +1,35 @@
|
||||
import os, shutil, markdown
|
||||
from flask import current_app
|
||||
from ..services.course_service import load_material
|
||||
from ..services.cos_service import get_text_file
|
||||
|
||||
def convert_markdown_to_html(md_file_path: str) -> str:
|
||||
"""读取 markdown 并转成 HTML 片段"""
|
||||
with open(md_file_path, 'r', encoding='utf-8') as f:
|
||||
md_content = f.read()
|
||||
return markdown.markdown(md_content)
|
||||
def load_full_markdown_file(course_id, chapter_name, lesson_name):
|
||||
material = load_material(course_id)
|
||||
for chapter in material.chapters:
|
||||
if chapter.chapter_name == chapter_name:
|
||||
for lesson in chapter.lessons:
|
||||
if lesson.lesson_name == lesson_name:
|
||||
return get_text_file(lesson.markdown_lesson_file_link), get_text_file(lesson.markdown_prompt_file_name), get_text_file(lesson.markdown_score_prompt_file_link)
|
||||
return None, None, None
|
||||
|
||||
def load_markdown_file(course_id, chapter_name, lesson_name):
|
||||
material = load_material(course_id)
|
||||
file_link = None
|
||||
for chapter in material.chapters:
|
||||
if chapter.chapter_name == chapter_name:
|
||||
for lesson in chapter.lessons:
|
||||
if lesson.lesson_name == lesson_name:
|
||||
file_link = lesson.markdown_lesson_file_link
|
||||
break
|
||||
break
|
||||
if file_link is None:
|
||||
return None
|
||||
print(f"load_markdown_file: {file_link}")
|
||||
return get_text_file(file_link)
|
||||
|
||||
def convert_markdown_to_html(md_file: str) -> str:
|
||||
"""将 markdown 文件转成 HTML 片段"""
|
||||
return markdown.markdown(md_file)
|
||||
|
||||
def wrap_with_styles(html_content: str) -> str:
|
||||
"""加上 CSS 样式和外层 HTML"""
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# myapp/services/memory_service.py
|
||||
import os, json
|
||||
from flask import current_app
|
||||
from db.user import load_user_from_json # 按你项目实际替换
|
||||
|
||||
def save_chapter_memory_by_uuid(
|
||||
user_uuid: str,
|
||||
@@ -14,11 +13,13 @@ def save_chapter_memory_by_uuid(
|
||||
):
|
||||
uuid2username = current_app.extensions["uuid2username"]
|
||||
user_map = current_app.extensions["user_uuid2UserClass"] # 可复用缓存
|
||||
user_data_dir = current_app.config["USER_DATA_DIR"]
|
||||
users_list = current_app.extensions["users_list"]
|
||||
|
||||
username = uuid2username[user_uuid]
|
||||
# 若内存里已有用户对象就直接用;否则从 JSON 载入
|
||||
user_obj = user_map.get(user_uuid) or load_user_from_json(username, user_data_dir=user_data_dir)
|
||||
user_obj = user_map.get(user_uuid) or users_list.get_user_by_name(
|
||||
username
|
||||
)
|
||||
user_map[user_uuid] = user_obj
|
||||
|
||||
user_obj.save_chapter_memory(
|
||||
|
||||
185
Html/apps/services/user_db_service.py
Normal file
185
Html/apps/services/user_db_service.py
Normal file
@@ -0,0 +1,185 @@
|
||||
from flask import current_app
|
||||
from bson.binary import Binary
|
||||
import uuid
|
||||
import os
|
||||
# Example usage:
|
||||
import json
|
||||
from datetime import datetime
|
||||
import copy
|
||||
from ..models.material import Material
|
||||
|
||||
class User:
|
||||
def __init__(self, user_uuid, username, teacher, password, select_course, head_icon, _id, **kwargs):
|
||||
self.user_uuid = user_uuid # User UUID
|
||||
self.username = username
|
||||
self.teacher = teacher
|
||||
self.password = password
|
||||
self.select_course = select_course # List of selected courses
|
||||
self.head_icon = head_icon # URL of the user's head icon
|
||||
self._id = _id
|
||||
self.kwargs = kwargs
|
||||
def save_chapter_memory(self, course_id, lesson_name, subchapter_title, mem_list, score, is_rebuttal):
|
||||
'''
|
||||
Save the memory of a chapter
|
||||
into the mongo db
|
||||
'''
|
||||
try:
|
||||
mongo = current_app.extensions["mongo"]
|
||||
cp = mongo.db.course_process.find_one({"user_uuid": self.user_uuid, "material_id": course_id})
|
||||
if not cp:
|
||||
return
|
||||
cp['course_last_study_date'] = datetime.now().strftime('%Y-%m-%d')
|
||||
have_lesson = False
|
||||
for _ in range(len(cp['lesson_processs'])):
|
||||
lesson_process, cname, lname = cp['lesson_processs'][_]
|
||||
if lname == lesson_name:
|
||||
have_lesson = True
|
||||
saveed = False
|
||||
for i in range(len(lesson_process)):
|
||||
step = lesson_process[i]
|
||||
if step['title'] == subchapter_title:
|
||||
step['dialog'] = mem_list
|
||||
if is_rebuttal:
|
||||
step['rebuttal_score'] = score
|
||||
else:
|
||||
step['score'] = score
|
||||
step['is_rebuttal'] = is_rebuttal
|
||||
saveed = True
|
||||
break
|
||||
if not saveed:
|
||||
cp['lesson_processs'].append({
|
||||
'title': subchapter_title,
|
||||
'dialog': mem_list,
|
||||
'score': score,
|
||||
'is_rebuttal': is_rebuttal,
|
||||
'rebuttal_score': score if is_rebuttal else 0,
|
||||
})
|
||||
break
|
||||
if not have_lesson:
|
||||
cp['lesson_processs'].append(([], chapter_name, lesson_name))
|
||||
mongo.db.course_process.update_one({"user_uuid": self.user_uuid, "material_id": course_id}, {"$set": cp})
|
||||
except Exception as e:
|
||||
print("=-=-=-=-=-=")
|
||||
print(e)
|
||||
def get_all_course_progress(self):
|
||||
mongo = current_app.extensions["mongo"]
|
||||
course_processes = mongo.db.course_process.find({"user_uuid": self.user_uuid})
|
||||
for cp in course_processes:
|
||||
print(f"Course: {cp['material_id']}")
|
||||
for lessons,chapter_name,lesson_name in cp["lesson_processs"]:
|
||||
print(f" Lesson ID: {lesson_name}")
|
||||
for step in lessons:
|
||||
print(f" Chapter Dialog: {step['dialog']}")
|
||||
print(f" Chapter Score: {step['score']}")
|
||||
print(f" Rebuttal: {'Yes' if step['is_rebuttal'] else 'No'}")
|
||||
if step['is_rebuttal']:
|
||||
print(f" Rebuttal Score: {step['rebuttal_score']}")
|
||||
|
||||
def get_course_progress(self, course_id):
|
||||
mongo = current_app.extensions["mongo"]
|
||||
cp = mongo.db.course_process.find_one({"user_uuid": self.user_uuid, "material_id": course_id})
|
||||
return cp
|
||||
|
||||
def select_new_course(self, course_id, course:Material):
|
||||
try:
|
||||
if course_id in self.select_course:
|
||||
return True
|
||||
self.select_course.append(course_id)
|
||||
mongo = current_app.extensions["mongo"]
|
||||
mongo.db.course_process.insert_one({
|
||||
'user_uuid': self.user_uuid,
|
||||
'material_id': course_id,
|
||||
'lesson_processs':[],
|
||||
'course_put_in_date':datetime.now().strftime('%Y-%m-%d'),
|
||||
'course_last_study_date':datetime.now().strftime('%Y-%m-%d'),
|
||||
'course_total_study_time':0})
|
||||
for chapter in course.chapters:
|
||||
for lesson in chapter.lessons:
|
||||
mongo.db.course_process.update_one({"user_uuid": self.user_uuid, "material_id": course_id}, {"$push": {"lesson_processs": ([], chapter.chapter_name, lesson.lesson_name)}})
|
||||
self.select_course.append(course_id)
|
||||
mongo.db.users.update_one({"user_uuid": self.user_uuid}, {"$push": {"select_course": course_id}})
|
||||
except Exception as e:
|
||||
print("=-=-=-=-=-=")
|
||||
print(e)
|
||||
return False
|
||||
return True
|
||||
def save_to_db(self):
|
||||
current_app.extensions["mongo"].db.users.update_one({"user_uuid": self.user_uuid}, {"$set": self.__json__()})
|
||||
|
||||
|
||||
def __json__(self):
|
||||
return {
|
||||
'username': self.username,
|
||||
'teacher': self.teacher,
|
||||
'select_course': self.select_course,
|
||||
'head_icon': self.head_icon,
|
||||
}
|
||||
|
||||
|
||||
|
||||
def to_json(self):
|
||||
return json.dumps(self.__json__(), indent=4)
|
||||
|
||||
|
||||
|
||||
class UserList:
|
||||
|
||||
def __init__(self):
|
||||
"""从mongo中获取用户信息"""
|
||||
self.Users = {}
|
||||
|
||||
def add_user(self, username, password, teacher=False):
|
||||
"""添加新的用户登录信息"""
|
||||
# 检查是否已经有该用户
|
||||
mongo = current_app.extensions["mongo"]
|
||||
if mongo.db.users.find_one({"username": username}) is None:
|
||||
mongo.db.users.insert_one({"user_uuid": Binary.from_uuid(uuid.uuid4()), "username": username, "teacher": teacher, "password": password, "select_course": [], "head_icon": ""})
|
||||
else:
|
||||
print(f"User with ID {username} already exists.")
|
||||
|
||||
def get_user_by_name(self, username):
|
||||
"""根据用户ID获取用户信息"""
|
||||
mongo = current_app.extensions["mongo"]
|
||||
if username not in self.Users:
|
||||
self.Users[username] = User(**mongo.db.users.find_one({"username": username}))
|
||||
return self.Users[username]
|
||||
else:
|
||||
return self.Users[username]
|
||||
|
||||
def has_user(self, username):
|
||||
"""检查用户是否存在"""
|
||||
mongo = current_app.extensions["mongo"]
|
||||
return mongo.db.users.find_one({"username": username}) is not None
|
||||
|
||||
def get_user_is_teacher(self, username):
|
||||
"""获取指定 user_id 的用户是否为教师"""
|
||||
mongo = current_app.extensions["mongo"]
|
||||
if mongo.db.users.find_one({"username": username}) is not None:
|
||||
result = mongo.db.users.find_one({"username": username})
|
||||
return result['teacher']
|
||||
return None
|
||||
|
||||
def get_user_pswd(self, username):
|
||||
"""获取指定 user_id 的用户信息"""
|
||||
mongo = current_app.extensions["mongo"]
|
||||
if mongo.db.users.find_one({"username": username}) is not None:
|
||||
result = mongo.db.users.find_one({"username": username})
|
||||
return result['password']
|
||||
return None
|
||||
|
||||
def update_password(self, username, new_password):
|
||||
"""更新用户的密码"""
|
||||
assert mongo.db.users.find_one({"username": username}) is not None, f"User with ID {username} does not exist."
|
||||
mongo.db.users.update_one({"username": username}, {"$set": {"password": new_password, "teacher": mongo.db.users.find_one({"username": username})['teacher']}})
|
||||
|
||||
def delete_user(self, username):
|
||||
"""删除用户"""
|
||||
assert mongo.db.users.find_one({"username": username}) is not None, f"User with ID {username} does not exist."
|
||||
mongo.db.users.delete_one({"username": username})
|
||||
|
||||
def get_all_users(self):
|
||||
"""获取所有用户的信息"""
|
||||
mongo = current_app.extensions["mongo"]
|
||||
return list(mongo.db.users.find())
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ import os
|
||||
from typing import Tuple
|
||||
from flask import current_app, session
|
||||
|
||||
# 假设你已有这两个 loader
|
||||
from db.user import load_user_from_json
|
||||
|
||||
def _username_from_session() -> str:
|
||||
"""通过 session['user_id'] -> username"""
|
||||
@@ -28,8 +26,9 @@ def get_or_load_current_user():
|
||||
|
||||
user_map = current_app.extensions["user_uuid2UserClass"]
|
||||
if user_uuid not in user_map:
|
||||
user_map[user_uuid] = load_user_from_json(
|
||||
username, user_data_dir=current_app.config["USER_DATA_DIR"]
|
||||
users_list = current_app.extensions["users_list"]
|
||||
user_map[user_uuid] = users_list.get_user_by_name(
|
||||
username
|
||||
)
|
||||
return user_map[user_uuid]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user