Browse Source

提现的一大堆功能

master
nili 4 months ago
parent
commit
c80fdb7647
  1. 9
      game-dao/src/main/java/awesome/group/game/dao/bean/MatrixApp.java
  2. 21
      game-dao/src/main/java/awesome/group/game/dao/bean/MatrixMoneyRecord.java
  3. 2
      game-dao/src/main/java/awesome/group/game/dao/bean/MatrixUser.java
  4. 30
      game-dao/src/main/java/awesome/group/game/dao/mapper/MatrixMoneyRecordMapper.java
  5. 7
      game-dao/src/main/java/awesome/group/game/dao/mapper/MatrixUserMapper.java
  6. 39
      game-service/src/main/java/awesome/group/game/service/ScheduleService.java
  7. 125
      game-service/src/main/java/awesome/group/game/service/UMengService.java
  8. 40
      game-service/src/main/java/awesome/group/game/service/bo/citrus/AppBo.java
  9. 18
      game-service/src/main/java/awesome/group/game/service/bo/citrus/CashRecord.java
  10. 1
      game-service/src/main/java/awesome/group/game/service/bo/citrus/LoginReq.java
  11. 2
      game-service/src/main/java/awesome/group/game/service/bo/citrus/UserBo.java
  12. 9
      game-service/src/main/java/awesome/group/game/service/bo/matrix/AliPayConfigBo.java
  13. 8
      game-service/src/main/java/awesome/group/game/service/bo/matrix/UmengConfigBo.java
  14. 6
      game-service/src/main/java/awesome/group/game/service/bo/matrix/WxConfigBo.java
  15. 18
      game-service/src/main/java/awesome/group/game/service/citrus/CitrusAppService.java
  16. 88
      game-service/src/main/java/awesome/group/game/service/citrus/UserService.java
  17. 114
      game-service/src/main/java/awesome/group/game/service/pay/AlipayFundTransUniTransfer.java
  18. 2
      game-service/src/test/java/awesome/group/game/ServiceTestApplication.java
  19. 18
      game-service/src/test/java/awesome/group/game/service/UMengServiceTest.java
  20. 198
      game-service/src/test/java/awesome/group/game/service/pay/AlipayFundTransUniTransferTest.java
  21. 9
      game-web/src/main/java/awesome/group/game/web/filter/CitrusLoginFilter.java
  22. 24
      game-web/src/main/java/awesome/group/game/web/rest/citrus/CitrusAppController.java
  23. 8
      game-web/src/main/java/awesome/group/game/web/rest/citrus/OpenController.java
  24. 27
      game-web/src/main/java/awesome/group/game/web/rest/citrus/UserController.java

9
game-dao/src/main/java/awesome/group/game/dao/bean/MatrixApp.java

@ -16,4 +16,13 @@ public class MatrixApp {
private String channel; private String channel;
private Integer hide; private Integer hide;
private String secret; private String secret;
private String umeng;//友盟的配置数据
private String aliPay;//支付宝的配置数据
private String wx;//微信的配置数据
private String moneyLadder;
private Integer noAuditMoney;
private String qqUrl;
private Integer dayLimit;//每日提现次数限制
} }

21
game-dao/src/main/java/awesome/group/game/dao/bean/MatrixMoneyRecord.java

@ -0,0 +1,21 @@
package awesome.group.game.dao.bean;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.sql.Timestamp;
@Data
public class MatrixMoneyRecord {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private Integer userId;
private Integer appId;
private Integer cent;
private String aliPayAccount;
private String name;
private String reason;
private Integer status;//0发起申请,1审批成功,2转账中,3转账成功,-1转账失败
private Timestamp createdAt;
}

2
game-dao/src/main/java/awesome/group/game/dao/bean/MatrixUser.java

@ -18,5 +18,5 @@ public class MatrixUser {
private String pwd; private String pwd;
private String inviteCode; private String inviteCode;
private Integer upUid; private Integer upUid;
private Long income; private Long income;//分,累计收益
} }

30
game-dao/src/main/java/awesome/group/game/dao/mapper/MatrixMoneyRecordMapper.java

@ -0,0 +1,30 @@
package awesome.group.game.dao.mapper;
import awesome.group.game.dao.bean.MatrixMoneyRecord;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.sql.Timestamp;
import java.util.List;
public interface MatrixMoneyRecordMapper extends BaseMapper<MatrixMoneyRecord> {
@Select("select count(*) from matrix_money_record where status != -1 and user_id = #{userId} and created_at > #{timestamp}")
int queryAfter(Integer userId, Timestamp timestamp);
@Select("select count(*) from matrix_money_record where status != -1 and ali_pay_account = #{aliPayAccount} and created_at > #{timestamp}")
int queryByAliPayAccount(String aliPayAccount, Timestamp timestamp);
@Select("select * from matrix_money_record where status = #{status}")
List<MatrixMoneyRecord> queryByStatus(Integer status);
@Update("update matrix_money_record set status = #{status} where id = #{id} and status = #{prevStatus}")
int updateStatusWithPrev(int id, int prevStatus, int status);
@Update("update matrix_money_record set status = #{status}, reason=#{reason} where id = #{id}")
int updateStatusAndReason(int id, int status, String reason);
@Select("select * from matrix_money_record where user_id = #{userId}")
List<MatrixMoneyRecord> queryByUserId(Integer userId);
}

7
game-dao/src/main/java/awesome/group/game/dao/mapper/MatrixUserMapper.java

@ -3,6 +3,7 @@ package awesome.group.game.dao.mapper;
import awesome.group.game.dao.bean.MatrixUser; import awesome.group.game.dao.bean.MatrixUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
public interface MatrixUserMapper extends BaseMapper<MatrixUser> { public interface MatrixUserMapper extends BaseMapper<MatrixUser> {
@ -11,4 +12,10 @@ public interface MatrixUserMapper extends BaseMapper<MatrixUser> {
@Select("select * from matrix_user where app_id = #{appId} and mobile = #{mobile}") @Select("select * from matrix_user where app_id = #{appId} and mobile = #{mobile}")
MatrixUser selectByAppIdAndMobile(int appId, String mobile); MatrixUser selectByAppIdAndMobile(int appId, String mobile);
@Update("update matrix_user set money = money + #{cent} where id = #{userId}")
int incMoney(int userId, int cent);
@Update("update matrix_user set ali_pay_account = #{aliPayAccount}, name = #{name} where id = #{userId}")
int updateAliPayAccount(int userId, String aliPayAccount, String name);
} }

39
game-service/src/main/java/awesome/group/game/service/ScheduleService.java

@ -0,0 +1,39 @@
package awesome.group.game.service;
import awesome.group.game.dao.bean.MatrixMoneyRecord;
import awesome.group.game.dao.mapper.MatrixMoneyRecordMapper;
import awesome.group.game.dao.mapper.MatrixUserMapper;
import awesome.group.game.service.citrus.UserService;
import awesome.group.game.service.pay.AlipayFundTransUniTransfer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ScheduleService {
@Autowired
private MatrixMoneyRecordMapper moneyRecordMapper;
@Autowired
private AlipayFundTransUniTransfer aliTransfer;
@Autowired
private MatrixUserMapper userMapper;
@Scheduled(cron = "0 0/1 * * * ?")
public void transfer() {
List<MatrixMoneyRecord> list = moneyRecordMapper.queryByStatus(UserService.STATUS_AUDIT_PASS);
for (MatrixMoneyRecord r : list) {
int rows = moneyRecordMapper.updateStatusWithPrev(r.getId(), UserService.STATUS_AUDIT_PASS, UserService.STATUS_TRANSFERRING);
if (rows < 1) {
continue;
}
boolean success = aliTransfer.transfer(r);
moneyRecordMapper.updateStatusAndReason(r.getId(), r.getStatus(), r.getReason());
if (!success) {
userMapper.incMoney(r.getUserId(), -r.getCent());
}
}
}
}

125
game-service/src/main/java/awesome/group/game/service/UMengService.java

@ -0,0 +1,125 @@
package awesome.group.game.service;
import awesome.group.game.service.common.exception.PaganiException;
import awesome.group.game.service.common.exception.PaganiExceptionCode;
import awesome.group.game.service.common.log.L;
import com.google.gson.Gson;
import okhttp3.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@Service
public class UMengService {
public static final String APP_KEY = "24785365";//阿里云
public static final String APP_SECRET = "7e3a9e8ae85cd8c1ff58343e241ec154";
public static final String APP_CODE = "2c62d2208aa640f09a55449efa634424";
public static final String APP_KEY_UMENT = "66403e5dcac2a664de3234d4";//友盟
public static final String API_PREFIX = "https://verify5.market.alicloudapi.com";
public static Gson gson = new Gson();
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
private final OkHttpClient httpClient = new OkHttpClient().newBuilder().connectTimeout(2, TimeUnit.SECONDS).readTimeout(5, TimeUnit.SECONDS).connectionPool(new ConnectionPool(8, 5, TimeUnit.MINUTES)).build();
public String getMobile(String token) {
Map<String, Object> data = new HashMap<>();
data.put("token", token);
String api = "/api/v1/mobile/info?appkey=" + APP_KEY_UMENT;
String res = doHttpPost(api, data);
System.out.println(res);
return res;
}
public String doHttpPost(String url, Map<String, Object> jsonBody) {
Map<String, String> header = new HashMap<>();
String body = gson.toJson(jsonBody);
header.put("Content-Type", "application/json; charset=utf-8");
header.put("Accept", "application/json");
header.put("X-Ca-Version", "1");
header.put("X-Ca-Signature-Headers", "X-Ca-Version,X-Ca-Stage,X-Ca-Key,X-Ca-Timestamp");
header.put("X-Ca-Stage", "RELEASE");
header.put("X-Ca-Key", APP_KEY);
header.put("X-Ca-Timestamp", String.valueOf(System.currentTimeMillis()));
header.put("X-Ca-Nonce", UUID.randomUUID().toString());
header.put("Content-MD5", Base64.encodeBase64String(DigestUtils.md5(body.getBytes())));
/**
* sign
*/
String stringToSign = getSignString(header, "POST", url);
try {
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
byte[] keyBytes = APP_SECRET.getBytes(StandardCharsets.UTF_8);
hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, "HmacSHA256"));
String sign = new String(Base64.encodeBase64(hmacSha256.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8))));
header.put("X-Ca-Signature", sign);
return postJson(url, jsonBody, header);
} catch (InvalidKeyException | NoSuchAlgorithmException e) {
throw new PaganiException(PaganiExceptionCode.GENERAL_ERROR, "验证失败,请重试");
}
}
private static String getSignString(Map<String, String> header, String method, String url) {
return method.toUpperCase() + "\n" +
header.get("Accept") + "\n" +
header.get("Content-MD5") + "\n" +
header.get("Content-Type") + "\n\n" +
"X-Ca-Key:" + header.get("X-Ca-Key") + "\n" +
"X-Ca-Stage:" + header.get("X-Ca-Stage") + "\n" +
"X-Ca-Timestamp:" + header.get("X-Ca-Timestamp") + "\n" +
"X-Ca-Version:" + header.get("X-Ca-Version") + "\n" +
url;
}
private String postJson(String url, Map<String, Object> body, Map<String, String> headers) {
String bodyStr = gson.toJson(body);
RequestBody requestBody = RequestBody.create(JSON, bodyStr);
if (!url.startsWith("http")) {
url = API_PREFIX + url;
}
HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
Request.Builder requestBuilder = new Request.Builder().post(requestBody).url(urlBuilder.build());
if (!CollectionUtils.isEmpty(headers)) {
headers.forEach(requestBuilder::addHeader);
}
Request request = requestBuilder.build();
String msg = "url:" + url + ",header:" + gson.toJson(headers) + ", body:" + bodyStr;
return doHttpExecute(msg, request);
}
private String doHttpExecute(String msg, Request request) {
try (Response resp = httpClient.newCall(request).execute()) {
if (!resp.isSuccessful() || resp.body() == null) {
L.trace("request_umeng_error", msg + ",resp:" + resp);
throw new PaganiException(PaganiExceptionCode.GENERAL_ERROR, "友盟请求失败");
}
return Objects.requireNonNull(resp.body()).string();
} catch (IOException ioe) {
L.trace("request_umeng_error", msg, ioe);
throw new PaganiException(PaganiExceptionCode.GENERAL_ERROR, ioe.getMessage(), ioe);
}
}
}

40
game-service/src/main/java/awesome/group/game/service/bo/citrus/AppBo.java

@ -0,0 +1,40 @@
package awesome.group.game.service.bo.citrus;
import awesome.group.game.dao.bean.MatrixApp;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.springframework.util.StringUtils;
import java.util.Arrays;
import java.util.List;
public class AppBo {
public List<Integer> moneyLadder;//提现梯度,单位分
public Integer noAuditMoney;//不需审核的金额,单位分
public String qqUrl;//qq客服链接
public Integer dayLimit;//每日提现次数
public AppBo() {
}
public AppBo(MatrixApp app) {
Gson gson = new Gson();
if (StringUtils.hasText(app.getMoneyLadder())) {
this.moneyLadder = gson.fromJson(app.getMoneyLadder(), new TypeToken<List<Long>>() {
}.getType());
} else {
moneyLadder = Arrays.asList(30, 50, 100, 10000, 30000, 50000);
}
if (app.getNoAuditMoney() != null) {
this.noAuditMoney = app.getNoAuditMoney();
} else {
this.noAuditMoney = 30;
}
this.qqUrl = app.getQqUrl();
if (app.getDayLimit() != null) {
this.dayLimit = app.getDayLimit();
} else {
this.dayLimit = 3;
}
}
}

18
game-service/src/main/java/awesome/group/game/service/bo/citrus/CashRecord.java

@ -0,0 +1,18 @@
package awesome.group.game.service.bo.citrus;
import awesome.group.game.dao.bean.MatrixMoneyRecord;
public class CashRecord {
public Integer cent;//提现金额,分
public Long createTime;//提现时间,时间戳, 毫秒
public Integer status;//0发起申请,1审批成功,2转账中,3转账成功,-1转账失败
public CashRecord() {
}
public CashRecord(MatrixMoneyRecord r) {
this.cent = r.getCent();
this.createTime = r.getCreatedAt().getTime();
this.status = r.getStatus();
}
}

1
game-service/src/main/java/awesome/group/game/service/bo/citrus/LoginReq.java

@ -5,5 +5,6 @@ public class LoginReq {
public String pwd; public String pwd;
public String appCode; public String appCode;
public String code;//验证码 public String code;//验证码
public String token;//友盟token
} }

2
game-service/src/main/java/awesome/group/game/service/bo/citrus/UserBo.java

@ -11,6 +11,7 @@ public class UserBo {
public Integer money;//分,已提现金额 public Integer money;//分,已提现金额
public String aliPayAccount; public String aliPayAccount;
public Long income;//ecpm和,分 public Long income;//ecpm和,分
public Long goldCoin;//金币
public String inviteCode; public String inviteCode;
public String inviteUrl; public String inviteUrl;
@ -28,5 +29,6 @@ public class UserBo {
this.nickname = u.getNickname(); this.nickname = u.getNickname();
this.avatar = u.getAvatar(); this.avatar = u.getAvatar();
this.money = u.getMoney(); this.money = u.getMoney();
this.goldCoin = u.getIncome() - (u.getMoney() * 1000);
} }
} }

9
game-service/src/main/java/awesome/group/game/service/bo/matrix/AliPayConfigBo.java

@ -0,0 +1,9 @@
package awesome.group.game.service.bo.matrix;
public class AliPayConfigBo {
public String aliPayPublicCert;
public String aliPayRootCert;
public String aliPayAppCert;
public String aliPayPrivateKey;
public String aliPayAppId;
}

8
game-service/src/main/java/awesome/group/game/service/bo/matrix/UmengConfigBo.java

@ -0,0 +1,8 @@
package awesome.group.game.service.bo.matrix;
public class UmengConfigBo {
public String umengAppKeyAli;
public String umengAppSecret;
public String umengAppCode;
public String umengAppKey;
}

6
game-service/src/main/java/awesome/group/game/service/bo/matrix/WxConfigBo.java

@ -0,0 +1,6 @@
package awesome.group.game.service.bo.matrix;
public class WxConfigBo {
public String wxAppId;
public String wxAppSecret;
}

18
game-service/src/main/java/awesome/group/game/service/citrus/CitrusAppService.java

@ -0,0 +1,18 @@
package awesome.group.game.service.citrus;
import awesome.group.game.dao.bean.MatrixApp;
import awesome.group.game.dao.mapper.MatrixAppMapper;
import awesome.group.game.service.bo.citrus.AppBo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class CitrusAppService {
@Autowired
private MatrixAppMapper appMapper;
public AppBo getAppDetail(String appCode) {
MatrixApp app = appMapper.queryByCode(appCode);
return new AppBo(app);
}
}

88
game-service/src/main/java/awesome/group/game/service/citrus/UserService.java

@ -1,20 +1,32 @@
package awesome.group.game.service.citrus; package awesome.group.game.service.citrus;
import awesome.group.game.dao.bean.MatrixApp; import awesome.group.game.dao.bean.MatrixApp;
import awesome.group.game.dao.bean.MatrixMoneyRecord;
import awesome.group.game.dao.bean.MatrixUser; import awesome.group.game.dao.bean.MatrixUser;
import awesome.group.game.dao.mapper.MatrixAppMapper; import awesome.group.game.dao.mapper.MatrixAppMapper;
import awesome.group.game.dao.mapper.MatrixMoneyRecordMapper;
import awesome.group.game.dao.mapper.MatrixUserMapper; import awesome.group.game.dao.mapper.MatrixUserMapper;
import awesome.group.game.service.SmsService; import awesome.group.game.service.SmsService;
import awesome.group.game.service.bo.citrus.AppBo;
import awesome.group.game.service.bo.citrus.CashRecord;
import awesome.group.game.service.bo.citrus.LoginReq; import awesome.group.game.service.bo.citrus.LoginReq;
import awesome.group.game.service.bo.citrus.UserBo; import awesome.group.game.service.bo.citrus.UserBo;
import awesome.group.game.service.common.exception.PaganiException; import awesome.group.game.service.common.exception.PaganiException;
import awesome.group.game.service.common.exception.PaganiExceptionCode; import awesome.group.game.service.common.exception.PaganiExceptionCode;
import awesome.group.game.service.util.DateUtil;
import awesome.group.game.service.util.EncryptUtil; import awesome.group.game.service.util.EncryptUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.sql.Timestamp;
import java.util.List;
@Service @Service
public class UserService { public class UserService {
@Autowired @Autowired
@ -26,6 +38,22 @@ public class UserService {
@Autowired @Autowired
private SmsService smsService; private SmsService smsService;
@Autowired
private MatrixMoneyRecordMapper moneyRecordMapper;
@Lazy
@Autowired
private UserService userService;
public static final int STATUS_WAITING = 0;//等审核
public static final int STATUS_AUDIT_PASS = 1;//已审核通过
public static final int STATUS_TRANSFERRING = 2;//转账中
public static final int TRANSFER_SUCCESS = 3;
public static final int TRANSFER_FAIL = -1;
public MatrixUser login(LoginReq req) { public MatrixUser login(LoginReq req) {
Assert.isTrue(req != null, "非法请求"); Assert.isTrue(req != null, "非法请求");
Assert.isTrue(StringUtils.hasText(req.mobile), "非法请求"); Assert.isTrue(StringUtils.hasText(req.mobile), "非法请求");
@ -56,8 +84,68 @@ public class UserService {
return user; return user;
} }
public MatrixUser loginByToken(String appCode, String token) {
Assert.isTrue(StringUtils.hasText(appCode), "非法请求");
Assert.isTrue(StringUtils.hasText(token), "非法请求");
MatrixApp app = appMapper.queryByCode(appCode);
Assert.isTrue(app != null, "非法请求");
LambdaQueryWrapper<MatrixUser> wrapper = Wrappers.lambdaQuery();
wrapper.eq(MatrixUser::getAppId, app.getId());
return userMapper.selectOne(wrapper);
}
public UserBo getUser(Integer uid) { public UserBo getUser(Integer uid) {
MatrixUser u = userMapper.selectById(uid); MatrixUser u = userMapper.selectById(uid);
return new UserBo(u); return new UserBo(u);
} }
public void bindAliPay(Integer uid, String name, String aliPayAccount) {
Assert.isTrue(StringUtils.hasText(aliPayAccount), "支付宝账号不能为空");
Assert.isTrue(StringUtils.hasText(name), "支付宝账号姓名不能为空");
MatrixUser u = userMapper.selectById(uid);
Assert.isTrue(u != null, "非法请求");
userMapper.updateAliPayAccount(uid, aliPayAccount, name);
}
public List<CashRecord> getCashRecord(Integer uid) {
List<MatrixMoneyRecord> list = moneyRecordMapper.queryByUserId(uid);
return list.stream().map(CashRecord::new).toList();
}
public void applyMoney(Integer uid, Integer cent) {
Assert.isTrue(cent >= 10, "至少提0.1元");
MatrixUser u = userMapper.selectById(uid);
Assert.isTrue(u != null, "非法请求");
Assert.isTrue(u.getMoney() + cent <= u.getIncome(), "余额不足");
String aliPayAccount = u.getAliPayAccount();
Assert.isTrue(StringUtils.hasText(aliPayAccount), "请先绑定支付宝账号");
Assert.isTrue(StringUtils.hasText(u.getName()), "请先填写支付宝实名姓名");
MatrixApp app = appMapper.selectById(u.getAppId());
AppBo appBo = new AppBo(app);
Assert.isTrue(appBo.moneyLadder.contains(cent), "提现金额不合法");
Timestamp todayBegin = new Timestamp(DateUtil.getDayBeginTimestamp(System.currentTimeMillis()));
int size = moneyRecordMapper.queryAfter(uid, todayBegin);
Assert.isTrue(size < appBo.dayLimit, "每天最多提现" + appBo.dayLimit + "次");
size = moneyRecordMapper.queryByAliPayAccount(aliPayAccount, todayBegin);
Assert.isTrue(size < appBo.dayLimit, "每天最多提现" + appBo.dayLimit + "次");
userService.doApply(u, app.getNoAuditMoney(), cent);
}
@Transactional
public void doApply(MatrixUser u, Integer noAuditMoney, Integer cent) {
int uid = u.getId();
MatrixMoneyRecord record = new MatrixMoneyRecord();
record.setUserId(uid);
record.setAppId(u.getAppId());
record.setCent(cent);
record.setAliPayAccount(u.getAliPayAccount());
record.setName(u.getName());
record.setStatus(cent <= noAuditMoney ? STATUS_AUDIT_PASS : STATUS_WAITING);
userMapper.incMoney(uid, cent);
u = userMapper.selectById(uid);
Assert.isTrue(u.getMoney() <= u.getIncome(), "余额不足");
moneyRecordMapper.insert(record);
}
} }

114
game-service/src/main/java/awesome/group/game/service/pay/AlipayFundTransUniTransfer.java

@ -0,0 +1,114 @@
package awesome.group.game.service.pay;
import awesome.group.game.dao.bean.MatrixApp;
import awesome.group.game.dao.bean.MatrixMoneyRecord;
import awesome.group.game.dao.mapper.MatrixAppMapper;
import awesome.group.game.service.bo.matrix.AliPayConfigBo;
import awesome.group.game.service.citrus.UserService;
import awesome.group.game.service.common.log.L;
import awesome.group.game.service.util.DateUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayFundTransUniTransferModel;
import com.alipay.api.domain.Participant;
import com.alipay.api.request.AlipayFundTransUniTransferRequest;
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.google.gson.Gson;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class AlipayFundTransUniTransfer {
@Autowired
private MatrixAppMapper appMapper;
private Map<Integer, AlipayClient> appPayClientMap = new HashMap<>();
private Gson gson = new Gson();
@PostConstruct
public void init() {
List<MatrixApp> appList = appMapper.selectList(null);
for (MatrixApp app : appList) {
if (StringUtils.hasText(app.getAliPay())) {
AliPayConfigBo configBo = gson.fromJson(app.getAliPay(), AliPayConfigBo.class);
CertAlipayRequest alipayConfig = getAlipayConfig(configBo);
try {
AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
appPayClientMap.put(app.getId(), alipayClient);
} catch (AlipayApiException e) {
L.trace("initAliPayClientError", "app:" + gson.toJson(app), e);
}
}
}
}
//文档:https://opendocs.alipay.com/open/309/106236?pathHash=97724ae4#%E8%BD%AC%E8%B4%A6%E5%92%8C%E9%80%9A%E7%9F%A5
public boolean transfer(MatrixMoneyRecord record) {
AlipayClient alipayClient = appPayClientMap.get(record.getAppId());
if (alipayClient == null) {
L.trace("transferError", "app:" + record.getAppId() + "提现未开启或配置错误");
return false;
}
MatrixApp app = appMapper.selectById(record.getAppId());
try {
AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
model.setOrderTitle(app.getName() + "-提现");
model.setBizScene("DIRECT_TRANSFER");
model.setBusinessParams("{\"payer_show_name_use_alias\":\"true\"}");
model.setRemark(app.getName() + "-提现");
String orderNo = String.format("%08d", record.getId());
model.setOutBizNo(DateUtil.currentDate() + orderNo);//最小可传金额 0.1 元,
model.setTransAmount(String.format("%.2f", record.getCent() / 100.0));
model.setProductCode("TRANS_ACCOUNT_NO_PWD");
Participant payeeInfo = new Participant();
payeeInfo.setIdentity(record.getAliPayAccount());
payeeInfo.setName(record.getName());
payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
model.setPayeeInfo(payeeInfo);
request.setBizModel(model);
AlipayFundTransUniTransferResponse response = alipayClient.certificateExecute(request);
if (response.isSuccess()) {
record.setStatus(UserService.TRANSFER_SUCCESS);
return true;
} else {
record.setStatus(UserService.TRANSFER_FAIL);
String reason = response.getCode() + "," + response.getMsg();
record.setReason(reason);
return false;
}
} catch (AlipayApiException e) {
L.trace("transferError", "record:" + gson.toJson(record), e);
record.setReason("转账失败");
record.setStatus(UserService.TRANSFER_FAIL);
return false;
}
}
private static CertAlipayRequest getAlipayConfig(AliPayConfigBo bo) {
String privateKey = bo.aliPayPrivateKey;
CertAlipayRequest alipayConfig = new CertAlipayRequest();
alipayConfig.setPrivateKey(privateKey);
alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
alipayConfig.setAppId(bo.aliPayAppId);
alipayConfig.setCharset("UTF-8");
alipayConfig.setSignType("RSA2");
alipayConfig.setFormat("json");
alipayConfig.setAlipayPublicCertContent(bo.aliPayPublicCert);
alipayConfig.setCertContent(bo.aliPayAppCert);
alipayConfig.setRootCertContent(bo.aliPayRootCert);
return alipayConfig;
}
}

2
game-service/src/test/java/awesome/group/game/ServiceTestApplication.java

@ -2,11 +2,13 @@ package awesome.group.game;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/** /**
* @author nidaren * @author nidaren
*/ */
@SpringBootApplication @SpringBootApplication
@EnableScheduling
public class ServiceTestApplication { public class ServiceTestApplication {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {

18
game-service/src/test/java/awesome/group/game/service/UMengServiceTest.java

@ -0,0 +1,18 @@
package awesome.group.game.service;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import static org.junit.jupiter.api.Assertions.*;
class UMengServiceTest extends BaseTest{
@Autowired
private UMengService uMengService;
@Test
void getMobile() {
String token = "eyJjIjoiNmk5amtxSVwvNXhXRElTRkNIeUpcL1RTemNjTEJsOEtiWndkT0NEYlhkUFJQREUzZ3g1bWx1bmNYdzRtclBWODVYOEludnJzS1pTOTRRXG53ejRudVlSaUs4cTFtRUdcL2FPQ0tIRktiUUtuS2Iya0ZFWjlyNWpPV044R0w3Q2I3V1g5dDA0ays2dmJwUXpaNGVTMklyOTJJcGtqaVxudm0rVG5vWVVVZWl4ZHhNNDArZ0hlaXBFRUpnUjlQNjhyZzY1VitrU1wvaWFQbXMxM3h4dEtGd2c3OVAwcVJ3VTZ1cFZcL2tUcXNvYTBOXG5jTDBtNThZc042RlwvcmZwcjJqbDVOZk1SdG1WdWFWTG1RVkVicHF3b2tUMWdiQk1UR0I4TDRIcHlhYUhyUXJUNnJQTG9kbDNWbjlNN1xudEFTZHRsU0JmMDYyVVVRSkZuZE9DeEZRN2diZ2JrRDNyYllBcXZ2cVZMUmFYWGlhNDNONGp6SnhTemJ0TnprM3ZTTmlrR0hHNFlaVlxuWXFJMlBcL3dlYlJucnlFRFlGQzhhaUVwdzB2R2UyRENcL3ZWNTdNMTlvN3VBVjFGaXFYUFpOSFFrdUVIcUFwRkpUUjBOODlRQ1Q0Qmw1XG5abmRsV2hyM1JWWTlRZWZSN3Nva0hjQjlHV1c0WlZWWXcyY0VFSDhIcHp5bmJlKzY2ZlwvbHpZZlJPUm5QUTNSdFpVV3dpNmFJNVd4M1xuY3F5ZVZjdEVCaTB6U1V5Y2tiVlRrXC90N0JaTlpMVkwyaHRKNzBXOXhXVnZRSU5LUloyOE1wc3M2bXNBNFlGa2gxdz09XG4iLCJrIjoiQ0ZZbm81SDNwSVJKK1FPMHhHZzZrU2FteGU2RXE5NDBxa0VoZXF1VHBiajlnSHl0UFwvNEdsQzh4R1lCYW04T093TVpoTElWSER5VVpvSThySFBOejRcL1ZKdm9XWXhwMEVNcWpyRkF0anV1cENDb1RKWUMzVWtXTmpMUkRLcG1za3Y2RHBjc2lBeHRvZnBPdVwvak04ZnR2dFhJOFBDQVwvU0Q4cHFENytKZDdqXC81Z0VQTUFndGgrdnZOYnp4VThrbU5cL01SVmRXK2FpUlFZSGswVFRZUnZ6eEJONDYwMCtDRjd2Vlh3djVcL1RUTmNBUmxCZkpkTFZnUnpnSFBjSE03Qk1NRzFRRW5PV3BGcjAyd29NS1dUdHZ6NndxYWdnQU9WeWFkdmgrRzg4eU9TRGNaTXBxbG5xOGtXQlFoY2QrampTZjRZaDdiOGNpdUZubWlzYmlXUmpmdz09IiwibyI6IkFuZHJvaWQifQ==";
uMengService.getMobile(token);
}
}

198
game-service/src/test/java/awesome/group/game/service/pay/AlipayFundTransUniTransferTest.java

@ -0,0 +1,198 @@
package awesome.group.game.service.pay;
import awesome.group.game.dao.bean.MatrixMoneyRecord;
import awesome.group.game.service.BaseTest;
import awesome.group.game.service.bo.matrix.AliPayConfigBo;
import awesome.group.game.service.citrus.UserService;
import com.alipay.api.AlipayApiException;
import com.google.gson.Gson;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
class AlipayFundTransUniTransferTest extends BaseTest {
@Autowired
private AlipayFundTransUniTransfer alipayFundTransUniTransfer;
@Autowired
private UserService userService;
@Test
void test1() throws AlipayApiException {
MatrixMoneyRecord matrixMoneyRecord = new MatrixMoneyRecord();
matrixMoneyRecord.setAppId(6);
matrixMoneyRecord.setAliPayAccount("19181749767");
matrixMoneyRecord.setName("倪丽");
matrixMoneyRecord.setCent(10);
alipayFundTransUniTransfer.transfer(matrixMoneyRecord);
}
@Test
public void testApply() {
userService.applyMoney(3, 10);
}
@Test
public void genGson() {
AliPayConfigBo bo = new AliPayConfigBo();
bo.aliPayAppId = "2021004143647533";
bo.aliPayPrivateKey = "MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQCeU75wMTR1FUEbptIFgk9/aR+lPgMWVsONuj1JnRADqz/3AiNvDiXm20V75aZ/mUf+LaPx2su3wn2JoVr5reIOvx797Tb9JiUn/ucBx5p0lcEQbkMEh+PzXAZK6miRS4thgLEWbfrcVV7TTvGvlKiBVVPPfOfEmaqd/qX0aen9bOJ6/HH8EnTb19yckTK9xNO4WK4SqD66Xr649KyRteeeqx62ClbIU04ZMbywlmvkF1sjQbMI7MHMfHDHuI+3SuxQHY6INZwvG8Fua/6c4xCpAijjO0PnOlm5aZ7CxxwaxQva/jfHAQ7mq5xuvs1pyvtkhDF6md/RIqgFXM+w1VHDAgMBAAECggEBAJkz/7sgYdpJzs6rBd8+0R5A4tZKw0ICgwfJhzSMPsrOEv85moAD+LkCxKG2/v3JnNhf4ZxOU4JlOITNFfM0RuJuHdcoi2U6XAnvpikatGLL5h24FDF2LSV3jr8/RCAUMbMPjExf77b1BOUEJun3t3Yu0wKbosmiyG5J0txHAJywDS08+2udQSIvg4/BY67qCBbQeBx7sqMvnxatNAbjV7VdVDL2gl3MIS8MMlImBEsMWWcejEts8+XetxGVPJXhUr0yraWcnCCvReZxWhzdMNnmEWepsyj8ky6Q/L86i0s4OFPMfgk6lCTvGqqV2XJnr5k7KDVArCPUi80qHbHP6IECgYEA7ViPC+7zswwAvDoWOrIzZsCs9LQa7vZcPNzxnhjGg1OAx2W/h03u5x9kHETYiIAvZZh/cC3sj605r3JkvQstasO9xXG8qyWUpntEmnlFncgflkEW5Ou6dtbAEyMx+FMM+cl+tHMQsmnsL5hnhOkjP+R0XBATSU8iUCXRcJRoCTsCgYEAqsVQIxHVGyQovojkG0cIJRu94Mf6kWzenmHrslGzGm7MY7awEKnnXH/eepxHgJBwGHiLeb+cHgX+6prO58fM3RwYkHEVDAvnYabxATIFcmXQeXPiMBRmW0yzgtadlz4hJKdj/ZKOSvxMdSmYNih8cw8+0Q3/dhka/ORlo8k2kRkCgYBJiSOgzeMBeVmM9+5FN0sHrfCoTFj/6qJ/VPEjS4fNzoRawyKJOFMplqc8vvPbruOAdbQePIxLo574xdeCXsEukADu+KM834Lj5dNGjQZNsWBf/ECsooB+K2ENTN1Bk/G0PoKcQ/5LWNgNkwmXu2fpds26bFydXQBDlsQCPmjRWwKBgCdrVIxD2YViW2VgBAen5eFq/fGdN+HJ17mHsPiAk29OlC+QRCQUlCtt+NUkrfynWrjLWqbH7CmiCK3u/kPSgx+nFKSC9fDJ7qdD+e3ktg0qI21lqpienOIGWomhMM9wsAXd/d7SrbXxd1S0PUaDIfcNVdq7+HQyZ2Bo+G1OTSJBAn8QuGVOuCOUHYUSyOi+GJu9W3nJuqr1e6TuN3cY3/uGjTHkaBKgea6vT46jQC4yyM17sZz8F9FjJ1XN2jkUJnBMPFCQtmjSZqJBDSxl1UqLWtIEUKC4eKp6O9lc0msH/5dpO/klRVAonG2ksNn1/GxCzvJQOqwcGysikcSMBX2F";
bo.aliPayRootCert = "-----BEGIN CERTIFICATE-----\n" +
"MIIBszCCAVegAwIBAgIIaeL+wBcKxnswDAYIKoEcz1UBg3UFADAuMQswCQYDVQQG\n" +
"EwJDTjEOMAwGA1UECgwFTlJDQUMxDzANBgNVBAMMBlJPT1RDQTAeFw0xMjA3MTQw\n" +
"MzExNTlaFw00MjA3MDcwMzExNTlaMC4xCzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVO\n" +
"UkNBQzEPMA0GA1UEAwwGUk9PVENBMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE\n" +
"MPCca6pmgcchsTf2UnBeL9rtp4nw+itk1Kzrmbnqo05lUwkwlWK+4OIrtFdAqnRT\n" +
"V7Q9v1htkv42TsIutzd126NdMFswHwYDVR0jBBgwFoAUTDKxl9kzG8SmBcHG5Yti\n" +
"W/CXdlgwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFEwysZfZ\n" +
"MxvEpgXBxuWLYlvwl3ZYMAwGCCqBHM9VAYN1BQADSAAwRQIgG1bSLeOXp3oB8H7b\n" +
"53W+CKOPl2PknmWEq/lMhtn25HkCIQDaHDgWxWFtnCrBjH16/W3Ezn7/U/Vjo5xI\n" +
"pDoiVhsLwg==\n" +
"-----END CERTIFICATE-----\n" +
"\n" +
"-----BEGIN CERTIFICATE-----\n" +
"MIIF0zCCA7ugAwIBAgIIH8+hjWpIDREwDQYJKoZIhvcNAQELBQAwejELMAkGA1UE\n" +
"BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmlj\n" +
"YXRpb24gQXV0aG9yaXR5MTEwLwYDVQQDDChBbnQgRmluYW5jaWFsIENlcnRpZmlj\n" +
"YXRpb24gQXV0aG9yaXR5IFIxMB4XDTE4MDMyMTEzNDg0MFoXDTM4MDIyODEzNDg0\n" +
"MFowejELMAkGA1UEBhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNV\n" +
"BAsMF0NlcnRpZmljYXRpb24gQXV0aG9yaXR5MTEwLwYDVQQDDChBbnQgRmluYW5j\n" +
"aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFIxMIICIjANBgkqhkiG9w0BAQEF\n" +
"AAOCAg8AMIICCgKCAgEAtytTRcBNuur5h8xuxnlKJetT65cHGemGi8oD+beHFPTk\n" +
"rUTlFt9Xn7fAVGo6QSsPb9uGLpUFGEdGmbsQ2q9cV4P89qkH04VzIPwT7AywJdt2\n" +
"xAvMs+MgHFJzOYfL1QkdOOVO7NwKxH8IvlQgFabWomWk2Ei9WfUyxFjVO1LVh0Bp\n" +
"dRBeWLMkdudx0tl3+21t1apnReFNQ5nfX29xeSxIhesaMHDZFViO/DXDNW2BcTs6\n" +
"vSWKyJ4YIIIzStumD8K1xMsoaZBMDxg4itjWFaKRgNuPiIn4kjDY3kC66Sl/6yTl\n" +
"YUz8AybbEsICZzssdZh7jcNb1VRfk79lgAprm/Ktl+mgrU1gaMGP1OE25JCbqli1\n" +
"Pbw/BpPynyP9+XulE+2mxFwTYhKAwpDIDKuYsFUXuo8t261pCovI1CXFzAQM2w7H\n" +
"DtA2nOXSW6q0jGDJ5+WauH+K8ZSvA6x4sFo4u0KNCx0ROTBpLif6GTngqo3sj+98\n" +
"SZiMNLFMQoQkjkdN5Q5g9N6CFZPVZ6QpO0JcIc7S1le/g9z5iBKnifrKxy0TQjtG\n" +
"PsDwc8ubPnRm/F82RReCoyNyx63indpgFfhN7+KxUIQ9cOwwTvemmor0A+ZQamRe\n" +
"9LMuiEfEaWUDK+6O0Gl8lO571uI5onYdN1VIgOmwFbe+D8TcuzVjIZ/zvHrAGUcC\n" +
"AwEAAaNdMFswCwYDVR0PBAQDAgEGMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFF90\n" +
"tATATwda6uWx2yKjh0GynOEBMB8GA1UdIwQYMBaAFF90tATATwda6uWx2yKjh0Gy\n" +
"nOEBMA0GCSqGSIb3DQEBCwUAA4ICAQCVYaOtqOLIpsrEikE5lb+UARNSFJg6tpkf\n" +
"tJ2U8QF/DejemEHx5IClQu6ajxjtu0Aie4/3UnIXop8nH/Q57l+Wyt9T7N2WPiNq\n" +
"JSlYKYbJpPF8LXbuKYG3BTFTdOVFIeRe2NUyYh/xs6bXGr4WKTXb3qBmzR02FSy3\n" +
"IODQw5Q6zpXj8prYqFHYsOvGCEc1CwJaSaYwRhTkFedJUxiyhyB5GQwoFfExCVHW\n" +
"05ZFCAVYFldCJvUzfzrWubN6wX0DD2dwultgmldOn/W/n8at52mpPNvIdbZb2F41\n" +
"T0YZeoWnCJrYXjq/32oc1cmifIHqySnyMnavi75DxPCdZsCOpSAT4j4lAQRGsfgI\n" +
"kkLPGQieMfNNkMCKh7qjwdXAVtdqhf0RVtFILH3OyEodlk1HYXqX5iE5wlaKzDop\n" +
"PKwf2Q3BErq1xChYGGVS+dEvyXc/2nIBlt7uLWKp4XFjqekKbaGaLJdjYP5b2s7N\n" +
"1dM0MXQ/f8XoXKBkJNzEiM3hfsU6DOREgMc1DIsFKxfuMwX3EkVQM1If8ghb6x5Y\n" +
"jXayv+NLbidOSzk4vl5QwngO/JYFMkoc6i9LNwEaEtR9PhnrdubxmrtM+RjfBm02\n" +
"77q3dSWFESFQ4QxYWew4pHE0DpWbWy/iMIKQ6UZ5RLvB8GEcgt8ON7BBJeMc+Dyi\n" +
"kT9qhqn+lw==\n" +
"-----END CERTIFICATE-----\n" +
"\n" +
"-----BEGIN CERTIFICATE-----\n" +
"MIICiDCCAgygAwIBAgIIQX76UsB/30owDAYIKoZIzj0EAwMFADB6MQswCQYDVQQG\n" +
"EwJDTjEWMBQGA1UECgwNQW50IEZpbmFuY2lhbDEgMB4GA1UECwwXQ2VydGlmaWNh\n" +
"dGlvbiBBdXRob3JpdHkxMTAvBgNVBAMMKEFudCBGaW5hbmNpYWwgQ2VydGlmaWNh\n" +
"dGlvbiBBdXRob3JpdHkgRTEwHhcNMTkwNDI4MTYyMDQ0WhcNNDkwNDIwMTYyMDQ0\n" +
"WjB6MQswCQYDVQQGEwJDTjEWMBQGA1UECgwNQW50IEZpbmFuY2lhbDEgMB4GA1UE\n" +
"CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxMTAvBgNVBAMMKEFudCBGaW5hbmNp\n" +
"YWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRTEwdjAQBgcqhkjOPQIBBgUrgQQA\n" +
"IgNiAASCCRa94QI0vR5Up9Yr9HEupz6hSoyjySYqo7v837KnmjveUIUNiuC9pWAU\n" +
"WP3jwLX3HkzeiNdeg22a0IZPoSUCpasufiLAnfXh6NInLiWBrjLJXDSGaY7vaokt\n" +
"rpZvAdmjXTBbMAsGA1UdDwQEAwIBBjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBRZ\n" +
"4ZTgDpksHL2qcpkFkxD2zVd16TAfBgNVHSMEGDAWgBRZ4ZTgDpksHL2qcpkFkxD2\n" +
"zVd16TAMBggqhkjOPQQDAwUAA2gAMGUCMQD4IoqT2hTUn0jt7oXLdMJ8q4vLp6sg\n" +
"wHfPiOr9gxreb+e6Oidwd2LDnC4OUqCWiF8CMAzwKs4SnDJYcMLf2vpkbuVE4dTH\n" +
"Rglz+HGcTLWsFs4KxLsq7MuU+vJTBUeDJeDjdA==\n" +
"-----END CERTIFICATE-----\n" +
"\n" +
"-----BEGIN CERTIFICATE-----\n" +
"MIIDxTCCAq2gAwIBAgIUEMdk6dVgOEIS2cCP0Q43P90Ps5YwDQYJKoZIhvcNAQEF\n" +
"BQAwajELMAkGA1UEBhMCQ04xEzARBgNVBAoMCmlUcnVzQ2hpbmExHDAaBgNVBAsM\n" +
"E0NoaW5hIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMMH2lUcnVzQ2hpbmEgQ2xhc3Mg\n" +
"MiBSb290IENBIC0gRzMwHhcNMTMwNDE4MDkzNjU2WhcNMzMwNDE4MDkzNjU2WjBq\n" +
"MQswCQYDVQQGEwJDTjETMBEGA1UECgwKaVRydXNDaGluYTEcMBoGA1UECwwTQ2hp\n" +
"bmEgVHJ1c3QgTmV0d29yazEoMCYGA1UEAwwfaVRydXNDaGluYSBDbGFzcyAyIFJv\n" +
"b3QgQ0EgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOPPShpV\n" +
"nJbMqqCw6Bz1kehnoPst9pkr0V9idOwU2oyS47/HjJXk9Rd5a9xfwkPO88trUpz5\n" +
"4GmmwspDXjVFu9L0eFaRuH3KMha1Ak01citbF7cQLJlS7XI+tpkTGHEY5pt3EsQg\n" +
"wykfZl/A1jrnSkspMS997r2Gim54cwz+mTMgDRhZsKK/lbOeBPpWtcFizjXYCqhw\n" +
"WktvQfZBYi6o4sHCshnOswi4yV1p+LuFcQ2ciYdWvULh1eZhLxHbGXyznYHi0dGN\n" +
"z+I9H8aXxqAQfHVhbdHNzi77hCxFjOy+hHrGsyzjrd2swVQ2iUWP8BfEQqGLqM1g\n" +
"KgWKYfcTGdbPB1MCAwEAAaNjMGEwHQYDVR0OBBYEFG/oAMxTVe7y0+408CTAK8hA\n" +
"uTyRMB8GA1UdIwQYMBaAFG/oAMxTVe7y0+408CTAK8hAuTyRMA8GA1UdEwEB/wQF\n" +
"MAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBLnUTfW7hp\n" +
"emMbuUGCk7RBswzOT83bDM6824EkUnf+X0iKS95SUNGeeSWK2o/3ALJo5hi7GZr3\n" +
"U8eLaWAcYizfO99UXMRBPw5PRR+gXGEronGUugLpxsjuynoLQu8GQAeysSXKbN1I\n" +
"UugDo9u8igJORYA+5ms0s5sCUySqbQ2R5z/GoceyI9LdxIVa1RjVX8pYOj8JFwtn\n" +
"DJN3ftSFvNMYwRuILKuqUYSHc2GPYiHVflDh5nDymCMOQFcFG3WsEuB+EYQPFgIU\n" +
"1DHmdZcz7Llx8UOZXX2JupWCYzK1XhJb+r4hK5ncf/w8qGtYlmyJpxk3hr1TfUJX\n" +
"Yf4Zr0fJsGuv\n" +
"-----END CERTIFICATE-----";
bo.aliPayAppCert = "-----BEGIN CERTIFICATE-----\n" +
"MIIEoDCCA4igAwIBAgIQICQFCYw2I4Ya+pK5n28TCTANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UE\n" +
"BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmljYXRpb24gQXV0\n" +
"aG9yaXR5MTkwNwYDVQQDDDBBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IENs\n" +
"YXNzIDEgUjEwHhcNMjQwNTA5MDI0ODU2WhcNMjkwNTA4MDI0ODU2WjBoMQswCQYDVQQGEwJDTjEt\n" +
"MCsGA1UECgwk5oiQ6YO95aWH6L+555WF546p56eR5oqA5pyJ6ZmQ5YWs5Y+4MQ8wDQYDVQQLDAZB\n" +
"bGlwYXkxGTAXBgNVBAMMEDIwODg4NDEyODQ2NTg5ODEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw\n" +
"ggEKAoIBAQCeU75wMTR1FUEbptIFgk9/aR+lPgMWVsONuj1JnRADqz/3AiNvDiXm20V75aZ/mUf+\n" +
"LaPx2su3wn2JoVr5reIOvx797Tb9JiUn/ucBx5p0lcEQbkMEh+PzXAZK6miRS4thgLEWbfrcVV7T\n" +
"TvGvlKiBVVPPfOfEmaqd/qX0aen9bOJ6/HH8EnTb19yckTK9xNO4WK4SqD66Xr649KyRteeeqx62\n" +
"ClbIU04ZMbywlmvkF1sjQbMI7MHMfHDHuI+3SuxQHY6INZwvG8Fua/6c4xCpAijjO0PnOlm5aZ7C\n" +
"xxwaxQva/jfHAQ7mq5xuvs1pyvtkhDF6md/RIqgFXM+w1VHDAgMBAAGjggEpMIIBJTAfBgNVHSME\n" +
"GDAWgBRxB+IEYRbk5fJl6zEPyeD0PJrVkTAdBgNVHQ4EFgQUSFMQjFFZwHUPg8Punc9zle3FnR0w\n" +
"QAYDVR0gBDkwNzA1BgdggRwBbgEBMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9jYS5hbGlwYXkuY29t\n" +
"L2Nwcy5wZGYwDgYDVR0PAQH/BAQDAgbAMC8GA1UdHwQoMCYwJKAioCCGHmh0dHA6Ly9jYS5hbGlw\n" +
"YXkuY29tL2NybDg5LmNybDBgBggrBgEFBQcBAQRUMFIwKAYIKwYBBQUHMAKGHGh0dHA6Ly9jYS5h\n" +
"bGlwYXkuY29tL2NhNi5jZXIwJgYIKwYBBQUHMAGGGmh0dHA6Ly9jYS5hbGlwYXkuY29tOjgzNDAv\n" +
"MA0GCSqGSIb3DQEBCwUAA4IBAQAheCMGQ1iPZXjuh4oQaaQPXnHmeUvS4aASbW1PwcPPXvuRvEVi\n" +
"1m4PJaygX082A9bgRUqLbdTK0GQPDhSuGX6ap+8sz0mkm0ywM485hbjirRsAj2GKXi9UxUeuJ6OP\n" +
"6oIvwloOPqG1SDMScSDPPTtuaXRnu8QNEvRUjIVFrognqpVC+z8yXJENC24+uJWd1zmshvo2epHG\n" +
"iQD+L5+pIoTlzy/PwYlE14gBlLlOWuBHjz7TJXyA20Nk1GtQ3/dD+40D74vSatbmBAxoIIjAwAZD\n" +
"mjgDzHRtRAysLHBbyZh2GAWG5bXhATZSfUwAHhyNKu+E8AD/jRcyeiku9CFO/6NH\n" +
"-----END CERTIFICATE-----";
bo.aliPayPublicCert = "-----BEGIN CERTIFICATE-----\n" +
"MIIDnTCCAoWgAwIBAgIQICQFCd/KXSqlPFRysYroGTANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UE\n" +
"BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmljYXRpb24gQXV0\n" +
"aG9yaXR5MTkwNwYDVQQDDDBBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IENs\n" +
"YXNzIDIgUjEwHhcNMjQwNTA5MDI0ODU3WhcNMjkwNTA4MDI0ODU3WjB+MQswCQYDVQQGEwJDTjEZ\n" +
"MBcGA1UECgwQMjA4ODg0MTI4NDY1ODk4MTEPMA0GA1UECwwGQWxpcGF5MUMwQQYDVQQDDDrmlK/k\n" +
"u5jlrp0o5Lit5Zu9Kee9kee7nOaKgOacr+aciemZkOWFrOWPuC0yMDg4ODQxMjg0NjU4OTgxMIIB\n" +
"IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmRfS59/z9uZCgainfQ7AWC3zNNrMxKOkU+Mr\n" +
"aZOI5wXR4nDrCk2xscd+84rd/DVQ13U7rXKDOAoWKrZNghDNyRM9j/bTBnkTceQGTbo2wOdeIOM1\n" +
"I90nmtQCfLE0sahcwiP32hyxL2s8C8RzEBNFWhwMuDvsWTZSBOjxDNz0B0rNG6ocfw8riNt1f0Ue\n" +
"5moRJ6MS1cWGOf8ngbOYgSccJn7E/K53iZj4EWhCeAA3wHTvRN2uX/hX5icbxc0tJ1eFFKisYhgZ\n" +
"VQCeYg0HJhmDV7G4R1uHL0EiHw5fQJFFjq+OWBrH1ro5he+kdU/adQC4fvT2DoVK/JamGjTN088A\n" +
"twIDAQABoxIwEDAOBgNVHQ8BAf8EBAMCA/gwDQYJKoZIhvcNAQELBQADggEBAEoVe17OXLCpO8l1\n" +
"6aED4aE4McQjeFeToxO4HtgQ0XC2sCur8ffSZDQZHCJN1eXyYedKH4dmGj3XhQqGGntqZgxTFymm\n" +
"zINRuBol8Z0OR7IAzP27R8Tml4+Ka8Q5sCHSFEBgmmv3YNOuL6LlNYZJ647FcSERvGZZmuOAnnV1\n" +
"Gis/hiwZ/0Rl7UM6KObKWO4eV2lyYOQqVJf6kI9NGDo2N6nTltgmJYag4PyFk+/70Y6arqCkIVjU\n" +
"qpajdaqMeZypFMwcMRnP1FDl5CrxL3NVBi3jXLGORe80dfg73ETZdiL0wM3wBSRT3J+dfFZT/sZ3\n" +
"Yfp28EoAG5Z1aF22j450Xhk=\n" +
"-----END CERTIFICATE-----\n" +
"-----BEGIN CERTIFICATE-----\n" +
"MIIE4jCCAsqgAwIBAgIIYsSr5bKAMl8wDQYJKoZIhvcNAQELBQAwejELMAkGA1UEBhMCQ04xFjAU\n" +
"BgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmljYXRpb24gQXV0aG9yaXR5MTEw\n" +
"LwYDVQQDDChBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFIxMB4XDTE4MDMy\n" +
"MjE0MzQxNVoXDTM3MTEyNjE0MzQxNVowgYIxCzAJBgNVBAYTAkNOMRYwFAYDVQQKDA1BbnQgRmlu\n" +
"YW5jaWFsMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTE5MDcGA1UEAwwwQW50IEZp\n" +
"bmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBDbGFzcyAyIFIxMIIBIjANBgkqhkiG9w0B\n" +
"AQEFAAOCAQ8AMIIBCgKCAQEAsLMfYaoRoPRbmDcAfXPCmKf43pWRN5yTXa/KJWO0l+mrgQvs89bA\n" +
"NEvbDUxlkGwycwtwi5DgBuBgVhLliXu+R9CYgr2dXs8D8Hx/gsggDcyGPLmVrDOnL+dyeauheARZ\n" +
"fA3du60fwEwwbGcVIpIxPa/4n3IS/ElxQa6DNgqxh8J9Xwh7qMGl0JK9+bALuxf7B541Gr4p0WEN\n" +
"G8fhgjBV4w4ut9eQLOoa1eddOUSZcy46Z7allwowwgt7b5VFfx/P1iKJ3LzBMgkCK7GZ2kiLrL7R\n" +
"iqV+h482J7hkJD+ardoc6LnrHO/hIZymDxok+VH9fVeUdQa29IZKrIDVj65THQIDAQABo2MwYTAf\n" +
"BgNVHSMEGDAWgBRfdLQEwE8HWurlsdsio4dBspzhATAdBgNVHQ4EFgQUSqHkYINtUSAtDPnS8Xoy\n" +
"oP9p7qEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIB\n" +
"AIQ8TzFy4bVIVb8+WhHKCkKNPcJe2EZuIcqvRoi727lZTJOfYy/JzLtckyZYfEI8J0lasZ29wkTt\n" +
"a1IjSo+a6XdhudU4ONVBrL70U8Kzntplw/6TBNbLFpp7taRALjUgbCOk4EoBMbeCL0GiYYsTS0mw\n" +
"7xdySzmGQku4GTyqutIGPQwKxSj9iSFw1FCZqr4VP4tyXzMUgc52SzagA6i7AyLedd3tbS6lnR5B\n" +
"L+W9Kx9hwT8L7WANAxQzv/jGldeuSLN8bsTxlOYlsdjmIGu/C9OWblPYGpjQQIRyvs4Cc/mNhrh+\n" +
"14EQgwuemIIFDLOgcD+iISoN8CqegelNcJndFw1PDN6LkVoiHz9p7jzsge8RKay/QW6C03KNDpWZ\n" +
"EUCgCUdfHfo8xKeR+LL1cfn24HKJmZt8L/aeRZwZ1jwePXFRVtiXELvgJuM/tJDIFj2KD337iV64\n" +
"fWcKQ/ydDVGqfDZAdcU4hQdsrPWENwPTQPfVPq2NNLMyIH9+WKx9Ed6/WzeZmIy5ZWpX1TtTolo6\n" +
"OJXQFeItMAjHxW/ZSZTok5IS3FuRhExturaInnzjYpx50a6kS34c5+c8hYq7sAtZ/CNLZmBnBCFD\n" +
"aMQqT8xFZJ5uolUaSeXxg7JFY1QsYp5RKvj4SjFwCGKJ2+hPPe9UyyltxOidNtxjaknOCeBHytOr\n" +
"-----END CERTIFICATE-----\n";
Gson gson = new Gson();
String json = gson.toJson(bo);
System.out.println(json);
}
}

9
game-web/src/main/java/awesome/group/game/web/filter/CitrusLoginFilter.java

@ -32,14 +32,7 @@ public class CitrusLoginFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try { try {
HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletRequest httpRequest = (HttpServletRequest) request;
String token = ""; String token = httpRequest.getHeader("Authorization");
if(httpRequest.getCookies() != null) {
for (Cookie c : httpRequest.getCookies()) {
if (c.getName().equals("CitrusToken")) {
token = c.getValue();
}
}
}
List<String> openApi = List.of( List<String> openApi = List.of(
"/api/citrus/register", "/api/citrus/register",
"/api/citrus/login" "/api/citrus/login"

24
game-web/src/main/java/awesome/group/game/web/rest/citrus/CitrusAppController.java

@ -0,0 +1,24 @@
package awesome.group.game.web.rest.citrus;
import awesome.group.game.service.bo.citrus.AppBo;
import awesome.group.game.service.citrus.CitrusAppService;
import awesome.group.game.service.common.response.R;
import awesome.group.game.web.aop.RestApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/citrus/app")
public class CitrusAppController {
@Autowired
private CitrusAppService appService;
@GetMapping("/getDetail")
@RestApi
public R<AppBo> getAppDetail(@RequestParam String appCode) {
return new R<>(appService.getAppDetail(appCode));
}
}

8
game-web/src/main/java/awesome/group/game/web/rest/citrus/OpenController.java

@ -75,4 +75,12 @@ public class OpenController {
return new R<>(R.CODE_SUCCESS, "ok", token); return new R<>(R.CODE_SUCCESS, "ok", token);
} }
@PostMapping("/loginByToken")
@RestApi
public R<String> loginByToken(@RequestBody LoginReq req) {
MatrixUser u = userService.loginByToken(req.appCode, req.token);
String token = JwtUtils.generatorToken(u.getId() + "", 15 * 86400);
return new R<>(R.CODE_SUCCESS, "ok", token);
}
} }

27
game-web/src/main/java/awesome/group/game/web/rest/citrus/UserController.java

@ -1,14 +1,15 @@
package awesome.group.game.web.rest.citrus; package awesome.group.game.web.rest.citrus;
import awesome.group.game.service.bo.citrus.CashRecord;
import awesome.group.game.service.bo.citrus.UserBo; import awesome.group.game.service.bo.citrus.UserBo;
import awesome.group.game.service.citrus.UserService; import awesome.group.game.service.citrus.UserService;
import awesome.group.game.service.common.response.R; import awesome.group.game.service.common.response.R;
import awesome.group.game.web.RequestContext; import awesome.group.game.web.RequestContext;
import awesome.group.game.web.aop.RestApi; import awesome.group.game.web.aop.RestApi;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import java.util.List;
@RestController @RestController
@RequestMapping("/api/citrus/user") @RequestMapping("/api/citrus/user")
@ -22,4 +23,24 @@ public class UserController {
public R<UserBo> currentUser() { public R<UserBo> currentUser() {
return new R<>(userService.getUser(RequestContext.getCitrusUid())); return new R<>(userService.getUser(RequestContext.getCitrusUid()));
} }
@PostMapping("/bindAliPay")
@RestApi
public R<Void> bindAliPay(@RequestBody UserBo userBo) {
userService.bindAliPay(RequestContext.getCitrusUid(), userBo.aliPayAccount, userBo.name);
return new R<>(null);
}
@GetMapping("/cashRecords")
@RestApi
public R<List<CashRecord>> getCashRecord() {
return new R<>(userService.getCashRecord(RequestContext.getCitrusUid()));
}
@PostMapping("/applyCash")
@RestApi
public R<Void> applyCash(@RequestParam Integer money) {
userService.applyMoney(RequestContext.getCitrusUid(), money);
return new R<>(null);
}
} }

Loading…
Cancel
Save