Commit 441ec6bf authored by liuyang's avatar liuyang

完成课程问答模块接口

parent 38c814f4
package com.qkdata.biz.enums;
public enum AnswerTypeEnum {
USER,TEACHER
}
package com.qkdata.biz.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
public enum QuestionStatusEnum {
WAIT_REPLY(0,"待回复"),
REPLY(1,"已回复"),
COMPLETE(2,"已完成");
@EnumValue
private Integer value;
private String text;
QuestionStatusEnum(Integer value, String text) {
this.value = value;
this.text = text;
}
}
package com.qkdata.biz.management.controller;
import com.qkdata.biz.common.BizConstants;
import com.qkdata.biz.enums.QuestionStatusEnum;
import com.qkdata.biz.management.service.QAService;
import com.qkdata.biz.management.vo.*;
import com.qkdata.common.annotation.SysLog;
import com.qkdata.common.base.model.PageResult;
import com.qkdata.common.base.model.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@Api(tags = "课程问答接口")
@RestController
@RequestMapping("/api/mgr/qa")
public class QAController {
@Autowired
private QAService qaService;
@ApiOperation("查询问题列表")
@SysLog("查询问题列表")
@PostMapping("/list")
@RequiresRoles(value = {BizConstants.ROLE_ADMIN,BizConstants.ROLE_OPERATOR,BizConstants.ROLE_TEACHER},logical = Logical.OR)
public PageResult<QuestionModel> questionList(@RequestBody QueryQuestionModel param){
return qaService.questionPageList(param);
}
@ApiOperation("查看问题回复列表")
@SysLog("查看问题回复列表")
@PostMapping("/answerList")
@RequiresRoles(value = {BizConstants.ROLE_ADMIN,BizConstants.ROLE_OPERATOR,BizConstants.ROLE_TEACHER},logical = Logical.OR)
public PageResult<QAModel> answerList(@RequestBody @Validated QueryAnswerModel param){
return qaService.answerList(param);
}
@ApiOperation("问题回复")
@SysLog("问题回复")
@PostMapping("/answer")
@RequiresRoles(value = {BizConstants.ROLE_ADMIN,BizConstants.ROLE_OPERATOR,BizConstants.ROLE_TEACHER},logical = Logical.OR)
public Result<String> answer(@RequestBody @Validated AnswerModel model){
qaService.answer(model);
return Result.succeed("ok");
}
@ApiOperation("修改问题状态为已完成")
@SysLog("修改问题状态为已完成")
@GetMapping("/question/complete")
@RequiresRoles(value = {BizConstants.ROLE_ADMIN,BizConstants.ROLE_OPERATOR,BizConstants.ROLE_TEACHER},logical = Logical.OR)
public Result<String> questionComplete(@RequestParam Long questionId){
qaService.changeQuestionStatus(questionId, QuestionStatusEnum.COMPLETE);
return Result.succeed("ok");
}
}
package com.qkdata.biz.management.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.qkdata.biz.enums.AnswerTypeEnum;
import com.qkdata.common.base.entity.BasePO;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 问题回答表
* </p>
*
* @author liuyang
* @since 2021-07-01
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("answer")
public class AnswerPO extends BasePO {
private static final long serialVersionUID = 1L;
/**
* 问题ID
*/
private Long questionId;
/**
* 回复人ID
*/
private Long userId;
/**
* 区分讲师回复还是用户回复
*/
private AnswerTypeEnum type;
/**
* 内容
*/
private String content;
}
package com.qkdata.biz.management.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.qkdata.biz.enums.QuestionStatusEnum;
import com.qkdata.common.base.entity.BasePO;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 用户问题表
* </p>
*
* @author liuyang
* @since 2021-07-01
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("question")
public class QuestionPO extends BasePO {
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
private Long userId;
/**
* 课程ID
*/
private Long courseId;
/**
* 章节ID
*/
private Long chapterId;
/**
* 问题内容
*/
private String content;
/**
* 状态:待回复、已回复、已完成
*/
private QuestionStatusEnum status;
}
package com.qkdata.biz.management.mapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qkdata.biz.management.entity.AnswerPO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qkdata.biz.management.vo.QAModel;
import com.qkdata.biz.management.vo.QueryAnswerModel;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* 问题回答表 Mapper 接口
* </p>
*
* @author liuyang
* @since 2021-07-01
*/
@Mapper
public interface AnswerMapper extends BaseMapper<AnswerPO> {
List<QAModel> answerPageList(Page page, @Param("p") QueryAnswerModel param);
}
package com.qkdata.biz.management.mapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qkdata.biz.management.entity.QuestionPO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qkdata.biz.management.vo.QueryQuestionModel;
import com.qkdata.biz.management.vo.QuestionModel;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* 用户问题表 Mapper 接口
* </p>
*
* @author liuyang
* @since 2021-07-01
*/
@Mapper
public interface QuestionMapper extends BaseMapper<QuestionPO> {
List<QuestionModel> questionPageList(Page page, @Param("p") QueryQuestionModel param,@Param("tId")Long teacherId);
List<QuestionModel> myQuestionPageList(Page page, @Param("userId") Long userId);
QuestionModel findQuestion(Long questionId);
}
package com.qkdata.biz.management.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qkdata.biz.common.BizConstants;
import com.qkdata.biz.enums.AnswerTypeEnum;
import com.qkdata.biz.enums.QuestionStatusEnum;
import com.qkdata.biz.management.entity.AnswerPO;
import com.qkdata.biz.management.entity.QuestionPO;
import com.qkdata.biz.management.entity.TeacherPO;
import com.qkdata.biz.management.mapper.AnswerMapper;
import com.qkdata.biz.management.mapper.QuestionMapper;
import com.qkdata.biz.management.vo.*;
import com.qkdata.biz.sys.entity.SysUserPO;
import com.qkdata.biz.web.vo.AskModel;
import com.qkdata.common.base.enums.CodeEnum;
import com.qkdata.common.base.model.PageResult;
import com.qkdata.common.util.UserContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 问答服务类
*/
@Slf4j
@Service
public class QAService {
@Autowired
private QuestionMapper questionMapper;
@Autowired
private AnswerMapper answerMapper;
@Autowired
private TeacherService teacherService;
/**
* 查询问题列表
* @param param
* @return
*/
public PageResult<QuestionModel> questionPageList(QueryQuestionModel param) {
Long teacherId = null;
boolean isTeacher = SecurityUtils.getSubject().hasRole(BizConstants.ROLE_TEACHER);
if (isTeacher){
TeacherPO po = teacherService.getByAccount(UserContext.getUser().getUsername());
teacherId = po.getId();
}
Page page = new Page(param.getPageIndex(),param.getPageSize());
List<QuestionModel> list = questionMapper.questionPageList(page,param,teacherId);
return PageResult.<QuestionModel>builder().code(CodeEnum.SUCCESS.getCode()).count(page.getTotal()).data(list).build();
}
/**
* 获取问题回复列表
* @param param
* @return
*/
public PageResult<QAModel> answerList(QueryAnswerModel param) {
Page page = new Page(param.getPageIndex(),param.getPageSize());
List<QAModel> list = answerMapper.answerPageList(page,param);
return PageResult.<QAModel>builder().code(CodeEnum.SUCCESS.getCode()).count(page.getTotal()).data(list).build();
}
/**
* 回复
* @param model
*/
@Transactional
public void answer(AnswerModel model) {
AnswerPO po = new AnswerPO();
po.setQuestionId(model.getQuestionId());
po.setContent(model.getContent());
po.setUserId(UserContext.getUserId());
boolean isTeacher = SecurityUtils.getSubject().hasRole(BizConstants.ROLE_TEACHER);
if (isTeacher){
po.setType(AnswerTypeEnum.TEACHER);
}else {
po.setType(AnswerTypeEnum.USER);
}
answerMapper.insert(po);
//修改问题状态
if (isTeacher){
changeQuestionStatus(model.getQuestionId(), QuestionStatusEnum.REPLY);
}else {
changeQuestionStatus(model.getQuestionId(),QuestionStatusEnum.WAIT_REPLY);
}
}
/**
* 修改问题状态
* @param questionId
* @param status
*/
public void changeQuestionStatus(Long questionId, QuestionStatusEnum status) {
QuestionPO po = new QuestionPO();
po.setId(questionId);
po.setStatus(status);
questionMapper.updateById(po);
}
/**
* 用户提问
* @param model
*/
@Transactional
public void ask(AskModel model) {
QuestionPO questionPO = new QuestionPO();
questionPO.setUserId(UserContext.getUserId());
questionPO.setCourseId(model.getCourseId());
questionPO.setChapterId(model.getChapterId());
questionPO.setContent(model.getContent());
questionPO.setStatus(QuestionStatusEnum.WAIT_REPLY);
questionMapper.insert(questionPO);
AnswerPO answerPO = new AnswerPO();
answerPO.setQuestionId(questionPO.getId());
answerPO.setUserId(questionPO.getUserId());
answerPO.setType(AnswerTypeEnum.USER);
answerPO.setContent(questionPO.getContent());
answerMapper.insert(answerPO);
}
/**
* 查询当前用户提问列表
* @param param
* @return
*/
public PageResult<QuestionModel> myQuestionPageList(QueryQuestionModel param) {
Page page = new Page(param.getPageIndex(),param.getPageSize());
List<QuestionModel> list = questionMapper.myQuestionPageList(page,UserContext.getUserId());
return PageResult.<QuestionModel>builder().code(CodeEnum.SUCCESS.getCode()).count(page.getTotal()).data(list).build();
}
/**
* 获取问题信息
* @param questionId
* @return
*/
public QuestionModel getQuestion(Long questionId) {
return questionMapper.findQuestion(questionId);
}
}
...@@ -129,4 +129,8 @@ public class TeacherService extends ServiceImpl<TeacherMapper, TeacherPO> { ...@@ -129,4 +129,8 @@ public class TeacherService extends ServiceImpl<TeacherMapper, TeacherPO> {
sysUserService.removeByUsername(teacherPO.getAccount()); sysUserService.removeByUsername(teacherPO.getAccount());
} }
} }
public TeacherPO getByAccount(String username) {
return getOne(Wrappers.<TeacherPO>lambdaQuery().eq(TeacherPO::getAccount,username));
}
} }
\ No newline at end of file
package com.qkdata.biz.management.vo;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 回复数据对象
*/
@Data
public class AnswerModel {
/**
* 问题ID
*/
@NotNull(message = "问题ID不能为空")
private Long questionId;
/**
* 回复内容
*/
@NotBlank(message = "内容不能为空")
private String content;
}
package com.qkdata.biz.management.vo;
import com.qkdata.biz.enums.AnswerTypeEnum;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 问题回复数据对象
*/
@Data
public class QAModel {
/**
* 问题ID
*/
private Long questionId;
/**
* 用户或讲师ID
*/
private Long userId;
/**
* 用户或讲师名称
*/
private String nickName;
/**
* 回复类型,用于区用户提问还是讲师回复
*/
private AnswerTypeEnum type;
/**
* 内容
*/
private String content;
/**
* 创建时间
*/
private LocalDateTime createTime;
}
package com.qkdata.biz.management.vo;
import com.qkdata.common.constants.Constants;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 查询问题回复请求参数
*/
@Data
public class QueryAnswerModel {
private int pageIndex = Constants.DEFAULT_PAGE;
private int pageSize = Constants.DEFAULT_PAGE_SIZE;
/**
* 问题ID
*/
@NotNull(message = "问题ID不能为空")
private Long questionId;
}
package com.qkdata.biz.management.vo;
import com.qkdata.common.constants.Constants;
import lombok.Data;
/**
* 问题列表查询参数
*/
@Data
public class QueryQuestionModel {
private int pageIndex = Constants.DEFAULT_PAGE;
private int pageSize = Constants.DEFAULT_PAGE_SIZE;
/**
* 用户昵称或用户手机号
*/
private String condition;
}
package com.qkdata.biz.management.vo;
import com.qkdata.biz.enums.QuestionStatusEnum;
import lombok.Data;
/**
* 问题数据对象
*/
@Data
public class QuestionModel {
/**
* 问题ID
*/
private Long id;
/**
* 用户ID
*/
private Long userId;
/**
* 用户昵称
*/
private String nickName;
/**
* 课程ID
*/
private Long courseId;
/**
* 课程名称
*/
private String courseName;
/**
* 课程封面url
*/
private String courseLogoUrl;
/**
* 章节ID
*/
private Long chapterId;
/**
* 章节名称
*/
private String chapterName;
/**
* 问题内容
*/
private String content;
/**
* 问题状态
*/
private QuestionStatusEnum status;
}
package com.qkdata.biz.web.controller;
import com.qkdata.biz.common.BizConstants;
import com.qkdata.biz.enums.QuestionStatusEnum;
import com.qkdata.biz.management.service.QAService;
import com.qkdata.biz.management.vo.*;
import com.qkdata.biz.web.vo.AskModel;
import com.qkdata.common.annotation.SysLog;
import com.qkdata.common.base.model.PageResult;
import com.qkdata.common.base.model.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@Api(tags = "问答模块接口-前端")
@RestController
@RequestMapping("/api/question")
public class FrontendQAController {
@Autowired
private QAService qaService;
@ApiOperation("提问")
@SysLog("提问")
@PostMapping("/ask")
@RequiresRoles(value = {BizConstants.ROLE_USER,BizConstants.ROLE_ENTERPRISE_ADMIN},logical = Logical.OR)
public Result<String> ask(@RequestBody @Validated AskModel model){
qaService.ask(model);
return Result.succeed("ok");
}
@ApiOperation("我的提问列表")
@SysLog("我的提问列表")
@PostMapping("/myList")
@RequiresRoles(value = {BizConstants.ROLE_USER,BizConstants.ROLE_ENTERPRISE_ADMIN},logical = Logical.OR)
public PageResult<QuestionModel> myList(@RequestBody QueryQuestionModel param){
param.setCondition(null);
return qaService.myQuestionPageList(param);
}
@ApiOperation("问题回复列表")
@SysLog("问题回复列表")
@PostMapping("/replyList")
@RequiresRoles(value = {BizConstants.ROLE_USER,BizConstants.ROLE_ENTERPRISE_ADMIN},logical = Logical.OR)
public PageResult<QAModel> replyList(@RequestBody QueryAnswerModel param){
return qaService.answerList(param);
}
@ApiOperation("补充提问题")
@SysLog("补充提问题")
@PostMapping("/reply")
@RequiresRoles(value = {BizConstants.ROLE_USER,BizConstants.ROLE_ENTERPRISE_ADMIN},logical = Logical.OR)
public Result<String> reply(@RequestBody AnswerModel model){
qaService.answer(model);
return Result.succeed("ok");
}
@ApiOperation("结束问答")
@SysLog("结束问答")
@GetMapping("/complete")
@RequiresRoles(value = {BizConstants.ROLE_USER,BizConstants.ROLE_ENTERPRISE_ADMIN},logical = Logical.OR)
public Result<String> complete(@RequestParam Long questionId){
qaService.changeQuestionStatus(questionId, QuestionStatusEnum.COMPLETE);
return Result.succeed("ok");
}
@ApiOperation("获取某个问题详细信息")
@SysLog("获取某个问题详细信息")
@GetMapping("/{questionId}")
@RequiresRoles(value = {BizConstants.ROLE_USER,BizConstants.ROLE_ENTERPRISE_ADMIN},logical = Logical.OR)
public Result<QuestionModel> getQuestion(@PathVariable Long questionId){
QuestionModel model = qaService.getQuestion(questionId);
return Result.succeed(model);
}
}
package com.qkdata.biz.web.vo;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 提问题数据对象
*/
@Data
public class AskModel {
/**
* 课程ID
*/
@NotNull(message = "课程ID不能为空")
private Long courseId;
/**
* 章节ID
*/
@NotNull(message = "章节ID不能为空")
private Long chapterId;
/**
* 问题内容
*/
@NotBlank(message = "问题描述不能为空")
private String content;
}
ALTER TABLE `question`
MODIFY COLUMN `status` tinyint(1) NULL DEFAULT NULL COMMENT '状态:待回复、已回复、已完成' AFTER `update_time`;
\ No newline at end of file
<?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.qkdata.biz.management.mapper.AnswerMapper">
<select id="answerPageList" resultType="com.qkdata.biz.management.vo.QAModel">
SELECT a.question_id,
a.user_id,
u.nick_name,
a.type,
a.content,
a.create_time
FROM answer a
INNER JOIN sys_user u on a.user_id = u.id
WHERE a.question_id = #{p.questionId}
ORDER BY a.create_time ASC
</select>
</mapper>
<?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.qkdata.biz.management.mapper.QuestionMapper">
<select id="questionPageList" resultType="com.qkdata.biz.management.vo.QuestionModel">
SELECT q.id,
q.user_id,
u.nick_name,
q.course_id,
c.`name` course_name,
q.chapter_id,
chp.`name` chapter_name,
q.content,
q.`status`,
q.create_time,
q.update_time
from question q
INNER JOIN sys_user u on q.user_id = u.id
INNER JOIN course c on q.course_id = c.id
INNER JOIN course_chapter chp on q.chapter_id = chp.id
where 1 =1
<if test="tId != null">
and c.teacher_id = #{tId}
</if>
<if test="p.condition != null and p.condition != ''">
and u.username like concat('%',#{p.condition},'%')
or u.nick_name like concat('%',#{p.condition},'%')
</if>
ORDER BY q.`status` ASC,q.update_time DESC
</select>
<select id="myQuestionPageList" resultType="com.qkdata.biz.management.vo.QuestionModel">
SELECT q.id,
q.user_id,
u.nick_name,
q.course_id,
c.`name` course_name,
q.chapter_id,
chp.`name` chapter_name,
q.content,
q.`status`,
q.create_time,
q.update_time
from question q
INNER JOIN sys_user u on q.user_id = u.id
INNER JOIN course c on q.course_id = c.id
INNER JOIN course_chapter chp on q.chapter_id = chp.id
where q.user_id = #{userId}
ORDER BY q.`status` ASC,q.update_time DESC
</select>
<select id="findQuestion" resultType="com.qkdata.biz.management.vo.QuestionModel">
SELECT q.id,
q.user_id,
u.nick_name,
q.course_id,
c.`name` course_name,
c.logo_url course_logo_url,
q.chapter_id,
chp.`name` chapter_name,
q.content,
q.`status`,
q.create_time,
q.update_time
from question q
INNER JOIN sys_user u on q.user_id = u.id
INNER JOIN course c on q.course_id = c.id
INNER JOIN course_chapter chp on q.chapter_id = chp.id
where q.id = #{questionId}
</select>
</mapper>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment