Commit f79839fe by 涂亚平

人脸识别demo

1 parent 0cb59b9a
Showing with 281 additions and 92 deletions
...@@ -65,7 +65,7 @@ ...@@ -65,7 +65,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>
......
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;
}
...@@ -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,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.image;
import lombok.Data;
@Data
public class ImageCheckDTO {
private Long id;
private String imageBase64;
private Long classId;
private Long paperId;
private String nonce ;
}
...@@ -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.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);
......
...@@ -2,25 +2,16 @@ package com.subsidy.service.impl; ...@@ -2,25 +2,16 @@ package com.subsidy.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.subsidy.common.configure.ActivityDetectionConfig;
import com.subsidy.common.configure.VODConfig;
import com.subsidy.dto.detection.GetCheckHistoryDTO; 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.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.subsidy.util.IpAddressUtil;
import com.subsidy.vo.activity.GetCheckHistoryVO; import com.subsidy.vo.activity.GetCheckHistoryVO;
import com.tencentcloudapi.captcha.v20190722.CaptchaClient;
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;
...@@ -36,37 +27,10 @@ import javax.servlet.http.HttpServletRequest; ...@@ -36,37 +27,10 @@ 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);
String ip = IpAddressUtil.getIpAddress(request);
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格式的字符串回包
ActivityDetectionDO activityDetectionDO = new ActivityDetectionDO(); ActivityDetectionDO activityDetectionDO = new ActivityDetectionDO();
activityDetectionDO.setClassId(verifyDTO.getClassId()); activityDetectionDO.setClassId(verifyDTO.getClassId());
...@@ -81,7 +45,7 @@ public class ActivityDetectionServiceImpl extends ServiceImpl<ActivityDetectionM ...@@ -81,7 +45,7 @@ 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;
......
...@@ -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;
......
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 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();
}
}
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;
}
...@@ -69,9 +69,3 @@ wechat: ...@@ -69,9 +69,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]=该课程已存在
......
...@@ -93,7 +93,7 @@ ...@@ -93,7 +93,7 @@
count( 1 ) AS cnt count( 1 ) AS cnt
FROM FROM
course_content t course_content t
LEFT JOIN vod_dict t2 ON t.id = t2.content_id LEFT JOIN content_vod_mapping t2 ON t.id = t2.content_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
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!