feat(lessonplan): 实现基于AI的学案自动生成与管理功能

- 新增DifyArticleClient工具类,实现基于Dify API的对话与文本生成功能
- 创建LessonPlansService接口及其实现,实现学案按天生成及存储
- 设计LessonPlansDO和StudentLessonPlansDO数据对象及对应MyBatis映射和数据库操作
- 扩展VocabularyBankDO实体及Mapper,支持查询单元词汇和学生未掌握词汇
- 利用deepoove-poi模板技术生成Word格式的学习计划文档,包含词汇、复习和练习
- 开发StringToPlanMapUtil工具类,解析AI返回结果为结构化学案内容
- 新增JUnit测试用例验证AI对话功能及学案生成逻辑正确性
- 更新Spring Boot配置,添加AI接口地址及密钥等参数
- 在前端Vue项目中新建学案页面,路由配置及导航菜单支持学案访问
This commit is contained in:
lbw
2025-12-16 19:08:58 +08:00
parent d027c9c7e6
commit 7f41036193
26 changed files with 831 additions and 5 deletions

View File

@@ -25,5 +25,13 @@ templates:
word: C:\project\java\enlish_edu\enlish\enlish-service\src\main\resources\templates\assessment_v5.docx
count: 100
data: C:\project\tess
plan:
weekday: C:\project\java\enlish_edu\enlish\enlish-service\src\main\resources\templates\tem_study_plan_v1.docx
weekend: C:\project\java\enlish_edu\enlish\enlish-service\src\main\resources\templates\study_plan_review_v1.docx
plan_day: 7
tmp:
png: C:\project\java\enlish_edu\enlish\enlish-service\src\main\resources\tmp\png\
png: C:\project\java\enlish_edu\enlish\enlish-service\src\main\resources\tmp\png\
ai:
key: app-loC6IrJpj4cS54MAYp73QtGl
url: https://chat.cosonggle.com/v1/chat-messages

View File

@@ -45,7 +45,7 @@
targetProject="src/main/java"/>
<!-- 需要生成的表-实体类 -->
<table tableName="grade_class" domainObjectName="GradeClassDO"
<table tableName="student_lesson_plans" domainObjectName="StudentLessonPlansDO"
enableCountByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"

View File

@@ -13,5 +13,11 @@
where grade_id = #{gradeId}
</select>
<select id="selectByUnitId" resultMap="BaseResultMap">
select *
from grade_unit
where unit_id = #{unitId}
</select>
</mapper>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yinlihupo.enlish.service.domain.mapper.LessonPlansDOMapper">
<resultMap id="BaseResultMap" type="com.yinlihupo.enlish.service.domain.dataobject.LessonPlansDO">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="title" jdbcType="VARCHAR" property="title" />
<result column="grade_id" jdbcType="VARCHAR" property="gradeId" />
<result column="unit_id" jdbcType="INTEGER" property="unitId" />
<result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.yinlihupo.enlish.service.domain.dataobject.LessonPlansDO">
<result column="content_details" jdbcType="LONGVARCHAR" property="contentDetails" />
</resultMap>
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
insert into lesson_plans (title, grade_id, unit_id, content_details, created_at)
values (#{title}, #{gradeId}, #{unitId}, #{contentDetails}, now())
</insert>
<select id="selectById" resultMap="ResultMapWithBLOBs">
select *
from lesson_plans
where id = #{id}
</select>
</mapper>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yinlihupo.enlish.service.domain.mapper.StudentLessonPlansDOMapper">
<resultMap id="BaseResultMap" type="com.yinlihupo.enlish.service.domain.dataobject.StudentLessonPlansDO">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="student_id" jdbcType="INTEGER" property="studentId" />
<result column="plan_id" jdbcType="INTEGER" property="planId" />
<result column="start_time" jdbcType="TIMESTAMP" property="startTime" />
<result column="mastery_rat" jdbcType="DECIMAL" property="masteryRat" />
<result column="total_count" jdbcType="INTEGER" property="totalCount" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.yinlihupo.enlish.service.domain.dataobject.StudentLessonPlansDO">
<result column="memorized_words_json" jdbcType="LONGVARCHAR" property="memorizedWordsJson" />
<result column="unmemorized_words_json" jdbcType="LONGVARCHAR" property="unmemorizedWordsJson" />
</resultMap>
<insert id="insert">
insert into student_lesson_plans (student_id, plan_id, start_time, mastery_rat, total_count)
values (#{studentId,jdbcType=INTEGER}, #{planId,jdbcType=INTEGER},
now(), 0.0, 0
)
</insert>
</mapper>

View File

@@ -7,6 +7,7 @@
<result column="definition" jdbcType="VARCHAR" property="definition" />
<result column="pronunciation" jdbcType="VARCHAR" property="pronunciation" />
<result column="unit_id" jdbcType="INTEGER" property="unitId" />
<result column="pos" jdbcType="VARCHAR" property="pos" />
</resultMap>
@@ -28,6 +29,9 @@
<if test="unitId != null">
unit_id,
</if>
<if test="pos != null">
pos,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
@@ -45,6 +49,9 @@
<if test="unitId != null">
#{unitId,jdbcType=INTEGER},
</if>
<if test="pos != null">
#{pos,jdbcType=VARCHAR},
</if>
</trim>
</insert>
@@ -69,4 +76,46 @@
from vocabulary_bank
</select>
<select id="selectVocabularyBankDOAllByUnitId" resultMap="BaseResultMap">
select *
from vocabulary_bank
where unit_id = #{unitId}
</select>
<select id="selectVocabularyBankListStudentNotMaster" resultMap="BaseResultMap">
<![CDATA[
select *
from vocabulary_bank
where unit_id in (
select unit_id
from grade_unit
where grade_id = #{gradeId}
)
and id in (
select word_id
from word_mastery_log
where memory_strength < 0
and student_id = #{studentId}
)
]]>
</select>
<select id="selectVocabularyBankListSelfCheck" resultMap="BaseResultMap">
select *
from vocabulary_bank vb
inner join grade_unit gu on vb.unit_id = gu.unit_id
inner join word_mastery_log wml on vb.id = wml.word_id
where gu.grade_id = #{gradeId}
and wml.student_id = #{studentId}
<!-- 修复not in的语法错误 + 空集合防护 -->
<if test="ids != null and ids.size() > 0">
and vb.id not in (
<foreach item="id" collection="ids" separator=",">
#{id}
</foreach>
)
</if>
limit #{wordCount}
</select>
</mapper>