Commit b3033f79 by 邓敏

Merge branch 'websocker'

2 parents b8a6f5cc 2c64b3b6
Showing with 930 additions and 161 deletions
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
<dependency> <dependency>
<groupId>com.tencentcloudapi</groupId> <groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java</artifactId> <artifactId>tencentcloud-sdk-java</artifactId>
<version>3.1.64</version> <version>3.1.322</version>
</dependency> </dependency>
<dependency> <dependency>
...@@ -221,6 +221,22 @@ ...@@ -221,6 +221,22 @@
<artifactId>spring-boot-starter-websocket</artifactId> <artifactId>spring-boot-starter-websocket</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java</artifactId>
<version>3.1.322</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<!-- <dependency>--> <!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>--> <!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-mongodb</artifactId>--> <!-- <artifactId>spring-boot-starter-data-mongodb</artifactId>-->
......
...@@ -3,6 +3,7 @@ package com.subsidy; ...@@ -3,6 +3,7 @@ package com.subsidy;
import org.mybatis.spring.annotation.MapperScan; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
...@@ -11,6 +12,7 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -11,6 +12,7 @@ import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication @SpringBootApplication
@MapperScan(basePackages = {"com.subsidy.mapper"}) @MapperScan(basePackages = {"com.subsidy.mapper"})
@EnableScheduling @EnableScheduling
@EnableCaching
@EnableAsync @EnableAsync
public class MeishuApplication { public class MeishuApplication {
......
package com.subsidy.common.configure;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@ConfigurationProperties(prefix = "activity")
public class ActivityDetectionConfig {
private Long captchaAppId;
private String appSecretKey;
private Long businessId;
}
package com.subsidy.common.constant;
import lombok.Getter;
@Getter
public class VodConstant {
/* 流量 */
public final static String FLUX = "Flux";
/* 带宽 */
public final static String BANDWIDTH = "Bandwidth";
/* 请求数 */
public final static String REQUESTS = "Requests";
/* 请求命中率 */
public final static String HITRATE = "Hitrate";
/* IP访问次数 */
public final static String IP_VISITS = "Ip_visits";
/* 带宽缓存key */
public final static String BANDWIDTH_CACHE_KEY = "CDNStatBandwidthCache";
/* 流量缓存key */
public final static String FLUX_CACHE_KEY = "CDNStatFluxCache";
/* 自定义缓存名称(ehcache.xml中的自定义规则名称) */
public final static String CDN_STAT_DETAILS_CACHE_NAME = "CDNStatDetails";
}
...@@ -103,4 +103,6 @@ public class AccessTokenController { ...@@ -103,4 +103,6 @@ public class AccessTokenController {
signVO.setSign(SecretUtils.getSHAString(signStr)); signVO.setSign(SecretUtils.getSHAString(signStr));
return ResponseData.generateCreatedResponse(0,signVO); return ResponseData.generateCreatedResponse(0,signVO);
} }
} }
...@@ -4,8 +4,8 @@ package com.subsidy.controller; ...@@ -4,8 +4,8 @@ package com.subsidy.controller;
import com.subsidy.common.ResponseData; import com.subsidy.common.ResponseData;
import com.subsidy.common.ResponseVO; import com.subsidy.common.ResponseVO;
import com.subsidy.common.interceptor.TimeRequired; import com.subsidy.common.interceptor.TimeRequired;
import com.subsidy.dto.detection.GetCheckHistoryDTO;
import com.subsidy.dto.detection.VerifyDTO; import com.subsidy.dto.detection.VerifyDTO;
import com.subsidy.model.ActivityDetectionDO;
import com.subsidy.service.ActivityDetectionService; import com.subsidy.service.ActivityDetectionService;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -43,11 +43,8 @@ public class ActivityDetectionController { ...@@ -43,11 +43,8 @@ public class ActivityDetectionController {
@PostMapping("getCheckHistory") @PostMapping("getCheckHistory")
@ApiOperation("获取某个人某个课程的活跃度验证详情 memberId classId") @ApiOperation("获取某个人某个课程的活跃度验证详情 memberId classId")
public ResponseVO getCheckHistory(@RequestBody ActivityDetectionDO activityDetectionDO){ public ResponseVO getCheckHistory(@RequestBody GetCheckHistoryDTO getCheckHistoryDTO){
return ResponseData.generateCreatedResponse(0,activityDetectionService.getCheckHistory(activityDetectionDO)); return ResponseData.generateCreatedResponse(0,activityDetectionService.getCheckHistory(getCheckHistoryDTO));
} }
} }
...@@ -77,4 +77,11 @@ public class CompanyDictController { ...@@ -77,4 +77,11 @@ public class CompanyDictController {
return ResponseData.generateCreatedResponse(0,companyDictService.getCompanyMembers(getCompanyMembersDTO)); return ResponseData.generateCreatedResponse(0,companyDictService.getCompanyMembers(getCompanyMembersDTO));
} }
@PostMapping("memberSummary")
@ApiOperation("学员认证详情 companyId")
@LoginRequired
public ResponseVO memberSummary(@RequestBody GetCompanyMembersDTO getCompanyMembersDTO){
return ResponseData.generateCreatedResponse(0,companyDictService.memberSummary(getCompanyMembersDTO));
}
} }
...@@ -4,6 +4,7 @@ package com.subsidy.controller; ...@@ -4,6 +4,7 @@ package com.subsidy.controller;
import com.subsidy.common.ResponseData; import com.subsidy.common.ResponseData;
import com.subsidy.common.ResponseVO; import com.subsidy.common.ResponseVO;
import com.subsidy.common.interceptor.LoginRequired; import com.subsidy.common.interceptor.LoginRequired;
import com.subsidy.dto.image.ImageCheckDTO;
import com.subsidy.model.ImageCheckRecordDO; import com.subsidy.model.ImageCheckRecordDO;
import com.subsidy.service.ImageCheckRecordService; import com.subsidy.service.ImageCheckRecordService;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
...@@ -30,14 +31,19 @@ public class ImageCheckRecordController { ...@@ -30,14 +31,19 @@ public class ImageCheckRecordController {
@Autowired @Autowired
private ImageCheckRecordService imageCheckRecordService; private ImageCheckRecordService imageCheckRecordService;
@PostMapping("getImageCheckHistory") @PostMapping("getImageCheckHistory")
@ApiOperation("获取某人某个班级的验证历史 memberId classId ") @ApiOperation("获取某人某个班级的验证历史 memberId classId ")
@LoginRequired @LoginRequired
public ResponseVO getImageCheckHistory(@RequestBody ImageCheckRecordDO imageCheckRecordDO){ public ResponseVO getImageCheckHistory(@RequestBody ImageCheckRecordDO imageCheckRecordDO) {
return ResponseData.generateCreatedResponse(0,imageCheckRecordService.getImageCheckHistory(imageCheckRecordDO)); return ResponseData.generateCreatedResponse(0, imageCheckRecordService.getImageCheckHistory(imageCheckRecordDO));
}
@PostMapping("imageCheck")
@ApiOperation("人身核验 id 用户id nonce ")
public ResponseVO imageCheck(@RequestBody ImageCheckDTO imageCheckDTO) throws Exception {
return ResponseData.generateCreatedResponse(0, imageCheckRecordService.imageCheck(imageCheckDTO));
} }
......
...@@ -102,13 +102,6 @@ public class MemberController { ...@@ -102,13 +102,6 @@ public class MemberController {
return ResponseData.generateCreatedResponse(0,memberService.updatePassword(memberDO)); return ResponseData.generateCreatedResponse(0,memberService.updatePassword(memberDO));
} }
@PostMapping("updateCheckImage")
@ApiOperation("上传采集照片 id checkImage")
@TimeRequired
public ResponseVO updateCheckImage(@RequestBody MemberDO memberDO){
return ResponseData.generateCreatedResponse(0,memberService.updateCheckImage(memberDO));
}
@PostMapping("removeCheckImage") @PostMapping("removeCheckImage")
@ApiOperation("清除采集照片 id ") @ApiOperation("清除采集照片 id ")
public ResponseVO removeCheckImage(@RequestBody MemberDO memberDO){ public ResponseVO removeCheckImage(@RequestBody MemberDO memberDO){
......
...@@ -45,7 +45,7 @@ public class VodPlayHistoryController { ...@@ -45,7 +45,7 @@ public class VodPlayHistoryController {
@RequestMapping("insertHistoryNew") @RequestMapping("insertHistoryNew")
@ApiOperation("记录学生看视频位置 classId班级id vodId 视频id memberId 成员id playLength 播放时长 playRecord 位点") @ApiOperation("记录学生看视频位置 classId班级id vodId 视频id memberId 成员id playLength 播放时长 playRecord 位点")
// @LoginRequired @LoginRequired
@TimeRequired @TimeRequired
public ResponseVO insertHistoryNew(@RequestBody String param){ public ResponseVO insertHistoryNew(@RequestBody String param){
InsertHistoryNewDTO insertHistoryNewDTO = JSON.parseObject(param, InsertHistoryNewDTO.class); InsertHistoryNewDTO insertHistoryNewDTO = JSON.parseObject(param, InsertHistoryNewDTO.class);
......
package com.subsidy.dto.company;
import lombok.Data;
@Data
public class DataOverviewDTO {
private Long companyId;
}
package com.subsidy.dto.detection;
import lombok.Data;
@Data
public class GetCheckHistoryDTO {
private Integer pageSize;
private Integer pageNum;
private Long memberId;
private Long classId;
}
package com.subsidy.dto.image;
import lombok.Data;
@Data
public class ImageCheckDTO {
private Long id;
private String imageBase64;
private Long classId;
private Long paperId;
private String nonce ;
}
package com.subsidy.mapper; package com.subsidy.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.subsidy.model.ActivityDetectionDO; import com.subsidy.model.ActivityDetectionDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.subsidy.vo.activity.GetCheckHistoryVO;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
/** /**
...@@ -15,4 +17,6 @@ import org.springframework.stereotype.Repository; ...@@ -15,4 +17,6 @@ import org.springframework.stereotype.Repository;
@Repository @Repository
public interface ActivityDetectionMapper extends BaseMapper<ActivityDetectionDO> { public interface ActivityDetectionMapper extends BaseMapper<ActivityDetectionDO> {
IPage<GetCheckHistoryVO> getCheckHistory(IPage iPage,Long classId,Long memberId);
} }
...@@ -53,4 +53,6 @@ public interface ClassDictMapper extends BaseMapper<ClassDictDO> { ...@@ -53,4 +53,6 @@ public interface ClassDictMapper extends BaseMapper<ClassDictDO> {
* 班级信息 -- 获取课程信息 + 公司信息 * 班级信息 -- 获取课程信息 + 公司信息
* */ * */
ClassAndCompanyInfoVO getClassAndCompanyInfoVO(Long classId); ClassAndCompanyInfoVO getClassAndCompanyInfoVO(Long classId);
Integer getClassCount();
} }
...@@ -97,4 +97,9 @@ public interface VodPlayHistoryMapper extends BaseMapper<VodPlayHistoryDO> { ...@@ -97,4 +97,9 @@ public interface VodPlayHistoryMapper extends BaseMapper<VodPlayHistoryDO> {
List<VodPlayHistoryDO> getVodPlayDay(Long classId, Long memberId, Date endDate); List<VodPlayHistoryDO> getVodPlayDay(Long classId, Long memberId, Date endDate);
double getStudyTotal();
double getSubsidyStudyTotal();
int getStudyHistoryNum();
} }
...@@ -78,6 +78,45 @@ public class ClassDictDO extends BaseModel { ...@@ -78,6 +78,45 @@ public class ClassDictDO extends BaseModel {
*/ */
private Integer testRule; private Integer testRule;
/**
* 学习上限时长
*/
private Integer limitHour;
/**
* 首次进入班级时人脸验证
*/
private Integer imageClassCheck;
/**
* 测试前人脸识别验证
*/
private Integer imageTestCheck;
/**
* 活跃度检测开启/关闭
*/
private Integer activityDetection;
/**
* 活跃度检测方式
*/
private Integer activityDetectionMethod;
/**
* 首次播放允许拖曳
*/
private Integer firstDragAllowed;
/**
* 首次播放允许倍速
*/
private Integer firstSpeedAllowed;
/**
* 课时抓拍
*/
private Integer playSnap;
......
...@@ -31,15 +31,13 @@ public class ImageCheckRecordDO extends BaseModel { ...@@ -31,15 +31,13 @@ public class ImageCheckRecordDO extends BaseModel {
private Long classId; private Long classId;
/** /**
* 试卷id
*/
private Long paperId;
/**
* 成员id * 成员id
*/ */
private Long memberId; private Long memberId;
/**
* 请求id
*/
private String requestId; private String requestId;
/** /**
......
...@@ -93,7 +93,7 @@ public class MemberDO extends BaseModel { ...@@ -93,7 +93,7 @@ public class MemberDO extends BaseModel {
/** /**
* 采集时间 * 采集时间
*/ */
private LocalDateTime checkTime; private String checkTime;
/** /**
* 身份证号 * 身份证号
......
package com.subsidy.service; package com.subsidy.service;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.subsidy.dto.detection.GetCheckHistoryDTO;
import com.subsidy.dto.detection.VerifyDTO; import com.subsidy.dto.detection.VerifyDTO;
import com.subsidy.model.ActivityDetectionDO; import com.subsidy.model.ActivityDetectionDO;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.subsidy.vo.activity.GetCheckHistoryVO;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.List;
/** /**
* <p> * <p>
...@@ -20,6 +21,6 @@ public interface ActivityDetectionService extends IService<ActivityDetectionDO> ...@@ -20,6 +21,6 @@ public interface ActivityDetectionService extends IService<ActivityDetectionDO>
String verify(VerifyDTO verifyDTO, HttpServletRequest request); String verify(VerifyDTO verifyDTO, HttpServletRequest request);
IPage<ActivityDetectionDO> getCheckHistory(ActivityDetectionDO activityDetectionDO); IPage<GetCheckHistoryVO> getCheckHistory(GetCheckHistoryDTO getCheckHistoryDTO);
} }
...@@ -6,10 +6,12 @@ import com.subsidy.dto.administer.OperatorsDTO; ...@@ -6,10 +6,12 @@ import com.subsidy.dto.administer.OperatorsDTO;
import com.subsidy.dto.company.AddCompanyDTO; import com.subsidy.dto.company.AddCompanyDTO;
import com.subsidy.dto.company.GetCompanyMembersDTO; import com.subsidy.dto.company.GetCompanyMembersDTO;
import com.subsidy.model.CompanyDictDO; import com.subsidy.model.CompanyDictDO;
import com.subsidy.model.MemberDO;
import com.subsidy.vo.administer.OperatorsVO; import com.subsidy.vo.administer.OperatorsVO;
import com.subsidy.vo.company.CDNStatDetailsVO;
import com.subsidy.vo.company.DataOverviewVO;
import com.subsidy.vo.company.GetAllCompanyVO; import com.subsidy.vo.company.GetAllCompanyVO;
import com.subsidy.vo.company.GetCompanyMembersVO; import com.subsidy.vo.company.GetCompanyMembersVO;
import com.subsidy.vo.company.MemberSummaryVO;
import java.util.List; import java.util.List;
...@@ -35,4 +37,11 @@ public interface CompanyDictService extends IService<CompanyDictDO> { ...@@ -35,4 +37,11 @@ public interface CompanyDictService extends IService<CompanyDictDO> {
IPage<GetCompanyMembersVO> getCompanyMembers(GetCompanyMembersDTO getCompanyMembersDTO); IPage<GetCompanyMembersVO> getCompanyMembers(GetCompanyMembersDTO getCompanyMembersDTO);
MemberSummaryVO memberSummary(GetCompanyMembersDTO getCompanyMembersDTO);
DataOverviewVO getCompanyDataOverview();
List<CDNStatDetailsVO> getCDNBandwidthStatDetails();
List<CDNStatDetailsVO> getCDNFluxStatDetails();
} }
package com.subsidy.service; package com.subsidy.service;
import com.subsidy.dto.image.ImageCheckDTO;
import com.subsidy.model.ImageCheckRecordDO; import com.subsidy.model.ImageCheckRecordDO;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
...@@ -17,4 +18,6 @@ public interface ImageCheckRecordService extends IService<ImageCheckRecordDO> { ...@@ -17,4 +18,6 @@ public interface ImageCheckRecordService extends IService<ImageCheckRecordDO> {
List<ImageCheckRecordDO> getImageCheckHistory(ImageCheckRecordDO imageCheckRecordDO); List<ImageCheckRecordDO> getImageCheckHistory(ImageCheckRecordDO imageCheckRecordDO);
String imageCheck(ImageCheckDTO imageCheckDTO)throws Exception;
} }
...@@ -43,8 +43,6 @@ public interface MemberService extends IService<MemberDO> { ...@@ -43,8 +43,6 @@ public interface MemberService extends IService<MemberDO> {
String updatePassword(MemberDO memberDO); String updatePassword(MemberDO memberDO);
String updateCheckImage(MemberDO memberDO);
String removeCheckImage(MemberDO memberDO); String removeCheckImage(MemberDO memberDO);
List<MyCoursesVO> myCourses(MyCoursesDTO myCoursesDTO); List<MyCoursesVO> myCourses(MyCoursesDTO myCoursesDTO);
......
package com.subsidy.service.impl; package com.subsidy.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.subsidy.common.configure.ActivityDetectionConfig; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.subsidy.common.configure.VODConfig; import com.subsidy.dto.detection.GetCheckHistoryDTO;
import com.subsidy.common.configure.WechatConfig;
import com.subsidy.dto.detection.VerifyDTO; import com.subsidy.dto.detection.VerifyDTO;
import com.subsidy.model.ActivityDetectionDO; import com.subsidy.model.ActivityDetectionDO;
import com.subsidy.mapper.ActivityDetectionMapper; import com.subsidy.mapper.ActivityDetectionMapper;
import com.subsidy.service.ActivityDetectionService; import com.subsidy.service.ActivityDetectionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.subsidy.util.ActivityDetectionUtils;
import com.subsidy.util.ConstantUtils; import com.subsidy.util.ConstantUtils;
import com.tencentcloudapi.captcha.v20190722.CaptchaClient; import com.subsidy.vo.activity.GetCheckHistoryVO;
import com.tencentcloudapi.captcha.v20190722.models.DescribeCaptchaResultRequest;
import com.tencentcloudapi.captcha.v20190722.models.DescribeCaptchaResultResponse; import com.tencentcloudapi.captcha.v20190722.models.DescribeCaptchaResultResponse;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
...@@ -33,50 +27,11 @@ import javax.servlet.http.HttpServletRequest; ...@@ -33,50 +27,11 @@ import javax.servlet.http.HttpServletRequest;
@Service @Service
public class ActivityDetectionServiceImpl extends ServiceImpl<ActivityDetectionMapper, ActivityDetectionDO> implements ActivityDetectionService { public class ActivityDetectionServiceImpl extends ServiceImpl<ActivityDetectionMapper, ActivityDetectionDO> implements ActivityDetectionService {
@Autowired
private ActivityDetectionConfig activityDetectionConfig;
@Autowired
private VODConfig vodConfig;
public String verify(VerifyDTO verifyDTO, HttpServletRequest request){ public String verify(VerifyDTO verifyDTO, HttpServletRequest request){
try{ try{
// 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密 DescribeCaptchaResultResponse resp = ActivityDetectionUtils.activityDetection(request,verifyDTO.getRandStr());
// 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
Credential cred = new Credential(vodConfig.getSecretId(),vodConfig.getSecretKey());
// 实例化一个http选项,可选的,没有特殊需求可以跳过
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint("captcha.tencentcloudapi.com");
// 实例化一个client选项,可选的,没有特殊需求可以跳过
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
// 实例化要请求产品的client对象,clientProfile是可选的
CaptchaClient client = new CaptchaClient(cred, "", clientProfile);
// 实例化一个请求对象,每个接口都会对应一个request对象
DescribeCaptchaResultRequest req = new DescribeCaptchaResultRequest();
req.setCaptchaType(9L);
req.setTicket(verifyDTO.getTicket());
// String ip = request.getHeader("x-forwarded-for");
String ip = request.getHeader( " x-forwarded-for " );
if (ip == null || ip.length() == 0 || " unknown " .equalsIgnoreCase(ip)) {
ip = request.getHeader( " Proxy-Client-IP " );
}
if (ip == null || ip.length() == 0 || " unknown " .equalsIgnoreCase(ip)) {
ip = request.getHeader( " WL-Proxy-Client-IP " );
}
if (ip == null || ip.length() == 0 || " unknown " .equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
req.setUserIp(ip);
req.setRandstr(verifyDTO.getRandStr());
req.setCaptchaAppId(activityDetectionConfig.getCaptchaAppId());
req.setAppSecretKey(activityDetectionConfig.getAppSecretKey());
req.setBusinessId(activityDetectionConfig.getBusinessId());
// 返回的resp是一个DescribeCaptchaResultResponse的实例,与请求对象对应
DescribeCaptchaResultResponse resp = client.DescribeCaptchaResult(req);
// 输出json格式的字符串回包 // 输出json格式的字符串回包
System.out.println(DescribeCaptchaResultResponse.toJsonString(resp));
ActivityDetectionDO activityDetectionDO = new ActivityDetectionDO(); ActivityDetectionDO activityDetectionDO = new ActivityDetectionDO();
activityDetectionDO.setClassId(verifyDTO.getClassId()); activityDetectionDO.setClassId(verifyDTO.getClassId());
activityDetectionDO.setMemberId(verifyDTO.getMemberId()); activityDetectionDO.setMemberId(verifyDTO.getMemberId());
...@@ -90,16 +45,15 @@ public class ActivityDetectionServiceImpl extends ServiceImpl<ActivityDetectionM ...@@ -90,16 +45,15 @@ public class ActivityDetectionServiceImpl extends ServiceImpl<ActivityDetectionM
this.baseMapper.insert(activityDetectionDO); this.baseMapper.insert(activityDetectionDO);
return ConstantUtils.FAIL_VERIFY; return ConstantUtils.FAIL_VERIFY;
} }
} catch (TencentCloudSDKException e) { } catch (Exception e) {
System.out.println(e.toString()); // System.out.println(e.toString());
} }
return null; return null;
} }
public IPage<ActivityDetectionDO> getCheckHistory(ActivityDetectionDO activityDetectionDO){ public IPage<GetCheckHistoryVO> getCheckHistory(GetCheckHistoryDTO getCheckHistoryDTO){
Page pager = new Page(getCheckHistoryDTO.getPageNum(), getCheckHistoryDTO.getPageSize());
return this.baseMapper.getCheckHistory(pager,getCheckHistoryDTO.getClassId(),getCheckHistoryDTO.getMemberId());
return null;
} }
} }
...@@ -44,7 +44,6 @@ import com.subsidy.model.MemberDepartmentMappingDO; ...@@ -44,7 +44,6 @@ import com.subsidy.model.MemberDepartmentMappingDO;
import com.subsidy.model.OprAdmDictDO; import com.subsidy.model.OprAdmDictDO;
import com.subsidy.model.PaperDictDO; import com.subsidy.model.PaperDictDO;
import com.subsidy.model.RoleAdministerMappingDO; import com.subsidy.model.RoleAdministerMappingDO;
import com.subsidy.model.RoleDictDO;
import com.subsidy.model.SignInRecordDO; import com.subsidy.model.SignInRecordDO;
import com.subsidy.model.VodDictDO; import com.subsidy.model.VodDictDO;
import com.subsidy.service.AdministerService; import com.subsidy.service.AdministerService;
...@@ -86,12 +85,12 @@ import org.apache.poi.xssf.streaming.SXSSFWorkbook; ...@@ -86,12 +85,12 @@ import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream; import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
...@@ -115,7 +114,6 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -115,7 +114,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
/** /**
* <p> * <p>
* 管理平台用户 服务实现类 * 管理平台用户 服务实现类
...@@ -175,9 +173,6 @@ public class AdministerServiceImpl extends ServiceImpl<AdministerMapper, Adminis ...@@ -175,9 +173,6 @@ public class AdministerServiceImpl extends ServiceImpl<AdministerMapper, Adminis
@Autowired @Autowired
private SignInRecordMapper signInRecordMapper; private SignInRecordMapper signInRecordMapper;
//@Autowired
//private MongoTemplate mongoTemplate;
@Autowired @Autowired
private PaperDictMapper paperDictMapper; private PaperDictMapper paperDictMapper;
...@@ -380,8 +375,9 @@ public class AdministerServiceImpl extends ServiceImpl<AdministerMapper, Adminis ...@@ -380,8 +375,9 @@ public class AdministerServiceImpl extends ServiceImpl<AdministerMapper, Adminis
return ConstantUtils.SET_SUCCESS; return ConstantUtils.SET_SUCCESS;
} }
@Override
@Cacheable(value = "ResultData", key = "'classId_'+#classDetailDTO.getId()")
public ClassSummaryVO classSummary(ClassDetailDTO classDetailDTO) { public ClassSummaryVO classSummary(ClassDetailDTO classDetailDTO) {
ClassSummaryVO classSummaryVO = new ClassSummaryVO(); ClassSummaryVO classSummaryVO = new ClassSummaryVO();
//班级人数 //班级人数
......
...@@ -4,35 +4,50 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; ...@@ -4,35 +4,50 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.subsidy.common.RedisPrefixConstant; import com.subsidy.common.configure.VODConfig;
import com.subsidy.common.constant.VodConstant;
import com.subsidy.common.exception.HttpException; import com.subsidy.common.exception.HttpException;
import com.subsidy.dto.administer.OperatorsDTO; import com.subsidy.dto.administer.OperatorsDTO;
import com.subsidy.dto.company.AddCompanyDTO; import com.subsidy.dto.company.AddCompanyDTO;
import com.subsidy.dto.company.GetCompanyMembersDTO; import com.subsidy.dto.company.GetCompanyMembersDTO;
import com.subsidy.mapper.AdministerMapper; import com.subsidy.mapper.AdministerMapper;
import com.subsidy.mapper.ClassDictMapper;
import com.subsidy.mapper.ClassHourDictMapper; import com.subsidy.mapper.ClassHourDictMapper;
import com.subsidy.mapper.ClassTypeDictMapper; import com.subsidy.mapper.ClassTypeDictMapper;
import com.subsidy.mapper.CompanyDictMapper; import com.subsidy.mapper.CompanyDictMapper;
import com.subsidy.mapper.CompanyFieldMappingMapper; import com.subsidy.mapper.CompanyFieldMappingMapper;
import com.subsidy.mapper.CourseDictMapper;
import com.subsidy.mapper.DepartmentDictMapper; import com.subsidy.mapper.DepartmentDictMapper;
import com.subsidy.mapper.FieldDictMapper; import com.subsidy.mapper.FieldDictMapper;
import com.subsidy.mapper.JobDictMapper; import com.subsidy.mapper.JobDictMapper;
import com.subsidy.mapper.MemberMapper;
import com.subsidy.mapper.RankDictMapper; import com.subsidy.mapper.RankDictMapper;
import com.subsidy.mapper.RoleAdministerMappingMapper; import com.subsidy.mapper.RoleAdministerMappingMapper;
import com.subsidy.mapper.RotationImgDictMapper; import com.subsidy.mapper.RotationImgDictMapper;
import com.subsidy.mapper.VodPlayHistoryMapper;
import com.subsidy.mapper.*;
import com.subsidy.model.*; import com.subsidy.model.*;
import com.subsidy.service.CompanyDictService; import com.subsidy.service.CompanyDictService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.subsidy.util.ConstantUtils; import com.subsidy.util.ConstantUtils;
import com.subsidy.util.DateFormatUtil;
import com.subsidy.util.EhCacheUtil;
import com.subsidy.util.VodUtil;
import com.subsidy.vo.administer.OperatorsVO; import com.subsidy.vo.administer.OperatorsVO;
import com.subsidy.vo.company.CDNStatDetailsVO;
import com.subsidy.vo.company.DataOverviewVO;
import com.subsidy.vo.company.GetAllCompanyVO; import com.subsidy.vo.company.GetAllCompanyVO;
import com.subsidy.vo.company.GetCompanyMembersVO; import com.subsidy.vo.company.GetCompanyMembersVO;
import com.tencentcloudapi.vod.v20180717.models.StatDataItem;
import org.apache.commons.collections.CollectionUtils;
import com.subsidy.vo.company.MemberSummaryVO;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
/** /**
...@@ -77,6 +92,21 @@ public class CompanyDictServiceImpl extends ServiceImpl<CompanyDictMapper, Compa ...@@ -77,6 +92,21 @@ public class CompanyDictServiceImpl extends ServiceImpl<CompanyDictMapper, Compa
@Autowired @Autowired
private RotationImgDictMapper rotationImgDictMapper; private RotationImgDictMapper rotationImgDictMapper;
@Autowired
private MemberMapper memberMapper;
@Autowired
private ClassDictMapper classDictMapper;
@Autowired
private CourseDictMapper courseDictMapper;
@Autowired
private VodPlayHistoryMapper vodPlayHistoryMapper;
@Autowired
private VODConfig vodConfig;
public IPage<OperatorsVO> operators(OperatorsDTO operatorsDTO) { public IPage<OperatorsVO> operators(OperatorsDTO operatorsDTO) {
Page pager = new Page(operatorsDTO.getPageNum(), operatorsDTO.getPageSize()); Page pager = new Page(operatorsDTO.getPageNum(), operatorsDTO.getPageSize());
...@@ -258,5 +288,129 @@ public class CompanyDictServiceImpl extends ServiceImpl<CompanyDictMapper, Compa ...@@ -258,5 +288,129 @@ public class CompanyDictServiceImpl extends ServiceImpl<CompanyDictMapper, Compa
return this.baseMapper.getCompanyMembers(pager,getCompanyMembersDTO.getCompanyId(),getCompanyMembersDTO.getUserName()); return this.baseMapper.getCompanyMembers(pager,getCompanyMembersDTO.getCompanyId(),getCompanyMembersDTO.getUserName());
} }
@Override
public DataOverviewVO getCompanyDataOverview() {
DataOverviewVO dataOverviewVO = new DataOverviewVO();
int companyNum = this.baseMapper.selectCount(new QueryWrapper<>());
/* 机构数量 */
dataOverviewVO.setCompanyNum(companyNum);
List<MemberDO> memberList = memberMapper.selectList(new QueryWrapper<>());
if(CollectionUtils.isNotEmpty(memberList)) {
int realNameNum = (int) memberList.stream().filter(m -> StringUtils.isNotBlank(m.getIdCard())).count();
/* 注册人数 */
dataOverviewVO.setRegistrantsNum(memberList.size());
/* 实名注册人数 */
dataOverviewVO.setRealNameNum(realNameNum);
}
/* 培训项目数量 */
int classNum = classDictMapper.getClassCount();
dataOverviewVO.setClassNum(classNum);
List<CourseDictDO> courseList = courseDictMapper.selectList(new QueryWrapper<>());
if(CollectionUtils.isNotEmpty(courseList)) {
/* 资源数量 */
dataOverviewVO.setCourseNum(courseList.size());
/* 专项资源数量 */
int subsidyCourseNum = (int) courseList.stream().filter(courseDictDO -> StringUtils.isNotBlank(courseDictDO.getCourseType()) &&
courseDictDO.getCourseType().equals("补贴培训")).count();
dataOverviewVO.setSubsidyCourseNum(subsidyCourseNum);
}
/* 累计学习时长(小时) */
double studyTotal = vodPlayHistoryMapper.getStudyTotal();
if(studyTotal > 0) {
dataOverviewVO.setStudyTotal(new BigDecimal(studyTotal).divide(new BigDecimal(Math.pow(60, 2)), 2, BigDecimal.ROUND_UP).doubleValue());
}
/* 专项资源时(小时) */
double subsidyStudyTotal = vodPlayHistoryMapper.getSubsidyStudyTotal();
if(subsidyStudyTotal > 0) {
dataOverviewVO.setSubsidyStudyTotal(new BigDecimal(subsidyStudyTotal).divide(new BigDecimal(Math.pow(60,2)), 2, BigDecimal.ROUND_UP).doubleValue());
}
/* 学习过程记录人次 */
int studyHistoryNum = vodPlayHistoryMapper.getStudyHistoryNum();
dataOverviewVO.setStudyHistoryNum(studyHistoryNum);
return dataOverviewVO;
}
public MemberSummaryVO memberSummary(GetCompanyMembersDTO getCompanyMembersDTO){
MemberSummaryVO memberSummaryVO = new MemberSummaryVO();
//总数
Integer total = memberMapper.selectCount(new QueryWrapper<MemberDO>()
.lambda()
.eq(MemberDO::getCompanyId,getCompanyMembersDTO.getCompanyId()));
memberSummaryVO.setTotal(total);
//短信验证
Integer smsCnt = memberMapper.selectCount(new QueryWrapper<MemberDO>()
.lambda()
.eq(MemberDO::getCompanyId,getCompanyMembersDTO.getCompanyId())
.isNull(MemberDO::getFirstLogin));
memberSummaryVO.setSmsCnt(smsCnt);
memberSummaryVO.setImgCnt(total-smsCnt);
return memberSummaryVO;
}
@Override
public List<CDNStatDetailsVO> getCDNBandwidthStatDetails() {
/*
* 根据今天时间查询七天前的数据
* 先从缓存中获取数据,如果缓存中没有数据,从远程请求中获取, 避免频繁请求
* 缓存28800秒(8小时)失效,重新远程请求更新数据
*/
List<CDNStatDetailsVO> data = new ArrayList<>();
if(EhCacheUtil.getEhCache(VodConstant.CDN_STAT_DETAILS_CACHE_NAME, VodConstant.BANDWIDTH_CACHE_KEY) != null) {
return (List<CDNStatDetailsVO>) EhCacheUtil.getEhCache(VodConstant.CDN_STAT_DETAILS_CACHE_NAME, VodConstant.BANDWIDTH_CACHE_KEY);
} else {
String startDate =LocalDateTime.now().minusDays(6).withNano(0)+"+08:00";
String endDate = LocalDateTime.now().withNano(0)+"+08:00";
StatDataItem[] statDataItems = VodUtil.DescribeCDNStatDetails(vodConfig, VodConstant.BANDWIDTH ,startDate, endDate);
for (StatDataItem statDataItem : statDataItems) {
CDNStatDetailsVO sd = new CDNStatDetailsVO();
LocalDateTime localDateTime = LocalDateTime.parse(statDataItem.getTime().replace("+08:00",""));
Date date = DateFormatUtil.localDateTimeToDate(localDateTime);
sd.setTime(DateFormatUtil.format(date, DateFormatUtil.FMT_sdf_yMd));
BigDecimal bigDecimal = new BigDecimal(statDataItem.getValue()).divide(new BigDecimal(1000000));
sd.setValue(bigDecimal.setScale(2, BigDecimal.ROUND_UP));
data.add(sd);
}
EhCacheUtil.putEhCache(VodConstant.CDN_STAT_DETAILS_CACHE_NAME, VodConstant.BANDWIDTH_CACHE_KEY, data);
return data;
}
}
@Override
public List<CDNStatDetailsVO> getCDNFluxStatDetails() {
/*
* 根据今天时间查询七天前的数据
* 先从缓存中获取数据,如果缓存中没有数据,从远程请求中获取,避免频繁请求
* 缓存28800秒(8小时)失效,重新远程请求更新数据
*/
List<CDNStatDetailsVO> data = new ArrayList<>();
if(EhCacheUtil.getEhCache(VodConstant.CDN_STAT_DETAILS_CACHE_NAME, VodConstant.FLUX_CACHE_KEY) != null) {
return (List<CDNStatDetailsVO>) EhCacheUtil.getEhCache(VodConstant.CDN_STAT_DETAILS_CACHE_NAME, VodConstant.FLUX_CACHE_KEY);
} else {
String startDate =LocalDateTime.now().minusDays(6).withNano(0)+"+08:00";
String endDate = LocalDateTime.now().withNano(0)+"+08:00";
StatDataItem[] statDataItems = VodUtil.DescribeCDNStatDetails(vodConfig, VodConstant.FLUX ,startDate, endDate);
for (StatDataItem statDataItem : statDataItems) {
CDNStatDetailsVO sd = new CDNStatDetailsVO();
LocalDateTime localDateTime = LocalDateTime.parse(statDataItem.getTime().replace("+08:00",""));
Date date = DateFormatUtil.localDateTimeToDate(localDateTime);
sd.setTime(DateFormatUtil.format(date, DateFormatUtil.FMT_sdf_yMd));
BigDecimal bigDecimal = new BigDecimal(statDataItem.getValue()).divide(new BigDecimal(Math.pow(1000, 3)));
sd.setValue(bigDecimal.setScale(2, BigDecimal.ROUND_UP));
data.add(sd);
}
EhCacheUtil.putEhCache(VodConstant.CDN_STAT_DETAILS_CACHE_NAME, VodConstant.FLUX_CACHE_KEY, data);
return data;
}
}
} }
...@@ -709,12 +709,6 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberDO> imple ...@@ -709,12 +709,6 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberDO> imple
return ConstantUtils.SET_SUCCESS; return ConstantUtils.SET_SUCCESS;
} }
public String updateCheckImage(MemberDO memberDO) {
memberDO.setCheckTime(LocalDateTime.now());
this.baseMapper.updateById(memberDO);
return ConstantUtils.SET_SUCCESS;
}
public String removeCheckImage(MemberDO memberDO) { public String removeCheckImage(MemberDO memberDO) {
this.baseMapper.removeCheckImage(memberDO.getId()); this.baseMapper.removeCheckImage(memberDO.getId());
return ConstantUtils.DELETE_SUCCESS; return ConstantUtils.DELETE_SUCCESS;
......
...@@ -66,9 +66,9 @@ public class VodDictServiceImpl extends ServiceImpl<VodDictMapper, VodDictDO> im ...@@ -66,9 +66,9 @@ public class VodDictServiceImpl extends ServiceImpl<VodDictMapper, VodDictDO> im
if(null == vod) { if(null == vod) {
throw new HttpException(18000); throw new HttpException(18000);
} }
this.baseMapper.deleteById(vodDictDO.getId());
VodUtil.deleteMedia(vodDictDO.getVodCode()); this.baseMapper.deleteById(vodDictDO.getId());
VodUtil.deleteMedia(vodConfig, vodDictDO.getVodCode());
} }
@Override @Override
...@@ -85,12 +85,13 @@ public class VodDictServiceImpl extends ServiceImpl<VodDictMapper, VodDictDO> im ...@@ -85,12 +85,13 @@ public class VodDictServiceImpl extends ServiceImpl<VodDictMapper, VodDictDO> im
orderNo = vod.getOrderNo() + 1; orderNo = vod.getOrderNo() + 1;
} }
} }
vodDictDO.setOrderNo(orderNo); vodDictDO.setOrderNo(orderNo);
this.baseMapper.insert(vodDictDO); this.baseMapper.insert(vodDictDO);
//测试环境就不转码了 //测试环境就不转码了
if (env.equals("prod")){ if (env.equals("prod")){
VodUtil.processMedia(vodDictDO.getVodCode()); VodUtil.processMedia(vodConfig, vodDictDO.getVodCode());
} }
} }
......
package com.subsidy.util;
import com.tencentcloudapi.captcha.v20190722.CaptchaClient;
import com.tencentcloudapi.captcha.v20190722.models.DescribeCaptchaResultRequest;
import com.tencentcloudapi.captcha.v20190722.models.DescribeCaptchaResultResponse;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import javax.servlet.http.HttpServletRequest;
public class ActivityDetectionUtils {
/**
* 活跃度检测工具类
* @param request
* @param randstr
* @return
* @throws Exception
*/
public static DescribeCaptchaResultResponse activityDetection(HttpServletRequest request, String randstr) throws Exception {
// 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密
// 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
Credential cred = new Credential(ConstantUtils.SECRET_ID, ConstantUtils.SECRET_KEY);
// 实例化一个http选项,可选的,没有特殊需求可以跳过
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint("captcha.tencentcloudapi.com");
// 实例化一个client选项,可选的,没有特殊需求可以跳过
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
// 实例化要请求产品的client对象,clientProfile是可选的
CaptchaClient client = new CaptchaClient(cred, "", clientProfile);
// 实例化一个请求对象,每个接口都会对应一个request对象
DescribeCaptchaResultRequest req = new DescribeCaptchaResultRequest();
req.setCaptchaType(9L);
String ip = IpAddressUtil.getIpAddress(request);
req.setUserIp(ip);
req.setRandstr(randstr);
req.setCaptchaAppId(ConstantUtils.CAPTCHAAPP_ID);
req.setAppSecretKey(ConstantUtils.APP_SECRET_KEY);
req.setBusinessId(ConstantUtils.BUSINESS_ID);
// 返回的resp是一个DescribeCaptchaResultResponse的实例,与请求对象对应
return client.DescribeCaptchaResult(req);
}
}
...@@ -86,4 +86,25 @@ public class ConstantUtils { ...@@ -86,4 +86,25 @@ public class ConstantUtils {
public static final String ADMINISTER_TERMINATE = "administer"; public static final String ADMINISTER_TERMINATE = "administer";
/**
* API密钥--微信参数
*/
public static final String SECRET_ID = "AKIDOcePHvZ2C5VeYHQGSO5aqtlNxJQLqfz2";
public static final String SECRET_KEY = "vjHYRmrfDbw0rWxA7oFcj7F8lDPKCm8E";
/**
* 图形验证码
*/
public static final Long CAPTCHAAPP_ID = 2013197365L;
public static final String APP_SECRET_KEY = "04ABoF0ZVuMje8NP84DE5Sg**";
public static final Long BUSINESS_ID = 1L;
/**
* 人脸识别
*/
} }
package com.subsidy.util;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import org.springframework.util.ClassUtils;
/**
* <p>
* Ehcache
* </p>
*
* @author DengMin
* @since 2022/8/1
*/
public class EhCacheUtil {
static CacheManager cacheManager = CacheManager.newInstance(ClassUtils.getDefaultClassLoader().getResource("").getPath()+"ehcache.xml");
/**
* 添加缓存
* @param cacheName
* @param key
* @param value
*/
public static void putEhCache(String cacheName, String key, Object value) {
Cache cache = cacheManager.getCache(cacheName);
Element element = new Element(key, value);
cache.put(element);
}
/**
* 获取缓存数据
* @param cacheName
* @param key
* @return
*/
public static Object getEhCache(String cacheName, String key) {
Cache cache = cacheManager.getCache(cacheName);
Element element = cache.get(key);
return element == null ? null : element.getObjectValue();
}
/**
* 删除缓存
* @param cacheName
* @param key
*/
public static void deleteEhCache(String cacheName, String key) {
Cache cache = cacheManager.getCache(cacheName);
cache.remove(key);
}
}
package com.subsidy.util;
import com.google.common.hash.Hashing;
import org.apache.commons.codec.Charsets;
import java.util.Collections;
import java.util.List;
/**
* 人脸识别工具类
*/
public class ImageCheckUtil {
/**
* 签名方法
* @param values
* @param ticket
* @return
*/
public static String sign(List<String> values, String ticket) { //values传ticket外的其他参数
if (values == null) {
throw new NullPointerException("values is null");
}
values.removeAll(Collections.singleton(null));// remove null
values.add(ticket); java.util.Collections.sort(values);
StringBuilder sb = new StringBuilder();
for (String s : values) { sb.append(s);
}
return Hashing.sha1().hashString(sb,
Charsets.UTF_8).toString().toUpperCase();
}
}
...@@ -6,21 +6,28 @@ import com.tencentcloudapi.common.Credential; ...@@ -6,21 +6,28 @@ import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException; import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile; import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile; import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.cvm.v20170312.models.DescribeZonesResponse;
import com.tencentcloudapi.vod.v20180717.VodClient; import com.tencentcloudapi.vod.v20180717.VodClient;
import com.tencentcloudapi.vod.v20180717.models.DeleteMediaRequest; import com.tencentcloudapi.vod.v20180717.models.DeleteMediaRequest;
import com.tencentcloudapi.vod.v20180717.models.DescribeCDNUsageDataRequest;
import com.tencentcloudapi.vod.v20180717.models.DescribeCDNUsageDataResponse;
import com.tencentcloudapi.vod.v20180717.models.MediaProcessTaskInput; import com.tencentcloudapi.vod.v20180717.models.MediaProcessTaskInput;
import com.tencentcloudapi.vod.v20180717.models.ProcessMediaRequest; import com.tencentcloudapi.vod.v20180717.models.ProcessMediaRequest;
import com.tencentcloudapi.vod.v20180717.models.ProcessMediaResponse; import com.tencentcloudapi.vod.v20180717.models.ProcessMediaResponse;
import com.tencentcloudapi.vod.v20180717.models.StatDataItem;
import com.tencentcloudapi.vod.v20180717.models.TranscodeTaskInput; import com.tencentcloudapi.vod.v20180717.models.TranscodeTaskInput;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Value;
/**
* <p>
* 腾讯云 - 云点播API
* </p>
*
* @author DengMin
* @since 2022/8/1
*/
@Component
public class VodUtil { public class VodUtil {
@Autowired
private static VODConfig vodConfig;
private static String endpoint = "vod.tencentcloudapi.com"; private static String endpoint = "vod.tencentcloudapi.com";
/** /**
...@@ -28,7 +35,7 @@ public class VodUtil { ...@@ -28,7 +35,7 @@ public class VodUtil {
* @param vodCode * @param vodCode
* @return * @return
*/ */
public static ProcessMediaResponse processMedia(String vodCode) { public static ProcessMediaResponse processMedia(VODConfig vodConfig, String vodCode) {
try { try {
//上传后直接转码 //上传后直接转码
Credential cred = new Credential(vodConfig.getSecretId(), vodConfig.getSecretKey()); Credential cred = new Credential(vodConfig.getSecretId(), vodConfig.getSecretKey());
...@@ -59,7 +66,7 @@ public class VodUtil { ...@@ -59,7 +66,7 @@ public class VodUtil {
* 删除腾讯云上原视频 * 删除腾讯云上原视频
* @param vodCode * @param vodCode
*/ */
public static void deleteMedia(String vodCode) { public static void deleteMedia(VODConfig vodConfig, String vodCode) {
try { try {
//删除原视频 //删除原视频
Credential cred = new Credential(vodConfig.getSecretId(), vodConfig.getSecretKey()); Credential cred = new Credential(vodConfig.getSecretId(), vodConfig.getSecretKey());
...@@ -76,6 +83,41 @@ public class VodUtil { ...@@ -76,6 +83,41 @@ public class VodUtil {
// 返回的resp是一个DeleteMediaResponse的实例,与请求对象对应 // 返回的resp是一个DeleteMediaResponse的实例,与请求对象对应
client.DeleteMedia(req); client.DeleteMedia(req);
} catch (TencentCloudSDKException e) { } catch (TencentCloudSDKException e) {
throw new HttpException(99999, e.getMessage());
}
}
/**
* 云点播域名的CDN统计数据
* @param vodConfig
* @param DataType
* @param startTime
* @param endTime
* @return
*/
public static StatDataItem[] DescribeCDNStatDetails(VODConfig vodConfig, String DataType, String startTime, String endTime) {
try {
Credential cred = new Credential(vodConfig.getSecretId(), vodConfig.getSecretKey());
// 实例化一个http选项,可选的,没有特殊需求可以跳过
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint(endpoint);
// 实例化一个client选项,可选的,没有特殊需求可以跳过
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
// 实例化要请求产品的client对象,clientProfile是可选的
VodClient client = new VodClient(cred, "", clientProfile);
// 实例化一个请求对象,每个接口都会对应一个request对象
DescribeCDNUsageDataRequest req = new DescribeCDNUsageDataRequest();
req.setStartTime(startTime);
req.setEndTime(endTime);
req.setDataType(DataType);
// 返回的resp是一个DescribeCDNUsageDataResponse的实例,与请求对象对应
DescribeCDNUsageDataResponse resp = client.DescribeCDNUsageData(req);
// 返回的resp是一个DescribeCDNStatDetailsResponse的实例,与请求对象对应
return resp.getData();
} catch (TencentCloudSDKException e) {
e.printStackTrace();
throw new HttpException(99999, e.getMessage());
} }
} }
} }
...@@ -40,6 +40,10 @@ public class WebSocketUtil implements WebSocketHandler { ...@@ -40,6 +40,10 @@ public class WebSocketUtil implements WebSocketHandler {
@Autowired @Autowired
private OprMemDictMapper oprMemDictMapper; private OprMemDictMapper oprMemDictMapper;
private int heartbeatMin = 1; // 断连最小心跳次数
private int heartbeatMax = 3; // 断连最大心跳次数
private int reconnectionSeconds = 60; //每次断连间隔重新连接秒
/** /**
* 存放建立连接webSocket对象 * 存放建立连接webSocket对象
*/ */
...@@ -58,14 +62,13 @@ public class WebSocketUtil implements WebSocketHandler { ...@@ -58,14 +62,13 @@ public class WebSocketUtil implements WebSocketHandler {
Long id = Long.valueOf(params.split("=")[1]); Long id = Long.valueOf(params.split("=")[1]);
if(null != webSocketMap && webSocketMap.get(id) != null) { if(null != webSocketMap && webSocketMap.get(id) != null) {
if(webSocketMap.get(id).isOpen()) { if(webSocketMap.get(id).isOpen()) {
/* /* 相同账户进行挤号,发送消息给WebSocket通知账户已在其他地方登录 */
相同账户进行挤号,发送消息给前者WebSocket通知账户已在其他地方登录
*/
webSocketMap.get(id).sendMessage(new TextMessage(JSONObject.toJSONString(ResponseData.generateCreatedResponse(1011)))); webSocketMap.get(id).sendMessage(new TextMessage(JSONObject.toJSONString(ResponseData.generateCreatedResponse(1011))));
webSocketMap.get(id).close(); webSocketMap.get(id).close();
} else { } else {
/* /*
* 如果上次连接的WebSocket状态是关闭,并且上一次记录时间大于60秒的,则判断为这次登陆是免密码登陆的重新记录上线时间 * 如果上次连接的WebSocket状态是关闭,
* 并且上一次记录时间大于 { heartbeatMax * reconnectionSeconds } 秒(心跳检测机制),则判断为这次登陆是免密码登陆的重新记录上线时间
*/ */
List<OprMemDictDO> list = oprMemDictMapper.selectList(new QueryWrapper<OprMemDictDO>() List<OprMemDictDO> list = oprMemDictMapper.selectList(new QueryWrapper<OprMemDictDO>()
.lambda() .lambda()
...@@ -74,7 +77,7 @@ public class WebSocketUtil implements WebSocketHandler { ...@@ -74,7 +77,7 @@ public class WebSocketUtil implements WebSocketHandler {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.setTime(DateFormatUtil.localDateTimeToDate(list.get(0).getCreateDate())); calendar.setTime(DateFormatUtil.localDateTimeToDate(list.get(0).getCreateDate()));
calendar.add(Calendar.SECOND,60); calendar.add(Calendar.SECOND,heartbeatMax * reconnectionSeconds);
if(calendar.getTime().after(DateFormatUtil.localDateTimeToDate(list.get(0).getCreateDate()))) { if(calendar.getTime().after(DateFormatUtil.localDateTimeToDate(list.get(0).getCreateDate()))) {
if(list.get(0).getOprType().equals("登出")) { if(list.get(0).getOprType().equals("登出")) {
OprMemDictDO oprMemDictDO = new OprMemDictDO(); OprMemDictDO oprMemDictDO = new OprMemDictDO();
...@@ -127,9 +130,6 @@ public class WebSocketUtil implements WebSocketHandler { ...@@ -127,9 +130,6 @@ public class WebSocketUtil implements WebSocketHandler {
@Override @Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception{ public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception{
if(null != session) { if(null != session) {
/*
断开连接后不会马上判断为下线状态,而是进入60秒的心跳检测机制,如果60秒内没有进行重连,则判断为下线,记录下线时间和状态
*/
if(null != webSocketMap) { if(null != webSocketMap) {
String params = session.getUri().getQuery(); String params = session.getUri().getQuery();
Long id = Long.valueOf(params.split("=")[1]); Long id = Long.valueOf(params.split("=")[1]);
...@@ -141,29 +141,36 @@ public class WebSocketUtil implements WebSocketHandler { ...@@ -141,29 +141,36 @@ public class WebSocketUtil implements WebSocketHandler {
} }
/** /**
* 断开连接后60秒后进行判断是否重新连接了,如果没有连接成功则判断为下线 * 断开连接后进行三次心跳验证判断是否重新连接了,如果没有连接成功则判断为下线
* *
* @param session * @param session
*/ */
public void heartbeat(WebSocketSession session) { public void heartbeat(WebSocketSession session) {
ScheduledExecutorService service = Executors.newScheduledThreadPool(1); ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
ScheduledFuture scheduledFuture = service.scheduleAtFixedRate(new Runnable() { ScheduledFuture scheduledFuture = service.scheduleAtFixedRate(new Runnable() {
int beatsNum = heartbeatMin;
@SneakyThrows @SneakyThrows
@Override @Override
public void run() { public void run() {
if(null != session && !session.isOpen()) { if(null != session && !session.isOpen()) {
String params = session.getUri().getQuery(); while (beatsNum > heartbeatMax) {
Long id = Long.valueOf(params.split("=")[1]); String params = session.getUri().getQuery();
OprMemDictDO oprMemDictDO = new OprMemDictDO(); Long id = Long.valueOf(params.split("=")[1]);
oprMemDictDO.setUserId(id); OprMemDictDO oprMemDictDO = new OprMemDictDO();
oprMemDictDO.setResult(1); oprMemDictDO.setUserId(id);
oprMemDictDO.setOprType("登出"); oprMemDictDO.setResult(1);
oprMemDictDO.setIpAddress(session.getRemoteAddress().getHostName()); oprMemDictDO.setOprType("登出");
oprMemDictMapper.insert(oprMemDictDO); oprMemDictDO.setIpAddress(session.getRemoteAddress().getHostName());
oprMemDictMapper.insert(oprMemDictDO);
taskMap.get(session.getId()).cancel(true);
}
beatsNum++;
} else if (null != session && session.isOpen()) {
/* 时间段内重新连接了结束验证 */
taskMap.get(session.getId()).cancel(true); taskMap.get(session.getId()).cancel(true);
} }
} }
}, 1, 1, TimeUnit.MINUTES); }, 0, reconnectionSeconds, TimeUnit.SECONDS);
taskMap.put(session.getId(), scheduledFuture); taskMap.put(session.getId(), scheduledFuture);
} }
......
package com.subsidy.vo.activity;
import lombok.Data;
@Data
public class GetCheckHistoryVO {
private Long id;
private String createDate;
private Integer status;
}
package com.subsidy.vo.company;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
@Data
public class CDNStatDetailsVO implements Serializable {
private String time;
private BigDecimal value;
}
package com.subsidy.vo.company;
import lombok.Data;
@Data
public class DataOverviewVO {
/**
* 机构数
*/
private Integer companyNum;
/**
* 注册人数
*/
private Integer registrantsNum;
/**
* 实名制注册人数
*/
private Integer realNameNum;
/**
* 培训项目数量
*/
private Integer classNum;
/**
* 资源数量
*/
private Integer courseNum;
/**
* 学习过程记录人次
*/
private Integer studyHistoryNum;
/**
* 累计学习时长
*/
private Double studyTotal;
/**
* 专项资源数量
*/
private Integer subsidyCourseNum;
/**
* 专项资源时长
*/
private Double subsidyStudyTotal;
}
package com.subsidy.vo.company;
import lombok.Data;
@Data
public class MemberSummaryVO {
private Integer total;
private Integer smsCnt;
private Integer imgCnt;
}
package com.subsidy.vo.token;
import lombok.Data;
@Data
public class CheckResultVO {
private String code;
private String msg;
private String bizSeqNo;
private ResultVO resultVO;
private String transactionTime;
}
package com.subsidy.vo.token;
import lombok.Data;
@Data
public class IdCardAccessTokenVO {
private String code;
private String msg;
private String transactionTime;
private String access_token;
private String expire_time;
private String expire_in;
}
package com.subsidy.vo.token;
import lombok.Data;
import java.util.List;
@Data
public class IdCardSignTicketVO {
private String code;
private String msg;
private String transactionTime;
private List<IdCardTicketsVO> tickets;
}
package com.subsidy.vo.token;
import lombok.Data;
@Data
public class IdCardTicketsVO {
private String value;
private String expire_in;
private String expire_time;
}
package com.subsidy.vo.token;
import lombok.Data;
@Data
public class ResultVO {
private String orderNo;
private String liveRate;
private String similarity;
private String occurredTime;
private String appId;
private String photo;
private String video;
private String bizSeqNo;
private String sdkVersion;
private String trtcFlag;
}
package com.subsidy.vo.token;
import lombok.Data;
@Data
public class SendIdCardInfoVO {
private String code;
private String msg;
private String bizSeqNo;
private SendResultVO result;
private String transactionTime;
}
package com.subsidy.vo.token;
import lombok.Data;
@Data
public class SendResultVO {
private String bizSeqNo;
private String transactionTime;
private String orderNo;
private String h5faceId;
private String optimalDomain;
private Boolean success;
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
spring.server.port=23457 spring.server.port=23457
# 数据源配置 # 数据源配置
spring.datasource.url=jdbc:mysql://47.97.19.66:3306/subsidy_test?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8 spring.datasource.url=jdbc:mysql://116.62.57.92:3306/subsidy_test?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
#spring.datasource.url=jdbc:mysql://rm-uf6rab73w0qg843opxo.mysql.rds.aliyuncs.com:3306/subsidy_test?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8 #spring.datasource.url=jdbc:mysql://rm-uf6rab73w0qg843opxo.mysql.rds.aliyuncs.com:3306/subsidy_test?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
......
...@@ -34,6 +34,9 @@ mybatis-plus.global-config.db-config.logic-delete-value=NOW() ...@@ -34,6 +34,9 @@ mybatis-plus.global-config.db-config.logic-delete-value=NOW()
mybatis-plus.global-config.db-config.logic-not-delete-value=NULL mybatis-plus.global-config.db-config.logic-not-delete-value=NULL
#日志配置 #日志配置
logging.config=classpath:logback-spring.xml logging.config=classpath:logback-spring.xml
#ehcache缓存配置
spring.cache.type=ehcache
spring.cache.ehcache.config=classpath:ehcache.xml
# 阿里云短信 # 阿里云短信
sms.product=Dysmsapi sms.product=Dysmsapi
sms.domain=dysmsapi.aliyuncs.com sms.domain=dysmsapi.aliyuncs.com
...@@ -69,9 +72,3 @@ wechat: ...@@ -69,9 +72,3 @@ wechat:
#pro #pro
appId: wx5e1ecb9c9bd33451 appId: wx5e1ecb9c9bd33451
appSecret: 4f5e1abb6fb4f68f5273820b6295ec6b appSecret: 4f5e1abb6fb4f68f5273820b6295ec6b
#活体检测配置
activity.captchaAppId: 2013197365
activity.appSecretKey: 04ABoF0ZVuMje8NP84DE5Sg**
activity.businessId: 1
\ No newline at end of file
...@@ -17,6 +17,7 @@ meishu.code-message[10021]=密码输入错误,您还可以输入1次密码 ...@@ -17,6 +17,7 @@ meishu.code-message[10021]=密码输入错误,您还可以输入1次密码
meishu.code-message[10022]=密码输入错误,您还可以输入2次密码 meishu.code-message[10022]=密码输入错误,您还可以输入2次密码
meishu.code-message[10023]=密码输入错误,您还可以输入3次密码 meishu.code-message[10023]=密码输入错误,您还可以输入3次密码
meishu.code-message[10024]=密码输入错误,您还可以输入4次密码 meishu.code-message[10024]=密码输入错误,您还可以输入4次密码
meishu.code-message[10025]=身份证识别错误
meishu.code-message[20001]=该课程已存在 meishu.code-message[20001]=该课程已存在
......
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore path="java.io.tmpdir" />
<defaultCache eternal="false"
maxElementsInMemory="1000"
overflowToDisk="false"
diskPersistent="true"
timeToIdleSeconds="0"
timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LRU" />
<!--
maxElementsInMemory 缓存最大个数,若放入Cache中的元素超过这个数值,则有以下两种情况
1)若overflowToDisk=true,则会将Cache中多出的元素放入磁盘文件中
2)若overflowToDisk=false,则根据memoryStoreEvictionPolicy策略替换Cache中原有的元素
eternal 缓存中对象是否永久有效
timeToIdleSeconds 缓存数据在失效前的允许闲置时间(单位:秒),仅当eternal=false时使用,默认值是0表示可闲置时间无穷大,若超过这个时间没有访问此Cache中的某个元素,那么此元素将被从Cache中清除
timeToLiveSeconds 缓存数据的总的存活时间(单位:秒),仅当eternal=false时使用,从创建开始计时,失效结束
overflowToDisk 内存不足时,是否启用磁盘缓存
diskPersistent 是否缓存虚拟机重启期数据
maxBytesLocalHeap 限制堆内存字节大小
-->
<!-- 云点播数据统计缓存 -->
<cache name="CDNStatDetails"
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="28800"
memoryStoreEvictionPolicy="LRU"/>
<!-- 普通数据缓存 -->
<cache name="ResultData"
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="7200"
memoryStoreEvictionPolicy="LRU"/>
</ehcache>
\ No newline at end of file
...@@ -21,4 +21,17 @@ ...@@ -21,4 +21,17 @@
id, class_id, member_id, status id, class_id, member_id, status
</sql> </sql>
<select id="getCheckHistory" resultType="com.subsidy.vo.activity.GetCheckHistoryVO">
SELECT
t.id,
t.`status`,
t.create_date
FROM
activity_detection t
WHERE
t.delete_date IS NULL
AND t.class_id = #{classId}
AND t.member_id = #{memberId}
</select>
</mapper> </mapper>
...@@ -169,4 +169,16 @@ ...@@ -169,4 +169,16 @@
AND cd.delete_date IS NULL AND cd.delete_date IS NULL
AND d.delete_date IS NULL AND d.delete_date IS NULL
</select> </select>
<select id="getClassCount" resultType="java.lang.Integer">
SELECT
count(t1.id)
FROM
class_dict t1
LEFT JOIN course_dict t2 ON t2.id = t1.course_id
WHERE
t2.course_type = "补贴培训"
AND t1.delete_date IS NULL
AND t2.delete_date IS NULL
</select>
</mapper> </mapper>
...@@ -93,13 +93,11 @@ ...@@ -93,13 +93,11 @@
count( 1 ) AS cnt count( 1 ) AS cnt
FROM FROM
course_content t course_content t
LEFT JOIN content_vod_mapping t3 ON t3.content_id = t.id LEFT JOIN content_vod_mapping t2 ON t.id = t2.content_id
LEFT JOIN vod_dict t2 ON t.id = t3.vod_id
WHERE WHERE
t.delete_date IS NULL t.delete_date IS NULL
AND t2.delete_date IS NULL AND t2.delete_date IS NULL
AND t3.delete_date IS NULL and t2.id is not null
AND t2.id IS NOT NULL
GROUP BY GROUP BY
t.course_id t.course_id
) t4 ON t3.id = t4.course_id ) t4 ON t3.id = t4.course_id
......
...@@ -398,4 +398,36 @@ ...@@ -398,4 +398,36 @@
t.create_date t.create_date
</select> </select>
<select id="getStudyTotal" resultType="java.lang.Double">
SELECT
sum( play_length )
FROM
vod_play_history
WHERE
delete_date IS NULL
</select>
<select id="getSubsidyStudyTotal" resultType="java.lang.Double">
SELECT
sum( t1.play_length )
FROM
vod_play_history t1
LEFT JOIN class_dict t2 ON t2.id = t1.class_id
LEFT JOIN course_dict t3 ON t3.id = t2.course_id
WHERE
t3.course_type = "补贴培训"
AND t1.delete_date IS NULL
AND t2.delete_date IS NULL
AND t3.delete_date IS NULL
</select>
<select id="getStudyHistoryNum" resultType="java.lang.Integer">
SELECT
count(DISTINCT member_id)
FROM
vod_play_history
WHERE
delete_date IS NULL
</select>
</mapper> </mapper>
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!