code review:文章管理

This commit is contained in:
YunaiV 2023-10-16 22:51:19 +08:00
parent cebdc190b6
commit 1ff9bc6a71
14 changed files with 33 additions and 79 deletions

View File

@ -1 +0,0 @@
ALTER TABLE member_user ADD COLUMN register_terminal tinyint NULL COMMENT '注册终端' AFTER register_ip;

View File

@ -1,49 +0,0 @@
-- 交易统计表
CREATE TABLE trade_statistics
(
id bigint AUTO_INCREMENT COMMENT '编号主键自增'
PRIMARY KEY,
time datetime NOT NULL COMMENT '统计日期',
order_create_count int DEFAULT 0 NOT NULL COMMENT '创建订单数',
order_pay_count int DEFAULT 0 NOT NULL COMMENT '支付订单商品数',
order_pay_price int DEFAULT 0 NOT NULL COMMENT '总支付金额单位',
order_wallet_pay_price int DEFAULT 0 NOT NULL COMMENT '总支付金额余额单位',
after_sale_count int DEFAULT 0 NOT NULL COMMENT '退款订单数',
after_sale_refund_price int DEFAULT 0 NOT NULL COMMENT '总退款金额单位',
brokerage_settlement_price int DEFAULT 0 NOT NULL COMMENT '佣金金额已结算单位',
recharge_pay_count int DEFAULT 0 NOT NULL COMMENT '充值订单数',
recharge_pay_price int DEFAULT 0 NOT NULL COMMENT '充值金额单位',
recharge_refund_count int DEFAULT 0 NOT NULL COMMENT '充值退款订单数',
recharge_refund_price int DEFAULT 0 NOT NULL COMMENT '充值退款金额单位',
creator varchar(64) DEFAULT '' NULL COMMENT '创建者',
create_time datetime DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '创建时间',
updater varchar(64) DEFAULT '' NULL COMMENT '更新者',
update_time datetime DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
deleted bit DEFAULT b'0' NOT NULL COMMENT '是否删除',
tenant_id bigint DEFAULT 0 NOT NULL COMMENT '租户编号'
)
COMMENT '交易统计表';
CREATE INDEX trade_statistics_time_index
ON trade_statistics (time);
-- 菜单
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name)
VALUES ('统计管理', '', 1, 4, 0, '/statistics', 'ep:data-line', '', '');
SELECT @parentId := LAST_INSERT_ID();
-- 交易统计
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name)
VALUES ('交易统计', '', 2, 1, @parentId, 'trade', 'fa-solid:credit-card', 'statistics/trade/index', 'TradeStatistics');
SELECT @parentId := LAST_INSERT_ID();
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('交易统计查询', 'statistics:trade:query', 3, 1, @parentId, '', '', '', 0);
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('交易统计导出', 'statistics:trade:export', 3, 2, @parentId, '', '', '', 0);
-- 会员统计
INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name)
VALUES ('会员统计', '', 2, 2, @parentId, 'member', 'ep:avatar', 'statistics/member/index', 'MemberStatistics');
SELECT @parentId := LAST_INSERT_ID();
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('会员统计查询', 'statistics:member:query', 3, 1, @parentId, '', '', '', 0);

View File

@ -31,6 +31,7 @@ public class AppArticleCategoryController {
public CommonResult<List<AppArticleCategoryRespVO>> getArticleCategoryList() { public CommonResult<List<AppArticleCategoryRespVO>> getArticleCategoryList() {
List<ArticleCategoryDO> categoryList = articleCategoryService.getArticleCategoryListByStatus( List<ArticleCategoryDO> categoryList = articleCategoryService.getArticleCategoryListByStatus(
CommonStatusEnum.ENABLE.getStatus()); CommonStatusEnum.ENABLE.getStatus());
// TODO @puhui999排序下
return success(ArticleCategoryConvert.INSTANCE.convertList04(categoryList)); return success(ArticleCategoryConvert.INSTANCE.convertList04(categoryList));
} }

View File

@ -39,7 +39,7 @@ public class AppArticleController {
@RequestParam(value = "recommendHot", required = false) Boolean recommendHot, @RequestParam(value = "recommendHot", required = false) Boolean recommendHot,
@RequestParam(value = "recommendBanner", required = false) Boolean recommendBanner) { @RequestParam(value = "recommendBanner", required = false) Boolean recommendBanner) {
return success(ArticleConvert.INSTANCE.convertList03( return success(ArticleConvert.INSTANCE.convertList03(
articleService.getArticleCategoryListByRecommendHotAndRecommendBanner(recommendHot, recommendBanner))); articleService.getArticleCategoryListByRecommend(recommendHot, recommendBanner)));
} }
@RequestMapping("/page") @RequestMapping("/page")
@ -55,4 +55,5 @@ public class AppArticleController {
return success(ArticleConvert.INSTANCE.convert01(articleService.getArticle(id))); return success(ArticleConvert.INSTANCE.convert01(articleService.getArticle(id)));
} }
// TODO @puhui999增加浏览量实现一个接口先简单做用户规模不大 +1 即可psuniapp 那边也要接下噢
} }

View File

@ -210,6 +210,7 @@ public interface CombinationActivityConvert {
* @param virtualGroupHeadRecord 虚拟成团团长记录 * @param virtualGroupHeadRecord 虚拟成团团长记录
* @return 虚拟记录列表 * @return 虚拟记录列表
*/ */
// TODO @puhui9991方法名建议改成 convertVirtualRecordList(CombinationRecordDO headRecord)2 220 225 可以搞成 mapstruct 一个方法默认都 copy 进去然后 set 226 232 的字段
default List<CombinationRecordDO> convertVirtualGroupList(CombinationRecordDO virtualGroupHeadRecord) { default List<CombinationRecordDO> convertVirtualGroupList(CombinationRecordDO virtualGroupHeadRecord) {
List<CombinationRecordDO> createRecords = new ArrayList<>(); List<CombinationRecordDO> createRecords = new ArrayList<>();
// 计算需要创建的虚拟成团记录数量 // 计算需要创建的虚拟成团记录数量

View File

@ -140,7 +140,7 @@ public interface CombinationRecordMapper extends BaseMapperX<CombinationRecordDO
} }
default List<CombinationRecordDO> selectListByHeadId(Long headId) { default List<CombinationRecordDO> selectListByHeadId(Long headId) {
return selectList(new LambdaQueryWrapperX<CombinationRecordDO>().eq(CombinationRecordDO::getHeadId, headId)); return selectList(CombinationRecordDO::getHeadId, headId);
} }
} }

View File

@ -56,6 +56,7 @@ public class ArticleCategoryServiceImpl implements ArticleCategoryService {
// 校验存在 // 校验存在
validateArticleCategoryExists(id); validateArticleCategoryExists(id);
// 校验是不是存在关联文章 // 校验是不是存在关联文章
// TODO @puhui999最好获得数量哈
List<ArticleDO> articleList = articleService.getArticleByCategoryId(id); List<ArticleDO> articleList = articleService.getArticleByCategoryId(id);
if (CollUtil.isNotEmpty(articleList)) { if (CollUtil.isNotEmpty(articleList)) {
throw exception(ARTICLE_CATEGORY_DELETE_FAIL_HAVE_ARTICLES); throw exception(ARTICLE_CATEGORY_DELETE_FAIL_HAVE_ARTICLES);
@ -83,6 +84,7 @@ public class ArticleCategoryServiceImpl implements ArticleCategoryService {
@Override @Override
public List<ArticleCategoryDO> getArticleCategoryListByStatus(Integer status) { public List<ArticleCategoryDO> getArticleCategoryListByStatus(Integer status) {
// TODO @puhui999selectListByStatus
return articleCategoryMapper.selectList(ArticleCategoryDO::getStatus, status); return articleCategoryMapper.selectList(ArticleCategoryDO::getStatus, status);
} }

View File

@ -62,7 +62,7 @@ public interface ArticleService {
* @param recommendBanner 是否轮播图 * @param recommendBanner 是否轮播图
* @return 文章详情列表 * @return 文章详情列表
*/ */
List<ArticleDO> getArticleCategoryListByRecommendHotAndRecommendBanner(Boolean recommendHot, Boolean recommendBanner); List<ArticleDO> getArticleCategoryListByRecommend(Boolean recommendHot, Boolean recommendBanner);
/** /**
* 获得文章详情分页 * 获得文章详情分页

View File

@ -30,6 +30,7 @@ public class ArticleServiceImpl implements ArticleService {
@Resource @Resource
private ArticleMapper articleMapper; private ArticleMapper articleMapper;
@Resource @Resource
private ArticleCategoryService articleCategoryService; private ArticleCategoryService articleCategoryService;
@ -89,7 +90,7 @@ public class ArticleServiceImpl implements ArticleService {
} }
@Override @Override
public List<ArticleDO> getArticleCategoryListByRecommendHotAndRecommendBanner(Boolean recommendHot, Boolean recommendBanner) { public List<ArticleDO> getArticleCategoryListByRecommend(Boolean recommendHot, Boolean recommendBanner) {
return articleMapper.selectList(recommendHot, recommendBanner); return articleMapper.selectList(recommendHot, recommendBanner);
} }

View File

@ -351,9 +351,10 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
convertSet(headExpireRecords, CombinationRecordDO::getActivityId)); convertSet(headExpireRecords, CombinationRecordDO::getActivityId));
Map<Long, CombinationActivityDO> activityMap = convertMap(activities, CombinationActivityDO::getId); Map<Long, CombinationActivityDO> activityMap = convertMap(activities, CombinationActivityDO::getId);
// 3. 改成每个团处理一次哈这样 handleExpireRecordhandleVirtualGroupRecord 都改成按团处理每个是一个小事务 // 3. 逐个处理拼团过期 or 虚拟成团
KeyValue<Integer, Integer> keyValue = new KeyValue<>(0, 0); // 统计过期拼团和虚拟成团 KeyValue<Integer, Integer> keyValue = new KeyValue<>(0, 0); // 统计过期拼团和虚拟成团
for (CombinationRecordDO recordDO : headExpireRecords) { for (CombinationRecordDO recordDO : headExpireRecords) {
// TODO @puhui999recordDO 非必要的情况下不用带 DO直接 record;
try { try {
CombinationActivityDO activity = activityMap.get(recordDO.getActivityId()); CombinationActivityDO activity = activityMap.get(recordDO.getActivityId());
if (activity == null || !activity.getVirtualGroup()) { // 取不到活动的或者不是虚拟拼团的 if (activity == null || !activity.getVirtualGroup()) { // 取不到活动的或者不是虚拟拼团的
@ -366,9 +367,9 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
keyValue.setValue(keyValue.getValue() + 1); keyValue.setValue(keyValue.getValue() + 1);
} }
} catch (Exception ignored) { // 处理异常继续循环 } catch (Exception ignored) { // 处理异常继续循环
// TODO @puhui999需要打印异常日志
} }
} }
return keyValue; return keyValue;
} }
@ -379,6 +380,8 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void handleExpireRecord(CombinationRecordDO headExpireRecord) { public void handleExpireRecord(CombinationRecordDO headExpireRecord) {
// TODO @puhui999这里的 null 其实不用判断真出现应该要处个 npe因为就是要错哈
// TODO @puhui999headExpireRecord 可以简化成 headRecord
if (headExpireRecord == null) { if (headExpireRecord == null) {
return; return;
} }
@ -386,14 +389,13 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
// 1.更新拼团记录 // 1.更新拼团记录
List<CombinationRecordDO> headsAndRecords = updateBatchCombinationRecords(headExpireRecord, List<CombinationRecordDO> headsAndRecords = updateBatchCombinationRecords(headExpireRecord,
CombinationRecordStatusEnum.FAILED); CombinationRecordStatusEnum.FAILED);
// TODO @puhui999这里的 null 其实不用判断真出现应该要处个 npe因为就是要错哈
if (headsAndRecords == null) { if (headsAndRecords == null) {
return; return;
} }
// 2.订单取消 // 2.订单取消
headsAndRecords.forEach(item -> { headsAndRecords.forEach(item -> tradeOrderApi.cancelPaidOrder(item.getUserId(), item.getOrderId()));
tradeOrderApi.cancelPaidOrder(item.getUserId(), item.getOrderId());
});
} }
/** /**
@ -403,6 +405,8 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void handleVirtualGroupRecord(CombinationRecordDO virtualGroupHeadRecord) { public void handleVirtualGroupRecord(CombinationRecordDO virtualGroupHeadRecord) {
// TODO @puhui999这里的 null 其实不用判断真出现应该要处个 npe因为就是要错哈
// TODO @puhui999headExpireRecord 可以简化成 headRecord
if (virtualGroupHeadRecord == null) { if (virtualGroupHeadRecord == null) {
return; return;
} }
@ -413,18 +417,21 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
updateBatchCombinationRecords(virtualGroupHeadRecord, CombinationRecordStatusEnum.SUCCESS); updateBatchCombinationRecords(virtualGroupHeadRecord, CombinationRecordStatusEnum.SUCCESS);
} }
// TODO @puhui999写下方法注释
private List<CombinationRecordDO> updateBatchCombinationRecords(CombinationRecordDO headRecord, CombinationRecordStatusEnum status) { private List<CombinationRecordDO> updateBatchCombinationRecords(CombinationRecordDO headRecord, CombinationRecordStatusEnum status) {
// 1. 查询团成员包含团长 // 1. 查询团成员包含团长
List<CombinationRecordDO> records = combinationRecordMapper.selectListByHeadId(headRecord.getId()); List<CombinationRecordDO> records = combinationRecordMapper.selectListByHeadId(headRecord.getId());
// TODO @puhui999是不是不用判断空哈例如说就一个团长然后过期
if (CollUtil.isEmpty(records)) { if (CollUtil.isEmpty(records)) {
return null; return null;
} }
records.add(headRecord);// 把团长加进去 records.add(headRecord);// 把团长加进去
// 2.批量更新拼团记录 status 失败/成团时间 // 2. 批量更新拼团记录 status endTime
List<CombinationRecordDO> updateRecords = new ArrayList<>(records.size()); List<CombinationRecordDO> updateRecords = new ArrayList<>(records.size());
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
records.forEach(item -> { records.forEach(item -> {
// TODO @puhui999record 改成 updateRecord
CombinationRecordDO record = new CombinationRecordDO().setId(item.getId()) CombinationRecordDO record = new CombinationRecordDO().setId(item.getId())
.setStatus(status.getStatus()).setEndTime(now); .setStatus(status.getStatus()).setEndTime(now);
if (CombinationRecordStatusEnum.isSuccess(status.getStatus())) { // 虚拟成团完事更改状态成功后还需要把参与人数修改为成团需要人数 if (CombinationRecordStatusEnum.isSuccess(status.getStatus())) { // 虚拟成团完事更改状态成功后还需要把参与人数修改为成团需要人数

View File

@ -93,19 +93,11 @@ public interface TradeOrderMapper extends BaseMapperX<TradeOrderDO> {
return selectOne(TradeOrderDO::getPickUpVerifyCode, pickUpVerifyCode); return selectOne(TradeOrderDO::getPickUpVerifyCode, pickUpVerifyCode);
} }
/** default TradeOrderDO selectByUserIdAndCombinationActivityIdAndStatus(Long userId, Long combinationActivityId, Integer status) {
* 只针对 combinationActivityId 的查询
*
* @param userId 用户编号
* @param activityId 拼团活动编号
* @param status 订单状态
* @return 交易订单
*/
default TradeOrderDO selectByUserIdAndCombinationActivityIdAndStatus(Long userId, Long activityId, Integer status) {
return selectOne(new LambdaQueryWrapperX<TradeOrderDO>() return selectOne(new LambdaQueryWrapperX<TradeOrderDO>()
.eq(TradeOrderDO::getUserId, userId) .eq(TradeOrderDO::getUserId, userId)
.eq(TradeOrderDO::getStatus, status) .eq(TradeOrderDO::getStatus, status)
.eq(TradeOrderDO::getCombinationActivityId, activityId) .eq(TradeOrderDO::getCombinationActivityId, combinationActivityId)
); );
} }

View File

@ -42,11 +42,11 @@ public interface TradeOrderQueryService {
* 获得指定用户指定活动指定状态的交易订单 * 获得指定用户指定活动指定状态的交易订单
* *
* @param userId 用户编号 * @param userId 用户编号
* @param activityId 活动编号 * @param combinationActivityId 活动编号
* @param status 订单状态 * @param status 订单状态
* @return 交易订单 * @return 交易订单
*/ */
TradeOrderDO getCombinationActivityOrderByUserIdAndCombinationActivityIdAndStatus(Long userId, Long activityId, Integer status); TradeOrderDO getOrderByUserIdAndStatusAndCombination(Long userId, Long combinationActivityId, Integer status);
/** /**
* 获得订单列表 * 获得订单列表

View File

@ -71,8 +71,8 @@ public class TradeOrderQueryServiceImpl implements TradeOrderQueryService {
} }
@Override @Override
public TradeOrderDO getCombinationActivityOrderByUserIdAndCombinationActivityIdAndStatus(Long userId, Long activityId, Integer status) { public TradeOrderDO getOrderByUserIdAndStatusAndCombination(Long userId, Long combinationActivityId, Integer status) {
return tradeOrderMapper.selectByUserIdAndCombinationActivityIdAndStatus(userId, activityId, status); return tradeOrderMapper.selectByUserIdAndCombinationActivityIdAndStatus(userId, combinationActivityId, status);
} }
@Override @Override

View File

@ -49,7 +49,7 @@ public class TradeCombinationOrderHandler implements TradeOrderHandler {
order.getCombinationHeadId(), item.getSkuId(), item.getCount()); order.getCombinationHeadId(), item.getSkuId(), item.getCount());
// 2. 校验该用户是否存在未支付的拼团活动订单避免一个拼团可以下多个单子了 // 2. 校验该用户是否存在未支付的拼团活动订单避免一个拼团可以下多个单子了
TradeOrderDO activityOrder = orderQueryService.getCombinationActivityOrderByUserIdAndCombinationActivityIdAndStatus( TradeOrderDO activityOrder = orderQueryService.getOrderByUserIdAndStatusAndCombination(
order.getUserId(), order.getCombinationActivityId(), TradeOrderStatusEnum.UNPAID.getStatus()); order.getUserId(), order.getCombinationActivityId(), TradeOrderStatusEnum.UNPAID.getStatus());
if (activityOrder != null) { if (activityOrder != null) {
throw exception(ORDER_CREATE_FAIL_EXIST_UNPAID); throw exception(ORDER_CREATE_FAIL_EXIST_UNPAID);
@ -69,9 +69,8 @@ public class TradeCombinationOrderHandler implements TradeOrderHandler {
CombinationRecordCreateRespDTO combinationRecord = combinationRecordApi.createCombinationRecord( CombinationRecordCreateRespDTO combinationRecord = combinationRecordApi.createCombinationRecord(
TradeOrderConvert.INSTANCE.convert(order, item)); TradeOrderConvert.INSTANCE.convert(order, item));
// 3. 更新拼团相关信息到订单 // 3. 更新拼团相关信息到订单为什么几个字段都要更新
// 为什么几个字段都要更新原因是 // 原因是如果创建订单时自己是团长的情况下 combinationHeadId 是为 null 设置团长编号这个操作时在订单是否后创建拼团记录时才设置的
// 如果创建订单时自己是团长的情况下 combinationHeadId 是为 null 设置团长编号这个操作时在订单是否后创建拼团记录时才设置的
orderUpdateService.updateOrderCombinationInfo(order.getId(), order.getCombinationActivityId(), orderUpdateService.updateOrderCombinationInfo(order.getId(), order.getCombinationActivityId(),
combinationRecord.getCombinationRecordId(), combinationRecord.getCombinationHeadId()); combinationRecord.getCombinationRecordId(), combinationRecord.getCombinationHeadId());
} }