Commit bbba83ef61527b3bd0a094bb5381d6cce1558f61
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 | 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 | 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 | 15 | * {@link cn.iocoder.yudao.framework.common.pojo.PageParam} 工具类 |
| ... | ... | @@ -9,8 +18,50 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 9 | 18 | */ |
| 10 | 19 | public class PageUtils { |
| 11 | 20 | |
| 21 | + private static final Object[] ORDER_TYPES = new String[]{SortingField.ORDER_ASC, SortingField.ORDER_DESC}; | |
| 22 | + | |
| 12 | 23 | public static int getStart(PageParam pageParam) { |
| 13 | 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 | 1 | package cn.iocoder.yudao.framework.mybatis.core.util; |
| 2 | 2 | |
| 3 | -import cn.hutool.core.collection.CollUtil; | |
| 4 | 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 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 9 | -import cn.iocoder.yudao.framework.common.pojo.SortablePageParam; | |
| 10 | 5 | import cn.iocoder.yudao.framework.common.pojo.SortingField; |
| 11 | 6 | import com.baomidou.mybatisplus.core.metadata.OrderItem; |
| 12 | 7 | import com.baomidou.mybatisplus.core.toolkit.StringPool; |
| ... | ... | @@ -16,7 +11,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| 16 | 11 | import net.sf.jsqlparser.expression.Alias; |
| 17 | 12 | import net.sf.jsqlparser.schema.Column; |
| 18 | 13 | import net.sf.jsqlparser.schema.Table; |
| 19 | -import org.springframework.util.Assert; | |
| 20 | 14 | |
| 21 | 15 | import java.util.ArrayList; |
| 22 | 16 | import java.util.Collection; |
| ... | ... | @@ -91,46 +85,4 @@ public class MyBatisUtils { |
| 91 | 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 './components/${subSimpleClassName}List.vu |
| 252 | 252 | /** ${table.classComment} 列表 */ |
| 253 | 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 | 261 | #if ( $table.templateType != 2 ) |
| 266 | 262 | // 列表的总页数 |
| ... | ... | @@ -283,10 +279,8 @@ const queryParams = reactive({ |
| 283 | 279 | #end |
| 284 | 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 | 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 | 28 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| 29 | 29 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| 30 | 30 | |
| 31 | +// TODO 芋艿:后面再看 | |
| 31 | 32 | @Tag(name = "用户 APP - 商品浏览记录") |
| 32 | 33 | @RestController |
| 33 | 34 | @RequestMapping("/product/browse-history") |
| ... | ... | @@ -65,10 +66,9 @@ public class AppProductBrowseHistoryController { |
| 65 | 66 | @Operation(summary = "获得商品浏览记录分页") |
| 66 | 67 | @PreAuthenticated |
| 67 | 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 | 72 | PageResult<ProductBrowseHistoryDO> pageResult = productBrowseHistoryService.getBrowseHistoryPage(pageReqVO); |
| 73 | 73 | if (CollUtil.isEmpty(pageResult.getList())) { |
| 74 | 74 | return success(PageResult.empty()); |
| ... | ... | @@ -77,14 +77,9 @@ public class AppProductBrowseHistoryController { |
| 77 | 77 | // 得到商品 spu 信息 |
| 78 | 78 | Set<Long> spuIds = convertSet(pageResult.getList(), ProductBrowseHistoryDO::getSpuId); |
| 79 | 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 | 16 | @EqualsAndHashCode(callSuper = true) |
| 17 | 17 | @ToString(callSuper = true) |
| 18 | 18 | public class AppProductBrowseHistoryPageReqVO extends PageParam { |
| 19 | + | |
| 19 | 20 | @Schema(description = "创建时间") |
| 20 | 21 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| 21 | 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 | 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 | 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 | 50 | .setUserId(userId) |
| 51 | 51 | .setSpuId(spuId); |
| 52 | 52 | browseHistoryMapper.insert(browseHistory); |
| 53 | - // 返回 | |
| 54 | 53 | return browseHistory.getId(); |
| 55 | 54 | } |
| 56 | 55 | |
| ... | ... | @@ -60,11 +59,6 @@ public class ProductBrowseHistoryServiceImpl implements ProductBrowseHistoryServ |
| 60 | 59 | } |
| 61 | 60 | |
| 62 | 61 | @Override |
| 63 | - public ProductBrowseHistoryDO getBrowseHistory(Long id) { | |
| 64 | - return browseHistoryMapper.selectById(id); | |
| 65 | - } | |
| 66 | - | |
| 67 | - @Override | |
| 68 | 62 | public Long getBrowseHistoryCount(Long userId, Boolean userDeleted) { |
| 69 | 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 | 79 | // 处理商品信息 |
| 80 | 80 | Set<Long> spuIds = convertSet(pageResult.getList(), ProductStatisticsDO::getSpuId); |
| 81 | 81 | Map<Long, ProductSpuRespDTO> spuMap = convertMap(productSpuApi.getSpuList(spuIds), ProductSpuRespDTO::getId); |
| 82 | - // 拼接返回 | |
| 83 | 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 | 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 | 27 | @ExcelProperty("商品SPU编号") |
| 28 | 28 | private Long spuId; |
| 29 | 29 | |
| 30 | - //region 商品信息 | |
| 30 | + // region 商品信息 | |
| 31 | 31 | |
| 32 | 32 | @Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "商品名称") |
| 33 | 33 | @ExcelProperty("商品名称") |
| ... | ... | @@ -37,7 +37,7 @@ public class ProductStatisticsRespVO { |
| 37 | 37 | @ExcelProperty("商品封面图") |
| 38 | 38 | private String picUrl; |
| 39 | 39 | |
| 40 | - //endregion | |
| 40 | + // endregion | |
| 41 | 41 | |
| 42 | 42 | @Schema(description = "浏览量", requiredMode = Schema.RequiredMode.REQUIRED, example = "17505") |
| 43 | 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 | 49 | @Resource |
| 50 | 50 | private BrokerageStatisticsService brokerageStatisticsService; |
| 51 | 51 | |
| 52 | - // TODO 芋艿:已经 review | |
| 53 | 52 | @GetMapping("/summary") |
| 54 | 53 | @Operation(summary = "获得交易统计") |
| 55 | 54 | @PreAuthorize("@ss.hasPermission('statistics:trade:query')") |
| ... | ... | @@ -75,7 +74,6 @@ public class TradeStatisticsController { |
| 75 | 74 | ArrayUtil.get(reqVO.getTimes(), 1))); |
| 76 | 75 | } |
| 77 | 76 | |
| 78 | - // TODO 芋艿:已经 review | |
| 79 | 77 | @GetMapping("/list") |
| 80 | 78 | @Operation(summary = "获得交易状况明细") |
| 81 | 79 | @PreAuthorize("@ss.hasPermission('statistics:trade:query')") |
| ... | ... | @@ -85,7 +83,6 @@ public class TradeStatisticsController { |
| 85 | 83 | return success(TradeStatisticsConvert.INSTANCE.convertList(list)); |
| 86 | 84 | } |
| 87 | 85 | |
| 88 | - // TODO 芋艿:已经 review | |
| 89 | 86 | @GetMapping("/export-excel") |
| 90 | 87 | @Operation(summary = "导出获得交易状况明细 Excel") |
| 91 | 88 | @PreAuthorize("@ss.hasPermission('statistics:trade:export')") |
| ... | ... | @@ -98,7 +95,6 @@ public class TradeStatisticsController { |
| 98 | 95 | ExcelUtils.write(response, "交易状况.xls", "数据", TradeTrendSummaryExcelVO.class, data); |
| 99 | 96 | } |
| 100 | 97 | |
| 101 | - // TODO 芋艿:已经 review | |
| 102 | 98 | @GetMapping("/order-count") |
| 103 | 99 | @Operation(summary = "获得交易订单数量") |
| 104 | 100 | @PreAuthorize("@ss.hasPermission('statistics:trade:query')") |
| ... | ... | @@ -116,7 +112,6 @@ public class TradeStatisticsController { |
| 116 | 112 | return success(TradeStatisticsConvert.INSTANCE.convert(undeliveredCount, pickUpCount, afterSaleApplyCount, auditingWithdrawCount)); |
| 117 | 113 | } |
| 118 | 114 | |
| 119 | - // TODO 芋艿:已经 review | |
| 120 | 115 | @GetMapping("/order-comparison") |
| 121 | 116 | @Operation(summary = "获得交易订单数量") |
| 122 | 117 | @PreAuthorize("@ss.hasPermission('statistics:trade:query')") |
| ... | ... | @@ -124,7 +119,6 @@ public class TradeStatisticsController { |
| 124 | 119 | return success(tradeOrderStatisticsService.getOrderComparison()); |
| 125 | 120 | } |
| 126 | 121 | |
| 127 | - // TODO 芋艿:已经 review | |
| 128 | 122 | @GetMapping("/order-count-trend") |
| 129 | 123 | @Operation(summary = "获得订单量趋势统计") |
| 130 | 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
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/job/product/ProductStatisticsJob.java
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 | import cn.hutool.core.util.ObjUtil; |
| 8 | 8 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 9 | 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 | 11 | import cn.iocoder.yudao.module.statistics.controller.admin.common.vo.DataComparisonRespVO; |
| 12 | 12 | import cn.iocoder.yudao.module.statistics.controller.admin.product.vo.ProductStatisticsReqVO; |
| 13 | 13 | import cn.iocoder.yudao.module.statistics.controller.admin.product.vo.ProductStatisticsRespVO; |
| ... | ... | @@ -42,8 +42,7 @@ public class ProductStatisticsServiceImpl implements ProductStatisticsService { |
| 42 | 42 | |
| 43 | 43 | @Override |
| 44 | 44 | public PageResult<ProductStatisticsDO> getProductStatisticsRankPage(ProductStatisticsReqVO reqVO, SortablePageParam pageParam) { |
| 45 | - // 默认浏览量倒序 | |
| 46 | - MyBatisUtils.buildDefaultSortingField(pageParam, ProductStatisticsDO::getBrowseCount); | |
| 45 | + PageUtils.buildDefaultSortingField(pageParam, ProductStatisticsDO::getBrowseCount); // 默认浏览量倒序 | |
| 47 | 46 | return productStatisticsMapper.selectPageGroupBySpuId(reqVO, pageParam); |
| 48 | 47 | } |
| 49 | 48 | |
| ... | ... | @@ -92,31 +91,26 @@ public class ProductStatisticsServiceImpl implements ProductStatisticsService { |
| 92 | 91 | return dateStr + " 数据已存在,如果需要重新统计,请先删除对应的数据"; |
| 93 | 92 | } |
| 94 | 93 | |
| 95 | - // 3. 统计数据 | |
| 96 | 94 | StopWatch stopWatch = new StopWatch(dateStr); |
| 97 | 95 | stopWatch.start(); |
| 98 | - | |
| 99 | - // 分页统计,避免商品表数据较多时,出现超时问题 | |
| 96 | + // 4. 分页统计,避免商品表数据较多时,出现超时问题 | |
| 100 | 97 | final int pageSize = 100; |
| 101 | - for (int pageNo = 1; ; pageNo ++) { | |
| 98 | + for (int pageNo = 1; ; pageNo++) { | |
| 102 | 99 | IPage<ProductStatisticsDO> page = productStatisticsMapper.selectStatisticsResultPageByTimeBetween( |
| 103 | 100 | Page.of(pageNo, pageSize, false), beginTime, endTime); |
| 104 | 101 | if (CollUtil.isEmpty(page.getRecords())) { |
| 105 | 102 | break; |
| 106 | 103 | } |
| 107 | - | |
| 104 | + // 4.1 计算访客支付转化率(百分比) | |
| 108 | 105 | for (ProductStatisticsDO record : page.getRecords()) { |
| 109 | 106 | record.setTime(date.toLocalDate()); |
| 110 | - // 计算 访客支付转化率(百分比) | |
| 111 | 107 | if (record.getBrowseUserCount() != null && ObjUtil.notEqual(record.getBrowseUserCount(), 0)) { |
| 112 | 108 | record.setBrowseConvertPercent(100 * record.getOrderPayCount() / record.getBrowseUserCount()); |
| 113 | 109 | } |
| 114 | 110 | } |
| 115 | - | |
| 116 | - // 4. 插入数据 | |
| 111 | + // 4.2 插入数据 | |
| 117 | 112 | productStatisticsMapper.insertBatch(page.getRecords()); |
| 118 | 113 | } |
| 119 | - | |
| 120 | 114 | return stopWatch.prettyPrint(); |
| 121 | 115 | } |
| 122 | 116 | ... | ... |