智慧教务系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

450 lines
15 KiB

<?php
// +----------------------------------------------------------------------
// | 学员端知识库服务类
// +----------------------------------------------------------------------
namespace app\service\api\student;
use app\model\student\Student;
use think\facade\Db;
use core\base\BaseService;
/**
* 学员知识库服务类
*/
class KnowledgeService extends BaseService
{
/**
* table_type 枚举值映射
*/
private $tableTypeMap = [
'1' => ['name' => '课程教学大纲', 'icon' => '📖'],
'2' => ['name' => '跳绳教案库', 'icon' => '🏃'],
'3' => ['name' => '增高教案库', 'icon' => '📏'],
'4' => ['name' => '篮球教案库', 'icon' => '🏀'],
'5' => ['name' => '强化教案库', 'icon' => '💪'],
'6' => ['name' => '空中忍者教案库', 'icon' => '🥷'],
'7' => ['name' => '少儿安防教案库', 'icon' => '🛡️'],
'8' => ['name' => '体能教案库', 'icon' => '🏋️'],
'9' => ['name' => '热身动作库', 'icon' => '🔥'],
'10' => ['name' => '体能动作库', 'icon' => '💪'],
'11' => ['name' => '趣味游戏库', 'icon' => '🎮'],
'12' => ['name' => '放松动作库', 'icon' => '🧘'],
'13' => ['name' => '训练内容', 'icon' => '📋'],
'14' => ['name' => '训练视频', 'icon' => '📹'],
'15' => ['name' => '课后作业', 'icon' => '📝'],
'16' => ['name' => '优秀一堂课', 'icon' => '⭐'],
'17' => ['name' => '空中忍者动作', 'icon' => '🥷'],
'18' => ['name' => '篮球动作', 'icon' => '🏀'],
'19' => ['name' => '跳绳动作', 'icon' => '🏃'],
'20' => ['name' => '跑酷动作', 'icon' => '🏃‍♂️'],
'21' => ['name' => '安防动作', 'icon' => '🛡️'],
'22' => ['name' => '标准化动作', 'icon' => '✅'],
'23' => ['name' => '3-6岁体测', 'icon' => '👶'],
'24' => ['name' => '7+体测', 'icon' => '🧒'],
'25' => ['name' => '3-6岁体测讲解—解读', 'icon' => '👶📊'],
'26' => ['name' => '7+岁体测讲解—解读', 'icon' => '🧒📊'],
'27' => ['name' => '互动游戏', 'icon' => '🎲'],
'28' => ['name' => '套圈游戏', 'icon' => '⭕'],
'29' => ['name' => '鼓励方式', 'icon' => '👏']
];
/**
* 获取知识文章列表
* @param array $data
* @return array
*/
public function getKnowledgeList($data)
{
$studentId = $data['student_id'];
$category = $data['category'] ?? '';
$page = $data['page'] ?? 1;
$limit = $data['limit'] ?? 10;
$keyword = $data['keyword'] ?? '';
// 构建查询条件
$where = [];
// 权限控制:检查学员是否有权限查看
$where[] = ['', 'exp', Db::raw("FIND_IN_SET({$studentId}, student_ids)")];
// 状态筛选:只查询启用状态的内容
$where[] = ['status', '=', 1];
// 软删除筛选:排除已删除的内容
$where[] = ['delete_time', '=', '0'];
// 分类筛选
if (!empty($category)) {
$where[] = ['table_type', '=', $category];
}
// 关键词搜索
if (!empty($keyword)) {
$where[] = ['title|content', 'like', "%{$keyword}%"];
}
// 查询总数
$total = Db::table('school_lesson_course_teaching')
->where($where)
->count();
// 分页查询文章列表
$articles = Db::table('school_lesson_course_teaching')
->where($where)
->field('id,title,image,type,url,content,status,create_time,update_time,table_type,user_permission,exam_papers_id')
->order('create_time desc')
->limit(($page - 1) * $limit, $limit)
->select();
$list = [];
foreach ($articles as $article) {
// 检查是否已读
$isRead = $this->checkArticleRead($article['id'], $studentId);
// 检查是否收藏
$isFavorite = $this->checkArticleFavorite($article['id'], $studentId);
// 获取分类名称
$categoryInfo = $this->tableTypeMap[$article['table_type']] ?? ['name' => '其他', 'icon' => '📄'];
$list[] = [
'id' => $article['id'],
'title' => $article['title'],
'image' => $article['image'] ? get_image_url($article['image']) : '',
'content' => strip_tags($article['content']),
'table_type' => $article['table_type'],
'category_name' => $categoryInfo['name'],
'type' => $article['type'],
'url' => $article['url'],
'status' => $article['status'],
'create_time' => $article['create_time'] ? strtotime($article['create_time']) : 0,
'update_time' => $article['update_time'] ? strtotime($article['update_time']) : 0,
'user_permission' => $article['user_permission'],
'is_read' => $isRead,
'is_favorite' => $isFavorite
];
}
return [
'list' => $list,
'current_page' => $page,
'last_page' => ceil($total / $limit),
'total' => $total,
'per_page' => $limit
];
}
/**
* 获取知识分类列表
* @return array
*/
public function getKnowledgeCategories()
{
$categories = [];
// 获取有数据的分类统计
$stats = Db::table('school_lesson_course_teaching')
->where('status', 1)
->where('delete_time', '0')
->group('table_type')
->field('table_type, count(*) as count')
->select();
foreach ($stats as $stat) {
$tableType = $stat['table_type'];
if (isset($this->tableTypeMap[$tableType])) {
$categories[] = [
'value' => $tableType,
'text' => $this->tableTypeMap[$tableType]['name'],
'icon' => $this->tableTypeMap[$tableType]['icon'],
'count' => $stat['count']
];
}
}
return $categories;
}
/**
* 获取推荐文章
* @param array $data
* @return array
*/
public function getRecommendArticles($data)
{
$studentId = $data['student_id'];
$limit = $data['limit'] ?? 5;
// 构建查询条件
$where = [];
$where[] = ['', 'exp', Db::raw("FIND_IN_SET({$studentId}, student_ids)")];
$where[] = ['status', '=', 1];
$where[] = ['delete_time', '=', '0'];
// 查询推荐文章(按创建时间倒序,取最新的)
$articles = Db::table('school_lesson_course_teaching')
->where($where)
->field('id,title,image,content,create_time,table_type')
->order('create_time desc')
->limit($limit)
->select();
$list = [];
foreach ($articles as $article) {
$categoryInfo = $this->tableTypeMap[$article['table_type']] ?? ['name' => '其他', 'icon' => '📄'];
$list[] = [
'id' => $article['id'],
'title' => $article['title'],
'image' => $article['image'] ? get_image_url($article['image']) : '',
'summary' => mb_substr(strip_tags($article['content']), 0, 100, 'UTF-8'),
'category_name' => $categoryInfo['name'],
'create_time' => $article['create_time'] ? strtotime($article['create_time']) : 0,
'read_count' => 0 // 这里可以后续添加阅读统计
];
}
return $list;
}
/**
* 获取文章详情
* @param array $data
* @return array
*/
public function getKnowledgeDetail($data)
{
$articleId = $data['id'];
$studentId = $data['student_id'];
// 权限验证
$article = Db::table('school_lesson_course_teaching')
->where('id', $articleId)
->where('status', 1)
->where('delete_time', '0')
->where('', 'exp', Db::raw("FIND_IN_SET({$studentId}, student_ids)"))
->find();
if (!$article) {
throw new \Exception('文章不存在或无权限访问');
}
// 检查是否已读
$isRead = $this->checkArticleRead($articleId, $studentId);
// 检查是否收藏
$isFavorite = $this->checkArticleFavorite($articleId, $studentId);
// 获取分类名称
$categoryInfo = $this->tableTypeMap[$article['table_type']] ?? ['name' => '其他', 'icon' => '📄'];
return [
'id' => $article['id'],
'title' => $article['title'],
'image' => $article['image'] ? get_image_url($article['image']) : '',
'content' => $article['content'],
'table_type' => $article['table_type'],
'category_name' => $categoryInfo['name'],
'type' => $article['type'],
'url' => $article['url'],
'status' => $article['status'],
'create_time' => $article['create_time'] ? strtotime($article['create_time']) : 0,
'update_time' => $article['update_time'] ? strtotime($article['update_time']) : 0,
'user_permission' => $article['user_permission'],
'exam_papers_id' => $article['exam_papers_id'],
'is_read' => $isRead,
'is_favorite' => $isFavorite
];
}
/**
* 标记文章已读
* @param array $data
* @return array
*/
public function markArticleRead($data)
{
$articleId = $data['article_id'];
$studentId = $data['student_id'];
// 检查文章是否存在且有权限
$article = Db::table('school_lesson_course_teaching')
->where('id', $articleId)
->where('status', 1)
->where('delete_time', '0')
->where('', 'exp', Db::raw("FIND_IN_SET({$studentId}, student_ids)"))
->find();
if (!$article) {
throw new \Exception('文章不存在或无权限访问');
}
// 检查是否已经标记为已读
$existRead = Db::table('school_student_article_reads')
->where('student_id', $studentId)
->where('article_id', $articleId)
->find();
if ($existRead) {
return ['message' => '已标记为已读'];
}
// 插入阅读记录
Db::table('school_student_article_reads')->insert([
'student_id' => $studentId,
'article_id' => $articleId,
'read_time' => date('Y-m-d H:i:s'),
'read_duration' => 0
]);
return ['message' => '标记已读成功'];
}
/**
* 收藏/取消收藏文章
* @param array $data
* @return array
*/
public function toggleArticleFavorite($data)
{
$articleId = $data['article_id'];
$studentId = $data['student_id'];
$action = $data['action'];
// 检查文章是否存在且有权限
$article = Db::table('school_lesson_course_teaching')
->where('id', $articleId)
->where('status', 1)
->where('delete_time', '0')
->where('', 'exp', Db::raw("FIND_IN_SET({$studentId}, student_ids)"))
->find();
if (!$article) {
throw new \Exception('文章不存在或无权限访问');
}
if ($action === 'add') {
// 收藏
$existFavorite = Db::table('school_student_favorites')
->where('student_id', $studentId)
->where('target_type', 'article')
->where('target_id', $articleId)
->find();
if ($existFavorite) {
return ['message' => '已收藏', 'is_favorite' => true];
}
Db::table('school_student_favorites')->insert([
'student_id' => $studentId,
'target_type' => 'article',
'target_id' => $articleId,
'created_at' => date('Y-m-d H:i:s')
]);
return ['message' => '收藏成功', 'is_favorite' => true];
} else {
// 取消收藏
Db::table('school_student_favorites')
->where('student_id', $studentId)
->where('target_type', 'article')
->where('target_id', $articleId)
->delete();
return ['message' => '取消收藏成功', 'is_favorite' => false];
}
}
/**
* 获取知识库统计信息
* @param int $studentId
* @return array
*/
public function getKnowledgeStats($studentId)
{
// 总文章数
$totalArticles = Db::table('school_lesson_course_teaching')
->where('status', 1)
->where('delete_time', '0')
->where('', 'exp', Db::raw("FIND_IN_SET({$studentId}, student_ids)"))
->count();
// 收藏数
$favorites = Db::table('school_student_favorites')
->where('student_id', $studentId)
->where('target_type', 'article')
->count();
// 已读文章数
$readArticles = Db::table('school_student_article_reads')
->where('student_id', $studentId)
->count();
// 分类统计
$categoriesCount = [];
$categoryStats = Db::table('school_lesson_course_teaching')
->where('status', 1)
->where('delete_time', '0')
->where('', 'exp', Db::raw("FIND_IN_SET({$studentId}, student_ids)"))
->group('table_type')
->field('table_type, count(*) as count')
->select();
foreach ($categoryStats as $stat) {
$categoriesCount[$stat['table_type']] = $stat['count'];
}
return [
'total_articles' => $totalArticles,
'favorites' => $favorites,
'read_articles' => $readArticles,
'categories_count' => $categoriesCount
];
}
/**
* 搜索知识文章
* @param array $data
* @return array
*/
public function searchKnowledgeArticles($data)
{
// 复用getKnowledgeList方法,已经包含了搜索功能
return $this->getKnowledgeList($data);
}
/**
* 检查文章是否已读
* @param int $articleId
* @param int $studentId
* @return bool
*/
private function checkArticleRead($articleId, $studentId)
{
$read = Db::table('school_student_article_reads')
->where('student_id', $studentId)
->where('article_id', $articleId)
->find();
return !empty($read);
}
/**
* 检查文章是否收藏
* @param int $articleId
* @param int $studentId
* @return bool
*/
private function checkArticleFavorite($articleId, $studentId)
{
$favorite = Db::table('school_student_favorites')
->where('student_id', $studentId)
->where('target_type', 'article')
->where('target_id', $articleId)
->find();
return !empty($favorite);
}
}