| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626 |
- package com.etotem.cfc.service;
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
- import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
- import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
- import com.etotem.cfc.common.Result;
- import com.etotem.cfc.dto.ActivityDTO;
- import com.etotem.cfc.entity.Activity;
- import com.etotem.cfc.entity.ActivityRegistration;
- import com.etotem.cfc.entity.FamilyMember;
- import com.etotem.cfc.entity.PointsLog;
- import com.etotem.cfc.entity.Task;
- import com.etotem.cfc.entity.User;
- import com.etotem.cfc.mapper.ActivityMapper;
- import com.etotem.cfc.mapper.FamilyMemberMapper;
- import com.etotem.cfc.mapper.PointsLogMapper;
- import com.etotem.cfc.mapper.TaskMapper;
- import com.etotem.cfc.mapper.UserMapper;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.scheduling.annotation.Scheduled;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import org.springframework.util.StringUtils;
- import javax.annotation.Resource;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- import java.util.stream.Collectors;
- import com.etotem.cfc.util.DimensionCodes;
- import com.etotem.cfc.util.SortUtil;
- @Slf4j
- @Service
- public class ActivityService extends ServiceImpl<ActivityMapper, Activity> {
- @Resource
- private TaskMapper taskMapper;
- @Resource
- private FamilyMemberMapper familyMemberMapper;
- @Resource
- private PointsLogMapper pointsLogMapper;
- @Resource
- private EnergyService energyService;
- @Resource
- private SysConfigService sysConfigService;
- @Resource
- private ActivityRegistrationService registrationService;
- @Resource
- private MembershipService membershipService;
- @Resource
- private UserMapper userMapper;
- @Resource
- private PlatformPointsService platformPointsService;
- public Result<Map<String, Object>> list(String dimensionCode, Integer page, Integer size, Long userId) {
- autoEndExpiredActivities();
- LambdaQueryWrapper<Activity> query = new LambdaQueryWrapper<Activity>()
- .eq(Activity::getStatus, "published")
- .orderByAsc(Activity::getStartTime);
- if (dimensionCode != null && !dimensionCode.isEmpty() && DimensionCodes.isValid(dimensionCode)) {
- String dim = dimensionCode.trim();
- // P1: 权重感知查询 — 匹配 dimension_weights > 0 或兼容旧版 dimension_code
- query.and(w -> w
- .apply("COALESCE(JSON_EXTRACT(dimension_weights, CONCAT('$.', {0})), 0) > 0", dim)
- .or().eq(Activity::getDimensionCode, dim)
- );
- }
- // 游客过滤:只返回公开活动
- if (userId == null) {
- query.and(w -> w.eq(Activity::getVisibility, "public")
- .or().eq(Activity::getVisibility, "all")
- .or().isNull(Activity::getVisibility));
- }
- SortUtil.applySort(query);
- Page<Activity> pageResult = this.page(new Page<>(page, size), query);
- boolean isGuest = (userId == null || userId <= 0);
- Long effectiveUserId = isGuest ? null : userId;
- String memberLevel = null;
- if (!isGuest) {
- try { memberLevel = membershipService.getMemberLevel(userId); } catch (Exception e) { /* ignore */ }
- }
- final String level = memberLevel;
- List<Activity> records = pageResult.getRecords();
- List<Long> activityIds = records.stream().map(Activity::getId).collect(Collectors.toList());
- Map<Long, String> regStatusMap = new HashMap<>();
- Set<Long> checkedInActivityIds = new HashSet<>();
- if (effectiveUserId != null && !activityIds.isEmpty()) {
- regStatusMap = registrationService.getRegistrationStatusMap(activityIds, effectiveUserId);
- List<Long> childIds = registrationService.getChildIdsByUser(effectiveUserId);
- if (!childIds.isEmpty()) {
- checkedInActivityIds = taskMapper.selectList(new LambdaQueryWrapper<Task>()
- .eq(Task::getSourceType, "activity")
- .in(Task::getSourceId, activityIds)
- .in(Task::getChildId, childIds)
- .eq(Task::getStatus, "completed"))
- .stream().map(Task::getSourceId).collect(Collectors.toSet());
- }
- }
- final Map<Long, String> regMap = regStatusMap;
- final Set<Long> checkedMap = checkedInActivityIds;
- List<ActivityDTO> dtos = records.stream().map(a -> {
- ActivityDTO dto = ActivityDTO.from(a, isGuest, level);
- String regStatus = regMap.getOrDefault(a.getId(), "not_registered");
- applyDisplayState(dto, a, regStatus, checkedMap.contains(a.getId()));
- return dto;
- }).collect(Collectors.toList());
- Map<String, Object> data = new HashMap<>();
- data.put("records", dtos);
- data.put("total", pageResult.getTotal());
- data.put("page", pageResult.getCurrent());
- data.put("size", pageResult.getSize());
- return Result.success(data);
- }
- public Result<ActivityDTO> detail(Long id, Long userId) {
- Activity activity = this.getById(id);
- if (activity == null) {
- return Result.error("活动不存在");
- }
- boolean isGuest = (userId == null || userId <= 0);
- String memberLevel = null;
- if (!isGuest) {
- try { memberLevel = membershipService.getMemberLevel(userId); } catch (Exception e) { /* ignore */ }
- }
- ActivityDTO dto = ActivityDTO.from(activity, isGuest, memberLevel);
- // applyDisplayState must run for ALL users (including guests) so that
- // displayStatus / displayLabel / registrationStatus are always populated.
- // For guests: registrationStatus=null, checkedIn=false → defaults to "open"/"not_registered".
- if (!isGuest) {
- String regStatus = registrationService.getUserRegistrationStatus(activity.getId(), userId);
- boolean checkedIn = hasCheckedIn(activity.getId(), userId);
- applyDisplayState(dto, activity, regStatus, checkedIn);
- } else {
- applyDisplayState(dto, activity, null, false);
- }
- return Result.success(dto);
- }
- public Result<ActivityDTO> create(Activity activity, Long creatorId) {
- activity.setStatus("draft");
- activity.setCurrentParticipants(0);
- activity.setApprovedCount(0);
- activity.setSignedCount(0);
- activity.setCreatorId(creatorId);
- activity.setCreatedAt(new Date());
- activity.setUpdatedAt(new Date());
- this.save(activity);
- return Result.success(ActivityDTO.from(activity));
- }
- public Result<ActivityDTO> update(Activity activity) {
- Activity existing = this.getById(activity.getId());
- if (existing == null) {
- return Result.error("活动不存在");
- }
- activity.setUpdatedAt(new Date());
- this.updateById(activity);
- return Result.success(ActivityDTO.from(this.getById(activity.getId())));
- }
- public Result<String> publish(Long id) {
- Activity activity = this.getById(id);
- if (activity == null) {
- return Result.error("活动不存在");
- }
- if (!"draft".equals(activity.getStatus())) {
- return Result.error("仅草稿状态可发布");
- }
- // P1-2: 发布前校验维度代码,两路(直发/审核流)统一要求 dimensionCode 非空
- if (activity.getDimensionCode() == null || activity.getDimensionCode().trim().isEmpty()) {
- return Result.error("请先设置活动维度(dimensionCode)");
- }
- activity.setStatus("published");
- activity.setUpdatedAt(new Date());
- this.updateById(activity);
- return Result.success("发布成功");
- }
- public Result<String> end(Long id) {
- Activity activity = this.getById(id);
- if (activity == null) {
- return Result.error("活动不存在");
- }
- activity.setStatus("ended");
- activity.setUpdatedAt(new Date());
- this.updateById(activity);
- return Result.success("活动已结束");
- }
- @Transactional
- public Map<String, Object> checkin(Long activityId, Long userId, Long memberId) {
- Map<String, Object> result = new HashMap<>();
- result.put("taskId", null);
- result.put("pointsEarned", 0);
- // 1. Validate activity exists and is active
- Activity activity = this.getById(activityId);
- if (activity == null) {
- result.put("error", "活动不存在");
- return result;
- }
- if (!"published".equals(activity.getStatus())) {
- result.put("error", "活动未发布或已结束");
- return result;
- }
- // 1.5 Time window check — checkin only allowed during the activity
- Date now = new Date();
- if (activity.getStartTime() != null && now.before(activity.getStartTime())) {
- result.put("error", "活动尚未开始,暂不能签到");
- return result;
- }
- if (activity.getEndTime() != null && now.after(activity.getEndTime())) {
- result.put("error", "活动已结束,不能签到");
- return result;
- }
- // 2. If no memberId, can't create task
- if (memberId == null) {
- result.put("error", "需要孩子身份签到");
- return result;
- }
- // 2.5 Identity: phone child self-checkin only; phone-less child allows same-family proxy
- FamilyMember child = familyMemberMapper.selectById(memberId);
- if (child == null) {
- result.put("error", "孩子不存在");
- return result;
- }
- boolean childHasPhone = StringUtils.hasText(child.getPhone());
- if (childHasPhone) {
- boolean isSelf = child.getUserId() != null && child.getUserId().equals(userId);
- if (!isSelf) {
- result.put("error", "有手机号的孩子只能本人签到");
- return result;
- }
- } else {
- User operator = userMapper.selectById(userId);
- boolean sameFamily = operator != null && operator.getFamilyId() != null
- && operator.getFamilyId().equals(child.getFamilyId());
- if (!sameFamily) {
- result.put("error", "无权限代签(需同一家庭)");
- return result;
- }
- }
- // 3. Registration check (if activity requires registration)
- boolean unregistered = false;
- if (activity.getRequireRegistration() != null && activity.getRequireRegistration() == 1) {
- boolean isApproved = registrationService.isApproved(activityId, memberId);
- boolean isRegistered = registrationService.isRegistered(activityId, memberId);
- if (!isApproved) {
- if (isRegistered) {
- result.put("error", "报名待审核,请等待审核通过");
- return result;
- }
- // Not registered at all — apply energy penalty, allow checkin anyway
- unregistered = true;
- Integer penaltyAmount = activity.getEnergyPenaltyUnregistered();
- if (penaltyAmount != null && penaltyAmount > 0) {
- try {
- int deducted = energyService.deductEnergyByCode(
- memberId,
- activity.getDimensionCode(),
- penaltyAmount,
- "未报名签到活动《" + activity.getTitle() + "》"
- );
- if (deducted >= 0) {
- result.put("energyPenalty", penaltyAmount);
- log.info("未报名签到能量扣减: memberId={}, activityId={}, penalty={}, dimension={}",
- memberId, activityId, penaltyAmount, activity.getDimensionCode());
- } else {
- result.put("energyPenaltyFailed", "余额不足");
- log.warn("未报名签到能量扣减失败(余额不足): memberId={}, activityId={}",
- memberId, activityId);
- }
- } catch (Exception e) {
- log.warn("能量扣减异常: memberId={}, activityId={}, error={}",
- memberId, activityId, e.getMessage());
- result.put("energyPenaltyFailed", e.getMessage());
- }
- }
- }
- }
- // 4. Check if already checked in (dedup by sourceType + sourceId + childId)
- Task existingTask = taskMapper.selectOne(
- new LambdaQueryWrapper<Task>()
- .eq(Task::getSourceType, "activity")
- .eq(Task::getSourceId, activityId)
- .eq(Task::getChildId, memberId)
- .last("LIMIT 1")
- );
- if (existingTask != null) {
- result.put("taskId", existingTask.getId());
- result.put("pointsEarned", 0);
- result.put("alreadyCompleted", true);
- return result;
- }
- // 5. Determine points — use activity's checkinPoints or sysconfig default
- int points = 5; // default
- if (activity.getCheckinPoints() != null && activity.getCheckinPoints() > 0) {
- points = activity.getCheckinPoints();
- } else {
- String defaultPointsStr = sysConfigService.getValue("activity_checkin_default_points");
- if (defaultPointsStr != null && !defaultPointsStr.isEmpty()) {
- try { points = Integer.parseInt(defaultPointsStr); } catch (NumberFormatException e) { /* use default */ }
- }
- }
- // 是否需要审核签到(活动级开关,默认免审)
- boolean needReview = activity.getRequireCheckinReview() != null && activity.getRequireCheckinReview() == 1;
- // 6. 创建签到任务;开启审核时进入 pending_review,待后台审核通过才发积分/能量
- Task task = new Task();
- if (child != null) {
- task.setFamilyId(child.getFamilyId());
- }
- task.setCreatorId(userId);
- task.setExecutorType("child"); // 非登录用户(不可登录成员)
- task.setExecutorId(memberId);
- task.setChildId(memberId);
- task.setTitle("活动签到: " + activity.getTitle());
- task.setDescription("自动生成 - 签到活动《" + activity.getTitle() + "》");
- task.setPoints(points);
- task.setRepeatType("none");
- task.setCategory("行动类");
- task.setNeedReview(needReview ? 1 : 0);
- task.setReviewByCategory(0);
- task.setTaskType("onetime");
- task.setSourceType("activity");
- task.setSourceId(activityId);
- if (needReview) {
- task.setStatus("pending_review");
- } else {
- task.setStatus("completed");
- task.setCompletedAt(new Date());
- }
- task.setCreatedAt(new Date());
- task.setUpdatedAt(new Date());
- // Set deadline to today end
- java.util.Calendar cal = java.util.Calendar.getInstance();
- cal.set(java.util.Calendar.HOUR_OF_DAY, 23);
- cal.set(java.util.Calendar.MINUTE, 59);
- cal.set(java.util.Calendar.SECOND, 59);
- task.setDeadline(cal.getTime());
- taskMapper.insert(task);
- // 7. 签到计数(无论是否需审核都计入 signedCount)
- activity.setSignedCount(activity.getSignedCount() != null ? activity.getSignedCount() + 1 : 1);
- activity.setUpdatedAt(new Date());
- this.updateById(activity);
- // 8. 发放奖励:免审直接发放;需审核在审核通过(reviewCheckin)时发放
- if (needReview) {
- result.put("needReview", true);
- result.put("pointsEarned", 0);
- log.info("活动签到进入待审核: activityId={}, memberId={}, taskId={}", activityId, memberId, task.getId());
- } else {
- awardCheckinRewards(activity, child, task, userId, points);
- result.put("needReview", false);
- result.put("pointsEarned", points);
- }
- // 9. Return result
- result.put("taskId", task.getId());
- return result;
- }
- /**
- * 签到奖励发放(积分/能量/CF)。免审签到在 checkin 内调用;需审核签到在审核通过时调用。
- */
- private void awardCheckinRewards(Activity activity, FamilyMember child, Task task, Long userId, int points) {
- // 更新孩子总积分
- if (child != null) {
- child.setTotalPoints(child.getTotalPoints() + points);
- child.setUpdatedAt(new Date());
- familyMemberMapper.updateById(child);
- }
- // 积分流水
- PointsLog pointsLog = new PointsLog();
- pointsLog.setChildId(task.getChildId());
- pointsLog.setTaskId(task.getId());
- pointsLog.setAmount(points);
- pointsLog.setType("earn");
- pointsLog.setCategory("task");
- pointsLog.setDescription("活动签到: " + activity.getTitle());
- pointsLog.setCreatedAt(new Date());
- pointsLogMapper.insert(pointsLog);
- // 发放能量
- try {
- energyService.awardEnergy(task.getChildId(), "activity", activity.getId(), points,
- "活动签到: " + activity.getTitle(), null);
- } catch (Exception e) {
- log.warn("能量发放失败(不影响积分): childId={}, activityId={}, error={}",
- task.getChildId(), activity.getId(), e.getMessage());
- }
- // 活动下发 CF 值(平台积分)
- if (activity.getPlatformPoints() != null && activity.getPlatformPoints() > 0 && userId != null) {
- try {
- platformPointsService.earn(userId, activity.getPlatformPoints(),
- "activity", activity.getId(), "活动签到: " + activity.getTitle());
- } catch (Exception e) {
- log.warn("活动CF值发放失败: userId={}, activityId={}, error={}",
- userId, activity.getId(), e.getMessage());
- }
- }
- }
- /**
- * 审核签到(活动级 requireCheckinReview 开启时):审批通过发放积分/能量/CF;驳回则不发。
- */
- @Transactional
- public Result<Map<String, Object>> reviewCheckin(Long taskId, Long reviewerId, boolean approve) {
- Task task = taskMapper.selectById(taskId);
- if (task == null) return Result.error("签到任务不存在");
- if (!"activity".equals(task.getSourceType())) return Result.error("非活动签到任务");
- if (!"pending_review".equals(task.getStatus())) return Result.error("当前状态不可审核");
- Map<String, Object> result = new HashMap<>();
- if (approve) {
- Activity activity = this.getById(task.getSourceId());
- FamilyMember child = task.getChildId() != null ? familyMemberMapper.selectById(task.getChildId()) : null;
- task.setStatus("completed");
- task.setCompletedAt(new Date());
- task.setUpdatedAt(new Date());
- taskMapper.updateById(task);
- int points = task.getPoints() != null ? task.getPoints() : 5;
- if (activity != null) {
- awardCheckinRewards(activity, child, task, task.getCreatorId(), points);
- }
- result.put("approved", true);
- return Result.success(result);
- } else {
- task.setStatus("rejected");
- task.setUpdatedAt(new Date());
- taskMapper.updateById(task);
- result.put("approved", false);
- return Result.success(result);
- }
- }
- /**
- * 自动结束过期活动
- * 逻辑:发布中且结束时间已过(endTime < now),将状态置为 ended。
- * 备注:正式上线建议改为 Spring @Scheduled(cron = "0 0 2 * * ?") 每日 02:00 执行(见 TODOs),此处保留方法供 list/detail 触发兜底。
- */
- /**
- * 自动结束过期活动(P2-1 定时化)
- * 每日 02:00 定时执行,结束阈值 = endTime < now()(去掉旧的 7 天延迟)。
- * 同时保留在 list/detail 查询时轻量调用兜底(实时状态判断)。
- */
- @Scheduled(cron = "0 0 2 * * ?")
- public void autoEndExpiredActivities() {
- try {
- Date now = new Date();
- this.update(new LambdaUpdateWrapper<Activity>()
- .eq(Activity::getStatus, "published")
- .lt(Activity::getEndTime, now)
- .set(Activity::getStatus, "ended")
- .set(Activity::getUpdatedAt, now));
- } catch (Exception e) {
- log.warn("自动结束过期活动失败: {}", e.getMessage());
- }
- }
- /**
- * 相关活动:按标签匹配(共享标签数降序 → 开始时间升序,与 {@link #list} 排序一致),
- * 排除自身,仅取已发布。游客(userId 为空)仅返回公开活动(与 list 的游客策略一致)。
- * 支持分页窗口截取。
- *
- * @param tags 源标签集合(来自文章/活动/商品)
- * @param excludeActivityId 需排除的活动ID(活动源排除自身;其他源为 null)
- * @param size 每页条数
- * @param page 页码(从1开始)
- * @param userId 当前用户ID(可为空)
- * @return 相关活动DTO列表,无匹配返回空列表
- */
- public List<ActivityDTO> getRelatedActivitiesByTags(List<String> tags, Long excludeActivityId,
- int size, int page, Long userId) {
- if (tags == null || tags.isEmpty() || size < 1) {
- return Collections.emptyList();
- }
- int p = page < 1 ? 1 : page;
- boolean isGuest = (userId == null || userId <= 0);
- LambdaQueryWrapper<Activity> wrapper = new LambdaQueryWrapper<Activity>()
- .eq(Activity::getStatus, "published");
- if (excludeActivityId != null) {
- wrapper.ne(Activity::getId, excludeActivityId);
- }
- wrapper.and(w -> {
- boolean first = true;
- for (String tag : tags) {
- if (first) {
- w.apply("FIND_IN_SET({0}, tags) > 0", tag);
- first = false;
- } else {
- w.or().apply("FIND_IN_SET({0}, tags) > 0", tag);
- }
- }
- });
- // 游客策略与 list() 一致:只返回公开/全部/未设置可见性的活动
- if (isGuest) {
- wrapper.and(w -> w.eq(Activity::getVisibility, "public")
- .or().eq(Activity::getVisibility, "all")
- .or().isNull(Activity::getVisibility));
- }
- List<Activity> candidates = this.list(wrapper);
- // 共享标签计数,剔除零共享(SQL 已限定至少一个标签命中,此处防御)
- Map<Long, Integer> score = new HashMap<>();
- List<Activity> matched = new ArrayList<>();
- for (Activity a : candidates) {
- if (excludeActivityId != null && a.getId() != null && a.getId().equals(excludeActivityId)) {
- continue;
- }
- int s = 0;
- if (a.getTags() != null) {
- for (String t : a.getTags().split(",")) {
- if (tags.contains(t.trim())) {
- s++;
- }
- }
- }
- if (s > 0) {
- matched.add(a);
- score.put(a.getId(), s);
- }
- }
- matched.sort((x, y) -> {
- int diff = score.getOrDefault(y.getId(), 0) - score.getOrDefault(x.getId(), 0);
- if (diff != 0) {
- return diff;
- }
- Date px = x.getStartTime();
- Date py = y.getStartTime();
- if (px == null && py == null) return 0;
- if (px == null) return 1;
- if (py == null) return -1;
- return px.compareTo(py);
- });
- // 分页窗口截取
- int from = (p - 1) * size;
- if (from >= matched.size()) {
- return Collections.emptyList();
- }
- int to = Math.min(from + size, matched.size());
- List<Activity> pageList = new ArrayList<>(matched.subList(from, to));
- // 会员价解析(与 list() 口径一致,失败静默降级为非会员价)
- String memberLevel = null;
- if (!isGuest) {
- try {
- memberLevel = membershipService.getMemberLevel(userId);
- } catch (Exception e) {
- // 会员查询失败不影响关联列表
- }
- }
- final String level = memberLevel;
- return pageList.stream()
- .map(a -> ActivityDTO.from(a, isGuest, level))
- .collect(Collectors.toList());
- }
- private boolean hasCheckedIn(Long activityId, Long userId) {
- List<Long> childIds = registrationService.getChildIdsByUser(userId);
- if (childIds.isEmpty()) {
- return false;
- }
- return taskMapper.selectCount(new LambdaQueryWrapper<Task>()
- .eq(Task::getSourceType, "activity")
- .eq(Task::getSourceId, activityId)
- .in(Task::getChildId, childIds)
- .eq(Task::getStatus, "completed")) > 0;
- }
- private void applyDisplayState(ActivityDTO dto, Activity activity, String registrationStatus, boolean checkedIn) {
- Date now = new Date();
- String displayStatus;
- String displayLabel;
- boolean ended = "ended".equals(activity.getStatus())
- || (activity.getEndTime() != null && now.after(activity.getEndTime()));
- if (ended) {
- displayStatus = "ended";
- displayLabel = "已结束";
- } else if (checkedIn) {
- displayStatus = "checked_in";
- displayLabel = "已签到";
- } else if (activity.getStartTime() != null && activity.getEndTime() != null
- && !now.before(activity.getStartTime()) && !now.after(activity.getEndTime())) {
- displayStatus = "ongoing";
- displayLabel = "进行中";
- } else if ("approved".equals(registrationStatus)) {
- displayStatus = "registered";
- displayLabel = "已报名";
- } else if (activity.getRegistrationDeadline() != null && now.after(activity.getRegistrationDeadline())) {
- displayStatus = "pending_start";
- displayLabel = "待开始";
- } else {
- displayStatus = "open";
- displayLabel = "报名中";
- }
- dto.setDisplayStatus(displayStatus);
- dto.setDisplayLabel(displayLabel);
- dto.setRegistrationStatus(checkedIn ? "checked_in" : (registrationStatus != null ? registrationStatus : "not_registered"));
- }
- }
|