(九)学生写作画像可视化

article/2025/6/22 18:45:44

在上次报告中提到的无法正确识别登录状态的问题已经解决,现在调用后端api时可以正确load_user并得到登录状态。
登录状态问题解决后,本次主要实现的是学生写作画像的数据可视化,学生可以登陆后查看自己之前的作文列表与历史各维度得分,获得得分雷达图,进行数据可视化。

一、学生写作中心后端

为了实现学生写作中心,主要是后端新增student_dashboard_routes.py。该文件定义了获取学生文章列表,学生作文分数,老师反馈等api供前端调用。
在get_student_essays中,通过获取currentuserid,进而使用models.py中已经定义的get_writing_history方法来查询每个studentid下所有的essay,并且在essay_list中读取每个essay的id来获取分数并计算平均分。

@student_dashboard.route('/student/essays', methods=['GET'])
@login_required
def get_student_essays():"""获取学生的所有作文列表"""try:user_model = UserModel(mysql)essays = user_model.get_writing_history(current_user.id)essay_list = []for essay in essays:essay_id = int(essay['essay_id'])  # 确保转为整数print(f"当前处理作文ID: {essay_id}")  # 使用f-string            # 获取作文评分profile = user_model.get_writing_profile(current_user.id,essay_id)# 获取教师评语feedback = user_model.get_teacher_feedback(current_user.id)essay_data = {'id': essay['essay_id'],'title': essay.get('title', ''),'createTime': essay['created_at'].isoformat(),'updateTime': essay['created_at'].isoformat(),'score': None,'scores': None,'comments': None}# 添加评分信息if profile:essay_data['score'] = round((profile['grammar_score'] + profile['idea_score'] + profile['structure_score'] + profile['rhetoric_score'] + profile['emotion_score'] + profile['innovation_score']) / 6, 1)essay_data['scores'] = {'grammar': round(profile['grammar_score'], 1),'idea': round(profile['idea_score'], 1),'structure': round(profile['structure_score'], 1),'rhetoric': round(profile['rhetoric_score'], 1),'emotion': round(profile['emotion_score'], 1),'innovation': round(profile['innovation_score'], 1)}# 添加教师评语if feedback:essay_data['comments'] = feedback[0]['feedback_content'] if feedback else Noneessay_list.append(essay_data)return jsonify({'success': True,'data': essay_list})except Exception as e:return jsonify({'success': False,'error': str(e)}), 500

而在调用get_student_essays之后,便可以使用get_essay_detail,通过essay_id来获取更为详细的作文内容,这些返回给前端,前端将这些数据生成雷达图进行可视化。

@student_dashboard.route('/student/essay/<int:essay_id>', methods=['GET'])
@login_required
def get_essay_detail(essay_id):"""获取单篇作文的详细信息"""try:user_model = UserModel(mysql)# 获取作文内容cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)cursor.execute('SELECT * FROM essays WHERE id = %s AND student_id = %s',(essay_id, current_user.id))essay = cursor.fetchone()cursor.close()if not essay:return jsonify({'success': False,'error': '作文不存在或无权访问'}), 404# 获取作文评分profile = user_model.get_writing_profile(current_user.id,essay_id)# 获取教师评语feedback = user_model.get_teacher_feedback(current_user.id)# 获取写作风格特征style = user_model.get_style_features(current_user.id)essay_detail = {'id': essay['id'],'title': essay['title'],'content': essay['content'],'createTime': essay['submission_date'].isoformat(),'updateTime': essay['submission_date'].isoformat(),'score': None,'scores': None,'comments': None,'styleFeatures': None}# 添加评分信息if profile:essay_detail['score'] = round((profile['grammar_score'] + profile['idea_score'] + profile['structure_score'] + profile['rhetoric_score'] + profile['emotion_score'] + profile['innovation_score']) / 6, 1)essay_detail['scores'] = {'grammar': round(profile['grammar_score'], 1),'idea': round(profile['idea_score'], 1),'structure': round(profile['structure_score'], 1),'rhetoric': round(profile['rhetoric_score'], 1),'emotion': round(profile['emotion_score'], 1),'innovation': round(profile['innovation_score'], 1)}# 添加教师评语if feedback:essay_detail['comments'] = feedback[0]['feedback_content'] if feedback else None# 添加写作风格特征if style:essay_detail['styleFeatures'] = {'vocabularyDiversity': style[0]['vocabulary_diversity'],'sentenceComplexity': style[0]['sentence_complexity'],'paragraphCoherence': style[0]['paragraph_coherence'],'argumentPatterns': style[0]['argument_patterns'],'wordChoiceFeatures': style[0]['word_choice_features'],'styleKeywords': style[0]['style_keywords']}return jsonify({'success': True,'data': essay_detail})except Exception as e:return jsonify({'success': False,'error': str(e)}), 500

这样就将之前所用的loginManager结合起来,实现用户登录查询。

二、学生写作中心前端

因为后端整个登录逻辑的更改,为了与后端登录认证相兼容,前端的登陆方法也进行一些改变。
通过在原始前端方法中加入withCredentials: true,使得浏览器能够保存并使用初始登录的session,进而确保之后每次调用api都会使用相同的session,这也也就使得后端能认证登录的状态。

const handleLogin = async () => {try {const response = await axios.post('http://localhost:5000/api/login', form.value, {withCredentials: true  // ✅ 关键设置});if (response.data.status === 'success') {router.push('/student-dashboard');}} catch (err) {error.value = err.response?.data?.message || '登录失败';}
};

前端为了获取文章,调用/api/student/essays,后端成功调用即可返回

async fetchEssays() {this.loading = true;this.error = null;try {const response = await axios.get('/api/student/essays', {withCredentials: true,headers: {'Accept': 'application/json','Content-Type': 'application/json'}});if (response.data.success) {this.essays = response.data.data;if (this.essays.length > 0) {this.selectEssay(this.essays[0]);}}} catch (err) {console.error('获取作文列表失败:', err);this.error = '获取作文列表失败,请稍后重试';} finally {this.loading = false;}},

获取文章数据后可使用getDimensionName,initRadarChart初始化可视化图表

        getDimensionName(dimension) {const dimensionMap = {grammar: '语法',idea: '内容',structure: '结构',rhetoric: '修辞',emotion: '情感',innovation: '创新'};return dimensionMap[dimension] || dimension;},initRadarChart() {if (!this.selectedEssay || !this.selectedEssay.scores) return;if (this.chart) {this.chart.dispose();}const chartDom = this.$refs.radarChart;this.chart = echarts.init(chartDom);const dimensions = Object.keys(this.selectedEssay.scores);const scores = Object.values(this.selectedEssay.scores);const option = {radar: {indicator: dimensions.map(dim => ({name: this.getDimensionName(dim),max: 100})),splitNumber: 4,axisName: {color: '#666'}},series: [{type: 'radar',data: [{value: scores,name: '能力维度',areaStyle: {color: 'rgba(74, 144, 226, 0.3)'},lineStyle: {color: '#4a90e2'},itemStyle: {color: '#4a90e2'}}]}]};this.chart.setOption(option);}},

三、结果展示

在这里插入图片描述


http://www.hkcw.cn/article/nsofctAjSD.shtml

相关文章

国家能源集团称从未设拓展中心 警惕假冒机构

国家能源集团称从未设拓展中心 警惕假冒机构。国家能源集团近期发现有不法分子假冒其名义在全国多地设立所谓“拓展中心”,涉嫌从事违法活动,并通过抖音、微信视频号等网络平台进行虚假宣传。对此,国家能源集团发布严正声明,强调从未在全国任何地区设立任何“拓展中心”或“…

官方证实!美国停止对华芯片设计软件(EDA)销售 打压“中国芯”再升级

面对中国在先进芯片领域取得的重大突破,美国特朗普政府将目光转向了设计芯片的软件,试图借此打压“中国芯”。英国《金融时报》5月28日报道称,美国政府已采取措施限制向中国出售此类产品。美国彭博社也报道了类似消息,称美国商务部工业与安全局已致函部分头部美国电子设计自…

乌称对俄军机发动大规模袭击 摧毁41架战略轰炸机

俄乌第二轮谈判定于6月2日举行。谈判前夕,乌克兰声称对俄罗斯实施了一次特别行动,摧毁了41架俄战略轰炸机。然而,俄媒认为乌方宣称的战果并不符合实际。乌克兰国家安全局在社交媒体上表示,6月1日晚对俄罗斯发起了一次代号为“蛛网”的特种作战行动,袭击了俄军的战略轰炸机…

离婚,失业,失亲……她40岁后的人生那么难?美丽无关年龄

离婚,失业,失亲……她40岁后的人生那么难?美丽无关年龄!美丽与年龄无关,即便他人不再认同你。都说年龄是女人最大的秘密,尤其是生儿育女之后,“衰老”这个词便成了女人内心最大的恐惧和痛处。如今,三八妇女节甚至被迫更名为“三八女神节”,以消除称呼上的忌讳。然而,…

巴西登革热疑似及确诊病例超143万 疫情严峻引发关注

巴西卫生部发布消息称,截至6月2日,今年该国登革热疑似及确诊病例已达到1430300例,死亡病例为1075例,另有818例疑似死亡病例正在调查中。圣保罗州、米纳斯吉拉斯州和巴拉那州是目前巴西登革热疫情最为严重的地区。责任编辑:zhangxiaohua

四川古蔺警方通报7人殴打未成年人 误会引发暴力事件

四川古蔺县警方于6月2日通报了一起涉及未成年人的暴力事件。据报道,两名未成年人在骑车时发出笑声,被15岁的陈某甲误以为是在嘲笑自己。随后,陈某甲与其他六人一起在地下停车场对这两名未成年人进行了殴打。目前,七名涉案人员均已被警方抓获,其中两人因涉嫌犯罪被刑事拘留…

多位男星减肥成功 压力已给到沈腾 贾冰瘦身引热议

5月31日,贾冰的妻子发布了一段视频,并配文“从此我家多了个瘦子”。在两人合影中,贾冰明显瘦了很多。评论区里大家纷纷询问他如何瘦下来的,甚至有人表示瘦得认不出来了。贾冰的妻子回复说,主要是通过少吃(一天只吃一顿)和运动来减肥的。贾冰在评论区幽默地回应说:“一次…

任务25:绘制全局时间线(TimeLine)

任务描述 知识点: DjangoECharts时间线图重 点: ECharts时间线图内 容: 参考ECharts官网示例创建timeline.js,绘制时间线图引入js文件,并调用绘图函数时间线图形配置项微调任务指导 1、参考ECharts官网示例:(https://echarts.apache.org/examples/zh/index.html),…

2025年渗透测试面试题总结-青藤云[校招]红队攻防岗(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 青藤云[校招]红队攻防岗 1. 数据库提权 2. Redis计划任务提权 3. 绕过杀软执行数据库命令 4. SQL Server…

HCIP:MPLS LDP的原理和配置

目录 一、MPLS LDP的原理 1.回顾MPLS 2.MPLS LDP的基本概念 3.LDP的工作过程主要分为两部分 ​4.LDP会话&#xff1a; 5.LDP的对等体 6.LDP的消息 7.LDP工作原理 8.标签的发布和管理 二、MPLD LDP的实验配置 1.配置IP地址和OSPF 2.配置MPLS LDP 3.查看各个设备的…

这个地级市,“含潮量”全国顶流? 潮玩之都的转型之路

这个地级市,“含潮量”全国顶流? 潮玩之都的转型之路!东莞市中心矗立着一座12米高的巨型潮玩雕塑“劳拉”,其轮廓以彩色线条勾勒,充满科幻感。这座2021年落成的城市新地标脚下,延伸出一条由设计工作室、潮玩展销中心和沉浸式体验馆串联的“潮玩大道”。这里不定期举行沙龙…

男子机场取车遭一嗨租车拦车 店员态度恶劣引发争议

男子机场取车遭一嗨租车拦车 店员态度恶劣引发争议!6月2日,苏先生在昆明长水机场停车时遇到了麻烦。他将车停在B2层S1区C7车位,该车位未标注“专用车位”且无人值守。然而当他返回取车时,“一嗨租车”的工作人员告知他该车位已被他们租下,并称他的车停到了他们的店里。苏先…

今年第一批吃菌子中毒的人出现了!小伙吃野生菌后竟开始隔空抓凤凰

近日,云南临沧,胡先生吃野生菌后中毒致幻,躺在病床上隔空抓物。胡先生称自己看到了凤凰、乌贼、水母、蜘蛛、螃蟹......除胡先生外,此前一对昆明情侣因吃见手青中毒,在医院过的“520”近日,有IP地址为昆明的网友发帖称,自己和丈夫在家做菌子吃,结果两人都出现中毒症状,…

乒超联赛门票开售 雄安首迎顶尖赛事

6月9日至11日,2025赛季中国乒乓球俱乐部超级联赛常规赛第一阶段比赛将在河北雄安新区雄安体育中心体育馆举行。门票于6月3日18:00在秀动票务平台开售,票价从288元到788元不等。2025赛季乒超联赛包括男子和女子团体赛,分为三个阶段的常规赛和总决赛,从6月持续到12月。常规赛…

【iOS】ARC 与 Autorelease

ARC 与 Autorelease 文章目录 ARC 与 Autorelease前言何为ARC内存管理考虑方式自己生成的对象,自己持有非自己生成的对象,自己也可以持有不再需要自己持有的对象时释放非自己持有的对象无法释放 ARC的具体实现编译期和运行期ARC做的事情ARC实现: __autoreleasing 与 Autoreleas…

成都一断头路骑手受伤倒地不幸身亡

6月2日,一位网友发视频称,他在前往四川乐山游玩的路上误入成都一个胡同,发现一名摩托车骑手受伤倒在地上,于是帮忙拨打了120急救电话。该网友表示,此事于6月1日发生在成都天府新区东山大道三段附近一处路段,骑手因伤势过重离世,“如果能更早发现,或许还能被抢救回来。”…

媒体:汽车行业的价格战该“刹车”了 行业协会倡议维护健康发展

“618”限时促销活动期间,部分国内车企发起了大幅降价活动,最高直降5.3万元,这标志着新能源汽车市场新一轮“价格战”开始。山东交通广播汽车栏目制作人、资深汽车媒体人胡明表示,这次价格战始于一家车企在5月23日发起的大规模降价,主要原因是该品牌面临更多有竞争力的对手…

男子免费帮老人收麦被强行投喂饮料 河南老乡的热情感动麦客

男子免费帮老人收麦被强行投喂饮料 河南老乡的热情感动麦客!近日,多名跨区作业的麦客通过视频表达了对河南农民的热情感激。这些麦客在河南割麦子期间,不断收到当地老乡的“投喂”。宝歌(化名)是一位来自河北的麦客。5月28日至30日,他在河南漯河割麦子时,一天内收到了五…

76.解决消息重复生成bug

解决完编辑用户消息相关的bug之后重新生成又出现了新的新的新新的bug&#xff08;本飘心已死~&#xff09; 当点击重新重新生成按钮时会出现两个气泡&#xff1a; 这个bug出现的原因是&#xff1a;在regenerateResponse方法中&#xff0c;我们既重置了当前消息内容&#xff0c…

【Python连接数据库基础 01】从原生驱动到ORM框架:Python数据库连接完全指南

【Python连接数据库基础 01】从原生驱动到ORM框架&#xff1a;Python数据库连接完全指南 关键词&#xff1a;Python数据库连接、原生驱动、ORM框架、SQLAlchemy、PyMySQL、psycopg2、数据库编程、连接池、事务管理 摘要&#xff1a;本文从零开始讲解Python连接数据库的完整流程…