Commit 891b94e7 authored by liuyang's avatar liuyang

完成用户端课程详情、获取视频播放凭证接口

parent 238110ae
...@@ -168,6 +168,12 @@ public class AliyunService { ...@@ -168,6 +168,12 @@ public class AliyunService {
return vodClient.getAcsResponse(request); return vodClient.getAcsResponse(request);
} }
public GetVideoPlayAuthResponse getVideoPlayAuth(String videoId) throws ClientException {
GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest();
request.setVideoId(videoId);
request.setAuthInfoTimeout(3000L);
return vodClient.getAcsResponse(request);
}
public void removeVideo(String videoId) throws ClientException { public void removeVideo(String videoId) throws ClientException {
DeleteMezzaninesRequest request = new DeleteMezzaninesRequest(); DeleteMezzaninesRequest request = new DeleteMezzaninesRequest();
......
package com.qkdata.biz.enums;
public enum UserPayRecordTypeEnum {
/**
* 月卡购买
*/
MONTH_VIP,
/**
* 单课购买
*/
SINGLE_COURSE
}
package com.qkdata.biz.management.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.qkdata.biz.enums.UserPayRecordTypeEnum;
import com.qkdata.common.base.entity.BasePO;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 企业会员领取记录
* </p>
*
* @author liuyang
* @since 2021-05-28
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("user_get_vip_record")
public class UserGetVipRecordPO extends BasePO {
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
private Long userId;
/**
* 领取类型(月卡、付费点播课程)
*/
private UserPayRecordTypeEnum type;
/**
* 课程ID
*/
private Long courseId;
/**
* 企业ID
*/
private Long orgId;
}
package com.qkdata.biz.management.mapper;
import com.qkdata.biz.management.entity.UserGetVipRecordPO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 企业会员领取记录 Mapper 接口
* </p>
*
* @author liuyang
* @since 2021-05-28
*/
@Mapper
public interface UserGetVipRecordMapper extends BaseMapper<UserGetVipRecordPO> {
}
...@@ -5,6 +5,7 @@ import cn.hutool.core.util.StrUtil; ...@@ -5,6 +5,7 @@ import cn.hutool.core.util.StrUtil;
import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse; import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse;
import com.aliyuncs.vod.model.v20170321.GetVideoInfoResponse; import com.aliyuncs.vod.model.v20170321.GetVideoInfoResponse;
import com.aliyuncs.vod.model.v20170321.GetVideoPlayAuthResponse;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
...@@ -228,7 +229,18 @@ public class CourseService extends ServiceImpl<CourseMapper, CoursePO> { ...@@ -228,7 +229,18 @@ public class CourseService extends ServiceImpl<CourseMapper, CoursePO> {
if (po != null) { if (po != null) {
chapterMapper.deleteById(chaperId); chapterMapper.deleteById(chaperId);
//删除资源 //删除资源
resourceService.removeById(po.getResourceId()); ResourcePO resourcePO = resourceService.getById(po.getResourceId());
if (resourcePO != null){
resourceService.removeById(po.getResourceId());
}
if (StrUtil.isNotBlank(resourcePO.getVideoId())){
try {
aliyunService.removeVideo(resourcePO.getVideoId());
} catch (ClientException e) {
log.error(e.getMessage(),e);
}
}
} }
...@@ -346,11 +358,11 @@ public class CourseService extends ServiceImpl<CourseMapper, CoursePO> { ...@@ -346,11 +358,11 @@ public class CourseService extends ServiceImpl<CourseMapper, CoursePO> {
private void saveCourseChaper(Long courseId, List<SaveCourseChaperModel> chaperList) { private void saveCourseChaper(Long courseId, List<SaveCourseChaperModel> chaperList) {
if (CollUtil.isNotEmpty(chaperList)){ if (CollUtil.isNotEmpty(chaperList)){
for (SaveCourseChaperModel chaperModel : chaperList){ for (SaveCourseChaperModel chaperModel : chaperList){
Long chaperId = chaperModel.getChaperId(); Long chaperId = chaperModel.getId();
if (chaperId == null){ if (chaperId == null){
//只做章节新增保存 //只做章节新增保存
ResourcePO resourcePO = new ResourcePO(); ResourcePO resourcePO = new ResourcePO();
resourcePO.setName(chaperModel.getChaperName()); resourcePO.setName(chaperModel.getName());
resourcePO.setVideoId(chaperModel.getVideoId()); resourcePO.setVideoId(chaperModel.getVideoId());
try { try {
GetVideoInfoResponse videoInfoResponse = aliyunService.getVideoInfo(chaperModel.getVideoId()); GetVideoInfoResponse videoInfoResponse = aliyunService.getVideoInfo(chaperModel.getVideoId());
...@@ -363,7 +375,7 @@ public class CourseService extends ServiceImpl<CourseMapper, CoursePO> { ...@@ -363,7 +375,7 @@ public class CourseService extends ServiceImpl<CourseMapper, CoursePO> {
CourseChapterPO chapterPO = new CourseChapterPO(); CourseChapterPO chapterPO = new CourseChapterPO();
chapterPO.setCourseId(courseId); chapterPO.setCourseId(courseId);
chapterPO.setSortNo(chaperModel.getSortNo()); chapterPO.setSortNo(chaperModel.getSortNo());
chapterPO.setName(chaperModel.getChaperName()); chapterPO.setName(chaperModel.getName());
chapterPO.setResourceId(resourcePO.getId()); chapterPO.setResourceId(resourcePO.getId());
chapterMapper.insert(chapterPO); chapterMapper.insert(chapterPO);
} }
...@@ -430,6 +442,9 @@ public class CourseService extends ServiceImpl<CourseMapper, CoursePO> { ...@@ -430,6 +442,9 @@ public class CourseService extends ServiceImpl<CourseMapper, CoursePO> {
if (coursePO == null){ if (coursePO == null){
throw new BusinessException("请求错误,该课程不存在"); throw new BusinessException("请求错误,该课程不存在");
} }
if (coursePO.getStatus() == CourseStatusEnum.DOWN){
throw new BusinessException("该课程已下架");
}
if (coursePO.getAllow() == CourseAllowEnum.SPECIFY){ if (coursePO.getAllow() == CourseAllowEnum.SPECIFY){
List<Long> allowOrgIds = getAllowEnterpriseList(courseId); List<Long> allowOrgIds = getAllowEnterpriseList(courseId);
if (CollUtil.isNotEmpty(allowOrgIds)){ if (CollUtil.isNotEmpty(allowOrgIds)){
...@@ -452,4 +467,125 @@ public class CourseService extends ServiceImpl<CourseMapper, CoursePO> { ...@@ -452,4 +467,125 @@ public class CourseService extends ServiceImpl<CourseMapper, CoursePO> {
throw new BusinessException("对不起,您没权限查看该课程"); throw new BusinessException("对不起,您没权限查看该课程");
} }
} }
public String getVideoPlayUrl(Long courseId, Long chaperId) {
CourseChapterPO po = chapterMapper.selectById(chaperId);
if (po != null){
ResourcePO resourcePO = resourceService.getById(po.getResourceId());
if (resourcePO != null && StrUtil.isNotBlank(resourcePO.getVideoId())){
try {
GetPlayInfoResponse response = aliyunService.getVideoPlayInfo(resourcePO.getVideoId());
if (CollUtil.isNotEmpty(response.getPlayInfoList())){
GetPlayInfoResponse.PlayInfo playInfo = response.getPlayInfoList().get(0);
return playInfo.getPlayURL();
}
} catch (ClientException e) {
e.printStackTrace();
}
}
}
return "";
}
public GetVideoPlayAuthResponse getVideoPlayAuth(Long courseId,Long chaperId){
CourseChapterPO po = chapterMapper.selectById(chaperId);
if (po != null){
ResourcePO resourcePO = resourceService.getById(po.getResourceId());
if (resourcePO != null && StrUtil.isNotBlank(resourcePO.getVideoId())){
try {
GetVideoPlayAuthResponse response = aliyunService.getVideoPlayAuth(resourcePO.getVideoId());
return response;
} catch (ClientException e) {
throw new BusinessException("获取视频凭证异常");
}
}
}
return null;
}
/**
* 推荐课程列表
* 默认推荐4个课程
* 优先推荐相同系列下的其它课程
* 如果相同系列下没有其它课程,则随机推荐其它课程
* 注意过滤指定企业可见范围的课程
* @return
*/
public List<RecommendConfigModel> recommend(Long courseId) {
CoursePO coursePO = getById(courseId);
if (coursePO != null){
throw new BusinessException("请求错误,课程不存在");
}
List<RecommendConfigModel> resultList = Lists.newArrayList();
Long seriesId = coursePO.getSeriesId();
Long enterpriseId = sysUserService.getCurrentUserEnterpriseId();
List<CoursePO> sameSeriesCourseList = list(Wrappers.<CoursePO>lambdaQuery().eq(CoursePO::getSeriesId,seriesId).eq(CoursePO::getStatus,CourseStatusEnum.UP));
for (CoursePO course : sameSeriesCourseList){
if (course.getAllow() == CourseAllowEnum.SPECIFY){
List<Long> orgIds = getAllowEnterpriseList(courseId);
boolean hasPerm = false;
for (Long orgId : orgIds){
if (enterpriseId != null){
if (orgId.longValue() == enterpriseId.longValue()){
hasPerm = true;
break;
}
}
}
if (hasPerm){
RecommendConfigModel model = new RecommendConfigModel();
model.setCourseId(courseId);
model.setCourseName(course.getName());
model.setCourseLogoUrl(course.getLogoUrl());
model.setChargeModel(course.getChargeModel());
model.setAllow(course.getAllow());
resultList.add(model);
}else {
continue;
}
}else {
RecommendConfigModel model = new RecommendConfigModel();
model.setCourseId(courseId);
model.setCourseName(course.getName());
model.setCourseLogoUrl(course.getLogoUrl());
model.setChargeModel(course.getChargeModel());
model.setAllow(course.getAllow());
resultList.add(model);
}
if (resultList.size() == 4){
break;
}
}
if (resultList.size() < 4){
int diff = 4 - resultList.size();
List<Long> ids = resultList.stream().map(RecommendConfigModel::getCourseId).collect(Collectors.toList());
List<CoursePO> courseList = list(Wrappers.<CoursePO>lambdaQuery()
.notIn(CoursePO::getId,ids)
.eq(CoursePO::getStatus,CourseStatusEnum.UP)
.last("limit "+diff));
for (CoursePO course : courseList){
RecommendConfigModel model = new RecommendConfigModel();
model.setCourseId(courseId);
model.setCourseName(course.getName());
model.setCourseLogoUrl(course.getLogoUrl());
model.setChargeModel(course.getChargeModel());
model.setAllow(course.getAllow());
resultList.add(model);
}
}
for (RecommendConfigModel model : resultList){
List<CourseTagPO> tagList = tagService.findListByCourseId(model.getCourseId());
model.setTags(tagList);
List<CourseChaperModel> chaperList = chaperList(model.getCourseId());
if (CollUtil.isNotEmpty(chaperList)){
CourseChaperModel chaperModel = chaperList.get(0);
ResourcePO resourcePO = resourceService.getById(chaperModel.getResourceId());
if (resourcePO != null){
model.setDuration(resourcePO.getVideoDuration());
}
}
}
return resultList;
}
} }
\ No newline at end of file
package com.qkdata.biz.management.service;
import com.qkdata.biz.management.entity.UserGetVipRecordPO;
import com.qkdata.biz.management.mapper.UserGetVipRecordMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* $!{table.comment} 服务类
* </p>
*
* @author liuyang
* @since 2021-05-28
*/
@Service
public class UserGetVipRecordService extends ServiceImpl<UserGetVipRecordMapper, UserGetVipRecordPO> {
}
\ No newline at end of file
...@@ -4,8 +4,8 @@ import lombok.Data; ...@@ -4,8 +4,8 @@ import lombok.Data;
@Data @Data
public class SaveCourseChaperModel { public class SaveCourseChaperModel {
private Long chaperId; private Long id;
private String chaperName; private String name;
private Integer sortNo = 0; private Integer sortNo = 0;
private String videoId; private String videoId;
} }
...@@ -135,4 +135,10 @@ public class SysUserService extends BaseServiceImpl<SysUserMapper, SysUserPO> { ...@@ -135,4 +135,10 @@ public class SysUserService extends BaseServiceImpl<SysUserMapper, SysUserPO> {
extUser.setType(AccountTypeEnum.USER); extUser.setType(AccountTypeEnum.USER);
sysUserExtMapper.insert(extUser); sysUserExtMapper.insert(extUser);
} }
public Long getCurrentUserEnterpriseId(){
String username = UserContext.getUser().getUsername();
FullUserInfo userInfo = findFullUserInfo(username);
Long enterpriesId = userInfo.getId();
return enterpriesId;
}
} }
package com.qkdata.biz.web.controller; package com.qkdata.biz.web.controller;
import com.aliyuncs.vod.model.v20170321.GetVideoPlayAuthResponse;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qkdata.biz.aliyun.service.AliyunService;
import com.qkdata.biz.common.BizConstants; import com.qkdata.biz.common.BizConstants;
import com.qkdata.biz.management.entity.CourseTagPO; import com.qkdata.biz.management.entity.CourseTagPO;
import com.qkdata.biz.management.entity.RecommendConfigPO;
import com.qkdata.biz.management.service.CourseService; import com.qkdata.biz.management.service.CourseService;
import com.qkdata.biz.management.service.CourseTagService; import com.qkdata.biz.management.service.CourseTagService;
import com.qkdata.biz.management.service.RecommendConfigService; import com.qkdata.biz.management.service.RecommendConfigService;
import com.qkdata.biz.management.service.SwiperConfigService; import com.qkdata.biz.management.service.SwiperConfigService;
import com.qkdata.biz.management.vo.CourseDetailModel; import com.qkdata.biz.management.vo.CourseDetailModel;
import com.qkdata.biz.management.vo.CourseTagsModel;
import com.qkdata.biz.management.vo.RecommendConfigModel; import com.qkdata.biz.management.vo.RecommendConfigModel;
import com.qkdata.biz.management.vo.SwiperConfigModel; import com.qkdata.biz.management.vo.SwiperConfigModel;
import com.qkdata.biz.web.service.UserCenterService;
import com.qkdata.biz.web.vo.MainPageModel; import com.qkdata.biz.web.vo.MainPageModel;
import com.qkdata.biz.web.vo.SearchCourseConditionModel; import com.qkdata.biz.web.vo.SearchCourseConditionModel;
import com.qkdata.biz.web.vo.SearchCourseResultModel; import com.qkdata.biz.web.vo.SearchCourseResultModel;
...@@ -41,6 +42,8 @@ public class MainPageController { ...@@ -41,6 +42,8 @@ public class MainPageController {
private CourseService courseService; private CourseService courseService;
@Autowired @Autowired
private CourseTagService tagService; private CourseTagService tagService;
@Autowired
private UserCenterService userCenterService;
@ApiOperation("获取配置信息") @ApiOperation("获取配置信息")
@GetMapping("") @GetMapping("")
...@@ -72,6 +75,15 @@ public class MainPageController { ...@@ -72,6 +75,15 @@ public class MainPageController {
List<CourseTagPO> tags = tagService.list(); List<CourseTagPO> tags = tagService.list();
return Result.succeed(tags); return Result.succeed(tags);
} }
@ApiOperation("获取推荐课程")
@GetMapping("/course/recommend/{courseId}")
@RequiresRoles(value = {BizConstants.ROLE_USER,BizConstants.ROLE_ENTERPRISE_ADMIN},logical = Logical.OR)
public Result<List<RecommendConfigModel>> courseRecommend(Long courseId){
List<RecommendConfigModel> list = courseService.recommend(courseId);
return Result.succeed(list);
}
@ApiOperation("获取课程详情") @ApiOperation("获取课程详情")
@GetMapping("/course/{id}") @GetMapping("/course/{id}")
@RequiresRoles(value = {BizConstants.ROLE_USER,BizConstants.ROLE_ENTERPRISE_ADMIN},logical = Logical.OR) @RequiresRoles(value = {BizConstants.ROLE_USER,BizConstants.ROLE_ENTERPRISE_ADMIN},logical = Logical.OR)
...@@ -81,4 +93,15 @@ public class MainPageController { ...@@ -81,4 +93,15 @@ public class MainPageController {
CourseDetailModel model = courseService.getCourseDetail(id); CourseDetailModel model = courseService.getCourseDetail(id);
return Result.succeed(model); return Result.succeed(model);
} }
@ApiOperation("获取视频播放凭证")
@GetMapping("/course/playVideo")
@RequiresRoles(value = {BizConstants.ROLE_USER,BizConstants.ROLE_ENTERPRISE_ADMIN},logical = Logical.OR)
@SysLog("获取视频播放凭证")
public Result<GetVideoPlayAuthResponse> getCoursePlayVideoUrl(@RequestParam Long courseId,@RequestParam Long chaperId){
//验证权限
userCenterService.checkCoursePlayPerm(courseId,chaperId);
GetVideoPlayAuthResponse response = courseService.getVideoPlayAuth(courseId,chaperId);
return Result.succeed(response);
}
} }
package com.qkdata.biz.web.service;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qkdata.biz.enums.CourseAllowEnum;
import com.qkdata.biz.enums.CourseChargeModelEnum;
import com.qkdata.biz.enums.CourseStatusEnum;
import com.qkdata.biz.enums.UserPayRecordTypeEnum;
import com.qkdata.biz.management.entity.CoursePO;
import com.qkdata.biz.management.entity.UserGetVipRecordPO;
import com.qkdata.biz.management.service.CourseService;
import com.qkdata.biz.management.service.UserGetVipRecordService;
import com.qkdata.biz.sys.service.SysUserService;
import com.qkdata.biz.web.vo.FullUserInfo;
import com.qkdata.common.base.entity.BasePO;
import com.qkdata.common.base.exception.BusinessException;
import com.qkdata.common.util.UserContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
@Slf4j
@Service
public class UserCenterService {
@Autowired
private SysUserService sysUserService;
@Autowired
private CourseService courseService;
@Autowired
private UserGetVipRecordService userGetVipRecordService;
/**
* 验证当前登陆用户是否有播放该课程和章节的权限
* 课程可见范围是否指定企业,当前用户是否符合
* 课程收费模式为免费,允许观看
* 课程收费模式为会员费免,当前用户是否已购买会员,并且在有效期中
* 课程收费模式为付费点播,当前用户是否已购买该课程,并且在效期中
* @param courseId
* @param chaperId
*/
public void checkCoursePlayPerm(Long courseId, Long chaperId) {
String username = UserContext.getUser().getUsername();
Long userId = UserContext.getUserId();
FullUserInfo userInfo = sysUserService.findFullUserInfo(username);
CoursePO course = courseService.getById(courseId);
if (course.getStatus() == CourseStatusEnum.DOWN){
throw new BusinessException("该课程已下架");
}
if (course.getAllow() == CourseAllowEnum.SPECIFY){
List<Long> orgIds = courseService.getAllowEnterpriseList(courseId);
boolean allow = false;
for (Long orgId : orgIds){
if (userInfo.getEnterpriseId() != null){
if (orgId.longValue() == userInfo.getEnterpriseId().longValue()){
allow = true;
break;
}
}
}
if (!allow){
throw new BusinessException("当前课程指已定企业观看,您不符合条件,请联系客服务人员");
}
}
if (course.getChargeModel() == CourseChargeModelEnum.FREE){
return;
}else if (course.getChargeModel() == CourseChargeModelEnum.VIP_FREE){
if (userInfo.getVipStartTime() == null || userInfo.getVipEndTime() == null){
throw new BusinessException("您还不是会员,请先成为会员再观看");
}
LocalDateTime now = LocalDateTime.now();
if (!(now.isAfter(userInfo.getVipStartTime()) && now.isBefore(userInfo.getVipEndTime()))){
throw new BusinessException("您的会员已过期,请续费后再观看");
}
}else if (course.getChargeModel() == CourseChargeModelEnum.PAY){
UserGetVipRecordPO userGetVipRecordPO = userGetVipRecordService.getOne(Wrappers.<UserGetVipRecordPO>lambdaQuery()
.eq(UserGetVipRecordPO::getUserId,userId)
.eq(UserGetVipRecordPO::getCourseId,courseId)
.eq(UserGetVipRecordPO::getType,UserPayRecordTypeEnum.SINGLE_COURSE)
.orderByDesc(BasePO::getCreateTime)
.last("limit 1"));
if (userGetVipRecordPO == null){
throw new BusinessException("当前课程为付费课程,请购买后再观看");
}
Integer validPeriod = course.getValidPeriod();
LocalDateTime startTime = userGetVipRecordPO.getCreateTime();
LocalDateTime endTime = startTime.plusHours(validPeriod);
LocalDateTime now = LocalDateTime.now();
if (!(now.isAfter(startTime) && now.isBefore(endTime))){
throw new BusinessException("您购买的该课程已过期,请重新购买");
}
}
}
}
...@@ -68,6 +68,14 @@ public class FullUserInfo { ...@@ -68,6 +68,14 @@ public class FullUserInfo {
* 是否企业管理员 * 是否企业管理员
*/ */
private boolean enterpriesMgr = false; private boolean enterpriesMgr = false;
/**
* vip会员开始时间
*/
private LocalDateTime vipStartTime;
/**
* vip会员结束时间
*/
private LocalDateTime vipEndTime;
/** /**
* 认证token * 认证token
*/ */
......
...@@ -64,6 +64,7 @@ ...@@ -64,6 +64,7 @@
WHERE WHERE
c.is_del = 0 c.is_del = 0
AND c.allow = 'ALL' AND c.allow = 'ALL'
and c.status = 'UP'
UNION UNION
SELECT SELECT
c.id course_id, c.id course_id,
...@@ -75,6 +76,7 @@ ...@@ -75,6 +76,7 @@
INNER JOIN allow_org_course o ON c.id = o.course_id INNER JOIN allow_org_course o ON c.id = o.course_id
WHERE WHERE
c.is_del = 0 c.is_del = 0
and c.status = 'UP'
AND c.allow = 'SPECIFY' AND c.allow = 'SPECIFY'
AND o.org_id = #{enterpriseId} AND o.org_id = #{enterpriseId}
) tmp ) tmp
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
c.allow c.allow
from recommend_config cfg from recommend_config cfg
INNER JOIN course c on cfg.course_id = c.id INNER JOIN course c on cfg.course_id = c.id
and c.status = 'UP'
ORDER BY cfg.sort_no ASC ORDER BY cfg.sort_no ASC
</select> </select>
</mapper> </mapper>
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
s.`name` course_name s.`name` course_name
from swiper_config c from swiper_config c
INNER JOIN course s on c.course_id = s.id INNER JOIN course s on c.course_id = s.id
and c.status = 'ENABLE'
and s.status = 'UP'
ORDER BY c.sort_no ASC ORDER BY c.sort_no ASC
</select> </select>
</mapper> </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.UserGetVipRecordMapper">
</mapper>
...@@ -35,7 +35,9 @@ ...@@ -35,7 +35,9 @@
e.sex, e.sex,
e.avatar_url, e.avatar_url,
e.type, e.type,
e.enterprise_id e.enterprise_id,
e.vip_start_time,
e.vip_end_time
FROM sys_user u FROM sys_user u
INNER JOIN user_ext e on u.id = e.user_id INNER JOIN user_ext e on u.id = e.user_id
WHERE u.is_del = 0 WHERE u.is_del = 0
......
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