| | |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.dsh.course.entity.CoursePackageOrderStudent; |
| | | import com.dsh.course.feignClient.account.*; |
| | | import com.dsh.course.feignClient.account.model.*; |
| | | import com.dsh.course.feignClient.activity.PointMercharsClient; |
| | | import com.dsh.course.feignClient.activity.CouponClient; |
| | | import com.dsh.course.feignClient.activity.PayHuiminClient; |
| | | import com.dsh.course.feignClient.activity.model.CouponDeductionQuery; |
| | | import com.dsh.course.feignClient.activity.model.CouponDeductionVO; |
| | | import com.dsh.course.feignClient.activity.model.HuiminPayQuery; |
| | | import com.dsh.course.feignClient.activity.model.UserCouponPayment; |
| | | import com.dsh.course.feignClient.competition.CompetitionClient; |
| | | import com.dsh.course.feignClient.competition.model.CompetionVO; |
| | | import com.dsh.course.feignClient.competition.model.Competition; |
| | | import com.dsh.course.feignClient.competition.model.CompetitionQuery; |
| | | import com.dsh.course.feignClient.competition.model.PaymentCompetition; |
| | | import com.dsh.course.feignClient.course.*; |
| | | import com.dsh.course.feignClient.course.model.TCoursePackage; |
| | | import com.dsh.course.feignClient.course.model.TCoursePackagePayment; |
| | | import com.dsh.course.feignClient.other.BallClient; |
| | | import com.dsh.course.feignClient.other.SiteClient; |
| | | import com.dsh.course.feignClient.other.StoreClient; |
| | | import com.dsh.course.feignClient.other.model.GameDataQuery; |
| | | import com.dsh.course.feignClient.other.model.Site; |
| | | import com.dsh.course.feignClient.other.model.TGameRecord; |
| | | import com.dsh.course.model.MoneyBack; |
| | | import com.dsh.guns.config.UserExt; |
| | | import com.dsh.guns.core.base.controller.BaseController; |
| | |
| | | import java.time.temporal.ChronoUnit; |
| | | import java.time.temporal.TemporalAdjusters; |
| | | import java.util.*; |
| | | import java.util.function.Predicate; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | |
| | | @RequestMapping("/data") |
| | | public class DataStatisticsController extends BaseController { |
| | | private String PREFIX = "/system/dataStatistics/"; |
| | | |
| | | private Integer resolveOperatorId(Integer operatorId) { |
| | | Integer objectType = UserExt.getUser().getObjectType(); |
| | | if (Integer.valueOf(2).equals(objectType)) { |
| | | return UserExt.getUser().getObjectId(); |
| | | } |
| | | return operatorId; |
| | | } |
| | | |
| | | private Integer resolveStoreId(Integer storeId) { |
| | | Integer objectType = UserExt.getUser().getObjectType(); |
| | | if (!Integer.valueOf(2).equals(objectType) || storeId == null) { |
| | | return storeId; |
| | | } |
| | | TStore store = storeService.getById(storeId); |
| | | if (store != null && UserExt.getUser().getObjectId().equals(store.getOperatorId())) { |
| | | return storeId; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 将门店统计目标限制在当前账号可见范围内。门店账号固定统计自身;运营商账号 |
| | | * 只能统计归属自己的门店,避免其它门店的数据混入其统计结果。 |
| | | */ |
| | | private Integer resolveStatisticsStoreId(Integer storeId) { |
| | | Integer objectType = UserExt.getUser().getObjectType(); |
| | | if (Integer.valueOf(3).equals(objectType)) { |
| | | return UserExt.getUser().getObjectId(); |
| | | } |
| | | if (storeId == null) { |
| | | return null; |
| | | } |
| | | TStore store = storeService.getById(storeId); |
| | | if (store == null || Integer.valueOf(3).equals(store.getState())) { |
| | | return null; |
| | | } |
| | | if (Integer.valueOf(2).equals(objectType) |
| | | && !UserExt.getUser().getObjectId().equals(store.getOperatorId())) { |
| | | return null; |
| | | } |
| | | return storeId; |
| | | } |
| | | |
| | | /** 平台(0)或运营商统计均以门店的 operatorId 作为唯一归属依据。 */ |
| | | private List<TStore> listStatisticsStores(Integer operatorId, boolean enabledOnly) { |
| | | LambdaQueryWrapper<TStore> wrapper = new LambdaQueryWrapper<>(); |
| | | if (enabledOnly) { |
| | | wrapper.eq(TStore::getState, 1); |
| | | } else { |
| | | wrapper.ne(TStore::getState, 3); |
| | | } |
| | | if (operatorId == null) { |
| | | // 平台统计:所有门店总和,不按门店所属运营商过滤。 |
| | | } else { |
| | | wrapper.eq(TStore::getOperatorId, operatorId); |
| | | } |
| | | return storeService.list(wrapper); |
| | | } |
| | | |
| | | /** 空门店范围必须显式传递无匹配值,不能让下游 SQL 因空集合而省略 IN 条件。 */ |
| | | private List<Integer> listStatisticsStoreIds(Integer operatorId, boolean enabledOnly) { |
| | | List<Integer> storeIds = listStatisticsStores(operatorId, enabledOnly).stream() |
| | | .map(TStore::getId).collect(Collectors.toList()); |
| | | return storeIds.isEmpty() ? Collections.singletonList(-1) : storeIds; |
| | | } |
| | | |
| | | /** 获取统计范围门店发生课程、订场或赛事消费的用户。 */ |
| | | private List<Integer> listStatisticsAppUserIds(Integer operatorId) { |
| | | List<Integer> storeIds = listStatisticsStores(operatorId, true).stream() |
| | | .map(TStore::getId).collect(Collectors.toList()); |
| | | if (storeIds.isEmpty()) { |
| | | return Collections.singletonList(-1); |
| | | } |
| | | List<Integer> userIds = new ArrayList<>(); |
| | | List<Integer> courseUserIds = coursePackagePaymentClient.queryPaymentCoursePackage(storeIds); |
| | | if (courseUserIds != null) { |
| | | userIds.addAll(courseUserIds); |
| | | } |
| | | userIds.addAll(siteBookingService.list(new QueryWrapper<SiteBooking>() |
| | | .in("storeId", storeIds).eq("state", 1)) |
| | | .stream().map(SiteBooking::getAppUserId).filter(Objects::nonNull) |
| | | .collect(Collectors.toList())); |
| | | List<Integer> competitionUserIds = competitionClient.queryAppUserId(storeIds); |
| | | if (competitionUserIds != null) { |
| | | userIds.addAll(competitionUserIds); |
| | | } |
| | | List<Integer> validUserIds = userIds.stream().filter(Objects::nonNull).distinct() |
| | | .collect(Collectors.toList()); |
| | | return validUserIds.isEmpty() ? Collections.singletonList(-1) : validUserIds; |
| | | } |
| | | |
| | | private List<Integer> listStatisticsAppUserIdsForStore(Integer storeId) { |
| | | if (storeId == null) { |
| | | return Collections.singletonList(-1); |
| | | } |
| | | List<Integer> userIds = new ArrayList<>(); |
| | | List<Integer> courseUserIds = coursePackagePaymentClient.queryPaymentCoursePackage( |
| | | Collections.singletonList(storeId)); |
| | | if (courseUserIds != null) { |
| | | userIds.addAll(courseUserIds); |
| | | } |
| | | userIds.addAll(siteBookingService.list(new QueryWrapper<SiteBooking>() |
| | | .eq("storeId", storeId).eq("state", 1)) |
| | | .stream().map(SiteBooking::getAppUserId).filter(Objects::nonNull) |
| | | .collect(Collectors.toList())); |
| | | List<Integer> competitionUserIds = competitionClient.queryAppUserId( |
| | | Collections.singletonList(storeId)); |
| | | if (competitionUserIds != null) { |
| | | userIds.addAll(competitionUserIds); |
| | | } |
| | | List<Integer> validUserIds = userIds.stream().filter(Objects::nonNull).distinct() |
| | | .collect(Collectors.toList()); |
| | | return validUserIds.isEmpty() ? Collections.singletonList(-1) : validUserIds; |
| | | } |
| | | |
| | | /** |
| | | * 计算门店每日营业整小时数。相同的起止时间表示全天营业,结束时间早于 |
| | | * 开始时间时按跨午夜营业处理。 |
| | | */ |
| | | private long getDailyBusinessHours(String startTime, String endTime) { |
| | | if (ToolUtil.isEmpty(startTime) || ToolUtil.isEmpty(endTime)) { |
| | | return 0; |
| | | } |
| | | |
| | | try { |
| | | LocalTime start = LocalTime.parse(startTime); |
| | | LocalTime end = LocalTime.parse(endTime); |
| | | long minutes = Duration.between(start, end).toMinutes(); |
| | | if (minutes <= 0) { |
| | | minutes += Duration.ofDays(1).toMinutes(); |
| | | } |
| | | return Duration.ofMinutes(minutes).toHours(); |
| | | } catch (DateTimeException e) { |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | private long getStoreOperatingHours(TStore store, Date now) { |
| | | long operatingDays = Math.max(0, DateUtil.betweenDay(store.getCreateTime(), now, true)); |
| | | return operatingDays * getDailyBusinessHours(store.getStartTime(), store.getEndTime()); |
| | | } |
| | | |
| | | @Autowired |
| | | private ICityService cityService; |
| | | @Autowired |
| | | @Resource |
| | | private CityManagerClient cityManagerClient; |
| | | |
| | | @Autowired |
| | | private IUserService sysUserService; |
| | | @Autowired |
| | | @Resource |
| | | private AppUserClient appUserClient; |
| | | |
| | | @Autowired |
| | | @Resource |
| | | private CourseClient courseClient; |
| | | |
| | | @Autowired |
| | | private IStoreService storeService; |
| | | @Autowired |
| | | @Resource |
| | | private VipPaymentClient vipPaymentClient; |
| | | @Autowired |
| | | @Resource |
| | | private FinanceClient financeClient; |
| | | @Autowired |
| | | @Resource |
| | | private CoursePackagePaymentClient coursePackagePaymentClient; |
| | | @Autowired |
| | | @Resource |
| | | private CompetitionClient competitionClient; |
| | | |
| | | @Autowired |
| | | private ISiteBookingService siteBookingService; |
| | | @Autowired |
| | | @Resource |
| | | private StoreClient storeClient; |
| | | @Autowired |
| | | @Resource |
| | | private SiteClient siteClient; |
| | | @Autowired |
| | | @Resource |
| | | private PointMercharsClient pointMercharsClient; |
| | | @Autowired |
| | | @Resource |
| | | private CouponClient couponClient; |
| | | @Resource |
| | | private PayHuiminClient payHuiminClient; |
| | | @Resource |
| | | private RefundCoursePackageClient refundCoursePackageClient; |
| | | @Resource |
| | | private CourseStuddentClient courseStuddentClient; |
| | | @Autowired |
| | | @Resource |
| | | private CoursePackageClient coursePackageClient; |
| | | @Autowired |
| | | private TOperatorService operatorService; |
| | | @Resource |
| | | private BallClient ballClient; |
| | | /** |
| | | * 跳转到平台统计数据页面 |
| | | */ |
| | | @RequestMapping("/platform") |
| | | public String index(Model model) { |
| | | Object o = type1(null); |
| | | model.addAttribute("data",o); |
| | | |
| | | |
| | | |
| | | // type1 保留课程/门票/订场扇形图所需的图表明细;金额卡片再以营收接口覆盖, |
| | | // 避免图表数据丢失,也避免收入类型与净收入的统计口径不一致。 |
| | | Map<String, Object> typeData = (Map<String, Object>) type1(null); |
| | | Map<String, Object> incomeData = (Map<String, Object>) getIncomeData(null, null, null); |
| | | Map<Integer, BigDecimal> incomeTypeNet = (Map<Integer, BigDecimal>) incomeData.get("incomeTypeNet"); |
| | | typeData.put("fee1", incomeTypeNet.getOrDefault(1, BigDecimal.ZERO)); |
| | | typeData.put("fee2", incomeTypeNet.getOrDefault(2, BigDecimal.ZERO)); |
| | | typeData.put("fee3", incomeTypeNet.getOrDefault(3, BigDecimal.ZERO)); |
| | | typeData.put("fee4", incomeTypeNet.getOrDefault(4, BigDecimal.ZERO)); |
| | | typeData.put("fee5", incomeTypeNet.getOrDefault(5, BigDecimal.ZERO)); |
| | | typeData.put("fee7", incomeTypeNet.getOrDefault(6, BigDecimal.ZERO)); |
| | | model.addAttribute("data", typeData); |
| | | // 教学统计 |
| | | HashMap<String, Object> map = appUserClient.queryUserAge(); |
| | | model.addAttribute("stuData",map); |
| | | |
| | | |
| | | |
| | | return PREFIX + "platformIncome.html"; |
| | | } |
| | | |
| | |
| | | */ |
| | | @RequestMapping(value = "/getIncomeData") |
| | | @ResponseBody |
| | | public Object getIncomeData(Integer operatorId,Integer storeId) { |
| | | public Object getIncomeData(Integer operatorId,Integer storeId, String time) { |
| | | Integer roleType = UserExt.getUser().getObjectType(); |
| | | Integer objectId = UserExt.getUser().getObjectId(); |
| | | |
| | | // 同一接口由平台、运营商、门店三个统计页面复用: |
| | | // 平台角色不应因自身 objectId 被错误收窄为某个运营商;运营商和门店只能查看各自范围。 |
| | | if (Integer.valueOf(3).equals(roleType)) { |
| | | operatorId = null; |
| | | storeId = objectId; |
| | | } else if (Integer.valueOf(2).equals(roleType)) { |
| | | operatorId = objectId; |
| | | storeId = resolveStoreId(storeId); |
| | | } |
| | | |
| | | // 下游多处查询会在门店集合为空时忽略门店过滤。运营商没有任何门店时, |
| | | // 直接返回完整的零值结构,避免被误统计为全平台数据。 |
| | | if (operatorId != null && storeId == null |
| | | && storeService.count(new LambdaQueryWrapper<TStore>() |
| | | .eq(TStore::getOperatorId, operatorId) |
| | | .ne(TStore::getState, 3)) == 0) { |
| | | Map<String, Object> emptyIncomeData = buildIncomeStatistics(Collections.emptyList()); |
| | | emptyIncomeData.put("incomeTypeNet", buildIncomeTypeNet(Collections.emptyList(), null)); |
| | | Map<String, Object> emptyTicketIncome = new HashMap<>(); |
| | | emptyTicketIncome.put("day", BigDecimal.ZERO); |
| | | emptyTicketIncome.put("month", BigDecimal.ZERO); |
| | | emptyTicketIncome.put("quarter", BigDecimal.ZERO); |
| | | emptyTicketIncome.put("year", BigDecimal.ZERO); |
| | | emptyIncomeData.put("ticketIncome", emptyTicketIncome); |
| | | return emptyIncomeData; |
| | | } |
| | | |
| | | // 参数代表当前统计目标,而非当前登录人的角色;平台账号查看运营商/门店页时, |
| | | // 会员、充值也必须跟随被查看的运营商/门店归属。 |
| | | Integer statisticsScopeType = Integer.valueOf(3).equals(roleType) || storeId != null ? 3 |
| | | : (Integer.valueOf(2).equals(roleType) || operatorId != null ? 2 : 1); |
| | | Integer statisticsScopeObjectId = statisticsScopeType == 3 ? storeId |
| | | : (statisticsScopeType == 2 ? operatorId : null); |
| | | |
| | | // 积分商品收入接口按门店 ID 过滤;空集合会被其 SQL 视为“不过滤”, |
| | | // 因此运营商统计必须传入该运营商名下的全部门店,不能传空集合。 |
| | | List<Integer> cityManagerId = new ArrayList<>(); |
| | | if (Integer.valueOf(2).equals(statisticsScopeType) && statisticsScopeObjectId != null) { |
| | | cityManagerId = storeService.list(new QueryWrapper<TStore>() |
| | | .eq("operatorId", statisticsScopeObjectId).ne("state", 3)) |
| | | .stream().map(TStore::getId).collect(Collectors.toList()); |
| | | } else if (Integer.valueOf(3).equals(statisticsScopeType) && statisticsScopeObjectId != null) { |
| | | cityManagerId.add(statisticsScopeObjectId); |
| | | } |
| | | // 报名课程查询query |
| | | RegisterOrderQuery query = new RegisterOrderQuery(); |
| | | // 充值记录查询query |
| | | // 充值记录查询query |
| | | RechargeRecordsQuery rechargeRecordsQuery = new RechargeRecordsQuery(); |
| | | // 赛事活动查询query |
| | | CompetitionQuery competitionQuery = new CompetitionQuery(); |
| | | |
| | | competitionQuery.setIncludeRefund(true); |
| | | // 会员支付查询query |
| | | IncomeQuery incomeQuery = new IncomeQuery(); |
| | | incomeQuery.setIncludeRefund(true); |
| | | // 场地预约记录查询query |
| | | SiteBookingQuery siteBookingQuery = new SiteBookingQuery(); |
| | | siteBookingQuery.setIncludeRefund(true); |
| | | // 智慧球场查询query |
| | | GameDataQuery gameDataQuery = new GameDataQuery(); |
| | | // 筛选运营商的是时候使用 |
| | | List<Integer> storeIds = new ArrayList<>(); |
| | | // 根据运营商ID 查询运营商下的所有门店 |
| | | if (storeId==null){ |
| | | if (operatorId!=null){ |
| | | List<TStore> stores = storeService.list(new QueryWrapper<TStore>().eq("operatorId", operatorId)); |
| | | List<TStore> stores = listStatisticsStores(operatorId, false); |
| | | // 拿到该运营商下的门店id集合 |
| | | storeIds = stores.stream().map(TStore::getId).collect(Collectors.toList()); |
| | | query.setStoresIds(storeIds); |
| | |
| | | } |
| | | }else { |
| | | List<Integer> list = new ArrayList<>(); |
| | | |
| | | |
| | | list.add(storeId); |
| | | |
| | | |
| | | query.setStoresIds(list); |
| | | siteBookingQuery.setStoreIds(list); |
| | | competitionQuery.setStoreId(storeId); |
| | | } |
| | | |
| | | |
| | | Integer roleType = UserExt.getUser().getObjectType(); |
| | | rechargeRecordsQuery.setInsertType(roleType); |
| | | query.setInsertType(roleType); |
| | | competitionQuery.setInsertType(roleType); |
| | | incomeQuery.setInsertType(roleType); |
| | | // 会员、充值按当前统计目标的用户创建来源归属。平台全量统计仅按 insertType=1, |
| | | // 不能叠加当前平台账号的 addUserId 条件。 |
| | | rechargeRecordsQuery.setInsertType(statisticsScopeType); |
| | | query.setInsertType(statisticsScopeType); |
| | | competitionQuery.setInsertType(statisticsScopeType); |
| | | incomeQuery.setInsertType(statisticsScopeType); |
| | | rechargeRecordsQuery.setTime(time); |
| | | query.setRegisterTime(time); |
| | | competitionQuery.setTime(time); |
| | | incomeQuery.setTime(time); |
| | | siteBookingQuery.setTime(time); |
| | | if (!Integer.valueOf(1).equals(statisticsScopeType)) { |
| | | rechargeRecordsQuery.setObjectId(statisticsScopeObjectId); |
| | | } |
| | | List<IncomeVO> incomeVOS = new ArrayList<>(); |
| | | Set<Long> usedCouponIds = new HashSet<>(); |
| | | // 会员支付记录 |
| | | List<VipPayment> vipPayments = vipPaymentClient.registrationList(incomeQuery); |
| | | for (VipPayment vipPayment : vipPayments) { |
| | | if (vipPayment.getPayStatus() == 3 && vipPayment.getAmount() != null) { |
| | | IncomeVO payment = new IncomeVO(); |
| | | payment.setIncomeType(1); |
| | | payment.setInsertTime(vipPayment.getPayTime() == null ? vipPayment.getInsertTime() : vipPayment.getPayTime()); |
| | | payment.setAmount(BigDecimal.valueOf(vipPayment.getAmount())); |
| | | incomeVOS.add(payment); |
| | | IncomeVO refund = new IncomeVO(); |
| | | refund.setIncomeType(1); |
| | | refund.setInsertTime(vipPayment.getRefundTime() == null ? vipPayment.getInsertTime() : vipPayment.getRefundTime()); |
| | | refund.setRefundAmount(BigDecimal.valueOf(vipPayment.getAmount())); |
| | | incomeVOS.add(refund); |
| | | continue; |
| | | } |
| | | IncomeVO temp = new IncomeVO(); |
| | | if (vipPayment.getPayStatus()==1){ |
| | | temp.setInsertTime(vipPayment.getInsertTime()); |
| | | temp.setIncomeType(1); |
| | | if (vipPayment.getState()!=3){ |
| | | temp.setInsertTime(vipPayment.getPayTime()); |
| | | incomeVOS.add(temp); |
| | | } |
| | | if (vipPayment.getAmount() != null) { |
| | |
| | | List<RechargeRecordsVO> rechargeRecordsVOS = financeClient.rechargeList(rechargeRecordsQuery); |
| | | for (RechargeRecordsVO rechargeRecordsVO : rechargeRecordsVOS) { |
| | | IncomeVO temp = new IncomeVO(); |
| | | temp.setInsertTime(rechargeRecordsVO.getInsertTime()); |
| | | temp.setIncomeType(2); |
| | | temp.setInsertTime(rechargeRecordsVO.getPayTime()); |
| | | if (rechargeRecordsVO.getAmount() != null) { |
| | | temp.setAmount(rechargeRecordsVO.getAmount()); |
| | | } |
| | | if (rechargeRecordsVO.getPayStatus() ==1){ |
| | | if (rechargeRecordsVO.getState() !=3){ |
| | | incomeVOS.add(temp); |
| | | } |
| | | |
| | | } |
| | | // 报名课程记录 |
| | | List<RegisterOrderVO> registerOrderVOS = coursePackagePaymentClient.listAllRegister(query); |
| | |
| | | continue; |
| | | } |
| | | IncomeVO temp = new IncomeVO(); |
| | | temp.setIncomeType(3); |
| | | temp.setInsertTime(registerOrderVO.getInsertTime()); |
| | | if (registerOrderVO.getMoney() != null) { |
| | | temp.setAmount(registerOrderVO.getMoney()); |
| | | } |
| | | if (registerOrderVO.getPayStatus()==2){ |
| | | if (registerOrderVO.getUserCouponId() != null) { |
| | | usedCouponIds.add(registerOrderVO.getUserCouponId()); |
| | | temp.setId(registerOrderVO.getUserCouponId().toString()); |
| | | } |
| | | incomeVOS.add(temp); |
| | | } |
| | | } |
| | | // query权限设置 获取运营商下的门店集合 |
| | | if (roleType==2){ |
| | | competitionQuery.setOperatorId(UserExt.getUser().getObjectId()); |
| | | } |
| | | // 报名活动 |
| | | List<PaymentCompetition> competitions = competitionClient.listAllPayment(competitionQuery); |
| | | for (PaymentCompetition competition : competitions) { |
| | | if (competition.getPayStatus() != 2) { |
| | | continue; |
| | | } |
| | | if (competition.getPayType()==3 || competition.getPayType()==4){ |
| | | continue; |
| | | } |
| | | if (competition.getState()==3) { |
| | | continue; |
| | | } |
| | | if (competition.getPayStatus() == 3 && competition.getAmount() != null) { |
| | | IncomeVO payment = new IncomeVO(); |
| | | payment.setIncomeType(4); |
| | | payment.setInsertTime(competition.getPayTime() == null |
| | | ? competition.getInsertTime() : competition.getPayTime()); |
| | | payment.setAmount(BigDecimal.valueOf(competition.getAmount())); |
| | | incomeVOS.add(payment); |
| | | IncomeVO refund = new IncomeVO(); |
| | | refund.setIncomeType(4); |
| | | refund.setInsertTime(competition.getRefundTime() == null |
| | | ? competition.getInsertTime() : competition.getRefundTime()); |
| | | refund.setRefundAmount(BigDecimal.valueOf(competition.getAmount())); |
| | | incomeVOS.add(refund); |
| | | continue; |
| | | } |
| | | if (competition.getPayStatus() != 2) { |
| | | continue; |
| | | } |
| | | IncomeVO temp = new IncomeVO(); |
| | | temp.setInsertTime(competition.getInsertTime()); |
| | | temp.setIncomeType(4); |
| | | temp.setInsertTime(competition.getPayTime()); |
| | | if (competition.getAmount() != null) { |
| | | temp.setAmount(new BigDecimal(competition.getAmount().toString())); |
| | | } |
| | |
| | | List<SiteBooking> siteBookings = siteClient.listAll(siteBookingQuery); |
| | | for (SiteBooking siteBooking : siteBookings) { |
| | | IncomeVO temp = new IncomeVO(); |
| | | if(siteBooking.getStatus()!=3){ |
| | | temp.setIncomeType(5); |
| | | if (siteBooking.getStatus() == 5) { |
| | | if (siteBooking.getPayMoney() != null) { |
| | | IncomeVO payment = new IncomeVO(); |
| | | payment.setIncomeType(5); |
| | | payment.setInsertTime(siteBooking.getPayTime() == null |
| | | ? siteBooking.getInsertTime() : siteBooking.getPayTime()); |
| | | payment.setAmount(BigDecimal.valueOf(siteBooking.getPayMoney())); |
| | | incomeVOS.add(payment); |
| | | IncomeVO refund = new IncomeVO(); |
| | | refund.setIncomeType(5); |
| | | refund.setInsertTime(siteBooking.getCancelTime() == null |
| | | ? siteBooking.getInsertTime() : siteBooking.getCancelTime()); |
| | | refund.setRefundAmount(BigDecimal.valueOf(siteBooking.getPayMoney())); |
| | | incomeVOS.add(refund); |
| | | } |
| | | continue; |
| | | } |
| | | if (siteBooking.getStatus() == 0) { |
| | | continue; |
| | | } |
| | | if (siteBooking.getPayType() ==3 || siteBooking.getPayType() ==4)continue; |
| | | temp.setInsertTime(siteBooking.getPayTime()); |
| | | if (siteBooking.getPayMoney() != null) { |
| | | temp.setAmount(new BigDecimal(siteBooking.getPayMoney().toString())); |
| | | } |
| | | if (siteBooking.getUserCouponId() != null) { |
| | | usedCouponIds.add(siteBooking.getUserCouponId()); |
| | | temp.setId(siteBooking.getUserCouponId().toString()); |
| | | } |
| | | incomeVOS.add(temp); |
| | | } |
| | | } |
| | | |
| | | // 惠民卡和优惠券购买不归属到单一课程/场地门店,当前仅在平台或运营商汇总中计入。 |
| | | if (storeId == null) { |
| | | appendHuiminIncome(incomeVOS, operatorId, usedCouponIds); |
| | | if (operatorId == null) { |
| | | appendCouponPurchaseIncome(incomeVOS); |
| | | } |
| | | } |
| | | |
| | | // 积分商品 |
| | | List<PointMerchandiseIncomeVo> amount = pointMercharsClient.getAmount(); |
| | | List<PointMerchandiseIncomeVo> amount = pointMercharsClient.getAmount(cityManagerId); |
| | | for (PointMerchandiseIncomeVo pointMerchandiseIncomeVo : amount) { |
| | | IncomeVO temp = new IncomeVO(); |
| | | temp.setIncomeType(6); |
| | | if (pointMerchandiseIncomeVo==null) continue; |
| | | temp.setInsertTime(pointMerchandiseIncomeVo.getInsertTime()); |
| | | if (pointMerchandiseIncomeVo.getCash()!=null){ |
| | | temp.setAmount(pointMerchandiseIncomeVo.getCash()); |
| | | if (pointMerchandiseIncomeVo.getUserCouponId() != null) { |
| | | usedCouponIds.add(pointMerchandiseIncomeVo.getUserCouponId()); |
| | | temp.setId(pointMerchandiseIncomeVo.getUserCouponId().toString()); |
| | | } |
| | | incomeVOS.add(temp); |
| | | } |
| | | } |
| | | // 最终返回的数据 |
| | | Map<String, List<Object>> monthlyData = new HashMap<>(); |
| | | // 创建一个 Map 用于存储每年的累计 amount |
| | | Map<Integer, BigDecimal> yearToTotalAmountMap = new HashMap<>(); |
| | | // 初始化一个 BigDecimal 用于累加 |
| | | BigDecimal totalAmount1 = BigDecimal.ZERO; |
| | | // 用于返回图表上的总营收 年度营收 月度 周度 日度 |
| | | List<Object> objects = new ArrayList<>(); |
| | | // 遍历 incomeVOS |
| | | for (IncomeVO incomeVO1 : incomeVOS) { |
| | | // 总营收 |
| | | BigDecimal total = incomeVO1.getAmount(); |
| | | // 累加到总金额 |
| | | totalAmount1 = totalAmount1.add(total); |
| | | |
| | | Date insertTime = incomeVO1.getInsertTime(); |
| | | BigDecimal amount1 = incomeVO1.getAmount(); |
| | | Calendar calendar = Calendar.getInstance(); |
| | | calendar.setTime(insertTime); |
| | | int year = calendar.get(Calendar.YEAR); // 获取年份 |
| | | // 更新年份对应的累计 amount |
| | | if (yearToTotalAmountMap.containsKey(year)) { |
| | | BigDecimal totalAmount = yearToTotalAmountMap.get(year); |
| | | yearToTotalAmountMap.put(year, totalAmount.add(amount1)); |
| | | } else { |
| | | yearToTotalAmountMap.put(year, amount1); |
| | | Map<Long, BigDecimal> couponDeductionAmounts = getCouponDeductionAmounts(usedCouponIds); |
| | | applyCouponDeductions(incomeVOS, couponDeductionAmounts); |
| | | // 平台智慧球场 |
| | | if (storeId==null&&operatorId==null){ |
| | | gameDataQuery.setObjectId(0); |
| | | List<TGameRecord> data = ballClient.getData(gameDataQuery); |
| | | for (TGameRecord datum : data) { |
| | | IncomeVO temp = new IncomeVO(); |
| | | temp.setIncomeType(5); |
| | | temp.setAmount(datum.getMoney()); |
| | | temp.setInsertTime(datum.getTime()); |
| | | incomeVOS.add(temp); |
| | | } |
| | | } |
| | | objects.add(totalAmount1); |
| | | // 创建一个新的列表,按年份升序排列 |
| | | List<Integer> sortedYears = new ArrayList<>(yearToTotalAmountMap.keySet()); |
| | | Collections.sort(sortedYears); |
| | | // 创建一个新的 IncomeVO 列表,包含按年份累计的 amount |
| | | List<Object> resultIncomeVOS = new ArrayList<>(); |
| | | // 当前年往前推十年 |
| | | List<Integer> integers1 = new ArrayList<>(); |
| | | int years = DateUtil.year(new Date()); |
| | | for (int i = 0; i < 10; i++) { |
| | | integers1.add(years-i); |
| | | } |
| | | List<Object> collect = integers1.stream().sorted().collect(Collectors.toList()); |
| | | List<Object> objects1 = new ArrayList<>(); |
| | | for (Object o : collect) { |
| | | BigDecimal orDefault = yearToTotalAmountMap.getOrDefault(Integer.valueOf(o.toString()), BigDecimal.ZERO); |
| | | objects1.add(orDefault); |
| | | } |
| | | monthlyData.put("yearIncome",objects1); |
| | | BigDecimal yearIn = new BigDecimal("0.00"); |
| | | for (Object o : objects1) { |
| | | yearIn = yearIn.add(new BigDecimal(o.toString())); |
| | | } |
| | | BigDecimal orDefault = yearToTotalAmountMap.getOrDefault(years, BigDecimal.ZERO); |
| | | objects.add(orDefault); |
| | | // 创建一个 Map 用于存储今年每个月的累计 amount |
| | | Map<Integer, BigDecimal> monthToTotalAmountMap = new HashMap<>(); |
| | | Calendar calendar = Calendar.getInstance(); |
| | | int currentYear = calendar.get(Calendar.YEAR); |
| | | List<BigDecimal> monthlyAmountList = new ArrayList<>(Collections.nCopies(12, BigDecimal.ZERO)); |
| | | |
| | | for (IncomeVO incomeVO1 : incomeVOS) { |
| | | Calendar calendar1 = Calendar.getInstance(); |
| | | calendar1.setTime(incomeVO1.getInsertTime()); |
| | | int year = calendar1.get(Calendar.YEAR); |
| | | int month = calendar1.get(Calendar.MONTH) + 1; // 月份从0开始,所以需要加1 |
| | | if (year == currentYear) { |
| | | BigDecimal totalAmount = monthlyAmountList.get(month - 1); |
| | | totalAmount = totalAmount.add(incomeVO1.getAmount()); |
| | | monthlyAmountList.set(month - 1, totalAmount); |
| | | // 运营商 |
| | | if (operatorId!=null && storeId==null){ |
| | | gameDataQuery.setObjectId(operatorId); |
| | | List<TGameRecord> data = ballClient.getData(gameDataQuery); |
| | | for (TGameRecord datum : data) { |
| | | IncomeVO temp = new IncomeVO(); |
| | | temp.setIncomeType(5); |
| | | temp.setAmount(datum.getMoney()); |
| | | temp.setInsertTime(datum.getTime()); |
| | | incomeVOS.add(temp); |
| | | } |
| | | } |
| | | monthlyData.put("monthIncome", Collections.singletonList(monthlyAmountList)); |
| | | //yearMount |
| | | BigDecimal monthI = new BigDecimal("0.00"); |
| | | for (BigDecimal bigDecimal : monthlyAmountList) { |
| | | monthI = monthI.add(bigDecimal); |
| | | } |
| | | objects.add(monthI); |
| | | // 获取当前月份 |
| | | LocalDate currentDate = LocalDate.now(); |
| | | int currentMonth = currentDate.getMonthValue(); |
| | | // 初始化一个长度为当前月份的天数的列表,并将每一天的金额初始化为零 |
| | | int daysInCurrentMonth = currentDate.lengthOfMonth(); |
| | | List<BigDecimal> weekAmount = new ArrayList<>(); |
| | | |
| | | // 获取最近四周 |
| | | LocalDateTime minNow = LocalDateTime.now().with(LocalTime.MIN); |
| | | LocalDateTime maxNow = LocalDateTime.now().with(LocalTime.MAX); |
| | | // 周度数据 |
| | | LocalDateTime week1Start = minNow.minusDays(6); |
| | | LocalDateTime week1End = maxNow; |
| | | |
| | | LocalDateTime week2Start = minNow.minusDays(13); |
| | | LocalDateTime week2End = minNow.minusDays(7); |
| | | |
| | | LocalDateTime week3Start = minNow.minusDays(20); |
| | | LocalDateTime week3End = minNow.minusDays(14); |
| | | |
| | | LocalDateTime week4Start = minNow.minusDays(27); |
| | | LocalDateTime week4End = minNow.minusDays(21); |
| | | |
| | | // 计算每个周的amount总和 |
| | | BigDecimal tAmount1 = BigDecimal.ZERO; |
| | | BigDecimal tAmount2 = BigDecimal.ZERO; |
| | | BigDecimal tAmount3 = BigDecimal.ZERO; |
| | | BigDecimal tAmount4 = BigDecimal.ZERO; |
| | | for (IncomeVO incomeVO1 : incomeVOS) { |
| | | Date insertTime = incomeVO1.getInsertTime(); |
| | | // 将Date转换为LocalDateTime |
| | | Instant instant = insertTime.toInstant(); |
| | | ZoneId zoneId = ZoneId.systemDefault(); |
| | | LocalDateTime dateTime = instant.atZone(zoneId).toLocalDateTime(); |
| | | // 判断该数据属于哪个周 |
| | | if (dateTime.isAfter(week1Start) && dateTime.isBefore(week1End)) { |
| | | BigDecimal amount1 = incomeVO1.getAmount(); |
| | | tAmount1=tAmount1.add(amount1); |
| | | } else if (dateTime.isAfter(week2Start) && dateTime.isBefore(week2End)) { |
| | | BigDecimal amount1 = incomeVO1.getAmount(); |
| | | tAmount2=tAmount2.add(amount1); |
| | | } else if (dateTime.isAfter(week3Start) && dateTime.isBefore(week3End)) { |
| | | BigDecimal amount1 = incomeVO1.getAmount(); |
| | | tAmount4=tAmount3.add(amount1); |
| | | } else if (dateTime.isAfter(week4Start) && dateTime.isBefore(week4End)) { |
| | | BigDecimal amount1 = incomeVO1.getAmount(); |
| | | tAmount4=tAmount4.add(amount1); |
| | | // 门店 |
| | | if (storeId!=null){ |
| | | gameDataQuery.setStoreId(storeId); |
| | | List<TGameRecord> data = ballClient.getData(gameDataQuery); |
| | | for (TGameRecord datum : data) { |
| | | IncomeVO temp = new IncomeVO(); |
| | | temp.setIncomeType(5); |
| | | temp.setAmount(datum.getMoney()); |
| | | temp.setInsertTime(datum.getTime()); |
| | | incomeVOS.add(temp); |
| | | } |
| | | } |
| | | weekAmount.add(tAmount1); |
| | | weekAmount.add(tAmount2); |
| | | weekAmount.add(tAmount3); |
| | | weekAmount.add(tAmount4); |
| | | monthlyData.put("weekIncome", Collections.singletonList(weekAmount)); |
| | | BigDecimal weekIn = new BigDecimal("0.00"); |
| | | for (BigDecimal bigDecimal : weekAmount) { |
| | | weekIn = weekIn.add(bigDecimal); |
| | | // 部分跨服务查询不支持日期参数,统一在收入明细层按支付/退款时间过滤, |
| | | // 确保总营收、净收入和收入类型统计使用完全相同的数据集。 |
| | | List<IncomeVO> statisticsIncomeVOS = filterIncomeRecordsByTime(incomeVOS, time); |
| | | Map<String, Object> monthlyData = buildIncomeStatistics(statisticsIncomeVOS); |
| | | monthlyData.put("incomeTypeNet", buildIncomeTypeNet(statisticsIncomeVOS, null)); |
| | | // 门票饼图需要日/月/季/年卡拆分;此前该数据只在 type1 内部返回, |
| | | // 现随统一营收接口返回,供平台页直接使用。 |
| | | monthlyData.put("ticketIncome", getTicketIncome(time, operatorId, storeId)); |
| | | // 平台收入类型饼图还需要课程、订场分类明细。此前页面只能读取 type1 |
| | | // 的模板数据,筛选后 getIncomeData 缺少该字段,导致课程图显示为空。 |
| | | if (operatorId == null && storeId == null) { |
| | | Map<String, Object> platformTypeData = (Map<String, Object>) type1(time); |
| | | monthlyData.put("courseData", platformTypeData.get("courseData")); |
| | | monthlyData.put("siteData", platformTypeData.get("siteData")); |
| | | } |
| | | objects.add(weekIn); |
| | | LocalDateTime currentDateTime = LocalDateTime.now(); |
| | | List<BigDecimal> amountByDay = new ArrayList<>(Collections.nCopies(7, BigDecimal.ZERO)); |
| | | for (IncomeVO incomeVO3 : incomeVOS) { |
| | | Date insertTime = incomeVO3.getInsertTime(); |
| | | // 将 Date 转换为 LocalDateTime |
| | | LocalDateTime insertDateTime = LocalDateTime.ofInstant(insertTime.toInstant(), ZoneId.systemDefault()); |
| | | // 计算日期与当前日期的差距 |
| | | long daysDifference = ChronoUnit.DAYS.between(insertDateTime.toLocalDate(), currentDateTime.toLocalDate()); |
| | | // 如果日期在七天内,累加金额 |
| | | if (daysDifference >= 0 && daysDifference < 7) { |
| | | int index = (int) (6 - daysDifference); // 计算对应的索引位置 |
| | | BigDecimal amount3 = incomeVO3.getAmount(); |
| | | BigDecimal updatedAmount = amountByDay.get(index).add(amount3); |
| | | amountByDay.set(index, updatedAmount); |
| | | |
| | | } |
| | | } |
| | | monthlyData.put("dayIncome", Collections.singletonList(amountByDay)); |
| | | BigDecimal totalToday = new BigDecimal("0.00"); |
| | | for (BigDecimal bigDecimal : amountByDay) { |
| | | totalToday = totalToday.add(bigDecimal); |
| | | } |
| | | objects.add(totalToday); |
| | | // 最后put |
| | | monthlyData.put("yearMount",objects); |
| | | |
| | | ArrayList<Object> integers = new ArrayList<>(); |
| | | int year = DateUtil.year(new Date()); |
| | | for (int i = 0; i < 10; i++) { |
| | | integers.add(year-i); |
| | | } |
| | | List<Object> collect1 = integers.stream().sorted().collect(Collectors.toList()); |
| | | monthlyData.put("year",collect1); |
| | | return monthlyData; |
| | | } |
| | | |
| | | private Map<String, Object> getTicketIncome(String time, Integer operatorId, Integer storeId) { |
| | | List<Integer> userIds; |
| | | if (storeId != null) { |
| | | userIds = listStatisticsAppUserIdsForStore(storeId); |
| | | } else if (operatorId != null) { |
| | | userIds = listStatisticsAppUserIds(operatorId); |
| | | } else { |
| | | userIds = listStatisticsAppUserIds(null); |
| | | } |
| | | if (userIds == null) { |
| | | userIds = new ArrayList<>(); |
| | | } |
| | | // 活动服务对空集合会补充 -1,传入可变副本以兼容该历史实现。 |
| | | return pointMercharsClient.queryFee(new QueryDataFee(time, new ArrayList<>(userIds))); |
| | | } |
| | | |
| | | /** 惠民卡采用支付、退款两条事实流水,赠送卡不计营收。 */ |
| | | private void appendHuiminIncome(List<IncomeVO> incomeRecords, Integer operatorId, Set<Long> usedCouponIds) { |
| | | HuiminPayQuery query = new HuiminPayQuery(); |
| | | query.setGiftPaymentType(3); |
| | | if (operatorId != null) { |
| | | query.setOperatorId(operatorId.longValue()); |
| | | } |
| | | List<SalesDetailVO> records = payHuiminClient.exportData(query); |
| | | if (records == null) { |
| | | return; |
| | | } |
| | | for (SalesDetailVO record : records) { |
| | | if (record == null || record.getSalesMoney() == null || record.getPaymentTime() == null) { |
| | | continue; |
| | | } |
| | | IncomeVO payment = new IncomeVO(); |
| | | payment.setIncomeType(6); |
| | | payment.setInsertTime(record.getPaymentTime()); |
| | | payment.setAmount(record.getSalesMoney()); |
| | | if (record.getUserCouponId() != null) { |
| | | usedCouponIds.add(record.getUserCouponId()); |
| | | payment.setId(record.getUserCouponId().toString()); |
| | | } |
| | | incomeRecords.add(payment); |
| | | if (Integer.valueOf(3).equals(record.getStatus()) |
| | | || Integer.valueOf(2).equals(record.getRefundStatus()) |
| | | || Integer.valueOf(3).equals(record.getRefundStatus())) { |
| | | IncomeVO refund = new IncomeVO(); |
| | | refund.setIncomeType(6); |
| | | refund.setInsertTime(record.getRefundTime() == null ? record.getPaymentTime() : record.getRefundTime()); |
| | | refund.setRefundAmount(record.getSalesMoney()); |
| | | incomeRecords.add(refund); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** 仅计入积分+现金的成功优惠券购买,纯积分兑换不形成现金营收。 */ |
| | | private void appendCouponPurchaseIncome(List<IncomeVO> incomeRecords) { |
| | | List<UserCouponPayment> records = couponClient.listPaidCouponPayments(); |
| | | if (records == null) { |
| | | return; |
| | | } |
| | | for (UserCouponPayment record : records) { |
| | | if (record == null || record.getCash() == null || record.getPaymentTime() == null) { |
| | | continue; |
| | | } |
| | | IncomeVO payment = new IncomeVO(); |
| | | payment.setIncomeType(6); |
| | | payment.setInsertTime(record.getPaymentTime()); |
| | | payment.setAmount(BigDecimal.valueOf(record.getCash())); |
| | | incomeRecords.add(payment); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 收入类型统计与净收入共用同一份收入明细。 |
| | | * 类型 1-5 对应会员、充值、课程、赛事、订场;6 为商品及其他平台收入。 |
| | | */ |
| | | private Map<Integer, BigDecimal> buildIncomeTypeNet(List<IncomeVO> incomeRecords, String time) { |
| | | Map<Integer, BigDecimal> result = new HashMap<>(); |
| | | for (int type = 1; type <= 6; type++) { |
| | | result.put(type, BigDecimal.ZERO); |
| | | } |
| | | Date startTime = null; |
| | | Date endTime = null; |
| | | if (ToolUtil.isNotEmpty(time)) { |
| | | try { |
| | | startTime = DateUtil.parse(time.split(" - ")[0] + " 00:00:00"); |
| | | endTime = DateUtil.parse(time.split(" - ")[1] + " 23:59:59"); |
| | | } catch (Exception ignored) { |
| | | // 页面日期格式异常时与原接口一致,不额外按日期过滤。 |
| | | } |
| | | } |
| | | for (IncomeVO record : incomeRecords) { |
| | | if (record.getIncomeType() == null || record.getInsertTime() == null) { |
| | | continue; |
| | | } |
| | | if (startTime != null && (record.getInsertTime().before(startTime) |
| | | || record.getInsertTime().after(endTime))) { |
| | | continue; |
| | | } |
| | | BigDecimal netAmount = getZeroIfNull(record.getAmount()) |
| | | .subtract(getZeroIfNull(record.getRefundAmount())); |
| | | result.put(record.getIncomeType(), result.getOrDefault(record.getIncomeType(), BigDecimal.ZERO) |
| | | .add(netAmount)); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | private List<IncomeVO> filterIncomeRecordsByTime(List<IncomeVO> incomeRecords, String time) { |
| | | if (ToolUtil.isEmpty(time)) { |
| | | return incomeRecords; |
| | | } |
| | | try { |
| | | Date startTime = DateUtil.parse(time.split(" - ")[0] + " 00:00:00"); |
| | | Date endTime = DateUtil.parse(time.split(" - ")[1] + " 23:59:59"); |
| | | return incomeRecords.stream() |
| | | .filter(record -> record.getInsertTime() != null |
| | | && !record.getInsertTime().before(startTime) |
| | | && !record.getInsertTime().after(endTime)) |
| | | .collect(Collectors.toList()); |
| | | } catch (Exception ignored) { |
| | | // 兼容旧页面的日期格式:解析失败时保留原有全量统计行为。 |
| | | return incomeRecords; |
| | | } |
| | | } |
| | | |
| | | /** 构建总计及年、月、周、日四个粒度的四维收入统计结果。 */ |
| | | private Map<String, Object> buildIncomeStatistics(List<IncomeVO> incomeRecords) { |
| | | Map<String, Object> result = new HashMap<>(); |
| | | LocalDate today = LocalDate.now(); |
| | | int currentYear = today.getYear(); |
| | | List<IncomeStatisticsVO> yearly = new ArrayList<>(); |
| | | List<Object> years = new ArrayList<>(); |
| | | List<String> yearLabels = new ArrayList<>(); |
| | | for (int year = currentYear - 9; year <= currentYear; year++) { |
| | | final int statisticYear = year; |
| | | yearly.add(sumIncomeStatistics(incomeRecords, record -> getRecordDate(record) |
| | | .getYear() == statisticYear)); |
| | | years.add(year); |
| | | yearLabels.add(String.valueOf(year)); |
| | | } |
| | | |
| | | List<IncomeStatisticsVO> monthly = new ArrayList<>(); |
| | | List<String> monthLabels = new ArrayList<>(); |
| | | for (int month = 1; month <= 12; month++) { |
| | | final int statisticMonth = month; |
| | | monthly.add(sumIncomeStatistics(incomeRecords, record -> { |
| | | LocalDate date = getRecordDate(record); |
| | | return date.getYear() == currentYear && date.getMonthValue() == statisticMonth; |
| | | })); |
| | | monthLabels.add(String.format("%d-%02d", currentYear, month)); |
| | | } |
| | | |
| | | List<IncomeStatisticsVO> weekly = new ArrayList<>(); |
| | | List<String> weekLabels = new ArrayList<>(); |
| | | for (int weekIndex = 3; weekIndex >= 0; weekIndex--) { |
| | | LocalDate startDate = today.minusDays(weekIndex * 7L + 6L); |
| | | LocalDate endDate = today.minusDays(weekIndex * 7L); |
| | | weekly.add(sumIncomeStatistics(incomeRecords, record -> { |
| | | LocalDate date = getRecordDate(record); |
| | | return !date.isBefore(startDate) && !date.isAfter(endDate); |
| | | })); |
| | | weekLabels.add(startDate.format(DateTimeFormatter.ISO_LOCAL_DATE) |
| | | + " 至 " + endDate.format(DateTimeFormatter.ISO_LOCAL_DATE)); |
| | | } |
| | | |
| | | List<IncomeStatisticsVO> daily = new ArrayList<>(); |
| | | List<String> dayLabels = new ArrayList<>(); |
| | | for (int dayIndex = 6; dayIndex >= 0; dayIndex--) { |
| | | LocalDate statisticDate = today.minusDays(dayIndex); |
| | | daily.add(sumIncomeStatistics(incomeRecords, record -> getRecordDate(record) |
| | | .equals(statisticDate))); |
| | | dayLabels.add(statisticDate.format(DateTimeFormatter.ISO_LOCAL_DATE)); |
| | | } |
| | | |
| | | IncomeStatisticsVO total = sumIncomeStatistics(incomeRecords, record -> true); |
| | | IncomeStatisticsVO currentYearStatistics = yearly.get(yearly.size() - 1); |
| | | IncomeStatisticsVO currentMonthStatistics = monthly.get(today.getMonthValue() - 1); |
| | | IncomeStatisticsVO currentWeekStatistics = sumIncomeStatistics(incomeRecords, record -> { |
| | | LocalDate date = getRecordDate(record); |
| | | return !date.isBefore(today.minusDays(6)) && !date.isAfter(today); |
| | | }); |
| | | IncomeStatisticsVO currentDayStatistics = daily.get(daily.size() - 1); |
| | | |
| | | result.put("incomeStatistics", total); |
| | | result.put("netIncomeAmount", total.getNetIncomeAmount()); |
| | | result.put("couponDeductionAmount", total.getCouponDeductionAmount()); |
| | | result.put("refundAmount", total.getRefundAmount()); |
| | | result.put("yearIncomeStatistics", yearly); |
| | | result.put("monthIncomeStatistics", monthly); |
| | | result.put("weekIncomeStatistics", weekly); |
| | | result.put("dayIncomeStatistics", daily); |
| | | result.put("year", years); |
| | | result.put("yearLabels", yearLabels); |
| | | result.put("monthLabels", monthLabels); |
| | | result.put("weekLabels", weekLabels); |
| | | result.put("dayLabels", dayLabels); |
| | | // 兼容既有图表消费字段,值调整为总营收金额。 |
| | | result.put("yearIncome", yearly.stream().map(IncomeStatisticsVO::getTotalIncomeAmount) |
| | | .collect(Collectors.toList())); |
| | | result.put("monthIncome", Collections.singletonList(monthly.stream() |
| | | .map(IncomeStatisticsVO::getTotalIncomeAmount).collect(Collectors.toList()))); |
| | | result.put("weekIncome", Collections.singletonList(weekly.stream() |
| | | .map(IncomeStatisticsVO::getTotalIncomeAmount).collect(Collectors.toList()))); |
| | | result.put("dayIncome", Collections.singletonList(daily.stream() |
| | | .map(IncomeStatisticsVO::getTotalIncomeAmount).collect(Collectors.toList()))); |
| | | result.put("yearMount", Arrays.asList(total.getTotalIncomeAmount(), |
| | | currentYearStatistics.getTotalIncomeAmount(), currentMonthStatistics.getTotalIncomeAmount(), |
| | | currentWeekStatistics.getTotalIncomeAmount(), currentDayStatistics.getTotalIncomeAmount())); |
| | | return result; |
| | | } |
| | | |
| | | /** 按给定时间条件汇总四个收入维度。 */ |
| | | private IncomeStatisticsVO sumIncomeStatistics(List<IncomeVO> incomeRecords, |
| | | Predicate<IncomeVO> timePredicate) { |
| | | IncomeStatisticsVO statistics = new IncomeStatisticsVO(); |
| | | for (IncomeVO record : incomeRecords) { |
| | | if (record.getInsertTime() == null || !timePredicate.test(record)) { |
| | | continue; |
| | | } |
| | | BigDecimal receivedAmount = getZeroIfNull(record.getAmount()); |
| | | BigDecimal couponAmount = getZeroIfNull(record.getCouponDeductionAmount()); |
| | | BigDecimal refundAmount = getZeroIfNull(record.getRefundAmount()); |
| | | statistics.setTotalIncomeAmount(statistics.getTotalIncomeAmount() |
| | | .add(receivedAmount).add(couponAmount)); |
| | | statistics.setCouponDeductionAmount(statistics.getCouponDeductionAmount().add(couponAmount)); |
| | | statistics.setRefundAmount(statistics.getRefundAmount().add(refundAmount)); |
| | | } |
| | | statistics.setNetIncomeAmount(statistics.getTotalIncomeAmount() |
| | | .subtract(statistics.getCouponDeductionAmount()) |
| | | .subtract(statistics.getRefundAmount())); |
| | | return statistics; |
| | | } |
| | | |
| | | /** 将收入记录时间转换为本地日期。 */ |
| | | private LocalDate getRecordDate(IncomeVO record) { |
| | | return LocalDateTime.ofInstant(record.getInsertTime().toInstant(), ZoneId.systemDefault()).toLocalDate(); |
| | | } |
| | | |
| | | /** 空金额按零参与统计。 */ |
| | | private BigDecimal getZeroIfNull(BigDecimal amount) { |
| | | return amount == null ? BigDecimal.ZERO : amount; |
| | | } |
| | | |
| | | /** 将批量查询到的优惠券抵扣金额回填到对应收入记录。 */ |
| | | private void applyCouponDeductions(List<IncomeVO> incomeRecords, |
| | | Map<Long, BigDecimal> couponDeductionAmounts) { |
| | | for (IncomeVO record : incomeRecords) { |
| | | if (record.getId() == null) { |
| | | continue; |
| | | } |
| | | try { |
| | | record.setCouponDeductionAmount(couponDeductionAmounts.getOrDefault( |
| | | Long.valueOf(record.getId()), BigDecimal.ZERO)); |
| | | } catch (NumberFormatException ignored) { |
| | | record.setCouponDeductionAmount(BigDecimal.ZERO); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 批量获取已使用优惠券的抵扣金额,避免按订单逐条调用优惠券服务。 |
| | | * |
| | | * @param usedCouponIds 用户优惠券领取记录 ID 集合 |
| | | * @return 用户优惠券领取记录 ID 与抵扣金额的映射(单位:元) |
| | | */ |
| | | private Map<Long, BigDecimal> getCouponDeductionAmounts(Set<Long> usedCouponIds) { |
| | | if (usedCouponIds.isEmpty()) { |
| | | return Collections.emptyMap(); |
| | | } |
| | | CouponDeductionQuery query = new CouponDeductionQuery(); |
| | | query.setUserCouponIds(new ArrayList<>(usedCouponIds)); |
| | | List<CouponDeductionVO> deductions = couponClient.queryDeductionAmounts(query); |
| | | if (deductions == null || deductions.isEmpty()) { |
| | | return Collections.emptyMap(); |
| | | } |
| | | return deductions.stream() |
| | | .filter(deduction -> deduction.getUserCouponId() != null) |
| | | .collect(Collectors.toMap(CouponDeductionVO::getUserCouponId, |
| | | deduction -> getZeroIfNull(deduction.getDeductionAmount()), BigDecimal::add)); |
| | | } |
| | | |
| | | /** |
| | |
| | | List<MoneyBack> refund = refundCoursePackageClient.getRefund(); |
| | | |
| | | for (MoneyBack moneyBack : refund) { |
| | | List<TCoursePackagePayment> coursePackagePayments = courseStuddentClient.queryByIds(moneyBack.getIds()); |
| | | List<CoursePackageOrderStudent> coursePackagePayments = courseStuddentClient.queryByIds(moneyBack.getIds()); |
| | | BigDecimal totalAmount = BigDecimal.ZERO; |
| | | for (TCoursePackagePayment payment : coursePackagePayments){ |
| | | //课包名称 |
| | | TCoursePackage tCoursePackage = coursePackageClient.queryById(payment.getCoursePackageId()); |
| | | payment.setName(tCoursePackage.getName()); |
| | | payment.setId(Long.valueOf(tCoursePackage.getId())); |
| | | BigDecimal cashPayment = payment.getCashPayment(); |
| | | if (cashPayment==null){ |
| | | cashPayment = BigDecimal.ZERO; |
| | | } |
| | | Integer totalClassHours = payment.getTotalClassHours(); |
| | | BigDecimal result = new BigDecimal(0); |
| | | if (totalClassHours!=0) { |
| | | result = cashPayment.divide(BigDecimal.valueOf(totalClassHours), 2, RoundingMode.HALF_UP); |
| | | } |
| | | //单价 |
| | | payment.setOnePrice(result); |
| | | int has = payment.getTotalClassHours() - payment.getLaveClassHours(); |
| | | //剩余课时 |
| | | payment.setHasHours(has); |
| | | BigDecimal onePrice = payment.getOnePrice(); |
| | | Integer laveClassHours = payment.getLaveClassHours(); |
| | | BigDecimal result1 = onePrice.multiply(BigDecimal.valueOf(laveClassHours)); |
| | | //总价 |
| | | payment.setRestPrice(result1); |
| | | System.out.println("======="+result1); |
| | | totalAmount = totalAmount.add(result1); |
| | | IncomeVO temp = new IncomeVO(); |
| | | temp.setInsertTime(payment.getInsertTime()); |
| | | temp.setAmount(result1); |
| | | incomeVOS.add(temp); |
| | | } |
| | | // for (TCoursePackagePayment payment : coursePackagePayments){ |
| | | // //课包名称 |
| | | // TCoursePackage tCoursePackage = coursePackageClient.queryById(payment.getCoursePackageId()); |
| | | // payment.setName(tCoursePackage.getName()); |
| | | // payment.setId(Long.valueOf(tCoursePackage.getId())); |
| | | // BigDecimal cashPayment = payment.getCashPayment(); |
| | | // if (cashPayment==null){ |
| | | // cashPayment = BigDecimal.ZERO; |
| | | // } |
| | | // Integer totalClassHours = payment.getTotalClassHours(); |
| | | // BigDecimal result = new BigDecimal(0); |
| | | // if (totalClassHours!=0) { |
| | | // result = cashPayment.divide(BigDecimal.valueOf(totalClassHours), 2, RoundingMode.HALF_UP); |
| | | // } |
| | | // //单价 |
| | | // payment.setOnePrice(result); |
| | | // int has = payment.getTotalClassHours() - payment.getLaveClassHours(); |
| | | // //剩余课时 |
| | | // payment.setHasHours(has); |
| | | // BigDecimal onePrice = payment.getOnePrice(); |
| | | // Integer laveClassHours = payment.getLaveClassHours(); |
| | | // BigDecimal result1 = onePrice.multiply(BigDecimal.valueOf(laveClassHours)); |
| | | // //总价 |
| | | // payment.setRestPrice(result1); |
| | | // System.out.println("======="+result1); |
| | | // totalAmount = totalAmount.add(result1); |
| | | // IncomeVO temp = new IncomeVO(); |
| | | // temp.setInsertTime(payment.getInsertTime()); |
| | | // temp.setAmount(result1); |
| | | // incomeVOS.add(temp); |
| | | // } |
| | | } |
| | | // 获取赛事退费记录 |
| | | List<PaymentCompetition> competitions = competitionClient.listAllPayment(competitionQuery); |
| | |
| | | @ResponseBody |
| | | public Object backPt(Integer type) { |
| | | HashMap<String, Object> map = new HashMap<>(); |
| | | List<Integer> userPt = appUserClient.getUserPt(Arrays.asList(1)); |
| | | if(userPt.size()==0){ |
| | | userPt.add(-1); |
| | | } |
| | | List<Integer> userPt = listStatisticsAppUserIds(null); |
| | | ArrayList<Object> integers = new ArrayList<>(); |
| | | int year = DateUtil.year(new Date()); |
| | | List<TBackRecord> thisYear = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().like(TBackRecord::getTime, year).in(TBackRecord::getUserId,userPt)); |
| | |
| | | @RequestMapping(value = "/backYys") |
| | | @ResponseBody |
| | | public Object backYys(Integer id) { |
| | | id = resolveOperatorId(id); |
| | | HashMap<String, Object> map = new HashMap<>(); |
| | | List<Integer> userPt = appUserClient.getUserYYs(id); |
| | | if(userPt.size()==0){ |
| | | userPt.add(-1); |
| | | } |
| | | List<Integer> userPt = listStatisticsAppUserIds(id); |
| | | ArrayList<Object> integers = new ArrayList<>(); |
| | | int year = DateUtil.year(new Date()); |
| | | List<TBackRecord> thisYear = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().like(TBackRecord::getTime, year).in(TBackRecord::getUserId,userPt)); |
| | |
| | | @RequestMapping(value = "/backStore") |
| | | @ResponseBody |
| | | public Object backStore(Integer id) { |
| | | HashMap<String, Object> map = new HashMap<>(); |
| | | List<Integer> userPt = appUserClient.getUserStore(id); |
| | | if(userPt.size()==0){ |
| | | userPt.add(-1); |
| | | id = resolveStatisticsStoreId(id); |
| | | List<Integer> collect1 = Collections.singletonList(id == null ? -1 : id); |
| | | //课程 |
| | | List<Integer> list = coursePackagePaymentClient.queryPaymentCoursePackage(collect1); |
| | | //场地 |
| | | List<SiteBooking> list1 = siteBookingService.list(new QueryWrapper<SiteBooking>().in("storeId", collect1).eq("state", 1)); |
| | | List<Integer> collect = list1.stream().map(SiteBooking::getAppUserId).collect(Collectors.toList()); |
| | | list.addAll(collect); |
| | | //赛事 |
| | | List<Integer> list2 = competitionClient.queryAppUserId(collect1); |
| | | list.addAll(list2); |
| | | // 没有消费用户时,避免 MyBatis-Plus 生成 userId IN () 的非法 SQL。 |
| | | if (list.isEmpty()) { |
| | | list.add(-1); |
| | | } |
| | | //门票 |
| | | |
| | | HashMap<String, Object> map = new HashMap<>(); |
| | | |
| | | ArrayList<Object> integers = new ArrayList<>(); |
| | | int year = DateUtil.year(new Date()); |
| | | List<TBackRecord> thisYear = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().like(TBackRecord::getTime, year).in(TBackRecord::getUserId,userPt)); |
| | | List<TBackRecord> thisYear = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().like(TBackRecord::getTime, year).in(TBackRecord::getUserId,list)); |
| | | double sum5 = thisYear.stream().mapToDouble(TBackRecord::getMoney).sum(); |
| | | map.put("thisYear",sum5); |
| | | |
| | | List<TBackRecord> thisMonth = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().like(TBackRecord::getTime, new SimpleDateFormat("yyyy-MM").format(new Date())).in(TBackRecord::getUserId,userPt)); |
| | | List<TBackRecord> thisMonth = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().like(TBackRecord::getTime, new SimpleDateFormat("yyyy-MM").format(new Date())).in(TBackRecord::getUserId,list)); |
| | | double sum6= thisMonth.stream().mapToDouble(TBackRecord::getMoney).sum(); |
| | | map.put("thisMonth",sum6); |
| | | |
| | |
| | | for (int i = 0; i < 10; i++) { |
| | | integers.add(year-i); |
| | | } |
| | | List<Object> collect = integers.stream().sorted().collect(Collectors.toList()); |
| | | List<Object> collectw = integers.stream().sorted().collect(Collectors.toList()); |
| | | // 年 |
| | | ArrayList<Double> years = new ArrayList<>(); |
| | | for (Object o : collect) { |
| | | for (Object o : collectw) { |
| | | double sum=0.0; |
| | | String s = o.toString(); |
| | | List<TBackRecord> list = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().like(TBackRecord::getTime, s).in(TBackRecord::getUserId,userPt)); |
| | | sum = list.stream().mapToDouble(TBackRecord::getMoney).sum(); |
| | | List<TBackRecord> lists = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().like(TBackRecord::getTime, s).in(TBackRecord::getUserId,list)); |
| | | sum = lists.stream().mapToDouble(TBackRecord::getMoney).sum(); |
| | | years.add(sum); |
| | | } |
| | | ArrayList<Double> months = new ArrayList<>(); |
| | |
| | | m="0"+i; |
| | | } |
| | | String s = year + "-" + m; |
| | | List<TBackRecord> list = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().like(TBackRecord::getTime, s).in(TBackRecord::getUserId,userPt)); |
| | | sum = list.stream().mapToDouble(TBackRecord::getMoney).sum(); |
| | | List<TBackRecord> lists = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().like(TBackRecord::getTime, s).in(TBackRecord::getUserId,list)); |
| | | sum = lists.stream().mapToDouble(TBackRecord::getMoney).sum(); |
| | | months.add(sum); |
| | | } |
| | | |
| | |
| | | String s7 = minNow.minusDays(27).toString(); |
| | | String s8 = maxNow.minusDays(20).toString(); |
| | | |
| | | List<TBackRecord> list = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().between(TBackRecord::getTime, s7,s8).in(TBackRecord::getUserId,userPt)); |
| | | double sum = list.stream().mapToDouble(TBackRecord::getMoney).sum(); |
| | | List<TBackRecord> lists = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().between(TBackRecord::getTime, s7,s8).in(TBackRecord::getUserId,list)); |
| | | double sum = lists.stream().mapToDouble(TBackRecord::getMoney).sum(); |
| | | |
| | | List<TBackRecord> list1 = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().between(TBackRecord::getTime, s5,s6).in(TBackRecord::getUserId,userPt)); |
| | | double sum1 = list1.stream().mapToDouble(TBackRecord::getMoney).sum(); |
| | | List<TBackRecord> list2 = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().between(TBackRecord::getTime, s3,s4).in(TBackRecord::getUserId,userPt)); |
| | | double sum2 = list2.stream().mapToDouble(TBackRecord::getMoney).sum(); |
| | | List<TBackRecord> list3 = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().between(TBackRecord::getTime, s1,s2).in(TBackRecord::getUserId,userPt)); |
| | | List<TBackRecord> lists1 = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().between(TBackRecord::getTime, s5,s6).in(TBackRecord::getUserId,list)); |
| | | double sum1 = lists1.stream().mapToDouble(TBackRecord::getMoney).sum(); |
| | | List<TBackRecord> lists2 = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().between(TBackRecord::getTime, s3,s4).in(TBackRecord::getUserId,list)); |
| | | double sum2 = lists2.stream().mapToDouble(TBackRecord::getMoney).sum(); |
| | | List<TBackRecord> list3 = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().between(TBackRecord::getTime, s1,s2).in(TBackRecord::getUserId,list)); |
| | | double sum3 = list3.stream().mapToDouble(TBackRecord::getMoney).sum(); |
| | | |
| | | map.put("thisWeek",sum3); |
| | |
| | | for (int i = 6; i >= 0; i--) { |
| | | String s = minNow.minusDays(i).toString(); |
| | | String s9 = maxNow.minusDays(i).toString(); |
| | | List<TBackRecord> day = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().between(TBackRecord::getTime, s,s9).in(TBackRecord::getUserId,userPt)); |
| | | List<TBackRecord> day = backRecordService.list(new LambdaQueryWrapper<TBackRecord>().between(TBackRecord::getTime, s,s9).in(TBackRecord::getUserId,list)); |
| | | double sum4 = day.stream().mapToDouble(TBackRecord::getMoney).sum(); |
| | | days.add(sum4); |
| | | if(i==0){ |
| | |
| | | @RequestMapping(value = "/userAndVipPt") |
| | | @ResponseBody |
| | | public Object userAndVipPt(Integer type) { |
| | | type=1; |
| | | HashMap<String, Object> map = appUserClient.userAndVipPt(type); |
| | | // 平台用户统计按用户归属全量统计,不能以“已有消费记录”筛选, |
| | | // 否则会遗漏尚未在门店消费的新注册用户。 |
| | | HashMap<String, Object> map = appUserClient.userAndVipPt(1); |
| | | return map; |
| | | } |
| | | |
| | | @RequestMapping(value = "/stuPt") |
| | | @ResponseBody |
| | | public Object stuPt() { |
| | | HashMap<String, Object> map = appUserClient.stuPt(); |
| | | HashMap<String, Object> map = appUserClient.stuYys(listStatisticsAppUserIds(null)); |
| | | return map; |
| | | } |
| | | @RequestMapping(value = "/stuYys") |
| | | @ResponseBody |
| | | public Object stuYys(Integer id) { |
| | | id = resolveOperatorId(id); |
| | | List<TStore> list4 = listStatisticsStores(id, true); |
| | | List<Integer> collect1 = list4.stream().map(TStore::getId).collect(Collectors.toList()); |
| | | // 运营商没有门店时,后续查询不能生成 storeId IN ()。 |
| | | if (collect1.isEmpty()) { |
| | | collect1.add(-1); |
| | | } |
| | | //课程 |
| | | List<Integer> list = coursePackagePaymentClient.queryPaymentCoursePackage(collect1); |
| | | //场地 |
| | | List<SiteBooking> list1 = siteBookingService.list(new QueryWrapper<SiteBooking>().in("storeId", collect1).eq("state", 1)); |
| | | List<Integer> collect = list1.stream().map(SiteBooking::getAppUserId).collect(Collectors.toList()); |
| | | list.addAll(collect); |
| | | //赛事 |
| | | List<Integer> list2 = competitionClient.queryAppUserId(collect1); |
| | | list.addAll(list2); |
| | | // 下游会员统计同样使用 IN 查询,空用户列表按无匹配记录处理。 |
| | | if (list.isEmpty()) { |
| | | list.add(-1); |
| | | } |
| | | //门票 |
| | | |
| | | HashMap<String, Object> map = appUserClient.stuYys(list); |
| | | return map; |
| | | } |
| | | @RequestMapping(value = "/stuStores") |
| | | @ResponseBody |
| | | public Object stuStores(Integer id) { |
| | | id = resolveStatisticsStoreId(id); |
| | | List<Integer> collect1 = Collections.singletonList(id == null ? -1 : id); |
| | | //课程 |
| | | List<Integer> list = coursePackagePaymentClient.queryPaymentCoursePackage(collect1); |
| | | //场地 |
| | | List<SiteBooking> list1 = siteBookingService.list(new QueryWrapper<SiteBooking>().in("storeId", collect1).eq("state", 1)); |
| | | List<Integer> collect = list1.stream().map(SiteBooking::getAppUserId).collect(Collectors.toList()); |
| | | list.addAll(collect); |
| | | //赛事 |
| | | List<Integer> list2 = competitionClient.queryAppUserId(collect1); |
| | | list.addAll(list2); |
| | | //门票 |
| | | |
| | | HashMap<String, Object> map = appUserClient.stuStores(list); |
| | | return map; |
| | | } |
| | | |
| | | // 消耗课时数据-平台 |
| | | @RequestMapping(value = "/coursePt") |
| | | @ResponseBody |
| | | public Object coursePt() { |
| | | List<Integer> userPt = appUserClient.getUserPt(Arrays.asList(1)); |
| | | List<Integer> userPt = listStatisticsAppUserIds(null); |
| | | HashMap<String, Object> map = coursePackagePaymentClient.coursePt(userPt); |
| | | return map; |
| | | } |
| | | // 消耗课时数据-运营商 |
| | | @RequestMapping(value = "/courseYys") |
| | | @ResponseBody |
| | | public Object courseYys(Integer id) { |
| | | id = resolveOperatorId(id); |
| | | List<Integer> userPt = listStatisticsAppUserIds(id); |
| | | HashMap<String, Object> map = coursePackagePaymentClient.coursePt(userPt); |
| | | return map; |
| | | } |
| | | // 消耗课时数据-运营商 |
| | | @RequestMapping(value = "/courseStore") |
| | | @ResponseBody |
| | | public Object courseStore(Integer id) { |
| | | id = resolveStatisticsStoreId(id); |
| | | List<Integer> userPt = listStatisticsAppUserIdsForStore(id); |
| | | HashMap<String, Object> map = coursePackagePaymentClient.coursePt(userPt); |
| | | return map; |
| | | } |
| | |
| | | @RequestMapping(value = "/userAndVipYys") |
| | | @ResponseBody |
| | | public Object userAndVipYys(Integer id) { |
| | | HashMap<String, Object> map = appUserClient.userAndVipYys(id); |
| | | id = resolveOperatorId(id); |
| | | List<Integer> collect1 = listStatisticsStoreIds(id, true); |
| | | //课程 |
| | | List<Integer> list = coursePackagePaymentClient.queryPaymentCoursePackage(collect1); |
| | | //场地 |
| | | List<SiteBooking> list1 = siteBookingService.list(new QueryWrapper<SiteBooking>().in("storeId", collect1).eq("state", 1)); |
| | | List<Integer> collect = list1.stream().map(SiteBooking::getAppUserId).collect(Collectors.toList()); |
| | | list.addAll(collect); |
| | | //赛事 |
| | | List<Integer> list2 = competitionClient.queryAppUserId(collect1); |
| | | list.addAll(list2); |
| | | //门票 |
| | | |
| | | HashMap<String, Object> map = appUserClient.userAndVipYys(list); |
| | | return map; |
| | | } |
| | | @RequestMapping(value = "/userAndVipStore") |
| | | @ResponseBody |
| | | public Object userAndVipStore(Integer id) { |
| | | HashMap<String, Object> map = appUserClient.userAndVipStore(id); |
| | | id = resolveStatisticsStoreId(id); |
| | | List<Integer> collect1 = Collections.singletonList(id == null ? -1 : id); |
| | | //课程 |
| | | List<Integer> list = coursePackagePaymentClient.queryPaymentCoursePackage(collect1); |
| | | //场地 |
| | | List<SiteBooking> list1 = siteBookingService.list(new QueryWrapper<SiteBooking>().in("storeId", collect1).eq("state", 1)); |
| | | List<Integer> collect = list1.stream().map(SiteBooking::getAppUserId).collect(Collectors.toList()); |
| | | list.addAll(collect); |
| | | //赛事 |
| | | List<Integer> list2 = competitionClient.queryAppUserId(collect1); |
| | | list.addAll(list2); |
| | | //门票 |
| | | |
| | | HashMap<String, Object> map = appUserClient.userAndVipStore(list); |
| | | return map; |
| | | } |
| | | @RequestMapping(value = "/actPt") |
| | | @ResponseBody |
| | | public Object actPt(Integer type) { |
| | | List<Integer> userPt = appUserClient.getUserPt(Arrays.asList(1)); |
| | | List<Integer> userPt = listStatisticsAppUserIds(null); |
| | | HashMap<String, Object> map = competitionClient.actPt(userPt); |
| | | |
| | | List<TStore> list = storeService.list(new LambdaQueryWrapper<TStore>().eq(TStore::getOperatorId, 0)); |
| | | List<TStore> list = listStatisticsStores(null, false); |
| | | long l1=0; |
| | | for (TStore tStore : list) { |
| | | long l = DateUtil.betweenDay(tStore.getCreateTime(), new Date(), true); |
| | | String startTime = tStore.getStartTime(); |
| | | String endTime = tStore.getEndTime(); |
| | | String s = startTime.split(":")[0]; |
| | | String s1 = endTime.split(":")[1]; |
| | | Integer integer = Integer.valueOf(s); |
| | | Integer integer1 = Integer.valueOf(s1); |
| | | Integer a =0; |
| | | if(integer==0 && integer1==0){ |
| | | a=24; |
| | | }else { |
| | | a= integer1-integer; |
| | | } |
| | | l1 += l * a; |
| | | l1 += getStoreOperatingHours(tStore, new Date()); |
| | | } |
| | | map.put("allHour",l1); |
| | | return map; |
| | |
| | | @RequestMapping(value = "/actYys") |
| | | @ResponseBody |
| | | public Object actYys(Integer id) { |
| | | List<Integer> userPt = appUserClient.getUserYYs(id); |
| | | HashMap<String, Object> map = competitionClient.actPt(userPt); |
| | | id = resolveOperatorId(id); |
| | | CompetionVO competionVO = new CompetionVO(); |
| | | List<Integer> collect1 = listStatisticsStoreIds(id, true); |
| | | //课程 |
| | | List<Integer> list = coursePackagePaymentClient.queryPaymentCoursePackage(collect1); |
| | | //场地 |
| | | List<SiteBooking> list1 = siteBookingService.list(new QueryWrapper<SiteBooking>().in("storeId", collect1).eq("state", 1)); |
| | | List<Integer> collect = list1.stream().map(SiteBooking::getAppUserId).collect(Collectors.toList()); |
| | | list.addAll(collect); |
| | | //赛事 |
| | | List<Integer> list2 = competitionClient.queryAppUserId(collect1); |
| | | list.addAll(list2); |
| | | //门票 |
| | | |
| | | List<TStore> list = storeService.list(new LambdaQueryWrapper<TStore>().eq(TStore::getOperatorId, 0)); |
| | | |
| | | competionVO.setIds(list2); |
| | | competionVO.setOperatorId(id); |
| | | competionVO.setStoreIds(collect1); |
| | | HashMap<String, Object> map = competitionClient.actYys(competionVO); |
| | | |
| | | List<TStore> lists = listStatisticsStores(id, true); |
| | | long l1=0; |
| | | for (TStore tStore : list) { |
| | | long l = DateUtil.betweenDay(tStore.getCreateTime(), new Date(), true); |
| | | String startTime = tStore.getStartTime(); |
| | | String endTime = tStore.getEndTime(); |
| | | String s = startTime.split(":")[0]; |
| | | String s1 = endTime.split(":")[1]; |
| | | Integer integer = Integer.valueOf(s); |
| | | Integer integer1 = Integer.valueOf(s1); |
| | | Integer a =0; |
| | | if(integer==0 && integer1==0){ |
| | | a=24; |
| | | }else { |
| | | a= integer1-integer; |
| | | } |
| | | l1 += l * a; |
| | | for (TStore tStore : lists) { |
| | | l1 += getStoreOperatingHours(tStore, new Date()); |
| | | } |
| | | map.put("allHour",l1); |
| | | return map; |
| | |
| | | @RequestMapping(value = "/actStore") |
| | | @ResponseBody |
| | | public Object actStore(Integer id) { |
| | | List<Integer> userPt = appUserClient.getUserStore(id); |
| | | HashMap<String, Object> map = competitionClient.actPt(userPt); |
| | | |
| | | List<TStore> list = storeService.list(new LambdaQueryWrapper<TStore>().eq(TStore::getOperatorId, 0)); |
| | | long l1=0; |
| | | for (TStore tStore : list) { |
| | | long l = DateUtil.betweenDay(tStore.getCreateTime(), new Date(), true); |
| | | String startTime = tStore.getStartTime(); |
| | | String endTime = tStore.getEndTime(); |
| | | String s = startTime.split(":")[0]; |
| | | String s1 = endTime.split(":")[1]; |
| | | Integer integer = Integer.valueOf(s); |
| | | Integer integer1 = Integer.valueOf(s1); |
| | | Integer a =0; |
| | | if(integer==0 && integer1==0){ |
| | | a=24; |
| | | }else { |
| | | a= integer1-integer; |
| | | } |
| | | l1 += l * a; |
| | | if (Integer.valueOf(3).equals(UserExt.getUser().getObjectType())) { |
| | | id = UserExt.getUser().getObjectId(); |
| | | } else { |
| | | id = resolveStoreId(id); |
| | | } |
| | | map.put("allHour",l1); |
| | | TStore store = id == null ? null : storeService.getById(id); |
| | | CompetionVO competionVO = new CompetionVO(); |
| | | if (store == null || !Integer.valueOf(1).equals(store.getState())) { |
| | | competionVO.setStoreIds(Collections.singletonList(-1)); |
| | | } else { |
| | | List<Integer> storeIds = Collections.singletonList(store.getId()); |
| | | competionVO.setStoreIds(storeIds); |
| | | } |
| | | HashMap<String, Object> map = competitionClient.actStore(competionVO); |
| | | map.put("allHour", store == null || !Integer.valueOf(1).equals(store.getState()) |
| | | ? 0 : getStoreOperatingHours(store, new Date())); |
| | | return map; |
| | | } |
| | | |
| | |
| | | @RequestMapping("/operator") |
| | | public String operator(Model model) { |
| | | Integer objectType = UserExt.getUser().getObjectType(); |
| | | List<TOperator> list = operatorService.list(new LambdaQueryWrapper<TOperator>().ne(TOperator::getState, 3)); |
| | | Integer objectId = UserExt.getUser().getObjectId(); |
| | | |
| | | List<TOperator> list = operatorService.list(new LambdaQueryWrapper<TOperator>().ne(TOperator::getState, 3).ne(TOperator::getId,0)); |
| | | model.addAttribute("list",list); |
| | | model.addAttribute("objectType",objectType); |
| | | model.addAttribute("objectId",objectId); |
| | | return PREFIX + "operatorIncome.html"; |
| | | } |
| | | |
| | |
| | | @ResponseBody |
| | | @RequestMapping("/selectYys") |
| | | public Object selectYys(Integer id,String time) { |
| | | id = resolveOperatorId(id); |
| | | HashMap<String, Object> map = new HashMap<>(); |
| | | // 找出平台的用户 |
| | | List<User> list = sysUserService.list(new LambdaQueryWrapper<User>().eq(User::getObjectType, 2)); |
| | | List<Integer> ids = list.stream().map(User::getId).collect(Collectors.toList()); |
| | | List<Integer> userIds = appUserClient.getUserYYs(id); |
| | | QueryDataFee queryDataFee = new QueryDataFee(time, userIds); |
| | | // 会员费 |
| | | HashMap<String, Object> map1 = appUserClient.queryFee(queryDataFee); |
| | | Object fee1 = map1.get("fee1"); |
| | | |
| | | map.put("fee1",fee1); |
| | | //玩湃比 |
| | | Object fee2 = map1.get("fee2"); |
| | | map.put("fee2",fee2); |
| | | // List<User> list = sysUserService.list(new LambdaQueryWrapper<User>().eq(User::getObjectType, 2)); |
| | | // List<Integer> ids = list.stream().map(User::getId).collect(Collectors.toList()); |
| | | // List<Integer> userIds = appUserClient.getUserYYs(id); |
| | | List<Integer> collect1 = listStatisticsStoreIds(id, true); |
| | | QueryDataFee queryDataFee = new QueryDataFee(time, collect1); |
| | | // 课程收入 |
| | | HashMap<String, Object> map3 = courseClient.queryFee(queryDataFee); |
| | | map.put("fee3",map3.get("fee")); |
| | |
| | | map.put("fee4",aDouble1); |
| | | |
| | | // 订场 |
| | | if(ids.size()==0){ |
| | | List<Integer> ids = new ArrayList<>(); |
| | | if(collect1.size()==0){ |
| | | ids.add(-1); |
| | | }else{ |
| | | List<TSite> list = siteService.list(new QueryWrapper<TSite>().in("storeId", collect1).eq("state", 1)); |
| | | ids = list.stream().map(TSite::getId).collect(Collectors.toList()); |
| | | if(ids.isEmpty()){ |
| | | ids.add(-1); |
| | | } |
| | | } |
| | | LambdaQueryWrapper<SiteBooking> vipPaymentLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
| | | if(ToolUtil.isNotEmpty(time)){ |
| | |
| | | String etime = time.split(" - ")[1]+" 23:59:59"; |
| | | vipPaymentLambdaQueryWrapper.between(SiteBooking::getInsertTime,stime,etime); |
| | | } |
| | | if(userIds.size()==0){ |
| | | userIds.add(-1); |
| | | } |
| | | vipPaymentLambdaQueryWrapper.in(SiteBooking::getAppUserId,userIds); |
| | | vipPaymentLambdaQueryWrapper.in(SiteBooking::getSiteId,ids); |
| | | vipPaymentLambdaQueryWrapper.ne(SiteBooking::getStatus,0); |
| | | ArrayList<Integer> objects = new ArrayList<>(); |
| | | objects.add(1); |
| | | objects.add(2); |
| | | vipPaymentLambdaQueryWrapper.in(SiteBooking::getPayType,objects); |
| | | List<SiteBooking> list1 = siteBookingService.list(vipPaymentLambdaQueryWrapper); |
| | | List<SiteBooking> list1 = new ArrayList<>(siteBookingService.list(vipPaymentLambdaQueryWrapper)); |
| | | double sum = list1.stream().mapToDouble(SiteBooking::getPayMoney).sum(); |
| | | map.put("fee5",sum); |
| | | |
| | | // 智慧球场支付记录的场地可能只保存在 t_game.siteId。ballClient 已补齐该值, |
| | | // 将其转换为订场明细后可与普通订场一起按场地类型统计。 |
| | | GameDataQuery gameDataQuery = new GameDataQuery(); |
| | | gameDataQuery.setObjectId(id); |
| | | if (ToolUtil.isNotEmpty(time)) { |
| | | gameDataQuery.setStartTime(time.split(" - ")[0] + " 00:00:00"); |
| | | gameDataQuery.setEndTime(time.split(" - ")[1] + " 23:59:59"); |
| | | } |
| | | double gameIncome = 0D; |
| | | for (TGameRecord gameRecord : ballClient.getData(gameDataQuery)) { |
| | | if (gameRecord.getSiteId() == null || gameRecord.getMoney() == null || !ids.contains(gameRecord.getSiteId())) { |
| | | continue; |
| | | } |
| | | SiteBooking gameBooking = new SiteBooking(); |
| | | gameBooking.setSiteId(gameRecord.getSiteId()); |
| | | gameBooking.setPayMoney(gameRecord.getMoney().doubleValue()); |
| | | list1.add(gameBooking); |
| | | gameIncome += gameRecord.getMoney().doubleValue(); |
| | | } |
| | | map.put("fee5", sum + gameIncome); |
| | | |
| | | |
| | | List<Integer> collect = list1.stream().map(SiteBooking::getSiteId).collect(Collectors.toList()); |
| | | if(collect.size()==0){ |
| | | collect.add(-1); |
| | | } |
| | | List<TSite> list3 = siteService.list(new LambdaQueryWrapper<TSite>().in(TSite::getId, collect)); |
| | | List<TSite> list3 = siteService.list(new LambdaQueryWrapper<TSite>().in(TSite::getId, collect).ne(TSite::getState, 3)); |
| | | for (SiteBooking siteBooking : list1) { |
| | | for (TSite tSite : list3) { |
| | | if(siteBooking.getSiteId().equals(tSite.getId())){ |
| | |
| | | } |
| | | |
| | | |
| | | List<TSiteType> list2 = siteTypeService.list(); |
| | | List<TSiteType> list2 = siteTypeService.list(new LambdaQueryWrapper<TSiteType>().ne(TSiteType::getState, 3)); |
| | | |
| | | List<Map<String,Object>> mapList = new ArrayList<>(); |
| | | |
| | |
| | | @ResponseBody |
| | | @RequestMapping("/selectStore") |
| | | public Object selectStore(Integer id,String time) { |
| | | id = resolveStatisticsStoreId(id); |
| | | HashMap<String, Object> map = new HashMap<>(); |
| | | // 找出平台的用户 |
| | | List<User> list = sysUserService.list(new LambdaQueryWrapper<User>().eq(User::getObjectType, 2)); |
| | | List<Integer> ids = list.stream().map(User::getId).collect(Collectors.toList()); |
| | | List<Integer> userIds = appUserClient.getUserStore(id); |
| | | QueryDataFee queryDataFee = new QueryDataFee(time, userIds); |
| | | List<Integer> collect1 = Collections.singletonList(id == null ? -1 : id); |
| | | //课程 |
| | | List<Integer> list = coursePackagePaymentClient.queryPaymentCoursePackage(collect1); |
| | | //场地 |
| | | List<SiteBooking> list1 = siteBookingService.list(new QueryWrapper<SiteBooking>().in("storeId", collect1).eq("state", 1)); |
| | | List<Integer> collect = list1.stream().map(SiteBooking::getAppUserId).collect(Collectors.toList()); |
| | | list.addAll(collect); |
| | | //赛事 |
| | | List<Integer> list2 = competitionClient.queryAppUserId(collect1); |
| | | list.addAll(list2); |
| | | // 没有消费用户时,避免 MyBatis-Plus 生成 appUserId IN () 的非法 SQL。 |
| | | if (list.isEmpty()) { |
| | | list.add(-1); |
| | | } |
| | | //门票 |
| | | |
| | | QueryDataFee queryDataFee = new QueryDataFee(time, list); |
| | | // 会员费 |
| | | HashMap<String, Object> map1 = appUserClient.queryFee(queryDataFee); |
| | | Object fee1 = map1.get("fee1"); |
| | |
| | | map.put("fee4",aDouble1); |
| | | |
| | | // 订场 |
| | | if(ids.size()==0){ |
| | | ids.add(-1); |
| | | } |
| | | LambdaQueryWrapper<SiteBooking> vipPaymentLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
| | | if(ToolUtil.isNotEmpty(time)){ |
| | | String stime = time.split(" - ")[0]+" 00:00:00"; |
| | | String etime = time.split(" - ")[1]+" 23:59:59"; |
| | | vipPaymentLambdaQueryWrapper.between(SiteBooking::getInsertTime,stime,etime); |
| | | } |
| | | if(userIds.size()==0){ |
| | | userIds.add(-1); |
| | | } |
| | | vipPaymentLambdaQueryWrapper.in(SiteBooking::getAppUserId,userIds); |
| | | vipPaymentLambdaQueryWrapper.in(SiteBooking::getAppUserId,list); |
| | | vipPaymentLambdaQueryWrapper.ne(SiteBooking::getStatus,0); |
| | | ArrayList<Integer> objects = new ArrayList<>(); |
| | | objects.add(1); |
| | | objects.add(2); |
| | | vipPaymentLambdaQueryWrapper.in(SiteBooking::getPayType,objects); |
| | | List<SiteBooking> list1 = siteBookingService.list(vipPaymentLambdaQueryWrapper); |
| | | double sum = list1.stream().mapToDouble(SiteBooking::getPayMoney).sum(); |
| | | List<SiteBooking> lists1 = siteBookingService.list(vipPaymentLambdaQueryWrapper); |
| | | double sum = lists1.stream().mapToDouble(SiteBooking::getPayMoney).sum(); |
| | | map.put("fee5",sum); |
| | | |
| | | |
| | | List<Integer> collect = list1.stream().map(SiteBooking::getSiteId).collect(Collectors.toList()); |
| | | if(collect.size()==0){ |
| | | collect.add(-1); |
| | | List<Integer> collects = list1.stream().map(SiteBooking::getSiteId).collect(Collectors.toList()); |
| | | if(collects.size()==0){ |
| | | collects.add(-1); |
| | | } |
| | | List<TSite> list3 = siteService.list(new LambdaQueryWrapper<TSite>().in(TSite::getId, collect)); |
| | | List<TSite> list3 = siteService.list(new LambdaQueryWrapper<TSite>().in(TSite::getId, collects).ne(TSite::getState, 3)); |
| | | for (SiteBooking siteBooking : list1) { |
| | | for (TSite tSite : list3) { |
| | | if(siteBooking.getSiteId().equals(tSite.getId())){ |
| | |
| | | } |
| | | |
| | | |
| | | List<TSiteType> list2 = siteTypeService.list(); |
| | | List<TSiteType> lists2 = siteTypeService.list(new LambdaQueryWrapper<TSiteType>().ne(TSiteType::getState, 3)); |
| | | |
| | | List<Map<String,Object>> mapList = new ArrayList<>(); |
| | | |
| | | for (TSiteType tSiteType : list2) { |
| | | for (TSiteType tSiteType : lists2) { |
| | | HashMap<String, Object> map2 = new HashMap<>(); |
| | | map2.put("name",tSiteType.getName()); |
| | | double a =0; |
| | | for (SiteBooking siteBooking : list1) { |
| | | if(tSiteType.getId().equals(siteBooking.getType())){ |
| | | if(null != siteBooking.getType() && tSiteType.getId().equals(siteBooking.getType()) && null != siteBooking.getPayMoney()){ |
| | | a += siteBooking.getPayMoney(); |
| | | } |
| | | } |
| | |
| | | map.put("quarterone",quarter); |
| | | map.put("yearone",year); |
| | | |
| | | // 数值卡片复用营收数据的同一批收入明细和退款口径。图表数据仍沿用原查询, |
| | | // 但收入类型净额之和始终与“营收数据-净收入”一致。 |
| | | Map<String, Object> incomeData = (Map<String, Object>) getIncomeData(null, null, time); |
| | | Map<Integer, BigDecimal> incomeTypeNet = (Map<Integer, BigDecimal>) incomeData.get("incomeTypeNet"); |
| | | map.put("fee1", incomeTypeNet.getOrDefault(1, BigDecimal.ZERO)); |
| | | map.put("fee2", incomeTypeNet.getOrDefault(2, BigDecimal.ZERO)); |
| | | map.put("fee3", incomeTypeNet.getOrDefault(3, BigDecimal.ZERO)); |
| | | map.put("fee4", incomeTypeNet.getOrDefault(4, BigDecimal.ZERO)); |
| | | map.put("fee5", incomeTypeNet.getOrDefault(5, BigDecimal.ZERO)); |
| | | map.put("fee7", incomeTypeNet.getOrDefault(6, BigDecimal.ZERO)); |
| | | |
| | | return map; |
| | | } |
| | | |
| | |
| | | @RequestMapping("/store") |
| | | public String store(Model model) { |
| | | Integer objectType = UserExt.getUser().getObjectType(); |
| | | List<TStore> list = storeService.list(new LambdaQueryWrapper<TStore>().eq(TStore::getState, 1)); |
| | | model.addAttribute("list",list); |
| | | List<TStore> tStores = new ArrayList<>(); |
| | | if(objectType == 1){ |
| | | tStores = storeService.list(new LambdaQueryWrapper<TStore>().eq(TStore::getState, 1)); |
| | | } |
| | | if (objectType == 2){ |
| | | tStores = storeService.list(new LambdaQueryWrapper<TStore>().eq(TStore::getState, 1).eq(TStore::getOperatorId,UserExt.getUser().getObjectId())); |
| | | } |
| | | if (objectType == 3){ |
| | | tStores = storeService.list(new LambdaQueryWrapper<TStore>().eq(TStore::getState, 1).eq(TStore::getId,UserExt.getUser().getObjectId())); |
| | | } |
| | | model.addAttribute("list",tStores); |
| | | model.addAttribute("objectType",objectType); |
| | | model.addAttribute("objectId",UserExt.getUser().getObjectId()); |
| | | return PREFIX + "storeIncome.html"; |
| | | } |
| | | |
| | |
| | | @ResponseBody |
| | | public Object type1(String time) { |
| | | HashMap<String, Object> map = new HashMap<>(); |
| | | // 找出平台的用户 |
| | | List<User> list = sysUserService.list(new LambdaQueryWrapper<User>().eq(User::getObjectType, 1)); |
| | | List<Integer> ids = list.stream().map(User::getId).collect(Collectors.toList()); |
| | | List<Integer> userIds = appUserClient.getUserPt(ids); |
| | | // 平台统计是所有门店总和,用户范围同样来自所有门店的消费用户。 |
| | | List<Integer> userIds = listStatisticsAppUserIds(null); |
| | | QueryDataFee queryDataFee = new QueryDataFee(time, userIds); |
| | | // 课程和赛事接口的 ids 参数表示门店 ID;不能把平台用户 ID 传入。 |
| | | List<Integer> platformStoreIds = storeService.list(new LambdaQueryWrapper<TStore>() |
| | | .eq(TStore::getState, 1)) |
| | | .stream().map(TStore::getId).collect(Collectors.toList()); |
| | | QueryDataFee storeFeeQuery = new QueryDataFee(time, platformStoreIds); |
| | | // 会员费 |
| | | HashMap<String, Object> map1 = appUserClient.queryFee(queryDataFee); |
| | | Object fee1 = map1.get("fee1"); |
| | | |
| | | map.put("fee1",fee1); |
| | | //玩湃比 |
| | | Object fee2 = map1.get("fee2"); |
| | | map.put("fee2",fee2); |
| | | // 课程收入 |
| | | HashMap<String, Object> map3 = courseClient.queryFee(queryDataFee); |
| | | HashMap<String, Object> map3 = courseClient.queryFee(storeFeeQuery); |
| | | map.put("fee3",map3.get("fee")); |
| | | Object data = map3.get("data"); |
| | | map.put("courseData",data); |
| | | |
| | | |
| | | // 赛事收入 |
| | | Double aDouble1 = competitionClient.queryFee(queryDataFee); |
| | | Double aDouble1 = competitionClient.queryFee(storeFeeQuery); |
| | | map.put("fee4",aDouble1); |
| | | |
| | | // 订场 |
| | | if(ids.size()==0){ |
| | | ids.add(-1); |
| | | } |
| | | LambdaQueryWrapper<SiteBooking> vipPaymentLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
| | | if(ToolUtil.isNotEmpty(time)){ |
| | | String stime = time.split(" - ")[0]+" 00:00:00"; |
| | | String etime = time.split(" - ")[1]+" 23:59:59"; |
| | | vipPaymentLambdaQueryWrapper.between(SiteBooking::getInsertTime,stime,etime); |
| | | vipPaymentLambdaQueryWrapper.between(SiteBooking::getPayTime,stime,etime); |
| | | } |
| | | if(userIds.size()==0){ |
| | | userIds.add(-1); |
| | | } |
| | | vipPaymentLambdaQueryWrapper.in(SiteBooking::getAppUserId,userIds); |
| | | vipPaymentLambdaQueryWrapper.eq(SiteBooking::getState, 1); |
| | | vipPaymentLambdaQueryWrapper.ne(SiteBooking::getStatus,0); |
| | | vipPaymentLambdaQueryWrapper.ne(SiteBooking::getStatus,5); |
| | | ArrayList<Integer> objects = new ArrayList<>(); |
| | | objects.add(1); |
| | | objects.add(2); |
| | | vipPaymentLambdaQueryWrapper.in(SiteBooking::getPayType,objects); |
| | | List<SiteBooking> list1 = siteBookingService.list(vipPaymentLambdaQueryWrapper); |
| | | double sum = list1.stream().mapToDouble(SiteBooking::getPayMoney).sum(); |
| | | map.put("fee5",sum); |
| | | // 智慧球场查询query |
| | | GameDataQuery gameDataQuery = new GameDataQuery(); |
| | | gameDataQuery.setObjectId(0); |
| | | if (ToolUtil.isNotEmpty(time)) { |
| | | gameDataQuery.setStartTime(time.split(" - ")[0] + " 00:00:00"); |
| | | gameDataQuery.setEndTime(time.split(" - ")[1] + " 23:59:59"); |
| | | } |
| | | // 平台智慧球场 |
| | | List<TGameRecord> data1 = ballClient.getData(gameDataQuery); |
| | | // 将游戏支付转换为场地收入明细参与后续 siteId -> siteTypeId 分类。 |
| | | // fee5 仍由普通订场金额与游戏金额分别相加,避免重复计入总额。 |
| | | for (TGameRecord gameRecord : data1) { |
| | | if (gameRecord.getSiteId() == null || gameRecord.getMoney() == null) { |
| | | continue; |
| | | } |
| | | SiteBooking gameBooking = new SiteBooking(); |
| | | gameBooking.setSiteId(gameRecord.getSiteId()); |
| | | gameBooking.setPayMoney(gameRecord.getMoney().doubleValue()); |
| | | list1.add(gameBooking); |
| | | } |
| | | double sum1 = data1.stream() |
| | | .map(TGameRecord::getMoney) // 获取每个 TGameRecord 对象的 money 字段 |
| | | .filter(Objects::nonNull) |
| | | .mapToDouble(BigDecimal::doubleValue) // 将 BigDecimal 转换为 double |
| | | .sum(); |
| | | map.put("fee5",sum+sum1); |
| | | |
| | | |
| | | List<Integer> collect = list1.stream().map(SiteBooking::getSiteId).collect(Collectors.toList()); |
| | | if(collect.size()==0){ |
| | | collect.add(-1); |
| | | } |
| | | List<TSite> list3 = siteService.list(new LambdaQueryWrapper<TSite>().in(TSite::getId, collect)); |
| | | List<TSite> list3 = siteService.list(new LambdaQueryWrapper<TSite>().in(TSite::getId, collect).ne(TSite::getState, 3)); |
| | | for (SiteBooking siteBooking : list1) { |
| | | for (TSite tSite : list3) { |
| | | if(siteBooking.getSiteId().equals(tSite.getId())){ |
| | |
| | | } |
| | | |
| | | |
| | | List<TSiteType> list2 = siteTypeService.list(); |
| | | List<TSiteType> list2 = siteTypeService.list(new LambdaQueryWrapper<TSiteType>().ne(TSiteType::getState, 3)); |
| | | |
| | | List<Map<String,Object>> mapList = new ArrayList<>(); |
| | | |
| | |
| | | @RequestMapping("/stuCourseData") |
| | | @ResponseBody |
| | | public Object stuCourseData() { |
| | | ArrayList<Integer> objects = new ArrayList<>(); |
| | | objects.add(1); |
| | | List<Integer> userIds = appUserClient.getUserPt(objects); |
| | | List<Integer> userIds = listStatisticsAppUserIds(null); |
| | | List<Map<String,Object>> list = coursePackagePaymentClient.queryCourseData(userIds); |
| | | ArrayList<Object> objects2 = new ArrayList<>(); |
| | | ArrayList<Object> objects3 = new ArrayList<>(); |
| | |
| | | @RequestMapping("/stuUserData") |
| | | @ResponseBody |
| | | public Object stuUserData() { |
| | | ArrayList<Integer> objects = new ArrayList<>(); |
| | | objects.add(1); |
| | | // 平台地域/年龄统计按平台注册用户全量口径,不能仅取已有消费记录的用户。 |
| | | HashMap<String, Object> map = appUserClient.queryUserAge1(); |
| | | |
| | | return map; |
| | |
| | | @RequestMapping("/stuUserDataYys") |
| | | @ResponseBody |
| | | public Object stuUserDataYys(Integer id) { |
| | | ArrayList<Integer> objects = new ArrayList<>(); |
| | | objects.add(1); |
| | | HashMap<String, Object> map = appUserClient.queryUserAgeYys(id); |
| | | |
| | | id = resolveOperatorId(id); |
| | | List<Integer> collect1 = listStatisticsStoreIds(id, true); |
| | | //课程 |
| | | List<Integer> list = coursePackagePaymentClient.queryPaymentCoursePackage(collect1); |
| | | //场地 |
| | | List<SiteBooking> list1 = siteBookingService.list(new QueryWrapper<SiteBooking>().in("storeId", collect1).eq("state", 1)); |
| | | List<Integer> collect = list1.stream().map(SiteBooking::getAppUserId).collect(Collectors.toList()); |
| | | list.addAll(collect); |
| | | //赛事 |
| | | List<Integer> list2 = competitionClient.queryAppUserId(collect1); |
| | | list.addAll(list2); |
| | | //门票 |
| | | HashMap<String, Object> map = appUserClient.queryUserAgeYys(list); |
| | | return map; |
| | | } |
| | | @RequestMapping("/stuUserDataStore") |
| | | @ResponseBody |
| | | public Object stuUserDataStore(Integer id) { |
| | | ArrayList<Integer> objects = new ArrayList<>(); |
| | | objects.add(1); |
| | | HashMap<String, Object> map = appUserClient.queryUserAgeStore(id); |
| | | id = resolveStatisticsStoreId(id); |
| | | List<Integer> collect1 = Collections.singletonList(id == null ? -1 : id); |
| | | //课程 |
| | | List<Integer> list = coursePackagePaymentClient.queryPaymentCoursePackage(collect1); |
| | | //场地 |
| | | List<SiteBooking> list1 = siteBookingService.list(new QueryWrapper<SiteBooking>().in("storeId", collect1).eq("state", 1)); |
| | | List<Integer> collect = list1.stream().map(SiteBooking::getAppUserId).collect(Collectors.toList()); |
| | | list.addAll(collect); |
| | | //赛事 |
| | | List<Integer> list2 = competitionClient.queryAppUserId(collect1); |
| | | list.addAll(list2); |
| | | //门票 |
| | | |
| | | HashMap<String, Object> map = appUserClient.queryUserAgeStore(list); |
| | | |
| | | return map; |
| | | } |
| | | @RequestMapping("/selectYysJx") |
| | | @ResponseBody |
| | | public Object selectYysJx(Integer id) { |
| | | ArrayList<Integer> objects = new ArrayList<>(); |
| | | objects.add(1); |
| | | HashMap<String, Object> map1 = appUserClient.queryUserAgeYys1(id); |
| | | // 找出运营商的用户 |
| | | List<Integer> userYYs = appUserClient.getUserYYs(id); |
| | | id = resolveOperatorId(id); |
| | | List<Integer> collect1 = listStatisticsStoreIds(id, true); |
| | | //课程 |
| | | List<Integer> list = coursePackagePaymentClient.queryPaymentCoursePackage(collect1); |
| | | //场地 |
| | | List<SiteBooking> list1 = siteBookingService.list(new QueryWrapper<SiteBooking>().in("storeId", collect1).eq("state", 1)); |
| | | List<Integer> collect = list1.stream().map(SiteBooking::getAppUserId).collect(Collectors.toList()); |
| | | list.addAll(collect); |
| | | //赛事 |
| | | List<Integer> list2 = competitionClient.queryAppUserId(collect1); |
| | | list.addAll(list2); |
| | | //门票 |
| | | |
| | | |
| | | List<Map<String, Object>> mapList = coursePackagePaymentClient.queryCourseData(userYYs); |
| | | HashMap<String, Object> map1 = appUserClient.queryUserAgeYys1(list); |
| | | List<Map<String, Object>> mapList = coursePackagePaymentClient.queryCourseData(list); |
| | | ArrayList<Object> objects2 = new ArrayList<>(); |
| | | ArrayList<Object> objects3 = new ArrayList<>(); |
| | | for (Map<String, Object> map : mapList) { |
| | |
| | | @RequestMapping("/selectStoreJx") |
| | | @ResponseBody |
| | | public Object selectStoreJx(Integer id) { |
| | | ArrayList<Integer> objects = new ArrayList<>(); |
| | | objects.add(1); |
| | | HashMap<String, Object> map1 = appUserClient.queryUserAgeStore1(id); |
| | | // 找出运营商的用户 |
| | | List<Integer> userYYs = appUserClient.getUserYYs(id); |
| | | id = resolveStatisticsStoreId(id); |
| | | List<Integer> collect1 = Collections.singletonList(id == null ? -1 : id); |
| | | //课程 |
| | | List<Integer> list = coursePackagePaymentClient.queryPaymentCoursePackage(collect1); |
| | | //场地 |
| | | List<SiteBooking> list1 = siteBookingService.list(new QueryWrapper<SiteBooking>().in("storeId", collect1).eq("state", 1)); |
| | | List<Integer> collect = list1.stream().map(SiteBooking::getAppUserId).collect(Collectors.toList()); |
| | | list.addAll(collect); |
| | | //赛事 |
| | | List<Integer> list2 = competitionClient.queryAppUserId(collect1); |
| | | list.addAll(list2); |
| | | //门票 |
| | | |
| | | HashMap<String, Object> map1 = appUserClient.queryUserAgeStore1(list); |
| | | |
| | | List<Map<String, Object>> mapList = coursePackagePaymentClient.queryCourseData(userYYs); |
| | | List<Map<String, Object>> mapList = coursePackagePaymentClient.queryCourseData(list); |
| | | ArrayList<Object> objects2 = new ArrayList<>(); |
| | | ArrayList<Object> objects3 = new ArrayList<>(); |
| | | for (Map<String, Object> map : mapList) { |
| | |
| | | return map1; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | |