diff --git a/pom.xml b/pom.xml index 95aa142..d837a31 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ com.imyeyu.timiserverapi TimiServerAPI - 1.0.54 + 1.0.55 jar TimiServerAPI imyeyu.com API diff --git a/src/main/java/com/imyeyu/api/modules/gao/controller/GaoRoleController.java b/src/main/java/com/imyeyu/api/modules/gao/controller/GaoRoleController.java index 5cc71b6..ffb19c2 100644 --- a/src/main/java/com/imyeyu/api/modules/gao/controller/GaoRoleController.java +++ b/src/main/java/com/imyeyu/api/modules/gao/controller/GaoRoleController.java @@ -3,8 +3,13 @@ package com.imyeyu.api.modules.gao.controller; import com.imyeyu.api.annotation.RequireCorePermission; import com.imyeyu.api.bean.CorePermissionCode; import com.imyeyu.api.bean.ModuleCode; +import com.imyeyu.api.modules.gao.entity.GaoStore; +import com.imyeyu.api.modules.gao.service.GaoStoreService; +import com.imyeyu.api.modules.user.bean.AuthOwnerType; import com.imyeyu.api.modules.user.entity.Role; import com.imyeyu.api.modules.user.service.AuthorizationScopeService; +import com.imyeyu.api.modules.user.service.PermissionService; +import com.imyeyu.api.modules.user.service.RoleService; import com.imyeyu.api.modules.user.service.UserLoginService; import com.imyeyu.spring.annotation.AOPLog; import com.imyeyu.spring.annotation.RequestRateLimit; @@ -26,6 +31,9 @@ public class GaoRoleController { private final UserLoginService userLoginService; private final AuthorizationScopeService authorizationScopeService; + private final GaoStoreService gaoStoreService; + private final PermissionService permissionService; + private final RoleService roleService; @AOPLog @RequestRateLimit @@ -34,4 +42,40 @@ public class GaoRoleController { public List availableList() { return authorizationScopeService.listGrantableRole(userLoginService.getRequireLoginUserId(), ModuleCode.GAO); } + + /// 查询登录用户所属门店内可管理的角色 + /// + /// @return 门店角色列表 + @AOPLog + @RequestRateLimit + @RequireCorePermission(CorePermissionCode.ROLE_READ) + @PostMapping("/management/list") + public List managementList() { + String loginUserId = userLoginService.getRequireLoginUserId(); + GaoStore store = gaoStoreService.getByUserId(loginUserId); + if (store == null) { + return List.of(); + } + + List roleList = authorizationScopeService.listManageableRole(loginUserId, ModuleCode.GAO) + .stream() + .filter(role -> role.getOwnerType() == AuthOwnerType.STORE) + .filter(role -> store.getId().equals(role.getOwnerId())) + .toList(); + roleList.forEach(this::fillRoleDetail); + return roleList; + } + + /// 填充角色详情 + /// + /// @param role 角色 + private void fillRoleDetail(Role role) { + role.setPermissionList(permissionService.listByRoleId(role.getId())); + role.setAllPermissionList(roleService.listPermissionByRoleId(role.getId())); + role.setChildRoleList(roleService.listChildByParentRoleId(role.getId())); + if (role.getParentRoleId() != null) { + role.setParentRole(roleService.get(role.getParentRoleId())); + } + role.setDelegationPermissionList(roleService.listDelegationPermissionByRoleId(role.getId())); + } } diff --git a/src/main/java/com/imyeyu/api/modules/gao/controller/GaoStoreChartController.java b/src/main/java/com/imyeyu/api/modules/gao/controller/GaoStoreChartController.java index f8f32d9..f4539f9 100644 --- a/src/main/java/com/imyeyu/api/modules/gao/controller/GaoStoreChartController.java +++ b/src/main/java/com/imyeyu/api/modules/gao/controller/GaoStoreChartController.java @@ -2,6 +2,7 @@ package com.imyeyu.api.modules.gao.controller; import com.imyeyu.api.modules.gao.annotation.RequireGaoPermission; import com.imyeyu.api.modules.gao.bean.GaoPermissionCode; +import com.imyeyu.api.modules.gao.service.GaoPointChartService; import com.imyeyu.api.modules.gao.service.GaoStoreChartService; import com.imyeyu.api.modules.gao.service.GaoStoreScopeService; import com.imyeyu.api.modules.gao.vo.GaoCustomerAgeStatView; @@ -10,6 +11,8 @@ import com.imyeyu.api.modules.gao.vo.GaoCustomerGenderStatView; import com.imyeyu.api.modules.gao.vo.GaoEventRecordCalendarView; import com.imyeyu.api.modules.gao.vo.GaoEventRecordDailyStatView; import com.imyeyu.api.modules.gao.vo.GaoEventRecordNumberValueDailyStatView; +import com.imyeyu.api.modules.gao.vo.GaoPointDailyStatView; +import com.imyeyu.api.modules.gao.vo.GaoPointRedemptionProductRankView; import com.imyeyu.api.modules.gao.vo.GaoStoreChartReq; import com.imyeyu.java.bean.timi.TimiException; import com.imyeyu.spring.annotation.AOPLog; @@ -33,6 +36,7 @@ import java.util.List; public class GaoStoreChartController { private final GaoStoreChartService service; + private final GaoPointChartService pointChartService; private final GaoStoreScopeService storeScopeService; /// 查询客户增长趋势 @@ -96,4 +100,26 @@ public class GaoStoreChartController { req.setStoreId(storeScopeService.resolveStoreId(req.getStoreId())); return service.eventRecordCalendar(req); } + + /// 查询每日积分获得、消耗和差值 + @AOPLog + @RequestRateLimit + @RequireGaoPermission(GaoPermissionCode.STAT_READ) + @PostMapping("/point/ledger/daily") + public List pointDaily(@RequestBody GaoStoreChartReq req) { + TimiException.required(req, "积分图表请求不能为空"); + req.setStoreId(storeScopeService.resolveStoreId(req.getStoreId())); + return pointChartService.dailyTrend(req); + } + + /// 查询积分兑换产品排行 + @AOPLog + @RequestRateLimit + @RequireGaoPermission(GaoPermissionCode.STAT_READ) + @PostMapping("/point/redemption/product/rank") + public List pointRedemptionProductRank(@RequestBody GaoStoreChartReq req) { + TimiException.required(req, "积分兑换排行请求不能为空"); + req.setStoreId(storeScopeService.resolveStoreId(req.getStoreId())); + return pointChartService.redemptionProductRank(req); + } } diff --git a/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoPointChartMapper.java b/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoPointChartMapper.java new file mode 100644 index 0000000..3749beb --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/gao/mapper/GaoPointChartMapper.java @@ -0,0 +1,20 @@ +package com.imyeyu.api.modules.gao.mapper; + +import com.imyeyu.api.modules.gao.vo.GaoPointDailyStatView; +import com.imyeyu.api.modules.gao.vo.GaoPointRedemptionProductRankView; +import com.imyeyu.api.modules.gao.vo.GaoStoreChartReq; + +import java.util.List; + +/// 门店积分图表统计 Mapper +/// +/// @author Codex +/// @since 2026-09-23 +public interface GaoPointChartMapper { + + /// 按天汇总积分获得和消耗 + List selectDailyTrend(GaoStoreChartReq req); + + /// 按产品汇总兑换积分并取前 10 + List selectRedemptionProductRank(GaoStoreChartReq req); +} diff --git a/src/main/java/com/imyeyu/api/modules/gao/service/GaoPointChartService.java b/src/main/java/com/imyeyu/api/modules/gao/service/GaoPointChartService.java new file mode 100644 index 0000000..e356094 --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/gao/service/GaoPointChartService.java @@ -0,0 +1,20 @@ +package com.imyeyu.api.modules.gao.service; + +import com.imyeyu.api.modules.gao.vo.GaoPointDailyStatView; +import com.imyeyu.api.modules.gao.vo.GaoPointRedemptionProductRankView; +import com.imyeyu.api.modules.gao.vo.GaoStoreChartReq; + +import java.util.List; + +/// 门店积分图表统计服务 +/// +/// @author Codex +/// @since 2026-09-23 +public interface GaoPointChartService { + + /// 查询每日积分获得、消耗和差值 + List dailyTrend(GaoStoreChartReq req); + + /// 查询积分兑换产品排行,按实际扣除积分取前 10 + List redemptionProductRank(GaoStoreChartReq req); +} diff --git a/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoPointChartServiceImplement.java b/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoPointChartServiceImplement.java new file mode 100644 index 0000000..d5ececc --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/gao/service/implement/GaoPointChartServiceImplement.java @@ -0,0 +1,43 @@ +package com.imyeyu.api.modules.gao.service.implement; + +import com.imyeyu.api.modules.gao.mapper.GaoPointChartMapper; +import com.imyeyu.api.modules.gao.service.GaoPointChartService; +import com.imyeyu.api.modules.gao.vo.GaoPointDailyStatView; +import com.imyeyu.api.modules.gao.vo.GaoPointRedemptionProductRankView; +import com.imyeyu.api.modules.gao.vo.GaoStoreChartReq; +import com.imyeyu.java.bean.timi.TimiException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +/// 门店积分图表统计服务实现 +/// +/// @author Codex +/// @since 2026-09-23 +@Service +@RequiredArgsConstructor +public class GaoPointChartServiceImplement implements GaoPointChartService { + + private final GaoPointChartMapper mapper; + + @Override + public List dailyTrend(GaoStoreChartReq req) { + checkRangeReq(req); + return mapper.selectDailyTrend(req); + } + + @Override + public List redemptionProductRank(GaoStoreChartReq req) { + checkRangeReq(req); + return mapper.selectRedemptionProductRank(req); + } + + private void checkRangeReq(GaoStoreChartReq req) { + TimiException.required(req, "积分图表请求不能为空"); + TimiException.required(req.getStoreId(), "积分图表门店不能为空"); + TimiException.required(req.getBeginAt(), "积分图表开始时间不能为空"); + TimiException.required(req.getEndAt(), "积分图表结束时间不能为空"); + TimiException.requiredTrue(req.getBeginAt() <= req.getEndAt(), "积分图表结束时间早于开始时间"); + } +} diff --git a/src/main/java/com/imyeyu/api/modules/gao/vo/GaoPointDailyStatView.java b/src/main/java/com/imyeyu/api/modules/gao/vo/GaoPointDailyStatView.java new file mode 100644 index 0000000..fb8512a --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/gao/vo/GaoPointDailyStatView.java @@ -0,0 +1,23 @@ +package com.imyeyu.api.modules.gao.vo; + +import lombok.Data; + +/// 每日积分获得与消耗统计 +/// +/// @author Codex +/// @since 2026-09-23 +@Data +public class GaoPointDailyStatView { + + /// 日期值,格式为 yyyyMMdd + private Integer dateValue; + + /// 每日获得积分 + private Long earnedPoints; + + /// 每日消耗积分,以正数返回 + private Long consumedPoints; + + /// 获得积分减消耗积分 + private Long netChangePoints; +} diff --git a/src/main/java/com/imyeyu/api/modules/gao/vo/GaoPointRedemptionProductRankView.java b/src/main/java/com/imyeyu/api/modules/gao/vo/GaoPointRedemptionProductRankView.java new file mode 100644 index 0000000..4689a33 --- /dev/null +++ b/src/main/java/com/imyeyu/api/modules/gao/vo/GaoPointRedemptionProductRankView.java @@ -0,0 +1,23 @@ +package com.imyeyu.api.modules.gao.vo; + +import lombok.Data; + +/// 积分兑换产品排行统计 +/// +/// @author Codex +/// @since 2026-09-23 +@Data +public class GaoPointRedemptionProductRankView { + + /// 产品 ID + private String productId; + + /// 产品名称 + private String productName; + + /// 兑换单数 + private Long redemptionCount; + + /// 实际扣除积分合计,不扣除退回积分 + private Long pointCost; +} diff --git a/src/main/resources/mapper/timi-server/gao/GaoPointChartMapper.xml b/src/main/resources/mapper/timi-server/gao/GaoPointChartMapper.xml new file mode 100644 index 0000000..d1632ec --- /dev/null +++ b/src/main/resources/mapper/timi-server/gao/GaoPointChartMapper.xml @@ -0,0 +1,36 @@ + + + + + + +