yangdamao 11 mesi fa
parent
commit
7d7d737364
27 ha cambiato i file con 528 aggiunte e 5 eliminazioni
  1. 79 0
      run-prod.sh
  2. 1 1
      zhongzheng-admin/src/main/java/com/zhongzheng/controller/grade/ClassGradeController.java
  3. 15 0
      zhongzheng-api/src/main/java/com/zhongzheng/controller/cmmon/CommonController.java
  4. 13 0
      zhongzheng-api/src/main/java/com/zhongzheng/controller/wx/WxLoginController.java
  5. 29 0
      zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/SysTenantServiceImpl.java
  6. 5 0
      zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/UserServiceImpl.java
  7. 82 1
      zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/WxLoginService.java
  8. 1 1
      zhongzheng-system/src/main/java/com/zhongzheng/modules/grade/bo/OffGradeOrder.java
  9. 6 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/system/domain/SysTenant.java
  10. 6 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/system/service/ISysTenantService.java
  11. 16 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/system/vo/SysTenantLoginSignVo.java
  12. 3 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/tencentcloud/bo/FaceQueryBo.java
  13. 88 2
      zhongzheng-system/src/main/java/com/zhongzheng/modules/tencentcloud/service/impl/FaceOcrServiceImpl.java
  14. 2 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/user/bo/UserStudyRecordAddBo.java
  15. 3 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/user/bo/UserStudyRecordPhotoAddBo.java
  16. 34 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/user/domain/UserDeviceWhite.java
  17. 44 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/user/domain/UserPhotoDevice.java
  18. 2 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/user/domain/UserStudyRecordPhoto.java
  19. 14 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/user/mapper/UserDeviceWhiteMapper.java
  20. 13 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/user/mapper/UserPhotoDeviceMapper.java
  21. 15 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/user/service/IUserDeviceWhiteService.java
  22. 14 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/user/service/IUserPhotoDeviceService.java
  23. 2 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/user/service/IUserService.java
  24. 17 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/user/service/impl/UserDeviceWhiteServiceImpl.java
  25. 17 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/user/service/impl/UserPhotoDeviceServiceImpl.java
  26. 1 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/user/service/impl/UserStudyRecordServiceImpl.java
  27. 6 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/wx/bo/WxLoginBody.java

+ 79 - 0
run-prod.sh

@@ -1,3 +1,82 @@
+#!/usr/bin/env bash
+# 定义应用组名
+group_name='zhongzheng'
+# 定义应用名称
+app_name='zhongzheng-saas-api'
+# 定义应用版本
+app_version='1.0-SNAPSHOT'
+# 定义应用环境
+profile_active='prod'
+echo '----copy jar----'
+docker stop ${app_name}
+echo '----stop container----'
+docker rm ${app_name}
+echo '----rm container----'
+docker rmi ${group_name}/${app_name}:${app_version}
+echo '----rm image----'
+# 打包编译docker镜像
+docker build -f /mydata/maven/build/Dockerfile -t ${group_name}/${app_name}:${app_version} .
+echo '----build image----'
+docker run -p 5055:5055 --name ${app_name} \
+--restart=always \
+-e 'spring.profiles.active'=${profile_active} \
+-e TZ="Asia/Shanghai" \
+-m 10240m \
+--cpus=3 \
+--log-opt max-size=50m \
+--log-opt max-file=3 \
+-v /etc/localtime:/etc/localtime \
+-v /usr/share/fonts:/usr/share/fonts \
+-v /data/logs/prod_api:/logs \
+-v /mydata/app/${app_name}/logs:/var/logs \
+-d ${group_name}/${app_name}:${app_version}
+echo '----start container----'
+
+echo "开始等待20秒..."
+# 1-10秒内随机
+sleep 5
+echo "等待后继续"
+
+#!/usr/bin/env bash
+# 定义应用组名
+group_admin_name='zhongzheng'
+# 定义应用名称
+app_admin_name='zhongzheng-saas-admin'
+# 定义应用版本
+app_admin_version='1.0-SNAPSHOT'
+# 定义应用环境
+profile_active='prod'
+echo '----copy jar admin----'
+docker stop ${app_admin_name}
+echo '----stop container admin----'
+docker rm ${app_admin_name}
+echo '----rm container admin----'
+docker rmi ${group_admin_name}/${app_admin_name}:${app_admin_version}
+echo '----rm image admin----'
+# 打包编译docker镜像
+docker build -f /mydata/maven/build/Dockerfile-admi -t ${group_admin_name}/${app_admin_name}:${app_admin_version} .
+echo '----build image admin----'
+docker run \
+-p 5030:5030 \
+--name ${app_admin_name} \
+--restart=always \
+--log-opt max-size=50m \
+--log-opt max-file=3 \
+-e 'spring.profiles.active'=${profile_active} \
+-e TZ="Asia/Shanghai" \
+-v /etc/localtime:/etc/localtime \
+-v /usr/share/fonts:/usr/share/fonts \
+-v /data/logs/prod_admin:/logs \
+-v /mydata/app/${app_admin_name}/logs:/var/logs \
+-v /data/nginx/conf.d:/data/nginx/conf.d \
+-d ${group_admin_name}/${app_admin_name}:${app_admin_version}
+echo '----start container admin----'
+
+echo "开始等待20秒..."
+# 1-10秒内随机
+sleep 5
+echo "等待后继续"
+
 #!/usr/bin/env bash
 # 定义应用组名
 group_admin_name='zhongzheng'

+ 1 - 1
zhongzheng-admin/src/main/java/com/zhongzheng/controller/grade/ClassGradeController.java

@@ -904,7 +904,7 @@ public class ClassGradeController extends BaseController {
 
     @ApiOperation("关闭班级订单")
     @PostMapping("/off/order")
-    public AjaxResult<Integer> offGradeOrder(@RequestBody OffGradeOrder bo) {
+    public AjaxResult<Integer> offGradeOrder(OffGradeOrder bo) {
         return AjaxResult.success(iClassGradeService.offGradeOrder(bo));
     }
 

+ 15 - 0
zhongzheng-api/src/main/java/com/zhongzheng/controller/cmmon/CommonController.java

@@ -38,6 +38,7 @@ import com.zhongzheng.modules.order.domain.Printer;
 import com.zhongzheng.modules.system.bo.SysTenantQueryBo;
 import com.zhongzheng.modules.system.service.ISysConfigService;
 import com.zhongzheng.modules.system.service.ISysTenantService;
+import com.zhongzheng.modules.system.vo.SysTenantLoginSignVo;
 import com.zhongzheng.modules.user.bo.UserLiveAccountLoginBo;
 import com.zhongzheng.modules.user.service.IUserService;
 import com.zhongzheng.modules.user.vo.UserLiveAccountLoginVo;
@@ -430,4 +431,18 @@ public class CommonController extends BaseController {
         Long time = iCourseService.getLiveTime();
         return AjaxResult.success(time);
     }
+
+    @ApiOperation("获取系统登录标识")
+    @GetMapping("/login/sign")
+    public AjaxResult<SysTenantLoginSignVo> getSysLoginSign() {
+        SysTenantLoginSignVo sign = iSysTenantService.getSysLoginSign();
+        return AjaxResult.success(sign);
+    }
+
+    @ApiOperation("获取系统学前提示语")
+    @GetMapping("/prompt")
+    public AjaxResult<String> getSysStudyPrompt() {
+        String prompt = iSysTenantService.getSysStudyPrompt();
+        return AjaxResult.success("成功",prompt);
+    }
 }

+ 13 - 0
zhongzheng-api/src/main/java/com/zhongzheng/controller/wx/WxLoginController.java

@@ -196,4 +196,17 @@ public class WxLoginController
         return AjaxResult.success(map);
     }
 
+    /**
+     * 校验公众号openId是否存在
+     *
+     * @param loginBody 登公众号录信息
+     * @return 结果
+     */
+    @ApiOperation("校验公众号openId是否存在")
+    @PostMapping("/app/common/check/gzh_openId")
+    public AjaxResult checkGzh_openId(@RequestBody WxLoginBody loginBody)
+    {
+        Map<String,String> map = wxLoginService.checkGzh_openId(loginBody);
+        return AjaxResult.success(map);
+    }
 }

+ 29 - 0
zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/SysTenantServiceImpl.java

@@ -21,6 +21,7 @@ import com.zhongzheng.common.utils.ServletUtils;
 import com.zhongzheng.modules.order.domain.Order;
 import com.zhongzheng.modules.order.service.IOrderService;
 import com.zhongzheng.modules.system.bo.*;
+import com.zhongzheng.modules.system.domain.SysConfig;
 import com.zhongzheng.modules.system.domain.SysOldOrg;
 import com.zhongzheng.modules.system.domain.SysRoleMenu;
 import com.zhongzheng.modules.system.domain.SysTenant;
@@ -29,6 +30,7 @@ import com.zhongzheng.modules.system.mapper.SysTenantMapper;
 import com.zhongzheng.modules.system.service.*;
 import com.zhongzheng.modules.system.vo.SysTenantAccountVo;
 import com.zhongzheng.modules.system.vo.SysTenantBankAccountVo;
+import com.zhongzheng.modules.system.vo.SysTenantLoginSignVo;
 import com.zhongzheng.modules.system.vo.SysTenantVo;
 import com.zhongzheng.modules.top.goods.domain.TopOldOrder;
 import com.zhongzheng.modules.top.goods.service.ITopOldOrderService;
@@ -510,6 +512,33 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
         return baseMapper.getExamRoomTenant();
     }
 
+    @Override
+    public SysTenantLoginSignVo getSysLoginSign() {
+        String tenantId = ServletUtils.getRequest().getHeader("TenantId");
+        if (StringUtils.isBlank(tenantId)){
+            throw new CustomException("tenantId获取有误");
+        }
+        SysTenant tenant = getById(Long.valueOf(tenantId));
+        if (ObjectUtils.isNull(tenant)){
+            throw new CustomException("机构获取失败");
+        }
+        SysTenantLoginSignVo vo = new SysTenantLoginSignVo();
+        vo.setLoginSign(tenant.getLoginSign());
+        vo.setTelSign(tenant.getTelSign());
+        vo.setWxSign(tenant.getWxSign());
+        return vo;
+    }
+
+    @Override
+    public String getSysStudyPrompt() {
+        String tenantId = ServletUtils.getRequest().getHeader("TenantId");
+        SysConfig config = iSysConfigService.getOne(new LambdaQueryWrapper<SysConfig>()
+                .eq(SysConfig::getConfigKey, "sys.study.prompt")
+                .eq(SysConfig::getTenantId, tenantId)
+                .last("limit 1"));
+        return config.getConfigValue();
+    }
+
     private void initRoles(Long newTenantId,Long tenantId) {
         List<String> roleKey = new ArrayList<>();
         roleKey.add("seller");

+ 5 - 0
zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/UserServiceImpl.java

@@ -2236,6 +2236,11 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
         return baseMapper.getBusinessPhotoSign(orderGoodsId);
     }
 
+    @Override
+    public User getUserByGzhOpenId(String openId) {
+        return getOne(new LambdaQueryWrapper<User>().eq(User::getGzhOpenId,openId).last("limit 1"));
+    }
+
     @Override
     public Map<String, Object> accountLogin(UserAppAccountLoginBo bo) {
         if(Validator.isEmpty(bo.getAccount())){

+ 82 - 1
zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/WxLoginService.java

@@ -31,6 +31,7 @@ import com.zhongzheng.modules.goods.domain.Goods;
 import com.zhongzheng.modules.goods.service.IGoodsService;
 import com.zhongzheng.modules.goods.vo.GoodsVo;
 import com.zhongzheng.modules.grade.domain.ClassGradeUser;
+import com.zhongzheng.modules.system.domain.SysConfig;
 import com.zhongzheng.modules.system.domain.SysTenant;
 import com.zhongzheng.modules.system.service.ISysConfigService;
 import com.zhongzheng.modules.system.service.ISysTenantService;
@@ -51,6 +52,7 @@ import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
@@ -169,6 +171,9 @@ public class WxLoginService implements IWxLoginService {
     @Autowired
     private ISysTenantService iSysTenantService;
 
+    @Autowired
+    private ISysConfigService iSysConfigService;
+
     private final String KEY_PREFIX = "GOODS_SHARE";
 
     public void initData(){
@@ -199,7 +204,8 @@ public class WxLoginService implements IWxLoginService {
         String scanCode = ToolsUtils.getCharAndNumr(6);
         String key = "SCAN_LOGIN_" + scanCode;
         String keyStatus = "SCAN_LOGIN_STATUS_" + scanCode; //0未扫码 1已扫码 2已登录
-        String codeUrl = scanLoginHost + "pc/login/" + scanCode;
+//        String codeUrl = scanLoginHost + "pc/login/" + scanCode;
+        String codeUrl = scanLoginHost + "pages4/login/pcLogin?q=" + scanCode;
         String urlBase64 = null;
         try {
             QRCodeWriter qrCodeWriter = new QRCodeWriter();
@@ -1517,4 +1523,79 @@ public class WxLoginService implements IWxLoginService {
         }
         return vo;
     }
+
+    public Map<String, String> checkGzh_openId(WxLoginBody loginBody) {
+        initData();
+        Map<String, String> map = new HashMap<>();
+        String param = String.format(gzh_wxAuthParam, gzh_appid, gzh_appsrcret, loginBody.getCode());
+        String resultString = HttpUtils.sendGet(gzh_wxAuthUrl, param);
+        //解析json
+        JSONObject jsonObject = (JSONObject) JSONObject.parse(resultString);
+        String access_token = String.valueOf(jsonObject.get("access_token"));
+        if(access_token.equals("null")){
+            throw new CustomException( String.valueOf(jsonObject.get("errmsg")));
+        }
+        String openId = String.valueOf(jsonObject.get("openid"));
+        //通过域名获取商户ID
+        SysConfig config = iSysConfigService.getOne(new LambdaQueryWrapper<SysConfig>()
+                .eq(SysConfig::getConfigValue, scanLoginHost)
+                .eq(SysConfig::getConfigKey, "wx.scanLogin.host")
+                .last("limit 1"));
+        if (ObjectUtils.isNull(config)){
+            throw new CustomException("域名配置获取失败,请检查!");
+        }
+        ServletUtils.getResponse().setHeader("TenantId",config.getTenantId().toString());
+        if (StringUtils.isNotBlank(loginBody.getAccount()) && StringUtils.isNotBlank(loginBody.getPassword())){
+            LambdaQueryWrapper<User> queryWrapper =new LambdaQueryWrapper<User>();
+            queryWrapper.and(wq -> wq
+                    .eq(User::getTelphone,EncryptHandler.encrypt(loginBody.getAccount()))
+                    .or()
+                    .eq(User::getIdCard,EncryptHandler.encrypt(loginBody.getAccount())));
+            User user = iUserService.getOne(queryWrapper);
+            if (ObjectUtils.isNull(user)){
+                throw new CustomException("登入信息有误,请检查账号或者密码!");
+            }
+            String password = null;
+            if(loginBody.getPassword().length()>20){
+                String rsaPrivate = null;
+                try {
+                    InputStream certStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("config/pri.key");
+                    rsaPrivate = AES.getStringByInputStream_1(certStream);
+                    certStream.close();
+                    password = AES.decrypt(loginBody.getPassword(),rsaPrivate);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }else{
+                password = loginBody.getPassword();
+            }
+            if (!SecurityUtils.matchesPassword(password,user.getPassword()))
+            {
+                throw new CustomException("登入信息有误,请检查账号或者密码!");
+            }
+            //校验公众号openId
+            if (StringUtils.isNotBlank(user.getGzhOpenId()) && !user.getGzhOpenId().equals(openId)){
+                throw new CustomException("该账号已绑定微信,请使用绑定微信扫码登入");
+            }
+            //登入和补充公众号openId
+            user.setGzhOpenId(openId);
+            iUserService.updateById(user);
+            ClientLoginUser loginUser = new ClientLoginUser();
+            loginUser.setUser(user);
+            map.put(Constants.TOKEN, wxTokenService.createToken(loginUser));
+            map.put("gzhStatus", "1");
+            return map;
+        }
+        //校验公众号openId
+        User user = iUserService.getUserByGzhOpenId(openId);
+        if (ObjectUtils.isNull(user)){
+            map.put("gzhStatus", "0");
+            return map;
+        }
+        ClientLoginUser loginUser = new ClientLoginUser();
+        loginUser.setUser(user);
+        map.put(Constants.TOKEN, wxTokenService.createToken(loginUser));
+        map.put("gzhStatus", "1");
+        return map;
+    }
 }

+ 1 - 1
zhongzheng-system/src/main/java/com/zhongzheng/modules/grade/bo/OffGradeOrder.java

@@ -10,5 +10,5 @@ public class OffGradeOrder implements Serializable {
     private Long gradeId;
 
     private Long userId;
+}
 
-}

+ 6 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/system/domain/SysTenant.java

@@ -125,4 +125,10 @@ private static final long serialVersionUID=1L;
     private Integer studentRestudy;
     /** 学员密码默认更改天数*/
     private Integer pwdCheckTime;
+    /** 账号密码登录标识:1隐藏 0显示*/
+    private Integer loginSign;
+    /** 微信登录标识:1隐藏 0显示 */
+    private Integer wxSign;
+    /** 手机验证码登录标识:1隐藏 0显示 */
+    private Integer telSign;
 }

+ 6 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/system/service/ISysTenantService.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.zhongzheng.modules.system.bo.*;
 import com.zhongzheng.modules.system.domain.SysTenant;
 import com.zhongzheng.modules.system.vo.SysTenantBankAccountVo;
+import com.zhongzheng.modules.system.vo.SysTenantLoginSignVo;
 import com.zhongzheng.modules.system.vo.SysTenantVo;
 
 import java.util.Collection;
@@ -73,4 +74,9 @@ public interface ISysTenantService extends IService<SysTenant> {
     List<SysTenant> getListNoTenant(Long tenantId);
 
 	List<SysTenant> getExamRoomTenant();
+
+    SysTenantLoginSignVo getSysLoginSign();
+
+	String getSysStudyPrompt();
+
 }

+ 16 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/system/vo/SysTenantLoginSignVo.java

@@ -0,0 +1,16 @@
+package com.zhongzheng.modules.system.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class SysTenantLoginSignVo implements Serializable {
+
+    /** 账号密码登录标识:1隐藏 0显示*/
+    private Integer loginSign;
+    /** 微信登录标识:1隐藏 0显示 */
+    private Integer wxSign;
+    /** 手机验证码登录标识:1隐藏 0显示 */
+    private Integer telSign;
+}

+ 3 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/tencentcloud/bo/FaceQueryBo.java

@@ -56,4 +56,7 @@ public class FaceQueryBo extends BaseEntity {
 
 	@ApiModelProperty("一寸照图片base64")
 	private String oneInchPhotos;
+
+	@ApiModelProperty("设备名称")
+	private String deviceName;
 }

+ 88 - 2
zhongzheng-system/src/main/java/com/zhongzheng/modules/tencentcloud/service/impl/FaceOcrServiceImpl.java

@@ -3,7 +3,9 @@ package com.zhongzheng.modules.tencentcloud.service.impl;
 
 import cn.hutool.core.lang.Validator;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.tencentcloudapi.bda.v20200324.models.SegmentPortraitPicRequest;
 import com.tencentcloudapi.common.Credential;
 import com.tencentcloudapi.common.exception.TencentCloudSDKException;
@@ -16,6 +18,7 @@ import com.tencentcloudapi.iai.v20200303.models.*;
 import com.tencentcloudapi.ocr.v20181119.OcrClient;
 import com.tencentcloudapi.ocr.v20181119.models.*;
 import com.zhongzheng.common.exception.CustomException;
+import com.zhongzheng.common.utils.DateUtils;
 import com.zhongzheng.modules.alioss.bo.OssRequest;
 import com.zhongzheng.modules.alioss.service.OssService;
 import com.zhongzheng.modules.base.bo.UserProfileFit;
@@ -25,6 +28,10 @@ import com.zhongzheng.modules.base.vo.UserProfileVo;
 import com.zhongzheng.modules.tencentcloud.bo.FaceQueryBo;
 import com.zhongzheng.modules.tencentcloud.bo.InvoiceQueryBo;
 import com.zhongzheng.modules.tencentcloud.service.IFaceOcrService;
+import com.zhongzheng.modules.user.domain.UserDeviceWhite;
+import com.zhongzheng.modules.user.domain.UserPhotoDevice;
+import com.zhongzheng.modules.user.service.IUserDeviceWhiteService;
+import com.zhongzheng.modules.user.service.IUserPhotoDeviceService;
 import com.zhongzheng.modules.user.service.IUserService;
 import com.zhongzheng.modules.user.vo.UserVo;
 import org.slf4j.Logger;
@@ -35,6 +42,8 @@ import org.springframework.stereotype.Service;
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 @Service
 public class FaceOcrServiceImpl implements IFaceOcrService {
@@ -54,6 +63,12 @@ public class FaceOcrServiceImpl implements IFaceOcrService {
     @Autowired
     private IUserService iUserService;
 
+    @Autowired
+    private IUserPhotoDeviceService iUserPhotoDeviceService;
+
+    @Autowired
+    private IUserDeviceWhiteService iUserDeviceWhiteService;
+
     @Autowired
     private IUserProfileService iUserProfileService;
 
@@ -73,6 +88,10 @@ public class FaceOcrServiceImpl implements IFaceOcrService {
             if(Validator.isEmpty(userVo)){
                 return 0;
             }
+            //照相设备校验
+            if (StringUtils.isNotBlank(bo.getDeviceName())){
+                deviceCheck(bo);
+            }
            /* UserProfileQueryBo userProfileQueryBo = new UserProfileQueryBo();
             userProfileQueryBo.setUserId(bo.getUserId());
             userProfileQueryBo.setOrderGoodsId(bo.getOrderGoodsId());
@@ -86,8 +105,9 @@ public class FaceOcrServiceImpl implements IFaceOcrService {
     //        Map<String, String> maps = JSONObject.parseObject(info.getKeyValue(),Map.class);
 
     //        String oneInchPhotos = JSONObject.parseObject(String.valueOf(maps.get("recent_photos")), UserProfileFit.class).getValue(); //审核资料一寸照片
-
             if(DetectFace(bo)){
+                //活体检测
+                detectLiveFaceCheck(bo);
                 String oneInchPhotos =ossHost+"/"+userVo.getOneInchPhotos();
                 Credential cred = new Credential(SecretId, SecretKey);
                 ClientProfile clientProfile = new ClientProfile();
@@ -103,6 +123,7 @@ public class FaceOcrServiceImpl implements IFaceOcrService {
                 faceRequest.setQualityControl(2L);
                 CompareFaceResponse response = iaiClient.CompareFace(faceRequest);
                 if (response.getScore().intValue() < 65){
+                    addUserPhotoRecord(bo.getUserId(),bo.getUrlA(),bo.getOrderGoodsId(),4,bo.getDeviceName());
                     throw new CustomException("人脸识别不通过,请重新拍照!",606);
                 }
                 return response.getScore().intValue();
@@ -114,6 +135,70 @@ public class FaceOcrServiceImpl implements IFaceOcrService {
         }
     }
 
+    private void detectLiveFaceCheck(FaceQueryBo bo) {
+        Credential cred = new Credential(SecretId, SecretKey);
+        ClientProfile clientProfile = new ClientProfile();
+        clientProfile.setSignMethod(clientProfile.SIGN_TC3_256);
+        IaiClient iaiClient = new IaiClient(cred,"ap-guangzhou");
+        DetectLiveFaceRequest faceRequest = new DetectLiveFaceRequest();
+        if(Validator.isNotEmpty(bo.getUrlA())){
+            faceRequest.setUrl(ossHost+"/"+bo.getUrlA());
+        }else{
+            faceRequest.setImage(bo.getImageA()); //学习拍照
+        }
+        try {
+            DetectLiveFaceResponse response = iaiClient.DetectLiveFace(faceRequest);
+            if (response.getScore().intValue() < 87){
+                addUserPhotoRecord(bo.getUserId(),bo.getUrlA(),bo.getOrderGoodsId(),3,bo.getDeviceName());
+                throw new CustomException("活体检测不通过,请重新拍照!",606);
+            }
+        }catch (TencentCloudSDKException e){
+            throw new CustomException(e.getMessage(),606);
+        }
+
+    }
+
+    //保存学员拍照错误记录
+    private void addUserPhotoRecord(Long userId,String photo,Long orderGoodsId,Integer type,String deviceName){
+        UserPhotoDevice add = new UserPhotoDevice();
+        add.setUserId(userId);
+        add.setPhoto(photo);
+        add.setOrderGoodsId(orderGoodsId);
+        add.setType(type);
+        add.setDeviceName(deviceName);
+        add.setCreateTime(DateUtils.getNowTime());
+        add.setUpdateTime(DateUtils.getNowTime());
+        iUserPhotoDeviceService.save(add);
+    }
+
+
+    private void deviceCheck(FaceQueryBo bo) {
+        //校验白黑名单
+        UserDeviceWhite deviceWhite = iUserDeviceWhiteService.getOne(new LambdaQueryWrapper<UserDeviceWhite>()
+                .eq(UserDeviceWhite::getUserId, bo.getUserId())
+                .eq(UserDeviceWhite::getDeviceName, bo.getDeviceName()));
+        if (ObjectUtils.isNotNull(deviceWhite)){
+            if (deviceWhite.getStatus() == 1){
+                //白名单
+                return;
+            }
+            if (deviceWhite.getStatus() == 2){
+                //黑名单
+                addUserPhotoRecord(bo.getUserId(),bo.getUrlA(),bo.getOrderGoodsId(),1, bo.getDeviceName());
+                throw new CustomException("您有疑是使用虚拟摄像头学习,请更换高清摄像头设备或手机学习!",606);
+            }
+        }
+
+        //正则校验设备名称
+        String reg_select = "([a-zA-Z0-9_ ]+)\\(([a-zA-Z0-9]+)[:]+([a-zA-Z0-9]+)\\)";
+        Pattern pattern = Pattern.compile(reg_select);
+        Matcher matcher = pattern.matcher(bo.getDeviceName());
+        if (!matcher.matches()){
+            addUserPhotoRecord(bo.getUserId(),bo.getUrlA(),bo.getOrderGoodsId(),1, bo.getDeviceName());
+            throw new CustomException("您有疑是使用虚拟摄像头学习,请更换高清摄像头设备或手机学习!",606);
+        }
+    }
+
     @Override
     public Boolean DetectFace(FaceQueryBo bo) {
         try{
@@ -187,7 +272,8 @@ public class FaceOcrServiceImpl implements IFaceOcrService {
                     throw new CustomException("请保证人脸全部在照片范围内!");
                 }
             }
-        }catch (TencentCloudSDKException e){
+        }catch (Exception e){
+            addUserPhotoRecord(bo.getUserId(),bo.getUrlA(),bo.getOrderGoodsId(),2, bo.getDeviceName());
             throw new CustomException("人脸检测错误:"+e.getMessage());
         }
         return true;

+ 2 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/user/bo/UserStudyRecordAddBo.java

@@ -92,5 +92,7 @@ public class UserStudyRecordAddBo {
     /** 相似度 */
     @ApiModelProperty("相似度")
     private Integer similarity;
+    @ApiModelProperty("设备名称")
+    private String deviceName;
     private Boolean erJianErZao;
 }

+ 3 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/user/bo/UserStudyRecordPhotoAddBo.java

@@ -47,4 +47,7 @@ public class UserStudyRecordPhotoAddBo {
     @ApiModelProperty("相似度")
     private Integer similarity;
 
+    @ApiModelProperty("设备名称")
+    private String deviceName;
+
 }

+ 34 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/user/domain/UserDeviceWhite.java

@@ -0,0 +1,34 @@
+package com.zhongzheng.modules.user.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * 用户学习记录对象 user_photo_device
+ *
+ * @author ruoyi
+ * @date 2021-12-16
+ */
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("user_device_white")
+public class UserDeviceWhite implements Serializable {
+
+    @TableId(value = "id")
+    private Long id;
+    /** 用户ID */
+    private Long userId;
+    /**  设备名称 */
+    private String deviceName;
+    /**  状态:1白名单 2黑名单 */
+    private Integer status;
+    /**  商户ID */
+    private Long tenantId;
+
+}

+ 44 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/user/domain/UserPhotoDevice.java

@@ -0,0 +1,44 @@
+package com.zhongzheng.modules.user.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * 用户学习记录对象 user_photo_device
+ *
+ * @author ruoyi
+ * @date 2021-12-16
+ */
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("user_photo_device")
+public class UserPhotoDevice implements Serializable {
+
+    @TableId(value = "id")
+    private Long id;
+    /** 用户ID */
+    private Long userId;
+    /** 订单商品ID */
+    private Long orderGoodsId;
+    /**  拍摄照片 */
+    private String photo;
+    /**  设备名称 */
+    private String deviceName;
+    /** 创建时间 */
+    private Long createTime;
+    /** 修改时间 */
+    private Long updateTime;
+    /** 类型 1拍照设备不过关 2人脸属性检测不过关 3人脸活体检测不过关 4人脸对比不过关 */
+    private Integer type;
+    /** 状态:1正常 0废弃 */
+    private Integer status;
+    /** 修改时间 */
+    private Long tenantId;
+
+}

+ 2 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/user/domain/UserStudyRecordPhoto.java

@@ -46,4 +46,6 @@ private static final long serialVersionUID=1L;
 
     /** 相似度 */
     private Integer similarity;
+    /** 设备名称 */
+    private String deviceName;
 }

+ 14 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/user/mapper/UserDeviceWhiteMapper.java

@@ -0,0 +1,14 @@
+package com.zhongzheng.modules.user.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhongzheng.modules.user.domain.UserDeviceWhite;
+import com.zhongzheng.modules.user.domain.UserPhotoDevice;
+
+/**
+ * 学习计划Mapper接口
+ *
+ * @author ruoyi
+ * @date 2021-12-08
+ */
+public interface UserDeviceWhiteMapper extends BaseMapper<UserDeviceWhite> {
+}

+ 13 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/user/mapper/UserPhotoDeviceMapper.java

@@ -0,0 +1,13 @@
+package com.zhongzheng.modules.user.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhongzheng.modules.user.domain.UserPhotoDevice;
+
+/**
+ * 学习计划Mapper接口
+ *
+ * @author ruoyi
+ * @date 2021-12-08
+ */
+public interface UserPhotoDeviceMapper extends BaseMapper<UserPhotoDevice> {
+}

+ 15 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/user/service/IUserDeviceWhiteService.java

@@ -0,0 +1,15 @@
+package com.zhongzheng.modules.user.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhongzheng.modules.user.domain.UserDeviceWhite;
+import com.zhongzheng.modules.user.domain.UserPhotoDevice;
+
+/**
+ * 高校Service接口
+ *
+ * @author ruoyi
+ * @date 2021-10-09
+ */
+public interface IUserDeviceWhiteService extends IService<UserDeviceWhite> {
+
+}

+ 14 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/user/service/IUserPhotoDeviceService.java

@@ -0,0 +1,14 @@
+package com.zhongzheng.modules.user.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhongzheng.modules.user.domain.UserPhotoDevice;
+
+/**
+ * 高校Service接口
+ *
+ * @author ruoyi
+ * @date 2021-10-09
+ */
+public interface IUserPhotoDeviceService extends IService<UserPhotoDevice> {
+
+}

+ 2 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/user/service/IUserService.java

@@ -177,4 +177,6 @@ public interface IUserService extends IService<User> {
 
 	Integer getBusinessPhotoSign(Long orderGoodsId);
 
+	User getUserByGzhOpenId(String openId);
+
 }

+ 17 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/user/service/impl/UserDeviceWhiteServiceImpl.java

@@ -0,0 +1,17 @@
+package com.zhongzheng.modules.user.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhongzheng.modules.user.domain.UserDeviceWhite;
+import com.zhongzheng.modules.user.mapper.UserDeviceWhiteMapper;
+import com.zhongzheng.modules.user.service.IUserDeviceWhiteService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 用户笔记记录Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2021-12-14
+ */
+@Service
+public class UserDeviceWhiteServiceImpl extends ServiceImpl<UserDeviceWhiteMapper, UserDeviceWhite> implements IUserDeviceWhiteService {
+}

+ 17 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/user/service/impl/UserPhotoDeviceServiceImpl.java

@@ -0,0 +1,17 @@
+package com.zhongzheng.modules.user.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhongzheng.modules.user.domain.UserPhotoDevice;
+import com.zhongzheng.modules.user.mapper.UserPhotoDeviceMapper;
+import com.zhongzheng.modules.user.service.IUserPhotoDeviceService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 用户笔记记录Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2021-12-14
+ */
+@Service
+public class UserPhotoDeviceServiceImpl extends ServiceImpl<UserPhotoDeviceMapper, UserPhotoDevice> implements IUserPhotoDeviceService {
+}

+ 1 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/user/service/impl/UserStudyRecordServiceImpl.java

@@ -1877,6 +1877,7 @@ public class UserStudyRecordServiceImpl extends ServiceImpl<UserStudyRecordMappe
             userStudyRecordPhotoAddBo.setPeriodId(periodId);
             userStudyRecordPhotoAddBo.setStatus(1);
             userStudyRecordPhotoAddBo.setUserId(entity.getUserId());
+            userStudyRecordPhotoAddBo.setDeviceName(bo.getDeviceName());
             if(Validator.isEmpty(bo.getSimilarity())){
                 throw new CustomException("相似度缺失");
             }

+ 6 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/wx/bo/WxLoginBody.java

@@ -65,4 +65,10 @@ public class WxLoginBody {
 
     @ApiModelProperty("小程序openId")
     private String openId;
+
+    @ApiModelProperty("账号")
+    private String account;
+
+    @ApiModelProperty("密码")
+    private String password;
 }