This commit is contained in:
zengtao01
2024-04-16 15:47:05 +08:00
parent 23bb203d36
commit ad8e9667dc
26 changed files with 770 additions and 24 deletions

View File

@ -66,7 +66,7 @@ public interface ErrorCodeConstants {
ErrorCode ALLOC_NOT_EXISTS = new ErrorCode(1_004_013_007, "订单明细不存在"); ErrorCode ALLOC_NOT_EXISTS = new ErrorCode(1_004_013_007, "订单明细不存在");
ErrorCode STORE_EVALUATE_NOT_EXISTS = new ErrorCode(1_004_013_008, "订单明细不存在"); ErrorCode STORE_EVALUATE_NOT_EXISTS = new ErrorCode(1_004_013_008, "订单明细不存在");
ErrorCode STORE_COMPLAIN_NOT_EXISTS = new ErrorCode(1_004_013_009, "订单明细不存在"); ErrorCode STORE_COMPLAIN_NOT_EXISTS = new ErrorCode(1_004_013_009, "订单明细不存在");
ErrorCode CUSTOMER_TRAFFIC_NOT_EXISTS = new ErrorCode(1_004_013_009, "订单明细不存在");
ErrorCode DINING_PLATES_NOT_EXISTS = new ErrorCode(1_004_099_000, "餐盘不存在"); ErrorCode DINING_PLATES_NOT_EXISTS = new ErrorCode(1_004_099_000, "餐盘不存在");
@ -79,4 +79,5 @@ public interface ErrorCodeConstants {
ErrorCode INSUFFICIENT_BALANCE = new ErrorCode(1_004_099_007, "余额不足30元,请充值"); ErrorCode INSUFFICIENT_BALANCE = new ErrorCode(1_004_099_007, "余额不足30元,请充值");
ErrorCode CARD_ALREADY_BIND = new ErrorCode(1_004_099_008, "卡号已绑定"); ErrorCode CARD_ALREADY_BIND = new ErrorCode(1_004_099_008, "卡号已绑定");
} }

View File

@ -89,6 +89,10 @@
<groupId>cn.iocoder.boot</groupId> <groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId> <artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
</dependency> </dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-websocket</artifactId>
</dependency>
</dependencies> </dependencies>

View File

@ -0,0 +1,102 @@
package cn.iocoder.yudao.module.member.controller.admin.customertraffic;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.member.controller.admin.customertraffic.vo.CustomerTrafficPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.customertraffic.vo.CustomerTrafficRespVO;
import cn.iocoder.yudao.module.member.controller.admin.customertraffic.vo.CustomerTrafficSaveReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.customertraffic.CustomerTrafficDO;
import cn.iocoder.yudao.module.member.service.customertraffic.CustomerTrafficService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Tag(name = "管理后台 - 顾客流量")
@RestController
@RequestMapping("/member/customer-traffic")
@Validated
public class CustomerTrafficController {
@Resource
private CustomerTrafficService customerTrafficService;
@PostMapping("/create")
@Operation(summary = "创建顾客流量")
@PreAuthorize("@ss.hasPermission('member:customer-traffic:create')")
public CommonResult<Long> createCustomerTraffic(@Valid @RequestBody CustomerTrafficSaveReqVO createReqVO) {
return success(customerTrafficService.createCustomerTraffic(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新顾客流量")
@PreAuthorize("@ss.hasPermission('member:customer-traffic:update')")
public CommonResult<Boolean> updateCustomerTraffic(@Valid @RequestBody CustomerTrafficSaveReqVO updateReqVO) {
customerTrafficService.updateCustomerTraffic(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除顾客流量")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('member:customer-traffic:delete')")
public CommonResult<Boolean> deleteCustomerTraffic(@RequestParam("id") Long id) {
customerTrafficService.deleteCustomerTraffic(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得顾客流量")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('member:customer-traffic:query')")
public CommonResult<CustomerTrafficRespVO> getCustomerTraffic(@RequestParam("id") Long id) {
CustomerTrafficDO customerTraffic = customerTrafficService.getCustomerTraffic(id);
return success(BeanUtils.toBean(customerTraffic, CustomerTrafficRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得顾客流量分页")
@PreAuthorize("@ss.hasPermission('member:customer-traffic:query')")
public CommonResult<PageResult<CustomerTrafficRespVO>> getCustomerTrafficPage(@Valid CustomerTrafficPageReqVO pageReqVO) {
PageResult<CustomerTrafficDO> pageResult = customerTrafficService.getCustomerTrafficPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, CustomerTrafficRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出顾客流量 Excel")
@PreAuthorize("@ss.hasPermission('member:customer-traffic:export')")
@OperateLog(type = EXPORT)
public void exportCustomerTrafficExcel(@Valid CustomerTrafficPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<CustomerTrafficDO> list = customerTrafficService.getCustomerTrafficPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "顾客流量.xls", "数据", CustomerTrafficRespVO.class,
BeanUtils.toBean(list, CustomerTrafficRespVO.class));
}
}

View File

@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.member.controller.admin.customertraffic.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 顾客流量分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CustomerTrafficPageReqVO extends PageParam {
@Schema(description = "时间节点")
private String timePoint;
@Schema(description = "门店id", example = "19185")
private Long storeId;
@Schema(description = "顾客数")
private Integer customerNum;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,36 @@
package cn.iocoder.yudao.module.member.controller.admin.customertraffic.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 顾客流量 Response VO")
@Data
@ExcelIgnoreUnannotated
public class CustomerTrafficRespVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8312")
@ExcelProperty("编号")
private Long id;
@Schema(description = "时间节点")
@ExcelProperty("时间节点")
private String timePoint;
@Schema(description = "门店id", example = "19185")
@ExcelProperty("门店id")
private Long storeId;
@Schema(description = "顾客数")
@ExcelProperty("顾客数")
private Integer customerNum;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.member.controller.admin.customertraffic.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 顾客流量新增/修改 Request VO")
@Data
public class CustomerTrafficSaveReqVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8312")
private Long id;
@Schema(description = "时间节点")
private String timePoint;
@Schema(description = "门店id", example = "19185")
private Long storeId;
@Schema(description = "顾客数")
private Integer customerNum;
}

View File

@ -0,0 +1,69 @@
package cn.iocoder.yudao.module.member.controller.admin.screen;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.member.controller.admin.customertraffic.vo.CustomerTrafficRespVO;
import cn.iocoder.yudao.module.member.controller.admin.screen.vo.DishVo;
import cn.iocoder.yudao.module.member.dal.dataobject.customertraffic.CustomerTrafficDO;
import cn.iocoder.yudao.module.member.service.customertraffic.CustomerTrafficService;
import cn.iocoder.yudao.module.member.service.order.OrderService;
import cn.iocoder.yudao.module.member.service.orderdetail.OrderDetailService;
import cn.iocoder.yudao.module.member.service.storeevaluate.StoreEvaluateService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
/**
* @author zt
* @description <description class purpose>
* @since 2024/4/16
*/
@Tag(name = "管理后台 - 大屏")
@RestController
@RequestMapping("/member/screen")
@PermitAll
public class ScreenController {
@Resource
private StoreEvaluateService storeEvaluateService;
@Resource
private CustomerTrafficService customerTrafficService;
@Resource
private OrderService orderService;
@Resource
private OrderDetailService orderDetailService;
@GetMapping("/getEvaluate")
@Operation(summary = "获得店铺评价,1-好评2-差评")
public Map<String,String> getEvaluate(){
return storeEvaluateService.getEvaluate();
}
@GetMapping("/getData")
@Operation(summary = "食堂今日顾客流量")
public CommonResult<List<CustomerTrafficRespVO>> getData() {
List<CustomerTrafficDO> data = customerTrafficService.getData();
return success(BeanUtils.toBean(data, CustomerTrafficRespVO.class));
}
@GetMapping("/getUserCount")
@Operation(summary = "获取总顾客流量")
public CommonResult<Integer> getUserCount() {
return success(orderService.selectTodayUser());
}
@GetMapping("/selectDishSale")
@Operation(summary = "菜品今日销售")
public CommonResult<List<DishVo>> selectDishSale() {
return success(orderDetailService.selectDishSale());
}
}

View File

@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.member.controller.admin.screen.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
/**
* @author zt
* @description <description class purpose>
* @since 2024/4/16
*/
@Data
public class DishVo {
@Schema(description = "菜品")
private String dishesName;
@Schema(description = "重量")
private BigDecimal weight;
@Schema(description = "价钱")
private BigDecimal price;
}

View File

@ -1,33 +1,38 @@
package cn.iocoder.yudao.module.member.controller.admin.storeevaluate; package cn.iocoder.yudao.module.member.controller.admin.storeevaluate;
import org.springframework.web.bind.annotation.*; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; import cn.iocoder.yudao.module.member.controller.admin.storeevaluate.vo.StoreEvaluatePageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.storeevaluate.vo.StoreEvaluateRespVO;
import cn.iocoder.yudao.module.member.controller.admin.storeevaluate.vo.*; import cn.iocoder.yudao.module.member.controller.admin.storeevaluate.vo.StoreEvaluateSaveReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.storeevaluate.StoreEvaluateDO; import cn.iocoder.yudao.module.member.dal.dataobject.storeevaluate.StoreEvaluateDO;
import cn.iocoder.yudao.module.member.service.storeevaluate.StoreEvaluateService; import cn.iocoder.yudao.module.member.service.storeevaluate.StoreEvaluateService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Tag(name = "管理后台 - 店铺评价") @Tag(name = "管理后台 - 店铺评价")
@RestController @RestController
@ -92,4 +97,7 @@ public class StoreEvaluateController {
BeanUtils.toBean(list, StoreEvaluateRespVO.class)); BeanUtils.toBean(list, StoreEvaluateRespVO.class));
} }
} }

View File

@ -0,0 +1,47 @@
package cn.iocoder.yudao.module.member.dal.dataobject.customertraffic;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* 顾客流量 DO
*
* @author 开发账号
*/
@TableName("member_customer_traffic")
@KeySequence("member_customer_traffic_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CustomerTrafficDO extends BaseDO {
/**
* 编号
*/
@TableId
private Long id;
/**
* 时间节点
*/
private String timePoint;
/**
* 门店id
*/
private Long storeId;
/**
* 顾客数
*/
private Integer customerNum;
}

View File

@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.member.dal.mysql.customertraffic;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.member.dal.dataobject.customertraffic.CustomerTrafficDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.member.controller.admin.customertraffic.vo.*;
/**
* 顾客流量 Mapper
*
* @author 开发账号
*/
@Mapper
public interface CustomerTrafficMapper extends BaseMapperX<CustomerTrafficDO> {
default PageResult<CustomerTrafficDO> selectPage(CustomerTrafficPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<CustomerTrafficDO>()
.eqIfPresent(CustomerTrafficDO::getTimePoint, reqVO.getTimePoint())
.eqIfPresent(CustomerTrafficDO::getStoreId, reqVO.getStoreId())
.eqIfPresent(CustomerTrafficDO::getCustomerNum, reqVO.getCustomerNum())
.betweenIfPresent(CustomerTrafficDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(CustomerTrafficDO::getId));
}
}

View File

@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.member.controller.admin.order.vo.OrderDetailsReqV
import cn.iocoder.yudao.module.member.controller.app.order.vo.AppOrderPageReqVO; import cn.iocoder.yudao.module.member.controller.app.order.vo.AppOrderPageReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.order.DishOrderDO; import cn.iocoder.yudao.module.member.dal.dataobject.order.DishOrderDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@ -42,4 +44,7 @@ public interface DishOrderMapper extends BaseMapperX<DishOrderDO> {
.orderByDesc(DishOrderDO::getId)); .orderByDesc(DishOrderDO::getId));
} }
@Select("select count(distinct user_id) from member_dish_order where create_time between #{startTime} and #{endTime}")
Integer selectTodayUser(@Param("startTime") LocalDateTime startTime,@Param("endTime") LocalDateTime endTime);
} }

View File

@ -3,9 +3,15 @@ package cn.iocoder.yudao.module.member.dal.mysql.orderdetail;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.member.controller.admin.screen.vo.DishVo;
import cn.iocoder.yudao.module.member.controller.app.orderdetail.vo.AppOrderDetailPageReqVO; import cn.iocoder.yudao.module.member.controller.app.orderdetail.vo.AppOrderDetailPageReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.orderdetail.OrderDetailDO; import cn.iocoder.yudao.module.member.dal.dataobject.orderdetail.OrderDetailDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.time.LocalDateTime;
import java.util.List;
/** /**
* 订单明细 Mapper * 订单明细 Mapper
@ -26,4 +32,7 @@ public interface OrderDetailMapper extends BaseMapperX<OrderDetailDO> {
.orderByDesc(OrderDetailDO::getId)); .orderByDesc(OrderDetailDO::getId));
} }
@Select("select dishes_name, sum(a.weight) as weight , sum(a.price) as price from member_order_detail a where a.create_time between #{startTime} and #{endTime} group by a.dishes_id,a.dishes_name")
List<DishVo> selectDishSale(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
} }

View File

@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.member.service.order.OrderService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -22,7 +23,7 @@ import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* 物理删除 N 天前的任务日志的 Job * 自动扣款 Job
* *
* @author j-sentinel * @author j-sentinel
*/ */
@ -47,6 +48,7 @@ public class BalanceDeductionJob implements JobHandler {
@Override @Override
@TenantIgnore @TenantIgnore
@Transactional(rollbackFor = Exception.class)
public String execute(String param) { public String execute(String param) {
//查询扣费用户 //查询扣费用户
List<DiningPlatesDO> diningPlatesToCharging = platesService.getDiningPlatesToCharging(EXPIRATION_TIME); List<DiningPlatesDO> diningPlatesToCharging = platesService.getDiningPlatesToCharging(EXPIRATION_TIME);

View File

@ -0,0 +1,48 @@
package cn.iocoder.yudao.module.member.job;
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.member.dal.dataobject.customertraffic.CustomerTrafficDO;
import cn.iocoder.yudao.module.member.service.customertraffic.CustomerTrafficService;
import cn.iocoder.yudao.module.member.service.diningplates.DiningPlatesService;
import cn.iocoder.yudao.module.member.util.MemberConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* @author zt
* @description <description class purpose>
* @since 2024/4/15
*/
@Slf4j
@Component
public class CustomerTrafficJob implements JobHandler {
@Resource
private DiningPlatesService platesService;
@Resource
private CustomerTrafficService trafficService;
/**
* 10分钟为1轮
*/
private static final Integer ROUND_TIME = 10;
@Override
@TenantIgnore
public String execute(String param) {
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(MemberConstants.HOUR_FORMAT);
LocalDateTime localDateTime = LocalDateTime.now().withSecond(0);
Integer diningPlatesNum = platesService.getDiningPlatesNum(localDateTime,ROUND_TIME);
CustomerTrafficDO customerTrafficDO = new CustomerTrafficDO();
customerTrafficDO.setCustomerNum(diningPlatesNum).setTimePoint(localDateTime.format(dateFormatter));
trafficService.insertOne(customerTrafficDO);
log.info("[execute][顾客统计任务顾客数量 ({}) 个]", diningPlatesNum);
return String.format("顾客统计定时任务顾客数量 %s 个", diningPlatesNum);
}
}

View File

@ -0,0 +1,64 @@
package cn.iocoder.yudao.module.member.service.customertraffic;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.member.controller.admin.customertraffic.vo.CustomerTrafficPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.customertraffic.vo.CustomerTrafficSaveReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.customertraffic.CustomerTrafficDO;
import javax.validation.Valid;
import java.util.List;
/**
* 顾客流量 Service 接口
*
* @author 开发账号
*/
public interface CustomerTrafficService {
/**
* 创建顾客流量
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createCustomerTraffic(@Valid CustomerTrafficSaveReqVO createReqVO);
/**
* 更新顾客流量
*
* @param updateReqVO 更新信息
*/
void updateCustomerTraffic(@Valid CustomerTrafficSaveReqVO updateReqVO);
/**
* 删除顾客流量
*
* @param id 编号
*/
void deleteCustomerTraffic(Long id);
/**
* 获得顾客流量
*
* @param id 编号
* @return 顾客流量
*/
CustomerTrafficDO getCustomerTraffic(Long id);
/**
* 获得顾客流量分页
*
* @param pageReqVO 分页查询
* @return 顾客流量分页
*/
PageResult<CustomerTrafficDO> getCustomerTrafficPage(CustomerTrafficPageReqVO pageReqVO);
void insertOne(CustomerTrafficDO customerTrafficDO);
/**
* 获取最新7个时间节点的数据
*/
List<CustomerTrafficDO> getData();
}

View File

@ -0,0 +1,88 @@
package cn.iocoder.yudao.module.member.service.customertraffic;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.member.controller.admin.customertraffic.vo.CustomerTrafficPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.customertraffic.vo.CustomerTrafficSaveReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.customertraffic.CustomerTrafficDO;
import cn.iocoder.yudao.module.member.dal.mysql.customertraffic.CustomerTrafficMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.CUSTOMER_TRAFFIC_NOT_EXISTS;
/**
* 顾客流量 Service 实现类
*
* @author 开发账号
*/
@Service
@Validated
public class CustomerTrafficServiceImpl implements CustomerTrafficService {
@Resource
private CustomerTrafficMapper customerTrafficMapper;
@Override
public Long createCustomerTraffic(CustomerTrafficSaveReqVO createReqVO) {
// 插入
CustomerTrafficDO customerTraffic = BeanUtils.toBean(createReqVO, CustomerTrafficDO.class);
customerTrafficMapper.insert(customerTraffic);
// 返回
return customerTraffic.getId();
}
@Override
public void updateCustomerTraffic(CustomerTrafficSaveReqVO updateReqVO) {
// 校验存在
validateCustomerTrafficExists(updateReqVO.getId());
// 更新
CustomerTrafficDO updateObj = BeanUtils.toBean(updateReqVO, CustomerTrafficDO.class);
customerTrafficMapper.updateById(updateObj);
}
@Override
public void deleteCustomerTraffic(Long id) {
// 校验存在
validateCustomerTrafficExists(id);
// 删除
customerTrafficMapper.deleteById(id);
}
private void validateCustomerTrafficExists(Long id) {
if (customerTrafficMapper.selectById(id) == null) {
throw exception(CUSTOMER_TRAFFIC_NOT_EXISTS);
}
}
@Override
public CustomerTrafficDO getCustomerTraffic(Long id) {
return customerTrafficMapper.selectById(id);
}
@Override
public PageResult<CustomerTrafficDO> getCustomerTrafficPage(CustomerTrafficPageReqVO pageReqVO) {
return customerTrafficMapper.selectPage(pageReqVO);
}
@Override
public void insertOne(CustomerTrafficDO customerTrafficDO) {
customerTrafficMapper.insert(customerTrafficDO);
}
@Override
public List<CustomerTrafficDO> getData() {
LocalDateTime now = LocalDateTime.now();
List<CustomerTrafficDO> customerTrafficDOS = customerTrafficMapper.selectList(Wrappers.<CustomerTrafficDO>lambdaQuery()
.lt(CustomerTrafficDO::getCreateTime, now)
.orderByDesc(CustomerTrafficDO::getCustomerNum)
.last("limit 7"));
return customerTrafficDOS;
}
}

View File

@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserInfoCardVO;
import cn.iocoder.yudao.module.member.dal.dataobject.diningplates.DiningPlatesDO; import cn.iocoder.yudao.module.member.dal.dataobject.diningplates.DiningPlatesDO;
import javax.validation.Valid; import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
/** /**
@ -88,4 +89,6 @@ public interface DiningPlatesService {
Boolean checkBind(String diningPlatesNum); Boolean checkBind(String diningPlatesNum);
AppUserInfoCardVO appCheckBind(String diningPlatesNum); AppUserInfoCardVO appCheckBind(String diningPlatesNum);
Integer getDiningPlatesNum(LocalDateTime localDateTime,Integer time);
} }

View File

@ -1,8 +1,10 @@
package cn.iocoder.yudao.module.member.service.diningplates; package cn.iocoder.yudao.module.member.service.diningplates;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender;
import cn.iocoder.yudao.module.member.controller.admin.diningplates.vo.DiningPlatesPageReqVO; import cn.iocoder.yudao.module.member.controller.admin.diningplates.vo.DiningPlatesPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.diningplates.vo.DiningPlatesSaveReqVO; import cn.iocoder.yudao.module.member.controller.admin.diningplates.vo.DiningPlatesSaveReqVO;
import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserInfoCardVO; import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserInfoCardVO;
@ -15,6 +17,7 @@ import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
import cn.iocoder.yudao.module.member.service.card.CardService; import cn.iocoder.yudao.module.member.service.card.CardService;
import cn.iocoder.yudao.module.member.util.MemberConstants; import cn.iocoder.yudao.module.member.util.MemberConstants;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -23,7 +26,10 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List; import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@ -48,6 +54,8 @@ public class DiningPlatesServiceImpl implements DiningPlatesService {
private DishOrderMapper dishOrderMapper; private DishOrderMapper dishOrderMapper;
@Resource @Resource
private StringRedisTemplate stringRedisTemplate; private StringRedisTemplate stringRedisTemplate;
@Resource
private WebSocketMessageSender webSocketMessageSender;
@Override @Override
public Long createDiningPlates(DiningPlatesSaveReqVO createReqVO) { public Long createDiningPlates(DiningPlatesSaveReqVO createReqVO) {
@ -162,6 +170,8 @@ public class DiningPlatesServiceImpl implements DiningPlatesService {
AppUserInfoCardVO data = new AppUserInfoCardVO(); AppUserInfoCardVO data = new AppUserInfoCardVO();
data.setName(memberUserDO.getNickname()); data.setName(memberUserDO.getNickname());
data.setMoney(money); data.setMoney(money);
//afterBind(memberUserDO.getId());
return data; return data;
} }
@ -197,6 +207,8 @@ public class DiningPlatesServiceImpl implements DiningPlatesService {
AppUserInfoCardVO data = new AppUserInfoCardVO(); AppUserInfoCardVO data = new AppUserInfoCardVO();
data.setName(memberUserDO.getNickname()); data.setName(memberUserDO.getNickname());
data.setMoney(money); data.setMoney(money);
//afterBind(memberUserDO.getId());
return data; return data;
} }
@Override @Override
@ -253,4 +265,55 @@ public class DiningPlatesServiceImpl implements DiningPlatesService {
throw exception(INSUFFICIENT_BALANCE); throw exception(INSUFFICIENT_BALANCE);
} }
} }
@Override
public Integer getDiningPlatesNum(LocalDateTime localDateTime, Integer time) {
// 获取当前时间
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(MemberConstants.TIME_FORMAT);
LocalDateTime currentTime = localDateTime;
// 计算指定分钟之前的时间
LocalDateTime timeMinutesAgo = currentTime.minusMinutes(time);
String end = currentTime.format(dateFormatter);
String start = timeMinutesAgo.format(dateFormatter);
QueryWrapper<DiningPlatesDO> queryWrapper = new QueryWrapper<>();
queryWrapper.le("date_format(binding_time,'%Y-%m-%d %H:%i:%s')",end)
.gt("date_format(binding_time,'%Y-%m-%d %H:%i:%s')",start);
Integer l = diningPlatesMapper.selectCount(queryWrapper).intValue();
return l;
}
/**
* 绑定之后的操作
*/
public void afterBind(Long userId){
//判断是否已记录
LocalDate today = LocalDate.now();
// 一天的开始时间
LocalDateTime startOfDay = today.atStartOfDay();
// 一天的结束时间
LocalDateTime endOfDay = today.atTime(LocalTime.MAX);
List<DishOrderDO> dishOrderDOS = dishOrderMapper.selectList(Wrappers.<DishOrderDO>lambdaQuery()
.eq(DishOrderDO::getUserId, userId)
.between(DishOrderDO::getCreateTime, startOfDay, endOfDay));
if(dishOrderDOS.size() > 0){
return;
}
String s = stringRedisTemplate.opsForValue().get(MemberConstants.CUSTOMER_PREFIX);
if(StrUtil.isBlank(s)){
s = "1";
}else {
s = String.valueOf(Integer.valueOf(s)+1);
}
stringRedisTemplate.opsForValue().set(MemberConstants.CUSTOMER_PREFIX,s);
//根据餐盘对应的门店ID发送给对应的用户
webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), 1L, // 给指定用户
"demo-message-receive", s);
}
} }

View File

@ -83,6 +83,12 @@ public interface OrderService {
*/ */
List<DishOrderDO> getDishOrderByTime(LocalDateTime startTime ,LocalDateTime endTime ); List<DishOrderDO> getDishOrderByTime(LocalDateTime startTime ,LocalDateTime endTime );
PageResult<OrderDetailsRespVO> getPageOrderDetails(OrderDetailsReqVO reqVO); PageResult<OrderDetailsRespVO> getPageOrderDetails(OrderDetailsReqVO reqVO);
/**
* 获取今日顾客总量
* @return
*/
Integer selectTodayUser();
} }

View File

@ -28,7 +28,9 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -210,5 +212,22 @@ public class OrderServiceImpl implements OrderService {
.eq(DishOrderDO::getUserId,SecurityFrameworkUtils.getLoginUserId()) .eq(DishOrderDO::getUserId,SecurityFrameworkUtils.getLoginUserId())
.between(DishOrderDO::getCreateTime, startTime, endTime)); .between(DishOrderDO::getCreateTime, startTime, endTime));
return dishOrderDOS; return dishOrderDOS;
}
@Override
public Integer selectTodayUser() {
LocalDate today = LocalDate.now();
// 一天的开始时间
LocalDateTime startOfDay = today.atStartOfDay();
// 一天的结束时间
LocalDateTime endOfDay = today.atTime(LocalTime.MAX);
return dishOrderMapper.selectTodayUser(startOfDay,endOfDay);
} }
} }

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.member.service.orderdetail; package cn.iocoder.yudao.module.member.service.orderdetail;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.member.controller.admin.screen.vo.DishVo;
import cn.iocoder.yudao.module.member.controller.app.orderdetail.vo.AppOrderDetailPageReqVO; import cn.iocoder.yudao.module.member.controller.app.orderdetail.vo.AppOrderDetailPageReqVO;
import cn.iocoder.yudao.module.member.controller.app.orderdetail.vo.AppOrderDetailRespVO; import cn.iocoder.yudao.module.member.controller.app.orderdetail.vo.AppOrderDetailRespVO;
import cn.iocoder.yudao.module.member.controller.app.orderdetail.vo.AppOrderDetailSaveReqVO; import cn.iocoder.yudao.module.member.controller.app.orderdetail.vo.AppOrderDetailSaveReqVO;
@ -57,4 +58,6 @@ public interface OrderDetailService {
List<AppOrderDetailRespVO> selectListByOrderId(Long orderId); List<AppOrderDetailRespVO> selectListByOrderId(Long orderId);
List<OrderDetailDO> selectListByOrderIds(List<Long> orderIds); List<OrderDetailDO> selectListByOrderIds(List<Long> orderIds);
List<DishVo> selectDishSale();
} }

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.member.service.orderdetail;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.member.controller.admin.screen.vo.DishVo;
import cn.iocoder.yudao.module.member.controller.app.orderdetail.vo.AppOrderDetailPageReqVO; import cn.iocoder.yudao.module.member.controller.app.orderdetail.vo.AppOrderDetailPageReqVO;
import cn.iocoder.yudao.module.member.controller.app.orderdetail.vo.AppOrderDetailRespVO; import cn.iocoder.yudao.module.member.controller.app.orderdetail.vo.AppOrderDetailRespVO;
import cn.iocoder.yudao.module.member.controller.app.orderdetail.vo.AppOrderDetailSaveReqVO; import cn.iocoder.yudao.module.member.controller.app.orderdetail.vo.AppOrderDetailSaveReqVO;
@ -28,6 +29,9 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List; import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@ -174,4 +178,20 @@ public class OrderDetailServiceImpl implements OrderDetailService {
throw exception(2000_10_001,"无法获取设备编码"); throw exception(2000_10_001,"无法获取设备编码");
} }
} }
@Override
public List<DishVo> selectDishSale() {
// 获取当前日期
LocalDate today = LocalDate.now();
// 一天的开始时间
LocalDateTime startOfDay = today.atStartOfDay();
// 一天的结束时间
LocalDateTime endOfDay = today.atTime(LocalTime.MAX);
return orderDetailMapper.selectDishSale(startOfDay,endOfDay);
}
} }

View File

@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.member.controller.app.storeevaluate.vo.AppStoreEv
import cn.iocoder.yudao.module.member.dal.dataobject.storeevaluate.StoreEvaluateDO; import cn.iocoder.yudao.module.member.dal.dataobject.storeevaluate.StoreEvaluateDO;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.Map;
/** /**
* 店铺评价 Service 接口 * 店铺评价 Service 接口
@ -58,4 +59,8 @@ public interface StoreEvaluateService {
StoreEvaluateDO selectByUserId(Long storeId); StoreEvaluateDO selectByUserId(Long storeId);
Map<String,String> getEvaluate();
} }

View File

@ -15,10 +15,14 @@ import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.STORE_EVALUATE_NOT_EXISTS; import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.STORE_EVALUATE_NOT_EXISTS;
/** /**
* 店铺评价 Service 实现类 * 店铺评价 Service 实现类
* *
@ -101,4 +105,22 @@ public class StoreEvaluateServiceImpl implements StoreEvaluateService {
.last(MemberConstants.LIMIT_ONE)); .last(MemberConstants.LIMIT_ONE));
return storeEvaluateDO; return storeEvaluateDO;
} }
@Override
public Map<String, String> getEvaluate() {
HashMap<String, String> result = new HashMap<>();
Long good = storeEvaluateMapper.selectCount(Wrappers.<StoreEvaluateDO>lambdaQuery()
.gt(StoreEvaluateDO::getEvaluate, MemberConstants.GOOD_EVALUATE));
Long total = storeEvaluateMapper.selectCount();
if(total == 0){
result.put("1","0");
result.put("0","0");
return result;
}
BigDecimal goodPercent = new BigDecimal(good).divide(new BigDecimal(total), 4, BigDecimal.ROUND_HALF_UP);
BigDecimal badPercent = BigDecimal.ONE.subtract(goodPercent);
result.put("1",goodPercent.multiply(new BigDecimal("100")).toString()+"%");
result.put("0",badPercent.multiply(new BigDecimal("100")).toString()+"%");
return result;
}
} }

View File

@ -24,6 +24,11 @@ public class MemberConstants {
*/ */
public static final String DATE_FORMAT = "yyyy-MM-dd"; public static final String DATE_FORMAT = "yyyy-MM-dd";
/**
* 时间格式
*/
public static final String HOUR_FORMAT = "HH:mm";
/** /**
* limit * limit
*/ */
@ -54,4 +59,13 @@ public class MemberConstants {
*/ */
public static final String EXCEED_PROPOSAL = "您本周摄入的热量超标,饮食均衡才能保证每天活动的能量和营养素供应充足,减肥也要吃饱,吃好哦。建议多吃水果,少吃肉类以及根茎类的蔬菜。以上建议不成为医疗建议"; public static final String EXCEED_PROPOSAL = "您本周摄入的热量超标,饮食均衡才能保证每天活动的能量和营养素供应充足,减肥也要吃饱,吃好哦。建议多吃水果,少吃肉类以及根茎类的蔬菜。以上建议不成为医疗建议";
/**
* 好评星级
*/
public static final String GOOD_EVALUATE = "3";
/**
* 门店顾客流量key
*/
public static final String CUSTOMER_PREFIX = "store";
} }