hejianhao
2026-09-01 4b4d225c0f8456b8918dc79eec2e093485746d0f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package com.tcm.training.admin.live.service;
 
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tcm.training.admin.common.PageResponse;
import com.tcm.training.admin.live.dto.ExpertSaveRequest;
import com.tcm.training.admin.live.dto.ExpertStatusRequest;
import com.tcm.training.admin.live.entity.Expert;
import com.tcm.training.admin.live.entity.LiveCourse;
import com.tcm.training.admin.live.mapper.ExpertMapper;
import com.tcm.training.admin.live.mapper.LiveCourseMapper;
import com.tcm.training.admin.live.vo.ExpertDetailVO;
import com.tcm.training.admin.live.vo.ExpertItemVO;
import com.tcm.training.admin.live.vo.ExpertOptionVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.util.ArrayList;
import java.util.List;
 
@Service
public class ExpertAppService {
 
    private final ExpertMapper expertMapper;
    private final LiveCourseMapper liveCourseMapper;
 
    public ExpertAppService(ExpertMapper expertMapper, LiveCourseMapper liveCourseMapper) {
        this.expertMapper = expertMapper;
        this.liveCourseMapper = liveCourseMapper;
    }
 
    public PageResponse<ExpertItemVO> page(int page, int pageSize, String keyword, Integer status) {
        LambdaQueryWrapper<Expert> qw = new LambdaQueryWrapper<Expert>();
        if (keyword != null && !keyword.trim().isEmpty()) {
            qw.like(Expert::getName, keyword.trim());
        }
        if (status != null) {
            qw.eq(Expert::getStatus, status);
        }
        qw.orderByDesc(Expert::getId);
 
        IPage<Expert> p = expertMapper.selectPage(new Page<Expert>(page, pageSize), qw);
        List<ExpertItemVO> list = new ArrayList<ExpertItemVO>();
        for (Expert e : p.getRecords()) {
            list.add(new ExpertItemVO(e.getId(), e.getName(), e.getAvatar(), e.getStatus(), e.getCreatedAt()));
        }
        return PageResponse.of(list, p.getTotal(), p.getCurrent(), p.getSize());
    }
 
    public ExpertDetailVO detail(Long id) {
        Expert expert = requireExpert(id);
        return toDetailVO(expert);
    }
 
    public List<ExpertOptionVO> options() {
        List<Expert> experts = expertMapper.selectList(new LambdaQueryWrapper<Expert>()
                .eq(Expert::getStatus, 1)
                .eq(Expert::getDeleted, 0)
                .orderByAsc(Expert::getId));
        List<ExpertOptionVO> list = new ArrayList<ExpertOptionVO>();
        for (Expert expert : experts) {
            list.add(new ExpertOptionVO(expert.getId(), expert.getName(), expert.getAvatar()));
        }
        return list;
    }
 
    @Transactional
    public ExpertDetailVO create(ExpertSaveRequest req) {
        Expert expert = new Expert();
        expert.setName(req.getName().trim());
        expert.setAvatar(req.getAvatar().trim());
        expert.setSpecialty(req.getSpecialty().trim());
        expert.setIntro(req.getIntro().trim());
        expert.setStatus(req.getStatus());
        expert.setDeleted(0);
        expertMapper.insert(expert);
        return detail(expert.getId());
    }
 
    @Transactional
    public ExpertDetailVO update(Long id, ExpertSaveRequest req) {
        Expert expert = requireExpert(id);
        expert.setName(req.getName().trim());
        expert.setAvatar(req.getAvatar().trim());
        expert.setSpecialty(req.getSpecialty().trim());
        expert.setIntro(req.getIntro().trim());
        expert.setStatus(req.getStatus());
        expertMapper.updateById(expert);
        return detail(id);
    }
 
    @Transactional
    public ExpertDetailVO patchStatus(Long id, ExpertStatusRequest req) {
        Expert expert = requireExpert(id);
        expert.setStatus(req.getStatus());
        expertMapper.updateById(expert);
        return detail(id);
    }
 
    @Transactional
    public void delete(Long id) {
        requireExpert(id);
        Long bindCount = liveCourseMapper.selectCount(new LambdaQueryWrapper<LiveCourse>()
                .eq(LiveCourse::getExpertId, id)
                .eq(LiveCourse::getDeleted, 0));
        if (bindCount != null && bindCount > 0) {
            throw new IllegalArgumentException("该授课专家已关联直播课程,暂不允许删除");
        }
        expertMapper.deleteById(id);
    }
 
    private Expert requireExpert(Long id) {
        Expert expert = expertMapper.selectOne(new LambdaQueryWrapper<Expert>()
                .eq(Expert::getId, id)
                .eq(Expert::getDeleted, 0)
                .last("limit 1"));
        if (expert == null) {
            throw new IllegalArgumentException("授课专家不存在");
        }
        return expert;
    }
 
    private ExpertDetailVO toDetailVO(Expert expert) {
        ExpertDetailVO vo = new ExpertDetailVO();
        vo.setId(expert.getId());
        vo.setName(expert.getName());
        vo.setAvatar(expert.getAvatar());
        vo.setSpecialty(expert.getSpecialty());
        vo.setIntro(expert.getIntro());
        vo.setStatus(expert.getStatus());
        vo.setCreatedAt(expert.getCreatedAt());
        vo.setUpdatedAt(expert.getUpdatedAt());
        return vo;
    }
}