小区活动分页

master
zzy 2026-04-25 12:23:10 +08:00
parent b1bca80f7d
commit c54540b11e
25 changed files with 1849 additions and 0 deletions

View File

@ -0,0 +1,229 @@
package com.fjrcloud.community.module.community.controller.admin.activity;
import com.fjrcloud.community.framework.apilog.core.annotation.ApiAccessLog;
import com.fjrcloud.community.framework.common.pojo.CommonResult;
import com.fjrcloud.community.framework.common.pojo.PageParam;
import com.fjrcloud.community.framework.common.pojo.PageResult;
import com.fjrcloud.community.framework.common.util.json.JsonUtils;
import com.fjrcloud.community.framework.common.util.object.BeanUtils;
import com.fjrcloud.community.framework.excel.core.util.ExcelUtils;
import com.fjrcloud.community.module.community.controller.admin.activity.vo.ActivityPageReqVO;
import com.fjrcloud.community.module.community.controller.admin.activity.vo.ActivityRespVO;
import com.fjrcloud.community.module.community.controller.admin.activity.vo.ActivitySaveReqVO;
import com.fjrcloud.community.module.community.dal.dataobject.activity.ActivityScopeDO;
import com.fjrcloud.community.module.community.dal.dataobject.activity.CommunityActivityDO;
import com.fjrcloud.community.module.community.dal.mysql.activity.ActivityScopeMapper;
import com.fjrcloud.community.module.community.service.activity.CommunityActivityService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
import static com.fjrcloud.community.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static com.fjrcloud.community.framework.common.pojo.CommonResult.success;
/**
* -
*
* @author fjrcloud
*/
@Tag(name = "管理后台 - 小区活动")
@RestController
@RequestMapping("/community/activity")
@Validated
public class CommunityActivityController {
@Resource
private CommunityActivityService communityActivityService;
@Resource
private ActivityScopeMapper activityScopeMapper;
@PostMapping("/create")
@Operation(summary = "创建小区活动")
@PreAuthorize("@ss.hasPermission('community:activity:create')")
public CommonResult<Long> createActivity(@Valid @RequestBody ActivitySaveReqVO createReqVO) {
return success(communityActivityService.createActivity(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新小区活动")
@PreAuthorize("@ss.hasPermission('community:activity:update')")
public CommonResult<Boolean> updateActivity(@Valid @RequestBody ActivitySaveReqVO updateReqVO) {
communityActivityService.updateActivity(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除小区活动")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('community:activity:delete')")
public CommonResult<Boolean> deleteActivity(@RequestParam("id") Long id) {
communityActivityService.deleteActivity(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除小区活动")
@PreAuthorize("@ss.hasPermission('community:activity:delete')")
public CommonResult<Boolean> deleteActivityList(@RequestParam("ids") List<Long> ids) {
communityActivityService.deleteActivityListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得小区活动")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('community:activity:query')")
public CommonResult<ActivityRespVO> getActivity(@RequestParam("id") Long id) {
CommunityActivityDO activity = communityActivityService.getActivity(id);
ActivityRespVO respVO = BeanUtils.toBean(activity, ActivityRespVO.class);
// 处理JSON字符串转列表
if (activity.getBannerImages() != null) {
respVO.setBannerImages(JsonUtils.parseArray(activity.getBannerImages(), String.class));
}
if (activity.getServiceCategories() != null) {
respVO.setServiceCategories(JsonUtils.parseArray(activity.getServiceCategories(), Integer.class));
}
if (activity.getServiceTargets() != null) {
respVO.setServiceTargets(JsonUtils.parseArray(activity.getServiceTargets(), Integer.class));
}
// 查询发布范围
List<ActivityScopeDO> scopeList = activityScopeMapper.selectListByActivityId(id);
if (scopeList != null && !scopeList.isEmpty()) {
List<Long> communityIds = scopeList.stream()
.map(ActivityScopeDO::getCommunityId)
.collect(Collectors.toList());
respVO.setCommunityIds(communityIds);
List<String> communityNames = scopeList.stream()
.map(ActivityScopeDO::getCommunityName)
.filter(Objects::nonNull)
.collect(Collectors.toList());
respVO.setCommunityNames(communityNames);
}
return success(respVO);
}
@GetMapping("/page")
@Operation(summary = "获得小区活动分页")
@PreAuthorize("@ss.hasPermission('community:activity:query')")
public CommonResult<PageResult<ActivityRespVO>> getActivityPage(@Valid ActivityPageReqVO pageReqVO) {
PageResult<CommunityActivityDO> pageResult = communityActivityService.getActivityPage(pageReqVO);
PageResult<ActivityRespVO> respVOPageResult = BeanUtils.toBean(pageResult, ActivityRespVO.class);
List<ActivityRespVO> activityList = respVOPageResult.getList();
if (activityList.isEmpty()) {
return success(respVOPageResult);
}
// 收集所有活动ID批量查询关联关系
List<Long> activityIds = activityList.stream()
.map(ActivityRespVO::getId)
.filter(Objects::nonNull)
.collect(Collectors.toList());
// 批量查询所有活动的关联小区
Map<Long, List<ActivityScopeDO>> activityScopeMap = new HashMap<>();
if (!activityIds.isEmpty()) {
List<ActivityScopeDO> allScopes = activityScopeMapper.selectListByActivityIds(activityIds);
activityScopeMap = allScopes.stream()
.collect(Collectors.groupingBy(ActivityScopeDO::getActivityId));
}
// 填充数据
for (int i = 0; i < activityList.size(); i++) {
ActivityRespVO respVO = activityList.get(i);
CommunityActivityDO activity = pageResult.getList().get(i);
try {
if (activity.getBannerImages() != null) {
respVO.setBannerImages(JsonUtils.parseArray(activity.getBannerImages(), String.class));
}
} catch (Exception e) {
respVO.setBannerImages(new ArrayList<>());
}
try {
if (activity.getServiceCategories() != null) {
respVO.setServiceCategories(JsonUtils.parseArray(activity.getServiceCategories(), Integer.class));
}
} catch (Exception e) {
respVO.setServiceCategories(new ArrayList<>());
}
try {
if (activity.getServiceTargets() != null) {
respVO.setServiceTargets(JsonUtils.parseArray(activity.getServiceTargets(), Integer.class));
}
} catch (Exception e) {
respVO.setServiceTargets(new ArrayList<>());
}
// 从缓存的Map中获取关联小区避免N+1查询
List<ActivityScopeDO> scopeList = activityScopeMap.getOrDefault(respVO.getId(), new ArrayList<>());
if (!scopeList.isEmpty()) {
List<Long> communityIds = new ArrayList<>(scopeList.size());
List<String> communityNames = new ArrayList<>(scopeList.size());
// 一次遍历同时提取ID和名称
for (ActivityScopeDO scope : scopeList) {
communityIds.add(scope.getCommunityId());
if (scope.getCommunityName() != null) {
communityNames.add(scope.getCommunityName());
}
}
respVO.setCommunityIds(communityIds);
respVO.setCommunityNames(communityNames);
}
}
return success(respVOPageResult);
}
@PutMapping("/publish")
@Operation(summary = "发布活动")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('community:activity:publish')")
public CommonResult<Boolean> publishActivity(@RequestParam("id") Long id) {
communityActivityService.publishActivity(id);
return success(true);
}
@PutMapping("/unpublish")
@Operation(summary = "下架活动")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('community:activity:unpublish')")
public CommonResult<Boolean> unpublishActivity(@RequestParam("id") Long id) {
communityActivityService.unpublishActivity(id);
return success(true);
}
@GetMapping("/export-excel")
@Operation(summary = "导出小区活动 Excel")
@PreAuthorize("@ss.hasPermission('community:activity:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportActivityExcel(@Valid ActivityPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<CommunityActivityDO> list = communityActivityService.getActivityPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "小区活动.xls", "数据", ActivityRespVO.class,
BeanUtils.toBean(list, ActivityRespVO.class));
}
}

View File

@ -0,0 +1,37 @@
package com.fjrcloud.community.module.community.controller.admin.activity.vo;
import com.fjrcloud.community.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static com.fjrcloud.community.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* - Request VO
*
* @author fjrcloud
*/
@Schema(description = "管理后台 - 小区活动分页 Request VO")
@Data
public class ActivityPageReqVO extends PageParam {
@Schema(description = "活动标题", example = "春节联欢")
private String title;
@Schema(description = "活动状态0-草稿1-报名中2-报名截止3-进行中4-已结束)", example = "1")
private Integer status;
@Schema(description = "活动开始时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] activityStartTime;
@Schema(description = "小区ID", example = "1")
private Long communityId;
@Schema(description = "是否显示", example = "false")
private Boolean isDisplay;
}

View File

@ -0,0 +1,104 @@
package com.fjrcloud.community.module.community.controller.admin.activity.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
/**
* - Response VO
*
* @author fjrcloud
*/
@Schema(description = "管理后台 - 小区活动 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ActivityRespVO {
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("编号")
private Long id;
@Schema(description = "活动标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "春节联欢晚会")
@ExcelProperty("活动标题")
private String title;
@Schema(description = "活动简介(富文本)", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("活动简介")
private String content;
@Schema(description = "封面图片URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://xxx.com/cover.jpg")
@ExcelProperty("封面图片")
private String coverImage;
@Schema(description = "轮播图URL列表", example = "[\"https://xxx.com/banner1.jpg\"]")
private List<String> bannerImages;
@Schema(description = "服务类别JSON数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 2]")
private List<Integer> serviceCategories;
@Schema(description = "服务对象JSON数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 3]")
private List<Integer> serviceTargets;
@Schema(description = "报名开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("报名开始时间")
private LocalDateTime registrationStartTime;
@Schema(description = "报名结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("报名结束时间")
private LocalDateTime registrationEndTime;
@Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("活动开始时间")
private LocalDateTime activityStartTime;
@Schema(description = "活动结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("活动结束时间")
private LocalDateTime activityEndTime;
@Schema(description = "活动地点", requiredMode = Schema.RequiredMode.REQUIRED, example = "小区活动中心")
@ExcelProperty("活动地点")
private String location;
@Schema(description = "人数上限", example = "100")
@ExcelProperty("人数上限")
private Integer maxParticipants;
@Schema(description = "联系人", example = "张三")
@ExcelProperty("联系人")
private String contactPerson;
@Schema(description = "联系电话", example = "13800138000")
@ExcelProperty("联系电话")
private String contactPhone;
@Schema(description = "当前报名人数", example = "50")
@ExcelProperty("当前报名人数")
private Integer currentParticipants;
@Schema(description = "活动状态0-草稿1-报名中2-报名截止3-进行中4-已结束)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("活动状态")
private Integer status;
@Schema(description = "浏览次数", example = "100")
@ExcelProperty("浏览次数")
private Integer viewCount;
@Schema(description = "是否展示0-隐藏1-展示)", example = "true")
@ExcelProperty("是否展示")
private Boolean isDisplay;
@Schema(description = "小区ID列表发布范围", example = "[1, 2, 3]")
private List<Long> communityIds;
@Schema(description = "小区名称列表", example = "[\"阳光小区\", \"花园小区\"]")
private List<String> communityNames;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,82 @@
package com.fjrcloud.community.module.community.controller.admin.activity.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.List;
/**
* - / Request VO
*
* @author fjrcloud
*/
@Schema(description = "管理后台 - 小区活动新增/修改 Request VO")
@Data
public class ActivitySaveReqVO {
@Schema(description = "活动编号", example = "1")
private Long id;
@Schema(description = "活动标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "春节联欢晚会")
@NotEmpty(message = "活动标题不能为空")
private String title;
@Schema(description = "活动简介(富文本)", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "活动简介不能为空")
private String content;
@Schema(description = "封面图片URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://xxx.com/cover.jpg")
@NotEmpty(message = "封面图片不能为空")
private String coverImage;
@Schema(description = "轮播图URL列表", example = "[\"https://xxx.com/banner1.jpg\", \"https://xxx.com/banner2.jpg\"]")
private List<String> bannerImages;
@Schema(description = "服务类别JSON数组1-社区服务2-敬老服务3-助残服务4-关爱儿童5-环保宣传6-文明礼仪7-文化教育)", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 2]")
@NotNull(message = "服务类别不能为空")
private List<Integer> serviceCategories;
@Schema(description = "服务对象JSON数组1-儿童2-孤寡老人3-残障人士4-优抚对象5-其他)", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 3]")
@NotNull(message = "服务对象不能为空")
private List<Integer> serviceTargets;
@Schema(description = "报名开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "报名开始时间不能为空")
private LocalDateTime registrationStartTime;
@Schema(description = "报名结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "报名结束时间不能为空")
private LocalDateTime registrationEndTime;
@Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "活动开始时间不能为空")
private LocalDateTime activityStartTime;
@Schema(description = "活动结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "活动结束时间不能为空")
private LocalDateTime activityEndTime;
@Schema(description = "活动地点", requiredMode = Schema.RequiredMode.REQUIRED, example = "小区活动中心")
@NotEmpty(message = "活动地点不能为空")
private String location;
@Schema(description = "人数上限", example = "100")
private Integer maxParticipants;
@Schema(description = "联系人", example = "张三")
private String contactPerson;
@Schema(description = "联系电话", example = "13800138000")
private String contactPhone;
@Schema(description = "是否展示0-隐藏1-展示)", example = "true")
private Boolean isDisplay;
@Schema(description = "小区ID列表发布范围", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 2, 3]")
@NotNull(message = "发布范围不能为空")
private List<Long> communityIds;
}

View File

@ -0,0 +1,187 @@
package com.fjrcloud.community.module.community.controller.app.activity;
import com.fjrcloud.community.framework.common.pojo.CommonResult;
import com.fjrcloud.community.framework.common.pojo.PageResult;
import com.fjrcloud.community.framework.common.util.json.JsonUtils;
import com.fjrcloud.community.framework.common.util.object.BeanUtils;
import com.fjrcloud.community.framework.security.core.util.SecurityFrameworkUtils;
import com.fjrcloud.community.module.community.controller.admin.activity.vo.ActivityPageReqVO;
import com.fjrcloud.community.module.community.controller.app.activity.vo.*;
import com.fjrcloud.community.module.community.dal.dataobject.activity.ActivityScopeDO;
import com.fjrcloud.community.module.community.dal.dataobject.activity.CommunityActivityDO;
import com.fjrcloud.community.module.community.dal.mysql.activity.ActivityScopeMapper;
import com.fjrcloud.community.module.community.service.activity.CommunityActivityService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.fjrcloud.community.framework.common.pojo.CommonResult.success;
/**
* APP -
*
* @author fjrcloud
*/
@Tag(name = "用户APP - 小区活动")
@RestController
@RequestMapping("/community/activity")
@Validated
@Slf4j
public class AppCommunityActivityController {
@Resource
private CommunityActivityService communityActivityService;
@Resource
private ActivityScopeMapper activityScopeMapper;
@GetMapping("/page")
@Operation(summary = "获取小区活动分页列表")
@PermitAll
public CommonResult<PageResult<AppActivityPageItemVO>> getActivityPage(@Validated AppActivityPageReqVO pageReqVO) {
// 复用管理后台的 PageReqVO
ActivityPageReqVO adminPageReqVO = new ActivityPageReqVO();
adminPageReqVO.setPageNo(pageReqVO.getPageNo());
adminPageReqVO.setPageSize(pageReqVO.getPageSize());
adminPageReqVO.setTitle(pageReqVO.getTitle());
adminPageReqVO.setCommunityId(pageReqVO.getCommunityId());
adminPageReqVO.setActivityStartTime(pageReqVO.getActivityStartTime());
// 只查询已发布且展示的活动
adminPageReqVO.setIsDisplay(true);
// 查询分页数据
PageResult<CommunityActivityDO> pageResult = communityActivityService.getActivityPage(adminPageReqVO);
return success(buildAppActivityPageResult(pageResult));
}
@GetMapping("/get")
@Operation(summary = "获取活动详情")
@Parameter(name = "id", description = "活动编号", required = true, example = "1024")
public CommonResult<AppActivityDetailVO> getActivity(@RequestParam("id") Long id) {
// 增加浏览次数
communityActivityService.incrementViewCount(id);
// 查询活动详情
CommunityActivityDO activity = communityActivityService.getActivity(id);
return success(buildAppActivityDetailVO(activity));
}
@PostMapping("/registration")
@Operation(summary = "报名参加活动")
public CommonResult<Boolean> registerActivity(@Validated @RequestBody AppActivityRegistrationReqVO reqVO) {
Long memberId = SecurityFrameworkUtils.getLoginUserId();
communityActivityService.registerActivity(memberId, reqVO.getActivityId(), reqVO.getRemark());
return success(true);
}
@GetMapping("/registration/page")
@Operation(summary = "获取我的报名记录分页")
public CommonResult<PageResult<AppActivityRegistrationRespVO>> getMyRegistrationPage(@Validated AppActivityPageReqVO pageReqVO) {
Long memberId = SecurityFrameworkUtils.getLoginUserId();
PageResult<AppActivityRegistrationRespVO> pageResult = communityActivityService.getMyRegistrationPage(memberId, pageReqVO);
return success(pageResult);
}
@PostMapping("/registration/cancel")
@Operation(summary = "取消报名")
@Parameter(name = "id", description = "报名编号", required = true, example = "1024")
public CommonResult<Boolean> cancelRegistration(@RequestParam("id") Long id) {
Long memberId = SecurityFrameworkUtils.getLoginUserId();
communityActivityService.cancelRegistration(memberId, id);
return success(true);
}
/**
* App
*
* @param pageResult
* @return App
*/
private PageResult<AppActivityPageItemVO> buildAppActivityPageResult(PageResult<CommunityActivityDO> pageResult) {
// 直接转换分页VO字段都是DO中已有的不需要额外填充
return BeanUtils.toBean(pageResult, AppActivityPageItemVO.class);
}
/**
* App
*
* @param activity DO
* @return App VO
*/
private AppActivityDetailVO buildAppActivityDetailVO(CommunityActivityDO activity) {
AppActivityDetailVO respVO = BeanUtils.toBean(activity, AppActivityDetailVO.class);
fillAppActivityDetailVO(respVO, activity);
return respVO;
}
/**
* App
*
* @param respVO VO
* @param activity DO
*/
private void fillAppActivityDetailVO(AppActivityDetailVO respVO, CommunityActivityDO activity) {
// 处理JSON字符串转列表
try {
if (activity.getBannerImages() != null) {
respVO.setBannerImages(JsonUtils.parseArray(activity.getBannerImages(), String.class));
} else {
respVO.setBannerImages(new ArrayList<>());
}
} catch (Exception e) {
log.error("[fillAppActivityDetailVO] 解析轮播图失败, activityId: {}", activity.getId(), e);
respVO.setBannerImages(new ArrayList<>());
}
try {
if (activity.getServiceCategories() != null) {
respVO.setServiceCategories(JsonUtils.parseArray(activity.getServiceCategories(), Integer.class));
} else {
respVO.setServiceCategories(new ArrayList<>());
}
} catch (Exception e) {
log.error("[fillAppActivityDetailVO] 解析服务类别失败, activityId: {}", activity.getId(), e);
respVO.setServiceCategories(new ArrayList<>());
}
try {
if (activity.getServiceTargets() != null) {
respVO.setServiceTargets(JsonUtils.parseArray(activity.getServiceTargets(), Integer.class));
} else {
respVO.setServiceTargets(new ArrayList<>());
}
} catch (Exception e) {
log.error("[fillAppActivityDetailVO] 解析服务对象失败, activityId: {}", activity.getId(), e);
respVO.setServiceTargets(new ArrayList<>());
}
// 查询发布范围
List<ActivityScopeDO> scopeList = activityScopeMapper.selectListByActivityId(respVO.getId());
if (scopeList != null && !scopeList.isEmpty()) {
List<String> communityNames = scopeList.stream()
.map(ActivityScopeDO::getCommunityName)
.filter(Objects::nonNull)
.collect(Collectors.toList());
respVO.setCommunityNames(communityNames);
}
// 查询当前用户是否已报名
Long memberId = SecurityFrameworkUtils.getLoginUserId();
if (memberId != null) {
respVO.setHasRegistered(communityActivityService.isUserRegistered(memberId, respVO.getId()));
} else {
respVO.setHasRegistered(false);
}
}
}

View File

@ -0,0 +1,78 @@
package com.fjrcloud.community.module.community.controller.app.activity.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
/**
* APP - Response VO
*
* @author fjrcloud
*/
@Schema(description = "用户APP - 小区活动详情 Response VO")
@Data
public class AppActivityDetailVO {
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "活动标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "春节联欢晚会")
private String title;
@Schema(description = "活动简介(富文本)", requiredMode = Schema.RequiredMode.REQUIRED)
private String content;
@Schema(description = "封面图片URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://xxx.com/cover.jpg")
private String coverImage;
@Schema(description = "轮播图URL列表", example = "[\"https://xxx.com/banner1.jpg\", \"https://xxx.com/banner2.jpg\"]")
private List<String> bannerImages;
@Schema(description = "服务类别JSON数组1-社区服务2-敬老服务3-助残服务4-关爱儿童5-环保宣传6-文明礼仪7-文化教育)", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 2]")
private List<Integer> serviceCategories;
@Schema(description = "服务对象JSON数组1-儿童2-孤寡老人3-残障人士4-优抚对象5-其他)", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 3]")
private List<Integer> serviceTargets;
@Schema(description = "报名开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime registrationStartTime;
@Schema(description = "报名结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime registrationEndTime;
@Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime activityStartTime;
@Schema(description = "活动结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime activityEndTime;
@Schema(description = "活动地点", requiredMode = Schema.RequiredMode.REQUIRED, example = "小区活动中心")
private String location;
@Schema(description = "人数上限", example = "100")
private Integer maxParticipants;
@Schema(description = "当前报名人数", example = "50")
private Integer currentParticipants;
@Schema(description = "联系人", example = "张三")
private String contactPerson;
@Schema(description = "联系电话", example = "13800138000")
private String contactPhone;
@Schema(description = "活动状态0-草稿1-报名中2-报名截止3-进行中4-已结束5-已撤回)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status;
@Schema(description = "浏览次数", example = "100")
private Integer viewCount;
@Schema(description = "小区名称列表", example = "[\"阳光小区\", \"花园小区\"]")
private List<String> communityNames;
@Schema(description = "是否已报名", example = "false")
private Boolean hasRegistered;
}

View File

@ -0,0 +1,44 @@
package com.fjrcloud.community.module.community.controller.app.activity.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
/**
* APP - Response VO
*
* @author fjrcloud
*/
@Schema(description = "用户APP - 小区活动分页列表 Response VO")
@Data
public class AppActivityPageItemVO {
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "活动标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "春节联欢晚会")
private String title;
@Schema(description = "封面图片URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://xxx.com/cover.jpg")
private String coverImage;
@Schema(description = "报名开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime registrationStartTime;
@Schema(description = "报名结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime registrationEndTime;
@Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime activityStartTime;
@Schema(description = "活动结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime activityEndTime;
@Schema(description = "活动地点", requiredMode = Schema.RequiredMode.REQUIRED, example = "小区活动中心")
private String location;
@Schema(description = "活动状态0-草稿1-报名中2-报名截止3-进行中4-已结束5-已撤回)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status;
}

View File

@ -0,0 +1,34 @@
package com.fjrcloud.community.module.community.controller.app.activity.vo;
import com.fjrcloud.community.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static com.fjrcloud.community.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* APP - Request VO
*
* @author fjrcloud
*/
@Schema(description = "用户APP - 小区活动分页 Request VO")
@Data
public class AppActivityPageReqVO extends PageParam {
@Schema(description = "活动标题", example = "春节联欢晚会")
private String title;
@Schema(description = "小区ID", example = "1")
private Long communityId;
@Schema(description = "服务类别", example = "1")
private Integer serviceCategory;
@Schema(description = "活动开始时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] activityStartTime;
}

View File

@ -0,0 +1,24 @@
package com.fjrcloud.community.module.community.controller.app.activity.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* APP - Request VO
*
* @author fjrcloud
*/
@Schema(description = "用户APP - 活动报名 Request VO")
@Data
public class AppActivityRegistrationReqVO {
@Schema(description = "活动ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "活动ID不能为空")
private Long activityId;
@Schema(description = "备注", example = "希望参加")
private String remark;
}

View File

@ -0,0 +1,38 @@
package com.fjrcloud.community.module.community.controller.app.activity.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
/**
* APP - Response VO
*
* @author fjrcloud
*/
@Schema(description = "用户APP - 活动报名记录 Response VO")
@Data
public class AppActivityRegistrationRespVO {
@Schema(description = "报名编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "活动ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long activityId;
@Schema(description = "活动标题", example = "春节联欢晚会")
private String activityTitle;
@Schema(description = "活动封面图片", example = "https://xxx.com/cover.jpg")
private String activityCoverImage;
@Schema(description = "报名状态0-待审核1-已通过2-已拒绝3-已取消)", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
private Integer status;
@Schema(description = "报名时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime registrationTime;
@Schema(description = "备注", example = "希望参加")
private String remark;
}

View File

@ -0,0 +1,78 @@
package com.fjrcloud.community.module.community.controller.app.activity.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
/**
* APP - Response VO
*
* @author fjrcloud
*/
@Schema(description = "用户APP - 小区活动 Response VO")
@Data
public class AppActivityRespVO {
@Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "活动标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "春节联欢晚会")
private String title;
@Schema(description = "活动简介(富文本)", requiredMode = Schema.RequiredMode.REQUIRED)
private String content;
@Schema(description = "封面图片URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://xxx.com/cover.jpg")
private String coverImage;
@Schema(description = "轮播图URL列表", example = "[\"https://xxx.com/banner1.jpg\", \"https://xxx.com/banner2.jpg\"]")
private List<String> bannerImages;
@Schema(description = "服务类别JSON数组1-社区服务2-敬老服务3-助残服务4-关爱儿童5-环保宣传6-文明礼仪7-文化教育)", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 2]")
private List<Integer> serviceCategories;
@Schema(description = "服务对象JSON数组1-儿童2-孤寡老人3-残障人士4-优抚对象5-其他)", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 3]")
private List<Integer> serviceTargets;
@Schema(description = "报名开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime registrationStartTime;
@Schema(description = "报名结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime registrationEndTime;
@Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime activityStartTime;
@Schema(description = "活动结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime activityEndTime;
@Schema(description = "活动地点", requiredMode = Schema.RequiredMode.REQUIRED, example = "小区活动中心")
private String location;
@Schema(description = "人数上限", example = "100")
private Integer maxParticipants;
@Schema(description = "当前报名人数", example = "50")
private Integer currentParticipants;
@Schema(description = "联系人", example = "张三")
private String contactPerson;
@Schema(description = "联系电话", example = "13800138000")
private String contactPhone;
@Schema(description = "活动状态0-草稿1-报名中2-报名截止3-进行中4-已结束5-已撤回)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status;
@Schema(description = "浏览次数", example = "100")
private Integer viewCount;
@Schema(description = "小区名称列表", example = "[\"阳光小区\", \"花园小区\"]")
private List<String> communityNames;
@Schema(description = "是否已报名", example = "false")
private Boolean hasRegistered;
}

View File

@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import java.util.List;
import static com.fjrcloud.community.framework.common.pojo.CommonResult.success;
@ -32,6 +33,7 @@ public class AppBannerController {
@GetMapping("/list")
@Operation(summary = "获取Banner列表")
@PermitAll
@Parameter(name = "position", description = "显示位置1-首页2-个人中心3-好房出租)", example = "1")
public CommonResult<List<AppBannerRespVO>> getBannerList(@RequestParam(value = "position", required = false) Integer position) {
List<BannerDO> list = bannerService.getBannerListByPosition(position);

View File

@ -17,6 +17,7 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@ -41,6 +42,7 @@ public class AppKnowledgeClassController {
private KnowledgeScopeMapper knowledgeScopeMapper;
@GetMapping("/page")
@PermitAll
@Operation(summary = "获取知识课堂分页列表")
public CommonResult<PageResult<AppKnowledgeClassRespVO>> getKnowledgeClassPage(@Validated AppKnowledgeClassPageReqVO pageReqVO) {
KnowledgeClassPageReqVO adminPageReqVO = new KnowledgeClassPageReqVO();

View File

@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import java.util.List;
import static com.fjrcloud.community.framework.common.pojo.CommonResult.success;
@ -32,6 +33,7 @@ public class AppMiniAppConfigController {
@GetMapping("/list")
@Operation(summary = "获取小程序配置列表")
@PermitAll
@Parameter(name = "position", description = "显示位置1-首页2-更多服务)", example = "1")
public CommonResult<List<AppMiniAppConfigRespVO>> getMiniAppConfigList(
@RequestParam(value = "position", required = false) Integer position) {

View File

@ -23,6 +23,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
@ -51,6 +52,7 @@ public class AppCommunityNoticeController {
@GetMapping("/page")
@Operation(summary = "获取通知分页列表")
@PermitAll
public CommonResult<PageResult<AppNoticeRespVO>> getNoticePage(@Validated AppNoticePageReqVO pageReqVO) {
// 复用管理后台的 PageReqVO
NoticePageReqVO adminPageReqVO = new NoticePageReqVO();

View File

@ -20,6 +20,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@ -45,6 +46,7 @@ public class AppCommunityPostController {
private PostScopeMapper postScopeMapper;
@GetMapping("/page")
@PermitAll
@Operation(summary = "获取社区动态分页列表")
public CommonResult<PageResult<AppCommunityPostRespVO>> getCommunityPostPage(@Validated AppCommunityPostPageReqVO pageReqVO) {
// 复用管理后台的 PageReqVO

View File

@ -0,0 +1,69 @@
package com.fjrcloud.community.module.community.dal.dataobject.activity;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fjrcloud.community.framework.mybatis.core.dataobject.BaseDO;
import com.fjrcloud.community.framework.tenant.core.aop.TenantIgnore;
import lombok.*;
import java.time.LocalDateTime;
/**
* DO
*
* @author fjrcloud
*/
@TableName("comm_activity_registration")
@KeySequence("comm_activity_registration_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TenantIgnore
public class ActivityRegistrationDO extends BaseDO {
/**
*
*/
@TableId
private Long id;
/**
* ID
*/
private Long activityId;
/**
* ID
*/
private Long memberId;
/**
*
*/
private String memberName;
/**
*
*/
private String memberPhone;
/**
*
*/
private LocalDateTime registrationTime;
/**
* 0-1-2-3-
*/
private Integer status;
/**
*
*/
private String remark;
}

View File

@ -0,0 +1,47 @@
package com.fjrcloud.community.module.community.dal.dataobject.activity;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fjrcloud.community.framework.mybatis.core.dataobject.BaseDO;
import com.fjrcloud.community.framework.tenant.core.aop.TenantIgnore;
import lombok.*;
/**
* DO
*
* @author fjrcloud
*/
@TableName("comm_activity_scope")
@KeySequence("comm_activity_scope_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TenantIgnore
public class ActivityScopeDO extends BaseDO {
/**
*
*/
@TableId
private Long id;
/**
* ID
*/
private Long activityId;
/**
* ID
*/
private Long communityId;
/**
*
*/
private String communityName;
}

View File

@ -0,0 +1,124 @@
package com.fjrcloud.community.module.community.dal.dataobject.activity;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fjrcloud.community.framework.mybatis.core.dataobject.BaseDO;
import com.fjrcloud.community.framework.tenant.core.aop.TenantIgnore;
import lombok.*;
import java.time.LocalDateTime;
/**
* DO
*
* @author fjrcloud
*/
@TableName("comm_activity")
@KeySequence("comm_activity_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TenantIgnore
public class CommunityActivityDO extends BaseDO {
/**
*
*/
@TableId
private Long id;
/**
*
*/
private String title;
/**
*
*/
private String content;
/**
* URL
*/
private String coverImage;
/**
* URLJSON
*/
private String bannerImages;
/**
* JSON1-2-3-...
*/
private String serviceCategories;
/**
* JSON1-2-3-...
*/
private String serviceTargets;
/**
*
*/
private LocalDateTime registrationStartTime;
/**
*
*/
private LocalDateTime registrationEndTime;
/**
*
*/
private LocalDateTime activityStartTime;
/**
*
*/
private LocalDateTime activityEndTime;
/**
*
*/
private String location;
/**
*
*/
private Integer maxParticipants;
/**
*
*/
private String contactPerson;
/**
*
*/
private String contactPhone;
/**
*
*/
private Integer currentParticipants;
/**
* 0-稿1-2-3-4-
*/
private Integer status;
/**
*
*/
private Integer viewCount;
/**
* 0-1-
*/
private Boolean isDisplay;
}

View File

@ -0,0 +1,46 @@
package com.fjrcloud.community.module.community.dal.mysql.activity;
import com.fjrcloud.community.framework.common.pojo.PageParam;
import com.fjrcloud.community.framework.common.pojo.PageResult;
import com.fjrcloud.community.framework.mybatis.core.mapper.BaseMapperX;
import com.fjrcloud.community.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.fjrcloud.community.module.community.dal.dataobject.activity.ActivityRegistrationDO;
import org.apache.ibatis.annotations.Mapper;
/**
* Mapper
*
* @author fjrcloud
*/
@Mapper
public interface ActivityRegistrationMapper extends BaseMapperX<ActivityRegistrationDO> {
/**
* IDID
*
* @param memberId ID
* @param activityId ID
* @return
*/
default Long selectCountByMemberIdAndActivityId(Long memberId, Long activityId) {
return selectCount(new LambdaQueryWrapperX<ActivityRegistrationDO>()
.eq(ActivityRegistrationDO::getMemberId, memberId)
.eq(ActivityRegistrationDO::getActivityId, activityId)
.ne(ActivityRegistrationDO::getStatus, 3));
}
/**
* ID
*
* @param memberId ID
* @param pageParam
* @return
*/
default PageResult<ActivityRegistrationDO> selectPageByMemberId(Long memberId, PageParam pageParam) {
return selectPage(pageParam, new LambdaQueryWrapperX<ActivityRegistrationDO>()
.eq(ActivityRegistrationDO::getMemberId, memberId)
.ne(ActivityRegistrationDO::getStatus, 3)
.orderByDesc(ActivityRegistrationDO::getRegistrationTime));
}
}

View File

@ -0,0 +1,86 @@
package com.fjrcloud.community.module.community.dal.mysql.activity;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fjrcloud.community.framework.mybatis.core.mapper.BaseMapperX;
import com.fjrcloud.community.module.community.dal.dataobject.activity.ActivityScopeDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.ArrayList;
import java.util.List;
/**
* Mapper
*
* @author fjrcloud
*/
@Mapper
public interface ActivityScopeMapper extends BaseMapperX<ActivityScopeDO> {
/**
* ID
*
* @param activityId ID
* @return
*/
default List<ActivityScopeDO> selectListByActivityId(Long activityId) {
return selectList(ActivityScopeDO::getActivityId, activityId);
}
/**
* ID
*
* @param activityId ID
* @return
*/
default int deleteByActivityId(Long activityId) {
List<ActivityScopeDO> list = selectList(ActivityScopeDO::getActivityId, activityId);
if (list == null || list.isEmpty()) {
return 0;
}
int count = 0;
for (ActivityScopeDO scope : list) {
count += deleteAbsoluteById(scope.getId());
}
return count;
}
/**
*
*
* @param activityId ID
* @param communityIds ID
* @param communityNames
*/
default void insertBatch(@Param("activityId") Long activityId,
@Param("communityIds") List<Long> communityIds,
@Param("communityNames") List<String> communityNames) {
List<ActivityScopeDO> list = new java.util.ArrayList<>();
for (int i = 0; i < communityIds.size(); i++) {
ActivityScopeDO scopeDO = new ActivityScopeDO();
scopeDO.setActivityId(activityId);
scopeDO.setCommunityId(communityIds.get(i));
if (communityNames != null && i < communityNames.size()) {
scopeDO.setCommunityName(communityNames.get(i));
}
list.add(scopeDO);
}
insertBatch(list);
}
/**
* ID
*
* @param activityIds ID
* @return
*/
default List<ActivityScopeDO> selectListByActivityIds(List<Long> activityIds) {
if (activityIds == null || activityIds.isEmpty()) {
return new ArrayList<>();
}
return selectList(new LambdaQueryWrapper<ActivityScopeDO>()
.in(ActivityScopeDO::getActivityId, activityIds));
}
}

View File

@ -0,0 +1,36 @@
package com.fjrcloud.community.module.community.dal.mysql.activity;
import com.fjrcloud.community.framework.common.pojo.PageResult;
import com.fjrcloud.community.framework.mybatis.core.mapper.BaseMapperX;
import com.fjrcloud.community.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.fjrcloud.community.module.community.controller.admin.activity.vo.ActivityPageReqVO;
import com.fjrcloud.community.module.community.dal.dataobject.activity.CommunityActivityDO;
import org.apache.ibatis.annotations.Mapper;
/**
* Mapper
*
* @author fjrcloud
*/
@Mapper
public interface CommunityActivityMapper extends BaseMapperX<CommunityActivityDO> {
/**
*
*
* @param reqVO
* @return
*/
default PageResult<CommunityActivityDO> selectPage(ActivityPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<CommunityActivityDO>()
.likeIfPresent(CommunityActivityDO::getTitle, reqVO.getTitle())
.eqIfPresent(CommunityActivityDO::getStatus, reqVO.getStatus())
.betweenIfPresent(CommunityActivityDO::getActivityStartTime, reqVO.getActivityStartTime())
.eqIfPresent(CommunityActivityDO::getIsDisplay, reqVO.getIsDisplay())
.apply(reqVO.getCommunityId() != null,
"EXISTS (SELECT 1 FROM comm_activity_scope WHERE activity_id = comm_activity.id AND community_id = {0})",
reqVO.getCommunityId())
.orderByDesc(CommunityActivityDO::getCreateTime));
}
}

View File

@ -49,5 +49,16 @@ public interface ErrorCodeConstants {
ErrorCode KNOWLEDGE_ALREADY_LIKED = new ErrorCode(2_006_000_001, "已经点赞过了");
ErrorCode KNOWLEDGE_NOT_LIKED = new ErrorCode(2_006_000_002, "还未点赞");
// ========== 小区活动 1-005-000-000 ==========
ErrorCode ACTIVITY_NOT_EXISTS = new ErrorCode(1_002_001_001, "活动不存在");
ErrorCode ACTIVITY_STATUS_ERROR = new ErrorCode(1_002_001_002, "活动状态不正确");
ErrorCode ACTIVITY_STATUS_NOT_REGISTRATION = new ErrorCode(1_002_001_003, "活动不在报名中");
ErrorCode ACTIVITY_REGISTRATION_NOT_STARTED = new ErrorCode(1_002_001_004, "活动报名未开始");
ErrorCode ACTIVITY_REGISTRATION_ENDED = new ErrorCode(1_002_001_005, "活动报名已结束");
ErrorCode ACTIVITY_ALREADY_REGISTERED = new ErrorCode(1_002_001_006, "您已报名该活动");
ErrorCode ACTIVITY_PARTICIPANTS_FULL = new ErrorCode(1_002_001_007, "活动报名人数已满");
ErrorCode ACTIVITY_REGISTRATION_NOT_EXISTS = new ErrorCode(1_002_001_008, "报名记录不存在");
ErrorCode ACTIVITY_REGISTRATION_NOT_OWNER = new ErrorCode(1_002_001_009, "无权操作该报名记录");
ErrorCode ACTIVITY_REGISTRATION_STATUS_ERROR = new ErrorCode(1_002_001_010, "报名状态不允许取消");
}

View File

@ -0,0 +1,121 @@
package com.fjrcloud.community.module.community.service.activity;
import com.fjrcloud.community.framework.common.pojo.PageParam;
import com.fjrcloud.community.framework.common.pojo.PageResult;
import com.fjrcloud.community.module.community.controller.admin.activity.vo.ActivityPageReqVO;
import com.fjrcloud.community.module.community.controller.admin.activity.vo.ActivitySaveReqVO;
import com.fjrcloud.community.module.community.controller.app.activity.vo.AppActivityRegistrationRespVO;
import com.fjrcloud.community.module.community.dal.dataobject.activity.CommunityActivityDO;
import javax.validation.Valid;
import java.util.List;
/**
* Service
*
* @author fjrcloud
*/
public interface CommunityActivityService {
/**
*
*
* @param createReqVO
* @return
*/
Long createActivity(@Valid ActivitySaveReqVO createReqVO);
/**
*
*
* @param updateReqVO
*/
void updateActivity(@Valid ActivitySaveReqVO updateReqVO);
/**
*
*
* @param id
*/
void deleteActivity(Long id);
/**
*
*
* @param ids
*/
void deleteActivityListByIds(List<Long> ids);
/**
*
*
* @param id
* @return
*/
CommunityActivityDO getActivity(Long id);
/**
*
*
* @param pageReqVO
* @return
*/
PageResult<CommunityActivityDO> getActivityPage(ActivityPageReqVO pageReqVO);
/**
*
*
* @param id ID
*/
void publishActivity(Long id);
/**
*
*
* @param id ID
*/
void unpublishActivity(Long id);
/**
*
*
* @param id ID
*/
void incrementViewCount(Long id);
/**
*
*
* @param memberId ID
* @param activityId ID
* @param remark
*/
void registerActivity(Long memberId, Long activityId, String remark);
/**
*
*
* @param memberId ID
* @param pageParam
* @return
*/
PageResult<AppActivityRegistrationRespVO> getMyRegistrationPage(Long memberId, PageParam pageParam);
/**
*
*
* @param memberId ID
* @param registrationId ID
*/
void cancelRegistration(Long memberId, Long registrationId);
/**
*
*
* @param memberId ID
* @param activityId ID
* @return
*/
boolean isUserRegistered(Long memberId, Long activityId);
}

View File

@ -0,0 +1,364 @@
package com.fjrcloud.community.module.community.service.activity;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.fjrcloud.community.framework.common.pojo.PageParam;
import com.fjrcloud.community.framework.common.pojo.PageResult;
import com.fjrcloud.community.framework.common.util.json.JsonUtils;
import com.fjrcloud.community.framework.common.util.object.BeanUtils;
import com.fjrcloud.community.framework.tenant.core.context.TenantContextHolder;
import com.fjrcloud.community.framework.tenant.core.util.TenantUtils;
import com.fjrcloud.community.module.community.controller.admin.activity.vo.ActivityPageReqVO;
import com.fjrcloud.community.module.community.controller.admin.activity.vo.ActivitySaveReqVO;
import com.fjrcloud.community.module.community.controller.app.activity.vo.AppActivityRegistrationRespVO;
import com.fjrcloud.community.module.community.dal.dataobject.activity.ActivityRegistrationDO;
import com.fjrcloud.community.module.community.dal.dataobject.activity.CommunityActivityDO;
import com.fjrcloud.community.module.community.dal.dataobject.community.CommunityDO;
import com.fjrcloud.community.module.community.dal.mysql.activity.ActivityRegistrationMapper;
import com.fjrcloud.community.module.community.dal.mysql.activity.ActivityScopeMapper;
import com.fjrcloud.community.module.community.dal.mysql.activity.CommunityActivityMapper;
import com.fjrcloud.community.module.community.service.community.CommunityService;
import com.fjrcloud.community.module.member.api.user.MemberUserApi;
import com.fjrcloud.community.module.member.api.user.dto.MemberUserRespDTO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static com.fjrcloud.community.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.fjrcloud.community.framework.tenant.core.security.TenantSecurityWebFilter.SYSTEM_TENANT_ID;
import static com.fjrcloud.community.module.community.enums.ErrorCodeConstants.*;
import static com.fjrcloud.community.module.member.enums.ErrorCodeConstants.USER_NOT_EXISTS;
/**
* Service
*
* @author fjrcloud
*/
@Service
@Validated
public class CommunityActivityServiceImpl implements CommunityActivityService {
@Resource
private CommunityActivityMapper communityActivityMapper;
@Resource
private ActivityRegistrationMapper activityRegistrationMapper;
@Resource
private ActivityScopeMapper activityScopeMapper;
@Resource
private CommunityService communityService;
@Resource
private MemberUserApi memberUserApi;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createActivity(ActivitySaveReqVO createReqVO) {
// 插入活动
CommunityActivityDO activity = BeanUtils.toBean(createReqVO, CommunityActivityDO.class);
activity.setBannerImages(JsonUtils.toJsonString(createReqVO.getBannerImages()));
activity.setServiceCategories(JsonUtils.toJsonString(createReqVO.getServiceCategories()));
activity.setServiceTargets(JsonUtils.toJsonString(createReqVO.getServiceTargets()));
activity.setStatus(0);
activity.setViewCount(0);
activity.setCurrentParticipants(0);
activity.setIsDisplay(false);
communityActivityMapper.insert(activity);
// 插入活动小区关联
insertActivityScope(activity.getId(), createReqVO.getCommunityIds());
// 返回
return activity.getId();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateActivity(ActivitySaveReqVO updateReqVO) {
// 校验存在
validateActivityExists(updateReqVO.getId());
// 更新活动
CommunityActivityDO updateObj = BeanUtils.toBean(updateReqVO, CommunityActivityDO.class);
updateObj.setBannerImages(JsonUtils.toJsonString(updateReqVO.getBannerImages()));
updateObj.setServiceCategories(JsonUtils.toJsonString(updateReqVO.getServiceCategories()));
updateObj.setServiceTargets(JsonUtils.toJsonString(updateReqVO.getServiceTargets()));
communityActivityMapper.updateById(updateObj);
// 更新活动小区关联
activityScopeMapper.deleteByActivityId(updateReqVO.getId());
insertActivityScope(updateReqVO.getId(), updateReqVO.getCommunityIds());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteActivity(Long id) {
// 校验存在
validateActivityExists(id);
// 删除活动小区关联
activityScopeMapper.deleteByActivityId(id);
// 删除活动
communityActivityMapper.deleteById(id);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteActivityListByIds(List<Long> ids) {
// 删除活动小区关联
for (Long id : ids) {
activityScopeMapper.deleteByActivityId(id);
}
// 删除活动
communityActivityMapper.deleteByIds(ids);
}
@Override
public CommunityActivityDO getActivity(Long id) {
return communityActivityMapper.selectById(id);
}
@Override
public PageResult<CommunityActivityDO> getActivityPage(ActivityPageReqVO pageReqVO) {
// 获取当前租户ID
Long tenantId = TenantContextHolder.getTenantId();
// 如果没有指定小区ID则根据租户类型确定
if (pageReqVO.getCommunityId() == null) {
// 超级管理员租户查询所有活动,忽略租户隔离
if (SYSTEM_TENANT_ID.equals(tenantId)) {
return TenantUtils.executeIgnore(() -> communityActivityMapper.selectPage(pageReqVO));
}
// 普通租户租户ID即小区ID
pageReqVO.setCommunityId(tenantId);
}
// 使用 EXISTS 子查询
return communityActivityMapper.selectPage(pageReqVO);
}
@Override
public void publishActivity(Long id) {
// 校验存在
CommunityActivityDO activity = validateActivityExists(id);
// 校验状态
if (activity.getStatus() != 0) {
throw exception(ACTIVITY_STATUS_ERROR);
}
// 更新状态为报名中
CommunityActivityDO updateObj = new CommunityActivityDO();
updateObj.setId(id);
updateObj.setStatus(1);
updateObj.setIsDisplay(true);
communityActivityMapper.updateById(updateObj);
}
@Override
public void unpublishActivity(Long id) {
// 校验存在
CommunityActivityDO activity = validateActivityExists(id);
// 更新状态为草稿
CommunityActivityDO updateObj = new CommunityActivityDO();
updateObj.setId(id);
updateObj.setStatus(0);
updateObj.setIsDisplay(false);
communityActivityMapper.updateById(updateObj);
}
@Override
public void incrementViewCount(Long id) {
CommunityActivityDO activity = communityActivityMapper.selectById(id);
if (activity != null) {
CommunityActivityDO updateObj = new CommunityActivityDO();
updateObj.setId(id);
updateObj.setViewCount(activity.getViewCount() + 1);
communityActivityMapper.updateById(updateObj);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void registerActivity(Long memberId, Long activityId, String remark) {
// 校验活动是否存在
CommunityActivityDO activity = validateActivityExists(activityId);
// 校验活动状态是否为报名中
if (activity.getStatus() != 1) {
throw exception(ACTIVITY_STATUS_NOT_REGISTRATION);
}
// 校验是否已过报名时间
LocalDateTime now = LocalDateTime.now();
if (now.isBefore(activity.getRegistrationStartTime())) {
throw exception(ACTIVITY_REGISTRATION_NOT_STARTED);
}
if (now.isAfter(activity.getRegistrationEndTime())) {
throw exception(ACTIVITY_REGISTRATION_ENDED);
}
// 校验是否已报名
Long count = activityRegistrationMapper.selectCountByMemberIdAndActivityId(memberId, activityId);
if (count > 0) {
throw exception(ACTIVITY_ALREADY_REGISTERED);
}
// 校验人数上限
if (activity.getMaxParticipants() != null && activity.getCurrentParticipants() >= activity.getMaxParticipants()) {
throw exception(ACTIVITY_PARTICIPANTS_FULL);
}
// 获取会员信息
MemberUserRespDTO memberUser = memberUserApi.getUser(memberId);
if (memberUser == null) {
throw exception(USER_NOT_EXISTS);
}
// 创建报名记录
ActivityRegistrationDO registration = ActivityRegistrationDO.builder()
.activityId(activityId)
.memberId(memberId)
.memberName(memberUser.getNickname())
.memberPhone(memberUser.getMobile())
.registrationTime(LocalDateTime.now())
.status(0)
.remark(remark)
.build();
activityRegistrationMapper.insert(registration);
// 更新活动当前报名人数
CommunityActivityDO updateObj = new CommunityActivityDO();
updateObj.setId(activityId);
updateObj.setCurrentParticipants(activity.getCurrentParticipants() + 1);
communityActivityMapper.updateById(updateObj);
}
@Override
public PageResult<AppActivityRegistrationRespVO> getMyRegistrationPage(Long memberId, PageParam pageParam) {
// 查询报名记录分页
PageResult<ActivityRegistrationDO> pageResult = activityRegistrationMapper.selectPageByMemberId(memberId, pageParam);
if (CollUtil.isEmpty(pageResult.getList())) {
return PageResult.empty(pageResult.getTotal());
}
// 转换为响应VO
PageResult<AppActivityRegistrationRespVO> respVOPageResult = BeanUtils.toBean(pageResult, AppActivityRegistrationRespVO.class);
// 批量查询活动信息
List<Long> activityIds = pageResult.getList().stream()
.map(ActivityRegistrationDO::getActivityId)
.collect(Collectors.toList());
List<CommunityActivityDO> activities = communityActivityMapper.selectByIds(activityIds);
Map<Long, CommunityActivityDO> activityMap = activities.stream()
.collect(Collectors.toMap(CommunityActivityDO::getId, activity -> activity));
// 填充活动标题和封面
for (int i = 0; i < respVOPageResult.getList().size(); i++) {
AppActivityRegistrationRespVO respVO = respVOPageResult.getList().get(i);
ActivityRegistrationDO registration = pageResult.getList().get(i);
CommunityActivityDO activity = activityMap.get(registration.getActivityId());
if (activity != null) {
respVO.setActivityTitle(activity.getTitle());
respVO.setActivityCoverImage(activity.getCoverImage());
}
}
return respVOPageResult;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void cancelRegistration(Long memberId, Long registrationId) {
// 查询报名记录
ActivityRegistrationDO registration = activityRegistrationMapper.selectById(registrationId);
if (registration == null) {
throw exception(ACTIVITY_REGISTRATION_NOT_EXISTS);
}
// 校验是否为本人报名
if (!registration.getMemberId().equals(memberId)) {
throw exception(ACTIVITY_REGISTRATION_NOT_OWNER);
}
// 校验报名状态,只有待审核和已通过的可以取消
if (registration.getStatus() != 0 && registration.getStatus() != 1) {
throw exception(ACTIVITY_REGISTRATION_STATUS_ERROR);
}
// 更新报名状态为已取消
ActivityRegistrationDO updateObj = new ActivityRegistrationDO();
updateObj.setId(registrationId);
updateObj.setStatus(3);
activityRegistrationMapper.updateById(updateObj);
// 减少活动当前报名人数
CommunityActivityDO activity = communityActivityMapper.selectById(registration.getActivityId());
if (activity != null && activity.getCurrentParticipants() > 0) {
CommunityActivityDO activityUpdateObj = new CommunityActivityDO();
activityUpdateObj.setId(registration.getActivityId());
activityUpdateObj.setCurrentParticipants(activity.getCurrentParticipants() - 1);
communityActivityMapper.updateById(activityUpdateObj);
}
}
@Override
public boolean isUserRegistered(Long memberId, Long activityId) {
Long count = activityRegistrationMapper.selectCountByMemberIdAndActivityId(memberId, activityId);
return count != null && count > 0;
}
/**
*
*
* @param activityId ID
* @param communityIds ID
*/
private void insertActivityScope(Long activityId, List<Long> communityIds) {
if (CollUtil.isEmpty(communityIds)) {
return;
}
// 获取小区名称
List<String> communityNames = communityIds.stream()
.map(communityId -> {
try {
CommunityDO community = communityService.getCommunity(communityId);
return community != null ? community.getCommunityName() : null;
} catch (Exception e) {
return null;
}
})
.filter(StrUtil::isNotBlank)
.collect(Collectors.toList());
// 批量插入
activityScopeMapper.insertBatch(activityId, communityIds, communityNames);
}
/**
*
*
* @param id ID
* @return
*/
private CommunityActivityDO validateActivityExists(Long id) {
CommunityActivityDO activity = communityActivityMapper.selectById(id);
if (activity == null) {
throw exception(ACTIVITY_NOT_EXISTS);
}
return activity;
}
}