diff --git a/pom.xml b/pom.xml index 4fa3f15..642b6a3 100644 --- a/pom.xml +++ b/pom.xml @@ -66,7 +66,7 @@ com.tencentcloudapi tencentcloud-sdk-java - 3.1.64 + 3.1.322 diff --git a/src/main/java/com/subsidy/common/configure/ActivityDetectionConfig.java b/src/main/java/com/subsidy/common/configure/ActivityDetectionConfig.java deleted file mode 100644 index 3aca11a..0000000 --- a/src/main/java/com/subsidy/common/configure/ActivityDetectionConfig.java +++ /dev/null @@ -1,18 +0,0 @@ -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; - -} diff --git a/src/main/java/com/subsidy/controller/AccessTokenController.java b/src/main/java/com/subsidy/controller/AccessTokenController.java index 0058e29..a82075d 100644 --- a/src/main/java/com/subsidy/controller/AccessTokenController.java +++ b/src/main/java/com/subsidy/controller/AccessTokenController.java @@ -103,4 +103,6 @@ public class AccessTokenController { signVO.setSign(SecretUtils.getSHAString(signStr)); return ResponseData.generateCreatedResponse(0,signVO); } + + } diff --git a/src/main/java/com/subsidy/controller/ActivityDetectionController.java b/src/main/java/com/subsidy/controller/ActivityDetectionController.java index 85ed646..c175510 100644 --- a/src/main/java/com/subsidy/controller/ActivityDetectionController.java +++ b/src/main/java/com/subsidy/controller/ActivityDetectionController.java @@ -4,8 +4,8 @@ package com.subsidy.controller; import com.subsidy.common.ResponseData; import com.subsidy.common.ResponseVO; import com.subsidy.common.interceptor.TimeRequired; +import com.subsidy.dto.detection.GetCheckHistoryDTO; import com.subsidy.dto.detection.VerifyDTO; -import com.subsidy.model.ActivityDetectionDO; import com.subsidy.service.ActivityDetectionService; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; @@ -43,11 +43,8 @@ public class ActivityDetectionController { @PostMapping("getCheckHistory") @ApiOperation("获取某个人某个课程的活跃度验证详情 memberId classId") - public ResponseVO getCheckHistory(@RequestBody ActivityDetectionDO activityDetectionDO){ - return ResponseData.generateCreatedResponse(0,activityDetectionService.getCheckHistory(activityDetectionDO)); + public ResponseVO getCheckHistory(@RequestBody GetCheckHistoryDTO getCheckHistoryDTO){ + return ResponseData.generateCreatedResponse(0,activityDetectionService.getCheckHistory(getCheckHistoryDTO)); } - - - } diff --git a/src/main/java/com/subsidy/controller/CompanyDictController.java b/src/main/java/com/subsidy/controller/CompanyDictController.java index 7428d1d..17182ce 100644 --- a/src/main/java/com/subsidy/controller/CompanyDictController.java +++ b/src/main/java/com/subsidy/controller/CompanyDictController.java @@ -6,7 +6,6 @@ import com.subsidy.common.ResponseVO; import com.subsidy.common.interceptor.LoginRequired; import com.subsidy.dto.administer.OperatorsDTO; import com.subsidy.dto.company.AddCompanyDTO; -import com.subsidy.dto.company.DataOverviewDTO; import com.subsidy.dto.company.GetCompanyMembersDTO; import com.subsidy.model.CompanyDictDO; import com.subsidy.model.MemberDO; @@ -78,22 +77,11 @@ public class CompanyDictController { return ResponseData.generateCreatedResponse(0,companyDictService.getCompanyMembers(getCompanyMembersDTO)); } - @PostMapping(value = "getCompanyDataOverview") - @ApiOperation("数据统计") - //@LoginRequired - public ResponseVO getCompanyDataOverview() { - return ResponseData.generateCreatedResponse(0, companyDictService.getCompanyDataOverview()); - } - - @PostMapping(value = "getCDNBandwidthStatDetails") - @ApiOperation("培训项目带宽使用情况") - public ResponseVO getCDNBandwidthStatDetails() { - return ResponseData.generateCreatedResponse(0, companyDictService.getCDNBandwidthStatDetails()); + @PostMapping("memberSummary") + @ApiOperation("学员认证详情 companyId") + @LoginRequired + public ResponseVO memberSummary(@RequestBody GetCompanyMembersDTO getCompanyMembersDTO){ + return ResponseData.generateCreatedResponse(0,companyDictService.memberSummary(getCompanyMembersDTO)); } - @PostMapping(value = "getCDNFluxStatDetails") - @ApiOperation("培训项目流量使用情况") - public ResponseVO getCDNFluxStatDetails() { - return ResponseData.generateCreatedResponse(0, companyDictService.getCDNFluxStatDetails()); - } } diff --git a/src/main/java/com/subsidy/controller/ImageCheckRecordController.java b/src/main/java/com/subsidy/controller/ImageCheckRecordController.java index b3db474..0d16246 100644 --- a/src/main/java/com/subsidy/controller/ImageCheckRecordController.java +++ b/src/main/java/com/subsidy/controller/ImageCheckRecordController.java @@ -4,6 +4,7 @@ package com.subsidy.controller; import com.subsidy.common.ResponseData; import com.subsidy.common.ResponseVO; import com.subsidy.common.interceptor.LoginRequired; +import com.subsidy.dto.image.ImageCheckDTO; import com.subsidy.model.ImageCheckRecordDO; import com.subsidy.service.ImageCheckRecordService; import io.swagger.annotations.ApiOperation; @@ -30,14 +31,19 @@ public class ImageCheckRecordController { @Autowired - private ImageCheckRecordService imageCheckRecordService; - + private ImageCheckRecordService imageCheckRecordService; @PostMapping("getImageCheckHistory") @ApiOperation("获取某人某个班级的验证历史 memberId classId ") @LoginRequired - public ResponseVO getImageCheckHistory(@RequestBody ImageCheckRecordDO imageCheckRecordDO){ - return ResponseData.generateCreatedResponse(0,imageCheckRecordService.getImageCheckHistory(imageCheckRecordDO)); + public ResponseVO getImageCheckHistory(@RequestBody ImageCheckRecordDO 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)); } diff --git a/src/main/java/com/subsidy/controller/MemberController.java b/src/main/java/com/subsidy/controller/MemberController.java index 848cb43..d693828 100644 --- a/src/main/java/com/subsidy/controller/MemberController.java +++ b/src/main/java/com/subsidy/controller/MemberController.java @@ -102,13 +102,6 @@ public class MemberController { 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") @ApiOperation("清除采集照片 id ") public ResponseVO removeCheckImage(@RequestBody MemberDO memberDO){ diff --git a/src/main/java/com/subsidy/controller/VodPlayHistoryController.java b/src/main/java/com/subsidy/controller/VodPlayHistoryController.java index 1f6b79e..7a241bd 100644 --- a/src/main/java/com/subsidy/controller/VodPlayHistoryController.java +++ b/src/main/java/com/subsidy/controller/VodPlayHistoryController.java @@ -45,7 +45,7 @@ public class VodPlayHistoryController { @RequestMapping("insertHistoryNew") @ApiOperation("记录学生看视频位置 classId班级id vodId 视频id memberId 成员id playLength 播放时长 playRecord 位点") -// @LoginRequired + @LoginRequired @TimeRequired public ResponseVO insertHistoryNew(@RequestBody String param){ InsertHistoryNewDTO insertHistoryNewDTO = JSON.parseObject(param, InsertHistoryNewDTO.class); diff --git a/src/main/java/com/subsidy/dto/detection/GetCheckHistoryDTO.java b/src/main/java/com/subsidy/dto/detection/GetCheckHistoryDTO.java new file mode 100644 index 0000000..70c2a30 --- /dev/null +++ b/src/main/java/com/subsidy/dto/detection/GetCheckHistoryDTO.java @@ -0,0 +1,17 @@ +package com.subsidy.dto.detection; + +import lombok.Data; + +@Data +public class GetCheckHistoryDTO { + + private Integer pageSize; + + private Integer pageNum; + + private Long memberId; + + private Long classId; + + +} diff --git a/src/main/java/com/subsidy/dto/image/ImageCheckDTO.java b/src/main/java/com/subsidy/dto/image/ImageCheckDTO.java new file mode 100644 index 0000000..9dd4717 --- /dev/null +++ b/src/main/java/com/subsidy/dto/image/ImageCheckDTO.java @@ -0,0 +1,18 @@ +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 ; + +} diff --git a/src/main/java/com/subsidy/mapper/ActivityDetectionMapper.java b/src/main/java/com/subsidy/mapper/ActivityDetectionMapper.java index caf5e1b..b3682dd 100644 --- a/src/main/java/com/subsidy/mapper/ActivityDetectionMapper.java +++ b/src/main/java/com/subsidy/mapper/ActivityDetectionMapper.java @@ -1,7 +1,9 @@ package com.subsidy.mapper; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.subsidy.model.ActivityDetectionDO; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.subsidy.vo.activity.GetCheckHistoryVO; import org.springframework.stereotype.Repository; /** @@ -15,4 +17,6 @@ import org.springframework.stereotype.Repository; @Repository public interface ActivityDetectionMapper extends BaseMapper { + IPage getCheckHistory(IPage iPage,Long classId,Long memberId); + } diff --git a/src/main/java/com/subsidy/model/ClassDictDO.java b/src/main/java/com/subsidy/model/ClassDictDO.java index 98cdd7c..20c4ef8 100644 --- a/src/main/java/com/subsidy/model/ClassDictDO.java +++ b/src/main/java/com/subsidy/model/ClassDictDO.java @@ -78,6 +78,45 @@ public class ClassDictDO extends BaseModel { */ 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; diff --git a/src/main/java/com/subsidy/model/ImageCheckRecordDO.java b/src/main/java/com/subsidy/model/ImageCheckRecordDO.java index d47b9df..71147a2 100644 --- a/src/main/java/com/subsidy/model/ImageCheckRecordDO.java +++ b/src/main/java/com/subsidy/model/ImageCheckRecordDO.java @@ -31,15 +31,13 @@ public class ImageCheckRecordDO extends BaseModel { private Long classId; /** - * 试卷id - */ - private Long paperId; - - /** * 成员id */ private Long memberId; + /** + * 请求id + */ private String requestId; /** diff --git a/src/main/java/com/subsidy/model/MemberDO.java b/src/main/java/com/subsidy/model/MemberDO.java index 8f60de6..9d7ae91 100644 --- a/src/main/java/com/subsidy/model/MemberDO.java +++ b/src/main/java/com/subsidy/model/MemberDO.java @@ -93,7 +93,7 @@ public class MemberDO extends BaseModel { /** * 采集时间 */ - private LocalDateTime checkTime; + private String checkTime; /** * 身份证号 diff --git a/src/main/java/com/subsidy/service/ActivityDetectionService.java b/src/main/java/com/subsidy/service/ActivityDetectionService.java index 3a0ab1e..a02bb4c 100644 --- a/src/main/java/com/subsidy/service/ActivityDetectionService.java +++ b/src/main/java/com/subsidy/service/ActivityDetectionService.java @@ -1,12 +1,13 @@ package com.subsidy.service; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.subsidy.dto.detection.GetCheckHistoryDTO; import com.subsidy.dto.detection.VerifyDTO; import com.subsidy.model.ActivityDetectionDO; import com.baomidou.mybatisplus.extension.service.IService; +import com.subsidy.vo.activity.GetCheckHistoryVO; import javax.servlet.http.HttpServletRequest; -import java.util.List; /** *

@@ -20,6 +21,6 @@ public interface ActivityDetectionService extends IService String verify(VerifyDTO verifyDTO, HttpServletRequest request); - IPage getCheckHistory(ActivityDetectionDO activityDetectionDO); + IPage getCheckHistory(GetCheckHistoryDTO getCheckHistoryDTO); } diff --git a/src/main/java/com/subsidy/service/CompanyDictService.java b/src/main/java/com/subsidy/service/CompanyDictService.java index c426f53..5c302e8 100644 --- a/src/main/java/com/subsidy/service/CompanyDictService.java +++ b/src/main/java/com/subsidy/service/CompanyDictService.java @@ -1,23 +1,15 @@ package com.subsidy.service; -import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; import com.subsidy.dto.administer.OperatorsDTO; import com.subsidy.dto.company.AddCompanyDTO; -import com.subsidy.dto.company.DataOverviewDTO; import com.subsidy.dto.company.GetCompanyMembersDTO; import com.subsidy.model.CompanyDictDO; -import com.subsidy.model.MemberDO; 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.GetCompanyMembersVO; -import com.tencentcloudapi.vod.v20180717.models.StatDataItem; - import java.util.List; -import java.util.Map; /** *

@@ -41,6 +33,8 @@ public interface CompanyDictService extends IService { IPage getCompanyMembers(GetCompanyMembersDTO getCompanyMembersDTO); + MemberSummaryVO memberSummary(GetCompanyMembersDTO getCompanyMembersDTO); + DataOverviewVO getCompanyDataOverview(); List getCDNBandwidthStatDetails(); diff --git a/src/main/java/com/subsidy/service/ImageCheckRecordService.java b/src/main/java/com/subsidy/service/ImageCheckRecordService.java index d66abc4..7448cb7 100644 --- a/src/main/java/com/subsidy/service/ImageCheckRecordService.java +++ b/src/main/java/com/subsidy/service/ImageCheckRecordService.java @@ -1,5 +1,6 @@ package com.subsidy.service; +import com.subsidy.dto.image.ImageCheckDTO; import com.subsidy.model.ImageCheckRecordDO; import com.baomidou.mybatisplus.extension.service.IService; @@ -17,4 +18,6 @@ public interface ImageCheckRecordService extends IService { List getImageCheckHistory(ImageCheckRecordDO imageCheckRecordDO); + String imageCheck(ImageCheckDTO imageCheckDTO)throws Exception; + } diff --git a/src/main/java/com/subsidy/service/MemberService.java b/src/main/java/com/subsidy/service/MemberService.java index df1526c..32abf7a 100644 --- a/src/main/java/com/subsidy/service/MemberService.java +++ b/src/main/java/com/subsidy/service/MemberService.java @@ -43,8 +43,6 @@ public interface MemberService extends IService { String updatePassword(MemberDO memberDO); - String updateCheckImage(MemberDO memberDO); - String removeCheckImage(MemberDO memberDO); List myCourses(MyCoursesDTO myCoursesDTO); diff --git a/src/main/java/com/subsidy/service/impl/ActivityDetectionServiceImpl.java b/src/main/java/com/subsidy/service/impl/ActivityDetectionServiceImpl.java index 48cd2d9..96f8497 100644 --- a/src/main/java/com/subsidy/service/impl/ActivityDetectionServiceImpl.java +++ b/src/main/java/com/subsidy/service/impl/ActivityDetectionServiceImpl.java @@ -1,23 +1,17 @@ package com.subsidy.service.impl; import com.baomidou.mybatisplus.core.metadata.IPage; -import com.subsidy.common.configure.ActivityDetectionConfig; -import com.subsidy.common.configure.VODConfig; -import com.subsidy.common.configure.WechatConfig; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.subsidy.dto.detection.GetCheckHistoryDTO; import com.subsidy.dto.detection.VerifyDTO; import com.subsidy.model.ActivityDetectionDO; import com.subsidy.mapper.ActivityDetectionMapper; import com.subsidy.service.ActivityDetectionService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.subsidy.util.ActivityDetectionUtils; import com.subsidy.util.ConstantUtils; -import com.tencentcloudapi.captcha.v20190722.CaptchaClient; -import com.tencentcloudapi.captcha.v20190722.models.DescribeCaptchaResultRequest; +import com.subsidy.vo.activity.GetCheckHistoryVO; 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 javax.servlet.http.HttpServletRequest; @@ -33,50 +27,11 @@ import javax.servlet.http.HttpServletRequest; @Service public class ActivityDetectionServiceImpl extends ServiceImpl implements ActivityDetectionService { - @Autowired - private ActivityDetectionConfig activityDetectionConfig; - - @Autowired - private VODConfig vodConfig; - public String verify(VerifyDTO verifyDTO, HttpServletRequest request){ try{ - // 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密 - // 密钥可前往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); + DescribeCaptchaResultResponse resp = ActivityDetectionUtils.activityDetection(request,verifyDTO.getRandStr()); // 输出json格式的字符串回包 - System.out.println(DescribeCaptchaResultResponse.toJsonString(resp)); ActivityDetectionDO activityDetectionDO = new ActivityDetectionDO(); activityDetectionDO.setClassId(verifyDTO.getClassId()); activityDetectionDO.setMemberId(verifyDTO.getMemberId()); @@ -90,16 +45,15 @@ public class ActivityDetectionServiceImpl extends ServiceImpl getCheckHistory(ActivityDetectionDO activityDetectionDO){ - - - return null; + public IPage getCheckHistory(GetCheckHistoryDTO getCheckHistoryDTO){ + Page pager = new Page(getCheckHistoryDTO.getPageNum(), getCheckHistoryDTO.getPageSize()); + return this.baseMapper.getCheckHistory(pager,getCheckHistoryDTO.getClassId(),getCheckHistoryDTO.getMemberId()); } } diff --git a/src/main/java/com/subsidy/service/impl/CompanyDictServiceImpl.java b/src/main/java/com/subsidy/service/impl/CompanyDictServiceImpl.java index 54e73ff..bd579dc 100644 --- a/src/main/java/com/subsidy/service/impl/CompanyDictServiceImpl.java +++ b/src/main/java/com/subsidy/service/impl/CompanyDictServiceImpl.java @@ -25,6 +25,7 @@ import com.subsidy.mapper.RankDictMapper; import com.subsidy.mapper.RoleAdministerMappingMapper; import com.subsidy.mapper.RotationImgDictMapper; import com.subsidy.mapper.VodPlayHistoryMapper; +import com.subsidy.mapper.*; import com.subsidy.model.*; import com.subsidy.service.CompanyDictService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -39,6 +40,7 @@ import com.subsidy.vo.company.GetAllCompanyVO; 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.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -105,6 +107,9 @@ public class CompanyDictServiceImpl extends ServiceImpl operators(OperatorsDTO operatorsDTO) { Page pager = new Page(operatorsDTO.getPageNum(), operatorsDTO.getPageSize()); @@ -334,6 +339,26 @@ public class CompanyDictServiceImpl extends ServiceImpl() + .lambda() + .eq(MemberDO::getCompanyId,getCompanyMembersDTO.getCompanyId())); + memberSummaryVO.setTotal(total); + + //短信验证 + Integer smsCnt = memberMapper.selectCount(new QueryWrapper() + .lambda() + .eq(MemberDO::getCompanyId,getCompanyMembersDTO.getCompanyId()) + .isNull(MemberDO::getFirstLogin)); + memberSummaryVO.setSmsCnt(smsCnt); + + memberSummaryVO.setImgCnt(total-smsCnt); + return memberSummaryVO; + } @Override public List getCDNBandwidthStatDetails() { diff --git a/src/main/java/com/subsidy/service/impl/ImageCheckRecordServiceImpl.java b/src/main/java/com/subsidy/service/impl/ImageCheckRecordServiceImpl.java index d5a85c3..05651c3 100644 --- a/src/main/java/com/subsidy/service/impl/ImageCheckRecordServiceImpl.java +++ b/src/main/java/com/subsidy/service/impl/ImageCheckRecordServiceImpl.java @@ -1,12 +1,34 @@ package com.subsidy.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.generator.config.TemplateConfig; +import com.google.common.hash.Hashing; +import com.subsidy.common.configure.RestTemplateConfig; +import com.subsidy.common.exception.HttpException; +import com.subsidy.dto.image.ImageCheckDTO; +import com.subsidy.mapper.MemberMapper; import com.subsidy.model.ImageCheckRecordDO; import com.subsidy.mapper.ImageCheckRecordMapper; +import com.subsidy.model.MemberDO; import com.subsidy.service.ImageCheckRecordService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.subsidy.util.ConstantUtils; +import com.subsidy.util.DateFormatUtil; +import com.subsidy.util.ImageCheckUtil; +import com.subsidy.vo.token.*; +import com.subsidy.vo.wechat.AccessTokenVO; +import com.tencentcloudapi.faceid.v20180301.models.GetFaceIdResultResponse; +import com.tencentcloudapi.faceid.v20180301.models.ImageRecognitionResponse; +import org.apache.commons.codec.Charsets; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.*; import org.springframework.stereotype.Service; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; import java.util.List; /** @@ -20,12 +42,224 @@ import java.util.List; @Service public class ImageCheckRecordServiceImpl extends ServiceImpl implements ImageCheckRecordService { - public List getImageCheckHistory(ImageCheckRecordDO imageCheckRecordDO){ + @Autowired + private MemberMapper memberMapper; + + @Autowired + private RestTemplateConfig restTemplateConfig; + +// public static final String WBAPPID = "IDAaOibN"; +// public static final String SECRET= "GD6Z55rHXSlBZB4oxEEowwI5h4IgwUdh0xOOHi6fambXYMFcHuDaBRxtnMx5FVhk"; + + public static final String WBAPPID = "TIDAbX8x"; + public static final String SECRET = "cWAMlQ8Aq7aOad0wrtfJcSpcgksCLFT62qHC4uDHFCGx0SPKqtpt1PungiAKya2M"; + + public List getImageCheckHistory(ImageCheckRecordDO imageCheckRecordDO) { return this.baseMapper.selectList(new QueryWrapper() - .lambda() - .eq(ImageCheckRecordDO::getClassId,imageCheckRecordDO.getClassId()) - .eq(ImageCheckRecordDO::getMemberId,imageCheckRecordDO.getMemberId()) - .orderByDesc(ImageCheckRecordDO::getCreateDate)); + .lambda() + .eq(ImageCheckRecordDO::getClassId, imageCheckRecordDO.getClassId()) + .eq(ImageCheckRecordDO::getMemberId, imageCheckRecordDO.getMemberId()) + .orderByDesc(ImageCheckRecordDO::getCreateDate)); + } + + public String imageCheck(ImageCheckDTO imageCheckDTO) throws Exception { + + //获取这个学生的基本信息 + MemberDO memberDO = memberMapper.selectById(imageCheckDTO.getId()); + + if (StringUtils.isEmpty(memberDO.getIdCard())) { + throw new HttpException(10025); + } + + //获取token + IdCardAccessTokenVO idCardAccessTokenVO = this.accessToken(); + + //获取signTicket + IdCardTicketsVO idCardTicketsVO = this.signTickets(idCardAccessTokenVO.getAccess_token()); + + List signList1 = new ArrayList<>(); + signList1.add(WBAPPID); + signList1.add("001"); + signList1.add(memberDO.getUserName()); + signList1.add(memberDO.getIdCard()); + signList1.add(memberDO.getId() + ""); + signList1.add("1.0.0"); + + //生成签名 + String sign = sign(signList1, idCardTicketsVO.getValue()); + System.out.println(sign); + + //合作方后台上送身份信息 + SendIdCardInfoVO sendIdCardInfoVO = this.sendIdCardInfo("001", memberDO, sign); + + //获取 NONCE ticket + IdCardTicketsVO nonceTicket = this.nonceTicket(idCardAccessTokenVO.getAccess_token(), memberDO.getId() + ""); + + //签名2 + List signList2 = new ArrayList<>(); + signList2.add(WBAPPID); + signList2.add(memberDO.getId() + ""); + signList2.add(imageCheckDTO.getNonce()); + signList2.add("1.0.0"); + signList2.add(sendIdCardInfoVO.getResult().getH5faceId()); + signList2.add(sendIdCardInfoVO.getResult().getOrderNo()); + String sign2 = sign(signList2, nonceTicket.getValue()); + + //启动人脸验证 + this.startCheck(imageCheckDTO.getNonce(), sendIdCardInfoVO.getResult(), memberDO.getId() + "", sign2); + + //签名3 + List signList3 = new ArrayList<>(); + signList3.add(WBAPPID); + signList3.add("001"); + signList3.add("1.0.0"); + signList3.add(imageCheckDTO.getNonce()); + + String sign3 = sign(signList3,idCardTicketsVO.getValue()); + System.out.println(sign3); + + //人身核验结果 + ResultVO resultVO = this.checkResult("001", imageCheckDTO.getNonce(), sign3); + + + if (Double.valueOf(resultVO.getSimilarity()) > 80.0) { + return ConstantUtils.SUCCESS_VERIFY; + } else { + return ConstantUtils.FAIL_VERIFY; + } + } + + /** + * 获取accessToken + */ + public IdCardAccessTokenVO accessToken() { + + String url = "https://miniprogram-kyc.tencentcloudapi.com/api/oauth2/access_token?app_id=" + WBAPPID + + "&secret=" + SECRET + "&grant_type=client_credential&version=1.0.0"; + ResponseEntity response = restTemplateConfig.restTemplate() + .exchange(url, HttpMethod.GET, null, IdCardAccessTokenVO.class); + + System.out.println(response.getBody().toString()); + + return response.getBody(); + } + + /** + * 获取sign_ticket + */ + public IdCardTicketsVO signTickets(String accessToken) { + + String url = "https://miniprogram-kyc.tencentcloudapi.com/api/oauth2/api_ticket?app_id=" + WBAPPID + "&access_token=" + accessToken + "&type=SIGN&version=1.0.0"; + ResponseEntity response = restTemplateConfig.restTemplate() + .exchange(url, HttpMethod.GET, null, IdCardSignTicketVO.class); + + System.out.println(response.getBody().getTickets()); + + return response.getBody().getTickets().get(0); + } + + /** + * 获取签名 + */ + public static String sign(List 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(); + } + + /** + * 合作方后台上送身份信息 POST请求 + */ + public SendIdCardInfoVO sendIdCardInfo(String orderNo, MemberDO memberDO, String sign) { + String url = "https://miniprogram-kyc.tencentcloudapi.com/api/server/h5/geth5faceid?orderNo=" + orderNo; + + String input = "{\n" + + " \"webankAppId\":\"" + WBAPPID + "\",\n" + + " \"orderNo\":\"" + orderNo + "\",\n" + + " \"name\":\"" + memberDO.getUserName() + "\"," + + " \"idNo\":\"" + memberDO.getIdCard() + "\"," + + " \"userId\":\"" + memberDO.getId() + "\"," + + " \"version\":\"1.0.0\"," + + " \"sign\":\"" + sign + "\"" + + "}"; + + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + ResponseEntity responseEntity = restTemplateConfig.restTemplate() + .exchange(url, HttpMethod.POST, new HttpEntity<>(input, headers), SendIdCardInfoVO.class); + + return responseEntity.getBody(); + } + + /** + * 获取nonce ticket + */ + public IdCardTicketsVO nonceTicket(String accessToken, String usrId) { + + String url = "https://miniprogram-kyc.tencentcloudapi.com/api/oauth2/api_ticket?app_id=" + WBAPPID + + "&access_token=" + accessToken + + "&type=NONCE&version=1.0.0&user_id=" + usrId; + ResponseEntity response = restTemplateConfig.restTemplate() + .exchange(url, HttpMethod.GET, null, IdCardSignTicketVO.class); + return response.getBody().getTickets().get(0); } + /** + * 启动 H5 人脸核身 + */ + public void startCheck(String nonce, SendResultVO sendResultVO, String userId, String sign) { + + String url = "https://miniprogram-kyc.tencentcloudapi.com/api/pc/login?webankAppId=" + WBAPPID + + "&version=1.0.0" + + "&nonce=" + nonce + + "&orderNo=" + sendResultVO.getOrderNo() + + "&h5faceId=" + sendResultVO.getH5faceId() + + "&url=" + sendResultVO.getOptimalDomain() + + "&userId=" + userId + + "&sign=" + sign; + restTemplateConfig.restTemplate() + .exchange(url, HttpMethod.GET, null, IdCardSignTicketVO.class); + } + + /** + * 人脸核身结果查询 POST + */ + public ResultVO checkResult(String orderNo,String nonce,String sign) { + + String url = "https://miniprogram-kyc.tencentcloudapi.com/api/v2/base/queryfacerecord?orderNo="+orderNo; + + String input = "{\n" + + " \"appId\":\"" + WBAPPID + "\",\n" + + " \"version\":\"1.0.0\",\n" + + " \"nonce\":\""+nonce+"\"," + + " \"orderNo\":\"" + orderNo + "\"," + + " \"sign\":\"" + sign + "\"," + + " \"getFile\":\"2\"," + + " \"queryVersion\":\"\"" + + "}"; + + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + + ResponseEntity responseEntity = restTemplateConfig.restTemplate() + .exchange(url, HttpMethod.POST, new HttpEntity<>(input.getBytes(), headers), CheckResultVO.class); + + + return responseEntity.getBody().getResultVO(); + } + + } diff --git a/src/main/java/com/subsidy/service/impl/MemberServiceImpl.java b/src/main/java/com/subsidy/service/impl/MemberServiceImpl.java index 66f430b..e6f0f2a 100644 --- a/src/main/java/com/subsidy/service/impl/MemberServiceImpl.java +++ b/src/main/java/com/subsidy/service/impl/MemberServiceImpl.java @@ -709,12 +709,6 @@ public class MemberServiceImpl extends ServiceImpl imple 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) { this.baseMapper.removeCheckImage(memberDO.getId()); return ConstantUtils.DELETE_SUCCESS; diff --git a/src/main/java/com/subsidy/util/ActivityDetectionUtils.java b/src/main/java/com/subsidy/util/ActivityDetectionUtils.java new file mode 100644 index 0000000..8af65cb --- /dev/null +++ b/src/main/java/com/subsidy/util/ActivityDetectionUtils.java @@ -0,0 +1,48 @@ +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); + } + +} diff --git a/src/main/java/com/subsidy/util/ConstantUtils.java b/src/main/java/com/subsidy/util/ConstantUtils.java index 5f05c6f..9b6db80 100644 --- a/src/main/java/com/subsidy/util/ConstantUtils.java +++ b/src/main/java/com/subsidy/util/ConstantUtils.java @@ -86,4 +86,25 @@ public class ConstantUtils { 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; + + /** + * 人脸识别 + */ + } diff --git a/src/main/java/com/subsidy/util/ImageCheckUtil.java b/src/main/java/com/subsidy/util/ImageCheckUtil.java new file mode 100644 index 0000000..5fcead4 --- /dev/null +++ b/src/main/java/com/subsidy/util/ImageCheckUtil.java @@ -0,0 +1,33 @@ +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 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(); + } +} diff --git a/src/main/java/com/subsidy/vo/activity/GetCheckHistoryVO.java b/src/main/java/com/subsidy/vo/activity/GetCheckHistoryVO.java new file mode 100644 index 0000000..349fd36 --- /dev/null +++ b/src/main/java/com/subsidy/vo/activity/GetCheckHistoryVO.java @@ -0,0 +1,14 @@ +package com.subsidy.vo.activity; + +import lombok.Data; + +@Data +public class GetCheckHistoryVO { + + private Long id; + + private String createDate; + + private Integer status; + +} diff --git a/src/main/java/com/subsidy/vo/company/MemberSummaryVO.java b/src/main/java/com/subsidy/vo/company/MemberSummaryVO.java new file mode 100644 index 0000000..4278ef1 --- /dev/null +++ b/src/main/java/com/subsidy/vo/company/MemberSummaryVO.java @@ -0,0 +1,15 @@ +package com.subsidy.vo.company; + +import lombok.Data; + +@Data +public class MemberSummaryVO { + + + private Integer total; + + private Integer smsCnt; + + private Integer imgCnt; + +} diff --git a/src/main/java/com/subsidy/vo/token/CheckResultVO.java b/src/main/java/com/subsidy/vo/token/CheckResultVO.java new file mode 100644 index 0000000..f3cd70c --- /dev/null +++ b/src/main/java/com/subsidy/vo/token/CheckResultVO.java @@ -0,0 +1,18 @@ +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; + +} diff --git a/src/main/java/com/subsidy/vo/token/IdCardAccessTokenVO.java b/src/main/java/com/subsidy/vo/token/IdCardAccessTokenVO.java new file mode 100644 index 0000000..97e0007 --- /dev/null +++ b/src/main/java/com/subsidy/vo/token/IdCardAccessTokenVO.java @@ -0,0 +1,19 @@ +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; +} diff --git a/src/main/java/com/subsidy/vo/token/IdCardSignTicketVO.java b/src/main/java/com/subsidy/vo/token/IdCardSignTicketVO.java new file mode 100644 index 0000000..4ff0c03 --- /dev/null +++ b/src/main/java/com/subsidy/vo/token/IdCardSignTicketVO.java @@ -0,0 +1,18 @@ +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 tickets; + +} diff --git a/src/main/java/com/subsidy/vo/token/IdCardTicketsVO.java b/src/main/java/com/subsidy/vo/token/IdCardTicketsVO.java new file mode 100644 index 0000000..359c2b9 --- /dev/null +++ b/src/main/java/com/subsidy/vo/token/IdCardTicketsVO.java @@ -0,0 +1,14 @@ +package com.subsidy.vo.token; + +import lombok.Data; + +@Data +public class IdCardTicketsVO { + + private String value; + + private String expire_in; + + private String expire_time; + +} diff --git a/src/main/java/com/subsidy/vo/token/ResultVO.java b/src/main/java/com/subsidy/vo/token/ResultVO.java new file mode 100644 index 0000000..22bfade --- /dev/null +++ b/src/main/java/com/subsidy/vo/token/ResultVO.java @@ -0,0 +1,28 @@ +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; + +} diff --git a/src/main/java/com/subsidy/vo/token/SendIdCardInfoVO.java b/src/main/java/com/subsidy/vo/token/SendIdCardInfoVO.java new file mode 100644 index 0000000..956c833 --- /dev/null +++ b/src/main/java/com/subsidy/vo/token/SendIdCardInfoVO.java @@ -0,0 +1,18 @@ +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; + +} diff --git a/src/main/java/com/subsidy/vo/token/SendResultVO.java b/src/main/java/com/subsidy/vo/token/SendResultVO.java new file mode 100644 index 0000000..ccda248 --- /dev/null +++ b/src/main/java/com/subsidy/vo/token/SendResultVO.java @@ -0,0 +1,20 @@ +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; + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 11f73ba..5c5c4fa 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -72,9 +72,3 @@ wechat: #pro appId: wx5e1ecb9c9bd33451 appSecret: 4f5e1abb6fb4f68f5273820b6295ec6b - - -#活体检测配置 -activity.captchaAppId: 2013197365 -activity.appSecretKey: 04ABoF0ZVuMje8NP84DE5Sg** -activity.businessId: 1 \ No newline at end of file diff --git a/src/main/resources/code.properties b/src/main/resources/code.properties index c677260..164d67f 100644 --- a/src/main/resources/code.properties +++ b/src/main/resources/code.properties @@ -17,6 +17,7 @@ meishu.code-message[10021]=密码输入错误,您还可以输入1次密码 meishu.code-message[10022]=密码输入错误,您还可以输入2次密码 meishu.code-message[10023]=密码输入错误,您还可以输入3次密码 meishu.code-message[10024]=密码输入错误,您还可以输入4次密码 +meishu.code-message[10025]=身份证识别错误 meishu.code-message[20001]=该课程已存在 diff --git a/src/main/resources/mapper/ActivityDetectionMapper.xml b/src/main/resources/mapper/ActivityDetectionMapper.xml index 9fc0b42..f8351eb 100644 --- a/src/main/resources/mapper/ActivityDetectionMapper.xml +++ b/src/main/resources/mapper/ActivityDetectionMapper.xml @@ -21,4 +21,17 @@ id, class_id, member_id, status + + diff --git a/src/main/resources/mapper/MemberMapper.xml b/src/main/resources/mapper/MemberMapper.xml index 3be171e..82ee958 100644 --- a/src/main/resources/mapper/MemberMapper.xml +++ b/src/main/resources/mapper/MemberMapper.xml @@ -93,13 +93,11 @@ count( 1 ) AS cnt FROM course_content t - LEFT JOIN content_vod_mapping t3 ON t3.content_id = t.id - LEFT JOIN vod_dict t2 ON t.id = t3.vod_id + LEFT JOIN content_vod_mapping t2 ON t.id = t2.content_id WHERE t.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 t.course_id ) t4 ON t3.id = t4.course_id