Commit e49a4064 authored by renjie's avatar renjie

定时任务检查过期

parent dd894e14
...@@ -152,7 +152,11 @@ ...@@ -152,7 +152,11 @@
<version>7.4.0</version> <version>7.4.0</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-spring</artifactId>
<version>2.1.0</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
package com.edgec.browserbackend.account.scheduler;
import com.edgec.browserbackend.account.domain.*;
import com.edgec.browserbackend.account.repository.AccountRepository;
import com.edgec.browserbackend.account.repository.UserBalanceRepository;
import com.edgec.browserbackend.account.repository.UserPrePaidBillingRepository;
import com.edgec.browserbackend.account.service.UserLackMoneyService;
import com.edgec.browserbackend.account.service.UserPrePaidBillingService;
import com.edgec.browserbackend.account.utils.AccountServicePool;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.Instant;
import java.time.YearMonth;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@Component
public class BillingTaskScheduler {
private static final Logger log = LoggerFactory.getLogger(BillingTaskScheduler.class);
@Autowired
private AccountRepository repository;
@Autowired
private UserPrePaidBillingService userPrePaidBillingService;
@Autowired
private UserPrePaidBillingRepository userPrePaidBillingRepository;
@Autowired
private UserBalanceRepository userBalanceRepository;
@Autowired
private UserLackMoneyService userLackMoneyService;
// @Scheduled(cron = "0 0 3 2-4 * ?")
// public void computeMonthlyBills() {
//
// final PageRequest request = PageRequest.of(0, 100);
//
// Page<Account> users = repository.findByParentIsNull(request);
//
// int pageSize = users.getTotalPages();
//
// final YearMonth lastmonth = YearMonth.now().minusMonths(1);
//
// int monthValue = lastmonth.getMonthValue();
// int year = lastmonth.getYear();
//
// for (int i = 0; i < pageSize; i++) {
//
// if (i > 0)
// users = repository.findByParentIsNull(PageRequest.of(i, 100));
//
// List<Account> currentAcounts = users.getContent();
//
// if (currentAcounts != null && currentAcounts.size() > 0) {
//
// currentAcounts.forEach(x -> {
//
// List<UserService> userServices = x.getUserServices();
//
// if (userServices == null || userServices.size() <= 0)
// return;
//
// //only one service 'intelligroup' currently.
// UserService userService = userServices.get(0);
// if (userService.getServiceType().equals(ServiceType.FORMAL) || userService.getServiceType().equals(ServiceType.TRIAL)) {
// try {
// List<UserPrePaidBilling> bill = userPrePaidBillingRepository.findByUsernameAndServicesAndYearAndMonth(x.getName(), userService.getServiceName().toString(), year, monthValue);
// if (bill.size() == 0)
// updateBillForMonth(x, userService, year, monthValue);
// } catch (Exception e) {
// log.error("Month bill generation fails, user: {}, year: {}, month: {}", x.getName(), year, monthValue, e);
// }
// }
// });
// }
// }
//
// }
// private void updateBillForMonth(Account account, UserService service, int year, int month) {
// List<Account> children = repository.findByParent(account.getName());
// if (children != null && children.size() > 0) {
// for (Account child : children) {
// upsertAccountMonthBill(child, service, year, month);
// }
// }
// upsertAccountMonthBill(account, service, year, month);
// }
// private void upsertAccountMonthBill(Account account, UserService service, int year, int month) {
// List<UserPrePaidBilling> existing = userPrePaidBillingRepository.findByUsernameAndServicesAndYearAndMonth(account.getName(), service.getServiceName().toString(), year, month);
// if (existing.size() == 0) {
// UserBillDto bill = cloudService.getMonthlyBills(account.getName(), year, month);
// float potential = bill.getOwnPotentialCost();
// float actual = bill.getOwnActualCost();
// float diff = potential - actual;
// if (diff < 0)
// diff = 0;
// float ownBillCost = Math.round(diff * service.getDiscount() / 100.0f);
// float total = ownBillCost;
// BillStatus billStatus = BillStatus.UNPAID;
// if (total == 0) {
// billStatus = BillStatus.PAID;
// }
// boolean isPrepaid = false;
// int chargeType = 9;
// String user = account.getName();
// String target;
// if (StringUtils.isEmpty(account.getParent())) {
// target = account.getName() + "创建的云端伸缩组(" + month + "月)";
// userPrePaidBillingRepository.upsertBillOwnCost(account.getName(), service.getServiceName().toString(), year, month, Instant.now().toEpochMilli(), potential, actual, ownBillCost, total, billStatus, isPrepaid, user, chargeType, target);
// } else {
// target = "子用户" + account.getName() + "创建的云端伸缩组(" + month + "月)";
// userPrePaidBillingRepository.upsertBillOwnCost(account.getParent(), service.getServiceName().toString(), year, month, Instant.now().toEpochMilli(), potential, actual, ownBillCost, total, billStatus, isPrepaid, user, chargeType, target);
// userPrePaidBillingRepository.upsertBillOwnCost(account.getName(), service.getServiceName().toString(), year, month, Instant.now().toEpochMilli(), potential, actual, ownBillCost, total, BillStatus.PARENTSHALLPAY, isPrepaid, user, chargeType, target);
// }
// }
// }
@Scheduled(cron = "0 0 0 * * ?")
public void updateUserBillingAndBalance() {
CompletableFuture.runAsync(() -> {
List<UserPrePaidBilling> billings = userPrePaidBillingRepository.findByStatus(BillStatus.UNPAID);
for (UserPrePaidBilling billing : billings) {
UserBalance balance = userBalanceRepository.findById(billing.getUsername()).orElse(null);
float shouldPayAmount;
if (billing.getDeductionRecords() == null) {
shouldPayAmount = billing.getTotal();
} else {
List<DeductionRecord> deductionAmount = billing.getDeductionRecords();
shouldPayAmount = billing.getTotal() - ((Double) deductionAmount.stream().mapToDouble(DeductionRecord::getDeductionAmount).sum()).floatValue();
}
if (balance == null || balance.getBalanced() < 1) {
} else {
DeductionRecord deductionRecord = new DeductionRecord();
deductionRecord.setDeductionTime(Instant.now().getEpochSecond());
billing.addDeductionRecord(deductionRecord);
if (balance.getBalanced() < shouldPayAmount) {
float affordable = balance.getBalanced();
deductionRecord.setDeductionAmount(affordable);
if (userPrePaidBillingRepository.updateBillStatus(billing.getId(), BillStatus.UNPAID, BillStatus.UNPAID, billing.getDeductionRecords()) == 1) {
userBalanceRepository.incrementBalance(balance, -affordable, affordable);
}
break;
} else {
deductionRecord.setDeductionAmount(shouldPayAmount);
if (userPrePaidBillingRepository.updateBillStatus(billing.getId(), BillStatus.UNPAID, BillStatus.PAID, billing.getDeductionRecords()) == 1) {
userBalanceRepository.incrementBalance(balance, -shouldPayAmount, shouldPayAmount);
}
}
}
}
updateAllUserLackMoney();
}, AccountServicePool.taskPool);
}
private void updateAllUserLackMoney(){
List<UserPrePaidBilling> unpaidBillings = userPrePaidBillingRepository.findAll();
Map<String, List<UserPrePaidBilling>> userPrePaidBillingMap = unpaidBillings.stream().collect(Collectors.groupingBy(UserPrePaidBilling::getUsername));
for (Map.Entry<String, List<UserPrePaidBilling>> entry : userPrePaidBillingMap.entrySet()) {
userLackMoneyService.updateLackMoney(entry.getValue(), false);
}
}
}
package com.edgec.browserbackend.account.scheduler;
import com.edgec.browserbackend.account.domain.CompanyMonthReport;
import com.edgec.browserbackend.account.repository.MonthReportRepository;
import com.edgec.browserbackend.account.repository.UserPrePaidBillingRepository;
import net.javacrumbs.shedlock.core.SchedulerLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.YearMonth;
@Component
public class PrepaidBillingCountTaskScheduler {
private static final Logger log = LoggerFactory.getLogger(PrepaidBillingCountTaskScheduler.class);
@Autowired
private UserPrePaidBillingRepository userPrePaidBillingRepository;
@Autowired
private MonthReportRepository monthReportRepository;
@Scheduled(cron = "0 0 5 1-3 * ?")
@SchedulerLock(name = "countMonthlyPrepaid", lockAtMostForString = "PT90S", lockAtLeastForString = "PT60S")
public void countMonthlyPrepaid() {
final YearMonth lastmonth = YearMonth.now().minusMonths(1);
int monthValue = lastmonth.getMonthValue();
int year = lastmonth.getYear();
for (int i = 2019; i <= year; i++){
for (int j =1; j <= monthValue; j++){
if (i == 2019 && j < 5){
continue;
}else {
if (monthReportRepository.findByYearAndMonth(i,j) == null){
int count = new Long(userPrePaidBillingRepository.countPrepaidNum(i, j)).intValue();
float amountSum = userPrePaidBillingRepository.prepaidAmount(i, j);
CompanyMonthReport companyMonthReport = new CompanyMonthReport();
companyMonthReport.setYear(i);
companyMonthReport.setMonth(j);
companyMonthReport.setPrepaidBillingCount(count);
companyMonthReport.setPrepaidBillingAmount(amountSum);
monthReportRepository.save(companyMonthReport);
}else {
continue;
}
}
}
}
}
}
...@@ -50,7 +50,7 @@ public class UserLackMoneyServiceImpl implements UserLackMoneyService { ...@@ -50,7 +50,7 @@ public class UserLackMoneyServiceImpl implements UserLackMoneyService {
JSONObject param = new JSONObject(); JSONObject param = new JSONObject();
param.put("billsamount", billsAmount); param.put("billsamount", billsAmount);
param.put("totalunpaid", totalUnpaid); param.put("totalunpaid", totalUnpaid);
SmsUtils.sendCloadamSms(telephone, SmsUtils.SmsTemplateCode.CLOUDAM_ARREARS, param); SmsUtils.sendIpSms(telephone, SmsUtils.SmsTemplateCode.CLOUDAM_ARREARS, param);
} }
} }
......
...@@ -3,6 +3,7 @@ package com.edgec.browserbackend.browser.domain; ...@@ -3,6 +3,7 @@ package com.edgec.browserbackend.browser.domain;
import com.edgec.browserbackend.browser.dto.Interval; import com.edgec.browserbackend.browser.dto.Interval;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -19,6 +20,7 @@ public class IpResource { ...@@ -19,6 +20,7 @@ public class IpResource {
private String region; private String region;
private String regionCn; private String regionCn;
//0:正常, 1:已过期, 2:即将过期 //0:正常, 1:已过期, 2:即将过期
@Transient
private int status; private int status;
private List<String> port; private List<String> port;
private long purchasedTime; private long purchasedTime;
......
package com.edgec.browserbackend.browser.domain;
public enum IpStatus {
NORMAL,
PROTECTION,
EXPIRED,
UNBIND,
ASSIGN;
}
...@@ -17,4 +17,6 @@ public interface IpResourceRepository extends MongoRepository<IpResource, String ...@@ -17,4 +17,6 @@ public interface IpResourceRepository extends MongoRepository<IpResource, String
Page<IpResource> findByAddrLikeAndIdInAndIsDeleted(String addr, List<String> ipIds, boolean isDeleted, Pageable pageable); Page<IpResource> findByAddrLikeAndIdInAndIsDeleted(String addr, List<String> ipIds, boolean isDeleted, Pageable pageable);
Page<IpResource> findByVendorLikeAndIdInAndIsDeleted(String vendor, List<String> ipIds, boolean isDeleted, Pageable pageable); Page<IpResource> findByVendorLikeAndIdInAndIsDeleted(String vendor, List<String> ipIds, boolean isDeleted, Pageable pageable);
Page<IpResource> findByRegionLikeAndIdInAndIsDeleted(String region, List<String> ipIds, boolean isDeleted, Pageable pageable); Page<IpResource> findByRegionLikeAndIdInAndIsDeleted(String region, List<String> ipIds, boolean isDeleted, Pageable pageable);
List<IpResource> findByValidTimeBetween(long beginTime, long endTime);
} }
...@@ -27,6 +27,7 @@ import org.springframework.data.domain.Page; ...@@ -27,6 +27,7 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.aggregation.ArrayOperators;
import org.springframework.http.*; import org.springframework.http.*;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
...@@ -172,10 +173,7 @@ public class IpResourceServiceImpl implements IpResourceService { ...@@ -172,10 +173,7 @@ public class IpResourceServiceImpl implements IpResourceService {
// ipResource.setPurchasedTime(Long.valueOf((String) jsonObject.get("createdWhen"))); // ipResource.setPurchasedTime(Long.valueOf((String) jsonObject.get("createdWhen")));
// ipResource.setValidTime(Long.valueOf((String)jsonObject.get("validTill"))); // ipResource.setValidTime(Long.valueOf((String)jsonObject.get("validTill")));
ipResource.setPurchasedTime(Instant.now().toEpochMilli()); ipResource.setPurchasedTime(Instant.now().toEpochMilli());
if (ipResourceRequestDto.getUnit().equals("month")) ipResource.setValidTime(Instant.parse(x.getValidTill()).toEpochMilli());
ipResource.setValidTime(Instant.now().plusSeconds(60*60*24*30).toEpochMilli());
else if (ipResourceRequestDto.getUnit().equals("week"))
ipResource.setValidTime(Instant.now().plusSeconds(60*60*24*7).toEpochMilli());
ipResource.setPort(port); ipResource.setPort(port);
ipResource.setVendor(Vendor.valueOf(ipResourceRequestDto.getVendor())); ipResource.setVendor(Vendor.valueOf(ipResourceRequestDto.getVendor()));
ipResource.setStatus(0); ipResource.setStatus(0);
...@@ -362,6 +360,12 @@ public class IpResourceServiceImpl implements IpResourceService { ...@@ -362,6 +360,12 @@ public class IpResourceServiceImpl implements IpResourceService {
else else
shopDto = new ShopDto(); shopDto = new ShopDto();
} }
if (x.getValidTime() <= Instant.now().plusSeconds(60*60*24*7).toEpochMilli() && x.getValidTime() >Instant.now().toEpochMilli())
x.setStatus(2);
else if (x.getValidTime() <= Instant.now().toEpochMilli())
x.setStatus(1);
else
x.setStatus(0);
ipResourceDtos.add(new IpResourceDto(x, shopDto)); ipResourceDtos.add(new IpResourceDto(x, shopDto));
}); });
} }
...@@ -378,6 +382,12 @@ public class IpResourceServiceImpl implements IpResourceService { ...@@ -378,6 +382,12 @@ public class IpResourceServiceImpl implements IpResourceService {
else else
shopDto = new ShopDto(); shopDto = new ShopDto();
} }
if (x.getValidTime() <= Instant.now().plusSeconds(60*60*24*7).toEpochMilli() && x.getValidTime() >Instant.now().toEpochMilli())
x.setStatus(2);
else if (x.getValidTime() <= Instant.now().toEpochMilli())
x.setStatus(1);
else
x.setStatus(0);
ipResourceDtos.add(new IpResourceDto(x, shopDto)); ipResourceDtos.add(new IpResourceDto(x, shopDto));
}); });
} }
...@@ -394,6 +404,12 @@ public class IpResourceServiceImpl implements IpResourceService { ...@@ -394,6 +404,12 @@ public class IpResourceServiceImpl implements IpResourceService {
else else
shopDto = new ShopDto(); shopDto = new ShopDto();
} }
if (x.getValidTime() <= Instant.now().plusSeconds(60*60*24*7).toEpochMilli() && x.getValidTime() >Instant.now().toEpochMilli())
x.setStatus(2);
else if (x.getValidTime() <= Instant.now().toEpochMilli())
x.setStatus(1);
else
x.setStatus(0);
ipResourceDtos.add(new IpResourceDto(x, shopDto)); ipResourceDtos.add(new IpResourceDto(x, shopDto));
}); });
} else { } else {
...@@ -408,6 +424,12 @@ public class IpResourceServiceImpl implements IpResourceService { ...@@ -408,6 +424,12 @@ public class IpResourceServiceImpl implements IpResourceService {
else else
shopDto = new ShopDto(); shopDto = new ShopDto();
} }
if (x.getValidTime() <= Instant.now().plusSeconds(60*60*24*7).toEpochMilli() && x.getValidTime() >Instant.now().toEpochMilli())
x.setStatus(2);
else if (x.getValidTime() <= Instant.now().toEpochMilli())
x.setStatus(1);
else
x.setStatus(0);
ipResourceDtos.add(new IpResourceDto(x, shopDto)); ipResourceDtos.add(new IpResourceDto(x, shopDto));
}); });
} }
......
package com.edgec.browserbackend.browser.task;
import com.alibaba.fastjson.JSONObject;
import com.edgec.browserbackend.account.domain.Account;
import com.edgec.browserbackend.account.repository.AccountRepository;
import com.edgec.browserbackend.browser.domain.IpResource;
import com.edgec.browserbackend.browser.repository.IpResourceRepository;
import com.edgec.browserbackend.common.commons.utils.SmsUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.Instant;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Component
public class ExpireSoonWarn {
@Autowired
private AccountRepository accountRepository;
@Autowired
private IpResourceRepository ipResourceRepository;
@Scheduled(cron = "0 0 1 * * ?")
public void sendMessages() {
this.sendExpiredIpAccount(3);
this.sendExpiredIpAccount(7);
}
private void sendExpiredIpAccount(int day) {
List<IpResource> ipResources = ipResourceRepository.findByValidTimeBetween(
Instant.now().atZone(ZoneOffset.UTC).plusDays(day - 1).toEpochSecond() * 1000,
Instant.now().atZone(ZoneOffset.UTC).plusDays(day).toEpochSecond() * 1000);
if (ipResources != null && ipResources.size() > 0) {
Map<String, List<IpResource>> map = ipResources.stream().collect(Collectors.groupingBy(IpResource::getOwner));
for (String key : map.keySet()) {
sendToAccount(key, day, map.get(key).size());
}
}
}
private void sendToAccount(String username, int day, int amount) {
Account account = accountRepository.findByName(username);
JSONObject param = new JSONObject();
param.put("day", day);
param.put("amount", amount);
SmsUtils.sendIpSms(account.getPhoneNumber(), SmsUtils.SmsTemplateCode.VPS_EXPIRE, param);
}
}
...@@ -91,7 +91,7 @@ public class SmsUtils { ...@@ -91,7 +91,7 @@ public class SmsUtils {
// } // }
public static void sendVpsSms(String phoneNum, SmsTemplateCode smsTemplateCode, JSONObject param) { public static void sendIpSms(String phoneNum, SmsTemplateCode smsTemplateCode, JSONObject param) {
CommonRequest request = new CommonRequest(); CommonRequest request = new CommonRequest();
//request.setProtocol(ProtocolType.HTTPS); //request.setProtocol(ProtocolType.HTTPS);
request.setMethod(MethodType.POST); request.setMethod(MethodType.POST);
...@@ -99,7 +99,7 @@ public class SmsUtils { ...@@ -99,7 +99,7 @@ public class SmsUtils {
request.setVersion("2017-05-25"); request.setVersion("2017-05-25");
request.setAction("SendSms"); request.setAction("SendSms");
request.putQueryParameter("PhoneNumbers", phoneNum); request.putQueryParameter("PhoneNumbers", phoneNum);
request.putQueryParameter("SignName", "防关联VPS"); request.putQueryParameter("SignName", "防关联浏览器");
request.putQueryParameter("TemplateCode", smsTemplateCode.getCode()); request.putQueryParameter("TemplateCode", smsTemplateCode.getCode());
request.putQueryParameter("TemplateParam", param.toJSONString()); request.putQueryParameter("TemplateParam", param.toJSONString());
try { try {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment