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
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);
|
|
}
|
|
}
|