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 @@
+
+
+
+
+
+
+