feat:个人喜好分析

This commit is contained in:
dzc committed 2025-08-13 19:04:28 +08:00
1 parent 702949a3a9
commit 9fef8f0a0a
9 files changed
+176 -27

No files matched your search

+22
View File
@@ -388,6 +388,28 @@ CREATE TABLE hard_appt
PRIMARY KEY (id)
) ENGINE = InnoDB COMMENT ='设备预约管理';
-- ----------------------------
-- Table structure for hard_table_manage
-- ----------------------------
DROP TABLE IF EXISTS hard_table_manage;
CREATE TABLE hard_table_manage
(
id bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
merchant_id bigint COMMENT '商户id',
code varchar(128) NOT NULL COMMENT '编号',
enable char(1) NOT NULL COMMENT '是否启用',
qr_code varchar(256) DEFAULT NULL COMMENT '二维码',
remark varchar(256) DEFAULT NULL COMMENT '备注',
create_by varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人',
create_time datetime DEFAULT NULL COMMENT '创建时间',
update_by varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '修改人',
update_time datetime DEFAULT NULL COMMENT '修改时间',
del_flag char(1) COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '删除标记',
tenant_id bigint DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (id)
) ENGINE = InnoDB COMMENT ='预约桌子管理';
-- ----------------------------
-- Table structure for hard_auth
-- ----------------------------
@@ -26,6 +26,8 @@ public enum HardPayTypeEnum {
HARD_DOOR_FREE_PAY("9", "智能柜免密支付"),
WECHANT_SELF_QR_CODE_PAY("10", "微信付款码支付"),
ALI_SELF_QR_CODE_PAY("11", "支付宝付款码支付"),
ZYY("12", "中医院"),
RMYY("13", "人民医院"),
;
private final String type;
private final String description;
@@ -0,0 +1,13 @@
package com.bsd.pjcloud.hard.api.dto.order.app;
import lombok.Data;
/**
* 个人菜品喜好排行
*/
@Data
public class HardAppProductLikeTopDto {
private Long userId;
}
@@ -0,0 +1,27 @@
package com.bsd.pjcloud.hard.api.vo.order.app;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 菜品销量按照分类查询
*/
@Data
public class HardAppProductLikeTopVo {
@Schema(description = "分类id")
private Long classifyId;
@Schema(description = "分类名")
private String classifyName;
@Schema(description = "商品id")
private Long productId;
@Schema(description = "商品名")
private String productName;
@Schema(description = "购买总数")
private Long payCount;
}
@@ -1,17 +1,22 @@
package com.bsd.pjcloud.hard.controller.order;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.common.security.annotation.Inner;
import com.bsd.pjcloud.common.security.service.PjcloudUser;
import com.bsd.pjcloud.common.security.util.SecurityUtils;
import com.bsd.pjcloud.hard.api.dto.order.HardCarDto;
import com.bsd.pjcloud.hard.api.dto.order.app.HardAppProductByCanteenDto;
import com.bsd.pjcloud.hard.api.dto.order.app.HardAppProductByClassifyDto;
import com.bsd.pjcloud.hard.api.dto.order.app.HardAppProductLikeTopDto;
import com.bsd.pjcloud.hard.api.vo.order.HardCanteenProductTotalVo;
import com.bsd.pjcloud.hard.api.dto.order.HardOrderDto;
import com.bsd.pjcloud.hard.api.vo.order.HardCarVo;
import com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductByCanteenVo;
import com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductByClassifyVo;
import com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductLikeTopVo;
import com.bsd.pjcloud.hard.service.HardCanteenTotalService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
@@ -22,6 +27,7 @@ import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* 食堂统计
@@ -52,10 +58,24 @@ public class HardCanteenTotalController {
@Inner(value = false)
@Operation(summary = "近一周各个食堂菜品购买统计", description = "近一周各个食堂菜品购买统计")
@PostMapping("/app/product-by-canteen")
public R<List<HardAppProductByCanteenVo>> productByCanteen(@RequestBody HardAppProductByCanteenDto dto) {
public R<List<Map<String, List<HardAppProductByCanteenVo>>>> productByCanteen(@RequestBody HardAppProductByCanteenDto dto) {
return R.ok(canteenTotalService.productByCanteen(dto));
}
/**
* 个人菜品喜好排行
*/
@Inner(value = false)
@Operation(summary = "个人菜品喜好排行", description = "个人菜品喜好排行")
@PostMapping("/app/product-like-top")
public R<List<HardAppProductLikeTopVo>> productLikeTop(@RequestBody HardAppProductLikeTopDto dto) {
PjcloudUser user = SecurityUtils.getUser();
if (ObjectUtil.isNotEmpty(user)) {
dto.setUserId(user.getId());
}
return R.ok(canteenTotalService.productLikeTop(dto));
}
/* ************************************* start app start ************************************* */
@Operation(summary = "根据部门 食堂菜品购买统计", description = "根据部门 食堂菜品购买统计")
@PostMapping("/proudct-total-by-dept")
@@ -5,6 +5,7 @@ import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper;
import com.bsd.pjcloud.hard.api.dto.order.app.HardAppProductByCanteenDto;
import com.bsd.pjcloud.hard.api.dto.order.app.HardAppProductByClassifyDto;
import com.bsd.pjcloud.hard.api.dto.order.app.HardAppProductLikeTopDto;
import com.bsd.pjcloud.hard.api.vo.order.HardCanteenProductTotalVo;
import com.bsd.pjcloud.hard.api.dto.order.HardCarDto;
import com.bsd.pjcloud.hard.api.dto.order.HardOrderDto;
@@ -12,6 +13,7 @@ import com.bsd.pjcloud.hard.api.entity.order.HardCarEntity;
import com.bsd.pjcloud.hard.api.vo.order.HardCarVo;
import com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductByCanteenVo;
import com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductByClassifyVo;
import com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductLikeTopVo;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -47,4 +49,9 @@ public interface HardCarMapper extends PjcloudBaseMapper<HardCarEntity> {
* 各个食堂菜品购买统计
*/
List<HardAppProductByCanteenVo> productByCanteen(@Param("dto") HardAppProductByCanteenDto dto);
/**
* 个人菜品喜好排行
*/
List<HardAppProductLikeTopVo> productLikeTop(@Param("dto") HardAppProductLikeTopDto dto);
}
@@ -6,13 +6,16 @@ import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.hard.api.dto.order.HardCarDto;
import com.bsd.pjcloud.hard.api.dto.order.app.HardAppProductByCanteenDto;
import com.bsd.pjcloud.hard.api.dto.order.app.HardAppProductByClassifyDto;
import com.bsd.pjcloud.hard.api.dto.order.app.HardAppProductLikeTopDto;
import com.bsd.pjcloud.hard.api.vo.order.HardCanteenProductTotalVo;
import com.bsd.pjcloud.hard.api.dto.order.HardOrderDto;
import com.bsd.pjcloud.hard.api.vo.order.HardCarVo;
import com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductByCanteenVo;
import com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductByClassifyVo;
import com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductLikeTopVo;
import java.util.List;
import java.util.Map;
public interface HardCanteenTotalService {
@@ -24,7 +27,12 @@ public interface HardCanteenTotalService {
/**
* 近一周各个食堂菜品购买统计
*/
List<HardAppProductByCanteenVo> productByCanteen(HardAppProductByCanteenDto dto);
List<Map<String, List<HardAppProductByCanteenVo>>> productByCanteen(HardAppProductByCanteenDto dto);
/**
* 个人菜品喜好排行
*/
List<HardAppProductLikeTopVo> productLikeTop(HardAppProductLikeTopDto dto);
/**
* 根据部门 食堂菜品购买统计
@@ -15,11 +15,13 @@ import com.bsd.pjcloud.hard.api.constant.total.DateRangeTypeEnum;
import com.bsd.pjcloud.hard.api.dto.order.HardCarDto;
import com.bsd.pjcloud.hard.api.dto.order.app.HardAppProductByCanteenDto;
import com.bsd.pjcloud.hard.api.dto.order.app.HardAppProductByClassifyDto;
import com.bsd.pjcloud.hard.api.dto.order.app.HardAppProductLikeTopDto;
import com.bsd.pjcloud.hard.api.vo.order.HardCanteenProductTotalVo;
import com.bsd.pjcloud.hard.api.dto.order.HardOrderDto;
import com.bsd.pjcloud.hard.api.vo.order.HardCarVo;
import com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductByCanteenVo;
import com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductByClassifyVo;
import com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductLikeTopVo;
import com.bsd.pjcloud.hard.mapper.order.HardCarMapper;
import com.bsd.pjcloud.hard.mapper.order.HardOrderMapper;
import com.bsd.pjcloud.hard.service.HardCanteenTotalService;
@@ -83,7 +85,7 @@ public class HardCanteenTotalServiceImpl implements HardCanteenTotalService {
* 近一周各个食堂菜品购买统计
*/
@Override
public List<HardAppProductByCanteenVo> productByCanteen(HardAppProductByCanteenDto dto) {
public List<Map<String, List<HardAppProductByCanteenVo>>> productByCanteen(HardAppProductByCanteenDto dto) {
dto.setPayTimeList(new LocalDate[]{LocalDate.now().minusWeeks(1), LocalDate.now()});
// 查询近一周的时间
List<HardAppProductByCanteenVo> dateList = new LinkedList<>();
@@ -95,22 +97,47 @@ public class HardCanteenTotalServiceImpl implements HardCanteenTotalService {
dateList.add(entity);
currentDate = currentDate.plusDays(1);
}
// 查询自营食堂
List<MchManageVo> mchList = remoteMchService.getByTypes(List.of(MerchantTypeEnum.CANTEEN.getType())).getData();
if (ObjectUtil.isEmpty(mchList)) return null;
List<Map<String, List<HardAppProductByCanteenVo>>> result = new ArrayList<>();
for (MchManageVo vo : mchList) {
result.add(Map.of(vo.getName(), dateList));
}
List<HardAppProductByCanteenVo> totalList = hardCarMapper.productByCanteen(dto);
if (ObjectUtil.isNotEmpty(totalList)) {
for (HardAppProductByCanteenVo vo : totalList) {
if (ObjectUtil.isEmpty(vo.getTime())) continue;
dateList.stream().filter(item -> ObjectUtil.equals(item.getTime(), vo.getTime())).findFirst().ifPresent(target -> {
target.setCanteenId(vo.getCanteenId());
target.setPayCount(vo.getPayCount());
target.setTotalPrice(vo.getTotalPrice());
target.setTimeCount(vo.getTimeCount());
target.setPayUserCount(vo.getPayUserCount());
});
for (Map<String, List<HardAppProductByCanteenVo>> map : result) {
for (Map.Entry<String, List<HardAppProductByCanteenVo>> entry : map.entrySet()) {
String canteenName = entry.getKey();
List<HardAppProductByCanteenVo> canteenList = entry.getValue();
for (HardAppProductByCanteenVo vo : canteenList) {
dateList.stream().filter(item -> ObjectUtil.equals(item.getCanteenName(), canteenName) && ObjectUtil.equals(item.getTime(), vo.getTime())).findFirst().ifPresent(target -> {
target.setCanteenId(vo.getCanteenId());
target.setCanteenName(canteenName);
target.setPayCount(vo.getPayCount());
target.setTotalPrice(vo.getTotalPrice());
target.setTimeCount(vo.getTimeCount());
target.setPayUserCount(vo.getPayUserCount());
});
}
}
}
}
// 处理一下
disposeProductByCanteen(dateList);
return dateList;
return result;
}
/**
* 个人菜品喜好排行
*/
@Override
public List<HardAppProductLikeTopVo> productLikeTop(HardAppProductLikeTopDto dto) {
List<HardAppProductLikeTopVo> totalList = hardCarMapper.productLikeTop(dto);
disposeProductLikeTop(totalList);
return totalList;
}
/**
@@ -287,22 +314,23 @@ public class HardCanteenTotalServiceImpl implements HardCanteenTotalService {
}
}
private void disposeProductByCanteen(List<HardAppProductByCanteenVo> list) {
private void disposeProductLikeTop(List<HardAppProductLikeTopVo> list) {
if (ObjectUtil.isEmpty(list)) return;
// 处理商户
List<Long> canteenIdList = list.stream().map(HardAppProductByCanteenVo::getCanteenId).toList();
if (ObjectUtil.isNotEmpty(canteenIdList)) {
List<MchManageVo> mchList = remoteMchService.getByIds(canteenIdList).getData();
if (ObjectUtil.isNotEmpty(mchList)) {
Map<Long, MchManageVo> categoryMap = mchList.stream().collect(Collectors.toMap(MchManageVo::getId, v -> v));
for (HardAppProductByCanteenVo i : list) {
MchManageVo category = categoryMap.get(i.getCanteenId());
if (ObjectUtil.isNotEmpty(category)) {
i.setCanteenName(category.getName());
// 处理菜品分类
List<Long> classifyList = list.stream().map(HardAppProductLikeTopVo::getClassifyId).filter(ObjectUtil::isNotEmpty).distinct().toList();
if (ObjectUtil.isNotEmpty(classifyList)) {
List<CanteenCategoryEntity> categoryList = canteenCategoryService.getAllSimple(null, null).getData();
if (ObjectUtil.isNotEmpty(categoryList)) {
Map<Long, CanteenCategoryEntity> categoryMap = categoryList.stream().collect(Collectors.toMap(CanteenCategoryEntity::getId, v -> v));
if (ObjectUtil.isNotEmpty(categoryMap)) {
for (HardAppProductLikeTopVo i : list) {
CanteenCategoryEntity category = categoryMap.get(i.getClassifyId());
if (ObjectUtil.isNotEmpty(category)) {
i.setClassifyName(category.getName());
}
}
}
}
}
}
}
@@ -349,4 +349,26 @@
order by DATE_FORMAT(o.pay_time, '%Y-%m-%d')
</select>
<select id="productLikeTop" resultType="com.bsd.pjcloud.hard.api.vo.order.app.HardAppProductLikeTopVo">
select
a.product_id as productId,
a.product_name as productName,
s.category_id as classifyId,
SUM(a.product_count) as payCount
from pjcloudx_hardware.hard_car a
inner join pjcloudx_hardware.hard_parent_car p on a.parent_car_id = p.id and p.del_flag = '0'
inner join pjcloudx_hardware.hard_order o
on o.parent_car_id = p.id and o.del_flag = '0' and o.hour_type is not null and
o.hour_type not in ('-1')
left join pjcloudx_canteen.canteen_spu s on a.product_id = s.id
<where>
a.del_flag = '0'
<if test="dto.userId != null and dto.userId != '' ">
and o.user_id = #{dto.userId}
</if>
</where>
group by a.product_id
order by SUM(a.product_count) desc
limit 10;
</select>
</mapper>