1、完善超分功能

2、完善积分系统
3、新增任务列表
This commit is contained in:
2024-03-26 14:58:43 +08:00
parent 305324fe1a
commit d411b428f8
26 changed files with 807 additions and 328 deletions

View File

@@ -51,7 +51,7 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
public void creditsIncrease(Long accountId, String creditsEvent) {
CreditsEventsEnum event = null;
switch (creditsEvent){
switch (creditsEvent) {
case "Daily Check-In":
event = CreditsEventsEnum.DAILY_CHECKIN;
break;
@@ -61,40 +61,44 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
case "Other":
event = CreditsEventsEnum.OTHER;
break;
case "Super Resolution":
event = CreditsEventsEnum.SUPER_RESOLUTION;
break;
default:
throw new BusinessException("UNKNOWN TYPE");
}
BigDecimal existingCredits = accountMapper.selectById(UserContext.getUserHolder().getId()).getCredits();
BigDecimal existingCredits = accountMapper.selectById(accountId).getCredits();
BigDecimal add = new BigDecimal(event.getValue()).add(existingCredits);
accountService.updateCredits(UserContext.getUserHolder().getId(), add.toString());
accountService.updateCredits(accountId, add.toString());
}
@Override
public void creditsDecrease(Long accountId, String creditsEvent) {
CreditsEventsEnum event = null;
CreditsEventsEnum event;
switch (creditsEvent){
switch (creditsEvent) {
case "Super Resolution":
event = CreditsEventsEnum.DAILY_CHECKIN;
event = CreditsEventsEnum.SUPER_RESOLUTION;
break;
case "Other":
event = CreditsEventsEnum.OTHER;
break;
default:
log.error("UNKNOWN TYPE");
throw new BusinessException("UNKNOWN TYPE");
}
BigDecimal existingCredits = accountMapper.selectById(UserContext.getUserHolder().getId()).getCredits();
BigDecimal existingCredits = accountMapper.selectById(accountId).getCredits();
BigDecimal subtract = existingCredits.subtract(new BigDecimal(event.getValue()));
accountService.updateCredits(UserContext.getUserHolder().getId(), subtract.toString());
accountService.updateCredits(accountId, subtract.toString());
}
@Override
public String getCredits() {
Account account = accountMapper.selectById(UserContext.getUserHolder().getId());
public String getCredits(Long accountId) {
Account account = accountMapper.selectById(accountId);
return account.getCredits().toString();
}
public void creditsRefund(Long accountId, Integer quantity){
public void creditsRefund(Long accountId, Integer quantity) {
BigDecimal existingCredits = accountMapper.selectById(accountId).getCredits();
BigDecimal newCredits = new BigDecimal(CreditsEventsEnum.BUY_CREDITS.getValue()).multiply(new BigDecimal(quantity));
BigDecimal subtracted = existingCredits.subtract(newCredits);
@@ -103,52 +107,54 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
/**
* 向积分变更详细表添加记录
*
* @param changeEvent 导致积分变更的事件
* @param credits 变更的积分
* @param changeType 变更类型 positive->增 negative->减
* @param credits 变更的积分
* @param changeType 变更类型 positive->增 negative->减
*/
@Override
public void insertToCreditsDetail(Long accountId, String changeEvent, String credits, String changeType){
public void insertToCreditsDetail(Long accountId, String changeEvent, String credits, String changeType) {
CreditsDetail creditsDetail = new CreditsDetail();
Account account = accountMapper.selectById(accountId);
BigDecimal finalCredits;
// BigDecimal finalCredits;
String changeCredits;
if ("positive".equals(changeType)){
finalCredits = account.getCredits().add(new BigDecimal(credits));
if ("positive".equals(changeType)) {
// finalCredits = account.getCredits().add(new BigDecimal(credits));
changeCredits = "+" + credits;
}else {
finalCredits = account.getCredits().subtract(new BigDecimal(credits));
} else {
// finalCredits = account.getCredits().subtract(new BigDecimal(credits));
changeCredits = "-" + credits;
}
creditsDetail.setAccountId(accountId);
creditsDetail.setChangeEvent(changeEvent);
creditsDetail.setChangedCredits(changeCredits);
creditsDetail.setCredits(finalCredits);
// creditsDetail.setCredits(finalCredits);
creditsDetail.setCredits(account.getCredits());
creditsDetail.setCreateTime(LocalDateTime.now());
baseMapper.insert(creditsDetail);
}
@Override
public PageBaseResponse<CreditsDetail> queryCreditsDetailsPage(QueryIncomeOrExpenditureDTO queryPageByTimeDTO){
public PageBaseResponse<CreditsDetail> queryCreditsDetailsPage(QueryIncomeOrExpenditureDTO queryPageByTimeDTO) {
QueryWrapper<CreditsDetail> qw = new QueryWrapper<>();
qw.eq("account_id",UserContext.getUserHolder().getId());
qw.eq("account_id", UserContext.getUserHolder().getId());
String startTime = queryPageByTimeDTO.getStartTime();
String endTime = queryPageByTimeDTO.getEndTime();
if (StringUtil.isNullOrEmpty(startTime)){
if (StringUtil.isNullOrEmpty(startTime)) {
startTime = "2024-03-01 00:00:00";
}
if (StringUtil.isNullOrEmpty(endTime)){
if (StringUtil.isNullOrEmpty(endTime)) {
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
endTime = now.format(dateTimeFormatter);
}
if (!Objects.isNull(queryPageByTimeDTO.getIsIncome())){
if (queryPageByTimeDTO.getIsIncome()){
qw.likeRight("changed_credits","+");
}else {
qw.likeRight("changed_credits","-");
if (!Objects.isNull(queryPageByTimeDTO.getIsIncome())) {
if (queryPageByTimeDTO.getIsIncome()) {
qw.likeRight("changed_credits", "+");
} else {
qw.likeRight("changed_credits", "-");
}
}
@@ -162,4 +168,15 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
return PageBaseResponse.success(orderInfo);
}
public Boolean checkCredits(Long accountId, CreditsEventsEnum event, Integer num) {
String credits = getCredits(accountId);
if (new BigDecimal(credits)
.subtract(new BigDecimal(event.getValue())
.multiply(new BigDecimal(num)))
.compareTo(BigDecimal.ZERO) < 0) {
return Boolean.FALSE;
}
return Boolean.TRUE;
}
}

View File

@@ -86,8 +86,8 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
OrderInfo orderInfo = orderInfoService.createOrderByProductId(amount, PayTypeEnum.PAYPAL.getType());
OrdersCreateRequest request = new OrdersCreateRequest();
request.header("prefer","return=representation");
request.requestBody(buildRequestBody(String.valueOf(orderInfo.getTotalFee()),returnUrl));
request.header("prefer", "return=representation");
request.requestBody(buildRequestBody(String.valueOf(orderInfo.getTotalFee()), returnUrl));
HttpResponse<Order> response = null;
try {
response = payPalClient.client(MODE, clientId, clientSecret).execute(request);
@@ -102,13 +102,13 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
log.info("Status Code = {}, Status = {}, OrderID = {}, Intent = {}", response.statusCode(), response.result().status(), response.result().id(), response.result().checkoutPaymentIntent());
for (LinkDescription link : response.result().links()) {
log.info("Links-{}: {} \tCall Type: {}", link.rel(), link.href(), link.method());
if(link.rel().equals("approve")) {
if (link.rel().equals("approve")) {
approve = link.href();
}
}
String totalAmount = response.result().purchaseUnits().get(0).amountWithBreakdown().currencyCode() + ":" + response.result().purchaseUnits().get(0).amountWithBreakdown().value();
log.info("Total Amount: {}", totalAmount);
String json= new JSONObject(new Json().serialize(response.result())).toString(4);
String json = new JSONObject(new Json().serialize(response.result())).toString(4);
log.info("createOrder response body: {}", json);
}
@@ -116,8 +116,8 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
orderInfoService.updateOrderNoById(orderInfo.getId(), orderId);
HashMap<String, String> returnData = new HashMap<>();
returnData.put("approve",approve);
returnData.put("orderNo",orderId);
returnData.put("approve", approve);
returnData.put("orderNo", orderId);
// 需要返回地址和订单id
return returnData;
@@ -132,12 +132,12 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
HashMap<String, Object> webhookRequest = new HashMap<>();
webhookRequest.put("auth_algo", SDKUtil.validateAndGet(getHeadersInfo(req), "PAYPAL-AUTH-ALGO"));
webhookRequest.put("cert_url",SDKUtil.validateAndGet(getHeadersInfo(req), "PAYPAL-CERT-URL"));
webhookRequest.put("transmission_id",SDKUtil.validateAndGet(getHeadersInfo(req), "PAYPAL-TRANSMISSION-ID"));
webhookRequest.put("transmission_sig",SDKUtil.validateAndGet(getHeadersInfo(req), "PAYPAL-TRANSMISSION-SIG"));
webhookRequest.put("transmission_time",SDKUtil.validateAndGet(getHeadersInfo(req), "PAYPAL-TRANSMISSION-TIME"));
webhookRequest.put("webhook_id",PayPalCheckoutConstant.WEBHOOK_ID);
webhookRequest.put("webhook_event",webhookEvent);
webhookRequest.put("cert_url", SDKUtil.validateAndGet(getHeadersInfo(req), "PAYPAL-CERT-URL"));
webhookRequest.put("transmission_id", SDKUtil.validateAndGet(getHeadersInfo(req), "PAYPAL-TRANSMISSION-ID"));
webhookRequest.put("transmission_sig", SDKUtil.validateAndGet(getHeadersInfo(req), "PAYPAL-TRANSMISSION-SIG"));
webhookRequest.put("transmission_time", SDKUtil.validateAndGet(getHeadersInfo(req), "PAYPAL-TRANSMISSION-TIME"));
webhookRequest.put("webhook_id", PayPalCheckoutConstant.WEBHOOK_ID);
webhookRequest.put("webhook_event", webhookEvent);
WebhookVerifyRequest webhookVerifyRequest = new WebhookVerifyRequest();
webhookVerifyRequest.authorization(getOAuth());
@@ -145,7 +145,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
// 验签
HttpResponse<HashMap> verified = payPalClient.client(MODE, clientId, clientSecret).execute(webhookVerifyRequest);
boolean verifyResult = verified.result().get("verification_status").toString().equals("SUCCESS");
if (verifyResult){
if (verifyResult) {
// ### Api Context
APIContext apiContext = new APIContext(clientId, clientSecret, PayPalCheckoutConstant.MODE);
@@ -155,14 +155,15 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
req), body);
log.info("Webhook Validated: " + result);
if (result){
if (result) {
// 处理订单数据
LinkedHashMap<String,LinkedHashMap<String,String>> webhookEventMap = (LinkedHashMap<String,LinkedHashMap<String,String>>) webhookEvent;
LinkedHashMap<String, LinkedHashMap<String, String>> webhookEventMap = (LinkedHashMap<String, LinkedHashMap<String, String>>) webhookEvent;
String orderId = webhookEventMap.get("resource").get("id");
processOrder(orderId);
return Boolean.TRUE;
}
} else {
log.error("Paypal 验签失败");
}
} catch (PayPalRESTException | InvalidKeyException | NoSuchAlgorithmException | SignatureException e) {
log.error(e.getMessage());
@@ -226,7 +227,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
ApplicationContext applicationContext = new ApplicationContext()
.brandName(BRANDNAME)
.landingPage(LANDINGPAGE)
.cancelUrl("https://www.example.com").returnUrl(returnUrl)
.cancelUrl(returnUrl).returnUrl(returnUrl)
.userAction(USERACTION)
.shippingPreference(SHIPPINGPREFERENCE);
orderRequest.applicationContext(applicationContext);
@@ -250,12 +251,12 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
log.info("通知参数 ===> {}", map);
// log.info(map.toString());
String outTradeNo = (String)map.get("invoice");
String paymentStatus = (String)map.get("payment_status");
String amount = (String)map.get("mc_gross");
String currency = (String)map.get("mc_currency");
String paymentId = (String)map.get("txn_id");
String parentPaymentId = (String)map.get("parent_txn_id");
String outTradeNo = (String) map.get("invoice");
String paymentStatus = (String) map.get("payment_status");
String amount = (String) map.get("mc_gross");
String currency = (String) map.get("mc_currency");
String paymentId = (String) map.get("txn_id");
String parentPaymentId = (String) map.get("parent_txn_id");
log.info("商家订单号 = {}", outTradeNo);
log.info("订单状态 = {}", paymentStatus);
log.info("金额 = {}", amount);
@@ -267,30 +268,30 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
log.info("FAIL = 商户id错误, outTradeNo = {}", outTradeNo);
return "failure";
}
if("Completed".equals(paymentStatus)) {
if ("Completed".equals(paymentStatus)) {
//进行数据库操作
//
//
log.info("支付成功,状态为=COMPLETED");
return "success";
}
if("Refunded".equals(paymentStatus)) {
if ("Refunded".equals(paymentStatus)) {
//进行数据库操作
//
//
log.info("退款成功");
return "success";
}
if("Pending".equals(paymentStatus) && StringUtils.isEmpty(parentPaymentId)) {
if ("Pending".equals(paymentStatus) && StringUtils.isEmpty(parentPaymentId)) {
String pendingReason = String.valueOf(map.get("pending_reason"));
//进行数据库操作
//
//
log.info("订单支付成功,状态为=PENDING产生此状态的原因是 {}", pendingReason );
log.info("订单支付成功,状态为=PENDING产生此状态的原因是 {}", pendingReason);
return "success";
}
if(StringUtils.isEmpty(parentPaymentId)) {
if(PayPalCheckoutConstant.PAYMENT_STATUS_REVERSED.equals(paymentStatus)
if (StringUtils.isEmpty(parentPaymentId)) {
if (PayPalCheckoutConstant.PAYMENT_STATUS_REVERSED.equals(paymentStatus)
|| PayPalCheckoutConstant.PAYMENT_STATUS_CANCELED_REVERSAL.equals(paymentStatus)
|| PayPalCheckoutConstant.PAYMENT_STATUS_DENIED.equals(paymentStatus)) {
String reasonCode = String.valueOf(map.get("reason_code"));
@@ -300,7 +301,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
log.info("订单异常,请尽快查看处理,状态为={},产生此状态的原因是 {} ", paymentStatus, reasonCode);
return PayPalCheckoutConstant.SUCCESS;
}
if(PayPalCheckoutConstant.PAYMENT_STATUS_EXPIRED.equals(paymentStatus)
if (PayPalCheckoutConstant.PAYMENT_STATUS_EXPIRED.equals(paymentStatus)
|| PayPalCheckoutConstant.PAYMENT_STATUS_CREATED.equals(paymentStatus)
|| PayPalCheckoutConstant.PAYMENT_STATUS_FAILED.equals(paymentStatus)
|| PayPalCheckoutConstant.PAYMENT_STATUS_PROCESSED.equals(paymentStatus)
@@ -317,6 +318,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
/**
* 查询订单信息
*
* @param orderNo
* @return
* @throws SerializeException
@@ -328,20 +330,20 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
try {
response = payPalClient.client(MODE, clientId, clientSecret).execute(request);
} catch (Exception e) {
log.error("paypal订单查询失败失败原因 ===> {}",e.getMessage());
log.error("paypal订单查询失败失败原因 ===> {}", e.getMessage());
}
System.out.println("Status Code: " + response.statusCode());
System.out.println("Status: " + response.result().status());
System.out.println("Order id: " + response.result().id());
if(response.result().purchaseUnits().get(0).payments() != null) {
if (response.result().purchaseUnits().get(0).payments() != null) {
List<Capture> captures = response.result().purchaseUnits().get(0).payments().captures();
if(captures != null) {
if (captures != null) {
for (Capture capture : captures) {
System.out.println("\t订单编号= " + capture.invoiceId() + "\tCapture Id= " + capture.id() + "\tCapture status= " + capture.status() + "\tCapture amount= " + capture.amount().currencyCode() + ":" + capture.amount().value());
}
}
List<Refund> refunds = response.result().purchaseUnits().get(0).payments().refunds();
if(refunds != null) {
if (refunds != null) {
for (Refund refund : refunds) {
System.out.println("\t售后编号= " + refund.invoiceId() + "\tRefund Id= " + refund.id() + "\tRefund status= " + refund.status() + "\tRefund amount= " + refund.amount().currencyCode() + ":" + refund.amount().value());
}
@@ -366,12 +368,12 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
OrdersCaptureRequest request = new OrdersCaptureRequest(orderId);
request.requestBody(new OrderRequest());
PayPalClient payPalClient = new PayPalClient();
HttpResponse<Order> response ;
HttpResponse<Order> response;
try {
response = payPalClient.client(MODE, clientId, clientSecret).execute(request);
} catch (Exception e) {
log.error("调用paypal扣款失败失败原因 ===> {}", e.getMessage() );
log.error("调用paypal扣款失败失败原因 ===> {}", e.getMessage());
throw new BusinessException("Order deduction failed.");
}
log.info("Status Code = {}, Status = {}, OrderID = {}", response.statusCode(), response.result().status(), response.result().id());
@@ -383,14 +385,14 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
log.info("Capture id: {}", capture.id());
log.info("status: {}", capture.status());
log.info("invoice_id: {}", capture.invoiceId());
if("COMPLETED".equals(capture.status())) {
if ("COMPLETED".equals(capture.status())) {
//进行数据库操作修改订单状态为已支付成功尽快发货配合回调和CapturesGet查询确定成功
log.info("支付成功,状态为=COMPLETED");
}
if("PENDING".equals(capture.status())) {
if ("PENDING".equals(capture.status())) {
log.info("status_details: {}", capture.captureStatusDetails().reason());
String reason = "PENDING";
if(capture.captureStatusDetails() != null && capture.captureStatusDetails().reason() != null) {
if (capture.captureStatusDetails() != null && capture.captureStatusDetails().reason() != null) {
reason = capture.captureStatusDetails().reason();
}
//进行数据库操作修改订单状态为已支付成功但触发了人工审核请审核通过后再发货配合回调和CapturesGet查询确定成功
@@ -406,7 +408,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
try {
json = new JSONObject(new Json().serialize(response.result())).toString(4);
} catch (SerializeException e) {
log.warn("response序列化出错具体信息 ===> {}",e.getMessage());
log.warn("response序列化出错具体信息 ===> {}", e.getMessage());
}
log.info("captureOrder response body: {}", json);
// return Convert.toStr(new Json().serialize(response.result()));
@@ -437,7 +439,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
* 申请退款
*/
@Transactional(rollbackFor = Exception.class)
public Boolean refundOrder(String orderId,String reason) throws IOException {
public Boolean refundOrder(String orderId, String reason) throws IOException {
RefundInfo refundByOrderNo = refundsInfoService.createRefundByOrderNo(orderId, reason);
@@ -445,7 +447,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
PayPalClient payPalClient = new PayPalClient();
HttpResponse<com.paypal.orders.Order> ordersGetResponse = null;
ordersGetRequest.authorization("Bearer " + getOAuth());
boolean result ;
boolean result;
try {
ordersGetResponse = payPalClient.client(MODE, clientId, clientSecret).execute(ordersGetRequest);
} catch (Exception e) {
@@ -458,7 +460,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
request.prefer("return=representation");
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderId);
request.requestBody(buildRefundRequestBody(String.valueOf(orderInfo.getTotalFee()),reason));
request.requestBody(buildRefundRequestBody(String.valueOf(orderInfo.getTotalFee()), reason));
HttpResponse<com.paypal.payments.Refund> response = null;
try {
response = payPalClient.client(MODE, clientId, clientSecret).execute(request);
@@ -468,7 +470,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
}
log.info("Status Code = {}, Status = {}, RefundID = {}", response.statusCode(), response.result().status(), response.result().id());
if("COMPLETED".equals(response.result().status())) {
if ("COMPLETED".equals(response.result().status())) {
//进行数据库操作,修改状态为已退款(配合回调和退款查询确定退款成功)
//更新订单状态
@@ -485,7 +487,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
creditsService.creditsRefund(orderByOrderNo.getAccountId(), orderByOrderNo.getTotalFee() / Integer.parseInt(CreditsEventsEnum.PRICE.getValue()));
log.info("退款成功");
result = Boolean.TRUE;
}else {
} else {
//更新订单状态
orderInfoService.updateStatusByOrderNo(orderId, OrderStatusEnum.REFUND_ABNORMAL);
@@ -540,24 +542,24 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
return null;
}
public String getOAuth(){
public String getOAuth() {
// 1、判断缓存区是否有该token
Boolean hasKey = redisUtil.hasKey(PAYPAL_TOKEN_KEY);
if (hasKey){
if (hasKey) {
return redisUtil.getFromString(PAYPAL_TOKEN_KEY);
// return "A21AAKnpozur9r9omqQ2ge5aXHBBdEERi5F8FIgNYOjhhO2N7rjmkz2irh2lScpBO3s3Cqukw3eZkpYZ4YWE7rIacjv7MHmow";
}
// 2、无或者过期重新获取token返回
AuthenticationRequest authenticationRequest = new AuthenticationRequest();
authenticationRequest.authorization(clientId,clientSecret);
authenticationRequest.authorization(clientId, clientSecret);
try {
HttpResponse<HashMap> authResult = payPalClient.client(MODE, clientId, clientSecret).execute(authenticationRequest);
String accessToken = authResult.result().get("access_token").toString();
long expiresIn = Long.parseLong(authResult.result().get("expires_in").toString());
// 3、存redis
redisUtil.addToString(PAYPAL_TOKEN_KEY,accessToken,expiresIn);
return accessToken;
redisUtil.addToString(PAYPAL_TOKEN_KEY, accessToken, expiresIn);
return accessToken;
} catch (IOException e) {
log.error("获取paypal token失败失败原因 ===> {}", e.getMessage());
throw new BusinessException(e);
@@ -566,17 +568,17 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
// 处理当前订单
@Transactional(rollbackFor = Exception.class)
public void processOrder(String orderId){
public void processOrder(String orderId) {
// 1、确定当前订单是否已经被扣款
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderId);
if (orderInfo.getOrderStatus().equals(OrderStatusEnum.SUCCESS.getType())){
if (orderInfo.getOrderStatus().equals(OrderStatusEnum.SUCCESS.getType())) {
// 直接返回
return ;
return;
}
// 发起扣款请求
Order capturedOrder = captureOrder(orderId);
// 业务处理
if (PayPalOrderStatusEnum.COMPLETED.getStatus().equals(capturedOrder.status())){
if (PayPalOrderStatusEnum.COMPLETED.getStatus().equals(capturedOrder.status())) {
//更新订单状态
orderInfoService.updateStatusByOrderNo(orderId, OrderStatusEnum.SUCCESS);
//记录支付日志

View File

@@ -1,29 +1,42 @@
package com.ai.da.service.impl;
import com.ai.da.common.config.exception.BusinessException;
import com.ai.da.common.context.UserContext;
import com.ai.da.common.enums.CreditsEventsEnum;
import com.ai.da.common.utils.AsyncCallerUtil;
import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.common.utils.RedisUtil;
import com.ai.da.mapper.primary.SuperResolutionMapper;
import com.ai.da.mapper.primary.entity.SuperResolution;
import com.ai.da.mapper.primary.TaskListMapper;
import com.ai.da.mapper.primary.entity.TaskList;
import com.ai.da.model.dto.QueryTaskHistoryDTO;
import com.ai.da.model.dto.SuperResolutionDTO;
import com.ai.da.model.dto.TaskDTO;
import com.ai.da.python.PythonService;
import com.ai.da.service.CreditsService;
import com.ai.da.service.RabbitMQService;
import com.ai.da.service.SuperResolutionService;
import com.ai.da.service.TaskListService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Slf4j
@Service
public class SuperResolutionServiceImpl extends ServiceImpl<SuperResolutionMapper, SuperResolution> implements SuperResolutionService {
public class SuperResolutionServiceImpl extends ServiceImpl<TaskListMapper, TaskList> implements SuperResolutionService {
public static final Integer creditsConsumption = 100;
@@ -32,10 +45,11 @@ public class SuperResolutionServiceImpl extends ServiceImpl<SuperResolutionMappe
@Resource
private RabbitMQService rabbitMQService;
@Resource
private AsyncCallerUtil asyncCallerUtil;
@Resource
private PythonService pythonService;
@Resource
private TaskListService taskListService;
@Resource
private RedisUtil redisUtil;
@@ -45,78 +59,144 @@ public class SuperResolutionServiceImpl extends ServiceImpl<SuperResolutionMappe
@Value("${redis.key.resultMap}")
private String resultMapKey;
@Value("${minio.bucketName.users}")
private String usersBucket;
@Value("${minio.endpoint}")
private String endpoint;
@Override
public String prepareForSR(SuperResolutionDTO superResolutionDTO) {
public List<String> prepareForSR(List<SuperResolutionDTO> superResolutionDTOList) {
// 异步处理
// 判断用户当前积分是否够本次超分消耗
String credits = creditsService.getCredits();
if (new BigDecimal(credits).subtract(new BigDecimal(creditsConsumption)).compareTo(BigDecimal.ZERO) < 0){
return "Not enough Credits";
Long accountId = UserContext.getUserHolder().getId();
// 1、判断用户当前积分是否够本次超分消耗
Boolean credits = creditsService.checkCredits(accountId, CreditsEventsEnum.SUPER_RESOLUTION, superResolutionDTOList.size());
// todo 积分扣除待升级
if (credits) {
// 先扣除积分,后失败后再加上
creditsService.creditsDecrease(accountId, CreditsEventsEnum.SUPER_RESOLUTION.getName());
} else {
throw new BusinessException("Not enough Credits");
}
// 2、生成唯一id 使用uuid
String uuid = UUID.randomUUID().toString();
int num = 1;
// 判断已经正常生成结果的uuid或正在排队的uuid中是否有相同的id
while ((redisUtil.isElementExistsInMap(resultMapKey, uuid) ||
redisUtil.isElementExistsInZSet(orderForSR, uuid))
&& num < 10) {
uuid = UUID.randomUUID().toString();
num++;
}
// 无依据确定的数字
if (num > 10) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
ArrayList<String> uuidList = new ArrayList<>();
for (SuperResolutionDTO superResolutionDTO : superResolutionDTOList) {
// 2、生成唯一id 使用uuid
String uuid = UUID.randomUUID().toString();
int num = 1;
// 判断已经正常生成结果的uuid或正在排队的uuid中是否有相同的id
while ((redisUtil.isElementExistsInMap(resultMapKey, uuid) ||
redisUtil.isElementExistsInZSet(orderForSR, uuid))
&& num < 10) {
uuid = UUID.randomUUID().toString();
num++;
}
uuid = UUID.randomUUID().toString();
uuid += "-" + accountId;
uuidList.add(uuid);
// 3、截取minio地址 (前提是该url是由minio地址转换来的)
String inputString = superResolutionDTO.getImages();
String replace = inputString.replace(endpoint + "/", "");
String minioPath = replace.substring(0, replace.indexOf("?"));
// log.info(minioPath);
superResolutionDTO.setImages(minioPath);
superResolutionDTO.setUniqueId(uuid);
String jsonString = JSON.toJSONString(superResolutionDTO);
// 4、将数据存到数据库
TaskList taskList = new TaskList();
taskList.setAccountId(accountId);
taskList.setTaskType("SR");
taskList.setInputUrl(superResolutionDTO.getImages());
taskList.setScale(superResolutionDTO.getScale());
taskList.setStatus("Waiting");
taskList.setTaskId(superResolutionDTO.getUniqueId());
taskList.setCreateTime(LocalDateTime.now());
baseMapper.insert(taskList);
// 5、加入任务列表 设置状态为 等待中
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String name = superResolutionDTO.getImages();
taskListService.addToTaskListRedis(new TaskDTO<>(uuid, "SR", name.substring(name.lastIndexOf("/") + 1), superResolutionDTO, "Waiting", LocalDateTime.now().format(dateTimeFormatter)));
// 6、将消息发布到MQ消息队列
log.info("发送消息到SR_QUEUE参数 {}", jsonString);
rabbitMQService.publishMessageToSR(jsonString);
}
superResolutionDTO.setUniqueId(uuid);
String jsonString = JSON.toJSONString(superResolutionDTO);
// 3、加入redis排队便于获取实时排队信息
Double maxScore = redisUtil.getMaxScore(orderForSR);
redisUtil.addToZSet(orderForSR, uuid, maxScore);
// 4、将消息发布到MQ消息队列
rabbitMQService.publishMessageToSR(jsonString);
// 5、返回唯一id
return uuid;
// 6、返回唯一id列表
return uuidList;
}
@Transactional(rollbackFor = Exception.class)
@Override
public String SR(SuperResolutionDTO superResolutionDTO){
public void SR(SuperResolutionDTO superResolutionDTO) throws Exception {
// 1、向模型发起请求
// String srResult = asyncCallerUtil.SR(superResolutionDTO);
String srResult = pythonService.superResolution(superResolutionDTO);
pythonService.superResolution(superResolutionDTO);
// 2、向数据库插入数据
SuperResolution superResolution = new SuperResolution();
superResolution.setInput_url(superResolutionDTO.getImages());
superResolution.setScale(superResolutionDTO.getScale());
superResolution.setOutput_url(srResult);
superResolution.setCreateTime(LocalDateTime.now());
baseMapper.insert(superResolution);
// 3、记录积分变更
creditsService.insertToCreditsDetail(UserContext.getUserHolder().getId(),
CreditsEventsEnum.SUPER_RESOLUTION.getName(),
CreditsEventsEnum.SUPER_RESOLUTION.getValue(),
"negative");
// 4、扣除积分
creditsService.creditsDecrease(UserContext.getUserHolder().getId(), CreditsEventsEnum.SUPER_RESOLUTION.getValue());
// 4、将数据存在数据库
return srResult;
// 2、更新状态
updateSROutput(superResolutionDTO.getUniqueId(), "Executing", null);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void setSRResult(String taskId, String output, String status) {
Long accountId = Long.parseLong(taskId.substring(taskId.lastIndexOf("-") + 1));
// 获取结果后更新
updateSROutput(taskId, status, output);
if ("success".equals(status)) {
// 3、记录积分变更
creditsService.insertToCreditsDetail(accountId,
CreditsEventsEnum.SUPER_RESOLUTION.getName(),
CreditsEventsEnum.SUPER_RESOLUTION.getValue(),
"negative");
} else {
// 将之前扣除的积分返还
creditsService.creditsIncrease(accountId, CreditsEventsEnum.SUPER_RESOLUTION.getName());
}
}
@Override
public void updateSROutput(String taskId, String status, String output) {
UpdateWrapper<TaskList> uw = new UpdateWrapper<>();
uw.eq("task_id", taskId);
uw.set("output_url", output);
uw.set("status", status);
baseMapper.update(null, uw);
}
// 分页查询
@Override
public PageBaseResponse<TaskList> getTaskHistoryPage(QueryTaskHistoryDTO queryTaskHistoryDTO) {
QueryWrapper<TaskList> qw = new QueryWrapper<>();
qw.eq("account_id", UserContext.getUserHolder().getId());
String startTime = queryTaskHistoryDTO.getStartTime();
String endTime = queryTaskHistoryDTO.getEndTime();
if (StringUtil.isNullOrEmpty(startTime)) {
startTime = "2024-03-01 00:00:00";
}
if (StringUtil.isNullOrEmpty(endTime)) {
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
endTime = now.format(dateTimeFormatter);
}
qw.between("create_time", startTime, endTime);
qw.orderByDesc("create_time");
Page<TaskList> pageInfo = new Page<>(queryTaskHistoryDTO.getPage(), queryTaskHistoryDTO.getSize());
Page<TaskList> orderInfo = baseMapper.selectPage(pageInfo, qw);
if (CollectionUtils.isEmpty(orderInfo.getRecords())) {
return PageBaseResponse.success(new Page<>());
}
return PageBaseResponse.success(orderInfo);
}
}

View File

@@ -0,0 +1,123 @@
package com.ai.da.service.impl;
import com.ai.da.common.context.UserContext;
import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.common.utils.MinioUtil;
import com.ai.da.common.utils.RedisUtil;
import com.ai.da.mapper.primary.TaskListMapper;
import com.ai.da.mapper.primary.entity.TaskList;
import com.ai.da.model.dto.QueryTaskHistoryDTO;
import com.ai.da.model.dto.SuperResolutionDTO;
import com.ai.da.model.dto.TaskDTO;
import com.ai.da.model.vo.TaskVO;
import com.ai.da.service.SuperResolutionService;
import com.ai.da.service.TaskListService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.lang.reflect.Type;
import java.time.format.DateTimeFormatter;
import java.util.*;
@Service
@Slf4j
public class TaskListServiceImpl extends ServiceImpl<TaskListMapper, TaskList> implements TaskListService {
@Resource
private RedisUtil redisUtil;
@Value("${redis.key.taskList}")
private String taskListKey;
@Resource
private MinioUtil minioUtil;
@Resource
private SuperResolutionService superResolutionService;
@Override
@Transactional(rollbackFor = Exception.class)
public List<TaskDTO<SuperResolutionDTO>> getExecTask(List<String> taskIdList) {
Long id = UserContext.getUserHolder().getId();
// Set<String> keys = redisUtil.getKeysFromString(taskListKey + ":" + id + ":*");
ArrayList<TaskDTO<SuperResolutionDTO>> taskDTOS = new ArrayList<>();
taskIdList.forEach(taskId -> {
String taskDetail = redisUtil.getFromString(taskListKey + ":" + id + ":" + taskId);
Gson gson = new Gson();
Type type = new TypeToken<TaskDTO<SuperResolutionDTO>>() {
}.getType();
TaskDTO<SuperResolutionDTO> taskDTO = gson.fromJson(taskDetail, type);
if (Objects.isNull(taskDTO)) {
// 未执行成功的taskId在redis被删除将该条数据在db中的状态改为失败
superResolutionService.updateSROutput(taskId, "fail", null);
taskDTOS.add(new TaskDTO<>());
} else {
SuperResolutionDTO inputParam = taskDTO.getInputParam();
inputParam.setImages(minioUtil.getPresignedUrl(inputParam.getImages(), 24 * 60));
taskDTO.setOutputImage(StringUtil.isNullOrEmpty(taskDTO.getOutputImage()) ? null : minioUtil.getPresignedUrl(taskDTO.getOutputImage(), 24 * 60));
taskDTOS.add(taskDTO);
}
});
return taskDTOS;
}
public void addToTaskListRedis(TaskDTO<SuperResolutionDTO> taskDTO) {
String key = taskListKey + ":" + UserContext.getUserHolder().getId() + ":" + taskDTO.getTaskId();
redisUtil.addToString(key, new Gson().toJson(taskDTO), 24L * 60 * 60 * 3);
}
// 3、更新任务状态
@Override
public void updateTaskStatusOrOutputRedis(String taskId, String status, String output) {
String key = taskListKey + ":" + taskId.substring(taskId.lastIndexOf("-") + 1) + ":" + taskId;
String taskDetail = redisUtil.getFromString(key);
Gson gson = new Gson();
Type type = new TypeToken<TaskDTO<SuperResolutionDTO>>() {
}.getType();
TaskDTO<SuperResolutionDTO> taskDTO = gson.fromJson(taskDetail, type);
taskDTO.setStatus(status);
if (!StringUtil.isNullOrEmpty(output)) {
taskDTO.setOutputImage(output);
}
Long expire = redisUtil.getExpire(key);
redisUtil.addToString(key, new Gson().toJson(taskDTO), expire);
}
@Override
public PageBaseResponse<TaskVO> getAllTask(QueryTaskHistoryDTO queryTaskHistoryDTO) {
PageBaseResponse<TaskVO> response = new PageBaseResponse<>();
ArrayList<TaskVO> taskLists = new ArrayList<>();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
switch (queryTaskHistoryDTO.getType()) {
case "SR":
PageBaseResponse<TaskList> taskHistoryPage = superResolutionService.getTaskHistoryPage(queryTaskHistoryDTO);
List<TaskList> srHistory = taskHistoryPage.getContent();
srHistory.forEach(s -> {
// 成功失败的都返回
TaskVO task = new TaskVO();
task.setImageName(s.getInputUrl().substring(s.getInputUrl().lastIndexOf("/") + 1));
task.setInputImage(minioUtil.getPresignedUrl(s.getInputUrl(), 24 * 60));
task.setOutputImage(StringUtil.isNullOrEmpty(s.getOutputUrl()) ? null : minioUtil.getPresignedUrl(s.getOutputUrl(), 24 * 60));
task.setStatus(s.getStatus());
task.setTaskId(s.getTaskId());
task.setCreateDate(s.getCreateTime().format(dateTimeFormatter));
task.setOtherInput("×" + s.getScale());
taskLists.add(task);
});
BeanUtils.copyProperties(taskHistoryPage, response);
response.setContent(taskLists);
break;
case "GENERATE":
log.info("未知任务类型--GENERATE");
}
return response;
}
}