用户补充信息相关的接口

This commit is contained in:
黎润豪 2026-03-26 10:25:27 +08:00
parent a258db21a4
commit 88eb4452b5
6 changed files with 397 additions and 0 deletions

View File

@ -0,0 +1,221 @@
package com.chinaweal.aiccs.org.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chinaweal.aiccs.common.util.RSAUTil;
import com.chinaweal.aiccs.common.util.StringUtils;
import com.chinaweal.aiccs.org.entity.TUsersapp;
import com.chinaweal.aiccs.org.service.TUsersappService;
import com.chinaweal.aiccs.redis.RedisService;
import com.chinaweal.youfool.framework.springboot.exception.custom.BusinessException;
import com.chinaweal.youfool.framework.springboot.rest.RestResult;
import com.chinaweal.youfool.framework.sso.util.SSOUtil;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Base64;
/**
* 用户APP信息管理
*/
@Api(tags = "用户APP信息管理")
@ApiSupport(author = "system")
@RestController
@RequestMapping("/usersapp")
@Slf4j
public class TUsersappController {
@Autowired
private TUsersappService tUsersappService;
@Resource
private RedisService redisService;
@Value("${redis-usersapp-privatekey.expire:300}")
private int privateKeyExpire;
private static final String REDIS_PRIVATE_KEY_PREFIX = "usersapp:rsa:privatekey:";
private static final String RSA_COOKIE_KEY = "usersapprsa";
/**
* 接口1检查用户对应的TUsersapp中有没有身份证号和手机号码的记录
*
* @param request 请求
* @return true-有完整记录false-没有完整记录
*/
@GetMapping("/check")
@ApiOperation(value = "检查用户是否有身份证号和手机号码记录")
public RestResult<Boolean> checkUserInfo(HttpServletRequest request) {
String userId = SSOUtil.getUser().getPrimaryKey();
if (StringUtils.isBlank(userId)) {
return RestResult.error(com.chinaweal.youfool.framework.springboot.rest.ResultCode.USER_NOT_LOGGED_IN);
}
TUsersapp byId = tUsersappService.getById(userId);
return RestResult.ok(byId != null && StringUtils.isNotBlank(byId.getMobile()) && StringUtils.isNotBlank(byId.getIdentityno()));
}
/**
* 接口2获取RSA密钥对
* 公钥返回给前端私钥存储在Redis中
* Redis的key后缀使用cookie中的值
*
* @param request 请求
* @return 公钥
*/
@GetMapping("/getPublicKey")
@ApiOperation(value = "获取RSA公钥")
public RestResult<String> getRsaPublicKey(HttpServletRequest request, HttpServletResponse response) {
String cookieValue = getCookieValue(request, RSA_COOKIE_KEY);
if (StringUtils.isBlank(cookieValue)) {
cookieValue = StringUtils.getUUID();
setCookieValue(response, RSA_COOKIE_KEY, cookieValue);
}
try {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(1024, new java.security.SecureRandom());
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded());
String privateKeyString = Base64.getEncoder().encodeToString(privateKey.getEncoded());
// 私钥存储到Rediskey后缀使用cookie值
String redisKey = REDIS_PRIVATE_KEY_PREFIX + cookieValue;
redisService.set(redisKey, privateKeyString, privateKeyExpire);
return RestResult.ok(publicKeyString);
} catch (NoSuchAlgorithmException e) {
log.error("生成RSA密钥对失败", e);
throw new BusinessException("生成RSA密钥对失败");
}
}
/**
* 接口3用户账号信息设置接口
* 用户传入身份证号RSA密文手机号RSA密文
* 将证件号和手机号解密后查询TUsersapp表确保数据是唯一的
* 如果不唯一则抛出BusinessException说明信息已被占用
* 否则创建或更新TUsersapp的记录
*
* @param identityNoEncrypted 身份证号密文
* @param mobileEncrypted 手机号密文
* @param request 请求
* @return 设置结果
*/
@PostMapping("/setUserInfo")
@ApiOperation(value = "设置用户账号信息")
public RestResult<Void> setUserInfo(
@ApiParam("身份证号密文") @RequestParam String identityNoEncrypted,
@ApiParam("手机号密文") @RequestParam String mobileEncrypted,
HttpServletRequest request) {
String userId = SSOUtil.getUser().getPrimaryKey();
if (StringUtils.isEmpty(userId)) {
return RestResult.error(com.chinaweal.youfool.framework.springboot.rest.ResultCode.USER_NOT_LOGGED_IN);
}
String cookieValue = getCookieValue(request, RSA_COOKIE_KEY);
if (StringUtils.isEmpty(cookieValue)) {
throw new BusinessException("Cookie不存在或已过期");
}
// 从Redis获取私钥
String redisKey = REDIS_PRIVATE_KEY_PREFIX + cookieValue;
String privateKeyString = redisService.get(redisKey);
if (StringUtils.isEmpty(privateKeyString)) {
throw new BusinessException("传输加密的密钥已过期,请刷新页面重新获取");
}
try {
// 解密身份证号和手机号
String identityNo = RSAUTil.decrypt(identityNoEncrypted, privateKeyString);
String mobile = RSAUTil.decrypt(mobileEncrypted, privateKeyString);
// 查询是否存在相同的身份证号或手机号(排除当前用户)
LambdaQueryWrapper<TUsersapp> wrapper = new LambdaQueryWrapper<>();
wrapper.and(w -> w
.eq(TUsersapp::getIdentityno, identityNo)
.or()
.eq(TUsersapp::getMobile, mobile)
).ne(TUsersapp::getUserid, userId);
long count = tUsersappService.count(wrapper);
if (count > 0) {
throw new BusinessException("身份证号或手机号已被其他用户占用");
}
// 查询当前用户的TUsersapp记录
TUsersapp existUser = tUsersappService.getById(userId);
if (existUser != null) {
// 更新记录
existUser.setIdentityno(identityNo);
existUser.setMobile(mobile);
tUsersappService.updateById(existUser);
} else {
// 创建新记录
TUsersapp newUser = new TUsersapp();
newUser.setUserid(userId);
newUser.setIdentityno(identityNo);
newUser.setMobile(mobile);
tUsersappService.save(newUser);
}
// 删除Redis中的私钥
redisService.remove(redisKey);
return RestResult.ok();
} catch (BusinessException e) {
throw e;
} catch (Exception e) {
log.error("设置用户账号信息失败", e);
throw new BusinessException("解密失败或处理异常");
}
}
/**
* 获取Cookie中的值
*/
private String getCookieValue(HttpServletRequest request, String cookieKey) {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
// 根据实际情况修改cookie名称
if (cookieKey.equals(cookie.getName())) {
return cookie.getValue();
}
}
}
return null;
}
/**
* 设置cookie
*
* @param response response
* @param cookieKey cookieKey
* @param cookieValue cookie值
*/
private void setCookieValue(HttpServletResponse response, String cookieKey, String cookieValue) {
Cookie cookie = new Cookie(cookieKey, cookieValue);
cookie.setPath("/aiccs-api");
response.addCookie(cookie);
}
}

View File

@ -0,0 +1,125 @@
package com.chinaweal.aiccs.org.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDate;
/**
* <p>
* 用户补充信息
* </p>
*
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName(value = "T_USERSAPP", schema = "CXAICORG")
public class TUsersapp extends Model<TUsersapp> {
private static final long serialVersionUID = 1L;
/**
* 用户id
*/
@TableId(value = "USERID")
@ApiModelProperty("用户id")
private String userid;
/**
* 性别
*/
@TableField("GENDER")
@ApiModelProperty("性别")
private String gender;
/**
* 联系电话号码
*/
@ApiModelProperty("联系电话号码")
@TableField("PHONENUMBER")
private String phonenumber;
/**
* 手机号
*/
@ApiModelProperty("手机号")
@TableField("MOBILE")
private String mobile;
/**
* 邮箱
*/
@ApiModelProperty("邮箱")
@TableField("EMAIL")
private String email;
/**
* 地址
*/
@ApiModelProperty("地址")
@TableField("ADDRESS")
private String address;
/**
* 工号
*/
@ApiModelProperty("工号")
@TableField("WORKNO")
private String workno;
/**
* 工作类型
*/
@ApiModelProperty("工作类型")
@TableField("WORKTYPE")
private String worktype;
/**
* 生日日期
*/
@ApiModelProperty("生日日期")
@TableField("BIRTHDAY")
private LocalDate birthday;
/**
* 雇用日期
*/
@ApiModelProperty("雇用日期")
@TableField("HIREDATE")
private LocalDate hiredate;
/**
* 离职日期
*/
@ApiModelProperty("离职日期")
@TableField("LEAVEDATE")
private LocalDate leavedate;
/**
* 身份证号
*/
@ApiModelProperty("身份证号")
@TableField("IDENTITYNO")
private String identityno;
/**
* 备注
*/
@ApiModelProperty("备注")
@TableField("REMARK")
private String remark;
@Override
protected Serializable pkVal() {
return this.userid;
}
}

View File

@ -0,0 +1,14 @@
package com.chinaweal.aiccs.org.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.chinaweal.aiccs.org.entity.TUsersapp;
/**
* <p>
* Mapper 接口
* </p>
*
*/
public interface TUsersappMapper extends BaseMapper<TUsersapp> {
}

View File

@ -0,0 +1,14 @@
package com.chinaweal.aiccs.org.service;
import com.chinaweal.aiccs.org.entity.TUsersapp;
import com.chinaweal.youfool.framework.springboot.mybatis.plus.BaseService;
/**
* <p>
* 服务类
* </p>
*
*/
public interface TUsersappService extends BaseService<TUsersapp> {
}

View File

@ -0,0 +1,18 @@
package com.chinaweal.aiccs.org.service.impl;
import com.chinaweal.aiccs.org.entity.TUsersapp;
import com.chinaweal.aiccs.org.mapper.TUsersappMapper;
import com.chinaweal.aiccs.org.service.TUsersappService;
import com.chinaweal.youfool.framework.springboot.mybatis.plus.BaseServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 服务实现类
* </p>
*
*/
@Service
public class TUsersappServiceImpl extends BaseServiceImpl<TUsersappMapper, TUsersapp> implements TUsersappService {
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chinaweal.aiccs.org.mapper.TUsersappMapper">
</mapper>