抖音部署
This commit is contained in:
zhouwentao 2024-04-14 21:59:21 +08:00
parent 020afd31b9
commit 2be5e2d250
17 changed files with 498 additions and 156 deletions

View File

@ -78,6 +78,7 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/mini/user/phoneLogin","anon");//小程序手机号登录
filterChainDefinitionMap.put("/mini/user/login","anon");//小程序登录
filterChainDefinitionMap.put("/mini/article/**","anon");//小程序-文章
filterChainDefinitionMap.put("/mini/user/dy/login","anon");//抖音小程序登录
filterChainDefinitionMap.put("/wx/pay/v1/payNotify","anon");//订单支付回调校验
filterChainDefinitionMap.put("/mini/pay/v1/payNotify","anon");//订单支付回调校验

View File

@ -6,9 +6,8 @@ import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.ijpay.core.IJPayHttpResponse;
import com.ijpay.core.enums.RequestMethodEnum;
@ -20,7 +19,6 @@ import com.ijpay.core.utils.DateTimeZoneUtil;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.enums.WxDomainEnum;
import com.ijpay.wxpay.enums.v3.BasePayApiEnum;
import com.ijpay.wxpay.enums.v3.OtherApiEnum;
import com.ijpay.wxpay.model.v3.Amount;
import com.ijpay.wxpay.model.v3.Payer;
import com.ijpay.wxpay.model.v3.UnifiedOrderModel;
@ -32,6 +30,9 @@ import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.AssertUtils;
import org.jeecg.modules.mini.douyin.util.DouWayPaymentMethod;
import org.jeecg.modules.mini.douyin.util.DouYinUtil;
import org.jeecg.modules.mini.douyin.util.Sign;
import org.jeecg.modules.mini.dto.VipDTO;
import org.jeecg.modules.mini.douyin.model.DouYinOrderModel;
import org.jeecg.modules.mini.service.MiniUserService;
@ -52,9 +53,7 @@ import java.io.ByteArrayInputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.*;
/**
* @Author: ZhouWenTao
@ -76,6 +75,14 @@ public class MiniPayApiController {
private IYxVipSkuService yxVipSkuService;
@Autowired
private MiniUserService miniUserService;
@Value("${douyin.appId}")
String douyinAppId;
@Value("${douyin.token}")
String douyinToken;
@Value("${douyin.notifyUrl}")
String douyinNotifyUrl;
@Value("${douyin.salt}")
String douyinSalt;
/**
* 微信小程序appid
**/
@ -125,8 +132,8 @@ public class MiniPayApiController {
@RequestMapping("/jsApiPay")
@ResponseBody
public Result<?> jsApiPay(@RequestBody JSONObject requestBody) {
String provider = requestBody.getStr("provider");//供应商
String skuCode = requestBody.getStr("skuCode");
String provider = requestBody.getString("provider");//供应商
String skuCode = requestBody.getString("skuCode");
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
SysUser user = sysUserService.getById(sysUser.getId());
if (user == null) {
@ -157,64 +164,64 @@ public class MiniPayApiController {
description += "" + yxVipSku.getSkuDetail();
}
//判断是抖音平台 还是 微信平台 小程序操作
String douyinUrl="https://developer.toutiao.com/api/apps/ecpay/v1/create_order";
if ("toutiao".equals(provider)) {
//抖音
DouYinOrderModel douYinOrderModel = new DouYinOrderModel();
}
try {
String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 3);
UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
// APPID
.setAppid(appid)
// 商户号
.setMchid(mchid)
.setDescription(description)
.setOut_trade_no(orderCode)
.setTime_expire(timeExpire)
.setAttach("艺体志愿宝VIP")
.setNotify_url(notifyUrl)
.setAmount(new Amount().setTotal(totalAmount.intValue()))
.setPayer(new Payer().setOpenid(openId));
log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
IJPayHttpResponse response = WxPayApi.v3(
RequestMethodEnum.POST,
WxDomainEnum.CHINA.toString(),
BasePayApiEnum.JS_API_PAY.toString(),
mchid,
getSerialNumber(),
null,
certKeyPath,
JSONUtil.toJsonStr(unifiedOrderModel)
);
log.info("统一下单响应 {}", response);
// 根据证书序列号查询对应的证书来验证签名结果
boolean verifySignature = WxPayKit.verifySignature(response, platFormPath);
log.info("verifySignature: {}", verifySignature);
if (response.getStatus() == HttpStatus.HTTP_OK && verifySignature) {
String body = response.getBody();
JSONObject jsonObject = JSONUtil.parseObj(body);
String prepayId = jsonObject.getStr("prepay_id");
Map<String, String> map = WxPayKit.jsApiCreateSign(appid, prepayId, certKeyPath);
log.info("唤起支付参数:{}", map);
String jsonStr = JSONUtil.toJsonStr(map);
//==============创建订单信息 Start
yxOrder.setOrderCode(orderCode);//orderCode
yxOrder.setSkuCode(skuCode);//vip商品Code
yxOrder.setOrderStatus("0");//订单状态
yxOrder.setTotalAmount(totalAmount);//金额
yxOrder.setPaymentUserId(user.getId());//付款人
yxOrder.setOrderSign(jsonStr);
yxOrder.setOrderStatus("1");
yxOrder.setPaymentType("3");//微信支付
yxOrderService.save(yxOrder);
//==============创建订单信息 End
return Result.OK("获取成功", yxOrder.getOrderCode());
yxOrder.setOrderCode(orderCode);//orderCode
yxOrder.setSkuCode(skuCode);//vip商品Code
yxOrder.setOrderStatus("0");//订单状态
yxOrder.setTotalAmount(totalAmount);//金额
yxOrder.setPaymentUserId(user.getId());//付款人
yxOrder.setOrderStatus("1");
yxOrder.setProvider(provider);
//判断是抖音平台 还是 微信平台 小程序操作
if ("toutiao".equals(provider)) {
//抖音
String douyinSign = DouYinUtil.main(douyinAppId, douyinToken, douyinNotifyUrl, douyinSalt, orderCode, totalAmount.intValue(),yxVipSku.getSkuName(), description);
yxOrder.setOrderSign(douyinSign);
}
else {
String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 3);
UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
// APPID
.setAppid(appid)
// 商户号
.setMchid(mchid)
.setDescription(description)
.setOut_trade_no(orderCode)
.setTime_expire(timeExpire)
.setAttach("艺体志愿宝"+yxVipSku.getSkuName())
.setNotify_url(notifyUrl)
.setAmount(new Amount().setTotal(totalAmount.intValue()))
.setPayer(new Payer().setOpenid(openId));
log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
IJPayHttpResponse response = WxPayApi.v3(
RequestMethodEnum.POST,
WxDomainEnum.CHINA.toString(),
BasePayApiEnum.JS_API_PAY.toString(),
mchid,
getSerialNumber(),
null,
certKeyPath,
JSONUtil.toJsonStr(unifiedOrderModel)
);
log.info("统一下单响应 {}", response);
// 根据证书序列号查询对应的证书来验证签名结果
boolean verifySignature = WxPayKit.verifySignature(response, platFormPath);
log.info("verifySignature: {}", verifySignature);
if (response.getStatus() == HttpStatus.HTTP_OK && verifySignature) {
String body = response.getBody();
JSONObject jsonObject = JSONObject.parseObject(body);
String prepayId = jsonObject.getString("prepay_id");
Map<String, String> map = WxPayKit.jsApiCreateSign(appid, prepayId, certKeyPath);
log.info("唤起支付参数:{}", map);
String jsonStr = JSONUtil.toJsonStr(map);
//==============创建订单信息 Start
yxOrder.setOrderSign(jsonStr);
yxOrder.setPaymentType("3");//微信支付
//==============创建订单信息 End
}
}
yxOrderService.save(yxOrder);
return Result.OK("获取成功", yxOrder.getOrderCode());
} catch (Exception e) {
e.printStackTrace();
}
@ -231,10 +238,10 @@ public class MiniPayApiController {
public void payNotify(HttpServletRequest request, HttpServletResponse response) {
Map<String, String> map = new HashMap<>(12);
String result = HttpKit.readData(request);
System.out.println("===================result:"+result);
if(false){
try {
String timestamp = request.getHeader("Wechatpay-Timestamp");
try {
String timestamp = request.getHeader("Wechatpay-Timestamp");
if (StringUtils.isNotBlank(timestamp)) {
//微信平台
String nonce = request.getHeader("Wechatpay-Nonce");
String serialNo = request.getHeader("Wechatpay-Serial");
String signature = request.getHeader("Wechatpay-Signature");
@ -245,7 +252,7 @@ public class MiniPayApiController {
mchKey, platFormPath);
log.info("支付通知明文 {}", plainText);
if (StrUtil.isNotEmpty(plainText)) {
com.alibaba.fastjson.JSONObject plainTextJson = com.alibaba.fastjson.JSONObject.parseObject(plainText);
com.alibaba.fastjson.JSONObject plainTextJson = JSONObject.parseObject(plainText);
//订单号
String outTradeNo = plainTextJson.getString("out_trade_no");
//支付状态
@ -266,9 +273,58 @@ public class MiniPayApiController {
response.setHeader("Content-type", ContentType.JSON.toString());
response.getOutputStream().write(JSONUtil.toJsonStr(map).getBytes(StandardCharsets.UTF_8));
response.flushBuffer();
} catch (Exception e) {
e.printStackTrace();
} else {
//抖音小程序
System.out.println("===================result:" + result);
JSONObject requestJson = JSONObject.parseObject(result);
//生成本地签名
List<String> sortedString = new ArrayList<>();
//token
sortedString.add(douyinToken);
//时间戳
sortedString.add(requestJson.getString("timestamp"));
//随机数
sortedString.add(requestJson.getString("nonce"));
//msg
sortedString.add(requestJson.getString("msg"));
Collections.sort(sortedString);
StringBuilder sb = new StringBuilder();
sortedString.forEach(sb::append);
String sign = Sign.callbackSign(sortedString);
timestamp = requestJson.getString("timestamp");//Unix 时间戳字符串类型
String nonce = requestJson.getString("nonce");//随机数
String msgSignature = requestJson.getString("msg_signature");//签名
String type = requestJson.getString("type");//回调类型标记支付成功回调为"payment"
String msg = requestJson.getString("msg");
JSONObject msgJson = JSONObject.parseObject(msg);//订单信息的 json 字符串
String way = msgJson.getString("way");//way 字段中标识了支付渠道 1-微信支付2-支付宝支付10-抖音支付
String cpOrderno = msgJson.getString("cp_orderno");//订单号
String channelNo = msgJson.getString("channel_no");//支付渠道侧单号(抖音平台请求下游渠道微信或支付宝时传入的单号)
String paymentOrderNo = msgJson.getString("payment_order_no");//支付渠道侧PC单号支付页面可见(微信支付宝侧的订单号)
Integer totalAmount = msgJson.getInteger("total_amount");//支付金额单位为分
String status = msgJson.getString("status");//固定SUCCESS
Long paidAt = msgJson.getLong("paid_at");//支付时间Unix 时间戳10 整型数
if ("SUCCESS".equals(status) && sign.equals(msgSignature)) {
//支付成功修改订单信息
Date date = new Date();
date.setTime(paidAt*1000);
yxOrderService.paymentOrderOver(cpOrderno, DouWayPaymentMethod.getByWay(way), "2", date);
response.setStatus(200);
map.put("code", "SUCCESS");
map.put("message", "SUCCESS");
} else {
response.setStatus(500);
map.put("code", "ERROR");
map.put("message", "签名错误");
}
response.setHeader("Content-type", ContentType.JSON.toString());
response.getOutputStream().write(JSONUtil.toJsonStr(map).getBytes(StandardCharsets.UTF_8));
response.flushBuffer();
}
} catch (Exception e) {
e.printStackTrace();
}
}
@ -287,7 +343,7 @@ public class MiniPayApiController {
}
@RequestMapping("/get")
/* @RequestMapping("/get")
@ResponseBody
public String v3Get() {
// 获取平台证书列表
@ -311,7 +367,7 @@ public class MiniPayApiController {
int isOk = 200;
if (status == isOk) {
JSONObject jsonObject = JSONUtil.parseObj(body);
JSONArray dataArray = jsonObject.getJSONArray("data");
JSONArray dataArray = jsonObject.tet("data");
// 默认认为只有一个平台证书
JSONObject encryptObject = dataArray.getJSONObject(0);
JSONObject encryptCertificate = encryptObject.getJSONObject("encrypt_certificate");
@ -330,7 +386,7 @@ public class MiniPayApiController {
e.printStackTrace();
return null;
}
}
}*/
/**

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.xkcoding.http.HttpUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
@ -14,6 +15,7 @@ import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.*;
import org.jeecg.modules.mini.douyin.vo.DyLoginVo;
import org.jeecg.modules.mini.dto.VipDTO;
import org.jeecg.modules.mini.service.MiniUserService;
import org.jeecg.modules.system.entity.SysUser;
@ -36,6 +38,8 @@ import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.util.HashMap;
import java.util.Map;
/**
* @Description
@ -45,7 +49,12 @@ import java.security.spec.AlgorithmParameterSpec;
@RequestMapping("/mini/user")
@RestController
@Api(tags = "小程序用户接口")
@Slf4j
public class MiniUserController {
@Value("${dy.appId}")
private String dyAppId;
@Value("${dy.appSecret}")
private String dyAppSecret;
@Value("${wx.appId}")
private String wxAppId;
@Value("${wx.appSecret}")
@ -55,12 +64,6 @@ public class MiniUserController {
@Autowired
private ISysUserService sysUserService;
@Autowired
private IYxUserScoreService yxUserScoreService;
@Autowired
private IYxVipCardService yxVipCardService;
@Autowired
private IYxOrderService yxOrderService;
@Autowired
private MiniUserService miniUserService;
public static final String AES = "AES";
public static final String AES_CBC_PADDING = "AES/CBC/PKCS7Padding";
@ -82,20 +85,65 @@ public class MiniUserController {
return Result.OK("保存成功");
}
@ApiOperation("注册接口")
@RequestMapping(value = "/register", method = RequestMethod.POST)
public Result<JSONObject> register(@RequestBody SysLoginModel sysLoginModel) {
Result<JSONObject> result = new Result<JSONObject>();
String username = sysLoginModel.getUsername();
String password = sysLoginModel.getPassword();
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
//queryWrapper.eq(SysUser::getUsername,username);
queryWrapper.eq(SysUser::getPhone, username);
SysUser sysUser = sysUserService.getOne(queryWrapper);
if (sysUser != null) {
result.error500("手机号已被注册");
return result;
}
//2. 校验用户名或密码是否正确
String userpassword = PasswordUtil.encrypt(sysUser.getUsername(), password, sysUser.getSalt());
String syspassword = sysUser.getPassword();
if (!syspassword.equals(userpassword)) {
result.error500("用户名或密码错误");
return result;
}
//用户登录信息
//1.生成token
String token = JwtUtil.sign(sysUser.getUsername(), syspassword);
// 设置token缓存有效时间
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, 3600 * 2);
JSONObject obj = new JSONObject();
LoginUser loginUser = new LoginUser();
BeanUtils.copyProperties(sysUser, loginUser);
//获取vip信息
VipDTO vipDTO = miniUserService.getUserVip(sysUser.getId());
if (vipDTO != null) {
obj.put("vipInfo", vipDTO);
} else {
obj.put("vipInfo", null);
}
obj.put("token", token);
obj.put("openId", "openId");
obj.put("sessionKey", "sessionKey");
obj.put("userInfo", loginUser);
return Result.OK(obj);
}
@ApiOperation("登录接口")
@RequestMapping(value = "/login", method = RequestMethod.POST)
public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel){
public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel) {
Result<JSONObject> result = new Result<JSONObject>();
String username = sysLoginModel.getUsername();
String password = sysLoginModel.getPassword();
//update-begin-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bugif条件永远为false
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
//queryWrapper.eq(SysUser::getUsername,username);
queryWrapper.eq(SysUser::getPhone,username);
queryWrapper.eq(SysUser::getPhone, username);
SysUser sysUser = sysUserService.getOne(queryWrapper);
//update-end-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bugif条件永远为false
result = sysUserService.checkUserIsEffective(sysUser);
if(!result.isSuccess()) {
if (!result.isSuccess()) {
return result;
}
@ -118,10 +166,10 @@ public class MiniUserController {
BeanUtils.copyProperties(sysUser, loginUser);
//获取vip信息
VipDTO vipDTO = miniUserService.getUserVip(sysUser.getId());
if (vipDTO!=null) {
obj.put("vipInfo",vipDTO);
}else{
obj.put("vipInfo",null);
if (vipDTO != null) {
obj.put("vipInfo", vipDTO);
} else {
obj.put("vipInfo", null);
}
obj.put("token", token);
obj.put("openId", "openId");
@ -132,12 +180,12 @@ public class MiniUserController {
@PostMapping("/phoneLogin")
@ApiOperation(value = "小程序手机号登录")
@ApiOperation(value = "微信小程序手机号登录")
public Result<?> wechatLogin(@NotNull @RequestBody WxModel wxModel) {
SysUser user = null;
if(false){
if (false) {
user = sysUserService.getUserByPhone("15090658223");
}else{
} else {
String url = "https://api.weixin.qq.com/sns/jscode2session" +
"?appid=" + wxAppId +
"&secret=" + wxAppSecret +
@ -180,15 +228,16 @@ public class MiniUserController {
BeanUtils.copyProperties(user, loginUser);
//获取vip信息
VipDTO vipDTO = miniUserService.getUserVip(user.getId());
if (vipDTO!=null) {
obj.put("vipInfo",vipDTO);
}else{
obj.put("vipInfo",null);
if (vipDTO != null) {
obj.put("vipInfo", vipDTO);
} else {
obj.put("vipInfo", null);
}
obj.put("token", token);
obj.put("openId", "openId");
obj.put("sessionKey", "sessionKey");
obj.put("userInfo", loginUser);
obj.put("loginState", "not");
return Result.OK(obj);
}
@ -212,6 +261,112 @@ public class MiniUserController {
return Result.OK();
}
@PostMapping("/dy/login")
@ApiOperation("抖音-登录接口")
public Result<?> dyLogin(@RequestBody DyLoginVo vo) {
if (StringUtils.isEmpty(vo.getCode())) {
return Result.error("code 不能为空");
}
//获取用户基本信息
JSONObject jsonObject = new JSONObject();
jsonObject.put("appid", dyAppId);
jsonObject.put("secret", dyAppSecret);
jsonObject.put("code", vo.getCode());
jsonObject.put("anonymous_code", "");
JSONObject baseDataObject = RestUtil.post("https://developer.toutiao.com/api/apps/v2/jscode2session", jsonObject);
String jsonString = JSONObject.toJSONString(jsonObject);
String baseDataStr = JSONObject.toJSONString(baseDataObject);
if (baseDataObject.get("data") == null) {
log.error("获取字节用户基本信息异常 req => {} , res => {}", jsonString, baseDataStr);
return Result.error("获取用户信息失败");
}
JSONObject baseData = baseDataObject.getJSONObject("data");
if (StringUtils.isBlank(baseData.getString("openid"))) {
log.error("获取字节用户基本信息异常 req => {} , res => {}", jsonString, baseDataStr);
return Result.error("获取用户信息失败");
}
String openId = baseData.get("openid").toString();
SysUser user = sysUserService.getByDyOpenId(openId);
if (user == null) {
String salt = oConvertUtils.randomGen(8);
//新用户
user = new SysUser();
user.setDyOpenId(openId);
user.setUsername(salt);
user.setRealname("用户-" + salt);
user.setSalt(salt);
String encryptPassword = PasswordUtil.encrypt(salt, "123456", salt);
user.setPassword(encryptPassword);
user.setStatus(1);
user.setUserIdentity(CommonConstant.USER_IDENTITY_1);
user.setDelFlag(CommonConstant.DEL_FLAG_0);
user.setOrgCode(null);
sysUserService.saveUser(user, null, null, null);
}
String username = user.getUsername();
String syspassword = user.getPassword();
//1.生成token
String token = JwtUtil.sign(username, syspassword);
// 设置token缓存有效时间
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, 3600 * 2);
JSONObject obj = new JSONObject();
LoginUser loginUser = new LoginUser();
BeanUtils.copyProperties(user, loginUser);
//获取vip信息
VipDTO vipDTO = miniUserService.getUserVip(user.getId());
if (vipDTO != null) {
obj.put("vipInfo", vipDTO);
} else {
obj.put("vipInfo", null);
}
obj.put("token", token);
obj.put("openId", "openId");
obj.put("sessionKey", "sessionKey");
obj.put("userInfo", loginUser);
obj.put("loginState", "not");
return Result.OK(obj);
}
@GetMapping(value = "/dy/checkBindPhone")
@ApiOperation(value = "抖音-判断手机号的绑定情况")
public Result<?> dyCheckBindPhone(@RequestParam String phone) {
SysUser sysUser = sysUserService.getUserByPhone(phone);
Map<String, Object> data = new HashMap<>();
if (sysUser == null) {
//未绑定
data.put("status", 0);
} else if (StringUtils.isNotBlank(sysUser.getDyOpenId())) {
//已绑定抖音openId不可绑定
data.put("status", 1);
} else if (StringUtils.isNotBlank(sysUser.getWxOpenId())) {
//已绑定微信openId
data.put("status", 2);
}
return Result.OK(data);
}
@PostMapping(value = "/dy/bindPhone")
@ApiOperation(value = "抖音-绑定手机号")
public Result<?> dyBindPhone(@RequestBody SysUser sysUser) {
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
String id = loginUser.getId();
String phone = sysUser.getPhone();
SysUser newSysUser = sysUserService.getUserByPhone(phone);
if (newSysUser == null) {
//绑定手机号
LambdaUpdateWrapper<SysUser> sysUserLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
sysUserLambdaUpdateWrapper.eq(SysUser::getId, id);
sysUserLambdaUpdateWrapper.set(SysUser::getPhone, phone);
sysUserService.update(sysUserLambdaUpdateWrapper);
return Result.OK(1);
}
//对应手机号的数据转移到当前账号下
miniUserService.transferDataUser(id, newSysUser.getId());
return Result.OK(2);
}
public static String phoneDecrypt(String encrypted, String sessionKey, String iv) {
String phoneNumber = null;
try {

View File

@ -0,0 +1,31 @@
package org.jeecg.modules.mini.douyin.util;
/**
* 抖音内付款方式
* @author ZhouWenTao
* @create 2024-04-14-16:12
*/
public enum DouWayPaymentMethod {
WECHAT("3"),//1 微信支付
ALIPAY("4"),//2 支付宝
DOUYIN("10");//10 抖音
private final String value;
DouWayPaymentMethod(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public static String getByWay(String way){
if ("1".equals(way)) {
return WECHAT.getValue();
}else if ("2".equals(way)) {
return WECHAT.getValue();
}
return "10";
}
}

View File

@ -1,39 +0,0 @@
package org.jeecg.modules.mini.douyin.util;
import com.alibaba.fastjson.JSONObject;
import org.jeecg.common.util.RestUtil;
import org.jeecg.config.sign.util.HttpUtils;
import java.util.HashMap;
import java.util.Map;
/**
* @author ZhouWenTao
* @create 2024-04-14-13:10
*/
public class DouYinTest {
public static void main(String[] args) {
Map<String, Object> testCase = new HashMap<String, Object>() {{
put("app_id", "tt59a72f1ac6964bfa01");
//put("thirdparty_id", "");//tta4bad200000xxxxxx
put("out_order_no", "test-02");
put("total_amount", 1);
put("subject", "test-payment_subject-test-paym...");
put("body", "测试购买vip");
put("valid_time", 172800);
put("notify_url", "https://yitisheng.vip/jbt/mini/pay/v1/payNotify");
put("cp_extra", "一些附加信息");
//put("disable_msg", 0);
//put("msg_page", "pages/user/orderDetail/orderDetail?id=997979879879879879");
//put("sign", "edc608b160a1be3de0xxxxxx");
}};
String sign = Sign.requestSign(testCase);
System.out.println(sign);
//发送post请求
String douyinUrl="https://developer.toutiao.com/api/apps/ecpay/v1/create_order";
testCase.put("sign",sign);
String jsonString = JSONObject.toJSONString(testCase);
JSONObject post = RestUtil.post(douyinUrl, JSONObject.parseObject(jsonString));
System.out.println(post);
}
}

View File

@ -0,0 +1,46 @@
package org.jeecg.modules.mini.douyin.util;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.RestUtil;
import java.util.HashMap;
import java.util.Map;
/**
* @author ZhouWenTao
* @create 2024-04-14-13:10
*/
@Slf4j
public class DouYinUtil {
public static String main(String appId,String token,String notifyUrl,String salt,String orderCode,
Integer totalAmount,String skuName,String description) {
Map<String, Object> testCase = new HashMap<String, Object>() {{
put("app_id", appId);
//put("thirdparty_id", "");//tta4bad200000xxxxxx
put("out_order_no", orderCode);
put("total_amount", totalAmount);
put("subject", skuName);
put("body", description);
put("valid_time", 172800);
put("notify_url", notifyUrl);
put("cp_extra", "一些附加信息");
put("salt",salt);
//put("disable_msg", 0);
//put("msg_page", "pages/user/orderDetail/orderDetail?id=997979879879879879");
//put("sign", "edc608b160a1be3de0xxxxxx");
}};
String sign = Sign.requestSign(testCase);
//发送post请求
String douyinUrl="https://developer.toutiao.com/api/apps/ecpay/v1/create_order";
testCase.put("sign",sign);
JSONObject post = RestUtil.post(douyinUrl, JSONObject.parseObject(JSONObject.toJSONString(testCase)));
log.debug("创建抖音支付----:"+post.toJSONString());
post.put("sign",testCase);
return post.toJSONString();
/*String ss="{\"msg\":\"{\\\"appid\\\":\\\"tt59a72f1ac6964bfa01\\\",\\\"cp_orderno\\\":\\\"test-03\\\",\\\"cp_extra\\\":\\\"一些附加信息\\\",\\\"way\\\":\\\"2\\\",\\\"channel_no\\\":\\\"2024041422001463641425874787\\\",\\\"channel_gateway_no\\\":\\\"DTPS2404141541259015355093003994\\\",\\\"payment_order_no\\\":\\\"DPS2404141541259015355420683994\\\",\\\"out_channel_order_no\\\":\\\"2024041422001463641425874787\\\",\\\"total_amount\\\":1,\\\"status\\\":\\\"SUCCESS\\\",\\\"seller_uid\\\":\\\"73556929590289226620\\\",\\\"extra\\\":\\\"\\\",\\\"item_id\\\":\\\"\\\",\\\"paid_at\\\":1713080495,\\\"message\\\":\\\"\\\",\\\"order_id\\\":\\\"N7357624400327362850\\\",\\\"ec_pay_trade_no\\\":\\\"DTPP2404141541259015354765323994\\\",\\\"real_buyer_id\\\":\\\"\\\",\\\"pay_sub_way\\\":\\\"\\\",\\\"trade_items\\\":null,\\\"cj_app_id\\\":\\\"\\\",\\\"channel_merchant_id\\\":\\\"\\\",\\\"cj_merchant_id\\\":\\\"\\\",\\\"bank_info\\\":\\\"\\\"}\",\"msg_signature\":\"fcb287f56e1e23c29b009d783352f598f720dbac\",\"nonce\":\"7345\",\"timestamp\":\"1713080496\",\"type\":\"payment\"}";
JSONObject jsonObject = JSONObject.parseObject(ss);
JSONObject msg = jsonObject.getJSONObject("msg");
System.out.println(JSONObject.parseObject(ss));*/
}
}

View File

@ -37,7 +37,7 @@ public class Sign {
*
* Payment key value, you need to replace it with your own key
*/
private static final String SALT = "wODf6Bg5BXndJ3IELXNb1w5CDMRjatXAmZVP2DQ7";
private static String SALT = "";
/**
* RequestSign 担保支付请求签名算法
@ -56,13 +56,15 @@ public class Sign {
continue;
}
String value = entry.getValue().toString();
if ("salt".equals(key)) {
SALT = value;
}
value = value.trim();
if (value.startsWith("\"") && value.endsWith("\"") && value.length() > 1) {
value = value.substring(1, value.length() - 1);
}
value = value.trim();
if (value.equals("") || value.equals("null")) {
if (value.isEmpty() || value.equals("null")) {
continue;
}
paramsArr.add(value);

View File

@ -0,0 +1,21 @@
package org.jeecg.modules.mini.douyin.vo;
import lombok.Data;
/**
* @author ZhouWenTao
* @create 2024-04-14-18:47
*/
@Data
public class DyLoginVo {
private String code;
// dy 抖音, tt 头条, xg 西瓜
private String btyeDanceType = "dy";
// 加密手机号
private String encryptedMobile;
private String anonymousCode;
//昵称
private String nickName;
//头像
private String avatarUrl;
}

View File

@ -1,18 +1,18 @@
package org.jeecg.modules.mini.service;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.mini.dto.VipDTO;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.yx.entity.YxOrder;
import org.jeecg.modules.yx.entity.YxVipCard;
import org.jeecg.modules.yx.entity.YxVipSku;
import org.jeecg.modules.yx.service.IYxOrderService;
import org.jeecg.modules.yx.service.IYxVipCardService;
import org.jeecg.modules.yx.service.IYxVipSkuService;
import org.jeecg.modules.yx.entity.*;
import org.jeecg.modules.yx.service.*;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.text.ParseException;
@ -31,6 +31,10 @@ public class MiniUserService {
@Resource
private ISysUserService sysUserService;
@Resource
private IYxUserScoreService yxUserScoreService;
@Resource
private IYxVolunteerService yxVolunteerService;
@Resource
private IYxVipCardService yxVipCardService;
@Resource
private IYxOrderService yxOrderService;
@ -122,4 +126,29 @@ public class MiniUserService {
}
return 0;
}
/**
* 将oldUserId的数据转移到当前账号且销毁那个账号
* @param nowUserId 当前userId
* @param oldUserId 旧的userId
*/
@Async
@Transactional(rollbackFor = Exception.class)
public void transferDataUser(String nowUserId, String oldUserId) {
//订单
yxOrderService.update(new LambdaUpdateWrapper<YxOrder>().eq(YxOrder::getPaymentUserId,oldUserId).set(YxOrder::getPaymentUserId,nowUserId));
//卡密
yxVipCardService.update(new LambdaUpdateWrapper<YxVipCard>().eq(YxVipCard::getUserId,oldUserId).set(YxVipCard::getUserId,nowUserId));
//成绩
yxUserScoreService.update(new LambdaUpdateWrapper<YxUserScore>().eq(YxUserScore::getCreateBy,oldUserId).set(YxUserScore::getCreateBy,nowUserId).set(YxUserScore::getState,0));
//志愿单
yxVolunteerService.update(new LambdaUpdateWrapper<YxVolunteer>().eq(YxVolunteer::getCreateBy,oldUserId).set(YxVolunteer::getCreateBy,nowUserId).set(YxVolunteer::getState,0));
//将旧的用户表中微信openId复制过来
SysUser oldSysUser = sysUserService.getById(oldUserId);
String wxOpenId = oldSysUser.getWxOpenId();
//将旧的用户表删了
sysUserService.update(new LambdaUpdateWrapper<SysUser>().eq(SysUser::getId,oldUserId).set(SysUser::getPhone,oldSysUser.getPhone()+11).set(SysUser::getDelFlag,1).set(SysUser::getWxOpenId,null));
//转移数据
sysUserService.update(new LambdaUpdateWrapper<SysUser>().eq(SysUser::getId,nowUserId).set(SysUser::getPhone,oldSysUser.getPhone()).set(SysUser::getWxOpenId,wxOpenId));
}
}

View File

@ -209,4 +209,8 @@ public class SysUser implements Serializable {
* 微信openId
*/
private String wxOpenId;
/**
* 抖音openId
*/
private String dyOpenId;
}

View File

@ -31,6 +31,11 @@ import java.util.Set;
* @since 2018-12-20
*/
public interface ISysUserService extends IService<SysUser> {
/**
* 根据抖音openId获取
* @param dyOpenId
*/
SysUser getByDyOpenId(String dyOpenId);
/**
* 根据openId获取
*/
@ -392,4 +397,5 @@ public interface ISysUserService extends IService<SysUser> {
* @param departs
*/
void editTenantUser(SysUser sysUser, String tenantId, String departs, String roles);
}

View File

@ -15,6 +15,7 @@ import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.dto.DataLogDTO;
import org.jeecg.common.api.dto.OnlineAuthDTO;
import org.jeecg.common.api.dto.message.*;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.UrlMatchEnum;
import org.jeecg.common.constant.*;
import org.jeecg.common.constant.enums.MessageTypeEnum;
@ -53,7 +54,7 @@ import java.util.*;
/**
* @Description: 底层共通业务API提供其他独立模块调用
* @Author: scott
* @Date:2019-4-20
* @Date:2019-4-20
* @Version:V1.0
*/
@Slf4j
@ -104,7 +105,8 @@ public class SysBaseApiImpl implements ISysBaseAPI {
private ISysDataLogService sysDataLogService;
@Autowired
private ISysFilesService sysFilesService;
@Autowired
private RedisUtil redisUtil;
@Override
//@SensitiveDecode
public LoginUser getUserByName(String username) {
@ -1297,4 +1299,4 @@ public class SysBaseApiImpl implements ISysBaseAPI {
obj.put(WebsocketConst.MSG_USER_ID, userId);
webSocket.sendMessage(userId, obj.toJSONString());
}
}
}

View File

@ -97,6 +97,11 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
@Autowired
private SysUserTenantMapper userTenantMapper;
@Override
public SysUser getByDyOpenId(String dyOpenId) {
return this.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getDyOpenId,dyOpenId));
}
@Override
public SysUser getByWxOpenId(String wxOpenId) {
return this.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getWxOpenId,wxOpenId));

View File

@ -3,6 +3,7 @@ package org.jeecg.modules.yx.service;
import org.jeecg.modules.yx.entity.YxOrder;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.Date;
import java.util.List;
/**
@ -14,4 +15,12 @@ import java.util.List;
public interface IYxOrderService extends IService<YxOrder> {
public List<YxOrder> findListByPaymentUserId(String paymentUserId);
/**
* 修改订单支付状态
* @param orderCode 订单编号
* @param orderStatus 状态
* @param paymentTime 支付时间
*/
void paymentOrderOver(String orderCode,String paymentType, String orderStatus, Date paymentTime);
}

View File

@ -1,6 +1,7 @@
package org.jeecg.modules.yx.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.jeecg.modules.yx.entity.YxOrder;
import org.jeecg.modules.yx.mapper.YxOrderMapper;
import org.jeecg.modules.yx.service.IYxOrderService;
@ -8,12 +9,13 @@ import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.Date;
import java.util.List;
/**
* @Description: 订单表
* @Author: jeecg-boot
* @Date: 2024-02-23
* @Date: 2024-02-23
* @Version: V1.0
*/
@Service
@ -23,4 +25,17 @@ public class YxOrderServiceImpl extends ServiceImpl<YxOrderMapper, YxOrder> impl
public List<YxOrder> findListByPaymentUserId(String paymentUserId) {
return baseMapper.findListByPaymentUserId(paymentUserId);
}
@Override
public void paymentOrderOver(String orderCode, String paymentType, String orderStatus, Date paymentTime) {
if (paymentTime == null) {
paymentTime = new Date();
}
LambdaUpdateWrapper<YxOrder> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper.eq(YxOrder::getOrderCode, orderCode);
lambdaUpdateWrapper.set(YxOrder::getPaymentTime, paymentTime);
lambdaUpdateWrapper.set(YxOrder::getPaymentType, paymentType);
lambdaUpdateWrapper.set(YxOrder::getOrderStatus, "2");
super.update(lambdaUpdateWrapper);
}
}

View File

@ -13,15 +13,12 @@ import org.jeecg.common.util.AssertUtils;
import org.jeecg.modules.art.dto.RecommendMajorDTO;
import org.jeecg.modules.art.vo.SaveVolunteerRecordVO;
import org.jeecg.modules.art.vo.SaveVolunteerVO;
import org.jeecg.modules.mini.dto.VipDTO;
import org.jeecg.modules.mini.service.MiniUserService;
import org.jeecg.modules.yx.constant.YxConstant;
import org.jeecg.modules.yx.dto.VolunteerDTO;
import org.jeecg.modules.yx.dto.VolunteerRecordDTO;
import org.jeecg.modules.yx.entity.*;
import org.jeecg.modules.yx.mapper.YxVolunteerMapper;
import org.jeecg.modules.yx.service.*;
import org.jeecg.modules.yx.util.ScoreUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -49,8 +46,6 @@ public class YxVolunteerServiceImpl extends ServiceImpl<YxVolunteerMapper, YxVol
private IYxVolunteerRecordService yxVolunteerRecordService;
@Resource
private IYxHistoryMajorEnrollService yxHistoryMajorEnrollService;
@Resource
private MiniUserService miniUserService;
final static BigDecimal bigDecimal100 = new BigDecimal("100");//100倍率
@ -155,10 +150,6 @@ public class YxVolunteerServiceImpl extends ServiceImpl<YxVolunteerMapper, YxVol
//获取已填报的志愿单
List<VolunteerRecordDTO> recordDTOList = yxVolunteerRecordService.listDTOByVolunteerId(userScore.getId(),userScore.getCalculationTableName(),volunteer.getId());
//获取上一年的招生人数
VipDTO userVip = miniUserService.getUserVip(userScore.getCreateBy());
if (userVip==null || userVip.getVipLevel()==null || userVip.getVipLevel()<2) {
recordDTOList.forEach(r->r.setEnrollProbability(new BigDecimal(0)));
}
yxHistoryMajorEnrollService.volunteerRecordDTOListSetHistoryInfo(recordDTOList);
/*//填报志愿明细信息-提前批

View File

@ -2,7 +2,7 @@ spring:
application:
name: jeecg-system
profiles:
active: '@profile.name@'
active: dev
wx:
appId: wxb9cf28f42ffa35e5
@ -25,3 +25,11 @@ wx:
#APlv2密钥hnjdsyxxkj1509065822315090679636
#APlv3密钥
#hnjdsyxxkj1509067963615090658223
dy:
appId: tt59a72f1ac6964bfa01
appSecret: 46882267247ca02561cf899d03adf562aa93ad3e
token: a1b2c3
# 回调接口地址
notifyUrl: https://yitisheng.vip/jbt/mini/pay/v1/payNotify
salt: wODf6Bg5BXndJ3IELXNb1w5CDMRjatXAmZVP2DQ7