<template>
<div class="personal-main">
<div class="personal-pay">
<h3><i>开通第三方账户</i></h3>
<div class="pay-notice">
<p>
请开通汇付宝存管账户以便于您正常理财
</p>
</div>
<div class="pay-form">
<ul>
<li>
<label>真实姓名</label>
<input
v-model="userBind.name"
type="text"
class="pay-txt"
maxlength="16"
placeholder="您的真实姓名"
/>
</li>
<li>
<label>身份证号</label>
<input
v-model="userBind.idCard"
type="text"
class="pay-txt"
maxlength="18"
placeholder="您的身份证号"
/>
<div id="idCardErrorDiv">
<p style="margin-top:10px;">
身份证信息认证后将不可修改,请您仔细填写
</p>
</div>
</li>
<li>
<label>绑定银行</label>
<input
v-model="userBind.bankType"
type="text"
class="pay-txt"
placeholder="银行名称"
/>
</li>
<li>
<label>银行卡号</label>
<input
v-model="userBind.bankNo"
type="text"
class="pay-txt"
placeholder="本人持有的银行卡"
/>
</li>
<li>
<label>预留手机</label>
<input
v-model="userBind.mobile"
type="text"
class="pay-txt"
placeholder="银行卡预留手机号"
/>
</li>
<li>
<label> </label>
<input v-model="agree" type="checkbox" />
我已阅读并同意
<a href="#" class="c-orange" target="_blank">
《汇付宝托管账户协议》
</a>
</li>
<li>
<label> </label>
<el-button :disabled="!agree" @click="commitBind()" type="primary">
开户
</el-button>
</li>
</ul>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
agree: false,
userBind: {},
}
},
methods: {
commitBind() {
this.$alert(
'您即将前往汇付宝绑定账号',
'前往汇付宝资金托管平台',
{
dangerouslyUseHTMLString: true,
confirmButtonText: '立即前往',
callback: (action) => {
//TODO 提交用户信息
console.log(action)
if (action == 'confirm') {
this.$axios
.$post('/api/core/userBind/auth/bind', this.userBind)
.then((response) => {
document.write(response.data.formStr)
})
}
},
}
)
},
},
}
</script>
package com.atguigu.srb.core.controller.api;
import com.alibaba.fastjson.JSON;
import com.atguigu.common.result.R;
import com.atguigu.srb.base.util.JwtUtils;
import com.atguigu.srb.core.hfb.RequestHelper;
import com.atguigu.srb.core.pojo.vo.UserBindVO;
import com.atguigu.srb.core.service.UserBindService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
*
* 用户绑定表 前端控制器
*
*
* @author Likejin
* @since 2023-04-09
*/
@RestController
@Api(tags = "会员账号绑定")
@RequestMapping("/api/core/userBind")
@Slf4j
public class UserBindController {
@Resource
private UserBindService userBindService;
//需要登录的才能访问的接口用/auth来定义
@ApiOperation("账户绑定提交数据")
@PostMapping("/auth/bind")
public R bind(
@RequestBody UserBindVO userBindVO, HttpServletRequest request){
//从header中拿到token,确保用户已经登录,从token中获取到userId(token中有id和username)
String token = request.getHeader("token");
//已经对token进行校验了
Long userId = JwtUtils.getUserId(token);
//根据userId做账户绑定,生成一个动态表单的字符串
String formStr = userBindService.commitBindUser(userBindVO,userId);
return R.ok().data("formStr",formStr);
}
@ApiOperation("账户绑定异步回调")
//汇付宝以post发起请求
@PostMapping("/notify")
//返回值时String,返回为sucess则成功回调,汇付宝不会重试
public String notify(HttpServletRequest request) {
//解析汇付宝发过来的request为map
Map<String, Object> paramMap = RequestHelper.switchMap(request.getParameterMap());
log.info("账户绑定异步回调接受参数{}", JSON.toJSONString(paramMap));
//校验签名(约定相同的算法,计算用其他参数得到的签名和实际签名是否相同)
if(!RequestHelper.isSignEquals(paramMap)){
log.error("用户账号绑定异步回调签名验证错误:"+ JSON.toJSONString(paramMap));
return "fail";
}
log.info("验签成功!开始账户绑定");
userBindService.notify(paramMap);
return "success";
}
}
package com.atguigu.srb.core.service;
import com.atguigu.srb.core.pojo.entity.UserBind;
import com.atguigu.srb.core.pojo.vo.UserBindVO;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.Map;
/**
*
* 用户绑定表 服务类
*
*
* @author Likejin
* @since 2023-04-09
*/
public interface UserBindService extends IService<UserBind> {
String commitBindUser(UserBindVO userBindVO, Long userId);
void notify(Map<String, Object> paramMap);
}
package com.atguigu.srb.core.service.impl;
import com.atguigu.common.exception.Assert;
import com.atguigu.common.result.ResponseEnum;
import com.atguigu.srb.core.enums.UserBindEnum;
import com.atguigu.srb.core.hfb.FormHelper;
import com.atguigu.srb.core.hfb.HfbConst;
import com.atguigu.srb.core.hfb.RequestHelper;
import com.atguigu.srb.core.mapper.UserBindMapper;
import com.atguigu.srb.core.mapper.UserInfoMapper;
import com.atguigu.srb.core.pojo.entity.UserBind;
import com.atguigu.srb.core.pojo.entity.UserInfo;
import com.atguigu.srb.core.pojo.vo.UserBindVO;
import com.atguigu.srb.core.service.UserBindService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
/**
*
* 用户绑定表 服务实现类
*
*
* @author Likejin
* @since 2023-04-09
*/
@Service
public class UserBindServiceImpl extends ServiceImpl<UserBindMapper, UserBind> implements UserBindService {
@Resource
private UserInfoMapper userInfoMapper;
@Override
public String commitBindUser(UserBindVO userBindVO, Long userId) {
//不同的userid,相同的身份证存在则不允许
QueryWrapper<UserBind> userBindQueryWrapper = new QueryWrapper<>();
userBindQueryWrapper.eq("id_card",userBindVO.getIdCard())
.ne("user_id",userId);
UserBind userBind = baseMapper.selectOne(userBindQueryWrapper);
Assert.isNull(userBind, ResponseEnum.USER_BIND_IDCARD_EXIST_ERROR);
//检查用户是否曾经填写过绑定表单
userBindQueryWrapper = new QueryWrapper<>();
userBindQueryWrapper.eq("user_id",userId);
userBind = baseMapper.selectOne(userBindQueryWrapper);
//如果userbind不存在则创建记录
if(userBind ==null){
//创建用户绑定记录
userBind = new UserBind();
//把前端传入的数据与数据库user_bind绑定
BeanUtils.copyProperties(userBindVO,userBind);
userBind.setUserId(userId);
userBind.setStatus(UserBindEnum.NO_BIND.getStatus());
baseMapper.insert(userBind);
}else{
//相同的user_id,存在,则更新
BeanUtils.copyProperties(userBindVO,userBind);
baseMapper.updateById(userBind);
}
//动态生成表单
//组装表单的参数
HashMap<String, Object> paramMap = new HashMap<>();
//商户唯一标识
paramMap.put("agentId", HfbConst.AGENT_ID);
//前端提交的表单对象
paramMap.put("agentUserId", userId);
paramMap.put("idCard",userBindVO.getIdCard());
paramMap.put("personalName", userBindVO.getName());
paramMap.put("bankType", userBindVO.getBankType());
paramMap.put("bankNo", userBindVO.getBankNo());
paramMap.put("mobile", userBindVO.getMobile());
//返回结果给平台前端的结果页
paramMap.put("returnUrl", HfbConst.USERBIND_RETURN_URL);
//返回商户平台的后端的接口
paramMap.put("notifyUrl", HfbConst.USERBIND_NOTIFY_URL);
//提交时间戳(远程调用)
paramMap.put("timestamp", RequestHelper.getTimestamp());
//生成签名,有已知的Sign_key(两者商量好的)
paramMap.put("sign", RequestHelper.getSign(paramMap));
//生成动态表单字符串(辅助生成字符串)
String formStr = FormHelper.buildForm(HfbConst.USERBIND_URL,paramMap);
//前端得到一个字符串,直接提交给汇付宝绑定用户
return formStr;
}
/**
* @param paramMap:
* @return void
* @author Likejin
* @description 处理汇付宝回调参数
* @date 2023/4/14 21:28
*/
@Transactional(rollbackFor = Exception.class)
@Override
public void notify(Map<String, Object> paramMap) {
String bindCode = (String)paramMap.get("bindCode");
String agentUserId = (String)paramMap.get("agentUserId");
//根据userid查询userBind对象
QueryWrapper<UserBind> userBindQueryWrapper = new QueryWrapper<>();
userBindQueryWrapper.eq("user_id",agentUserId);
UserBind userBind = baseMapper.selectOne(userBindQueryWrapper);
//更新尚融宝数据用户绑定表 user_bind
userBind.setBindCode(bindCode);
userBind.setStatus(UserBindEnum.BIND_OK.getStatus());
baseMapper.updateById(userBind);
//更新尚融宝数据用户信息表 user_info
//原来这些值都没传递,都传到了汇付宝,需要用这些值更新用户信息表 user_info
UserInfo userInfo = userInfoMapper.selectById(agentUserId);
userInfo.setBindCode(bindCode);
//名字原来和手机号绑定
userInfo.setName(userBind.getName());
userInfo.setIdCard(userBind.getIdCard());
userInfo.setBindStatus(UserBindEnum.BIND_OK.getStatus());
userInfoMapper.updateById(userInfo);
}
}