Compare commits

..

37 Commits

Author SHA1 Message Date
与非
88c1279f12 按分类批量设置卷内分值 设置卷内单题分值 2026-10-14 14:52:04 +08:00
与非
9eebc9d71d 用户建立 v2 版本 2026-10-09 09:32:48 +08:00
与非
e05a640675 Merge remote-tracking branch 'origin/main' 2026-09-23 14:23:42 +08:00
与非
d28c3da6f8 官网获取文章列表 接口契约 2026-09-23 14:23:26 +08:00
zj
7d13b700f1 update 2026-09-21 09:02:15 +08:00
zj
cba3c123c9 新增获取最新一条AI批改接口 2026-09-21 08:43:12 +08:00
zj
c088a12166 update 2026-09-20 10:51:57 +08:00
zj
4c0429489d 调整AI面试相关接口 2026-09-20 10:24:39 +08:00
与非
3ef41a50ec 课程服务新增官网获取课程列表方法 2026-09-18 10:10:09 +08:00
与非
7f0df32c25 Revert "课程服务新增官网获取热门课程方法"
This reverts commit 70bb3f5468.
2026-09-17 15:41:28 +08:00
与非
70bb3f5468 课程服务新增官网获取热门课程方法 2026-09-17 15:30:38 +08:00
与非
2b19cbb512 题目导入预览修正:新增解析暂存校验与更新契约 2026-09-17 11:08:31 +08:00
zj
66e467b452 将AI申论批改调整为单题模式 2026-09-15 16:09:45 +08:00
zj
121e1f72dc 增加AI申论题相关管理接口 2026-09-15 13:43:24 +08:00
堂吉诃德拉曼查的英豪
b86dc5715e ArticleService契约getContentColumnsByChannel增加platform参数 2026-09-11 14:13:41 +08:00
堂吉诃德拉曼查的英豪
75bb17b51a 获取用户错题v2契约 2026-09-10 11:25:47 +08:00
堂吉诃德拉曼查的英豪
88ffa75eb5 题目管理新增创建与材料内容保存契约 2026-09-08 14:57:01 +08:00
堂吉诃德拉曼查的英豪
2b2dcc0584 题目管理新增管理端分页列表与字段级保存契约 2026-09-08 11:36:45 +08:00
堂吉诃德拉曼查的英豪
e4c509ebef 题型分类接口 subjectId 支持缺省,不传时返回不限科目的分类树 2026-09-08 09:51:15 +08:00
堂吉诃德拉曼查的英豪
9ae3b1f4b6 科目加年份筛选试卷总数 2026-09-04 11:25:31 +08:00
堂吉诃德拉曼查的英豪
a8d5109a0a CampusRelation契约新增首页科目套卷统计方法 2026-09-03 14:34:21 +08:00
堂吉诃德拉曼查的英豪
2f530d6595 ExamService契约新增错题练习抽题方法 2026-09-02 10:26:42 +08:00
堂吉诃德拉曼查的英豪
328a5f1a66 面试题音频:新增批量查询音频状态与列表附加音频状态契约 2026-09-01 14:29:38 +08:00
堂吉诃德拉曼查的英豪
7f258560a4 AI面试朗读接口新增题目音频同步方法 2026-08-31 14:15:03 +08:00
堂吉诃德拉曼查的英豪
9e3b6a400d Merge branch 'zd-feature' 2026-08-31 16:43:06 +08:00
堂吉诃德拉曼查的英豪
bfe41c4b99 薄弱项接口 2026-08-31 16:42:39 +08:00
堂吉诃德拉曼查的英豪
7e13db52bf 面试朗读TTS新增异步提交与状态查询方法 2026-08-28 10:53:10 +08:00
堂吉诃德拉曼查的英豪
885316c990 AI面试 文字转音频 2026-08-27 15:01:02 +08:00
堂吉诃德拉曼查的英豪
a2b3310860 错题记录:新增首页明细融合接口契约 appGetWrongRecordDetail 2026-08-26 16:26:19 +08:00
zj
a0194a8d38 新增答题卡删除用户答题记录 2026-08-26 15:46:12 +08:00
zj
25bfb2aeea 新增APP获取答题卡试卷详情 2026-08-25 16:50:04 +08:00
堂吉诃德拉曼查的英豪
e1a0a2b638 Merge remote-tracking branch 'origin/main' 2026-08-25 15:01:53 +08:00
堂吉诃德拉曼查的英豪
4bf1c1fe56 错题记录 和 每日刷题 契约 2026-08-25 15:01:35 +08:00
zj
b2109af8a6 update 2026-08-25 14:54:16 +08:00
zj
033ffc1acf 新增更新学生分校 2026-08-25 14:52:36 +08:00
zj
058cf9b355 新增获取学员分校下拉列表 2026-08-25 14:12:08 +08:00
堂吉诃德拉曼查的英豪
783888f12f 文章标签 2026-08-24 11:06:55 +08:00
21 changed files with 391 additions and 28 deletions

View File

@@ -10,4 +10,5 @@ namespace Dhd\Micro\Interface\AIService;
interface AIService extends
AiEssayCheckInterface,
AiInterviewCheckInterface {}
AiInterviewCheckInterface,
AiInterviewTtsInterface {}

View File

@@ -25,15 +25,16 @@ interface AiEssayCheckInterface
*/
public function getEssayCheckDetail(int $id): ?array;
/**
* 获取未提交的试卷ID列表
* @param int $userId 用户ID
* @return array
*/
public function getEassayPaperNoSubmitList(int $userId): array;
/**
* 用户提交申论批改
*/
public function submitEssayPaper(array $params): int;
public function submitAiEssay(array $params): int;
/**
* 获取用户最近一次申论批改记录
* @param int $userId 用户ID
* @param int $questionId 面试题ID
* @return array|null
*/
public function getEssayQuestionUserLastRecord(int $userId, int $questionId): ?array;
}

View File

@@ -39,4 +39,12 @@ interface AiInterviewCheckInterface
* @return array
*/
public function getInterviewQuestionExamTypeList(): array;
/**
* 获取用户最近一次面试批改记录
* @param int $userId 用户ID
* @param int $questionId 面试题ID
* @return array|null
*/
public function getInterviewQuestionUserLastRecord(int $userId, int $questionId): ?array;
}

View File

@@ -0,0 +1,56 @@
<?php
/**
* AI面试朗读(TTS)相关接口
*/
declare(strict_types=1);
namespace Dhd\Micro\Interface\AIService;
interface AiInterviewTtsInterface
{
/**
* 朗读面试题(文字转语音):懒生成并缓存,已存在则直接返回已有音频
* 音频按题目(question_id)生成并全局复用
* @param array $params 参数,['question_id'=>面试题ID]
*/
public function interviewTtsAudio(array $params): array;
/**
* 查询面试题是否已生成音频,仅查缓存不触发合成(供取题接口附带音频使用)
* @param int $questionId 面试题ID
*/
public function getInterviewQuestionAudioUrl(int $questionId): ?string;
/**
* 批量查询面试题音频生成状态(管理列表使用):仅查询不触发合成。
* 以文件中心按当前题干哈希精确匹配为准判断是否已生成,
* 未生成时结合 Redis 状态键区分排队/合成中/失败。
* @param array $questions 题目列表,元素结构 ['question_id'=>面试题ID, 'content'=>题干内容]
* @return array [面试题ID => ['status'=>queued|processing|success|failed|unknown, 'audio_url'=>?string]]
*/
public function getInterviewQuestionAudioMap(array $questions): array;
/**
* 提交朗读任务(异步):已生成直接返回成功,未生成投递队列后台合成并返回排队状态
* 音频按题目(question_id)生成并全局复用,同一题目并发只合成一次
* @param array $params 参数,['question_id'=>面试题ID]
*/
public function submitInterviewTts(array $params): array;
/**
* 同步面试题音频(后台创建/编辑题目后调用):按题干内容哈希判断是否已生成,
* 内容未变跳过,内容变化或首次生成则投递队列后台合成
* @param array $params 参数,['question_id'=>面试题ID, 'content'=>题干内容]
* 返回 ['question_id'=>int, 'status'=>success|queued]
*/
public function syncInterviewQuestionTts(array $params): array;
/**
* 查询朗读任务状态(供前端轮询使用)
* @param int $questionId 面试题ID
* 返回 ['question_id'=>int, 'status'=>queued|processing|success|failed|unknown, 'url'=>?string]
*/
public function getInterviewTtsStatus(int $questionId): array;
}

View File

@@ -17,6 +17,7 @@ interface ArticleService
public function getArticleDetailWithUser(int $id, int $userId): array;
public function getArticleList(array $params = []): array;
public function appGetArticleList(array $params = []): array;
public function officialGetArticleList(array $params = []): array;
public function searchArticles(string $keyword, array $params = []): array;
// 类型
@@ -36,6 +37,12 @@ interface ArticleService
public function unbindCategoryTypes(int $categoryId, array $typeIds): bool;
public function getCategoryBoundTypes(int $categoryId): array;
// 标签相关
public function createTag(array $data): int;
public function updateTag(int $id, array $data): bool;
public function deleteTag(int $id): bool;
public function getTagList(array $params = []): array;
// 附件
public function createAttachment(array $data): int;
public function updateAttachment(int $id, array $data): bool;
@@ -65,7 +72,7 @@ interface ArticleService
public function deleteContentColumn(int $id): bool;
public function getContentColumnList(array $params = []): array;
public function getContentColumnDetail(int $id): array;
public function getContentColumnsByChannel(string $channel): array;
public function getContentColumnsByChannel(string $channel, string $platform = 'all'): array;
// FAQ
public function createFaq(array $data): int;

View File

@@ -36,6 +36,12 @@ interface CourseServiceInterface
*/
public function appGetCourseList(array $params): array;
/**
* 官网获取课程列表,按更新时间最新在前
* @param array $params 获取参数
*/
public function officialGetCourseList(array $params): array;
/**
* 获取课程详情
* @param int $id 课程ID

View File

@@ -27,6 +27,12 @@ interface ConfigInterface
*/
public function getPublicConfigs(string $platform = '', array $types = [], array $configNames = []): array;
/**
* App 端配置列表(支持 route_path / config_name 过滤,不含过滤条件时行为与 getPublicConfigs 一致).
* @param array $params {platform:string, types:array<int>, route_path?:string, config_name?:string}
*/
public function appGetConfigList(array $params): array;
/**
* 获取配置列表
* @param string $platform 配置所属平台

View File

@@ -6,6 +6,7 @@ namespace Dhd\Micro\Interface\ExamService;
use Dhd\Micro\Interface\ExamService\JsonRpcInterface\ExamServiceInterface;
use Dhd\Micro\Interface\ExamService\JsonRpcInterface\UserPaperInterface;
use Dhd\Micro\Interface\ExamService\JsonRpcInterface\AiInterviewCategoryInterface;
use Dhd\Micro\Interface\ExamService\JsonRpcInterface\AiInterviewQuestionInterface;
use Dhd\Micro\Interface\ExamService\JsonRpcInterface\CustomQuestionInterface;
use Dhd\Micro\Interface\ExamService\JsonRpcInterface\PaperInterface;
@@ -18,10 +19,12 @@ use Dhd\Micro\Interface\ExamService\JsonRpcInterface\CampusRelationInterface;
use Dhd\Micro\Interface\ExamService\JsonRpcInterface\PaperImportInterface;
use Dhd\Micro\Interface\ExamService\JsonRpcInterface\QuestionNoteInterface;
use Dhd\Micro\Interface\ExamService\JsonRpcInterface\DailyPracticeInterface;
use Dhd\Micro\Interface\ExamService\JsonRpcInterface\AiEssayQuestionInterface;
interface ExamService extends
ExamServiceInterface,
UserPaperInterface,
AiInterviewCategoryInterface,
AiInterviewQuestionInterface,
CustomQuestionInterface,
PaperInterface,
@@ -33,4 +36,5 @@ interface ExamService extends
CampusRelationInterface,
PaperImportInterface,
QuestionNoteInterface,
DailyPracticeInterface {}
DailyPracticeInterface,
AiEssayQuestionInterface {}

View File

@@ -0,0 +1,58 @@
<?php
namespace Dhd\Micro\Interface\ExamService\JsonRpcInterface;
interface AiEssayQuestionInterface
{
/**
* 获取AI申论题列表
* @param array $params 查询参数
* @return array
*/
public function getAiEssayQuestionList(array $params): array;
/**
* app获取AI申论题列表
* @param int $userId 用户ID
* @param array $params 查询参数
* @return array
*/
public function appGetAiEssayQuestionList(int $userId, array $params): array;
/**
* 获取AI申论题详情
* @param int $id AI申论题id
* @return array|null
*/
public function getAiEssayQuestionDetail(int $id): ?array;
/**
* 创建AI申论题
* @param array $params AI申论题参数
* @return void
*/
public function createAiEssayQuestion(array $params): void;
/**
* 更新AI申论题
* @param int $id AI申论题id
* @param array $params AI申论题参数
*/
public function updateAiEssayQuestion(int $id, array $params): void;
/**
* 删除AI申论题
* @param int $id AI申论题id
* @return void
*/
public function deleteAiEssayQuestion(int $id): void;
/**
* 随机获取一个问题
* @param int $examTypeId 考试类型
* @param int $campusId 地区ID
* @param int $subjectId 考试科目
* @return array|null
*/
public function getAiEssayQuestionRandom(int $examTypeId, int $campusId, int $subjectId): ?array;
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Dhd\Micro\Interface\ExamService\JsonRpcInterface;
interface AiInterviewCategoryInterface
{
/**
* 获取AI面试类型列表
* @param array $params 查询参数
* @return array
*/
public function getAiInterviewCategoryList(array $params): array;
/**
* 获取AI面试类型下拉列表
* @return array
*/
public function getAiInterviewCategorySelectList(): array;
/**
* 创建AI面试类型
* @param array $params 创建参数
*/
public function createAiInterviewCategory(array $params): void;
/**
* 更新AI面试类型
* @param int $id 类型ID
* @param array $params 更新参数
*/
public function updateAiInterviewCategory(int $id, array $params): void;
/**
* 删除AI面试类型
* @param int $id 类型ID
*/
public function deleteAiInterviewCategory(int $id): void;
}

View File

@@ -11,6 +11,28 @@ interface AiInterviewQuestionInterface
*/
public function getAiInterviewQuestionList(array $params): array;
/**
* app获取面试题列表
* @param int $userId 用户ID
* @param array $params 查询参数
* @return array
*/
public function appGetAiInterviewQuestionList(int $userId, array $params): array;
/**
* 管理端获取面试题列表(平台方法):在通用列表基础上逐行附加音频生成状态 audio
* @param array $params 查询参数,同 getAiInterviewQuestionList
* @return array 同通用列表结构,行内新增 audio: ['status'=>string, 'audio_url'=>?string]
*/
public function adminGetAiInterviewQuestionList(array $params): array;
/**
* 管理端批量查询面试题音频生成状态(前端轮询使用):仅查询不触发合成
* @param array $questionIds 面试题ID列表
* @return array [面试题ID => ['status'=>queued|processing|success|failed|unknown, 'audio_url'=>?string]]
*/
public function getAiInterviewQuestionTtsStatus(array $questionIds): array;
/**
* 获取面试题详情
* @param int $id 面试题id

View File

@@ -27,11 +27,20 @@ interface CampusRelationInterface
public function getCategoriesByConditions(int $campusId, int $examTypeId, int $subjectId): array;
/**
* App 平台方法:指定地区+招考类型+科目下的题型分类树。
* App 平台方法:指定地区+招考类型下的题型分类树,可选按科目过滤。
* @param int $regionId 招考地区ID,0=全部
* @param int $examTypeId 招考类型ID
* @param int $subjectId 考试科目ID
* @param int $subjectId 考试科目ID,0=不限科目
* @return array
*/
public function appGetCategoriesByRegionExamTypeSubject(int $regionId, int $examTypeId, int $subjectId): array;
public function appGetCategoriesByRegionExamTypeSubject(int $regionId, int $examTypeId, int $subjectId = 0): array;
/**
* App 平台方法:按招考类型获取首页科目列表,并统计模拟/真题套卷总套数。
* @param int $examTypeId 招考类型ID
* @param int $regionId 招考地区ID,0=全部
* @param int $year 试卷年份,0=不限年份
* @return array 科目列表,每项附加 mock_total(模拟套数)、zhenti_total(真题套数)、total(总套数)
*/
public function appGetSubjectsByExamType(int $examTypeId, int $regionId = 0, int $year = 0): array;
}

View File

@@ -6,16 +6,23 @@ namespace Dhd\Micro\Interface\ExamService\JsonRpcInterface;
interface DailyPracticeInterface
{
/**
* App 每日刷题:今日刷题情况 + 每日题目分类列表.
*
* 分类由编码按日期确定性随机选取;
* 抽题复用 getExerciseQuestionList(test_type=4 每日刷题)。
*
* @param int $userId 用户ID
* @return array {today_completed:int, today_total:int, list:list<{
* category_id:int, category_name:string, question_num:int, completed:bool
* }>}
*/
public function appGetDailyPractice(int $userId): array;
}
/**
* App 每日刷题:今日刷题情况 + 每日题目分类列表.
*
* 分类由编码按日期确定性随机选取;
* 抽题复用 getExerciseQuestionList(test_type=4 每日刷题)。
* completed 表示该分类今日已作答 >= 组题数(默认5),部分作答未完成时下次继续展示。
* @param int $userId 用户ID
*/
public function appGetDailyPractice(int $userId): array;
/**
* App 每日刷题:指定分类今日作答进度与已答题目(断点续答:恢复已答题并展示剩余题数).
*
* 返回已答题目详情(题干/选项/用户答案/判分)供二次进入做题页恢复展示;
*
* @param int $userId 用户ID
* @param int $categoryId 分类ID
*/
public function appGetDailyPracticeProgress(int $userId, int $categoryId): array;
}

View File

@@ -79,6 +79,41 @@ interface ExamServiceInterface
*/
public function batchUpdateScores(array $params): bool;
/**
* 获取错题记录首页统计(总错题数、顽固错题数、模块错题数与正确率、薄弱项).
*/
public function appGetWrongRecordStats(int $userId): array;
/**
* 获取错题记录模块明细(模块错题数与正确率、二级知识点错题数).
*/
public function appGetWrongRecordModuleDetail(int $userId, int $categoryId): array;
/**
* 获取错题记录首页明细(融合首页统计与各模块知识点明细,一次返回).
*/
public function appGetWrongRecordDetail(int $userId): array;
/**
* 提交错题记录发起的专项练习(写做题记录并更新错题,返回判分结果与正确率对比).
*/
public function submitWrongPractice(int $userId, array $params): array;
/**
* 错题练习抽题:按分类抽取用户当前错题(仅错题,不足 num 时全量返回),随机排序.
*
* @param array $params category_id 分类ID(模块根或知识点);num 抽题数量;get_correct 是否附带正确答案
*/
public function getWrongPracticeQuestions(array $params, int $userId): array;
/**
* 获取用户薄弱项(有错题且正确率低于阈值且正确率最低的模块;无则 null).
*
* 用于首页弹窗「薄弱项:{模块名}正确率低 → 攻克它 → 专项刷题」,
* 以及错题记录页面薄弱项展示;与错题记录首页统计字段 weak_category 同口径.
*/
public function appGetWeakPoint(int $userId): ?array;
/**
* 获取考试类型列表(V1 兼容接口).
*/
@@ -99,7 +134,6 @@ interface ExamServiceInterface
*/
public function getQuestionStoreList(array $params): array;
/**
* 提交题目答案,根据试卷类型自动选择智能组卷或普通试卷逻辑.
*/

View File

@@ -58,6 +58,18 @@ interface PaperInterface
*/
public function getPaperQuestionList(int $paperId, bool $getCorrect = false, string $platform = 'admin'): array;
/**
* 设置卷内单题分值(后台试卷详情即时改分,只改本卷卷内分值)
* @param array $params ['paper_id' => int, 'question_id' => int, 'score' => float]
*/
public function setPaperQuestionScore(array $params): array;
/**
* 按分类批量设置卷内分值(设置分类总分,按该分类在本卷的题目数平均分配,末题吸收差额)
* @param array $params ['paper_id' => int, 'categories' => [['category_id' => int, 'total_score' => float], ...]]
*/
public function batchSetPaperQuestionScores(array $params): array;
/**
* 按年份统计试卷数量
* @param int $paperType 试卷类型

View File

@@ -14,6 +14,16 @@ interface QuestionInterface
*/
public function submitImportQuestion(array $params): array;
/**
* 只读校验解析暂存内容,返回逐题校验结果,不写库、不移动图片.
*/
public function previewImportQuestion(array $params): array;
/**
* 保存对解析暂存内容的修改,并返回最新暂存内容和逐题校验结果.
*/
public function updateImportQuestion(array $params): array;
/**
* 随机获取用户错题
* @param $userId 用户id
@@ -22,6 +32,11 @@ interface QuestionInterface
*/
public function getWrongQuestions(int $userId, int $num): array;
/**
* 获取用户错题,V2版本(基于 v1 getWrongQuestions,支持分类范围、数量、是否正确).
*/
public function getWrongQuestionsV2(array $params, int $userId): array;
public function getQuestionList(array $filters = []): array;
public function getQuestionDetail(int $id): array;
@@ -35,6 +50,29 @@ interface QuestionInterface
public function deleteQuestion(int $id): array;
/**
* 管理端题库新增题目:题库级录入(普通题目,不带材料)。
* @return array 统一外壳,data 为 ['id' => 新题目ID]
*/
public function adminCreateQuestion(array $data): array;
/**
* 管理端题目材料内容保存:仅更新关联材料内容,绑定关系不变。
* @return array 统一外壳,data 为 ['affected' => 受影响题目数]
*/
public function adminUpdateQuestionMaterial(int $id, string $content): array;
/**
* 管理端题目分页列表:支持题型/科目/分类/选项类型/状态/题干关键词/招考地区筛选。
*/
public function adminGetQuestionPage(array $filters): array;
/**
* 管理端题目字段级保存:白名单字段即时更新,含范围级联校验与判重指纹重算。
*/
public function adminUpdateQuestionFields(int $id, array $fields): array;
/**
* 刷题,批量提交用户答案
*/

View File

@@ -27,4 +27,10 @@ interface FileServiceInterface
* 获取文件列表
*/
public function getFileList(array $params): array;
/**
* 保存二进制(base64)文件,用于服务端生成的文件
* @param array $params 参数,如 ['base64'=>.., 'file_name'=>.., 'file_type'=>.., 'group_id'=>.., 'channel'=>.., 'uploader_id'=>..]
*/
public function saveBase64File(array $params): array;
}

View File

@@ -22,4 +22,9 @@ interface QuestionParseInterface
* 读取解析暂存数据,不确认导入且不移动图片。
*/
public function getQuestionParseByCode(string $code): array;
/**
* 修改解析暂存数据,仅允许未确认导入的批次按主键更新白名单字段。
*/
public function updateQuestionParseByCode(string $code, array $questionList, array $materialList): array;
}

View File

@@ -43,4 +43,19 @@ interface StudentInterface
* @return void
*/
public function updateStudentSchool(int $studentId, int $schoolId): void;
/**
* 获取学员分校下拉列表
* @param string $mobile 手机号
* @return array
*/
public function getStudentSchoolSelectList(string $mobile): array;
/**
* 更新学生姓名
* @param int $studentId 学生ID
* @param string $name 姓名
* @return void
*/
public function updateStudentName(int $studentId, string $name): void;
}

View File

@@ -45,4 +45,21 @@ interface PgUserPaperRecordInterface
* @return void
*/
public function submitPgUserPaper(int $userId, array $params): void;
/**
* APP获取试卷详情
* @param int $userId 用户id
* @param int $paperId 试卷id
* @return array
*/
public function appGetPgPaperDetail(int $userId, int $paperId): array;
/**
* 删除用户答题记录
* @param int $userId 用户id
* @param int $paperId 试卷id
* @param int $sectionId 章节id
* @return void
*/
public function deleteUserPaperRecord(int $userId, int $paperId, int $sectionId = 0): void;
}

View File

@@ -31,4 +31,17 @@ interface UserCurriculumVitaeInterface
* @return array
*/
public function deleteUserWorkExperience(int $userId, int $index): array;
/**
* 获取用户简历(V2:工作经历数组,含职称、资格证书、重要荣誉)
* @param int $userId 用户id
* @return array
*/
public function getCurriculumVitaeV2(int $userId): array;
/**
* 编辑用户简历(V2:工作经历数组,含职称、资格证书、重要荣誉)
* @param array $params 简历参数
* @param int $userId 用户id
* @return array
*/
public function editCurriculumVitaeV2(array $params, int $userId): array;
}