diff --git a/sky/sky-common/src/main/java/com/sky/constant/MessageConstant.java b/sky/sky-common/src/main/java/com/sky/constant/MessageConstant.java new file mode 100644 index 0000000..4617ce2 --- /dev/null +++ b/sky/sky-common/src/main/java/com/sky/constant/MessageConstant.java @@ -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 = "订单不存在"; +} \ No newline at end of file diff --git a/sky/sky-common/src/main/java/com/sky/enumeration/OperationType.java b/sky/sky-common/src/main/java/com/sky/enumeration/OperationType.java new file mode 100644 index 0000000..63f5510 --- /dev/null +++ b/sky/sky-common/src/main/java/com/sky/enumeration/OperationType.java @@ -0,0 +1,20 @@ +package com.sky.enumeration; + +/** + * 数据库操作类型枚举,用于定义在应用程序中可能执行的不同类型的数据库操作。 + * 这些操作类型主要用于标识SQL语句的性质,例如是更新现有记录还是插入新记录。 + */ +public enum OperationType { + + /** + * 更新操作,表示对数据库中已存在的记录进行修改。 + * 该操作通常涉及使用SQL UPDATE语句来更改一个或多个字段的值。 + */ + UPDATE, + + /** + * 插入操作,表示向数据库中添加新的记录。 + * 该操作通常涉及使用SQL INSERT语句将新数据行插入到指定的表中。 + */ + INSERT; +} \ No newline at end of file diff --git a/sky/sky-common/src/main/java/com/sky/exception/BaseException.java b/sky/sky-common/src/main/java/com/sky/exception/BaseException.java new file mode 100644 index 0000000..71e7e44 --- /dev/null +++ b/sky/sky-common/src/main/java/com/sky/exception/BaseException.java @@ -0,0 +1,34 @@ +package com.sky.exception; + +/** + * 业务异常类,用于表示应用程序在处理业务逻辑时发生的异常情况。 + *
+ * 这个类继承自 {@link RuntimeException},因此它是一个非检查型异常(unchecked exception), + * 不需要在调用处显式地进行捕获或声明抛出。它主要用于处理那些由于业务规则违反或其他业务逻辑错误导致的问题。 + *
+ * 使用场景: + * - 当业务逻辑验证失败时,例如参数无效、数据不一致等; + * - 当执行某些操作不符合业务流程时,比如尝试对一个已关闭的订单进行修改; + * - 在服务层中,当遇到不可恢复的业务错误时,可以通过抛出此异常来快速返回错误信息给调用者。 + */ +public class BaseException extends RuntimeException { + + /** + * 构造一个没有详细消息的业务异常,默认构造函数。 + *
+ * 此构造函数通常用于不需要提供具体原因的情况下,或者在后续代码中会补充更详细的错误信息时使用。 + */ + public BaseException() { + super(); + } + + /** + * 构造一个带有指定详细消息的业务异常。 + * + * @param msg 异常的详细消息,描述了发生的具体问题或错误情况。 + * 这个消息可以被用来向用户展示错误提示,也可以记录到日志中供调试和分析。 + */ + public BaseException(String msg) { + super(msg); + } +} \ No newline at end of file diff --git a/sky/sky-common/src/main/java/com/sky/exception/PasswordEditFailedException.java b/sky/sky-common/src/main/java/com/sky/exception/PasswordEditFailedException.java new file mode 100644 index 0000000..b47a0fd --- /dev/null +++ b/sky/sky-common/src/main/java/com/sky/exception/PasswordEditFailedException.java @@ -0,0 +1,19 @@ +package com.sky.exception; + +/** + * PasswordEditFailedException类用于表示密码修改操作失败时所抛出的特定异常情况。 + * 它继承自BaseException,这样可以复用BaseException中定义的与异常处理相关的通用逻辑(例如可能包含的统一的错误消息记录、日志打印等功能)。 + * 当在系统中进行密码修改的相关业务逻辑出现问题,导致修改无法成功完成时,就可以抛出该异常来清晰地传达错误信息,方便上层调用者进行针对性的异常处理。 + */ +public class PasswordEditFailedException extends BaseException { + + /** + * 构造函数,用于创建PasswordEditFailedException类的实例。 + * + * @param msg 传递进来的表示具体错误消息的字符串,这个消息将被传递给父类BaseException的构造函数, + * 以便后续在处理该异常时可以获取到详细的错误原因说明。例如,msg可能是像"密码长度不符合要求导致修改失败"之类的具体提示信息。 + */ + public PasswordEditFailedException(String msg) { + super(msg); + } +} diff --git a/sky/sky-common/src/main/java/com/sky/exception/UserNotLoginException.java b/sky/sky-common/src/main/java/com/sky/exception/UserNotLoginException.java new file mode 100644 index 0000000..fe26906 --- /dev/null +++ b/sky/sky-common/src/main/java/com/sky/exception/UserNotLoginException.java @@ -0,0 +1,30 @@ +package com.sky.exception; + +/** + * UserNotLoginException类是一个自定义的异常类,用于表示用户未登录的异常情况。 + * 在应用程序中,当需要判断用户是否登录并且发现用户未登录而某些操作又需要用户处于登录状态才能执行时, + * 就可以抛出这个异常来明确地告知调用者出现了用户未登录的问题,以便进行相应的异常处理,比如提示用户登录、重定向到登录页面等操作。 + * 该类继承自BaseException,这样可以借助BaseException中已有的与异常处理相关的通用机制,例如可能存在的统一记录异常日志、 + * 按特定格式处理错误消息等功能,方便在整个项目中对异常进行标准化管理。 + */ +public class UserNotLoginException extends BaseException { + + /** + * 默认构造函数,无参构造函数。 + * 当不需要传递具体的错误消息,只是想单纯抛出表示用户未登录这个异常情况时,可以使用该构造函数来创建异常实例。 + * 不过通常情况下,使用带有具体错误消息的构造函数能提供更详细准确的异常信息,方便后续处理。 + */ + public UserNotLoginException() { + } + + /** + * 带有具体错误消息的构造函数。 + * + * @param msg 一个表示具体错误消息的字符串参数,它将被传递给父类BaseException的构造函数, + * 进而可以在后续处理该异常时获取到详细的错误提示信息。 + * 例如,msg可以是"用户未登录,无法访问个人资料页面"之类明确指出因未登录导致具体操作受限的提示内容。 + */ + public UserNotLoginException(String msg) { + super(msg); + } +} diff --git a/sky/sky-common/src/main/java/com/sky/properties/ReportExcelProperties.java b/sky/sky-common/src/main/java/com/sky/properties/ReportExcelProperties.java new file mode 100644 index 0000000..ad3f3aa --- /dev/null +++ b/sky/sky-common/src/main/java/com/sky/properties/ReportExcelProperties.java @@ -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; + +/** + * ReportExcelProperties类用于配置与Excel相关的属性信息。 + * 它在Spring Boot项目中扮演着重要角色,通过将配置文件中的相关属性值绑定到该类的成员变量上,方便在程序中使用这些配置数据。 + * 例如,配置Excel文件的路径以及相关工作表(sheet)的信息等。 + */ +@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; + + /** + * 用于存储Excel文件中工作表(sheet)的名称数组。 + * 可以通过配置文件中以"sky.excel.sheet"开头的多个属性值来填充这个数组,这些值将被解析并转换为字符串数组,方便后续在操作Excel文件时指定要处理的工作表。 + * 例如,配置文件中可以配置像"sky.excel.sheet[0]=Sheet1"、"sky.excel.sheet[1]=Sheet2"这样的属性来定义多个工作表名称,它们会被绑定到这个数组中,对应的数组形式为{"Sheet1", "Sheet2"}。 + */ + private String[] sheet; + +} diff --git a/sky/sky-common/src/main/java/com/sky/utils/AliOssUtil.java b/sky/sky-common/src/main/java/com/sky/utils/AliOssUtil.java new file mode 100644 index 0000000..c95e72f --- /dev/null +++ b/sky/sky-common/src/main/java/com/sky/utils/AliOssUtil.java @@ -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; + +/** + * AliOssUtil类是一个工具类,主要用于与阿里云对象存储服务(OSS)进行交互,实现文件上传的功能。 + * 它利用了阿里云OSS的Java SDK,方便在Spring Boot项目中将本地文件以字节数组的形式上传到指定的OSS存储桶中,并返回文件在OSS上的访问路径。 + */ +@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)。 + * 它指定了与阿里云OSS进行通信的网络地址,不同的地域对应的Endpoint是不同的,通过配置该属性可以准确连接到对应的OSS服务区域。 + * 例如:"oss-cn-hangzhou.aliyuncs.com"表示阿里云杭州地域的OSS端点,该属性的值通常会从项目的配置文件(如application.properties或application.yml)中获取并注入到这个变量中。 + */ + private String endpoint; + + /** + * 阿里云OSS服务的访问密钥ID(Access Key ID)。 + * 它是用于身份验证的重要凭据之一,与Access Key Secret一起,用于确认调用OSS服务的合法性,相当于用户在阿里云OSS服务中的账号标识,只有拥有正确的Access Key ID和Access Key Secret才能进行相应的操作,如上传、下载文件等。 + * 同样,该值也是从项目的配置文件中安全地获取并注入到此变量中的。 + */ + private String accessKeyId; + + /** + * 阿里云OSS服务的访问密钥(Access Key Secret)。 + * 与Access Key ID配合使用,用于对请求进行签名验证,确保请求的安全性和合法性,是访问OSS服务的重要安全凭证,需要妥善保管,防止泄露。 + * 其值通过配置文件注入到该变量中。 + */ + private String accessKeySecret; + + /** + * 阿里云OSS存储桶(Bucket)的名称。 + * 存储桶是OSS中用于存储对象(如文件等)的容器,类似于文件系统中的文件夹概念,但功能更强大,所有上传到OSS的文件都要存放在某个特定的存储桶中,通过指定该名称,就能确定文件上传的目标存储位置。 + * 其名称由用户在阿里云控制台创建存储桶时定义,并且在项目配置中指定,以便在代码中使用。 + */ + private String bucketName; + + /** + * 文件上传方法,用于将给定的字节数组形式的文件内容上传到阿里云OSS指定的存储桶中,并返回文件在OSS上的访问路径。 + * + * @param bytes 文件字节码,即代表要上传文件的内容以字节数组的形式传入,例如可以通过读取本地文件并转换为字节数组后传递进来,以便将该文件上传到OSS中。 + * @param objectName 文件名字,它是文件在OSS存储桶中的对象名称,也就是文件在OSS中的唯一标识,类似于文件在本地文件系统中的文件名,需要注意命名的唯一性和合法性,遵循OSS的命名规范。 + * @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(); + } +}