Merge pull request 'wuyuxin_zhushi' (#6) from develop into main

main
m4bagu2fl 7 months ago
commit be5b38751a

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/sky/sky-common/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/sky/sky-pojo/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/sky/sky-server/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/sky/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/sky/src/main/resources" charset="UTF-8" />
</component>
</project>

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>

@ -0,0 +1,103 @@
package com.sky.constant;
/**
*
*
*/
public class MessageConstant {
/**
*
*/
public static final String PASSWORD_ERROR = "密码错误";
/**
* 访
*/
public static final String ACCOUNT_NOT_FOUND = "账号不存在";
/**
*
*/
public static final String ACCOUNT_LOCKED = "账号被锁定";
/**
*
*/
public static final String ALREADY_EXISTS = "已存在";
/**
*
*/
public static final String UNKNOWN_ERROR = "未知错误";
/**
*
*/
public static final String USER_NOT_LOGIN = "用户未登录";
/**
*
*/
public static final String CATEGORY_BE_RELATED_BY_SETMEAL = "当前分类关联了套餐,不能删除";
/**
*
*/
public static final String CATEGORY_BE_RELATED_BY_DISH = "当前分类关联了菜品,不能删除";
/**
*
*/
public static final String SHOPPING_CART_IS_NULL = "购物车数据为空,不能下单";
/**
* 簿
*/
public static final String ADDRESS_BOOK_IS_NULL = "用户地址为空,不能下单";
/**
*
*/
public static final String LOGIN_FAILED = "登录失败";
/**
*
*/
public static final String UPLOAD_FAILED = "文件上传失败";
/**
*
*/
public static final String SETMEAL_ENABLE_FAILED = "套餐内包含未启售菜品,无法启售";
/**
*
*/
public static final String PASSWORD_EDIT_FAILED = "密码修改失败";
/**
*
*/
public static final String DISH_ON_SALE = "起售中的菜品不能删除";
/**
*
*/
public static final String SETMEAL_ON_SALE = "起售中的套餐不能删除";
/**
*
*/
public static final String DISH_BE_RELATED_BY_SETMEAL = "当前菜品关联了套餐,不能删除";
/**
*
*/
public static final String ORDER_STATUS_ERROR = "订单状态错误";
/**
* ID
*/
public static final String ORDER_NOT_FOUND = "订单不存在";
}

@ -0,0 +1,20 @@
package com.sky.enumeration;
/**
*
* SQL
*/
public enum OperationType {
/**
*
* 使SQL UPDATE
*/
UPDATE,
/**
*
* 使SQL INSERT
*/
INSERT;
}

@ -0,0 +1,34 @@
package com.sky.exception;
/**
*
* <p>
* {@link RuntimeException}unchecked exception
*
* <p>
* 使
* -
* -
* -
*/
public class BaseException extends RuntimeException {
/**
*
* <p>
* 使
*/
public BaseException() {
super();
}
/**
*
*
* @param msg
*
*/
public BaseException(String msg) {
super(msg);
}
}

@ -0,0 +1,19 @@
package com.sky.exception;
/**
* PasswordEditFailedException
* BaseExceptionBaseException
* 便
*/
public class PasswordEditFailedException extends BaseException {
/**
* PasswordEditFailedException
*
* @param msg BaseException
* 便msg"密码长度不符合要求导致修改失败"
*/
public PasswordEditFailedException(String msg) {
super(msg);
}
}

@ -0,0 +1,30 @@
package com.sky.exception;
/**
* UserNotLoginException
*
* 便
* BaseExceptionBaseException
* 便
*/
public class UserNotLoginException extends BaseException {
/**
*
* 使
* 使便
*/
public UserNotLoginException() {
}
/**
*
*
* @param msg BaseException
*
* msg"用户未登录,无法访问个人资料页面"
*/
public UserNotLoginException(String msg) {
super(msg);
}
}

@ -0,0 +1,37 @@
package com.sky.properties;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
/**
* ReportExcelPropertiesExcel
* Spring Boot便使
* Excelsheet
*/
@Component
// 使用@Component注解将该类标记为Spring的组件这样Spring容器能够扫描并管理它使其可以在项目的其他地方通过依赖注入等方式使用。
@ConfigurationProperties(prefix = "sky.excel")
// @ConfigurationProperties注解用于指定配置属性的前缀Spring Boot会自动将配置文件中以"sky.excel"为前缀的属性值绑定到该类对应的成员变量上。
@Data
// 使用Lombok的@Data注解它会自动为类生成常用的方法比如Getter、Setter、toString、equals和hashCode等方法简化代码编写提高开发效率。
public class ReportExcelProperties {
/**
* Excel
*
* Spring Boot"sky.excel.filePath"
*/
private String filePath;
/**
* Excelsheet
* "sky.excel.sheet"便Excel
* "sky.excel.sheet[0]=Sheet1""sky.excel.sheet[1]=Sheet2"{"Sheet1", "Sheet2"}
*/
private String[] sheet;
}

@ -0,0 +1,113 @@
package com.sky.utils;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
/**
* AliOssUtilOSS
* OSSJava SDK便Spring BootOSSOSS访
*/
@Data
// 使用Lombok的@Data注解会自动为类中的私有成员变量生成对应的Getter、Setter方法以及toString、equals和hashCode等方法简化代码编写。
@Slf4j
// 使用Lombok的@Slf4j注解会在类中自动生成一个名为log的Slf4j日志记录器方便在代码中记录相关的操作信息、异常等情况便于调试和监控。
@Component
// 使用@Component注解将该类标记为Spring框架中的一个组件这样Spring容器能够自动扫描并管理它使得该类可以在项目的其他地方通过依赖注入等方式被使用。
@AllArgsConstructor
// 使用Lombok的@AllArgsConstructor注解会自动生成一个包含所有成员变量的构造函数方便在创建类实例时进行参数注入等操作。
@NoArgsConstructor
// 使用Lombok的@NoArgsConstructor注解会自动生成一个无参构造函数满足某些场景下需要默认构造函数的需求例如在一些框架进行对象实例化时可能会调用无参构造函数。
public class AliOssUtil {
/**
* OSS访Endpoint
* OSSEndpointOSS
* "oss-cn-hangzhou.aliyuncs.com"OSSapplication.propertiesapplication.yml
*/
private String endpoint;
/**
* OSS访IDAccess Key ID
* Access Key SecretOSSOSSAccess Key IDAccess Key Secret
*
*/
private String accessKeyId;
/**
* OSS访Access Key Secret
* Access Key ID使访OSS
*
*/
private String accessKeySecret;
/**
* OSSBucket
* OSSOSS
* 便使
*/
private String bucketName;
/**
* OSSOSS访
*
* @param bytes 便OSS
* @param objectName OSSOSSOSS
* @return OSS访URL"https://BucketName.Endpoint/ObjectName"便使访
*/
public String upload(byte[] bytes, String objectName) {
// 创建OSSClient实例。
// 通过OSSClientBuilder构建器使用传入的endpoint、accessKeyId和accessKeySecret来创建一个与阿里云OSS服务进行交互的客户端实例
// 该客户端实例将用于后续的文件上传等操作它封装了与OSS服务通信的底层细节提供了一系列方便的方法来操作OSS资源。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
// 创建PutObject请求。
// 使用ossClient的putObject方法创建一个文件上传请求将指定的字节数组内容通过ByteArrayInputStream包装后上传到指定的bucketName存储桶中以objectName作为对象名称。
// 这个操作实际上就是向OSS服务发送请求将本地的文件数据传输到云端存储桶里如果上传过程中出现OSS相关的异常情况会被相应的异常处理机制捕获。
ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
} catch (OSSException oe) {
// 捕获OSSException异常该异常表示请求已经发送到OSS服务端但由于某些原因如权限问题、资源不存在等被服务端拒绝并返回了错误响应信息。
// 下面的代码主要是将OSS服务端返回的详细错误信息打印出来方便开发人员定位问题例如错误消息、错误代码、请求ID以及主机ID等信息都有助于排查问题所在。
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
// 捕获ClientException异常该异常表示客户端在尝试与OSS服务进行通信时遇到了严重的内部问题比如无法访问网络等情况
// 通常是客户端自身环境或者配置方面的问题导致无法正常连接到OSS服务这里同样打印出错误消息以便分析是哪里出现了通信故障。
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient!= null) {
// 无论文件上传是否成功都需要关闭OSSClient实例释放相关的资源避免资源泄露保证程序的稳定性和性能。
ossClient.shutdown();
}
}
// 文件访问路径规则 https://BucketName.Endpoint/ObjectName
StringBuilder stringBuilder = new StringBuilder("https://");
stringBuilder
.append(bucketName)
.append(".")
.append(endpoint)
.append("/")
.append(objectName);
log.info("文件上传到:{}", stringBuilder);
return stringBuilder.toString();
}
}

@ -0,0 +1,17 @@
// 定义了一个名为DataOverViewQueryDTO的类它位于com.sky.dto包中。
// 这个类实现了Serializable接口这意味着它可以被序列化通常用于网络传输或持久化到文件中。
// 使用Lombok提供的注解@Data这个注解自动为类生成getter和setter方法以及equals、hashCode和toString方法。
// 使用@Builder注解这个注解自动为类生成一个Builder模式的构建器用于创建类的实例。
// 使用@NoArgsConstructor注解这个注解自动为类生成一个无参的构造函数。
// 使用@AllArgsConstructor注解这个注解自动为类生成一个包含所有成员变量的构造函数。
public class DataOverViewQueryDTO implements Serializable {
// 成员变量begin类型为LocalDateTime表示查询的开始时间。
private LocalDateTime begin;
// 成员变量end类型为LocalDateTime表示查询的结束时间。
private LocalDateTime end;
}

@ -0,0 +1,29 @@
// 导入所需的包
package com.sky.dto;
// 导入Swagger注解用于生成API文档
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
// 导入Lombok注解用于简化Java对象的创建
import lombok.Data;
// 导入Serializable接口使得类可以被序列化
import java.io.Serializable;
// 使用@Data注解Lombok会自动为这个类生成getter和setter方法以及equals、hashCode和toString方法。
@Data
// 使用@ApiModel注解指定这个类是Swagger文档中的一个模型并提供模型的描述。
@ApiModel(description = "员工登录时传递的数据模型")
// 声明这个类实现了Serializable接口这意味着它可以被序列化通常用于网络传输或持久化到文件中。
public class EmployeeLoginDTO implements Serializable {
// 使用@ApiModelProperty注解为username字段提供API文档中的描述。
@ApiModelProperty("用户名")
// 定义一个私有字段username类型为String用于存储员工的用户名。
private String username;
// 使用@ApiModelProperty注解为password字段提供API文档中的描述。
@ApiModelProperty("密码")
// 定义一个私有字段password类型为String用于存储员工的密码。
private String password;
}

@ -0,0 +1,28 @@
// 导入所需的包
package com.sky.dto;
// 导入Lombok注解用于简化Java对象的创建
import lombok.Data;
// 导入Serializable接口使得类可以被序列化
import java.io.Serializable;
// 使用@Data注解Lombok会自动为这个类生成getter和setter方法以及equals、hashCode和toString方法。
@Data
// 声明这个类实现了Serializable接口这意味着它可以被序列化通常用于网络传输或持久化到文件中。
public class OrdersConfirmDTO implements Serializable {
// 定义一个私有字段id类型为Long用于存储订单的唯一标识符。
private Long id;
// 定义一个私有字段status类型为Integer用于存储订单的状态。
// 订单状态的不同值代表不同的订单处理阶段:
// 1 - 待付款
// 2 - 待接单
// 3 - 已接单
// 4 - 派送中
// 5 - 已完成
// 6 - 已取消
// 7 - 退款
private Integer status;
}

@ -0,0 +1,21 @@
// 导入所需的包
package com.sky.dto;
// 导入Lombok注解用于简化Java对象的创建
import lombok.Data;
// 导入Serializable接口使得类可以被序列化
import java.io.Serializable;
// 使用@Data注解Lombok会自动为这个类生成getter和setter方法以及equals、hashCode和toString方法。
@Data
// 声明这个类实现了Serializable接口这意味着它可以被序列化通常用于网络传输或持久化到文件中。
public class OrdersRejectionDTO implements Serializable {
// 定义一个私有字段id类型为Long用于存储订单的唯一标识符。
private Long id;
// 定义一个私有字段rejectionReason类型为String用于存储订单被拒绝的原因。
// 这个字段用于在订单被拒绝时提供详细的解释或理由。
private String rejectionReason;
}

@ -0,0 +1,31 @@
// 导入所需的包
package com.sky.dto;
// 导入Lombok注解用于简化Java对象的创建
import lombok.Data;
// 导入Serializable接口使得类可以被序列化
import java.io.Serializable;
// 使用@Data注解Lombok会自动为这个类生成getter和setter方法以及equals、hashCode和toString方法。
@Data
// 声明这个类实现了Serializable接口这意味着它可以被序列化通常用于网络传输或持久化到文件中。
public class SetmealPageQueryDTO implements Serializable {
// 定义一个私有字段page类型为int用于存储分页查询的当前页码。
private int page;
// 定义一个私有字段pageSize类型为int用于存储分页查询中每页显示的记录数。
private int pageSize;
// 定义一个私有字段name类型为String用于存储套餐名称的查询条件。
private String name;
// 定义一个私有字段categoryId类型为Integer用于存储分类id的查询条件。
// 分类id用于筛选特定分类下的套餐。
private Integer categoryId;
// 定义一个私有字段status类型为Integer用于存储状态的查询条件。
// 状态字段的值0表示禁用1表示启用用于筛选启用或禁用的套餐。
private Integer status;
}

@ -0,0 +1,56 @@
// 定义了一个名为com.sky.entity的包用于存放实体类
package com.sky.entity;
// 导入了Lombok库中的注解用于简化实体类的编写
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
// 导入了Serializable接口使得Category类的对象可以被序列化用于网络传输或文件存储
import java.io.Serializable;
// 导入了LocalDateTime类用于存储日期和时间
import java.time.LocalDateTime;
// 使用@Data注解自动生成getter和setter方法以及equals、hashCode和toString方法
@Data
// 使用@Builder注解自动生成builder模式代码方便对象的构建
@Builder
// 使用@NoArgsConstructor注解自动生成无参构造方法
@NoArgsConstructor
// 使用@AllArgsConstructor注解自动生成包含所有属性的构造方法
@AllArgsConstructor
// 声明Category类实现了Serializable接口表示该类的对象可以被序列化
public class Category implements Serializable {
// 定义了一个serialVersionUID用于在序列化时保持版本的一致性
private static final long serialVersionUID = 1L;
// 定义了一个id属性类型为Long表示分类的唯一标识
private Long id;
// 定义了一个type属性类型为Integer表示分类的类型1表示菜品分类2表示套餐分类
private Integer type;
// 定义了一个name属性类型为String表示分类的名称
private String name;
// 定义了一个sort属性类型为Integer表示分类的顺序
private Integer sort;
// 定义了一个status属性类型为Integer表示分类的状态0表示禁用1表示启用
private Integer status;
// 定义了一个createTime属性类型为LocalDateTime表示分类的创建时间
private LocalDateTime createTime;
// 定义了一个updateTime属性类型为LocalDateTime表示分类的更新时间
private LocalDateTime updateTime;
// 定义了一个createUser属性类型为Long表示创建分类的用户ID
private Long createUser;
// 定义了一个updateUser属性类型为Long表示更新分类的用户ID
private Long updateUser;
}

@ -0,0 +1,59 @@
// 定义了一个名为com.sky.entity的包用于存放实体类
package com.sky.entity;
// 导入了Lombok库中的注解用于简化实体类的编写
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
// 导入了Serializable接口使得OrderDetail类的对象可以被序列化用于网络传输或文件存储
import java.io.Serializable;
// 导入了BigDecimal类用于精确表示货币金额
import java.math.BigDecimal;
/**
*
*/
// 使用@Data注解自动生成getter和setter方法以及equals、hashCode和toString方法
@Data
// 使用@Builder注解自动生成builder模式代码方便对象的构建
@Builder
// 使用@NoArgsConstructor注解自动生成无参构造方法
@NoArgsConstructor
// 使用@AllArgsConstructor注解自动生成包含所有属性的构造方法
@AllArgsConstructor
// 声明OrderDetail类实现了Serializable接口表示该类的对象可以被序列化
public class OrderDetail implements Serializable {
// 定义了一个serialVersionUID用于在序列化时保持版本的一致性
private static final long serialVersionUID = 1L;
// 定义了一个id属性类型为Long表示订单明细的唯一标识
private Long id;
// 定义了一个name属性类型为String表示订单明细的名称
private String name;
// 定义了一个orderId属性类型为Long表示所属订单的ID
private Long orderId;
// 定义了一个dishId属性类型为Long表示菜品的ID
private Long dishId;
// 定义了一个setmealId属性类型为Long表示套餐的ID
private Long setmealId;
// 定义了一个dishFlavor属性类型为String表示菜品的口味
private String dishFlavor;
// 定义了一个number属性类型为Integer表示订单明细的数量
private Integer number;
// 定义了一个amount属性类型为BigDecimal表示订单明细的金额
private BigDecimal amount;
// 定义了一个image属性类型为String表示订单明细的图片路径或URL
private String image;
}

@ -0,0 +1,65 @@
// 定义了一个名为com.sky.entity的包用于存放实体类
package com.sky.entity;
// 导入了Lombok库中的注解用于简化实体类的编写
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
// 导入了Serializable接口使得ShoppingCart类的对象可以被序列化用于网络传输或文件存储
import java.io.Serializable;
// 导入了BigDecimal类用于精确表示货币金额
import java.math.BigDecimal;
// 导入了LocalDateTime类用于存储日期和时间
import java.time.LocalDateTime;
/**
*
*/
// 使用@Data注解自动生成getter和setter方法以及equals、hashCode和toString方法
@Data
// 使用@Builder注解自动生成builder模式代码方便对象的构建
@Builder
// 使用@NoArgsConstructor注解自动生成无参构造方法
@NoArgsConstructor
// 使用@AllArgsConstructor注解自动生成包含所有属性的构造方法
@AllArgsConstructor
// 声明ShoppingCart类实现了Serializable接口表示该类的对象可以被序列化
public class ShoppingCart implements Serializable {
// 定义了一个serialVersionUID用于在序列化时保持版本的一致性
private static final long serialVersionUID = 1L;
// 定义了一个id属性类型为Long表示购物车的唯一标识
private Long id;
// 定义了一个name属性类型为String表示购物车的名称或描述
private String name;
// 定义了一个userId属性类型为Long表示用户的ID
private Long userId;
// 定义了一个dishId属性类型为Long表示菜品的ID
private Long dishId;
// 定义了一个setmealId属性类型为Long表示套餐的ID
private Long setmealId;
// 定义了一个dishFlavor属性类型为String表示菜品的口味
private String dishFlavor;
// 定义了一个number属性类型为Integer表示商品的数量
private Integer number;
// 定义了一个amount属性类型为BigDecimal表示商品的总金额
private BigDecimal amount;
// 定义了一个image属性类型为String表示商品的图片路径或URL
private String image;
// 定义了一个createTime属性类型为LocalDateTime表示购物车创建的时间
private LocalDateTime createTime;
}

@ -0,0 +1,31 @@
// 定义了一个名为com.sky.vo的包用于存放视图对象类
package com.sky.vo;
// 导入了Lombok库中的注解用于简化类的编写
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
// 导入了Serializable接口使得DishOverViewVO类的对象可以被序列化用于网络传输或文件存储
import java.io.Serializable;
/**
*
*/
// 使用@Data注解自动生成getter和setter方法以及equals、hashCode和toString方法
@Data
// 使用@Builder注解自动生成builder模式代码方便对象的构建
@Builder
// 使用@NoArgsConstructor注解自动生成无参构造方法
@NoArgsConstructor
// 使用@AllArgsConstructor注解自动生成包含所有属性的构造方法
@AllArgsConstructor
// 声明DishOverViewVO类实现了Serializable接口表示该类的对象可以被序列化
public class DishOverViewVO implements Serializable {
// 定义了一个sold属性类型为Integer表示已启售的菜品数量
private Integer sold;
// 定义了一个discontinued属性类型为Integer表示已停售的菜品数量
private Integer discontinued;
}

@ -0,0 +1,40 @@
// 定义了一个名为com.sky.vo的包用于存放视图对象类
package com.sky.vo;
// 导入了Lombok库中的注解用于简化类的编写
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
// 导入了Serializable接口使得OrderPaymentVO类的对象可以被序列化用于网络传输或文件存储
import java.io.Serializable;
/**
*
*/
// 使用@Data注解自动生成getter和setter方法以及equals、hashCode和toString方法
@Data
// 使用@Builder注解自动生成builder模式代码方便对象的构建
@Builder
// 使用@NoArgsConstructor注解自动生成无参构造方法
@NoArgsConstructor
// 使用@AllArgsConstructor注解自动生成包含所有属性的构造方法
@AllArgsConstructor
// 声明OrderPaymentVO类实现了Serializable接口表示该类的对象可以被序列化
public class OrderPaymentVO implements Serializable {
// 定义了一个nonceStr属性类型为String表示随机字符串用于支付过程中的随机性
private String nonceStr;
// 定义了一个paySign属性类型为String表示签名用于验证支付请求的合法性
private String paySign;
// 定义了一个timeStamp属性类型为String表示时间戳用于记录支付请求的时间
private String timeStamp;
// 定义了一个signType属性类型为String表示签名算法用于指定签名的算法类型
private String signType;
// 定义了一个packageStr属性类型为String表示统一下单接口返回的prepay_id参数值用于后续支付流程
private String packageStr;
}

@ -0,0 +1,36 @@
// 定义了一个名为com.sky.vo的包用于存放视图对象类
package com.sky.vo;
// 导入了实体类Orders和OrderDetail以便在视图对象中使用
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
// 导入了Lombok库中的注解用于简化类的编写
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
// 导入了Serializable接口使得OrderVO类的对象可以被序列化用于网络传输或文件存储
import java.io.Serializable;
// 导入了List接口用于存储订单详情列表
import java.util.List;
/**
* Orders
*/
// 使用@Data注解自动生成getter和setter方法以及equals、hashCode和toString方法
@Data
// 使用@NoArgsConstructor注解自动生成无参构造方法
@NoArgsConstructor
// 使用@AllArgsConstructor注解自动生成包含所有属性的构造方法
@AllArgsConstructor
// 声明OrderVO类继承自Orders实体类并实现了Serializable接口表示该类的对象可以被序列化
public class OrderVO extends Orders implements Serializable {
// 定义了一个orderDishes属性类型为String表示订单中的菜品信息通常用于展示订单中包含的所有菜品的名称或描述
private String orderDishes;
// 定义了一个orderDetailList属性类型为List<OrderDetail>,表示订单详情列表,包含了订单中每个商品的详细信息
private List<OrderDetail> orderDetailList;
}

@ -0,0 +1,38 @@
// 定义了一个名为com.sky.vo的包用于存放视图对象类
package com.sky.vo;
// 导入了Lombok库中的注解用于简化类的编写
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
// 导入了Serializable接口使得TurnoverReportVO类的对象可以被序列化用于网络传输或文件存储
import java.io.Serializable;
/**
*
*/
// 使用@Data注解自动生成getter和setter方法以及equals、hashCode和toString方法
@Data
// 使用@Builder注解自动生成builder模式代码方便对象的构建
@Builder
// 使用@NoArgsConstructor注解自动生成无参构造方法
@NoArgsConstructor
// 使用@AllArgsConstructor注解自动生成包含所有属性的构造方法
@AllArgsConstructor
// 声明TurnoverReportVO类实现了Serializable接口表示该类的对象可以被序列化
public class TurnoverReportVO implements Serializable {
/**
*
* "2022-10-01,2022-10-02,2022-10-03"
*/
private String dateList;
/**
*
* "406.0,1520.0,75.0"
*/
private String turnoverList;
}

@ -0,0 +1,35 @@
// 导入所需的包
package com.sky.config;
// 导入Lombok提供的@Slf4j注解用于自动注入一个日志对象
import lombok.extern.slf4j.Slf4j;
// 导入Spring框架的配置注解用于声明这是一个配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// 导入Spring Data Redis的连接工厂接口
import org.springframework.data.redis.connection.RedisConnectionFactory;
// 导入Spring Data Redis的核心组件用于操作Redis
import org.springframework.data.redis.core.RedisTemplate;
// 导入Spring Data Redis的字符串序列化器
import org.springframework.data.redis.serializer.StringRedisSerializer;
// 使用@Configuration注解声明这个类是一个Spring配置类其中的Bean会被Spring容器自动扫描和管理。
@Configuration
// 使用@Slf4j注解自动为这个类注入一个日志对象方便记录日志信息。
@Slf4j
public class RedisConfiguration {
// 使用@Bean注解声明一个BeanSpring容器会调用这个方法来创建Bean并将其加入到容器中。
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
// 记录日志信息表示开始创建Redis模板对象。
log.info("开始创建redis模版对象...");
// 创建RedisTemplate实例泛型参数为Object表示键和值都可以是任意类型的对象。
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
// 设置连接工厂对象这个对象负责与Redis服务器建立连接。
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 设置Redis key的序列化器这里使用StringRedisSerializer表示key会被序列化为String类型。
redisTemplate.setKeySerializer(new StringRedisSerializer());
// 返回配置好的RedisTemplate对象它将被Spring容器管理。
return redisTemplate;
}
}

@ -0,0 +1,68 @@
// 导入所需的包
package com.sky.controller.admin;
// 导入项目中定义的消息常量类
import com.sky.constant.MessageConstant;
// 导入项目中定义的结果封装类
import com.sky.result.Result;
// 导入项目中定义的通用服务接口
import com.sky.service.CommonService;
// 导入Swagger注解用于生成API文档
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
// 导入Lombok提供的@Slf4j注解用于自动注入一个日志对象
import lombok.extern.slf4j.Slf4j;
// 导入Spring框架的自动注入注解
import org.springframework.beans.factory.annotation.Autowired;
// 导入Spring框架的映射注解
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
// 导入Spring框架的文件上传组件
import org.springframework.web.multipart.MultipartFile;
// 导入Java IO异常类
import java.io.IOException;
// 使用@RestController注解声明这个类是一个Spring MVC的控制器并且返回的数据会自动以JSON格式响应。
@RestController
// 使用@RequestMapping注解声明这个控制器处理请求的基本路径。
@RequestMapping("/admin/common")
// 使用@Api注解指定这个控制器是Swagger文档中的一个API并提供API的描述。
@Api("通用接口")
// 使用@Slf4j注解自动为这个类注入一个日志对象方便记录日志信息。
@Slf4j
public class CommonController {
// 使用@Autowired注解自动注入CommonService服务。
@Autowired
// 定义CommonService类型的变量commmonService注意这里有一个拼写错误应该是commonService。
CommonService commmonService;
/**
*
*
* @param file 使MultipartFile
* @return Result
*/
// 使用@ApiOperation注解为Swagger文档提供文件上传操作的描述。
@ApiOperation("文件上传")
// 使用@PostMapping注解指定这个方法处理POST请求。
@PostMapping("/upload")
public Result<String> upload(MultipartFile file) {
// 记录日志信息,包括文件上传的操作和传入的文件对象。
log.info("文件上传{}", file);
// 定义一个String类型的变量filePath用于存储文件上传后的路径。
String filePath;
try {
// 调用commmonService的upload方法上传文件并返回文件路径。
filePath = commmonService.upload(file);
} catch (IOException e) {
// 如果发生IOException异常返回错误结果使用MessageConstant中的UPLOAD_FAILED常量作为错误消息。
return Result.error(MessageConstant.UPLOAD_FAILED);
}
// 如果文件上传成功,返回成功结果,包含文件路径。
return Result.success(filePath);
}
}

@ -0,0 +1,134 @@
// 定义了一个名为com.sky.controller.admin的包用于存放控制器类
package com.sky.controller.admin;
// 导入了项目中定义的结果类
import com.sky.result.Result;
// 导入了项目中定义的报告服务接口
import com.sky.service.ReportService;
// 导入了项目中定义的视图对象类
import com.sky.vo.*;
// 导入了Swagger注解用于API文档的生成
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
// 导入了Lombok提供的@Slf4j注解用于简化日志操作
import lombok.extern.slf4j.Slf4j;
// 导入了HttpServletResponse类用于处理HTTP响应
import javax.servlet.http.HttpServletResponse;
// 导入了IOException类用于处理可能发生的IO异常
import java.io.IOException;
// 导入了LocalDate类用于处理日期
import java.time.LocalDate;
// 导入了InvalidFormatException类用于处理可能发生格式无效的异常
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
/**
*
*/
// 使用@RestController注解声明这是一个控制器类并且返回的数据会自动以JSON格式响应
@RestController
// 使用@RequestMapping注解定义这个控制器类的基础请求映射路径
@RequestMapping("/admin/report")
// 使用@Slf4j注解提供日志功能
@Slf4j
// 使用@Api注解为这个控制器类添加Swagger文档的描述
@Api("营业额相关接口")
public class ReportController {
// 自动注入ReportService
@Autowired
ReportService reportService;
/**
*
*
* @param begin
* @param end
* @return
*/
// 使用@ApiOperation注解为这个接口方法添加Swagger文档的描述
@ApiOperation("营业额相关接口")
// 使用@GetMapping注解定义GET请求映射
@GetMapping("/turnoverStatistics")
public Result<TurnoverReportVO> turnoverStatistics(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin, @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {
// 使用日志记录营业额统计的操作
log.info("营业额统计:{},{}", begin, end);
// 调用ReportService的getTurnoverStatistics方法获取营业额统计结果
return reportService.getTurnoverStatistics(begin, end);
}
/**
*
*
* @param begin
* @param end
* @return
*/
// 使用@ApiOperation注解为这个接口方法添加Swagger文档的描述
@ApiOperation("用户统计")
// 使用@GetMapping注解定义GET请求映射
@GetMapping("/userStatistics")
public Result<UserReportVO> userStatistics(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin, @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {
// 使用日志记录用户统计的操作
log.info("用户统计:{},{}", begin, end);
// 调用ReportService的userStatistics方法获取用户统计结果并包装成成功的响应
return Result.success(reportService.userStatistics(begin, end));
}
/**
*
*
* @param begin
* @param end
* @return
*/
// 使用@ApiOperation注解为这个接口方法添加Swagger文档的描述
@ApiOperation("订单统计")
// 使用@GetMapping注解定义GET请求映射
@GetMapping("/ordersStatistics")
public Result<OrderReportVO> orderStatistics(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin, @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {
// 使用日志记录订单统计的操作
log.info("订单统计{},{}", begin, end);
// 调用ReportService的orderStatistics方法获取订单统计结果并包装成成功的响应
return Result.success(reportService.orderStatistics(begin, end));
}
/**
*
*
* @param begin
* @param end
* @return
*/
// 使用@ApiOperation注解为这个接口方法添加Swagger文档的描述
@ApiOperation("销量排行前十")
// 使用@GetMapping注解定义GET请求映射
@GetMapping("/top10")
public Result<SalesTop10ReportVO> salesTop10Report(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin, @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {
// 使用日志记录销量排名前十的操作
log.info("销售排名前10:{},{}", begin, end);
// 调用ReportService的salesTop10Report方法获取销量排名前十的结果并包装成成功的响应
return Result.success(reportService.salesTop10Report(begin, end));
}
/**
* excel
*
* @param httpResponse HTTP
* @return
* @throws IOException IO
* @throws InvalidFormatException
*/
// 使用@ApiOperation注解为这个接口方法添加Swagger文档的描述
@ApiOperation("导出excel表格")
// 使用@GetMapping注解定义GET请求映射
@GetMapping("/export")
public Result export(HttpServletResponse httpResponse) throws IOException, InvalidFormatException {
// 使用日志记录导出Excel表格的操作
log.info("导出Excel表格");
// 调用ReportService的export方法导出Excel表格
reportService.export(httpResponse);
// 返回操作成功的结果
return Result.success("OK");
}
}

@ -0,0 +1,135 @@
// 定义了一个名为com.sky.controller.notify的包用于存放支付回调相关的控制器类
package com.sky.controller.notify;
// 导入了JSON处理相关的类
import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
// 导入了项目中定义的微信支付属性类
import com.sky.properties.WeChatProperties;
// 导入了项目中定义的订单服务接口
import com.sky.service.OrderService;
// 导入了微信支付加解密工具类
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
// 导入了Lombok提供的@Slf4j注解用于简化日志操作
import lombok.extern.slf4j.Slf4j;
// 导入了HTTP相关的类
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
/**
*
*/
// 使用@RestController注解声明这是一个控制器类并且返回的数据会自动以JSON格式响应
@RestController
// 使用@RequestMapping注解定义这个控制器类的基础请求映射路径
@RequestMapping("/notify")
// 使用@Slf4j注解提供日志功能
@Slf4j
public class PayNotifyController {
// 自动注入OrderService
@Autowired
private OrderService orderService;
// 自动注入WeChatProperties
@Autowired
private WeChatProperties weChatProperties;
/**
*
*
* @param request HTTP
* @param response HTTP
* @throws Exception
*/
@RequestMapping("/paySuccess")
public void paySuccessNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 读取数据
String body = readData(request);
log.info("支付成功回调:{}", body);
// 数据解密
String plainText = decryptData(body);
log.info("解密后的文本:{}", plainText);
JSONObject jsonObject = JSON.parseObject(plainText);
// 商户平台订单号
String outTradeNo = jsonObject.getString("out_trade_no");
// 微信支付交易号
String transactionId = jsonObject.getString("transaction_id");
log.info("商户平台订单号:{}", outTradeNo);
log.info("微信支付交易号:{}", transactionId);
// 业务处理,修改订单状态、来单提醒
orderService.paySuccess(outTradeNo);
// 给微信响应
responseToWeixin(response);
}
/**
* HTTP
*
* @param request HTTP
* @return
* @throws Exception
*/
private String readData(HttpServletRequest request) throws Exception {
BufferedReader reader = request.getReader();
StringBuilder result = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
if (result.length() > 0) {
result.append("\n");
}
result.append(line);
}
return result.toString();
}
/**
*
*
* @param body
* @return
* @throws Exception
*/
private String decryptData(String body) throws Exception {
JSONObject resultObject = JSON.parseObject(body);
JSONObject resource = resultObject.getJSONObject("resource");
String ciphertext = resource.getString("ciphertext");
String nonce = resource.getString("nonce");
String associatedData = resource.getString("associated_data");
AesUtil aesUtil = new AesUtil(weChatProperties.getApiV3Key().getBytes(StandardCharsets.UTF_8));
// 密文解密
String plainText = aesUtil.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),
nonce.getBytes(StandardCharsets.UTF_8),
ciphertext);
return plainText;
}
/**
*
*
* @param response HTTP
* @throws Exception
*/
private void responseToWeixin(HttpServletResponse response) throws Exception{
response.setStatus(200);
HashMap<Object, Object> map = new HashMap<>();
map.put("code", "SUCCESS");
map.put("message", "SUCCESS");
response.setHeader("Content-type", ContentType.APPLICATION_JSON.toString());
response.getOutputStream().write(JSONUtils.toJSONString(map).getBytes(StandardCharsets.UTF_8));
response.flushBuffer();
}
}

@ -0,0 +1,159 @@
// 定义了一个名为com.sky.controller.user的包用于存放用户端订单控制器类
package com.sky.controller.user;
// 导入了项目中定义的数据传输对象DTO
import com.sky.dto.OrdersDTO;
import com.sky.dto.OrdersPageQueryDTO;
import com.sky.dto.OrdersPaymentDTO;
// 导入了项目中定义的实体类
import com.sky.entity.Orders;
// 导入了项目中定义的结果类
import com.sky.result.PageResult;
import com.sky.result.Result;
// 导入了项目中定义的服务接口
import com.sky.service.OrderService;
// 导入了项目中定义的视图对象VO
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
// 导入了Swagger注解用于API文档的生成
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
// 导入了Lombok提供的@Slf4j注解用于简化日志操作
import lombok.extern.slf4j.Slf4j;
// 导入了Spring框架中的@Autowired注解用于自动注入Spring管理的Bean
import org.springframework.beans.factory.annotation.Autowired;
// 导入了Spring框架中的@RequestMapping注解用于定义请求映射
import org.springframework.web.bind.annotation.*;
/**
*
*/
// 使用@RestController注解声明这是一个控制器类并且返回的数据会自动以JSON格式响应
@RestController
// 使用@RequestMapping注解定义这个控制器类的基础请求映射路径
@RequestMapping("/user/order")
// 使用@Slf4j注解提供日志功能
@Slf4j
// 使用@Api注解为这个控制器类添加Swagger文档的描述
@Api(tags = "C端-订单接口")
public class OrderController {
// 自动注入OrderService
@Autowired
OrderService orderService;
/**
*
*
* @param id ID
* @return
*/
// 使用@ApiOperation注解为这个接口方法添加Swagger文档的描述
@ApiOperation("再来一单")
// 使用@PostMapping注解定义POST请求映射
@PostMapping("/repetition/{id}")
public Result repetition(@PathVariable Long id) {
orderService.repetition(id);
return Result.success();
}
/**
*
*
* @param id ID
* @return
* @throws Exception
*/
// 使用@ApiOperation注解为这个接口方法添加Swagger文档的描述
@ApiOperation("取消订单")
// 使用@PutMapping注解定义PUT请求映射
@PutMapping("/cancel/{id}")
public Result cancel(@PathVariable("id") Long id) throws Exception {
orderService.userCancelById(id);
return Result.success();
}
/**
*
*
* @param ordersDTO
* @return
*/
// 使用@ApiOperation注解为这个接口方法添加Swagger文档的描述
@ApiOperation("用户下单")
// 使用@RequestMapping注解定义请求映射
@RequestMapping("/submit")
public Result<OrderSubmitVO> submitOrder(@RequestBody OrdersDTO ordersDTO) {
log.info("用户下单,订单信息:{}", ordersDTO);
OrderSubmitVO order = orderService.submit(ordersDTO);
return Result.success(order);
}
/**
*
*
* @param ordersPaymentDTO
* @return
* @throws Exception
*/
// 使用@ApiOperation注解为这个接口方法添加Swagger文档的描述
@ApiOperation("订单支付")
// 使用@PutMapping注解定义PUT请求映射
@PutMapping("/payment")
public Result<OrderPaymentVO> payment(@RequestBody OrdersPaymentDTO ordersPaymentDTO) throws Exception {
log.info("订单支付:{}", ordersPaymentDTO);
orderService.paySuccess(ordersPaymentDTO.getOrderNumber());
return Result.success();
}
/**
*
*
* @param id ID
* @return
*/
// 使用@ApiOperation注解为这个接口方法添加Swagger文档的描述
@ApiOperation("催单")
// 使用@GetMapping注解定义GET请求映射
@GetMapping("/reminder/{id}")
public Result reminder(@PathVariable Long id) {
log.info("用户催单orderId:{}", id);
orderService.reminder(id);
return Result.success();
}
/**
*
*
* @param page
* @param pageSize
* @param status
* @return
*/
// 使用@ApiOperation注解为这个接口方法添加Swagger文档的描述
@ApiOperation("历史订单查询")
// 使用@GetMapping注解定义GET请求映射
@GetMapping("/historyOrders")
public Result<PageResult> page(int page, int pageSize, Integer status) {
PageResult pageResult = orderService.pageQuery4User(page, pageSize, status);
return Result.success(pageResult);
}
/**
*
*
* @param id ID
* @return
*/
// 使用@ApiOperation注解为这个接口方法添加Swagger文档的描述
@ApiOperation("查询订单详情")
// 使用@GetMapping注解定义GET请求映射
@GetMapping("/orderDetail/{id}")
public Result<OrderVO> details(@PathVariable("id") Long id) {
OrderVO orderVO = orderService.details(id);
return Result.success(orderVO);
}
}

@ -0,0 +1,80 @@
// 定义了一个名为com.sky.controller.user的包用于存放用户控制器类
package com.sky.controller.user;
// 导入了项目中定义的常量类
import com.sky.constant.JwtClaimsConstant;
// 导入了项目中定义的用户登录数据传输对象DTO
import com.sky.dto.UserLoginDTO;
// 导入了项目中定义的实体类
import com.sky.entity.User;
// 导入了项目中定义的JWT属性类
import com.sky.properties.JwtProperties;
// 导入了项目中定义的结果类
import com.sky.result.Result;
// 导入了项目中定义的服务接口
import com.sky.service.UserService;
// 导入了项目中定义的JWT工具类
import com.sky.utils.JwtUtil;
// 导入了项目中定义的视图对象VO
import com.sky.vo.UserLoginVO;
// 导入了Swagger注解用于API文档的生成
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
// 导入了Lombok提供的@Slf4j注解用于简化日志操作
import lombok.extern.slf4j.Slf4j;
// 导入了Spring框架中的@Autowired注解用于自动注入Spring管理的Bean
import org.springframework.beans.factory.annotation.Autowired;
// 导入了Spring框架中的@RequestMapping注解用于定义请求映射
import org.springframework.web.bind.annotation.*;
/**
*
*/
// 使用@RestController注解声明这是一个控制器类并且返回的数据会自动以JSON格式响应
@RestController
// 使用@RequestMapping注解定义这个控制器类的基础请求映射路径
@RequestMapping("/user/user")
// 使用@Slf4j注解提供日志功能
@Slf4j
// 使用@Api注解为这个控制器类添加Swagger文档的描述
@Api("C端用户相关接口")
public class UserController {
// 自动注入UserService
@Autowired
UserService userService;
// 自动注入JwtProperties
@Autowired
JwtProperties jwtProperties;
/**
*
*
* @param userLoginDTO
* @return JWT
*/
// 使用@ApiOperation注解为这个接口方法添加Swagger文档的描述
@ApiOperation("用户登录")
// 使用@PostMapping注解定义POST请求映射
@PostMapping("/login")
public Result<UserLoginVO> login(@RequestBody UserLoginDTO userLoginDTO){
// 使用日志记录用户登录的操作
log.info("微信登录:{}",userLoginDTO);
// 调用UserService的wxLogin方法进行微信登录
User user = userService.wxLogin(userLoginDTO);
// 生成JWT令牌
Map<String, Object> claims = new HashMap<>();
claims.put(JwtClaimsConstant.USER_ID, user.getId());
String jwt = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);
// 构建用户登录视图对象
UserLoginVO userLoginVO = UserLoginVO.builder()
.id(user.getId())
.token(jwt)
.openid(user.getOpenid())
.build();
// 返回成功的结果,包含用户登录视图对象
return Result.success(userLoginVO);
}
}

@ -0,0 +1,71 @@
// 定义了一个名为com.sky.mapper的包用于存放MyBatis Mapper接口
package com.sky.mapper;
// 导入了项目中定义的AddressBook实体类
import com.sky.entity.AddressBook;
// 导入了MyBatis相关注解
import org.apache.ibatis.annotations.*;
// 导入了Java.util.List接口用于定义返回列表类型
import java.util.List;
// 使用@Mapper注解标记这是一个MyBatis Mapper接口
@Mapper
public interface AddressBookMapper {
/**
* AddressBook簿
*
* @param addressBook
* @return AddressBook
*/
List<AddressBook> list(AddressBook addressBook);
/**
* 簿
*
* @param addressBook AddressBook
*/
// 使用@Insert注解标记这是一个插入操作并提供SQL语句
@Insert("insert into address_book" +
" (user_id, consignee, phone, sex, province_code, province_name, city_code, city_name, district_code," +
" district_name, detail, label, is_default)" +
" values (#{userId}, #{consignee}, #{phone}, #{sex}, #{provinceCode}, #{provinceName}, #{cityCode}, #{cityName}," +
" #{districtCode}, #{districtName}, #{detail}, #{label}, #{isDefault})")
void insert(AddressBook addressBook);
/**
* idID簿
*
* @param id ID
* @return AddressBook
*/
// 使用@Select注解标记这是一个查询操作并提供SQL语句
@Select("select * from address_book where user_id = #{id}")
AddressBook getById(Long id);
/**
* idAddressBook簿
*
* @param addressBook AddressBook
*/
void update(AddressBook addressBook);
/**
* idID
*
* @param addressBook IDAddressBook
*/
// 使用@Update注解标记这是一个更新操作并提供SQL语句
@Update("update address_book set is_default = #{isDefault} where user_id = #{userId}")
void updateIsDefaultByUserId(AddressBook addressBook);
/**
* idID簿
*
* @param id 簿ID
*/
// 使用@Delete注解标记这是一个删除操作并提供SQL语句
@Delete("delete from address_book where id = #{id}")
void deleteById(Long id);
}

@ -0,0 +1,35 @@
// 定义了一个名为com.sky.mapper的包用于存放MyBatis Mapper接口
package com.sky.mapper;
// 导入了项目中定义的OrderDetail实体类
import com.sky.entity.OrderDetail;
// 导入了MyBatis相关注解
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
// 导入了Java.util.List接口用于定义返回列表类型
import java.util.List;
// 导入了Java.util.ArrayList类用于定义批量插入的数据类型
import java.util.ArrayList;
// 使用@Mapper注解标记这是一个MyBatis Mapper接口
@Mapper
public interface OrderDetailMapper {
/**
*
*
* @param orderDetails
*/
// 此方法的具体实现需要在MyBatis的映射文件中定义通常使用<insert>标签并设置typeHandler进行批量插入
void insertBatch(ArrayList<OrderDetail> orderDetails);
/**
* idID
*
* @param orderId ID
* @return
*/
// 使用@Select注解标记这是一个查询操作并提供SQL语句
@Select("select * from order_detail where order_id = #{orderId}")
List<OrderDetail> getByOrderId(Long orderId);
}

@ -0,0 +1,57 @@
// 定义了一个名为com.sky.mapper的包用于存放MyBatis Mapper接口
package com.sky.mapper;
// 导入了项目中定义的ShoppingCart实体类
import com.sky.entity.ShoppingCart;
// 导入了MyBatis相关注解
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Update;
// 导入了Java.util.List接口用于定义返回列表类型
import java.util.List;
// 使用@Mapper注解标记这是一个MyBatis Mapper接口
@Mapper
public interface ShoppingCartMapper {
/**
*
*
* @param shoppingCartList
*/
void insertBatch(List<ShoppingCart> shoppingCartList);
/**
* ShoppingCart
*
* @param shoppingCart
* @return ShoppingCart
*/
List<ShoppingCart> list(ShoppingCart shoppingCart);
/**
* id
*
* @param shoppingCart ShoppingCart
*/
// 使用@Update注解标记这是一个更新操作并提供SQL语句
@Update("update shopping_cart set number=#{number},amount=#{amount} where id=#{id}")
void update(ShoppingCart shoppingCart);
/**
*
*
* @param shoppingCart ShoppingCart
*/
// 使用@Insert注解标记这是一个插入操作并提供SQL语句
@Insert("insert into shopping_cart(name,user_id,dish_id,setmeal_id,dish_flavor,number,amount,image,create_time)" +
"values (#{name},#{userId},#{dishId},#{setmealId},#{dishFlavor},#{number},#{amount},#{image},#{createTime})")
void insert(ShoppingCart shoppingCart);
/**
* ShoppingCart
*
* @param shoppingCart ShoppingCart
*/
void delete(ShoppingCart shoppingCart);
}

@ -0,0 +1,87 @@
package com.sky.service;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.result.PageResult;
import com.sky.vo.DishVO;
import com.sky.vo.SetmealVO;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* DishService
*/
public interface DishService {
/**
*
* DishPageQueryDTO
*
* @param dishPageQueryDTO DTO
* @return PageResult
*/
PageResult pageQuery(DishPageQueryDTO dishPageQueryDTO);
/**
*
* DishDTO
*
* @param dishDTO DTO
*/
void saveWithFlaver(DishDTO dishDTO);
/**
*
* ID
*
* @param ids ID
*/
void deleteBatch(ArrayList<Long> ids);
/**
*
* DishDTO
*
* @param dishDTO DTO
*/
void updateDish(DishDTO dishDTO);
/**
* id
* IDVO
*
* @param id ID
* @return DishVO
*/
DishVO getById(Long id);
/**
* id
* ID
*
* @param categoryId ID
* @return
*/
ArrayList<Dish> getByCategoryId(Long categoryId);
/**
*
* ID
*
* @param id ID
* @param status
*/
void startOrStop(Long id, Integer status);
/**
*
* DishVO
*
* @param dish Dish
* @return VO
*/
List<DishVO> listWithFlavor(Dish dish);
}

@ -0,0 +1,87 @@
package com.sky.service;
import com.sky.dto.CategoryPageQueryDTO;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.entity.Setmeal;
import com.sky.result.PageResult;
import com.sky.vo.DishItemVO;
import com.sky.vo.SetmealVO;
import java.util.ArrayList;
import java.util.List;
/**
* SetmealService
*/
public interface SetmealService {
/**
*
* Setmeal
*
* @param setmeal Setmeal
* @return
*/
List<Setmeal> list(Setmeal setmeal);
/**
* id
* IDVO
*
* @param id ID
* @return VO
*/
List<DishItemVO> getDishItemById(Long id);
/**
*
* SetmealPageQueryDTO
*
* @param setmealPageQueryDTO DTO
* @return PageResult
*/
PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO);
/**
*
* ID
*
* @param status
* @param id ID
*/
void startOrStop(Integer status, Long id);
/**
*
* SetmealDTO
*
* @param setmealDTO DTO
*/
void updateSetmeal(SetmealDTO setmealDTO);
/**
* id
* IDVO
*
* @param id ID
* @return SetmealVO
*/
SetmealVO getDishById(Long id);
/**
* id
* ID
*
* @param ids ID
*/
void batchDeleteById(ArrayList<Long> ids);
/**
*
* SetmealDTO
*
* @param setmealDTO DTO
*/
void insert(SetmealDTO setmealDTO);
}

@ -0,0 +1,54 @@
package com.sky.service.impl;
import com.sky.service.CommonService;
import com.sky.utils.AliOssUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.UUID;
/**
* CommonServiceImplCommonService
*/
@Service
@Slf4j
public class CommonServiceImpl implements CommonService {
/**
* AliOssUtilOSS
* @AutowiredSpringAliOssUtil
*/
@Autowired
private AliOssUtil aliOssUtil;
/**
* uploadOSS
* MultipartFileSpring MVC
*
*
* @param file
* @return OSS
*/
@Override
public String upload(MultipartFile file) {
String filePath = null;
// 获取原始文件名
String originalFilename = file.getOriginalFilename();
// 从原始文件名中截取文件后缀
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
// 构造新的文件名使用UUID确保唯一性加上原文件后缀
String objectName = UUID.randomUUID() + extension;
try {
// 使用aliOssUtil上传文件并获取文件路径
filePath = aliOssUtil.upload(file.getBytes(), objectName);
} catch (IOException e) {
// 如果上传过程中发生IO异常记录错误日志
log.error("文件上传失败:{}", e);
}
// 返回文件路径
return filePath;
}
}

@ -0,0 +1,364 @@
package com.sky.service.impl;
import com.sky.entity.Orders;
import com.sky.mapper.ReportMapper;
import com.sky.properties.ReportExcelProperties;
import com.sky.result.Result;
import com.sky.service.ReportService;
import com.sky.vo.*;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.extractor.ExcelExtractor;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Service;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
@Service
@Slf4j
public class ReportServiceImpl implements ReportService {
@Autowired
ReportMapper reportMapper;
@Autowired
ReportExcelProperties reportExcelProperties;
@Autowired
WorkspaceServiceImpl workspaceService;
/**
*
*
* @param begin
* @param end
* @return
*/
@Override
public Result<TurnoverReportVO> getTurnoverStatistics(LocalDate begin, LocalDate end) {
LocalDate p = begin;
ArrayList<LocalDate> dateTimes = new ArrayList<>();
while (!p.equals(end)) {
dateTimes.add(p);
p = p.plusDays(1);
}
ArrayList<Double> count = new ArrayList<>();
for (LocalDate dateTime : dateTimes) {
HashMap<String, Object> map = new HashMap<>();
map.put("status", 5);
map.put("begin", LocalDateTime.of(dateTime, LocalTime.MIN));
map.put("end", LocalDateTime.of(dateTime, LocalTime.MAX));
Double sum = reportMapper.sumByMap(map);
if (sum == null) {
sum = 0D;
}
count.add(sum);
}
return Result.success(TurnoverReportVO.builder()
.dateList(StringUtils.join(dateTimes, ","))
.turnoverList(StringUtils.join(count, ","))
.build());
}
/**
*
*
* @param begin
* @param end
* @return
*/
@Override
public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
LocalDate p = begin;
ArrayList<LocalDate> dateTimes = new ArrayList<>();
while (!p.equals(end)) {
dateTimes.add(p);
p = p.plusDays(1);
}
ArrayList<Integer> user = new ArrayList<>();
ArrayList<Integer> newUser = new ArrayList<>();
for (LocalDate dateTime : dateTimes) {
HashMap<String, Object> map = new HashMap<>();
map.put("begin", LocalDateTime.of(dateTime, LocalTime.MIN));
map.put("end", LocalDateTime.of(dateTime, LocalTime.MAX));
Integer sum = reportMapper.sumUserByDay(map);
Integer sumUser = reportMapper.sumUser(map);
if (sum == null) {
sum = 0;
}
if (sumUser == null) {
sumUser = 0;
}
newUser.add(sum);
user.add(sumUser);
}
return UserReportVO.builder()
.dateList(StringUtils.join(dateTimes, ","))
.totalUserList(StringUtils.join(user, ","))
.newUserList(StringUtils.join(newUser, ","))
.build();
}
/**
*
*
* @param begin
* @param end
* @return
*/
@Override
public OrderReportVO orderStatistics(LocalDate begin, LocalDate end) {
// 初始化日期列表,用于存储开始和结束日期之间的每一天
LocalDate p = begin;
ArrayList<LocalDate> dateTimes = new ArrayList<>();
while (!p.equals(end)) {
dateTimes.add(p);
p = p.plusDays(1);
}
// 初始化订单数量和新订单数量的列表
ArrayList<Integer> order = new ArrayList<>();
ArrayList<Integer> newOrder = new ArrayList<>();
// 遍历每一天,统计订单数量和新订单数量
for (LocalDate dateTime : dateTimes) {
HashMap<String, Object> map = new HashMap<>();
map.put("begin", LocalDateTime.of(dateTime, LocalTime.MIN)); // 当天的最小时间
map.put("end", LocalDateTime.of(dateTime, LocalTime.MAX)); // 当天的最大时间
map.put("status", Orders.COMPLETED); // 完成的订单状态
// 调用reportMapper查询新订单和订单总数
Integer sum = reportMapper.sumNewOrder(map);
Integer sumOrder = reportMapper.sumOrder(map);
// 处理查询结果为null的情况
if (sum == null) {
sum = 0;
}
if (sumOrder == null) {
sumOrder = 0;
}
// 将查询结果添加到列表中
order.add(sumOrder);
newOrder.add(sum);
}
// 计算订单完成率
Double rate;
if (sumArrayList(order) == 0) {
rate = 1.0; // 如果订单总数为0则完成率为1.0
} else {
rate = sumArrayList(newOrder) / sumArrayList(order) * 1.0; // 计算完成率
}
// 构建并返回订单统计报告对象
return OrderReportVO.builder()
.dateList(StringUtils.join(dateTimes, ","))
// 日期列表,以逗号分隔
.orderCountList(StringUtils.join(newOrder, ","))
// 新订单数量列表,以逗号分隔
.validOrderCountList(StringUtils.join(order, ","))
// 订单数量列表,以逗号分隔
.totalOrderCount(sumArrayList(newOrder))
// 新订单总数
.validOrderCount(sumArrayList(order))
// 订单总数
.orderCompletionRate(rate)
// 订单完成率
.build();
// 构建报告对象
}
/**
*
*
* @param begin
* @param end
* @return
*/
@Override
public SalesTop10ReportVO salesTop10Report(LocalDate begin, LocalDate end) {
// 初始化商品名称和销售数量的列表
ArrayList<String> name = new ArrayList<>();
ArrayList<Integer> number = new ArrayList<>();
// 创建映射,用于传递查询参数
HashMap<String, Object> map = new HashMap<>();
// 查询结果集
ArrayList<HashMap<String, Object>> result;
// 设置查询参数
map.put("begin", LocalDateTime.of(begin, LocalTime.MIN)); // 查询开始时间(当天的最小时间)
map.put("end", LocalDateTime.of(end, LocalTime.MAX)); // 查询结束时间(当天的最大时间)
map.put("status", Orders.COMPLETED); // 订单状态,这里为已完成的订单
// 调用reportMapper查询销售排行前十的商品
result = reportMapper.salesTop10Report(map);
// 遍历查询结果,提取商品名称和销售数量
for (HashMap<String, Object> hashMap : result) {
name.add((String) hashMap.get("name")); // 获取商品名称
number.add(((BigDecimal) hashMap.get("number")).intValue()); // 获取销售数量并转换为整数
}
// 构建并返回销售排行报告对象
return SalesTop10ReportVO.builder()
.nameList(StringUtils.join(name, ",")) // 将商品名称列表转换为逗号分隔的字符串
.numberList(StringUtils.join(number, ",")) // 将销售数量列表转换为逗号分隔的字符串
.build(); // 构建报告对象
}
/**
* excel
*/
@Override
public void export(HttpServletResponse httpResponse) throws IOException, InvalidFormatException {
File file = new File(reportExcelProperties.getFilePath());
OPCPackage opcPackage = OPCPackage.open(file);
//获取工作薄
XSSFWorkbook workbook = new XSSFWorkbook(opcPackage);
String s = reportExcelProperties.getSheet()[0];
//获取工作表
XSSFSheet sheet = workbook.getSheet(s);
//填写日期
XSSFRow row = sheet.getRow(1);
XSSFCellStyle dataStyle = workbook.createCellStyle();
//设置日期的字体
XSSFFont font = workbook.createFont();
font.setFontHeight(16);
font.setFontName("宋体");
dataStyle.setAlignment(HorizontalAlignment.RIGHT);
XSSFCell cell0 = row.getCell(1);
dataStyle.setFont(font);
cell0.setCellStyle(dataStyle);
//获取营业概览数据
LocalDateTime begin = LocalDateTime.now().with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
LocalDateTime end = LocalDateTime.now().with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
cell0.setCellValue(begin.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss")) + "——" + end.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss")));
BusinessDataVO businessData = workspaceService.getBusinessData(begin, end);
XSSFRow row3 = sheet.getRow(3);
//营业额
XSSFCell cell = row3.getCell(2);
cell.setCellValue(businessData.getTurnover());
//订单完成率
XSSFCell cell1 = row3.getCell(4);
cell1.setCellValue(businessData.getOrderCompletionRate());
//新增用户数
XSSFCell cell2 = row3.getCell(6);
cell2.setCellValue(businessData.getNewUsers());
//有效订单
XSSFRow row1 = sheet.getRow(4);
XSSFCell cell3 = row1.getCell(2);
cell3.setCellValue(businessData.getValidOrderCount());
//平均客单价
XSSFCell cell4 = row1.getCell(4);
cell4.setCellValue(businessData.getValidOrderCount());
int dayOfMonth = Period.between(begin.toLocalDate(), end.toLocalDate()).getDays();
System.out.println("dayOfMonth:" + dayOfMonth);
//获取明细数据
for (int i = 0; i < dayOfMonth; i++) {
XSSFRow row2 = sheet.getRow(i + 7);
LocalDateTime localDateTimeBegin = begin.plusDays(i);
LocalDateTime localDateTimeEnd = localDateTimeBegin.with(LocalTime.MAX);
BusinessDataVO data = workspaceService.getBusinessData(localDateTimeBegin, localDateTimeEnd);
//设置日期
row2.getCell(1).setCellValue(localDateTimeBegin.toLocalDate().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
//营业额
row2.getCell(2).setCellValue(data.getTurnover());
//有效订单
row2.getCell(3).setCellValue(data.getValidOrderCount());
//订单完成率
row2.getCell(4).setCellValue(data.getOrderCompletionRate());
//平均客单价
row2.getCell(5).setCellValue(data.getUnitPrice());
//新增用户数
row2.getCell(6).setCellValue(data.getNewUsers());
}
/**
* Servlet
* HTTP
*/
ServletOutputStream outputStream = httpResponse.getOutputStream();
/**
* HTTP
* reset()
*
*/
httpResponse.reset();
/**
* Excel
* ContentType"application/vnd.ms-excel"Excel
*/
httpResponse.setContentType("application/vnd.ms-excel");
/**
*
* Content-disposition"attachment"
* "template.xlsx"
*/
httpResponse.addHeader("Content-disposition", "attachment;filename=template.xlsx");
/**
* Excel簿Servlet
* 使Apache POIwriteExcel簿workbook
*/
workbook.write(outputStream);
/**
*
* flush()
*/
outputStream.flush();
/**
*
*
*/
outputStream.close();
}
/**
*
* ArrayList<Integer>
*
* @param arrayList
* @return
*/
private Integer sumArrayList(ArrayList<Integer> arrayList) {
Integer sum = 0; // 初始化总和为0
for (Integer integer : arrayList) { // 遍历列表中的每个整数
sum += integer; // 将当前整数加到总和上
}
return sum; // 返回计算出的总和
}
}

@ -0,0 +1,168 @@
package com.sky.service.impl;
import com.sky.constant.StatusConstant;
import com.sky.entity.Orders;
import com.sky.mapper.DishMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.WorkspaceService;
import com.sky.vo.BusinessDataVO;
import com.sky.vo.DishOverViewVO;
import com.sky.vo.OrderOverViewVO;
import com.sky.vo.SetmealOverViewVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* WorkspaceServiceImplWorkspaceService
*/
@Service
@Slf4j
public class WorkspaceServiceImpl implements WorkspaceService {
// 自动注入OrderMapper用于操作订单相关的数据库操作
@Autowired
private OrderMapper orderMapper;
// 自动注入UserMapper用于操作用户相关的数据库操作
@Autowired
private UserMapper userMapper;
// 自动注入DishMapper用于操作菜品相关的数据库操作
@Autowired
private DishMapper dishMapper;
// 自动注入SetmealMapper用于操作套餐相关的数据库操作
@Autowired
private SetmealMapper setmealMapper;
/**
*
*
*
* @param begin
* @param end
* @return BusinessDataVO
*/
public BusinessDataVO getBusinessData(LocalDateTime begin, LocalDateTime end) {
// 初始化查询参数的HashMap
HashMap<String, Object> map = new HashMap<>();
map.put("begin", begin);
map.put("end", end);
map.put("status", null);
// 查询总订单数
Integer totalOrderCount = orderMapper.countByMap(map);
// 设置状态为已完成,查询营业额和有效订单数
map.put("status", Orders.COMPLETED);
Double turnover = orderMapper.sumByMap(map);
turnover = turnover == null ? 0.0 : turnover;
Integer validOrderCount = orderMapper.countByMap(map);
// 计算订单完成率和平均客单价
Double unitPrice = 0.0;
Double orderCompletionRate = 0.0;
if (totalOrderCount != 0 && validOrderCount != 0) {
orderCompletionRate = validOrderCount.doubleValue() / totalOrderCount;
unitPrice = turnover / validOrderCount;
}
// 查询新增用户数
Integer newUsers = userMapper.countByMap(map);
// 构建并返回营业数据对象
return BusinessDataVO.builder()
.turnover(turnover)
.validOrderCount(validOrderCount)
.orderCompletionRate(orderCompletionRate)
.unitPrice(unitPrice)
.newUsers(newUsers)
.build();
}
/**
*
*
* @return OrderOverViewVO
*/
public OrderOverViewVO getOrderOverView() {
Map map = new HashMap();
map.put("begin", LocalDateTime.now().with(LocalTime.MIN));
map.put("end", LocalDateTime.now().with(LocalTime.MAX));
map.put("status", Orders.TO_BE_CONFIRMED);
// 查询待接单数量
Integer waitingOrders = orderMapper.countByMap(map);
// 查询待派送数量
map.put("status", Orders.CONFIRMED);
Integer deliveredOrders = orderMapper.countByMap(map);
// 查询已完成数量
map.put("status", Orders.COMPLETED);
Integer completedOrders = orderMapper.countByMap(map);
// 查询已取消数量
map.put("status", Orders.CANCELLED);
Integer cancelledOrders = orderMapper.countByMap(map);
// 查询全部订单数量
map.put("status", null);
Integer allOrders = orderMapper.countByMap(map);
// 构建并返回订单管理数据对象
return OrderOverViewVO.builder()
.waitingOrders(waitingOrders)
.deliveredOrders(deliveredOrders)
.completedOrders(completedOrders)
.cancelledOrders(cancelledOrders)
.allOrders(allOrders)
.build();
}
/**
*
*
* @return DishOverViewVO
*/
public DishOverViewVO getDishOverView() {
Map map = new HashMap();
map.put("status", StatusConstant.ENABLE);
Integer sold = dishMapper.countByMap(map);
map.put("status", StatusConstant.DISABLE);
Integer discontinued = dishMapper.countByMap(map);
// 构建并返回菜品总览数据对象
return DishOverViewVO.builder()
.sold(sold)
.discontinued(discontinued)
.build();
}
/**
*
*
* @return SetmealOverViewVO
*/
public SetmealOverViewVO getSetmealOverView() {
Map map = new HashMap();
map.put("status", StatusConstant.ENABLE);
Integer sold = setmealMapper.countByMap(map);
map.put("status", StatusConstant.DISABLE);
Integer discontinued = setmealMapper.countByMap(map);
// 构建并返回套餐总览数据对象
return SetmealOverViewVO.builder()
.sold(sold)
.discontinued(discontinued)
.build();
}
}

@ -0,0 +1,57 @@
package com.sky.task;
import com.sky.entity.Orders;
import com.sky.mapper.OrderMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
/**
* OrderTask
*/
@Component
@Slf4j
public class OrderTask {
@Autowired
private OrderMapper orderMapper; // 注入OrderMapper用于数据库操作
/**
*
* 15
*/
@Scheduled(cron = "0 * * * * ?")
public void processTimeOrderTask() {
log.info("处理订单超时:{}", LocalDateTime.now()); // 记录当前时间
LocalDateTime time = LocalDateTime.now().plusMinutes(-15); // 设置15分钟前的时间
ArrayList<Orders> ordersList = (ArrayList<Orders>) orderMapper.getByStatusAndOrderTimeLT(Orders.PENDING_PAYMENT, time); // 查询待支付且下单时间超过15分钟的订单
if (ordersList != null && ordersList.size() > 0) { // 如果存在这样的订单
for (int i = 0; i < ordersList.size(); i++) { // 遍历这些订单
ordersList.get(i).setStatus(Orders.CANCELLED); // 设置状态为已取消
ordersList.get(i).setCancelReason("订单超时"); // 设置取消原因为订单超时
}
orderMapper.updateBatchStatus(ordersList, Orders.CANCELLED); // 更新订单状态
}
}
/**
* 1
*
*/
@Scheduled(cron = "0 0 1 * * ?")
public void processDeliveryOrder() {
log.info("定时处理处于派送中的订单:{}", LocalDateTime.now()); // 记录当前时间
ArrayList<Orders> ordersList = (ArrayList<Orders>) orderMapper.getByStatusAndOrderTimeLT(Orders.DELIVERY_IN_PROGRESS, null); // 查询一直处于派送中的订单
if (ordersList != null && ordersList.size() > 0) { // 如果存在这样的订单
for (int i = 0; i < ordersList.size(); i++) { // 遍历这些订单
ordersList.get(i).setStatus(Orders.COMPLETED); // 设置状态为已完成
}
orderMapper.updateBatchStatus(ordersList, Orders.COMPLETED); // 更新订单状态
}
}
}
Loading…
Cancel
Save