fix: fix performance salary calculation
Some checks failed
Build and Push Backend / docker (push) Failing after 6s
Some checks failed
Build and Push Backend / docker (push) Failing after 6s
This commit is contained in:
@@ -45,6 +45,7 @@ import com.starry.admin.modules.shop.service.IPlayCouponDetailsService;
|
||||
import com.starry.admin.modules.weichat.entity.order.*;
|
||||
import com.starry.admin.modules.weichat.service.WxCustomMpService;
|
||||
import com.starry.admin.modules.withdraw.service.IEarningsService;
|
||||
import com.starry.admin.utils.DateRangeUtils;
|
||||
import com.starry.admin.utils.SecurityUtils;
|
||||
import com.starry.common.utils.ConvertUtil;
|
||||
import com.starry.common.utils.IdUtils;
|
||||
@@ -456,8 +457,17 @@ public class PlayOrderInfoServiceImpl extends ServiceImpl<PlayOrderInfoMapper, P
|
||||
public List<PlayOrderInfoEntity> clerkSelectOrderInfoList(String clerkId, String startTime, String endTime) {
|
||||
LambdaQueryWrapper<PlayOrderInfoEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
lambdaQueryWrapper.eq(PlayOrderInfoEntity::getAcceptBy, clerkId);
|
||||
if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
|
||||
lambdaQueryWrapper.between(PlayOrderInfoEntity::getPurchaserTime, startTime, endTime);
|
||||
String normalizedStart = DateRangeUtils.normalizeStartOptional(startTime);
|
||||
String normalizedEnd = DateRangeUtils.normalizeEndOptional(endTime);
|
||||
if (StrUtil.isNotBlank(normalizedStart) && StrUtil.isNotBlank(normalizedEnd)) {
|
||||
lambdaQueryWrapper.between(PlayOrderInfoEntity::getPurchaserTime, normalizedStart, normalizedEnd);
|
||||
} else {
|
||||
if (StrUtil.isNotBlank(normalizedStart)) {
|
||||
lambdaQueryWrapper.ge(PlayOrderInfoEntity::getPurchaserTime, normalizedStart);
|
||||
}
|
||||
if (StrUtil.isNotBlank(normalizedEnd)) {
|
||||
lambdaQueryWrapper.le(PlayOrderInfoEntity::getPurchaserTime, normalizedEnd);
|
||||
}
|
||||
}
|
||||
return this.baseMapper.selectList(lambdaQueryWrapper);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.starry.admin.modules.statistics.module.vo.ClerkPerformanceOverviewRes
|
||||
import com.starry.admin.modules.statistics.module.vo.PlayClerkPerformanceInfoQueryVo;
|
||||
import com.starry.admin.modules.statistics.module.vo.PlayClerkPerformanceInfoReturnVo;
|
||||
import com.starry.admin.modules.statistics.service.IPlayClerkPerformanceService;
|
||||
import com.starry.admin.utils.DateRangeUtils;
|
||||
import com.starry.common.result.R;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
@@ -69,19 +70,27 @@ public class PlayClerkPerformanceController {
|
||||
public R listByPage(
|
||||
@ApiParam(value = "查询条件", required = true) @Validated @RequestBody PlayClerkPerformanceInfoQueryVo vo) {
|
||||
IPage<PlayClerkUserInfoEntity> page = clerkUserInfoService.selectByPage(vo);
|
||||
IPage<PlayClerkPerformanceInfoReturnVo> voPage = page.convert(u -> {
|
||||
IPage<PlayClerkPerformanceInfoReturnVo> voPage = page.convert(user -> {
|
||||
List<PlayClerkLevelInfoEntity> clerkLevelInfoEntity = playClerkLevelInfoService.selectAll();
|
||||
String startTime = vo.getEndOrderTime() != null ? vo.getEndOrderTime().get(0) : "";
|
||||
String endTime = vo.getEndOrderTime() != null ? vo.getEndOrderTime().get(1) : "";
|
||||
List<PlayOrderInfoEntity> orderInfoEntities = playOrderInfoService.clerkSelectOrderInfoList(u.getId(),
|
||||
String rawStart = vo.getEndOrderTime() != null && vo.getEndOrderTime().size() > 0
|
||||
? vo.getEndOrderTime().get(0)
|
||||
: null;
|
||||
String rawEnd = vo.getEndOrderTime() != null && vo.getEndOrderTime().size() > 1
|
||||
? vo.getEndOrderTime().get(1)
|
||||
: null;
|
||||
String startTime = DateRangeUtils.normalizeStartOptional(rawStart);
|
||||
String endTime = DateRangeUtils.normalizeEndOptional(rawEnd);
|
||||
List<PlayOrderInfoEntity> orderInfoEntities = playOrderInfoService.clerkSelectOrderInfoList(user.getId(),
|
||||
startTime, endTime);
|
||||
List<PlayPersonnelGroupInfoEntity> groupInfoEntities = playPersonnelGroupInfoService.selectAll();
|
||||
return playClerkPerformanceService.getClerkPerformanceInfo(u, orderInfoEntities, clerkLevelInfoEntity,
|
||||
groupInfoEntities);
|
||||
|
||||
return playClerkPerformanceService.getClerkPerformanceInfo(user, orderInfoEntities, clerkLevelInfoEntity,
|
||||
groupInfoEntities, startTime, endTime);
|
||||
});
|
||||
voPage.setRecords(voPage.getRecords().stream()
|
||||
.sorted(Comparator.comparing(PlayClerkPerformanceInfoReturnVo::getOrderNumber).reversed())
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
return R.ok(voPage);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ public interface IPlayClerkPerformanceService {
|
||||
*/
|
||||
PlayClerkPerformanceInfoReturnVo getClerkPerformanceInfo(PlayClerkUserInfoEntity userInfo,
|
||||
List<PlayOrderInfoEntity> orderInfoEntities, List<PlayClerkLevelInfoEntity> clerkLevelInfoEntity,
|
||||
List<PlayPersonnelGroupInfoEntity> groupInfoEntities);
|
||||
List<PlayPersonnelGroupInfoEntity> groupInfoEntities, String startTime, String endTime);
|
||||
|
||||
ClerkPerformanceOverviewResponseVo queryOverview(ClerkPerformanceOverviewQueryVo vo);
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.starry.admin.modules.clerk.module.entity.PlayClerkLevelInfoEntity;
|
||||
import com.starry.admin.modules.clerk.module.entity.PlayClerkUserInfoEntity;
|
||||
import com.starry.admin.modules.clerk.service.IPlayClerkLevelInfoService;
|
||||
import com.starry.admin.modules.clerk.service.IPlayClerkUserInfoService;
|
||||
import com.starry.admin.modules.order.module.constant.OrderConstant;
|
||||
import com.starry.admin.modules.order.module.entity.PlayOrderInfoEntity;
|
||||
import com.starry.admin.modules.order.service.IPlayOrderInfoService;
|
||||
import com.starry.admin.modules.personnel.module.entity.PlayPersonnelGroupInfoEntity;
|
||||
@@ -26,12 +27,13 @@ import com.starry.admin.modules.statistics.module.vo.ClerkPerformanceSnapshotVo;
|
||||
import com.starry.admin.modules.statistics.module.vo.ClerkPerformanceTrendPointVo;
|
||||
import com.starry.admin.modules.statistics.module.vo.PlayClerkPerformanceInfoReturnVo;
|
||||
import com.starry.admin.modules.statistics.service.IPlayClerkPerformanceService;
|
||||
import com.starry.admin.modules.withdraw.mapper.EarningsLineMapper;
|
||||
import com.starry.admin.utils.DateRangeUtils;
|
||||
import com.starry.admin.utils.SecurityUtils;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
@@ -51,9 +53,6 @@ import org.springframework.stereotype.Service;
|
||||
@Service
|
||||
public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceService {
|
||||
|
||||
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@Resource
|
||||
private IPlayClerkUserInfoService clerkUserInfoService;
|
||||
|
||||
@@ -66,10 +65,14 @@ public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceSer
|
||||
@Resource
|
||||
private IPlayPersonnelGroupInfoService playPersonnelGroupInfoService;
|
||||
|
||||
@Resource
|
||||
private EarningsLineMapper earningsLineMapper;
|
||||
|
||||
@Override
|
||||
public PlayClerkPerformanceInfoReturnVo getClerkPerformanceInfo(PlayClerkUserInfoEntity userInfo,
|
||||
List<PlayOrderInfoEntity> orderInfoEntities, List<PlayClerkLevelInfoEntity> clerkLevelInfoEntities,
|
||||
List<PlayPersonnelGroupInfoEntity> groupInfoEntities) {
|
||||
List<PlayPersonnelGroupInfoEntity> groupInfoEntities, String startTime, String endTime) {
|
||||
|
||||
Set<String> customIds = new HashSet<>();
|
||||
int orderContinueNumber = 0;
|
||||
int orderRefundNumber = 0;
|
||||
@@ -79,28 +82,31 @@ public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceSer
|
||||
BigDecimal orderTotalAmount = BigDecimal.ZERO;
|
||||
BigDecimal orderRewardAmount = BigDecimal.ZERO;
|
||||
BigDecimal orderRefundAmount = BigDecimal.ZERO;
|
||||
BigDecimal estimatedRevenue = BigDecimal.ZERO;
|
||||
|
||||
for (PlayOrderInfoEntity orderInfoEntity : orderInfoEntities) {
|
||||
customIds.add(orderInfoEntity.getPurchaserBy());
|
||||
finalAmount = finalAmount.add(defaultZero(orderInfoEntity.getFinalAmount()));
|
||||
if ("1".equals(orderInfoEntity.getFirstOrder())) {
|
||||
if (OrderConstant.YesNoFlag.YES.getCode().equals(orderInfoEntity.getFirstOrder())) {
|
||||
orderFirstAmount = orderFirstAmount.add(defaultZero(orderInfoEntity.getFinalAmount()));
|
||||
} else {
|
||||
orderContinueNumber++;
|
||||
orderTotalAmount = orderTotalAmount.add(defaultZero(orderInfoEntity.getFinalAmount()));
|
||||
}
|
||||
if ("2".equals(orderInfoEntity.getPlaceType())) {
|
||||
if (OrderConstant.PlaceType.REWARD.getCode().equals(orderInfoEntity.getPlaceType())) {
|
||||
orderRewardAmount = orderRewardAmount.add(defaultZero(orderInfoEntity.getFinalAmount()));
|
||||
}
|
||||
if ("1".equals(orderInfoEntity.getRefundType())) {
|
||||
if (OrderConstant.OrderRefundFlag.REFUNDED.getCode().equals(orderInfoEntity.getRefundType())) {
|
||||
orderRefundNumber++;
|
||||
orderRefundAmount = orderRefundAmount.add(defaultZero(orderInfoEntity.getRefundAmount()));
|
||||
}
|
||||
if ("1".equals(orderInfoEntity.getOrdersExpiredState())) {
|
||||
if (OrderConstant.OrdersExpiredState.EXPIRED.getCode().equals(orderInfoEntity.getOrdersExpiredState())) {
|
||||
ordersExpiredNumber++;
|
||||
}
|
||||
estimatedRevenue = estimatedRevenue.add(defaultZero(orderInfoEntity.getEstimatedRevenue()));
|
||||
}
|
||||
|
||||
BigDecimal estimatedRevenue =
|
||||
calculateEarningsAmount(userInfo.getId(), orderInfoEntities, startTime, endTime);
|
||||
|
||||
PlayClerkPerformanceInfoReturnVo returnVo = new PlayClerkPerformanceInfoReturnVo();
|
||||
returnVo.setClerkId(userInfo.getId());
|
||||
returnVo.setClerkNickname(userInfo.getNickname());
|
||||
@@ -149,7 +155,7 @@ public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceSer
|
||||
for (PlayClerkUserInfoEntity clerk : clerks) {
|
||||
List<PlayOrderInfoEntity> orders = playOrderInfoService.clerkSelectOrderInfoList(clerk.getId(),
|
||||
range.startTime, range.endTime);
|
||||
snapshots.add(buildSnapshot(clerk, orders, levelNameMap, groupNameMap));
|
||||
snapshots.add(buildSnapshot(clerk, orders, levelNameMap, groupNameMap, range.startTime, range.endTime));
|
||||
}
|
||||
int total = snapshots.size();
|
||||
ClerkPerformanceOverviewSummaryVo summary = aggregateSummary(snapshots);
|
||||
@@ -184,7 +190,8 @@ public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceSer
|
||||
(a, b) -> a));
|
||||
List<PlayOrderInfoEntity> orders = playOrderInfoService.clerkSelectOrderInfoList(clerk.getId(),
|
||||
range.startTime, range.endTime);
|
||||
ClerkPerformanceSnapshotVo snapshot = buildSnapshot(clerk, orders, levelNameMap, groupNameMap);
|
||||
ClerkPerformanceSnapshotVo snapshot =
|
||||
buildSnapshot(clerk, orders, levelNameMap, groupNameMap, range.startTime, range.endTime);
|
||||
ClerkPerformanceDetailResponseVo responseVo = new ClerkPerformanceDetailResponseVo();
|
||||
responseVo.setProfile(buildProfile(clerk, levelNameMap, groupNameMap));
|
||||
responseVo.setSnapshot(snapshot);
|
||||
@@ -262,7 +269,7 @@ public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceSer
|
||||
for (PlayOrderInfoEntity order : orders) {
|
||||
BigDecimal finalAmount = defaultZero(order.getFinalAmount());
|
||||
gmv = gmv.add(finalAmount);
|
||||
if ("1".equals(order.getFirstOrder())) {
|
||||
if (OrderConstant.YesNoFlag.YES.getCode().equals(order.getFirstOrder())) {
|
||||
firstAmount = firstAmount.add(finalAmount);
|
||||
} else {
|
||||
continuedAmount = continuedAmount.add(finalAmount);
|
||||
@@ -408,8 +415,27 @@ public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceSer
|
||||
return summary;
|
||||
}
|
||||
|
||||
private BigDecimal calculateEarningsAmount(String clerkId, List<PlayOrderInfoEntity> orders, String startTime,
|
||||
String endTime) {
|
||||
if (StrUtil.isBlank(clerkId) || CollectionUtil.isEmpty(orders)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
List<String> orderIds = orders.stream()
|
||||
.map(PlayOrderInfoEntity::getId)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtil.isEmpty(orderIds)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
String normalizedStart = DateRangeUtils.normalizeStartOptional(startTime);
|
||||
String normalizedEnd = DateRangeUtils.normalizeEndOptional(endTime);
|
||||
BigDecimal sum = earningsLineMapper.sumAmountByClerkAndOrderIds(clerkId, orderIds, normalizedStart,
|
||||
normalizedEnd);
|
||||
return defaultZero(sum);
|
||||
}
|
||||
|
||||
private ClerkPerformanceSnapshotVo buildSnapshot(PlayClerkUserInfoEntity clerk, List<PlayOrderInfoEntity> orders,
|
||||
Map<String, String> levelNameMap, Map<String, String> groupNameMap) {
|
||||
Map<String, String> levelNameMap, Map<String, String> groupNameMap, String startTime, String endTime) {
|
||||
ClerkPerformanceSnapshotVo snapshot = new ClerkPerformanceSnapshotVo();
|
||||
snapshot.setClerkId(clerk.getId());
|
||||
snapshot.setClerkNickname(clerk.getNickname());
|
||||
@@ -422,7 +448,6 @@ public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceSer
|
||||
BigDecimal continuedAmount = BigDecimal.ZERO;
|
||||
BigDecimal rewardAmount = BigDecimal.ZERO;
|
||||
BigDecimal refundAmount = BigDecimal.ZERO;
|
||||
BigDecimal estimatedRevenue = BigDecimal.ZERO;
|
||||
int firstCount = 0;
|
||||
int continuedCount = 0;
|
||||
int refundCount = 0;
|
||||
@@ -432,28 +457,28 @@ public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceSer
|
||||
BigDecimal finalAmount = defaultZero(order.getFinalAmount());
|
||||
gmv = gmv.add(finalAmount);
|
||||
userOrderMap.merge(order.getPurchaserBy(), 1, Integer::sum);
|
||||
if ("1".equals(order.getFirstOrder())) {
|
||||
if (OrderConstant.YesNoFlag.YES.getCode().equals(order.getFirstOrder())) {
|
||||
firstCount++;
|
||||
firstAmount = firstAmount.add(finalAmount);
|
||||
} else {
|
||||
continuedCount++;
|
||||
continuedAmount = continuedAmount.add(finalAmount);
|
||||
}
|
||||
if ("2".equals(order.getPlaceType())) {
|
||||
if (OrderConstant.PlaceType.REWARD.getCode().equals(order.getPlaceType())) {
|
||||
rewardAmount = rewardAmount.add(finalAmount);
|
||||
}
|
||||
if ("1".equals(order.getRefundType())) {
|
||||
if (OrderConstant.OrderRefundFlag.REFUNDED.getCode().equals(order.getRefundType())) {
|
||||
refundCount++;
|
||||
refundAmount = refundAmount.add(defaultZero(order.getRefundAmount()));
|
||||
}
|
||||
if ("1".equals(order.getOrdersExpiredState())) {
|
||||
if (OrderConstant.OrdersExpiredState.EXPIRED.getCode().equals(order.getOrdersExpiredState())) {
|
||||
expiredCount++;
|
||||
}
|
||||
estimatedRevenue = estimatedRevenue.add(defaultZero(order.getEstimatedRevenue()));
|
||||
}
|
||||
int orderCount = orders.size();
|
||||
int userCount = userOrderMap.size();
|
||||
int continuedUserCount = (int) userOrderMap.values().stream().filter(cnt -> cnt > 1).count();
|
||||
BigDecimal estimatedRevenue = calculateEarningsAmount(clerk.getId(), orders, startTime, endTime);
|
||||
snapshot.setGmv(gmv);
|
||||
snapshot.setFirstOrderAmount(firstAmount);
|
||||
snapshot.setContinuedOrderAmount(continuedAmount);
|
||||
@@ -504,41 +529,19 @@ public class PlayClerkPerformanceServiceImpl implements IPlayClerkPerformanceSer
|
||||
String startStr;
|
||||
String endStr;
|
||||
if (CollectionUtil.isNotEmpty(endOrderTime) && endOrderTime.size() >= 2) {
|
||||
startStr = normalizeStart(endOrderTime.get(0));
|
||||
endStr = normalizeEnd(endOrderTime.get(1));
|
||||
startStr = DateRangeUtils.normalizeStart(endOrderTime.get(0));
|
||||
endStr = DateRangeUtils.normalizeEnd(endOrderTime.get(1));
|
||||
} else {
|
||||
LocalDate end = LocalDate.now();
|
||||
LocalDate start = end.minusDays(6);
|
||||
startStr = start.format(DATE_FORMATTER) + " 00:00:00";
|
||||
endStr = end.format(DATE_FORMATTER) + " 23:59:59";
|
||||
startStr = start.format(DateRangeUtils.DATE_FORMATTER) + " 00:00:00";
|
||||
endStr = end.format(DateRangeUtils.DATE_FORMATTER) + " 23:59:59";
|
||||
}
|
||||
LocalDate startDate = LocalDate.parse(startStr.substring(0, 10), DATE_FORMATTER);
|
||||
LocalDate endDate = LocalDate.parse(endStr.substring(0, 10), DATE_FORMATTER);
|
||||
LocalDate startDate = LocalDate.parse(startStr.substring(0, 10), DateRangeUtils.DATE_FORMATTER);
|
||||
LocalDate endDate = LocalDate.parse(endStr.substring(0, 10), DateRangeUtils.DATE_FORMATTER);
|
||||
return new DateRange(startStr, endStr, startDate, endDate);
|
||||
}
|
||||
|
||||
private String normalizeStart(String raw) {
|
||||
if (StrUtil.isBlank(raw)) {
|
||||
return LocalDate.now().minusDays(6).format(DATE_FORMATTER) + " 00:00:00";
|
||||
}
|
||||
if (raw.length() > 10) {
|
||||
LocalDateTime.parse(raw, DATE_TIME_FORMATTER);
|
||||
return raw;
|
||||
}
|
||||
return raw + " 00:00:00";
|
||||
}
|
||||
|
||||
private String normalizeEnd(String raw) {
|
||||
if (StrUtil.isBlank(raw)) {
|
||||
return LocalDate.now().format(DATE_FORMATTER) + " 23:59:59";
|
||||
}
|
||||
if (raw.length() > 10) {
|
||||
LocalDateTime.parse(raw, DATE_TIME_FORMATTER);
|
||||
return raw;
|
||||
}
|
||||
return raw + " 23:59:59";
|
||||
}
|
||||
|
||||
private BigDecimal calcPercentage(int numerator, int denominator) {
|
||||
if (denominator <= 0) {
|
||||
return BigDecimal.ZERO;
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.starry.admin.modules.weichat.entity.order.PlayClerkOrderInfoQueryVo;
|
||||
import com.starry.admin.modules.weichat.entity.order.PlayClerkOrderListReturnVo;
|
||||
import com.starry.admin.modules.weichat.service.WxCustomMpService;
|
||||
import com.starry.admin.modules.weichat.service.WxCustomUserService;
|
||||
import com.starry.admin.utils.DateRangeUtils;
|
||||
import com.starry.admin.utils.SecurityUtils;
|
||||
import com.starry.admin.utils.SmsUtils;
|
||||
import com.starry.common.redis.RedisCache;
|
||||
@@ -126,11 +127,13 @@ public class WxClerkController {
|
||||
PlayClerkUserInfoEntity entity = clerkUserInfoService
|
||||
.selectById(ThreadLocalRequestDetail.getClerkUserInfo().getId());
|
||||
List<PlayClerkLevelInfoEntity> clerkLevelInfoEntity = playClerkLevelInfoService.selectAll();
|
||||
String startTime = DateRangeUtils.normalizeStartOptional(vo.getStartTime());
|
||||
String endTime = DateRangeUtils.normalizeEndOptional(vo.getEndTime());
|
||||
List<PlayOrderInfoEntity> orderInfoEntities = playOrderInfoService.clerkSelectOrderInfoList(entity.getId(),
|
||||
vo.getStartTime(), vo.getEndTime());
|
||||
startTime, endTime);
|
||||
List<PlayPersonnelGroupInfoEntity> groupInfoEntities = playPersonnelGroupInfoService.selectAll();
|
||||
return R.ok(playClerkPerformanceService.getClerkPerformanceInfo(entity, orderInfoEntities, clerkLevelInfoEntity,
|
||||
groupInfoEntities));
|
||||
groupInfoEntities, startTime, endTime));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -178,10 +178,16 @@ public class WxCustomMpService {
|
||||
data.add(new WxMpTemplateData("thing11", commodityName));
|
||||
data.add(new WxMpTemplateData("amount8", money));
|
||||
templateMessage.setData(data);
|
||||
PlayClerkUserInfoEntity clerkUserInfo =
|
||||
StringUtils.isBlank(openId) ? null : clerkUserInfoService.selectByOpenid(openId);
|
||||
String clerkId = clerkUserInfo == null ? null : clerkUserInfo.getId();
|
||||
String clerkNickname = clerkUserInfo == null ? null : clerkUserInfo.getNickname();
|
||||
try {
|
||||
proxyWxMpService(tenantId).getTemplateMsgService().sendTemplateMsg(templateMessage);
|
||||
} catch (WxErrorException e) {
|
||||
log.error("接单成功发送消息异常", e);
|
||||
log.error(
|
||||
"接单成功发送消息异常, tenantId={}, tenantName={}, orderId={}, orderNo={}, recipientType=clerk, clerkId={}, openId={}, nickname={}",
|
||||
tenantId, tenant.getTenantName(), orderId, orderNo, clerkId, openId, clerkNickname, e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.starry.admin.modules.withdraw.entity.EarningsLineEntity;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
@@ -34,4 +35,28 @@ public interface EarningsLineMapper extends BaseMapper<EarningsLineEntity> {
|
||||
" AND (status = 'available' OR (status = 'frozen' AND unlock_time <= #{now})) " +
|
||||
"ORDER BY unlock_time ASC")
|
||||
List<EarningsLineEntity> selectWithdrawableLines(@Param("clerkId") String clerkId, @Param("now") LocalDateTime now);
|
||||
|
||||
@Select("<script>" +
|
||||
"SELECT COALESCE(SUM(el.amount), 0) " +
|
||||
"FROM play_earnings_line el " +
|
||||
"JOIN play_order_info oi ON oi.id = el.order_id " +
|
||||
"WHERE el.deleted = 0 " +
|
||||
" AND oi.deleted = 0 " +
|
||||
" AND el.clerk_id = #{clerkId} " +
|
||||
" AND el.status <> 'reversed' " +
|
||||
"<if test='orderIds != null and orderIds.size > 0'>" +
|
||||
" AND el.order_id IN " +
|
||||
" <foreach item='id' collection='orderIds' open='(' separator=',' close=')'>#{id}</foreach>" +
|
||||
"</if>" +
|
||||
"<if test='startTime != null'>" +
|
||||
" AND oi.purchaser_time >= #{startTime}" +
|
||||
"</if>" +
|
||||
"<if test='endTime != null'>" +
|
||||
" AND oi.purchaser_time <= #{endTime}" +
|
||||
"</if>" +
|
||||
"</script>")
|
||||
BigDecimal sumAmountByClerkAndOrderIds(@Param("clerkId") String clerkId,
|
||||
@Param("orderIds") Collection<String> orderIds,
|
||||
@Param("startTime") String startTime,
|
||||
@Param("endTime") String endTime);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.starry.admin.utils;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
|
||||
/**
|
||||
* Utilities for normalizing date/time range inputs.
|
||||
*/
|
||||
public final class DateRangeUtils {
|
||||
|
||||
public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
private DateRangeUtils() {}
|
||||
|
||||
public static String normalizeStart(String raw) {
|
||||
if (StrUtil.isBlank(raw)) {
|
||||
return LocalDate.now().minusDays(6).format(DATE_FORMATTER) + " 00:00:00";
|
||||
}
|
||||
if (raw.length() > 10) {
|
||||
LocalDateTime.parse(raw, DATE_TIME_FORMATTER);
|
||||
return raw;
|
||||
}
|
||||
return raw + " 00:00:00";
|
||||
}
|
||||
|
||||
public static String normalizeEnd(String raw) {
|
||||
if (StrUtil.isBlank(raw)) {
|
||||
return LocalDate.now().format(DATE_FORMATTER) + " 23:59:59";
|
||||
}
|
||||
if (raw.length() > 10) {
|
||||
LocalDateTime.parse(raw, DATE_TIME_FORMATTER);
|
||||
return raw;
|
||||
}
|
||||
return raw + " 23:59:59";
|
||||
}
|
||||
|
||||
public static String normalizeStartOptional(String raw) {
|
||||
if (StrUtil.isBlank(raw)) {
|
||||
return null;
|
||||
}
|
||||
return normalizeFlexible(raw, false);
|
||||
}
|
||||
|
||||
public static String normalizeEndOptional(String raw) {
|
||||
if (StrUtil.isBlank(raw)) {
|
||||
return null;
|
||||
}
|
||||
return normalizeFlexible(raw, true);
|
||||
}
|
||||
|
||||
private static String normalizeFlexible(String raw, boolean isEnd) {
|
||||
String candidate = raw.trim().replace('T', ' ').replace("Z", "");
|
||||
if (candidate.length() <= 10) {
|
||||
candidate = candidate + (isEnd ? " 23:59:59" : " 00:00:00");
|
||||
} else if (candidate.length() > 19) {
|
||||
candidate = candidate.substring(0, 19);
|
||||
}
|
||||
try {
|
||||
LocalDateTime.parse(candidate, DATE_TIME_FORMATTER);
|
||||
return candidate;
|
||||
} catch (DateTimeParseException ex) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,15 +22,18 @@ import com.starry.admin.modules.statistics.module.vo.ClerkPerformanceOverviewRes
|
||||
import com.starry.admin.modules.statistics.module.vo.ClerkPerformanceOverviewSummaryVo;
|
||||
import com.starry.admin.modules.statistics.module.vo.ClerkPerformanceSnapshotVo;
|
||||
import com.starry.admin.modules.statistics.service.impl.PlayClerkPerformanceServiceImpl;
|
||||
import com.starry.admin.modules.withdraw.mapper.EarningsLineMapper;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.Month;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
@@ -55,6 +58,9 @@ class PlayClerkPerformanceServiceImplTest {
|
||||
@Mock
|
||||
private IPlayPersonnelGroupInfoService playPersonnelGroupInfoService;
|
||||
|
||||
@Mock
|
||||
private EarningsLineMapper earningsLineMapper;
|
||||
|
||||
@InjectMocks
|
||||
private PlayClerkPerformanceServiceImpl service;
|
||||
|
||||
@@ -89,6 +95,10 @@ class PlayClerkPerformanceServiceImplTest {
|
||||
|
||||
when(playOrderInfoService.clerkSelectOrderInfoList(eq("c1"), anyString(), anyString())).thenReturn(ordersA);
|
||||
when(playOrderInfoService.clerkSelectOrderInfoList(eq("c2"), anyString(), anyString())).thenReturn(ordersB);
|
||||
when(earningsLineMapper.sumAmountByClerkAndOrderIds(eq("c1"), anyCollection(), any(), any()))
|
||||
.thenReturn(new BigDecimal("170.00"));
|
||||
when(earningsLineMapper.sumAmountByClerkAndOrderIds(eq("c2"), anyCollection(), any(), any()))
|
||||
.thenReturn(new BigDecimal("55.00"));
|
||||
|
||||
setAuthentication();
|
||||
try {
|
||||
@@ -109,6 +119,8 @@ class PlayClerkPerformanceServiceImplTest {
|
||||
assertEquals(2, top.getContinuedOrderCount());
|
||||
assertEquals(new BigDecimal("66.67"), top.getContinuedRate());
|
||||
assertEquals(new BigDecimal("100.00"), top.getAverageTicketPrice());
|
||||
assertEquals(new BigDecimal("170.00"), top.getEstimatedRevenue());
|
||||
assertEquals(new BigDecimal("55.00"), response.getRankings().get(1).getEstimatedRevenue());
|
||||
|
||||
ClerkPerformanceOverviewSummaryVo summary = response.getSummary();
|
||||
assertEquals(new BigDecimal("380.00"), summary.getTotalGmv());
|
||||
@@ -117,6 +129,7 @@ class PlayClerkPerformanceServiceImplTest {
|
||||
assertEquals(2, summary.getTotalContinuedOrderCount());
|
||||
assertEquals(new BigDecimal("50.00"), summary.getContinuedRate());
|
||||
assertEquals(new BigDecimal("95.00"), summary.getAverageTicketPrice());
|
||||
assertEquals(new BigDecimal("225.00"), summary.getTotalEstimatedRevenue());
|
||||
} finally {
|
||||
clearAuthentication();
|
||||
}
|
||||
@@ -146,6 +159,8 @@ class PlayClerkPerformanceServiceImplTest {
|
||||
withRefund(order("c1", "userB", "0", "2", "1", new BigDecimal("60.00"), new BigDecimal("30.00"),
|
||||
LocalDateTime.of(2024, Month.AUGUST, 2, 18, 0)), new BigDecimal("20.00")));
|
||||
when(playOrderInfoService.clerkSelectOrderInfoList(eq("c1"), anyString(), anyString())).thenReturn(orders);
|
||||
when(earningsLineMapper.sumAmountByClerkAndOrderIds(eq("c1"), anyCollection(), any(), any()))
|
||||
.thenReturn(new BigDecimal("110.00"));
|
||||
|
||||
setAuthentication();
|
||||
try {
|
||||
@@ -158,6 +173,7 @@ class PlayClerkPerformanceServiceImplTest {
|
||||
assertEquals(3, response.getSnapshot().getOrderCount());
|
||||
assertEquals(new BigDecimal("66.67"), response.getSnapshot().getContinuedRate());
|
||||
assertEquals(new BigDecimal("86.67"), response.getSnapshot().getAverageTicketPrice());
|
||||
assertEquals(new BigDecimal("110.00"), response.getSnapshot().getEstimatedRevenue());
|
||||
|
||||
assertNotNull(response.getComposition());
|
||||
assertEquals(4, response.getComposition().getOrderComposition().size());
|
||||
@@ -191,6 +207,30 @@ class PlayClerkPerformanceServiceImplTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("getClerkPerformanceInfo aligns earnings lookup with purchaser time")
|
||||
void getClerkPerformanceInfoAlignsEarningsLookupWithPurchaserTime() {
|
||||
PlayClerkUserInfoEntity clerk = buildClerk("c3", "Carol", "g3", "l3");
|
||||
List<PlayOrderInfoEntity> orders = Collections.singletonList(
|
||||
order("c3", "userX", "1", "0", "0", new BigDecimal("99.00"), new BigDecimal("50.00"),
|
||||
LocalDateTime.of(2024, Month.AUGUST, 1, 15, 30)));
|
||||
when(earningsLineMapper.sumAmountByClerkAndOrderIds(eq("c3"), anyCollection(), any(), any()))
|
||||
.thenReturn(new BigDecimal("80.00"));
|
||||
|
||||
service.getClerkPerformanceInfo(clerk, orders, Collections.singletonList(level("l3", "钻石")),
|
||||
Collections.singletonList(group("g3", "三组")), "2024-08-01", "2024-08-02");
|
||||
|
||||
ArgumentCaptor<Collection<String>> orderIdsCaptor = ArgumentCaptor.forClass(Collection.class);
|
||||
ArgumentCaptor<String> startCaptor = ArgumentCaptor.forClass(String.class);
|
||||
ArgumentCaptor<String> endCaptor = ArgumentCaptor.forClass(String.class);
|
||||
verify(earningsLineMapper).sumAmountByClerkAndOrderIds(eq("c3"), orderIdsCaptor.capture(),
|
||||
startCaptor.capture(), endCaptor.capture());
|
||||
|
||||
assertTrue(orderIdsCaptor.getValue().contains(orders.get(0).getId()));
|
||||
assertEquals("2024-08-01 00:00:00", startCaptor.getValue());
|
||||
assertEquals("2024-08-02 23:59:59", endCaptor.getValue());
|
||||
}
|
||||
|
||||
private PlayClerkUserInfoEntity buildClerk(String id, String name, String groupId, String levelId) {
|
||||
PlayClerkUserInfoEntity entity = new PlayClerkUserInfoEntity();
|
||||
entity.setId(id);
|
||||
@@ -229,6 +269,7 @@ class PlayClerkPerformanceServiceImplTest {
|
||||
order.setEstimatedRevenue(estimatedRevenue);
|
||||
order.setOrdersExpiredState("1".equals(refundType) ? "1" : "0");
|
||||
order.setPurchaserTime(purchaserTime);
|
||||
order.setId(clerkId + "-" + purchaser + "-" + purchaserTime.toString());
|
||||
return order;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user