feat:后台页面

This commit is contained in:
dzc committed 2025-11-24 15:03:08 +08:00
1 parent 0afb7b724b
commit 326096430a
12 files changed
+200 -37

No files matched your search

@@ -81,8 +81,8 @@ public class OperationController {
@Operation(summary = "获得朋友圈操作分页")
@PreAuthorize("@ss.hasPermission('member:operation:query')")
public CommonResult<PageResult<OperationRespVO>> getOperationPage(@Valid OperationPageReqVO pageReqVO) {
PageResult<OperationDO> pageResult = operationService.getOperationPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, OperationRespVO.class));
PageResult<OperationRespVO> pageResult = operationService.getOperationPage(pageReqVO);
return success(pageResult);
}
@GetMapping("/export-excel")
@@ -91,9 +91,9 @@ public class OperationController {
@ApiAccessLog(operateType = EXPORT)
public void exportOperationExcel(@Valid OperationPageReqVO pageReqVO, HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<OperationDO> list = operationService.getOperationPage(pageReqVO).getList();
List<OperationRespVO> list = operationService.getOperationPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "朋友圈操作.xls", "数据", OperationRespVO.class, BeanUtils.toBean(list, OperationRespVO.class));
ExcelUtils.write(response, "朋友圈操作.xls", "数据", OperationRespVO.class, list);
}
}
@@ -1,10 +1,14 @@
package cn.iocoder.yudao.module.member.controller.admin.recent.vo;
import cn.iocoder.yudao.module.member.enums.MemberRecentOperateEnum;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -15,15 +19,24 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
@ToString(callSuper = true)
public class OperationPageReqVO extends PageParam {
@Schema(description = "用户编号", example = "31854")
@Schema(description = "用户编号")
private Long memberId;
@Schema(description = "朋友圈编号", example = "29447")
@Schema(description = "朋友圈编号")
private Long memberRecentId;
@Schema(description = "点赞、屏蔽、举报", example = "2")
@Schema(description = "朋友圈编号")
private List<Long> memberRecentIds;
/**
* @see MemberRecentOperateEnum
*/
@Schema(description = "点赞、屏蔽、举报")
private String bizType;
@Schema(description = "点赞、屏蔽、举报")
private List<String> bizTypes;
@Schema(description = "点击时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] tapTime;
@@ -32,7 +45,7 @@ public class OperationPageReqVO extends PageParam {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] cancelTime;
@Schema(description = "举报类型", example = "2")
@Schema(description = "举报类型")
private String reportType;
@Schema(description = "身材评分")
@@ -16,19 +16,30 @@ import com.alibaba.excel.annotation.*;
@ExcelIgnoreUnannotated
public class OperationRespVO {
@Schema(description = "收件地址编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11909")
@Schema(description = "收件地址编号", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("收件地址编号")
private Long id;
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31854")
@ExcelProperty("用户编号")
@Schema(description = "操作用户编号", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("操作用户编号")
private Long operatorMemberId;
@Schema(description = "操作时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("操作用户昵称")
private String operatorMemberNickname;
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("朋友圈用户编号")
private Long memberId;
@Schema(description = "朋友圈编号", example = "29447")
@Schema(description = "朋友圈用户昵称", requiredMode = Schema.RequiredMode.REQUIRED)
private String memberNickname;
@Schema(description = "朋友圈编号")
@ExcelProperty("朋友圈编号")
private Long memberRecentId;
@Schema(description = "点赞、屏蔽、举报", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@Schema(description = "点赞、屏蔽、举报", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("点赞、屏蔽、举报")
private String bizType;
@@ -40,7 +51,7 @@ public class OperationRespVO {
@ExcelProperty("取消时间")
private LocalDateTime cancelTime;
@Schema(description = "举报类型", example = "2")
@Schema(description = "举报类型")
@ExcelProperty("举报类型")
private String reportType;
@@ -0,0 +1,27 @@
package cn.iocoder.yudao.module.member.controller.admin.recent.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "朋友圈统计 Request VO")
@Data
public class OperationTotalGroupRecentRespVO {
@Schema(description = "朋友圈id")
private Long memberRecentId;
@Schema(description = "操作类型")
private String bizType;
@Schema(description = "朋友圈点赞总数")
private Integer likeTotal = 0;
@Schema(description = "朋友圈举报总数")
private Integer reportTotal = 0;
@Schema(description = "朋友圈屏蔽总数")
private Integer shieldTotal = 0;
@Schema(description = "收藏总数")
private Integer collectTotal = 0;
}
@@ -16,12 +16,18 @@ public class RecentPageResVo extends RecentDO {
@Schema(description = "距离相关")
private LocationVo location;
@Schema(description = "操作统计相关")
private OperationTotal operationTotal;
@Data
public static class MemberVo {
@Schema(description = "用户编号")
private Long memberId;
@Schema(description = "用户性别")
private Integer memberSex;
@Schema(description = "用户头像")
private String memberAvatar;
@@ -49,6 +55,22 @@ public class RecentPageResVo extends RecentDO {
@Schema(description = "距离(千米)")
private Double distance;
}
@Data
public static class OperationTotal {
@Schema(description = "朋友圈点赞总数")
private Integer recentLikeTotal = 0;
@Schema(description = "朋友圈举报总数")
private Integer recentReportTotal = 0;
@Schema(description = "朋友圈屏蔽总数")
private Integer recentShieldTotal = 0;
@Schema(description = "朋友圈收藏总数")
private Integer recentCollectTotal = 0;
}
@@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.module.member.dal.dataobject.feedback.FeedbackDO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.member.controller.admin.feedback.vo.*;
@@ -19,14 +20,18 @@ import cn.iocoder.yudao.module.member.controller.admin.feedback.vo.*;
public interface FeedbackMapper extends BaseMapperX<FeedbackDO> {
default PageResult<FeedbackRespVO> selectPage(FeedbackPageReqVO reqVO) {
return selectJoinPage(reqVO, FeedbackRespVO.class, new MPJLambdaWrapperX<FeedbackDO>()
MPJLambdaWrapper<FeedbackDO> queryWrapper = new MPJLambdaWrapperX<FeedbackDO>()
.selectAll(FeedbackDO.class)
.selectAs(MemberUserDO::getNickname, FeedbackPageReqVO::getMemberName)
.leftJoin(MemberUserDO.class, MemberUserDO::getId, FeedbackDO::getMemberId)
.eqIfExists(FeedbackDO::getMemberId, reqVO.getMemberId())
.likeIfExists(FeedbackDO::getContent, reqVO.getContent())
.between(ObjectUtil.isNotEmpty(reqVO.getCreateTime()), FeedbackDO::getCreateTime, reqVO.getCreateTime()[0], reqVO.getCreateTime()[1])
.orderByDesc(FeedbackDO::getId));
.likeIfExists(MemberUserDO::getNickname, reqVO.getMemberName());
if (ObjectUtil.isNotEmpty(reqVO.getCreateTime())) {
queryWrapper.between(FeedbackDO::getCreateTime, reqVO.getCreateTime()[0], reqVO.getCreateTime()[1]);
}
queryWrapper.orderByDesc(FeedbackDO::getId);
return selectJoinPage(reqVO, FeedbackRespVO.class, queryWrapper);
}
}
@@ -2,35 +2,45 @@ package cn.iocoder.yudao.module.member.dal.mysql.recent;
import java.util.*;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.module.member.controller.admin.recent.vo.OperationPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.recent.vo.OperationRespVO;
import cn.iocoder.yudao.module.member.controller.admin.recent.vo.OperationTotalGroupRecentRespVO;
import cn.iocoder.yudao.module.member.controller.admin.recent.vo.RecentPageReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.recent.OperationDO;
import cn.iocoder.yudao.module.member.dal.dataobject.recent.RecentDO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* 朋友圈操作 Mapper
*
* @author 聊天交友
*/
@Mapper
public interface OperationMapper extends BaseMapperX<OperationDO> {
default PageResult<OperationDO> selectPage(OperationPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<OperationDO>()
.eqIfPresent(OperationDO::getMemberId, reqVO.getMemberId())
.eqIfPresent(OperationDO::getMemberRecentId, reqVO.getMemberRecentId())
.eqIfPresent(OperationDO::getBizType, reqVO.getBizType())
.betweenIfPresent(OperationDO::getTapTime, reqVO.getTapTime())
.betweenIfPresent(OperationDO::getCancelTime, reqVO.getCancelTime())
.eqIfPresent(OperationDO::getReportType, reqVO.getReportType())
.eqIfPresent(OperationDO::getScoreSc, reqVO.getScoreSc())
.eqIfPresent(OperationDO::getScoreNx, reqVO.getScoreNx())
.eqIfPresent(OperationDO::getScoreSk, reqVO.getScoreSk())
.eqIfPresent(OperationDO::getScoreYq, reqVO.getScoreYq())
.betweenIfPresent(OperationDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(OperationDO::getId));
default PageResult<OperationRespVO> selectPage(OperationPageReqVO reqVO) {
MPJLambdaWrapper<OperationDO> queryWrapper = new MPJLambdaWrapperX<OperationDO>()
.selectAll(OperationDO.class)
.selectAs("member", MemberUserDO::getNickname, OperationRespVO::getMemberNickname)
.selectAs("operator_member", MemberUserDO::getNickname, OperationRespVO::getOperatorMemberNickname)
.leftJoin(MemberUserDO.class, "member", MemberUserDO::getId, OperationDO::getMemberId)
.leftJoin(MemberUserDO.class, "operator_member", MemberUserDO::getId, OperationDO::getOperatorMemberId)
.eqIfExists(OperationDO::getMemberId, reqVO.getMemberId())
.eqIfExists(OperationDO::getMemberRecentId, reqVO.getMemberRecentId())
.eqIfExists(OperationDO::getBizType, reqVO.getBizType())
.eqIfExists(OperationDO::getReportType, reqVO.getReportType());
if (ObjectUtil.isNotEmpty(reqVO.getCreateTime())) {
queryWrapper.between(OperationDO::getCreateTime, reqVO.getCreateTime()[0], reqVO.getCreateTime()[1]);
}
queryWrapper.orderByDesc(OperationDO::getId);
return selectJoinPage(reqVO, OperationRespVO.class, queryWrapper);
}
List<OperationTotalGroupRecentRespVO> totalGroupRecent(@Param("dto") OperationPageReqVO dto);
}
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.member.service.recent;
import javax.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.member.controller.admin.recent.vo.OperationPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.recent.vo.OperationRespVO;
import cn.iocoder.yudao.module.member.controller.admin.recent.vo.OperationSaveReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.recent.OperationDO;
@@ -49,6 +50,6 @@ public interface OperationService {
* @param pageReqVO 分页查询
* @return 朋友圈操作分页
*/
PageResult<OperationDO> getOperationPage(OperationPageReqVO pageReqVO);
PageResult<OperationRespVO> getOperationPage(OperationPageReqVO pageReqVO);
}
@@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.member.service.recent;
import cn.iocoder.yudao.module.member.controller.admin.recent.vo.OperationPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.recent.vo.OperationRespVO;
import cn.iocoder.yudao.module.member.controller.admin.recent.vo.OperationSaveReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.recent.OperationDO;
import cn.iocoder.yudao.module.member.dal.mysql.recent.OperationMapper;
@@ -65,7 +66,7 @@ public class OperationServiceImpl implements OperationService {
}
@Override
public PageResult<OperationDO> getOperationPage(OperationPageReqVO pageReqVO) {
public PageResult<OperationRespVO> getOperationPage(OperationPageReqVO pageReqVO) {
return operationMapper.selectPage(pageReqVO);
}
@@ -226,6 +226,8 @@ public class RecentServiceImpl implements RecentService {
List<RecentPageResVo> resultList = BeanUtils.toBean(recentPageList.getList(), RecentPageResVo.class);
// 为RecentPageResVo设置Member信息
convertRecentPageResVoSetupMember(resultList);
// 为RecentPageResVo设置OperationTotal信息
convertRecentPageResVoSetupOperationTotal(resultList, pageReqVO);
return new PageResult<>(resultList, recentPageList.getTotal());
}
@@ -384,12 +386,42 @@ public class RecentServiceImpl implements RecentService {
memberVO.setMemberOcc(member.getOcc());
memberVO.setMemberHeight(member.getHeight());
memberVO.setMemberWeight(member.getWeight());
memberVO.setMemberSex(member.getSex());
entity.setMember(memberVO);
}
}
}
}
/**
* 为RecentPageResVo设置OperationTotal信息
*/
private void convertRecentPageResVoSetupOperationTotal(List<RecentPageResVo> list, RecentPageReqVO query) {
if (ObjectUtil.isEmpty(list)) return;
List<Long> ids = list.stream().map(RecentPageResVo::getId).collect(Collectors.toList());
OperationPageReqVO operationTotalQuery = new OperationPageReqVO();
List<String> bizTypes = MemberRecentOperateEnum.userOperateList.stream().map(MemberRecentOperateEnum::getType).collect(Collectors.toList());
operationTotalQuery.setBizTypes(bizTypes);
operationTotalQuery.setMemberRecentIds(ids);
List<OperationTotalGroupRecentRespVO> totalList = operationMapper.totalGroupRecent(operationTotalQuery);
Map<Long, OperationTotalGroupRecentRespVO> totalMap = IterUtil.toMap(totalList, OperationTotalGroupRecentRespVO::getMemberRecentId);
for (RecentPageResVo entity : list) {
// 操作统计相关
OperationTotalGroupRecentRespVO total = totalMap.get(entity.getId());
if (ObjectUtil.isNotEmpty(total)) {
RecentPageResVo.OperationTotal operationTotal = new RecentPageResVo.OperationTotal();
operationTotal.setRecentLikeTotal(total.getLikeTotal());
operationTotal.setRecentReportTotal(total.getReportTotal());
operationTotal.setRecentShieldTotal(total.getShieldTotal());
operationTotal.setRecentCollectTotal(total.getCollectTotal());
entity.setOperationTotal(operationTotal);
} else {
entity.setOperationTotal(new RecentPageResVo.OperationTotal());
}
}
}
private void convertRecentPageResVoSetupMember(RecentPageResVo detail) {
if (ObjectUtil.isEmpty(detail)) return;
MemberUserDO member = memberUserService.getUser(detail.getMemberId());
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.member.dal.mysql.recent.OperationMapper">
<sql id="selectA">
a.deleted = 0
<if test="dto.memberRecentId != null">
and a.member_recent_id = #{dto.memberRecentId}
</if>
<if test="dto.memberRecentIds != null and dto.memberRecentIds.size() != 0">
and a.member_recent_id in
<foreach collection="dto.memberRecentIds" item="v" open="(" close=")" separator=",">
#{v}
</foreach>
</if>
<if test="dto.bizType != null">
and a.biz_type = #{dto.bizType}
</if>
<if test="dto.bizTypes != null and dto.bizTypes.size() != 0">
and a.biz_type in
<foreach collection="dto.bizTypes" item="v" open="(" close=")" separator=",">
#{v}
</foreach>
</if>
</sql>
<select id="totalGroupRecent"
resultType="cn.iocoder.yudao.module.member.controller.admin.recent.vo.OperationTotalGroupRecentRespVO">
select sum(if(a.biz_type = '1', 1, 0)) as likeTotal,
sum(if(a.biz_type = '2', 1, 0)) as reportTotal,
sum(if(a.biz_type = '3', 1, 0)) as shieldTotal,
sum(if(a.biz_type = '4', 1, 0)) as collectTotal,
a.biz_type as bizType,
a.member_recent_id as memberRecentId
from member_operation a
<where>
<include refid="selectA"/>
</where>
group by a.biz_type, a.member_recent_id
</select>
</mapper>
@@ -3,8 +3,8 @@ spring:
name: yudao-server
profiles:
active: prod
# active: local
# active: prod
active: local
main:
allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。