Commit bbba83ef61527b3bd0a094bb5381d6cce1558f61

Authored by YunaiV
1 parent eb048532

📖 MALL:code review 商品统计的代码

Showing 14 changed files with 77 additions and 147 deletions
sql/mysql/optinal/product_statistics.sql deleted
1 -CREATE TABLE product_statistics  
2 -(  
3 - id bigint AUTO_INCREMENT COMMENT '编号,主键自增' PRIMARY KEY,  
4 - time date NOT NULL COMMENT '统计日期',  
5 - spu_id bigint NOT NULL COMMENT '商品SPU编号',  
6 - browse_count int DEFAULT 0 NOT NULL COMMENT '浏览量',  
7 - browse_user_count int DEFAULT 0 NOT NULL COMMENT '访客量',  
8 - favorite_count int DEFAULT 0 NOT NULL COMMENT '收藏数量',  
9 - cart_count int DEFAULT 0 NOT NULL COMMENT '加购数量',  
10 - order_count int DEFAULT 0 NOT NULL COMMENT '下单件数',  
11 - order_pay_count int DEFAULT 0 NOT NULL COMMENT '支付件数',  
12 - order_pay_price int DEFAULT 0 NOT NULL COMMENT '支付金额,单位:分',  
13 - after_sale_count int DEFAULT 0 NOT NULL COMMENT '退款件数',  
14 - after_sale_refund_price int DEFAULT 0 NOT NULL COMMENT '退款金额,单位:分',  
15 - browse_convert_percent int DEFAULT 0 NOT NULL COMMENT '访客支付转化率(百分比)',  
16 - creator varchar(64) DEFAULT '' NULL COMMENT '创建者',  
17 - create_time datetime DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '创建时间',  
18 - updater varchar(64) DEFAULT '' NULL COMMENT '更新者',  
19 - update_time datetime DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',  
20 - deleted bit DEFAULT b'0' NOT NULL COMMENT '是否删除',  
21 - tenant_id bigint DEFAULT 0 NOT NULL COMMENT '租户编号'  
22 -)  
23 - COMMENT '商品统计表';  
24 -  
25 -CREATE INDEX idx_time  
26 - ON product_statistics (time);  
27 -  
28 -CREATE INDEX idx_spu_id  
29 - ON product_statistics (spu_id);  
30 -  
31 -INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted) VALUES ('商品统计', '', 2, 6, 2358, 'product', 'fa:product-hunt', 'statistics/product/index', 'ProductStatistics', 0, true, true, true, '', '2023-12-15 18:54:28', '', '2023-12-15 18:54:33', false);  
32 -SELECT @parentId1 := LAST_INSERT_ID();  
33 -INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted) VALUES ('商品统计查询', 'statistics:product:query', 3, 1, @parentId, '', '', '', null, 0, true, true, true, '', '2023-09-30 03:22:40', '', '2023-09-30 03:22:40', false);  
34 -INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted) VALUES ('商品统计导出', 'statistics:product:export', 3, 2, @parentId, '', '', '', null, 0, true, true, true, '', '2023-09-30 03:22:40', '', '2023-09-30 03:22:40', false);  
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/PageUtils.java
1 package cn.iocoder.yudao.framework.common.util.object; 1 package cn.iocoder.yudao.framework.common.util.object;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.lang.func.Func1;
  5 +import cn.hutool.core.lang.func.LambdaUtil;
  6 +import cn.hutool.core.util.ArrayUtil;
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 7 import cn.iocoder.yudao.framework.common.pojo.PageParam;
  8 +import cn.iocoder.yudao.framework.common.pojo.SortablePageParam;
  9 +import cn.iocoder.yudao.framework.common.pojo.SortingField;
  10 +import org.springframework.util.Assert;
  11 +
  12 +import java.util.List;
4 13
5 /** 14 /**
6 * {@link cn.iocoder.yudao.framework.common.pojo.PageParam} 工具类 15 * {@link cn.iocoder.yudao.framework.common.pojo.PageParam} 工具类
@@ -9,8 +18,50 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; @@ -9,8 +18,50 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
9 */ 18 */
10 public class PageUtils { 19 public class PageUtils {
11 20
  21 + private static final Object[] ORDER_TYPES = new String[]{SortingField.ORDER_ASC, SortingField.ORDER_DESC};
  22 +
12 public static int getStart(PageParam pageParam) { 23 public static int getStart(PageParam pageParam) {
13 return (pageParam.getPageNo() - 1) * pageParam.getPageSize(); 24 return (pageParam.getPageNo() - 1) * pageParam.getPageSize();
14 } 25 }
15 26
  27 + /**
  28 + * 构建排序字段(默认倒序)
  29 + *
  30 + * @param func 排序字段的 Lambda 表达式
  31 + * @param <T> 排序字段所属的类型
  32 + * @return 排序字段
  33 + */
  34 + public static <T> SortingField buildSortingField(Func1<T, ?> func) {
  35 + return buildSortingField(func, SortingField.ORDER_DESC);
  36 + }
  37 +
  38 + /**
  39 + * 构建排序字段
  40 + *
  41 + * @param func 排序字段的 Lambda 表达式
  42 + * @param order 排序类型 {@link SortingField#ORDER_ASC} {@link SortingField#ORDER_DESC}
  43 + * @param <T> 排序字段所属的类型
  44 + * @return 排序字段
  45 + */
  46 + public static <T> SortingField buildSortingField(Func1<T, ?> func, String order) {
  47 + Assert.isTrue(ArrayUtil.contains(ORDER_TYPES, order), String.format("字段的排序类型只能是 %s/%s", ORDER_TYPES));
  48 +
  49 + String fieldName = LambdaUtil.getFieldName(func);
  50 + return new SortingField(fieldName, order);
  51 + }
  52 +
  53 + /**
  54 + * 构建默认的排序字段
  55 + * 如果排序字段为空,则设置排序字段;否则忽略
  56 + *
  57 + * @param sortablePageParam 排序分页查询参数
  58 + * @param func 排序字段的 Lambda 表达式
  59 + * @param <T> 排序字段所属的类型
  60 + */
  61 + public static <T> void buildDefaultSortingField(SortablePageParam sortablePageParam, Func1<T, ?> func) {
  62 + if (sortablePageParam != null && CollUtil.isEmpty(sortablePageParam.getSortingFields())) {
  63 + sortablePageParam.setSortingFields(List.of(buildSortingField(func)));
  64 + }
  65 + }
  66 +
16 } 67 }
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/MyBatisUtils.java
1 package cn.iocoder.yudao.framework.mybatis.core.util; 1 package cn.iocoder.yudao.framework.mybatis.core.util;
2 2
3 -import cn.hutool.core.collection.CollUtil;  
4 import cn.hutool.core.collection.CollectionUtil; 3 import cn.hutool.core.collection.CollectionUtil;
5 -import cn.hutool.core.lang.func.Func1;  
6 -import cn.hutool.core.lang.func.LambdaUtil;  
7 -import cn.hutool.core.util.ArrayUtil;  
8 import cn.iocoder.yudao.framework.common.pojo.PageParam; 4 import cn.iocoder.yudao.framework.common.pojo.PageParam;
9 -import cn.iocoder.yudao.framework.common.pojo.SortablePageParam;  
10 import cn.iocoder.yudao.framework.common.pojo.SortingField; 5 import cn.iocoder.yudao.framework.common.pojo.SortingField;
11 import com.baomidou.mybatisplus.core.metadata.OrderItem; 6 import com.baomidou.mybatisplus.core.metadata.OrderItem;
12 import com.baomidou.mybatisplus.core.toolkit.StringPool; 7 import com.baomidou.mybatisplus.core.toolkit.StringPool;
@@ -16,7 +11,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -16,7 +11,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
16 import net.sf.jsqlparser.expression.Alias; 11 import net.sf.jsqlparser.expression.Alias;
17 import net.sf.jsqlparser.schema.Column; 12 import net.sf.jsqlparser.schema.Column;
18 import net.sf.jsqlparser.schema.Table; 13 import net.sf.jsqlparser.schema.Table;
19 -import org.springframework.util.Assert;  
20 14
21 import java.util.ArrayList; 15 import java.util.ArrayList;
22 import java.util.Collection; 16 import java.util.Collection;
@@ -91,46 +85,4 @@ public class MyBatisUtils { @@ -91,46 +85,4 @@ public class MyBatisUtils {
91 return new Column(tableName + StringPool.DOT + column); 85 return new Column(tableName + StringPool.DOT + column);
92 } 86 }
93 87
94 -  
95 - /**  
96 - * 构建排序字段(默认倒序)  
97 - *  
98 - * @param func 排序字段的 Lambda 表达式  
99 - * @param <T> 排序字段所属的类型  
100 - * @return 排序字段  
101 - */  
102 - public static <T> SortingField buildSortingField(Func1<T, ?> func) {  
103 - return buildSortingField(func, SortingField.ORDER_DESC);  
104 - }  
105 -  
106 - /**  
107 - * 构建排序字段  
108 - *  
109 - * @param func 排序字段的 Lambda 表达式  
110 - * @param order 排序类型 {@link SortingField#ORDER_ASC} {@link SortingField#ORDER_DESC}  
111 - * @param <T> 排序字段所属的类型  
112 - * @return 排序字段  
113 - */  
114 - public static <T> SortingField buildSortingField(Func1<T, ?> func, String order) {  
115 - Object[] orderTypes = {SortingField.ORDER_ASC, SortingField.ORDER_DESC};  
116 - Assert.isTrue(ArrayUtil.contains(orderTypes, order), String.format("字段的排序类型只能是%s/%s", orderTypes));  
117 -  
118 - String fieldName = LambdaUtil.getFieldName(func);  
119 - return new SortingField(fieldName, order);  
120 - }  
121 -  
122 - /**  
123 - * 构建默认的排序字段  
124 - * 如果排序字段为空,则设置排序字段;否则忽略  
125 - *  
126 - * @param sortablePageParam 排序分页查询参数  
127 - * @param func 排序字段的 Lambda 表达式  
128 - * @param <T> 排序字段所属的类型  
129 - */  
130 - public static <T> void buildDefaultSortingField(SortablePageParam sortablePageParam, Func1<T, ?> func) {  
131 - if (sortablePageParam != null && CollUtil.isEmpty(sortablePageParam.getSortingFields())) {  
132 - sortablePageParam.setSortingFields(List.of(buildSortingField(func)));  
133 - }  
134 - }  
135 -  
136 } 88 }
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3/views/index.vue.vm
@@ -252,15 +252,11 @@ import ${subSimpleClassName}List from &#39;./components/${subSimpleClassName}List.vu @@ -252,15 +252,11 @@ import ${subSimpleClassName}List from &#39;./components/${subSimpleClassName}List.vu
252 /** ${table.classComment} 列表 */ 252 /** ${table.classComment} 列表 */
253 defineOptions({ name: '${table.className}' }) 253 defineOptions({ name: '${table.className}' })
254 254
255 -// 消息弹窗  
256 -const message = useMessage()  
257 -// 国际化  
258 -const { t } = useI18n() 255 +const message = useMessage() // 消息弹窗
  256 +const { t } = useI18n() // 国际化
259 257
260 -// 列表的加载中  
261 -const loading = ref(true)  
262 -// 列表的数据  
263 -const list = ref<${simpleClassName}VO[]>([]) 258 +const loading = ref(true) // 列表的加载中
  259 +const list = ref<${simpleClassName}VO[]>([]) // 列表的数据
264 ## 特殊:树表专属逻辑(树不需要分页接口) 260 ## 特殊:树表专属逻辑(树不需要分页接口)
265 #if ( $table.templateType != 2 ) 261 #if ( $table.templateType != 2 )
266 // 列表的总页数 262 // 列表的总页数
@@ -283,10 +279,8 @@ const queryParams = reactive({ @@ -283,10 +279,8 @@ const queryParams = reactive({
283 #end 279 #end
284 #end 280 #end
285 }) 281 })
286 -// 搜索的表单  
287 -const queryFormRef = ref()  
288 -// 导出的加载中  
289 -const exportLoading = ref(false) 282 +const queryFormRef = ref() // 搜索的表单
  283 +const exportLoading = ref(false) // 导出的加载中
290 284
291 /** 查询列表 */ 285 /** 查询列表 */
292 const getList = async () => { 286 const getList = async () => {
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/history/AppProductBrowseHistoryController.java
@@ -28,6 +28,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. @@ -28,6 +28,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
28 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 28 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
29 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 29 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
30 30
  31 +// TODO 芋艿:后面再看
31 @Tag(name = "用户 APP - 商品浏览记录") 32 @Tag(name = "用户 APP - 商品浏览记录")
32 @RestController 33 @RestController
33 @RequestMapping("/product/browse-history") 34 @RequestMapping("/product/browse-history")
@@ -65,10 +66,9 @@ public class AppProductBrowseHistoryController { @@ -65,10 +66,9 @@ public class AppProductBrowseHistoryController {
65 @Operation(summary = "获得商品浏览记录分页") 66 @Operation(summary = "获得商品浏览记录分页")
66 @PreAuthenticated 67 @PreAuthenticated
67 public CommonResult<PageResult<AppProductBrowseHistoryRespVO>> getBrowseHistoryPage(AppProductBrowseHistoryPageReqVO reqVO) { 68 public CommonResult<PageResult<AppProductBrowseHistoryRespVO>> getBrowseHistoryPage(AppProductBrowseHistoryPageReqVO reqVO) {
68 - ProductBrowseHistoryPageReqVO pageReqVO = BeanUtils.toBean(reqVO, ProductBrowseHistoryPageReqVO.class);  
69 - pageReqVO.setUserId(getLoginUserId());  
70 - // 排除用户已删除的(隐藏的)  
71 - pageReqVO.setUserDeleted(false); 69 + ProductBrowseHistoryPageReqVO pageReqVO = BeanUtils.toBean(reqVO, ProductBrowseHistoryPageReqVO.class)
  70 + .setUserId(getLoginUserId())
  71 + .setUserDeleted(false); // 排除用户已删除的(隐藏的)
72 PageResult<ProductBrowseHistoryDO> pageResult = productBrowseHistoryService.getBrowseHistoryPage(pageReqVO); 72 PageResult<ProductBrowseHistoryDO> pageResult = productBrowseHistoryService.getBrowseHistoryPage(pageReqVO);
73 if (CollUtil.isEmpty(pageResult.getList())) { 73 if (CollUtil.isEmpty(pageResult.getList())) {
74 return success(PageResult.empty()); 74 return success(PageResult.empty());
@@ -77,14 +77,9 @@ public class AppProductBrowseHistoryController { @@ -77,14 +77,9 @@ public class AppProductBrowseHistoryController {
77 // 得到商品 spu 信息 77 // 得到商品 spu 信息
78 Set<Long> spuIds = convertSet(pageResult.getList(), ProductBrowseHistoryDO::getSpuId); 78 Set<Long> spuIds = convertSet(pageResult.getList(), ProductBrowseHistoryDO::getSpuId);
79 Map<Long, ProductSpuDO> spuMap = convertMap(productSpuService.getSpuList(spuIds), ProductSpuDO::getId); 79 Map<Long, ProductSpuDO> spuMap = convertMap(productSpuService.getSpuList(spuIds), ProductSpuDO::getId);
80 -  
81 - // 转换 VO 结果  
82 - PageResult<AppProductBrowseHistoryRespVO> result = BeanUtils.toBean(pageResult, AppProductBrowseHistoryRespVO.class,  
83 - vo -> Optional.ofNullable(spuMap.get(vo.getSpuId())).ifPresent(spu -> {  
84 - vo.setSpuName(spu.getName());  
85 - vo.setPicUrl(spu.getPicUrl());  
86 - }));  
87 - return success(result); 80 + return success(BeanUtils.toBean(pageResult, AppProductBrowseHistoryRespVO.class,
  81 + vo -> Optional.ofNullable(spuMap.get(vo.getSpuId()))
  82 + .ifPresent(spu -> vo.setSpuName(spu.getName()).setPicUrl(spu.getPicUrl()))));
88 } 83 }
89 84
90 } 85 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/history/vo/AppProductBrowseHistoryPageReqVO.java
@@ -16,6 +16,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @@ -16,6 +16,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
16 @EqualsAndHashCode(callSuper = true) 16 @EqualsAndHashCode(callSuper = true)
17 @ToString(callSuper = true) 17 @ToString(callSuper = true)
18 public class AppProductBrowseHistoryPageReqVO extends PageParam { 18 public class AppProductBrowseHistoryPageReqVO extends PageParam {
  19 +
19 @Schema(description = "创建时间") 20 @Schema(description = "创建时间")
20 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 21 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
21 private LocalDateTime[] createTime; 22 private LocalDateTime[] createTime;
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/history/ProductBrowseHistoryService.java
@@ -31,14 +31,6 @@ public interface ProductBrowseHistoryService { @@ -31,14 +31,6 @@ public interface ProductBrowseHistoryService {
31 void hideUserBrowseHistory(Long userId, Collection<Long> spuId); 31 void hideUserBrowseHistory(Long userId, Collection<Long> spuId);
32 32
33 /** 33 /**
34 - * 获得商品浏览记录  
35 - *  
36 - * @param id 编号  
37 - * @return 商品浏览记录  
38 - */  
39 - ProductBrowseHistoryDO getBrowseHistory(Long id);  
40 -  
41 - /**  
42 * 获取用户记录数量 34 * 获取用户记录数量
43 * 35 *
44 * @param userId 用户编号 36 * @param userId 用户编号
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/history/ProductBrowseHistoryServiceImpl.java
@@ -50,7 +50,6 @@ public class ProductBrowseHistoryServiceImpl implements ProductBrowseHistoryServ @@ -50,7 +50,6 @@ public class ProductBrowseHistoryServiceImpl implements ProductBrowseHistoryServ
50 .setUserId(userId) 50 .setUserId(userId)
51 .setSpuId(spuId); 51 .setSpuId(spuId);
52 browseHistoryMapper.insert(browseHistory); 52 browseHistoryMapper.insert(browseHistory);
53 - // 返回  
54 return browseHistory.getId(); 53 return browseHistory.getId();
55 } 54 }
56 55
@@ -60,11 +59,6 @@ public class ProductBrowseHistoryServiceImpl implements ProductBrowseHistoryServ @@ -60,11 +59,6 @@ public class ProductBrowseHistoryServiceImpl implements ProductBrowseHistoryServ
60 } 59 }
61 60
62 @Override 61 @Override
63 - public ProductBrowseHistoryDO getBrowseHistory(Long id) {  
64 - return browseHistoryMapper.selectById(id);  
65 - }  
66 -  
67 - @Override  
68 public Long getBrowseHistoryCount(Long userId, Boolean userDeleted) { 62 public Long getBrowseHistoryCount(Long userId, Boolean userDeleted) {
69 return browseHistoryMapper.selectCountByUserIdAndUserDeleted(userId, userDeleted); 63 return browseHistoryMapper.selectCountByUserIdAndUserDeleted(userId, userDeleted);
70 } 64 }
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/product/ProductStatisticsController.java
@@ -79,13 +79,9 @@ public class ProductStatisticsController { @@ -79,13 +79,9 @@ public class ProductStatisticsController {
79 // 处理商品信息 79 // 处理商品信息
80 Set<Long> spuIds = convertSet(pageResult.getList(), ProductStatisticsDO::getSpuId); 80 Set<Long> spuIds = convertSet(pageResult.getList(), ProductStatisticsDO::getSpuId);
81 Map<Long, ProductSpuRespDTO> spuMap = convertMap(productSpuApi.getSpuList(spuIds), ProductSpuRespDTO::getId); 81 Map<Long, ProductSpuRespDTO> spuMap = convertMap(productSpuApi.getSpuList(spuIds), ProductSpuRespDTO::getId);
82 - // 拼接返回  
83 return success(BeanUtils.toBean(pageResult, ProductStatisticsRespVO.class, 82 return success(BeanUtils.toBean(pageResult, ProductStatisticsRespVO.class,
84 - // 拼接商品信息  
85 - item -> Optional.ofNullable(spuMap.get(item.getSpuId())).ifPresent(spu -> {  
86 - item.setName(spu.getName());  
87 - item.setPicUrl(spu.getPicUrl());  
88 - }))); 83 + item -> Optional.ofNullable(spuMap.get(item.getSpuId()))
  84 + .ifPresent(spu -> item.setName(spu.getName()).setPicUrl(spu.getPicUrl()))));
89 } 85 }
90 86
91 } 87 }
92 \ No newline at end of file 88 \ No newline at end of file
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/product/vo/ProductStatisticsRespVO.java
@@ -27,7 +27,7 @@ public class ProductStatisticsRespVO { @@ -27,7 +27,7 @@ public class ProductStatisticsRespVO {
27 @ExcelProperty("商品SPU编号") 27 @ExcelProperty("商品SPU编号")
28 private Long spuId; 28 private Long spuId;
29 29
30 - //region 商品信息 30 + // region 商品信息
31 31
32 @Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "商品名称") 32 @Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "商品名称")
33 @ExcelProperty("商品名称") 33 @ExcelProperty("商品名称")
@@ -37,7 +37,7 @@ public class ProductStatisticsRespVO { @@ -37,7 +37,7 @@ public class ProductStatisticsRespVO {
37 @ExcelProperty("商品封面图") 37 @ExcelProperty("商品封面图")
38 private String picUrl; 38 private String picUrl;
39 39
40 - //endregion 40 + // endregion
41 41
42 @Schema(description = "浏览量", requiredMode = Schema.RequiredMode.REQUIRED, example = "17505") 42 @Schema(description = "浏览量", requiredMode = Schema.RequiredMode.REQUIRED, example = "17505")
43 @ExcelProperty("浏览量") 43 @ExcelProperty("浏览量")
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/trade/TradeStatisticsController.java
@@ -49,7 +49,6 @@ public class TradeStatisticsController { @@ -49,7 +49,6 @@ public class TradeStatisticsController {
49 @Resource 49 @Resource
50 private BrokerageStatisticsService brokerageStatisticsService; 50 private BrokerageStatisticsService brokerageStatisticsService;
51 51
52 - // TODO 芋艿:已经 review  
53 @GetMapping("/summary") 52 @GetMapping("/summary")
54 @Operation(summary = "获得交易统计") 53 @Operation(summary = "获得交易统计")
55 @PreAuthorize("@ss.hasPermission('statistics:trade:query')") 54 @PreAuthorize("@ss.hasPermission('statistics:trade:query')")
@@ -75,7 +74,6 @@ public class TradeStatisticsController { @@ -75,7 +74,6 @@ public class TradeStatisticsController {
75 ArrayUtil.get(reqVO.getTimes(), 1))); 74 ArrayUtil.get(reqVO.getTimes(), 1)));
76 } 75 }
77 76
78 - // TODO 芋艿:已经 review  
79 @GetMapping("/list") 77 @GetMapping("/list")
80 @Operation(summary = "获得交易状况明细") 78 @Operation(summary = "获得交易状况明细")
81 @PreAuthorize("@ss.hasPermission('statistics:trade:query')") 79 @PreAuthorize("@ss.hasPermission('statistics:trade:query')")
@@ -85,7 +83,6 @@ public class TradeStatisticsController { @@ -85,7 +83,6 @@ public class TradeStatisticsController {
85 return success(TradeStatisticsConvert.INSTANCE.convertList(list)); 83 return success(TradeStatisticsConvert.INSTANCE.convertList(list));
86 } 84 }
87 85
88 - // TODO 芋艿:已经 review  
89 @GetMapping("/export-excel") 86 @GetMapping("/export-excel")
90 @Operation(summary = "导出获得交易状况明细 Excel") 87 @Operation(summary = "导出获得交易状况明细 Excel")
91 @PreAuthorize("@ss.hasPermission('statistics:trade:export')") 88 @PreAuthorize("@ss.hasPermission('statistics:trade:export')")
@@ -98,7 +95,6 @@ public class TradeStatisticsController { @@ -98,7 +95,6 @@ public class TradeStatisticsController {
98 ExcelUtils.write(response, "交易状况.xls", "数据", TradeTrendSummaryExcelVO.class, data); 95 ExcelUtils.write(response, "交易状况.xls", "数据", TradeTrendSummaryExcelVO.class, data);
99 } 96 }
100 97
101 - // TODO 芋艿:已经 review  
102 @GetMapping("/order-count") 98 @GetMapping("/order-count")
103 @Operation(summary = "获得交易订单数量") 99 @Operation(summary = "获得交易订单数量")
104 @PreAuthorize("@ss.hasPermission('statistics:trade:query')") 100 @PreAuthorize("@ss.hasPermission('statistics:trade:query')")
@@ -116,7 +112,6 @@ public class TradeStatisticsController { @@ -116,7 +112,6 @@ public class TradeStatisticsController {
116 return success(TradeStatisticsConvert.INSTANCE.convert(undeliveredCount, pickUpCount, afterSaleApplyCount, auditingWithdrawCount)); 112 return success(TradeStatisticsConvert.INSTANCE.convert(undeliveredCount, pickUpCount, afterSaleApplyCount, auditingWithdrawCount));
117 } 113 }
118 114
119 - // TODO 芋艿:已经 review  
120 @GetMapping("/order-comparison") 115 @GetMapping("/order-comparison")
121 @Operation(summary = "获得交易订单数量") 116 @Operation(summary = "获得交易订单数量")
122 @PreAuthorize("@ss.hasPermission('statistics:trade:query')") 117 @PreAuthorize("@ss.hasPermission('statistics:trade:query')")
@@ -124,7 +119,6 @@ public class TradeStatisticsController { @@ -124,7 +119,6 @@ public class TradeStatisticsController {
124 return success(tradeOrderStatisticsService.getOrderComparison()); 119 return success(tradeOrderStatisticsService.getOrderComparison());
125 } 120 }
126 121
127 - // TODO 芋艿:已经 review  
128 @GetMapping("/order-count-trend") 122 @GetMapping("/order-count-trend")
129 @Operation(summary = "获得订单量趋势统计") 123 @Operation(summary = "获得订单量趋势统计")
130 @PreAuthorize("@ss.hasPermission('statistics:trade:query')") 124 @PreAuthorize("@ss.hasPermission('statistics:trade:query')")
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/dal/dataobject/product/ProductStatisticsDO.java
@@ -33,7 +33,7 @@ public class ProductStatisticsDO extends BaseDO { @@ -33,7 +33,7 @@ public class ProductStatisticsDO extends BaseDO {
33 */ 33 */
34 private LocalDate time; 34 private LocalDate time;
35 /** 35 /**
36 - * 商品SPU编号 36 + * 商品 SPU 编号
37 */ 37 */
38 private Long spuId; 38 private Long spuId;
39 /** 39 /**
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/job/product/ProductStatisticsJob.java
@@ -45,4 +45,5 @@ public class ProductStatisticsJob implements JobHandler { @@ -45,4 +45,5 @@ public class ProductStatisticsJob implements JobHandler {
45 String result = productStatisticsService.statisticsProduct(days); 45 String result = productStatisticsService.statisticsProduct(days);
46 return StrUtil.format("商品统计:\n{}", result); 46 return StrUtil.format("商品统计:\n{}", result);
47 } 47 }
  48 +
48 } 49 }
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/product/ProductStatisticsServiceImpl.java
@@ -7,7 +7,7 @@ import cn.hutool.core.util.ArrayUtil; @@ -7,7 +7,7 @@ import cn.hutool.core.util.ArrayUtil;
7 import cn.hutool.core.util.ObjUtil; 7 import cn.hutool.core.util.ObjUtil;
8 import cn.iocoder.yudao.framework.common.pojo.PageResult; 8 import cn.iocoder.yudao.framework.common.pojo.PageResult;
9 import cn.iocoder.yudao.framework.common.pojo.SortablePageParam; 9 import cn.iocoder.yudao.framework.common.pojo.SortablePageParam;
10 -import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; 10 +import cn.iocoder.yudao.framework.common.util.object.PageUtils;
11 import cn.iocoder.yudao.module.statistics.controller.admin.common.vo.DataComparisonRespVO; 11 import cn.iocoder.yudao.module.statistics.controller.admin.common.vo.DataComparisonRespVO;
12 import cn.iocoder.yudao.module.statistics.controller.admin.product.vo.ProductStatisticsReqVO; 12 import cn.iocoder.yudao.module.statistics.controller.admin.product.vo.ProductStatisticsReqVO;
13 import cn.iocoder.yudao.module.statistics.controller.admin.product.vo.ProductStatisticsRespVO; 13 import cn.iocoder.yudao.module.statistics.controller.admin.product.vo.ProductStatisticsRespVO;
@@ -42,8 +42,7 @@ public class ProductStatisticsServiceImpl implements ProductStatisticsService { @@ -42,8 +42,7 @@ public class ProductStatisticsServiceImpl implements ProductStatisticsService {
42 42
43 @Override 43 @Override
44 public PageResult<ProductStatisticsDO> getProductStatisticsRankPage(ProductStatisticsReqVO reqVO, SortablePageParam pageParam) { 44 public PageResult<ProductStatisticsDO> getProductStatisticsRankPage(ProductStatisticsReqVO reqVO, SortablePageParam pageParam) {
45 - // 默认浏览量倒序  
46 - MyBatisUtils.buildDefaultSortingField(pageParam, ProductStatisticsDO::getBrowseCount); 45 + PageUtils.buildDefaultSortingField(pageParam, ProductStatisticsDO::getBrowseCount); // 默认浏览量倒序
47 return productStatisticsMapper.selectPageGroupBySpuId(reqVO, pageParam); 46 return productStatisticsMapper.selectPageGroupBySpuId(reqVO, pageParam);
48 } 47 }
49 48
@@ -92,31 +91,26 @@ public class ProductStatisticsServiceImpl implements ProductStatisticsService { @@ -92,31 +91,26 @@ public class ProductStatisticsServiceImpl implements ProductStatisticsService {
92 return dateStr + " 数据已存在,如果需要重新统计,请先删除对应的数据"; 91 return dateStr + " 数据已存在,如果需要重新统计,请先删除对应的数据";
93 } 92 }
94 93
95 - // 3. 统计数据  
96 StopWatch stopWatch = new StopWatch(dateStr); 94 StopWatch stopWatch = new StopWatch(dateStr);
97 stopWatch.start(); 95 stopWatch.start();
98 -  
99 - // 分页统计,避免商品表数据较多时,出现超时问题 96 + // 4. 分页统计,避免商品表数据较多时,出现超时问题
100 final int pageSize = 100; 97 final int pageSize = 100;
101 - for (int pageNo = 1; ; pageNo ++) { 98 + for (int pageNo = 1; ; pageNo++) {
102 IPage<ProductStatisticsDO> page = productStatisticsMapper.selectStatisticsResultPageByTimeBetween( 99 IPage<ProductStatisticsDO> page = productStatisticsMapper.selectStatisticsResultPageByTimeBetween(
103 Page.of(pageNo, pageSize, false), beginTime, endTime); 100 Page.of(pageNo, pageSize, false), beginTime, endTime);
104 if (CollUtil.isEmpty(page.getRecords())) { 101 if (CollUtil.isEmpty(page.getRecords())) {
105 break; 102 break;
106 } 103 }
107 - 104 + // 4.1 计算访客支付转化率(百分比)
108 for (ProductStatisticsDO record : page.getRecords()) { 105 for (ProductStatisticsDO record : page.getRecords()) {
109 record.setTime(date.toLocalDate()); 106 record.setTime(date.toLocalDate());
110 - // 计算 访客支付转化率(百分比)  
111 if (record.getBrowseUserCount() != null && ObjUtil.notEqual(record.getBrowseUserCount(), 0)) { 107 if (record.getBrowseUserCount() != null && ObjUtil.notEqual(record.getBrowseUserCount(), 0)) {
112 record.setBrowseConvertPercent(100 * record.getOrderPayCount() / record.getBrowseUserCount()); 108 record.setBrowseConvertPercent(100 * record.getOrderPayCount() / record.getBrowseUserCount());
113 } 109 }
114 } 110 }
115 -  
116 - // 4. 插入数据 111 + // 4.2 插入数据
117 productStatisticsMapper.insertBatch(page.getRecords()); 112 productStatisticsMapper.insertBatch(page.getRecords());
118 } 113 }
119 -  
120 return stopWatch.prettyPrint(); 114 return stopWatch.prettyPrint();
121 } 115 }
122 116