Commit f79839fe by 涂亚平

人脸识别demo

1 parent 0cb59b9a
Showing with 517 additions and 94 deletions
......@@ -65,7 +65,7 @@
<dependency>
<groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java</artifactId>
<version>3.1.64</version>
<version>3.1.322</version>
</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 {
signVO.setSign(SecretUtils.getSHAString(signStr));
return ResponseData.generateCreatedResponse(0,signVO);
}
}
......@@ -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;
......@@ -32,12 +33,17 @@ public class ImageCheckRecordController {
@Autowired
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));
}
......
......@@ -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){
......
......@@ -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);
......
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 {
private Long classId;
/**
* 试卷id
*/
private Long paperId;
/**
* 成员id
*/
private Long memberId;
/**
* 请求id
*/
private String requestId;
/**
......
......@@ -93,7 +93,7 @@ public class MemberDO extends BaseModel {
/**
* 采集时间
*/
private LocalDateTime checkTime;
private String checkTime;
/**
* 身份证号
......
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<ImageCheckRecordDO> {
List<ImageCheckRecordDO> getImageCheckHistory(ImageCheckRecordDO imageCheckRecordDO);
String imageCheck(ImageCheckDTO imageCheckDTO)throws Exception;
}
......@@ -43,8 +43,6 @@ public interface MemberService extends IService<MemberDO> {
String updatePassword(MemberDO memberDO);
String updateCheckImage(MemberDO memberDO);
String removeCheckImage(MemberDO memberDO);
List<MyCoursesVO> myCourses(MyCoursesDTO myCoursesDTO);
......
......@@ -2,25 +2,16 @@ package com.subsidy.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
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.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.subsidy.util.IpAddressUtil;
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.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;
......@@ -36,37 +27,10 @@ import javax.servlet.http.HttpServletRequest;
@Service
public class ActivityDetectionServiceImpl extends ServiceImpl<ActivityDetectionMapper, ActivityDetectionDO> 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);
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);
DescribeCaptchaResultResponse resp = ActivityDetectionUtils.activityDetection(request,verifyDTO.getRandStr());
// 输出json格式的字符串回包
ActivityDetectionDO activityDetectionDO = new ActivityDetectionDO();
activityDetectionDO.setClassId(verifyDTO.getClassId());
......@@ -81,7 +45,7 @@ public class ActivityDetectionServiceImpl extends ServiceImpl<ActivityDetectionM
this.baseMapper.insert(activityDetectionDO);
return ConstantUtils.FAIL_VERIFY;
}
} catch (TencentCloudSDKException e) {
} catch (Exception e) {
// System.out.println(e.toString());
}
return null;
......
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<ImageCheckRecordMapper, ImageCheckRecordDO> implements ImageCheckRecordService {
public List<ImageCheckRecordDO> 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<ImageCheckRecordDO> getImageCheckHistory(ImageCheckRecordDO imageCheckRecordDO) {
return this.baseMapper.selectList(new QueryWrapper<ImageCheckRecordDO>()
.lambda()
.eq(ImageCheckRecordDO::getClassId,imageCheckRecordDO.getClassId())
.eq(ImageCheckRecordDO::getMemberId,imageCheckRecordDO.getMemberId())
.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<String> 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<String> 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<String> 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<IdCardAccessTokenVO> 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<IdCardSignTicketVO> 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<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();
}
/**
* 合作方后台上送身份信息 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<SendIdCardInfoVO> 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<IdCardSignTicketVO> 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<CheckResultVO> responseEntity = restTemplateConfig.restTemplate()
.exchange(url, HttpMethod.POST, new HttpEntity<>(input.getBytes(), headers), CheckResultVO.class);
return responseEntity.getBody().getResultVO();
}
}
......@@ -709,12 +709,6 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberDO> 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;
......
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 {
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:
#pro
appId: wx5e1ecb9c9bd33451
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次密码
meishu.code-message[10022]=密码输入错误,您还可以输入2次密码
meishu.code-message[10023]=密码输入错误,您还可以输入3次密码
meishu.code-message[10024]=密码输入错误,您还可以输入4次密码
meishu.code-message[10025]=身份证识别错误
meishu.code-message[20001]=该课程已存在
......
......@@ -93,7 +93,7 @@
count( 1 ) AS cnt
FROM
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
t.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!