Sfoglia il codice sorgente

fix(h5): 身份识别

Go 4 anni fa
parent
commit
2e537dc589

+ 1 - 1
front/project/admin/stores/user.js

@@ -5,7 +5,7 @@ export default class UserStore extends BaseStore {
     this.token({ id })
       .then(token => {
         const w = window.open('about:blank');
-        w.location.href = `${url}?token=${token}`;
+        w.location.href = `${url}?token=${encodeURIComponent(token)}`;
       });
   }
 

+ 23 - 18
front/project/h5/routes/page/identity/page.js

@@ -22,6 +22,7 @@ export default class extends Page {
   }
 
   submitFront() {
+    const self = this;
     if (this.wx) {
       this.wx.chooseImage({
         count: 1, // 默认9
@@ -41,11 +42,11 @@ export default class extends Page {
                 // 此时一个正常的base64图片路径就完美生成赋值到img的src中了
                 imageBase64 = `data:image/jpeg;base64,${localData.replace(/\n/g, '')}`;
               }
-              this.setState({ front: imageBase64 });
-              My.realFront(new File(dataURLtoBlob(imageBase64), 'front.jpg', { type: 'image/jpeg' }))
+              self.setState({ front: imageBase64 });
+              My.realFront(new File([dataURLtoBlob(imageBase64)], 'front.jpg'))
                 .then(() => {
-                  this.back = true;
-                  this.submit();
+                  self.front = true;
+                  self.submit();
                 })
                 .catch(err => {
                   asyncSMessage(err.message, 'error');
@@ -58,6 +59,7 @@ export default class extends Page {
   }
 
   submitBack() {
+    const self = this;
     if (this.wx) {
       this.wx.chooseImage({
         count: 1, // 默认9
@@ -77,13 +79,11 @@ export default class extends Page {
                 // 此时一个正常的base64图片路径就完美生成赋值到img的src中了
                 imageBase64 = `data:image/jpeg;base64,${localData.replace(/\n/g, '')}`;
               }
-              this.setState({ back: imageBase64 });
-              dataURLtoBlob(imageBase64);
-
-              My.realBack(new File(dataURLtoBlob(imageBase64), 'back.jpg', { type: 'image/jpeg' }))
+              self.setState({ back: imageBase64 });
+              My.realBack(new File([dataURLtoBlob(imageBase64)], 'back.jpg'))
                 .then(() => {
-                  this.back = true;
-                  this.submit();
+                  self.back = true;
+                  self.submit();
                 })
                 .catch(err => {
                   asyncSMessage(err.message, 'error');
@@ -113,22 +113,26 @@ export default class extends Page {
           千行将重视和保护您的隐私。
         </div>
         <div className="id-card-1">
-          <Assets name="IDcard" />
           <Assets
-            className="scan"
             src={this.state.front}
-            name="scan1"
+            name={this.state.front ? '' : 'IDcard'}
+          />
+          <Assets
+            className="scan"
+            name='scan1'
             onClick={() => {
               this.submitFront();
             }}
           />
         </div>
         <div className="id-card-2">
-          <Assets name="IDcard2" />
           <Assets
-            className="scan"
             src={this.state.back}
-            name="scan2"
+            name={this.state.back ? '' : 'IDcard2'}
+          />
+          <Assets
+            className="scan"
+            name='scan2'
             onClick={() => {
               this.submitBack();
             }}
@@ -139,7 +143,8 @@ export default class extends Page {
   }
 
   renderFinish() {
-    const { data } = this.state;
+    const { data = {} } = this.state;
+    const { record } = data;
     return (
       <div className="finish">
         <div className="icon">
@@ -147,7 +152,7 @@ export default class extends Page {
         </div>
         <div className="title">认证完成!</div>
         <div className="desc">90天VIP权限已赠送至您的账户</div>
-        <div className="desc">生效时间:{data.useStartTime && formatDate(data.useStartTime, 'YYYY-MM-DD')}</div>
+        <div className="desc">生效时间:{record.useStartTime && formatDate(record.useStartTime, 'YYYY-MM-DD')}</div>
       </div>
     );
   }

+ 2 - 2
front/project/h5/stores/common.js

@@ -35,14 +35,14 @@ export default class CommonStore extends BaseStore {
 
   readyWechat(url, list) {
     return this.apiGet('/common/wechat/ticket').then(ticket => {
-      const time = new Date().getTime() / 1000;
+      const time = parseInt(new Date().getTime() / 1000, 10);
       const nonce = generateUUID(6, 10);
       const p = `jsapi_ticket=${ticket}&noncestr=${nonce}&timestamp=${time}&url=${url.split('#')[0]}`;
       const a = list.map(row => row);
       a.push('checkJsApi');
       wx.config({
         debug: false, // 是否打开调试模式,调用的api会被alert出来,在pc端也能看到log信息
-        appid: WechatH5AppId, // 必填,微信公众号的唯一标识
+        appId: WechatH5AppId, // 必填,微信公众号的唯一标识
         timestamp: time, // 必填,生成签名的时间戳
         nonceStr: nonce, // 必填,生成签名的随机串
         signature: sha1(p), // 必填,用于验证的签名

+ 5 - 4
front/project/www/routes/my/main/page.js

@@ -32,7 +32,7 @@ class LogItem extends Component {
       { title: '逻辑CR', key: 'cr' },
       { title: '阅读RC', key: 'rc' },
     ];
-    this.state = { open: false };
+    this.state = { open: false, showTop: true };
   }
 
   render() {
@@ -380,9 +380,10 @@ export default class extends Page {
 
   renderTop() {
     const { info } = this.props.user;
-    return !info.bindPrepare && <div className="top-layout">
-      <Assets name='my_main_banner' />
-      <div className='close' />
+    const { showTop } = this.state;
+    return !info.bindPrepare && showTop && <div className="top-layout">
+      <Assets name='my_main_banner' onClick={() => this.setState({ showExamination: true })} />
+      <div className='close' onClick={() => this.setState({ showTop: false })} />
       <div className='go' onClick={() => this.setState({ showExamination: true })} />
     </div>;
   }

+ 6 - 0
server/gateway-api/src/main/java/com/qxgmat/controller/api/AuthController.java

@@ -142,6 +142,9 @@ public class AuthController {
             throw new ParameterException("登录失败");
         }
         User openUser = (User) shiroHelp.getLoginUser();
+        if (openUser.getId() != null && openUser.getId() > 0){
+            shiroHelp.getSession().login(shiroHelp.user(openUser.getArea()+":"+openUser.getMobile(), ""));
+        }
         MyDto dto = processUser(openUser, request);
         return ResponseHelp.success(dto);
     }
@@ -161,6 +164,9 @@ public class AuthController {
             throw new ParameterException("登录失败");
         }
         User openUser = (User) shiroHelp.getLoginUser();
+        if (openUser.getId() != null && openUser.getId() > 0){
+            shiroHelp.getSession().login(shiroHelp.user(openUser.getArea()+":"+openUser.getMobile(), ""));
+        }
         MyDto dto = processUser(openUser, request);
         return ResponseHelp.success(dto);
     }

+ 23 - 16
server/gateway-api/src/main/java/com/qxgmat/controller/api/MyController.java

@@ -276,7 +276,7 @@ public class MyController {
         return ResponseHelp.success(true);
     }
 
-    @RequestMapping(value = "/real/front", produces = MediaType.IMAGE_JPEG_VALUE, method = RequestMethod.POST)
+    @RequestMapping(value = "/real/front", method = RequestMethod.POST)
     @ApiOperation(value = "实名认证", notes = "保存用户实名信息", httpMethod = "POST")
     public Response<UserRealDto> realFront(@RequestParam("file") MultipartFile file) throws IOException {
         if (file.isEmpty()) {
@@ -291,14 +291,17 @@ public class MyController {
         dto.setIdentity(map.get("identity"));
 
         User in = usersService.getByIdentity(map.get("identity"));
-        if (in != null){
+        if (in != null && !in.getId().equals(user.getId())){
             throw new ParameterException("该身份证已被其他账号认证");
         }
 
-        String frontName = UUID.randomUUID().toString();
+        String filename = file.getOriginalFilename();
+        String suffix = filename.substring(filename.lastIndexOf(".")+1);
+        String frontName = UUID.randomUUID().toString()+"."+suffix;
         try {
-            File frontDest = new File(localPath + File.separator+frontName);
-            file.transferTo(frontDest);
+            File dir = new File(localPath);
+            File dest = new File(dir.getAbsolutePath() + File.separator+frontName);
+            file.transferTo(dest);
             dto.setPhotoFront(webUrl+frontName);
             usersService.edit(User.builder()
                     .id(user.getId())
@@ -314,7 +317,7 @@ public class MyController {
         }
     }
 
-    @RequestMapping(value = "/real/back", produces = MediaType.IMAGE_JPEG_VALUE, method = RequestMethod.POST)
+    @RequestMapping(value = "/real/back", method = RequestMethod.POST)
     @ApiOperation(value = "实名认证", notes = "保存用户实名信息", httpMethod = "POST")
     public Response<UserRealDto> realBack(@RequestParam("file") MultipartFile file) throws IOException {
         if (file.isEmpty()) {
@@ -324,10 +327,13 @@ public class MyController {
         UserRealDto dto = new UserRealDto();
 
         aiHelp.orcIdcardBack(file.getBytes());
-        String backName = UUID.randomUUID().toString();
+        String filename = file.getOriginalFilename();
+        String suffix = filename.substring(filename.lastIndexOf(".")+1);
+        String backName = UUID.randomUUID().toString()+"."+suffix;
         try {
-            File backDest = new File(localPath + File.separator+backName);
-            file.transferTo(backDest);
+            File dir = new File(localPath);
+            File dest = new File(dir.getAbsolutePath() + File.separator+backName);
+            file.transferTo(dest);
             dto.setPhotoBack(webUrl+backName);
             usersService.edit(User.builder()
                     .id(user.getId())
@@ -340,26 +346,26 @@ public class MyController {
         }
     }
 
-    @RequestMapping(value = "/real/finish", produces = MediaType.IMAGE_JPEG_VALUE, method = RequestMethod.POST)
+    @RequestMapping(value = "/real/finish", method = RequestMethod.POST)
     @ApiOperation(value = "实名认证", notes = "保存用户实名信息", httpMethod = "POST")
     public Response<UserRealDto> realFinish() {
         User user = (User) shiroHelp.getLoginUser();
         UserRealDto dto = new UserRealDto();
 
         User in = usersService.get(user.getId());
-        if (in.getRealAddress() == null || !in.getRealAddress().equals("")){
+        if (in.getRealAddress() == null || in.getRealAddress().equals("")){
             throw new ParameterException("实名认证流程错误");
         }
-        if (in.getRealIdentity() == null || !in.getRealIdentity().equals("")){
+        if (in.getRealIdentity() == null || in.getRealIdentity().equals("")){
             throw new ParameterException("实名认证流程错误");
         }
-        if (in.getRealName() == null || !in.getRealName().equals("")){
+        if (in.getRealName() == null || in.getRealName().equals("")){
             throw new ParameterException("实名认证流程错误");
         }
-        if (in.getRealPhotoFront() == null || !in.getRealPhotoFront().equals("")){
+        if (in.getRealPhotoFront() == null || in.getRealPhotoFront().equals("")){
             throw new ParameterException("实名认证流程错误");
         }
-        if (in.getRealPhotoBack() == null || !in.getRealPhotoBack().equals("")){
+        if (in.getRealPhotoBack() == null || in.getRealPhotoBack().equals("")){
             throw new ParameterException("实名认证流程错误");
         }
 
@@ -368,7 +374,8 @@ public class MyController {
                 .realStatus(1)
                 .realTime(new Date())
                 .build());
-        orderFlowService.giveReal(in);
+        UserOrderRecord record = orderFlowService.giveReal(in);
+        dto.setRecord(Transform.convert(record, UserOrderRecordExtendDto.class));
         return ResponseHelp.success(dto);
     }
 

+ 61 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserOrderRecordExtendDto.java

@@ -4,6 +4,7 @@ package com.qxgmat.dto.extend;
 import com.alibaba.fastjson.JSONObject;
 
 import java.math.BigDecimal;
+import java.util.Date;
 import java.util.List;
 
 public class UserOrderRecordExtendDto {
@@ -39,6 +40,18 @@ public class UserOrderRecordExtendDto {
 
     private JSONObject serviceInfo;
 
+    private Date startTime;
+
+    private Date endTime;
+
+    private Date useStartTime;
+
+    private Date useEndTime;
+
+    private Integer isUsed;
+
+    private Date useTime;
+
     private List<UserOrderRecordExtendDto> children;
 
     public String getProductType() {
@@ -176,4 +189,52 @@ public class UserOrderRecordExtendDto {
     public void setOrderId(Integer orderId) {
         this.orderId = orderId;
     }
+
+    public Date getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(Date startTime) {
+        this.startTime = startTime;
+    }
+
+    public Date getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(Date endTime) {
+        this.endTime = endTime;
+    }
+
+    public Date getUseStartTime() {
+        return useStartTime;
+    }
+
+    public void setUseStartTime(Date useStartTime) {
+        this.useStartTime = useStartTime;
+    }
+
+    public Date getUseEndTime() {
+        return useEndTime;
+    }
+
+    public void setUseEndTime(Date useEndTime) {
+        this.useEndTime = useEndTime;
+    }
+
+    public Integer getIsUsed() {
+        return isUsed;
+    }
+
+    public void setIsUsed(Integer isUsed) {
+        this.isUsed = isUsed;
+    }
+
+    public Date getUseTime() {
+        return useTime;
+    }
+
+    public void setUseTime(Date useTime) {
+        this.useTime = useTime;
+    }
 }

+ 11 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/response/UserRealDto.java

@@ -2,6 +2,7 @@ package com.qxgmat.dto.response;
 
 import com.nuliji.tools.annotation.Dto;
 import com.qxgmat.data.dao.entity.User;
+import com.qxgmat.dto.extend.UserOrderRecordExtendDto;
 import io.swagger.annotations.ApiModelProperty;
 
 /**
@@ -24,6 +25,8 @@ public class UserRealDto {
     @ApiModelProperty(value = "身份照片-反面", required = true)
     private String photoBack = "";
 
+    private UserOrderRecordExtendDto record;
+
     public String getIdentity() {
         return identity;
     }
@@ -63,4 +66,12 @@ public class UserRealDto {
     public void setPhotoBack(String photoBack) {
         this.photoBack = photoBack;
     }
+
+    public UserOrderRecordExtendDto getRecord() {
+        return record;
+    }
+
+    public void setRecord(UserOrderRecordExtendDto record) {
+        this.record = record;
+    }
 }

+ 6 - 3
server/gateway-api/src/main/java/com/qxgmat/service/extend/OrderFlowService.java

@@ -1092,7 +1092,7 @@ public class OrderFlowService {
      * 给用户邀请奖励: 7天vip
      * @param user
      */
-    public void giveInvite(User user){
+    public UserOrderRecord giveInvite(User user){
         UserOrderRecord record = UserOrderRecord.builder()
                 .userId(user.getId())
                 .productType(ProductType.SERVICE.key)
@@ -1106,13 +1106,14 @@ public class OrderFlowService {
         record = initRecordCallback.get(ProductType.SERVICE).callback(UserOrder.builder().build(), record);
         userOrderRecordService.add(record);
         messageExtendService.sendInviteSuccess(user, record);
+        return record;
     }
 
     /**
      * 给用户备考奖励: 7天vip
      * @param user
      */
-    public void givePrepare(User user){
+    public UserOrderRecord givePrepare(User user){
         UserOrderRecord record = UserOrderRecord.builder()
                 .userId(user.getId())
                 .productType(ProductType.SERVICE.key)
@@ -1126,13 +1127,14 @@ public class OrderFlowService {
         record = initRecordCallback.get(ProductType.SERVICE).callback(UserOrder.builder().build(), record);
         userOrderRecordService.add(record);
         messageExtendService.sendPrepare(user, record);
+        return record;
     }
 
     /**
      * 给用户实名认证奖励: 180天vip
      * @param user
      */
-    public void giveReal(User user){
+    public UserOrderRecord giveReal(User user){
         UserOrderRecord record = UserOrderRecord.builder()
                 .userId(user.getId())
                 .productType(ProductType.SERVICE.key)
@@ -1146,6 +1148,7 @@ public class OrderFlowService {
         record = initRecordCallback.get(ProductType.SERVICE).callback(UserOrder.builder().build(), record);
         userOrderRecordService.add(record);
         messageExtendService.sendReal(user, record);
+        return record;
     }
 
     /**

+ 3 - 0
server/gateway-api/src/main/java/com/qxgmat/util/shiro/OauthRealm.java

@@ -4,10 +4,13 @@ import com.qxgmat.data.dao.entity.User;
 import com.qxgmat.service.UsersService;
 import org.apache.shiro.authc.*;
 import org.apache.shiro.authz.AuthorizationInfo;
+import org.apache.shiro.authz.SimpleAuthorizationInfo;
 import org.apache.shiro.realm.AuthorizingRealm;
 import org.apache.shiro.subject.PrincipalCollection;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import java.util.ArrayList;
+
 /**
  * Created by GaoJie on 2017/11/3.
  */

+ 5 - 1
server/tools/src/main/java/com/nuliji/tools/CipherHelp.java

@@ -14,6 +14,8 @@ public class CipherHelp {
     public final static String DES = "DES";
     public final static String DES3 = "3DESC";
 
+    private static SecureRandom random = new SecureRandom();
+
     /**
      * encrypt base on DES or 3DES or AES.
      *
@@ -73,7 +75,9 @@ public class CipherHelp {
     public static Key getKey(String key, String algorithm) {
         try {
             KeyGenerator generator = KeyGenerator.getInstance(algorithm);
-            generator.init(new SecureRandom(key.getBytes()));
+            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+            random.setSeed(key.getBytes());
+            generator.init(random);
             return generator.generateKey();
 
         } catch (Exception e) {

+ 13 - 5
server/tools/src/main/java/com/nuliji/tools/third/baidu/BaiduAi.java

@@ -123,8 +123,15 @@ public class BaiduAi {
         params.add("id_card_side", idCardSide.key);
         params.add("detect_direction", detectDirection ? "true" : "false");
         params.add("detect_risk", detectRisk ? "true" : "false");
-
-        return Transform.convert(execute(api+"ocr/v1/idcard?access_token"+getAccessToken(appKey, appSecret), params), IdcardResponse.class);
+        JSONObject object = execute(api+"ocr/v1/idcard?access_token="+getAccessToken(appKey, appSecret), params);
+        IdcardResponse response = new IdcardResponse();
+        response.setDirection(object.getInteger("direction"));
+        response.setEdit_tool(object.getString("edit_tools"));
+        response.setImage_status(object.getString("image_status"));
+        response.setRisk_type(object.getString("risk_type"));
+        response.setWords_result(object.getJSONObject("words_result"));
+        response.setWords_result_num(object.getInteger("words_result_num"));
+        return response;
     }
 
     /**
@@ -138,7 +145,7 @@ public class BaiduAi {
         if (!tokenMap.containsKey(appKey) || date.getTime() / 1000 - tokenExpiresIn.get(appKey).getTime() / 1000 >= 2592000) {
             try {
                 Map<String, String> params = new HashMap<>();
-                params.put("grant_type", "client_credential");
+                params.put("grant_type", "client_credentials");
                 params.put("client_id", appKey);
                 params.put("client_secret", appSecret);
                 String paramStr = "";
@@ -148,7 +155,7 @@ public class BaiduAi {
                     paramStr = paramStr + key + "=" + value + "&";
                 }
                 JSONObject object = execute("https://aip.baidubce.com/oauth/2.0/token?"+paramStr, null);
-                tokenMap.put(appKey, object.getString("accessToken"));
+                tokenMap.put(appKey, object.getString("access_token"));
                 tokenExpiresIn.put(appKey, date);
                 logger.info("getAccessToken:" + tokenMap.get(appKey));
             } catch (UnsupportedEncodingException e) {
@@ -161,6 +168,7 @@ public class BaiduAi {
 
     private JSONObject execute(String api, MultiValueMap<String, Object> params) throws RuntimeException {
         try {
+            logger.info("BaiduAi请求:" + api);
             HttpHeaders headers = new HttpHeaders();
             headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
             RestTemplate restTemplate = new RestTemplate();
@@ -170,7 +178,7 @@ public class BaiduAi {
             logger.info("BaiduAi返回结果:" + result);
             JSONObject a = JSONObject.parseObject(result);
 
-            if (a.getInteger("status") == 0) {
+            if (a.getInteger("error_code") != null && a.getInteger("error_code") > 0) {
                 throw new Exception("BaiduAi接口错误: " + result);
             }
             return a;