diff --git a/.idea/code.iml b/.idea/homework.iml
similarity index 100%
rename from .idea/code.iml
rename to .idea/homework.iml
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
deleted file mode 100644
index 712ab9d..0000000
--- a/.idea/jarRepositories.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index df3a8bb..639900d 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,14 +1,6 @@
-
-
-
-
-
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 556bb1f..0f05a28 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -2,7 +2,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 94a25f7..35eb1dd 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..6ee5908
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1734481479677
+
+
+ 1734481479677
+
+
+
+
+
+
+ 1734481658673
+
+
+
+ 1734481658673
+
+
+
+ 1734481925729
+
+
+
+ 1734481925729
+
+
+
+ 1734481967448
+
+
+
+ 1734481967448
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sky/sky-common/src/main/java/com/sky/constant/PasswordConstant.java b/sky/sky-common/src/main/java/com/sky/constant/PasswordConstant.java
new file mode 100644
index 0000000..4a71eb6
--- /dev/null
+++ b/sky/sky-common/src/main/java/com/sky/constant/PasswordConstant.java
@@ -0,0 +1,16 @@
+package com.sky.constant;
+
+/**
+ * 密码常量类,用于定义项目中与密码相关的常量值。
+ * 此类中的常量可以在整个项目的多个地方被引用,方便统一管理和维护密码相关的固定值。
+ */
+public class PasswordConstant {
+
+ /**
+ * 默认密码常量,定义了系统默认使用的密码字符串值为 "123456"。
+ * 在一些场景下,例如新用户首次创建账号时,如果没有指定密码,可能会默认赋予该密码。
+ * 或者在进行密码重置等操作,当需要一个初始的默认密码时可使用此常量所代表的值。
+ */
+ public static final String DEFAULT_PASSWORD = "123456";
+
+}
diff --git a/sky/sky-common/src/main/java/com/sky/exception/AccountLockedException.java b/sky/sky-common/src/main/java/com/sky/exception/AccountLockedException.java
new file mode 100644
index 0000000..d0388eb
--- /dev/null
+++ b/sky/sky-common/src/main/java/com/sky/exception/AccountLockedException.java
@@ -0,0 +1,28 @@
+package com.sky.exception;
+
+/**
+ * 账号被锁定异常类,用于表示在系统中账号处于被锁定状态时抛出的异常情况。
+ * 当检测到账号由于某些原因(比如多次输入错误密码等)被锁定后,会通过抛出该异常来通知相关的业务逻辑进行相应处理,
+ * 该异常类继承自BaseException,便于统一纳入项目的异常处理体系中。
+ */
+public class AccountLockedException extends BaseException {
+
+ /**
+ * 默认构造函数,无参构造。
+ * 当不需要传递额外的异常信息,仅想表示账号被锁定这一异常情况时可使用此构造函数创建异常实例。
+ */
+ public AccountLockedException() {
+ }
+
+ /**
+ * 带参构造函数,用于创建带有特定异常消息的账号被锁定异常实例。
+ * 通过传入具体的消息字符串(msg),可以在异常抛出时提供更详细的关于账号被锁定原因等方面的信息,
+ * 方便在进行异常处理和日志记录等操作时更清晰地了解具体情况,该构造函数调用了父类(BaseException)的带参构造函数来传递消息。
+ *
+ * @param msg 异常相关的具体消息内容,描述账号被锁定的详细原因等信息。
+ */
+ public AccountLockedException(String msg) {
+ super(msg);
+ }
+
+}
diff --git a/sky/sky-common/src/main/java/com/sky/exception/DeletionNotAllowedException.java b/sky/sky-common/src/main/java/com/sky/exception/DeletionNotAllowedException.java
new file mode 100644
index 0000000..e3de70a
--- /dev/null
+++ b/sky/sky-common/src/main/java/com/sky/exception/DeletionNotAllowedException.java
@@ -0,0 +1,22 @@
+package com.sky.exception;
+/**
+ * 禁止删除异常类,用于在系统中当某些对象或数据不允许被删除的情况下抛出异常。
+ * 例如,可能存在业务规则限制某些关键数据、处于特定状态的数据不能被删除,
+ * 当违反这些规则尝试进行删除操作时,就可以通过抛出该异常来告知调用方操作不被允许,
+ * 它继承自BaseException,以便能更好地融入项目整体的异常处理框架中。
+ */
+public class DeletionNotAllowedException extends BaseException {
+
+ /**
+ * 带参构造函数,用于创建带有具体异常消息的禁止删除异常实例。
+ * 通过传入一个消息字符串(msg),能够详细地说明为什么当前的删除操作不被允许,
+ * 比如是因为数据关联了其他重要模块、处于特定业务流程中不能删除等具体原因,
+ * 该构造函数调用了父类(BaseException)的带参构造函数来传递此消息,方便后续处理异常时获取相关信息。
+ *
+ * @param msg 具体描述禁止删除原因的消息内容。
+ */
+ public DeletionNotAllowedException(String msg) {
+ super(msg);
+ }
+
+}
\ No newline at end of file
diff --git a/sky/sky-common/src/main/java/com/sky/exception/PasswordErrorException.java b/sky/sky-common/src/main/java/com/sky/exception/PasswordErrorException.java
new file mode 100644
index 0000000..a0e2b4e
--- /dev/null
+++ b/sky/sky-common/src/main/java/com/sky/exception/PasswordErrorException.java
@@ -0,0 +1,30 @@
+package com.sky.exception;
+
+/**
+ * 密码错误异常类,用于表示在进行密码验证相关操作时,输入的密码不符合要求、与正确密码不一致的异常情况。
+ * 例如用户登录、修改密码时验证原密码等场景下,若输入的密码不正确,就会通过抛出该异常来通知相应的业务逻辑进行处理,
+ * 该异常类继承自BaseException,便于在整个项目的异常管理体系中统一进行处理和追踪。
+ */
+public class PasswordErrorException extends BaseException {
+
+ /**
+ * 无参构造函数,用于创建一个默认的密码错误异常实例。
+ * 当不需要传递额外详细的异常消息,仅想表明密码出现错误这一基本情况时,可以使用这个构造函数来创建异常对象,
+ * 后续可以根据异常类型在统一的异常处理机制中进行相应的通用处理操作。
+ */
+ public PasswordErrorException() {
+ }
+
+ /**
+ * 带参构造函数,用于创建带有特定消息的密码错误异常实例。
+ * 通过传入具体的消息字符串(msg),可以详细说明密码错误的具体原因,比如是长度不符合要求、格式不对,
+ * 或者与存储的正确密码不匹配等具体情况,此构造函数调用了父类(BaseException)的带参构造函数来传递该消息,
+ * 方便在异常处理以及日志记录等环节能够准确获取密码错误的详细缘由并进行针对性的处理。
+ *
+ * @param msg 描述密码错误具体原因的消息内容。
+ */
+ public PasswordErrorException(String msg) {
+ super(msg);
+ }
+
+}
diff --git a/sky/sky-common/src/main/java/com/sky/json/JacksonObjectMapper.java b/sky/sky-common/src/main/java/com/sky/json/JacksonObjectMapper.java
new file mode 100644
index 0000000..5279524
--- /dev/null
+++ b/sky/sky-common/src/main/java/com/sky/json/JacksonObjectMapper.java
@@ -0,0 +1,77 @@
+package com.sky.json;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
+
+/**
+ * JacksonObjectMapper类,继承自ObjectMapper,主要用于在Java对象与JSON数据之间进行相互转换,是基于Jackson框架实现的对象映射器。
+ * 在数据交互过程中,将JSON解析为Java对象的操作被称为 [从JSON反序列化Java对象],而把Java对象转换生成JSON的操作则被称为 [序列化Java对象到JSON]。
+ * 此类通过配置一系列的序列化和反序列化相关特性及自定义模块,来满足项目中对于JSON和Java对象转换时的特定需求,例如时间格式处理以及对未知属性的兼容处理等。
+ */
+public class JacksonObjectMapper extends ObjectMapper {
+
+ /**
+ * 默认的日期格式字符串,用于定义在序列化和反序列化LocalDate类型时采用的日期格式,格式为 "yyyy-MM-dd",
+ * 符合常见的日期表示规范,方便在JSON数据与Java的LocalDate对象转换时统一日期的呈现和解析方式,确保数据的一致性和准确性。
+ */
+ public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
+
+ /**
+ * 默认的日期时间格式字符串,原本定义为 "yyyy-MM-dd HH:mm:ss",后修改为 "yyyy-MM-dd HH:mm",用于指定在处理LocalDateTime类型时的日期时间格式,
+ * 这种格式适用于项目中对于日期时间的具体展示和解析需求,例如在记录操作时间、事件发生时间等场景下,按照此格式进行转换,便于前后端数据交互以及数据存储和展示的统一。
+ */
+ public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
+
+ /**
+ * 默认的时间格式字符串,用于规范LocalTime类型在序列化和反序列化过程中的时间格式,格式为 "HH:mm:ss",
+ * 主要用于表示一天内的具体时间点,在涉及只关注时间部分(如营业时间、任务执行时间等)的业务场景中,以此格式来准确转换JSON与Java对象中的时间数据。
+ */
+ public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
+
+ /**
+ * 构造函数,在创建JacksonObjectMapper对象时进行一系列的初始化配置操作。
+ */
+ public JacksonObjectMapper() {
+ super();
+
+ // 配置在接收到未知属性时不报异常的特性。
+ // 在JSON数据转换为Java对象时,如果JSON中包含了Java对象对应类中不存在的属性,默认情况下Jackson会抛出异常,
+ // 通过设置此项为false,使得在遇到这种情况时能够进行兼容处理,避免因未知属性导致转换失败,提高了对不同格式JSON数据的兼容性。
+ this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
+
+ // 进一步设置反序列化时属性不存在的兼容处理。
+ // 确保在反序列化过程中,即使遇到JSON中的属性在Java对象对应类里不存在的情况,也能平稳进行处理,不会因这种差异而中断转换流程,
+ // 这是对反序列化兼容性的再次强化,和上面的配置一起保障了在接收不同结构JSON数据时的稳健性。
+ this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+
+ SimpleModule simpleModule = new SimpleModule()
+ // 为LocalDateTime类型添加反序列化器,使用指定的日期时间格式(由DEFAULT_DATE_TIME_FORMAT定义)来解析JSON中的日期时间字符串,将其转换为Java的LocalDateTime对象。
+ .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
+ // 为LocalDate类型添加反序列化器,按照默认的日期格式(DEFAULT_DATE_FORMAT)把JSON中的日期字符串反序列化为Java的LocalDate对象。
+ .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
+ // 为LocalTime类型添加反序列化器,依据默认的时间格式(DEFAULT_TIME_FORMAT)将JSON中的时间字符串转换为Java的LocalTime对象。
+ .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
+ // 为LocalDateTime类型添加序列化器,将Java的LocalDateTime对象按照指定的日期时间格式(DEFAULT_DATE_TIME_FORMAT)转换为JSON中的日期时间字符串进行输出。
+ .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
+ // 为LocalDate类型添加序列化器,把Java的LocalDate对象依照默认的日期格式(DEFAULT_DATE_FORMAT)序列化为JSON中的日期字符串。
+ .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
+ // 为LocalTime类型添加序列化器,使用默认的时间格式(DEFAULT_TIME_FORMAT)将Java的LocalTime对象转换为JSON中的时间字符串,方便在JSON数据中呈现。
+ .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
+
+ // 注册功能模块,通过注册这个自定义的SimpleModule,使得添加的针对时间类型的序列化器和反序列化器生效,
+ // 同时也可以在后续根据需要添加更多自定义的序列化器和反序列化器,扩展该对象映射器的功能,以满足不同业务场景下对JSON与Java对象转换的特殊要求。
+ this.registerModule(simpleModule);
+ }
+}
\ No newline at end of file
diff --git a/sky/sky-common/src/main/java/com/sky/properties/WeChatProperties.java b/sky/sky-common/src/main/java/com/sky/properties/WeChatProperties.java
new file mode 100644
index 0000000..ba33547
--- /dev/null
+++ b/sky/sky-common/src/main/java/com/sky/properties/WeChatProperties.java
@@ -0,0 +1,74 @@
+package com.sky.properties;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * WeChatProperties类,主要用于配置与微信相关的各种属性信息,方便在项目中集中管理和获取微信小程序、支付等相关功能所需要的关键参数。
+ * 通过使用Spring框架提供的相关注解,能够将配置文件(通常是application.properties或application.yml等)中以特定前缀开头的配置项自动绑定到此类的对应属性上,实现配置的便捷注入和使用。
+ */
+@Component
+@ConfigurationProperties(prefix = "sky.wechat")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class WeChatProperties {
+
+ /**
+ * 小程序的appid,是小程序在微信平台上的唯一标识,用于区分不同的小程序应用,
+ * 在与微信小程序进行交互时,如调用微信登录、获取用户信息等接口操作,都需要提供这个appid来进行身份验证和授权,确保操作是针对特定的小程序进行的。
+ */
+ private String appid;
+
+ /**
+ * 小程序的秘钥,是用于保障小程序与微信服务器之间通信安全的重要密钥,
+ * 例如在获取小程序的访问令牌(access token)等涉及安全验证的操作中,会结合这个秘钥来生成签名等信息,确保请求的合法性和数据的保密性,防止非法访问和数据篡改。
+ */
+ private String secret;
+
+ /**
+ * 商户号,是在微信支付体系中用于标识商家身份的唯一编号,
+ * 当进行微信支付相关的业务操作,如发起支付、处理退款等流程时,微信支付平台会通过这个商户号来识别是哪个商家在进行操作,关联对应的账户信息、交易记录等内容。
+ */
+ private String mchid;
+
+ /**
+ * 商户API证书的证书序列号,用于唯一标识商户的API证书,
+ * 在使用微信支付的一些高级接口或者涉及到证书验证的操作场景中,微信支付平台会通过这个序列号来验证商户所提供证书的合法性和有效性,确保通信双方的身份可靠。
+ */
+ private String mchSerialNo;
+
+ /**
+ * 商户私钥文件,指向存储商户私钥的文件路径,商户私钥是进行加密、签名等安全操作的关键元素,
+ * 在与微信支付平台进行数据交互时,使用私钥来生成数字签名等,以证明请求是由合法的商户发起的,保障支付交易过程中的安全性和不可抵赖性。
+ */
+ private String privateKeyFilePath;
+
+ /**
+ * 证书解密的密钥,用于对微信支付相关证书进行解密操作,
+ * 在获取和使用微信支付平台提供的一些加密数据、验证证书内容等场景下,需要使用这个密钥来解密相关信息,确保能够正确读取和使用证书中的关键数据。
+ */
+ private String apiV3Key;
+
+ /**
+ * 平台证书,指向微信支付平台证书文件的路径,平台证书是微信支付平台用于向商户证明其自身身份合法性的重要凭证,
+ * 商户在与微信支付进行交互时,通过验证平台证书来确认是与合法的微信支付平台进行通信,保障支付交易的安全性和可靠性。
+ */
+ private String weChatPayCertFilePath;
+
+ /**
+ * 支付成功的回调地址,是微信支付平台在支付操作成功后,向商户系统发送支付结果通知的目标URL地址,
+ * 商户系统需要提供这个有效的回调地址,以便及时获取支付成功的信息,进而进行后续的业务处理,比如更新订单状态、通知用户支付成功等操作。
+ */
+ private String notifyUrl;
+
+ /**
+ * 退款成功的回调地址,类似于支付成功的回调地址,不过它是专门用于在微信支付平台完成退款操作成功后,向商户系统发送退款结果通知的目标URL地址,
+ * 商户系统依据这个回调地址接收到退款成功的通知后,可以进行相应的业务处理,例如更新退款相关的记录、通知用户退款已到账等操作。
+ */
+ private String refundNotifyUrl;
+
+}
\ No newline at end of file
diff --git a/sky/sky-common/src/main/java/com/sky/utils/HttpClientUtil.java b/sky/sky-common/src/main/java/com/sky/utils/HttpClientUtil.java
new file mode 100644
index 0000000..6e0c261
--- /dev/null
+++ b/sky/sky-common/src/main/java/com/sky/utils/HttpClientUtil.java
@@ -0,0 +1,205 @@
+package com.sky.utils;
+
+import com.alibaba.fastjson.JSONObject;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * HttpClientUtil类,是一个Http工具类,主要用于在Java程序中方便地发送HTTP请求(支持GET、POST等常见方式),并获取相应的响应结果,
+ * 简化了与HTTP协议交互的操作,使得在项目中进行网络请求相关的业务逻辑开发更加便捷高效,避免了重复编写复杂的底层HTTP请求代码。
+ */
+public class HttpClientUtil {
+
+ /**
+ * 定义请求超时时间,单位为毫秒,此处设置为5秒(5 * 1000毫秒),用于控制HTTP请求在连接建立、等待连接可用以及数据传输等阶段的最长等待时间,
+ * 避免因网络问题等原因导致请求长时间阻塞,影响程序的性能和稳定性,在创建请求配置时会应用这个超时时间。
+ */
+ static final int TIMEOUT_MSEC = 5 * 1000;
+
+ /**
+ * 发送GET方式请求的方法,用于向指定的URL发送GET请求,并可携带请求参数,最后返回服务器响应的结果字符串。
+ *
+ * @param url 请求的url,即要访问的目标服务器资源的网络地址,完整地指定了请求的目标位置,例如某个API接口地址等。
+ * @param paramMap 请求参数,以Map形式存储,其中键为参数名,值为对应的参数值,可用于向服务器传递一些查询条件、筛选条件等信息,方便服务器根据这些参数返回相应的数据,参数可为空,表示无参数请求。
+ * @return 返回响应结果,是服务器接收到请求后返回的内容,通常为JSON字符串、HTML页面内容或者其他符合约定的数据格式,若请求出现异常等情况可能返回空字符串。
+ */
+ public static String doGet(String url, Map paramMap) {
+ // 创建Httpclient对象,通过HttpClients.createDefault()方法获取默认配置的可关闭的HttpClient实例,用于后续发起HTTP请求,它是整个请求操作的基础客户端对象。
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+
+ String result = "";
+ CloseableHttpResponse response = null;
+
+ try {
+ // 创建URIBuilder对象,用于构建完整的URI(统一资源标识符),可以方便地在给定基础URL的基础上添加各种参数,构造出符合要求的请求地址。
+ URIBuilder builder = new URIBuilder(url);
+ if (paramMap!= null) {
+ // 遍历请求参数Map,将每个参数添加到URIBuilder中,使其构建的URI包含相应的查询参数,按照参数名和参数值的对应关系进行添加,形成完整的带参请求地址。
+ for (String key : paramMap.keySet()) {
+ builder.addParameter(key, paramMap.get(key));
+ }
+ }
+ // 根据构建好的URIBuilder生成最终的URI对象,该对象完整地描述了请求的目标资源位置及相关参数信息。
+ URI uri = builder.build();
+
+ // 创建GET请求对象,使用生成的URI来初始化HttpGet实例,明确此次请求的方式为GET以及请求的具体目标地址。
+ HttpGet httpGet = new HttpGet(uri);
+
+ // 发送请求,通过之前创建的HttpClient实例执行HttpGet请求,获取服务器返回的响应对象CloseableHttpResponse,此对象包含了响应的状态码、响应头以及响应体等重要信息。
+ response = httpClient.execute(httpGet);
+
+ // 判断响应状态,获取响应的状态码,若状态码为200,表示请求成功,此时将响应体内容(通过EntityUtils.toString方法,指定编码为"UTF-8")读取出来赋值给result变量,作为最终的响应结果返回;若状态码不是200,则返回空字符串。
+ if (response.getStatusLine().getStatusCode() == 200) {
+ result = EntityUtils.toString(response.getEntity(), "UTF-8");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ // 关闭响应对象,释放相关资源,避免资源泄漏,无论请求是否成功都需要执行此操作。
+ response.close();
+ // 关闭HttpClient对象,释放其占用的网络连接等资源,确保程序的资源管理良好。
+ httpClient.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * 发送POST方式请求的方法(用于发送表单形式数据的POST请求),向指定URL发送POST请求,携带以表单形式组织的参数,返回服务器响应的结果字符串,若请求过程中出现IO异常则向上抛出。
+ *
+ * @param url 目标请求的URL地址,指定了请求要发送到的服务器资源位置,同GET请求方法中的url参数作用类似。
+ * @param paramMap 请求参数,以Map形式存储,其中键是表单字段名,值为对应字段的值,用于向服务器传递需要处理的数据,比如提交用户注册信息、登录信息等以表单形式组织的数据,参数可为空表示无参数POST请求。
+ * @return 返回响应结果,即服务器接收到POST请求后返回的内容,格式根据服务器端的响应设定而定,通常可能是操作结果提示信息、新生成的数据等内容,以字符串形式返回,若请求出现异常等情况则按照异常处理逻辑进行处理。
+ * @throws IOException 当在请求执行过程中(如创建请求实体、执行请求、关闭响应等操作涉及到的输入输出操作)出现I/O相关异常时,会将该异常向上抛出,由调用者进行进一步的处理。
+ */
+ public static String doPost(String url, Map paramMap) throws IOException {
+ // 创建Httpclient对象,获取默认配置的可关闭的HttpClient实例,用于后续发起HTTP的POST请求操作,作为请求的客户端基础对象。
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+ CloseableHttpResponse response = null;
+ String resultString = "";
+
+ try {
+ // 创建Http Post请求对象,使用给定的URL初始化HttpPost实例,明确此次请求的方式为POST以及请求的目标地址,后续将在此基础上添加请求参数等内容。
+ HttpPost httpPost = new HttpPost(url);
+
+ // 创建参数列表,若传入的请求参数Map不为空,则遍历该Map,将每个参数转换为NameValuePair对象并添加到List中,NameValuePair用于表示键值对形式的参数,方便后续构建表单形式的请求实体。
+ if (paramMap!= null) {
+ List paramList = new ArrayList<>();
+ for (Map.Entry param : paramMap.entrySet()) {
+ paramList.add(new BasicNameValuePair(param.getKey(), param.getValue()));
+ }
+ // 模拟表单,通过将参数列表转换为UrlEncodedFormEntity对象来构建表单形式的请求实体,它会对参数进行适当的编码处理(例如对中文等特殊字符进行URL编码),符合HTTP表单提交的规范,然后将该请求实体设置到HttpPost请求对象中,使得请求携带相应的参数信息。
+ UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
+ httpPost.setEntity(entity);
+
+ }
+
+ // 设置请求配置,通过调用builderRequestConfig方法构建请求配置对象,并设置到HttpPost请求中,该配置包含了连接超时时间、请求获取连接的超时时间以及套接字超时时间等设置,确保请求在合理的时间范围内进行,避免长时间等待。
+ httpPost.setConfig(builderRequestConfig());
+
+ // 执行http请求,使用HttpClient实例执行HttpPost请求,获取服务器返回的响应对象CloseableHttpResponse,其中包含了响应的各种关键信息,如状态码、响应头和响应体等。
+ response = httpClient.execute(httpPost);
+ // 将响应体内容(通过EntityUtils.toString方法,指定编码为"UTF-8")读取出来赋值给resultString变量,作为最终的响应结果返回,若响应体为空或者读取出现异常等情况会按照相应逻辑处理。
+ resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ try {
+ // 关闭响应对象,释放相关资源,确保资源正确回收,避免资源泄漏,无论请求是否成功都需要执行此操作。
+ response.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ return resultString;
+ }
+
+ /**
+ * 发送POST方式请求的方法(用于发送JSON格式数据的POST请求),向指定URL发送POST请求,携带以JSON格式组织的参数,返回服务器响应的结果字符串,若请求过程中出现IO异常则向上抛出。
+ *
+ * @param url 目标请求的URL地址,指定了请求要发送到的服务器资源位置,作用与前面的POST方法中的url参数相同。
+ * @param paramMap 请求参数,以Map形式存储,用于构建JSON格式的数据,其中键将作为JSON对象中的属性名,值作为对应的属性值,方便向服务器传递复杂的数据结构,参数可为空表示无参数的JSON格式POST请求。
+ * @return 返回响应结果,即服务器接收到JSON格式POST请求后返回的内容,格式根据服务器端的响应设定而定,一般可能是处理后的JSON数据、操作提示信息等,以字符串形式返回,若请求出现异常等情况则按照相应的异常处理逻辑进行处理。
+ * @throws IOException 当在请求执行过程中(如构造JSON数据、创建请求实体、执行请求、关闭响应等操作涉及到的输入输出操作)出现I/O相关异常时,会将该异常向上抛出,由调用者进行进一步的处理。
+ */
+ public static String doPost4Json(String url, Map paramMap) throws IOException {
+ // 创建Httpclient对象,获取默认配置的可关闭的HttpClient实例,作为发起HTTP的JSON格式POST请求的客户端基础对象。
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+ CloseableHttpResponse response = null;
+ String resultString = "";
+
+ try {
+ // 创建Http Post请求对象,使用给定的URL初始化HttpPost实例,明确此次请求的方式为POST以及请求的目标地址,后续在此基础上构建JSON格式的请求数据。
+ HttpPost httpPost = new HttpPost(url);
+
+ if (paramMap!= null) {
+ // 构造json格式数据,通过遍历请求参数Map,将每个参数添加到JSONObject中,形成一个JSON格式的对象,其中参数名作为JSON对象的属性名,参数值作为对应属性的值,方便以JSON格式向服务器传递数据,符合现在很多基于RESTful API等交互中常用的JSON数据传输规范。
+ JSONObject jsonObject = new JSONObject();
+ for (Map.Entry param : paramMap.entrySet()) {
+ jsonObject.put(param.getKey(), param.getValue());
+ }
+ // 创建StringEntity对象,将JSON对象转换为字符串形式,并指定编码为"utf-8",然后设置其内容编码和数据类型(设置为"application/json",表明这是一个JSON格式的数据),最后将该请求实体设置到HttpPost请求对象中,使得请求携带JSON格式的参数信息。
+ StringEntity entity = new StringEntity(jsonObject.toString(), "utf-8");
+ // 设置请求编码,明确请求实体的编码方式为"utf-8",确保数据在传输过程中的编码一致性,便于服务器正确解析接收到的数据。
+ entity.setContentEncoding("utf-8");
+ // 设置数据类型,将请求实体的数据类型设置为"application/json",告知服务器此次请求发送的数据是JSON格式的,方便服务器按照相应的解析方式处理接收到的数据。
+ entity.setContentType("application/json");
+ httpPost.setEntity(entity);
+ }
+
+ // 设置请求配置,调用builderRequestConfig方法构建请求配置对象,并设置到HttpPost请求中,该配置包含了连接超时时间、请求获取连接的超时时间以及套接字超时时间等设置,保证请求能在合理的时间范围内完成,避免因网络等问题导致请求长时间无响应。
+ httpPost.setConfig(builderRequestConfig());
+
+ // 执行http请求,使用HttpClient实例执行HttpPost请求,获取服务器返回的响应对象CloseableHttpResponse,该对象包含了响应的状态码、响应头以及响应体等重要信息,用于后续获取响应结果。
+ response = httpClient.execute(httpPost);
+
+ // 将响应体内容(通过EntityUtils.toString方法,指定编码为"UTF-8")读取出来赋值给resultString变量,作为最终的响应结果返回,若响应体为空或者读取出现异常等情况会按照相应逻辑处理。
+ resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ try {
+ // 关闭响应对象,释放相关资源,避免资源泄漏,无论请求是否成功都需要执行此操作。
+ response.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ return resultString;
+ }
+
+ /**
+ * 构建请求配置的私有方法,用于创建一个RequestConfig对象,设置了连接超时时间、请求获取连接的超时时间以及套接字超时时间,均使用类中定义的TIMEOUT_MSEC常量值(5秒),
+ * 该配置对象用于在发送HTTP请求(如HttpGet、HttpPost等请求)时设置相关的超时限制,确保请求在合理的时间范围内进行,避免因网络问题等导致请求长时间阻塞,影响程序性能和用户体验。
+ *
+ * @return 返回构建好的RequestConfig对象,包含了设置好的各种超时时间配置,供其他发送请求的方法使用来设置请求的超时相关属性。
+ */
+ private static RequestConfig builderRequestConfig() {
+ return RequestConfig.custom()
+ .setConnectTimeout(TIMEOUT_MSEC)
+ .setConnectionRequestTimeout(TIMEOUT_MSEC)
+ .setSocketTimeout(TIMEOUT_MSEC).build();
+ }
+
+}
\ No newline at end of file
diff --git a/sky/sky-pojo/src/main/java/com/sky/dto/DishDTO.java b/sky/sky-pojo/src/main/java/com/sky/dto/DishDTO.java
new file mode 100644
index 0000000..207285d
--- /dev/null
+++ b/sky/sky-pojo/src/main/java/com/sky/dto/DishDTO.java
@@ -0,0 +1,67 @@
+package com.sky.dto;
+
+import com.sky.entity.DishFlavor;
+import lombok.Data;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * DishDTO类,作为数据传输对象(Data Transfer Object),主要用于在系统不同模块或层次(比如业务逻辑层与展示层之间)传递菜品相关的数据信息,
+ * 其目的在于简化数据交互流程,将菜品的关键属性整合起来进行传递,遵循关注点分离原则,避免传递过多业务逻辑无关的内容,方便各模块间协同工作,确保数据传输的高效性和准确性。
+ * 该类实现了Serializable接口,这意味着它能够被序列化,可应用于网络传输、持久化存储等场景,保障了数据在不同环境下可以完整且正确地流转和保存,满足系统对数据交互的实际需求。
+ * 通过使用Lombok的@Data注解,自动为类生成了常用的方法,像Getter、Setter、toString、equals和hashCode等方法,减少了手动编写这些样板代码的工作量,使代码更加简洁明了,易于维护和扩展。
+ */
+@Data
+public class DishDTO implements Serializable {
+
+ /**
+ * 菜品的唯一标识符,通常对应数据库中菜品记录的主键值,通过这个id可以在整个系统中精准地定位到具体的某一道菜品,
+ * 便于进行菜品的查询、修改、删除以及与其他业务逻辑相关的操作,是菜品在系统内的重要标识,对于菜品管理等业务场景起着关键作用。
+ */
+ private Long id;
+
+ /**
+ * 菜品名称,是展示给用户看到的、用于区分不同菜品的重要文本信息,用户可以根据菜品名称直观地了解菜品的大致内容或特点,
+ * 同时也是系统内部进行菜品管理、查询等操作时的重要依据之一,例如在菜单展示、点菜操作等场景中,菜品名称都是必不可少的关键元素。
+ */
+ private String name;
+
+ /**
+ * 菜品分类id,用于指明该菜品所属的分类,不同的分类可能有不同的业务规则、展示方式或者营销策略等,
+ * 通过这个分类id可以关联到对应的分类信息,比如在菜单展示中按照分类来分组显示菜品,方便用户查找和选择,有助于提升用户体验以及系统的菜品管理效率。
+ */
+ private Long categoryId;
+
+ /**
+ * 菜品价格,使用BigDecimal类型来精确表示价格数值,因为在涉及金额计算时,需要保证精度和准确性,避免浮点数运算带来的精度丢失问题,
+ * 该价格是用户购买菜品需要支付的金额,也是进行财务统计、价格比较等业务操作的关键数据,对于餐饮系统等涉及菜品售卖的业务场景十分重要。
+ */
+ private BigDecimal price;
+
+ /**
+ * 图片,用于展示菜品的外观、样式等可视化信息,通过图片可以让用户更直观地感受菜品的样子,增强用户购买的欲望,
+ * 在前端界面展示中,通常会将这个图片显示在菜品相关的位置,提升菜品展示效果以及用户的点菜意愿,是优化用户体验的重要因素之一。
+ */
+ private String image;
+
+ /**
+ * 描述信息,用于对菜品进行更详细的介绍,比如菜品的制作工艺、口味特点、食材组成等内容,
+ * 帮助用户更好地了解菜品详情,以便做出是否购买的决策,同时也便于后台管理人员对菜品进行准确的描述和管理,在菜品展示和管理环节都有着重要意义。
+ */
+ private String description;
+
+ /**
+ * 状态字段,以整数形式表示菜品的当前销售状态,其中“0”表示停售,意味着该菜品暂时不可供用户购买,可能是由于原材料短缺、菜品调整等原因;
+ * “1”表示起售,即菜品处于正常可售卖、可供用户选择的状态,系统可以根据这个状态来决定是否展示该菜品以及是否允许进行相关的下单操作等,方便对菜品的售卖情况进行管控。
+ */
+ private Integer status;
+
+ /**
+ * 口味,是一个List集合,用于存放与该菜品相关联的DishFlavor对象,每个DishFlavor对象代表菜品的一种口味以及相关的口味信息(如口味的具体配料、辣度等),
+ * 通过这个集合可以清晰地知道该菜品具体有哪些口味可供选择,便于进行菜品口味的管理、展示以及在业务流程中涉及口味调整等操作,满足用户对于菜品口味多样化的需求。
+ */
+ private List flavors = new ArrayList<>();
+
+}
\ No newline at end of file
diff --git a/sky/sky-pojo/src/main/java/com/sky/dto/EmployeePageQueryDTO.java b/sky/sky-pojo/src/main/java/com/sky/dto/EmployeePageQueryDTO.java
new file mode 100644
index 0000000..892e1ef
--- /dev/null
+++ b/sky/sky-pojo/src/main/java/com/sky/dto/EmployeePageQueryDTO.java
@@ -0,0 +1,33 @@
+package com.sky.dto;
+
+import lombok.Data;
+import java.io.Serializable;
+
+/**
+ * EmployeePageQueryDTO类,作为数据传输对象(Data Transfer Object),主要用于在系统中传递员工信息分页查询相关的数据。
+ * 它在涉及员工列表分页展示、按条件分页查找员工等业务场景下,负责将查询所需的关键参数从一层(比如表现层)传递到另一层(如业务逻辑层),以方便进行相应的数据库查询操作,遵循了关注点分离原则,简化了数据交互过程。
+ * 该类实现了Serializable接口,这使得它能够被序列化,便于在诸如网络传输(例如从前端页面传递查询参数到后端服务)、持久化存储(虽相对少见,但在特定缓存等场景下可能涉及)等场景下正常使用,确保数据的完整性以及可以顺利地流转和保存。
+ * 通过使用Lombok的@Data注解,自动为类生成了常用的方法,像Getter、Setter、toString、equals和hashCode等方法,减少了手动编写这些重复代码的工作量,让代码更加简洁高效,便于开发人员聚焦于核心业务逻辑。
+ */
+@Data
+public class EmployeePageQueryDTO implements Serializable {
+
+ /**
+ * 员工姓名,用于指定要查询的员工姓名相关的筛选条件。
+ * 可以是完整的员工真实姓名,也可以是部分姓名,业务逻辑层在接收到这个参数后,可根据具体的数据库查询规则(比如模糊查询等方式),查找出符合该姓名条件的员工记录,方便进行精准或模糊的员工查找操作,满足不同的查询需求。
+ */
+ private String name;
+
+ /**
+ * 页码,用于表示当前要查询的是第几页的数据。
+ * 在分页查询中,数据通常会被分成多个页面进行展示,这个页码参数明确了用户希望查看的具体页面位置,后端根据该页码以及每页显示记录数等信息,计算出要从数据库中提取哪些对应的数据记录,以便准确返回相应页面的员工信息,提升用户查看数据的便捷性和体验感。
+ */
+ private int page;
+
+ /**
+ * 每页显示记录数,确定了每个页面中最多显示的员工记录数量。
+ * 通过合理设置这个参数,可以控制页面数据的展示密度,避免一次展示过多数据导致页面加载缓慢或用户查看不便等问题,同时也便于后端进行数据库查询时,准确地按照设定的数量提取相应的员工记录来填充每一页的数据内容,优化分页查询的效果。
+ */
+ private int pageSize;
+
+}
\ No newline at end of file
diff --git a/sky/sky-pojo/src/main/java/com/sky/dto/OrdersDTO.java b/sky/sky-pojo/src/main/java/com/sky/dto/OrdersDTO.java
new file mode 100644
index 0000000..64ff6b3
--- /dev/null
+++ b/sky/sky-pojo/src/main/java/com/sky/dto/OrdersDTO.java
@@ -0,0 +1,135 @@
+package com.sky.dto;
+
+import com.sky.entity.OrderDetail;
+import lombok.Data;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * OrdersDTO类,作为数据传输对象(Data Transfer Object),主要用于在系统不同模块或层次(比如业务逻辑层与展示层之间)传递订单相关的数据信息,
+ * 其目的在于整合订单相关的关键数据,简化数据交互流程,使得在涉及订单处理、展示等业务场景下,各模块能够方便地传递和使用订单数据,遵循关注点分离原则,避免传递过多不必要的业务逻辑细节,确保系统各部分协同高效工作。
+ * 该类实现了Serializable接口,这意味着它能够被序列化,可应用于网络传输、持久化存储等多种场景,保障了订单数据在不同环境下可以完整、准确地流转和保存,满足系统在不同业务环节对订单数据交互的需求。
+ * 通过使用Lombok的@Data注解,自动为类生成了常用的方法,像Getter、Setter、toString、equals和hashCode等方法,减少了手动编写这些样板代码的工作量,使代码更加简洁易读,便于后续的维护和扩展。
+ */
+@Data
+public class OrdersDTO implements Serializable {
+
+ /**
+ * 订单的唯一标识符,通常对应数据库中订单记录的主键值,通过这个id可以在整个系统中精准地定位到具体的某一笔订单,
+ * 便于进行订单的查询、修改、删除以及与其他业务逻辑相关的操作,是订单在系统内的重要标识,对于订单管理、订单状态跟踪等业务场景起着关键作用。
+ */
+ private Long id;
+
+ /**
+ * 订单号,是用于唯一标识每一笔订单的字符串,在整个系统中通过这个订单号可以快速且准确地找到对应的订单,
+ * 它在与外部系统交互(如支付平台回调、物流配送对接等)、用户查看订单详情以及内部业务逻辑处理(如订单查询、关联订单相关业务操作等)等场景下,都是非常重要的标识信息,方便各环节准确识别具体的订单。
+ */
+ private String number;
+
+ /**
+ * 订单状态,以整数形式表示订单当前所处的不同阶段,其中:
+ * 1表示待付款,意味着用户已经提交了订单,但尚未完成支付操作,此时订单处于等待用户付款的状态,系统可能会根据业务规则设定一定的付款期限等相关处理;
+ * 2表示待派送,说明用户已成功付款,订单进入等待商家安排派送的阶段,商家需要准备商品、安排配送人员等相关事宜;
+ * 3表示已派送,代表商品已经从商家发出,正在送往用户指定地址的过程中,用户可以通过此状态跟踪配送进度等;
+ * 4表示已完成,即订单的整个交易流程顺利结束,用户已收到商品且无其他后续问题,商家可以进行相应的订单完结处理,如统计销售数据等;
+ * 5表示已取消,代表订单由于某些原因(如用户主动取消、不符合下单条件等)被终止,系统需要根据具体的取消原因进行相应的后续处理,比如退款、释放库存等操作。
+ * 这个状态字段方便系统根据不同状态进行相应的业务流程控制和展示不同状态下的订单信息给用户查看。
+ */
+ private Integer status;
+
+ /**
+ * 下单用户id,用于关联到具体下单的用户,通过这个id可以查询出该用户的相关信息(如用户名、联系方式等),也便于进行用户相关的订单统计分析(如查看某个用户的历史订单情况等),
+ * 在订单处理、用户订单管理等业务场景中,是建立订单与用户之间联系的重要标识,确保订单数据与对应的用户信息准确对应。
+ */
+ private Long userId;
+
+ /**
+ * 餐具数量,用于记录用户在下单时所选择的餐具数量,比如在餐饮外卖等业务场景下,用户可以根据实际用餐人数等因素选择需要的餐具份数,
+ * 该数量信息对于商家准备餐具、配送餐具以及可能涉及的餐具收费等业务操作提供了明确的数据依据,确保满足用户需求同时合理安排相关资源。
+ */
+ private int tablewareNumber;
+
+ /**
+ * 餐具数量状态,以整数形式表示餐具数量的选择方式,其中:
+ * 1表示按餐量提供,意味着餐具数量是根据订单中商品的餐量情况自动匹配提供的,无需用户手动选择具体数量,一般按照一定的业务规则来确定;
+ * 0表示选择具体数量,即用户自己明确指定了需要的餐具具体份数,系统按照用户所选数量进行相应安排,这个字段便于系统区分不同的餐具数量确定方式并进行相应处理。
+ */
+ private Integer tablewareStatus;
+
+ /**
+ * 地址id,用于关联到用户的收货地址信息,通过这个id可以获取到详细的收货地址(如省市区、详细街道地址、收货人等信息),
+ * 在订单派送、地址管理以及物流配送等业务场景中,是确定商品最终送达位置的关键标识,确保订单能够准确无误地送到用户指定的地点。
+ */
+ private Long addressBookId;
+
+ /**
+ * 下单时间,使用LocalDateTime类型精确记录订单创建的时间点,这个时间信息对于统计订单的下单时间分布、分析业务高峰期、查看订单时效性等业务分析操作非常有帮助,
+ * 同时也可以作为订单处理流程中的时间参考依据,比如判断是否超过了付款期限等情况,有助于系统进行相关的时间敏感型业务处理。
+ */
+ private LocalDateTime orderTime;
+
+ /**
+ * 结账时间,同样使用LocalDateTime类型来记录订单完成支付结算的时间,对于财务统计(如统计每日、每月的收款情况等)、订单处理流程跟踪(确定付款环节的具体时间)等业务场景有着重要作用,
+ * 它与下单时间等其他时间字段结合,可以清晰地展现订单从创建到完成支付这一过程的时间跨度以及具体时间节点。
+ */
+ private LocalDateTime checkoutTime;
+
+ /**
+ * 支付方式,以整数形式表示用户选择的用于支付订单的具体途径,其中:
+ * 1表示微信支付,意味着用户通过微信平台提供的支付功能完成了订单付款;
+ * 2表示支付宝支付,即用户使用支付宝的支付服务来支付订单金额,这个字段方便系统对接相应的支付平台进行支付处理以及后续的支付记录统计分析等工作。
+ */
+ private Integer payMethod;
+
+ /**
+ * 实收金额,使用BigDecimal类型来精确表示订单实际收到的金额数值,因为在涉及金额计算和记录时,需要保证精度和准确性,避免浮点数运算带来的精度丢失问题,
+ * 该金额是用户最终为订单支付的实际费用,对于财务核算、订单金额统计、与支付平台对账等业务操作是关键的数据依据。
+ */
+ private BigDecimal amount;
+
+ /**
+ * 备注,是用户在下单时可以填写的一些额外说明信息,比如对菜品口味的特殊要求(在外卖餐饮订单中)、配送时间的特殊期望、对商品的特殊备注等内容,
+ * 商家可以根据这些备注信息来尽量满足用户的个性化需求,同时在订单处理和查看过程中,备注信息也有助于更全面地了解订单的具体情况,提升用户体验。
+ */
+ private String remark;
+
+ /**
+ * 用户名,用于展示下单用户的名称信息,方便在订单相关的展示界面中让接收方(如商家、配送人员等)快速知晓是哪位用户下的订单,
+ * 同时也便于用户在查看自己的订单时,能够直观地确认订单归属,增强订单信息的可读性和辨识度。
+ */
+ private String userName;
+
+ /**
+ * 手机号,记录下单用户的联系方式,在订单处理过程中,如果遇到问题(如配送地址不清楚、商品有疑问等情况),相关人员(如配送员、客服等)可以通过这个手机号与用户取得联系,
+ * 它是保障订单顺利完成以及进行用户沟通的重要信息,对于订单的配送、售后服务等环节起着关键作用。
+ */
+ private String phone;
+
+ /**
+ * 地址,用于展示用户的详细收货地址信息,将收货地址以字符串形式呈现出来,方便相关人员(如配送员等)直接查看并准确找到送货地点,
+ * 与地址id关联获取的地址信息相对应,是在订单展示等场景下更直观呈现地址内容的一种方式,确保订单能够准确送达目的地。
+ */
+ private String address;
+
+ /**
+ * 收货人,明确记录了接收商品的人员姓名,在配送环节,配送员可以通过这个收货人姓名来确认将商品交付给正确的对象,
+ * 是收货地址信息中很重要的一部分,对于保证商品准确送达以及避免配送错误等情况有着重要意义,提升订单配送的准确性。
+ */
+ private String consignee;
+
+ /**
+ * 订单详情列表,用于存放与该订单相关联的OrderDetail对象,每个OrderDetail对象代表订单中的一项商品详情(如商品名称、数量、单价等信息),
+ * 通过这个列表可以清晰地知道该订单具体包含了哪些商品以及它们各自的具体情况,便于进行订单商品的管理、展示以及在业务流程中涉及商品调整、统计商品销售数量等操作,是订单数据中不可或缺的重要组成部分。
+ */
+ private List orderDetails;
+
+ /**
+ * 配送状态,以整数形式表示商品配送的时间安排情况,其中:
+ * 1表示立即送出,意味着订单完成支付后,商家会尽快安排商品进行配送,无需用户指定具体的配送时间,按照正常的业务流程尽快发货;
+ * 0表示选择具体时间,即用户在下单时指定了希望商品在某个特定时间进行配送,商家需要根据用户的要求来安排相应的配送计划,这个字段便于系统区分不同的配送时间安排方式并进行相应处理。
+ */
+ private Integer deliveryStatus;
+
+}
\ No newline at end of file
diff --git a/sky/sky-pojo/src/main/java/com/sky/dto/OrdersSubmitDTO.java b/sky/sky-pojo/src/main/java/com/sky/dto/OrdersSubmitDTO.java
new file mode 100644
index 0000000..11836f5
--- /dev/null
+++ b/sky/sky-pojo/src/main/java/com/sky/dto/OrdersSubmitDTO.java
@@ -0,0 +1,75 @@
+package com.sky.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * OrdersSubmitDTO类,作为数据传输对象(Data Transfer Object),主要用于在系统中传递订单提交相关的数据信息,
+ * 也就是在用户完成下单操作、即将向系统提交订单时,将涉及订单提交环节的关键数据整合起来进行传递,方便各业务模块间协同处理订单提交的业务逻辑,
+ * 遵循了关注点分离原则,简化了数据交互过程,使得订单提交这一复杂业务场景中的数据流转更加清晰、高效。
+ * 该类实现了Serializable接口,这使得它能够被序列化,便于在诸如网络传输(从前端页面传递订单提交数据到后端服务)、持久化存储(比如可能涉及的临时存储订单提交信息等场景)等场景下正常使用,确保数据的完整性以及可以顺利地流转和保存。
+ * 通过使用Lombok的@Data注解,自动为类生成了常用的方法,像Getter、Setter、toString、equals和hashCode等方法,减少了手动编写这些重复代码的工作量,让代码更加简洁高效,便于开发人员聚焦于核心业务逻辑。
+ */
+@Data
+public class OrdersSubmitDTO implements Serializable {
+
+ /**
+ * 地址簿id,用于关联到用户预先设置好的地址簿信息,通过这个id可以获取到详细的收货地址(包括收货人姓名、联系电话、省市区地址以及详细街道地址等内容),
+ * 在订单提交时,明确收货地址是非常关键的,它决定了商品最终要送达的位置,确保订单能够准确无误地送到用户指定的地点,方便后续的配送等业务操作。
+ */
+ private Long addressBookId;
+
+ /**
+ * 付款方式,以整数形式表示用户选择的用于支付该订单的具体途径,例如可以约定特定的整数值对应不同的支付渠道,像1可能表示微信支付,2可能表示支付宝支付等等,
+ * 系统会根据这个字段的值来对接相应的支付平台进行支付处理,确保订单金额能够正确收取,同时也便于后续进行支付记录统计分析以及与支付平台对账等业务操作。
+ */
+ private int payMethod;
+
+ /**
+ * 备注,是用户在下单过程中可以填写的一些额外说明信息,比如对商品的特殊要求(如餐饮订单中菜品的口味偏好、特殊包装需求等)、对配送时间的特殊期望(如果配送状态选择了具体时间但还想进一步备注说明等情况)等内容,
+ * 商家和配送人员可以根据这些备注信息来尽量满足用户的个性化需求,提升用户的购物体验,同时也有助于更全面地了解订单的具体情况,方便后续对订单的处理。
+ */
+ private String remark;
+
+ /**
+ * 预计送达时间,使用LocalDateTime类型来记录用户期望商品送达的时间点,通过@JsonFormat注解进行格式化配置,将其格式指定为"yyyy-MM-dd HH:mm:ss",
+ * 这样在数据传输和展示过程中能够以统一、清晰的时间格式呈现,方便前后端数据交互以及用户查看,在配送安排等业务场景中,这个时间信息可作为重要参考,帮助商家合理规划配送任务,确保尽量满足用户的期望送达时间要求。
+ */
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
+ private LocalDateTime estimatedDeliveryTime;
+
+ /**
+ * 配送状态,以整数形式表示商品配送的时间安排情况,其中:
+ * 1表示立即送出,意味着用户希望订单完成支付后,商家能尽快安排商品进行配送,无需再指定具体的配送时间,按照正常的业务流程尽快发货;
+ * 0表示选择具体时间,即用户明确指定了希望商品在某个特定时间进行配送,商家需要根据用户的要求来安排相应的配送计划,这个字段便于系统区分不同的配送时间安排方式并进行相应的配送业务处理。
+ */
+ private Integer deliveryStatus;
+
+ /**
+ * 餐具数量,用于记录用户在下单时所选择的餐具数量,比如在餐饮外卖等业务场景下,用户可以根据实际用餐人数等因素选择需要的餐具份数,
+ * 该数量信息对于商家准备餐具、配送餐具以及可能涉及的餐具收费等业务操作提供了明确的数据依据,确保满足用户需求同时合理安排相关资源。
+ */
+ private Integer tablewareNumber;
+
+ /**
+ * 餐具数量状态,以整数形式表示餐具数量的选择方式,其中:
+ * 1表示按餐量提供,意味着餐具数量是根据订单中商品的餐量情况自动匹配提供的,无需用户手动选择具体数量,一般按照一定的业务规则来确定;
+ * 0表示选择具体数量,即用户自己明确指定了需要的餐具具体份数,系统按照用户所选数量进行相应安排,这个字段便于系统区分不同的餐具数量确定方式并进行相应处理。
+ */
+ private Integer tablewareStatus;
+
+ /**
+ * 打包费,以整数形式表示该订单的打包费用,在一些商品需要特殊包装或者商家对打包服务单独收费的业务场景下,这个字段记录了相应的打包费用金额,
+ * 它是订单总金额的一部分,对于财务统计、费用明细展示以及与用户确认最终费用等业务操作有着重要作用,确保费用计算准确透明。
+ */
+ private Integer packAmount;
+
+ /**
+ * 总金额,使用BigDecimal类型来精确表示订单的全部费用金额,因为在涉及金额计算和记录时,需要保证精度和准确性,避免浮点数运算带来的精度丢失问题,
+ * 这个总金额包含了商品价格、打包费等各项费用的总和,是用户最终需要支付的金额,对于财务核算、订单金额统计以及与用户确认支付金额等业务操作是关键的数据依据。
+ */
+ private BigDecimal amount;
+}
\ No newline at end of file
diff --git a/sky/sky-pojo/src/main/java/com/sky/dto/ShoppingCartDTO.java b/sky/sky-pojo/src/main/java/com/sky/dto/ShoppingCartDTO.java
new file mode 100644
index 0000000..97f0165
--- /dev/null
+++ b/sky/sky-pojo/src/main/java/com/sky/dto/ShoppingCartDTO.java
@@ -0,0 +1,33 @@
+package com.sky.dto;
+
+import lombok.Data;
+import java.io.Serializable;
+
+/**
+ * ShoppingCartDTO类,作为数据传输对象(Data Transfer Object),主要用于在系统不同模块或层次(比如业务逻辑层与展示层之间)传递购物车相关的数据信息,
+ * 其目的在于简化购物车相关数据的交互流程,将购物车中关键的商品相关数据整合起来进行传递,遵循关注点分离原则,避免传递过多与购物车业务逻辑无关的内容,方便各模块协同完成购物车相关的业务操作,例如添加商品到购物车、查看购物车商品等。
+ * 该类实现了Serializable接口,这意味着它能够被序列化,可应用于网络传输、持久化存储等多种场景,保障了购物车数据在不同环境下可以完整且正确地流转和保存,满足系统在购物车功能实现过程中对数据交互的需求。
+ * 通过使用Lombok的@Data注解,自动为类生成了常用的方法,像Getter、Setter、toString、equals和hashCode等方法,减少了手动编写这些样板代码的工作量,使代码更加简洁明了,易于维护和扩展。
+ */
+@Data
+public class ShoppingCartDTO implements Serializable {
+
+ /**
+ * 菜品id,用于唯一标识购物车中的某一道菜品,通过这个id可以关联到菜品的详细信息(如菜品名称、价格、图片、口味等),
+ * 在购物车业务场景中,便于准确知晓购物车中具体包含了哪些菜品个体,以及后续进行与该菜品相关的操作,比如修改菜品数量、删除该菜品等,是购物车中菜品管理的重要标识之一。
+ */
+ private Long dishId;
+
+ /**
+ * 套餐id,用于标识购物车中添加的套餐,凭借这个id可以获取到套餐的详细信息(如套餐名称、包含的菜品、价格等),
+ * 当用户将套餐加入购物车后,通过该id能清晰确定是哪个套餐在购物车中,方便进行套餐相关的业务操作,例如查看套餐详情、调整套餐数量等,是对购物车中套餐进行管理的关键标识。
+ */
+ private Long setmealId;
+
+ /**
+ * 菜品口味,用于记录购物车中菜品的口味信息,例如对于一道有多种口味可选的菜品(如麻辣、糖醋等口味),这个字段就会记录用户选择的具体口味,
+ * 使得系统能够准确了解用户对于菜品口味的偏好,在购物车展示、下单处理等业务环节中,根据这个口味信息来准确准备相应口味的菜品,提升用户购物体验。
+ */
+ private String dishFlavor;
+
+}
\ No newline at end of file
diff --git a/sky/sky-pojo/src/main/java/com/sky/entity/Dish.java b/sky/sky-pojo/src/main/java/com/sky/entity/Dish.java
new file mode 100644
index 0000000..3dceb08
--- /dev/null
+++ b/sky/sky-pojo/src/main/java/com/sky/entity/Dish.java
@@ -0,0 +1,93 @@
+package com.sky.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * Dish类,用于表示菜品相关的实体信息,是餐饮系统等相关项目中对菜品数据进行存储、查询、更新等操作的核心数据载体,
+ * 涵盖了菜品从基本属性(如名称、价格、分类等)到状态信息以及创建、更新相关的时间与用户记录等多方面的关键内容,方便在菜品管理、售卖等诸多业务场景下使用。
+ * 该类实现了Serializable接口,这使得它可以被序列化,从而能够在诸如网络传输(例如不同门店间同步菜品信息)、持久化存储(保存到数据库中供后续查询和操作)等场景下正常流转,保障数据的完整性和可复用性。
+ * 通过使用Lombok提供的多个注解,有效简化了代码编写过程中对于构造函数、Getter/Setter方法以及对象构建方式等部分的代码量。
+ * @Data注解自动生成常用的Getter、Setter、toString、equals和hashCode等方法;
+ * @Builder注解便于使用建造者模式来创建该类的对象,使对象创建过程更加清晰灵活;
+ * @NoArgsConstructor和@AllArgsConstructor注解分别生成无参构造函数和包含所有参数的构造函数,以满足不同业务场景下创建对象的需求。
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class Dish implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 菜品的唯一标识符,通常对应数据库中菜品记录的主键,凭借这个id能够在整个系统中精准地定位到具体的某一道菜品,
+ * 便于进行菜品信息的各种操作,如查询、修改、删除等,是菜品实体在系统内的重要标识依据,对于菜品管理等业务场景起着关键作用。
+ */
+ private Long id;
+
+ /**
+ * 菜品名称,是展示给用户看到的、用于区分不同菜品的重要文本信息,用户可以根据菜品名称直观地了解菜品的大致内容或特点,
+ * 同时也是系统内部进行菜品管理、查询等操作时的重要依据之一,例如在菜单展示、点菜操作等场景中,菜品名称都是必不可少的关键元素,方便用户进行选择以及系统进行菜品相关的管理操作。
+ */
+ private String name;
+
+ /**
+ * 菜品分类id,用于指明该菜品所属的分类,不同的分类可能有不同的业务规则、展示方式或者营销策略等,
+ * 通过这个分类id可以关联到对应的分类信息,比如在菜单展示中按照分类来分组显示菜品,方便用户查找和选择,有助于提升用户体验以及系统的菜品管理效率,是菜品组织与展示的重要关联属性。
+ */
+ private Long categoryId;
+
+ /**
+ * 菜品价格,使用BigDecimal类型来精确表示价格数值,因为在涉及金额计算时,需要保证精度和准确性,避免浮点数运算带来的精度丢失问题,
+ * 该价格是用户购买菜品需要支付的金额,也是进行财务统计、价格比较等业务操作的关键数据,对于餐饮系统等涉及菜品售卖的业务场景十分重要,明确了菜品的价值衡量标准。
+ */
+ private BigDecimal price;
+
+ /**
+ * 图片,用于展示菜品的外观、样式等可视化信息,通过图片可以让用户更直观地感受菜品的样子,增强用户购买的欲望,
+ * 在前端界面展示中,通常会将这个图片显示在菜品相关的位置,提升菜品展示效果以及用户的点菜意愿,是优化用户体验的重要因素之一,从视觉角度辅助菜品的推广与销售。
+ */
+ private String image;
+
+ /**
+ * 描述信息,用于对菜品进行更详细的介绍,比如菜品的制作工艺、口味特点、食材组成等内容,
+ * 帮助用户更好地了解菜品详情,以便做出是否购买的决策,同时也便于后台管理人员对菜品进行准确的描述和管理,在菜品展示和管理环节都有着重要意义,丰富了用户对菜品的认知。
+ */
+ private String description;
+
+ /**
+ * 状态字段,以整数形式表示菜品的当前销售状态,其中“0”表示停售,意味着该菜品暂时不可供用户购买,可能是由于原材料短缺、菜品调整等原因;
+ * “1”表示起售,即菜品处于正常可售卖、可供用户选择的状态,系统可以根据这个状态来决定是否展示该菜品以及是否允许进行相关的下单操作等,方便对菜品的售卖情况进行管控,保障菜品销售管理的有序性。
+ */
+ private Integer status;
+
+ /**
+ * 菜品的创建时间,使用LocalDateTime类型来精确记录菜品信息首次被录入系统的时间点,
+ * 这个时间信息有助于进行数据溯源、统计不同时间段的菜品新增情况等业务分析,例如可以查看每月新推出了哪些菜品等,为菜品管理的历史记录提供了时间维度的参考依据。
+ */
+ private LocalDateTime createTime;
+
+ /**
+ * 菜品的更新时间,同样使用LocalDateTime类型来记录菜品信息最近一次被修改的时间,
+ * 可以用于跟踪菜品信息的变动情况,了解哪些菜品信息在何时进行了更新,对于数据审计、历史记录查询等方面有一定帮助,便于掌握菜品数据的变化轨迹。
+ */
+ private LocalDateTime updateTime;
+
+ /**
+ * 创建该菜品信息的用户的唯一标识符,通常对应着操作创建菜品记录的那个用户(可能是系统管理员或者有相应权限的厨师、工作人员等)的id,
+ * 通过这个关联可以追溯菜品信息最初是由谁录入系统的,便于进行操作记录和责任划分等管理工作,明确菜品创建的责任主体。
+ */
+ private Long createUser;
+
+ /**
+ * 更新该菜品信息的用户的唯一标识符,对应着最后一次对菜品信息进行修改操作的用户的id,
+ * 有助于了解菜品信息的变动是由哪位用户执行的,在需要核对信息修改情况以及权限管理等方面能发挥作用,辅助监控菜品信息的更新情况及对应的操作人。
+ */
+ private Long updateUser;
+}
\ No newline at end of file
diff --git a/sky/sky-pojo/src/main/java/com/sky/entity/Orders.java b/sky/sky-pojo/src/main/java/com/sky/entity/Orders.java
new file mode 100644
index 0000000..897e6ce
--- /dev/null
+++ b/sky/sky-pojo/src/main/java/com/sky/entity/Orders.java
@@ -0,0 +1,205 @@
+package com.sky.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * Orders类,用于表示订单相关的实体信息,是整个系统中对订单数据进行存储、查询、更新以及业务流程处理等操作的核心数据载体,
+ * 涵盖了订单从基本属性(如订单号、下单用户、金额等)到不同阶段的状态信息(订单状态、支付状态等)以及与配送、取消、备注等相关的多方面关键内容,
+ * 在订单管理、交易流程跟踪、配送安排以及售后处理等诸多业务场景下起着至关重要的作用。
+ * 该类实现了Serializable接口,这使得它可以被序列化,从而能够在诸如网络传输(例如在客户端与服务器之间传递订单数据、不同系统间同步订单信息等)、
+ * 持久化存储(保存到数据库中以便后续查询、统计和操作)等场景下正常流转,保障数据的完整性和可复用性。
+ * 通过使用Lombok提供的多个注解,有效简化了代码编写过程中对于构造函数、Getter/Setter方法以及对象构建方式等部分的代码量。
+ * @Data注解自动生成常用的Getter、Setter、toString、equals和hashCode等方法;
+ * @Builder注解便于使用建造者模式来创建该类的对象,使对象创建过程更加清晰灵活;
+ * @NoArgsConstructor和@AllArgsConstructor注解分别生成无参构造函数和包含所有参数的构造函数,以满足不同业务场景下创建对象的需求。
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class Orders implements Serializable {
+
+ /**
+ * 订单状态相关的常量定义,用于清晰表示订单所处的不同业务阶段,方便在代码中进行状态判断和业务逻辑处理,使代码的可读性更强。
+ * 以下是各常量对应的具体含义:
+ * 1待付款,表示用户已经提交了订单,但尚未完成支付操作,此时订单处于等待用户付款的状态,系统可能会根据业务规则设定一定的付款期限等相关处理;
+ * 2待接单,意味着订单已生成但商家还未确认接收该订单,通常用于外卖、服务预订等业务场景中商家处理订单的前置阶段;
+ * 3已接单,代表商家已经确认接收了订单,会开始准备商品或安排相应服务等后续操作,标志着订单进入商家处理流程;
+ * 4派送中,说明商品或服务已经准备好,正在送往用户指定地址的过程中,用户可以通过此状态跟踪配送进度等;
+ * 5已完成,即订单的整个交易流程顺利结束,用户已收到商品或服务且无其他后续问题,商家可以进行相应的订单完结处理,如统计销售数据等;
+ * 6已取消,代表订单由于某些原因(如用户主动取消、不符合下单条件等)被终止,系统需要根据具体的取消原因进行相应的后续处理,比如退款、释放库存等操作;
+ * 7退款,用于表示订单已经进行了退款操作,可能是因为用户申请退款且符合退款条件,后续涉及财务退款流程以及订单状态更新等相关处理。
+ */
+ public static final Integer PENDING_PAYMENT = 1;
+ public static final Integer TO_BE_CONFIRMED = 2;
+ public static final Integer CONFIRMED = 3;
+ public static final Integer DELIVERY_IN_PROGRESS = 4;
+ public static final Integer COMPLETED = 5;
+ public static final Integer CANCELLED = 6;
+
+ /**
+ * 支付状态相关的常量定义,用于明确订单在支付方面所处的不同情况,便于在业务逻辑中针对不同支付状态进行相应处理,增强代码的可维护性和可读性。
+ * 具体含义如下:
+ * 0未支付,说明订单虽然已经生成,但用户还未完成支付动作,系统需要提示用户付款或者根据业务规则进行相应的超时等处理;
+ * 1已支付,代表用户已经成功完成了订单的支付操作,此时订单可以进入后续的商家处理、配送等流程;
+ * 2退款,意味着订单发生了退款情况,可能是用户申请退款且经过审核通过等原因,后续需要涉及财务相关的退款处理以及更新订单相关状态等操作。
+ */
+ public static final Integer UN_PAID = 0;
+ public static final Integer PAID = 1;
+ public static final Integer REFUND = 2;
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 订单的唯一标识符,通常对应数据库中订单记录的主键,凭借这个id能够在整个系统中精准地定位到具体的某一笔订单,
+ * 便于进行订单信息的各种操作,如查询、修改、删除以及与其他业务逻辑相关的操作,是订单实体在系统内的重要标识依据,对于订单管理、订单状态跟踪等业务场景起着关键作用。
+ */
+ private Long id;
+
+ /**
+ * 订单号,是用于唯一标识每一笔订单的字符串,在整个系统中通过这个订单号可以快速且准确地找到对应的订单,
+ * 它在与外部系统交互(如支付平台回调、物流配送对接等)、用户查看订单详情以及内部业务逻辑处理(如订单查询、关联订单相关业务操作等)等场景下,都是非常重要的标识信息,方便各环节准确识别具体的订单。
+ */
+ private String number;
+
+ /**
+ * 订单状态,以整数形式表示订单当前所处的不同阶段,取值对应上面定义的订单状态常量(PENDING_PAYMENT、TO_BE_CONFIRMED等),
+ * 系统根据这个状态值来决定接下来要执行的业务流程,例如对于待付款状态的订单,会提醒用户付款;已接单状态则通知商家准备商品等,方便对订单的整个生命周期进行管理和控制。
+ */
+ private Integer status;
+
+ /**
+ * 下单用户id,用于关联到具体下单的用户,通过这个id可以查询出该用户的相关信息(如用户名、联系方式等),也便于进行用户相关的订单统计分析(如查看某个用户的历史订单情况等),
+ * 在订单处理、用户订单管理等业务场景中,是建立订单与用户之间联系的重要标识,确保订单数据与对应的用户信息准确对应。
+ */
+ private Long userId;
+
+ /**
+ * 地址id,用于关联到用户的收货地址信息,通过这个id可以获取到详细的收货地址(如省市区、详细街道地址、收货人等信息),
+ * 在订单派送、地址管理以及物流配送等业务场景中,是确定商品最终送达位置的关键标识,确保订单能够准确无误地送到用户指定的地点。
+ */
+ private Long addressBookId;
+
+ /**
+ * 下单时间,使用LocalDateTime类型精确记录订单创建的时间点,这个时间信息对于统计订单的下单时间分布、分析业务高峰期、查看订单时效性等业务分析操作非常有帮助,
+ * 同时也可以作为订单处理流程中的时间参考依据,比如判断是否超过了付款期限等情况,有助于系统进行相关的时间敏感型业务处理。
+ */
+ private LocalDateTime orderTime;
+
+ /**
+ * 结账时间,同样使用LocalDateTime类型来记录订单完成支付结算的时间,对于财务统计(如统计每日、每月的收款情况等)、订单处理流程跟踪(确定付款环节的具体时间)等业务场景有着重要作用,
+ * 它与下单时间等其他时间字段结合,可以清晰地展现订单从创建到完成支付这一过程的时间跨度以及具体时间节点。
+ */
+ private LocalDateTime checkoutTime;
+
+ /**
+ * 支付方式,以整数形式表示用户选择的用于支付订单的具体途径,其中:
+ * 1表示微信支付,意味着用户通过微信平台提供的支付功能完成了订单付款;
+ * 2表示支付宝支付,即用户使用支付宝的支付服务来支付订单金额,这个字段方便系统对接相应的支付平台进行支付处理以及后续的支付记录统计分析等工作。
+ */
+ private Integer payMethod;
+
+ /**
+ * 支付状态,以整数形式表示订单在支付方面的当前情况,取值对应上面定义的支付状态常量(UN_PAID、PAID、REFUND),
+ * 系统根据这个状态来决定是否需要进行支付提醒、是否启动退款流程等与支付相关的业务操作,便于对订单支付情况进行准确把控。
+ */
+ private Integer payStatus;
+
+ /**
+ * 实收金额,使用BigDecimal类型来精确表示订单实际收到的金额数值,因为在涉及金额计算和记录时,需要保证精度和准确性,避免浮点数运算带来的精度丢失问题,
+ * 该金额是用户最终为订单支付的实际费用,对于财务核算、订单金额统计、与支付平台对账等业务操作是关键的数据依据。
+ */
+ private BigDecimal amount;
+
+ /**
+ * 备注,是用户在下单时可以填写的一些额外说明信息,比如对商品的特殊要求(在外卖餐饮订单中)、配送时间的特殊期望、对商品的特殊备注等内容,
+ * 商家和配送人员可以根据这些备注信息来尽量满足用户的个性化需求,同时在订单处理和查看过程中,备注信息也有助于更全面地了解订单的具体情况,提升用户体验。
+ */
+ private String remark;
+
+ /**
+ * 用户名,用于展示下单用户的名称信息,方便在订单相关的展示界面中让接收方(如商家、配送人员等)快速知晓是哪位用户下的订单,
+ * 同时也便于用户在查看自己的订单时,能够直观地确认订单归属,增强订单信息的可读性和辨识度。
+ */
+ private String userName;
+
+ /**
+ * 手机号,记录下单用户的联系方式,在订单处理过程中,如果遇到问题(如配送地址不清楚、商品有疑问等情况),相关人员(如配送员、客服等)可以通过这个手机号与用户取得联系,
+ * 它是保障订单顺利完成以及进行用户沟通的重要信息,对于订单的配送、售后服务等环节起着关键作用。
+ */
+ private String phone;
+
+ /**
+ * 地址,用于展示用户的详细收货地址信息,将收货地址以字符串形式呈现出来,方便相关人员(如配送员等)直接查看并准确找到送货地点,
+ * 与地址id关联获取的地址信息相对应,是在订单展示等场景下更直观呈现地址内容的一种方式,确保订单能够准确送达目的地。
+ */
+ private String address;
+
+ /**
+ * 收货人,明确记录了接收商品的人员姓名,在配送环节,配送员可以通过这个收货人姓名来确认将商品交付给正确的对象,
+ * 是收货地址信息中很重要的一部分,对于保证商品准确送达以及避免配送错误等情况有着重要意义,提升订单配送的准确性。
+ */
+ private String consignee;
+
+ /**
+ * 订单取消原因,用于记录订单被取消的具体缘由,比如是用户主动取消(可能因为改变主意、不需要商品了等原因),还是因为系统原因(如库存不足无法发货、不符合下单规则等)导致的取消,
+ * 这个字段有助于后续进行数据分析、处理退款事宜以及向用户反馈取消原因等业务操作,对于订单取消流程的管理和用户沟通非常重要。
+ */
+ private String cancelReason;
+
+ /**
+ * 订单拒绝原因,在一些业务场景下(例如商家拒绝接单等情况),用于记录订单被拒绝的具体原因,可能是因为商家无法提供相应服务、商品缺货等原因,
+ * 通过记录这个原因,便于系统进行相应的后续处理,如通知用户、调整订单状态以及进行相关业务数据统计分析等操作。
+ */
+ private String rejectionReason;
+
+ /**
+ * 订单取消时间,使用LocalDateTime类型精确记录订单被取消的时间点,对于统计订单取消的时间分布、分析取消订单的规律以及涉及退款等业务操作的时间参考等方面有着重要作用,
+ * 它与下单时间、结账时间等时间字段共同构成了订单时间线的一部分,有助于全面了解订单的整个生命周期情况。
+ */
+ private LocalDateTime cancelTime;
+
+ /**
+ * 预计送达时间,使用LocalDateTime类型来记录预估的商品送达用户手中的时间点,在配送安排等业务场景中,这个时间信息可作为重要参考,
+ * 商家可以根据这个时间来合理规划配送任务,配送员也可以据此安排自己的送货顺序等,同时也方便用户知晓大概何时能收到商品,提升用户体验。
+ */
+ private LocalDateTime estimatedDeliveryTime;
+
+ /**
+ * 配送状态,以整数形式表示商品配送的时间安排情况,其中:
+ * 1表示立即送出,意味着订单完成支付后,商家会尽快安排商品进行配送,无需用户指定具体的配送时间,按照正常的业务流程尽快发货;
+ * 0表示选择具体时间,即用户在下单时指定了希望商品在某个特定时间进行配送,商家需要根据用户的要求来安排相应的配送计划,这个字段便于系统区分不同的配送时间安排方式并进行相应的配送业务处理。
+ */
+ private Integer deliveryStatus;
+
+ /**
+ * 送达时间,使用LocalDateTime类型精确记录商品实际送达用户手中的时间点,对于统计配送时效、分析配送效率以及进行订单完成情况确认等业务操作有着重要作用,
+ * 它与预计送达时间对比,可以评估配送是否按时完成等情况,是衡量配送服务质量的重要依据之一。
+ */
+ private LocalDateTime deliveryTime;
+
+ /**
+ * 打包费,以整数形式表示该订单的打包费用,在一些商品需要特殊包装或者商家对打包服务单独收费的业务场景下,这个字段记录了相应的打包费用金额,
+ * 它是订单总金额的一部分,对于财务统计、费用明细展示以及与用户确认最终费用等业务操作有着重要作用,确保费用计算准确透明。
+ */
+ private int packAmount;
+
+ /**
+ * 餐具数量,用于记录用户在下单时所选择的餐具数量,比如在餐饮外卖等业务场景下,用户可以根据实际用餐人数等因素选择需要的餐具份数,
+ * 该数量信息对于商家准备餐具、配送餐具以及可能涉及的餐具收费等业务操作提供了明确的数据依据,确保满足用户需求同时合理安排相关资源。
+ */
+ private int tablewareNumber;
+
+ /**
+ * 餐具数量状态,以整数形式表示餐具数量的选择方式,其中:
+ * 1表示按餐量提供,意味着餐具数量是根据订单中商品的餐量情况自动匹配提供的,无需用户手动选择具体数量,一般按照一定的业务规则来确定;
+ * 0表示选择具体数量,即用户自己明确指定了需要的餐具具体份数,系统按照用户所选数量进行相应安排,这个字段便于系统区分不同的餐具数量确定方式并进行相应处理。
+ */
+ private Integer tablewareStatus;
+}
\ No newline at end of file
diff --git a/sky/sky-pojo/src/main/java/com/sky/entity/User.java b/sky/sky-pojo/src/main/java/com/sky/entity/User.java
new file mode 100644
index 0000000..aef8c9b
--- /dev/null
+++ b/sky/sky-pojo/src/main/java/com/sky/entity/User.java
@@ -0,0 +1,72 @@
+package com.sky.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * User类,用于表示用户相关的实体信息,是系统中对用户数据进行存储、查询、更新等操作的核心数据载体,
+ * 涵盖了从用户在平台的唯一标识(如微信用户的openid)到基本个人信息(姓名、手机号、性别等)以及注册相关时间记录等多方面的关键内容,
+ * 在用户管理、身份验证、个性化服务等诸多业务场景下起着重要作用。
+ * 该类实现了Serializable接口,这使得它可以被序列化,从而能够在诸如网络传输(例如不同服务器间同步用户信息、与第三方平台交互用户数据等)、
+ * 持久化存储(保存到数据库中供后续查询和操作)等场景下正常流转,保障数据的完整性和可复用性。
+ * 通过使用Lombok提供的多个注解,有效简化了代码编写过程中对于构造函数、Getter/Setter方法以及对象构建方式等部分的代码量。
+ * @Data注解自动生成常用的Getter、Setter、toString、equals和hashCode等方法;
+ * @Builder注解便于使用建造者模式来创建该类的对象,使对象创建过程更加清晰灵活;
+ * @NoArgsConstructor和@AllArgsConstructor注解分别生成无参构造函数和包含所有参数的构造函数,以满足不同业务场景下创建对象的需求。
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 用户的唯一标识符,通常对应数据库中用户记录的主键,凭借这个id能够在整个系统中精准地定位到具体的某一位用户,
+ * 便于进行用户信息的各种操作,如查询、修改、删除等,是用户实体在系统内的重要标识依据,对于用户管理等业务场景起着关键作用。
+ */
+ private Long id;
+
+ /**
+ * 微信用户唯一标识,在基于微信生态的应用或者与微信进行关联登录等场景下,这个openid是用于区分不同微信用户的重要标识,
+ * 系统通过该openid来识别用户身份,与微信平台进行交互(如获取用户信息、验证登录状态等),是实现微信相关用户功能的关键属性。
+ */
+ private String openid;
+
+ /**
+ * 姓名,用于展示用户的真实称呼,方便在系统内进行用户展示、交互以及个性化服务等场景中使用,例如在用户信息页面展示、客服沟通等环节,姓名是重要的识别信息。
+ */
+ private String name;
+
+ /**
+ * 手机号,作为联系用户的重要方式,可用于发送短信通知(如验证码、订单提醒等)、找回密码等业务操作,同时也是用户在平台进行账号安全验证等方面的重要依据之一。
+ */
+ private String phone;
+
+ /**
+ * 性别,以字符串形式表示,其中“0”代表女性,“1”代表男性,虽然性别信息在部分业务场景中并非核心要素,但在一些个性化服务场景(如根据性别推荐不同内容)、
+ * 统计分析(如用户性别比例统计)等情况下会发挥作用,有助于更细致地了解用户群体特征。
+ */
+ private String sex;
+
+ /**
+ * 身份证号,作为重要的身份识别信息,常用于需要严格身份认证的业务流程中,例如在涉及实名认证、办理重要业务(如涉及资金交易、权益保障等)时,需要核对身份证号以确保用户身份的准确性。
+ */
+ private String idNumber;
+
+ /**
+ * 头像,用于展示用户的个人形象,通常以图片链接或者图片数据的形式存储,在用户信息展示、社交互动等场景中,头像可以让用户形象更加直观,提升用户体验和辨识度。
+ */
+ private String avatar;
+
+ /**
+ * 注册时间,使用LocalDateTime类型来精确记录用户首次在系统中注册账号的时间点,
+ * 这个时间信息有助于进行数据溯源、统计不同时间段的用户新增情况等业务分析,例如可以查看每月新注册了多少用户等,为用户增长相关的数据分析提供了时间维度的参考依据。
+ */
+ private LocalDateTime createTime;
+}
\ No newline at end of file
diff --git a/sky/sky-pojo/src/main/java/com/sky/vo/DishVO.java b/sky/sky-pojo/src/main/java/com/sky/vo/DishVO.java
new file mode 100644
index 0000000..eb46ccb
--- /dev/null
+++ b/sky/sky-pojo/src/main/java/com/sky/vo/DishVO.java
@@ -0,0 +1,92 @@
+package com.sky.vo;
+
+import com.sky.entity.DishFlavor;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * DishVO类,属于值对象(Value Object),主要用于在系统不同模块或业务场景之间传递与菜品相关的特定数据信息,
+ * 它整合了菜品的诸多关键属性,比如基本信息(名称、价格、分类等)、状态信息、关联的口味信息等,方便进行数据展示、交互以及在不同层次之间传递使用,
+ * 有助于简化业务逻辑中对菜品相关数据的处理流程,遵循了关注点分离原则,聚焦于传递需要展示或使用的菜品关键信息,同时避免传递过多不必要的业务细节。
+ * 该类实现了Serializable接口,这使得它可以被序列化,能够应用在诸如网络传输(比如从服务端将菜品相关数据发送到前端展示)、持久化存储(虽相对较少但在特定缓存等场景可能涉及)等场景下,确保数据的完整性以及能够顺利地流转和使用。
+ * 通过使用Lombok提供的多个注解,极大地简化了代码编写时关于构造函数、Getter/Setter方法以及对象构建方式等方面的代码量。
+ * @Data注解自动生成常用的Getter、Setter、toString、equals和hashCode等方法,减少了手动编写这些重复代码的工作量;
+ * @Builder注解方便运用建造者模式来创建该类的对象,让对象的创建过程更加清晰、灵活,适合在需要灵活配置对象属性值的场景下使用;
+ * @NoArgsConstructor和@AllArgsConstructor注解分别生成无参构造函数和包含所有参数的构造函数,以满足不同业务场景下创建对象的需求,例如在某些默认初始化或者根据完整属性值创建对象的情况中可以按需选用。
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class DishVO implements Serializable {
+
+ /**
+ * 菜品的唯一标识符,通常对应数据库中菜品记录的主键值,通过这个id可以在整个系统中精准地定位到具体的某一道菜品,
+ * 便于进行菜品的查询、修改、删除以及与其他业务逻辑相关的操作,是菜品在系统内的重要标识,对于菜品管理、展示等业务场景起着关键作用。
+ */
+ private Long id;
+
+ /**
+ * 菜品名称,是展示给用户看到的、用于区分不同菜品的重要文本信息,用户可以根据菜品名称直观地了解菜品的大致内容或特点,
+ * 同时也是系统内部进行菜品管理、查询等操作时的重要依据之一,例如在菜单展示、点菜操作等场景中,菜品名称都是必不可少的关键元素,方便用户进行选择以及系统进行菜品相关的管理操作。
+ */
+ private String name;
+
+ /**
+ * 菜品分类id,用于指明该菜品所属的分类,不同的分类可能有不同的业务规则、展示方式或者营销策略等,
+ * 通过这个分类id可以关联到对应的分类信息,比如在菜单展示中按照分类来分组显示菜品,方便用户查找和选择,有助于提升用户体验以及系统的菜品管理效率,是菜品组织与展示的重要关联属性。
+ */
+ private Long categoryId;
+
+ /**
+ * 菜品价格,使用BigDecimal类型来精确表示价格数值,因为在涉及金额计算时,需要保证精度和准确性,避免浮点数运算带来的精度丢失问题,
+ * 该价格是用户购买菜品需要支付的金额,也是进行财务统计、价格比较等业务操作的关键数据,对于餐饮系统等涉及菜品售卖的业务场景十分重要,明确了菜品的价值衡量标准。
+ */
+ private BigDecimal price;
+
+ /**
+ * 图片,用于展示菜品的外观、样式等可视化信息,通过图片可以让用户更直观地感受菜品的样子,增强用户购买的欲望,
+ * 在前端界面展示中,通常会将这个图片显示在菜品相关的位置,提升菜品展示效果以及用户的点菜意愿,是优化用户体验的重要因素之一,从视觉角度辅助菜品的推广与销售。
+ */
+ private String image;
+
+ /**
+ * 描述信息,用于对菜品进行更详细的介绍,比如菜品的制作工艺、口味特点、食材组成等内容,
+ * 帮助用户更好地了解菜品详情,以便做出是否购买的决策,同时也便于后台管理人员对菜品进行准确的描述和管理,在菜品展示和管理环节都有着重要意义,丰富了用户对菜品的认知。
+ */
+ private String description;
+
+ /**
+ * 状态字段,以整数形式表示菜品的当前销售状态,其中“0”表示停售,意味着该菜品暂时不可供用户购买,可能是由于原材料短缺、菜品调整等原因;
+ * “1”表示起售,即菜品处于正常可售卖、可供用户选择的状态,系统可以根据这个状态来决定是否展示该菜品以及是否允许进行相关的下单操作等,方便对菜品的售卖情况进行管控,保障菜品销售管理的有序性。
+ */
+ private Integer status;
+
+ /**
+ * 更新时间,使用LocalDateTime类型来记录菜品信息最近一次被修改的时间,
+ * 可以用于跟踪菜品信息的变动情况,了解哪些菜品信息在何时进行了更新,对于数据审计、历史记录查询等方面有一定帮助,便于掌握菜品数据的变化轨迹,同时也能让用户或管理人员知晓菜品相关信息的时效性。
+ */
+ private LocalDateTime updateTime;
+
+ /**
+ * 分类名称,用于展示菜品所属分类的具体名称,相较于分类id,这个名称更加直观易懂,方便用户在查看菜品信息时快速了解其所属的分类情况,
+ * 在菜单展示、菜品管理等场景中,与分类id配合使用,能进一步提升菜品信息展示的友好性和可读性,让用户对菜品的分类归属有更清晰的认知。
+ */
+ private String categoryName;
+
+ /**
+ * 菜品关联的口味,是一个List集合,用于存放与该菜品相关联的DishFlavor对象,每个DishFlavor对象代表菜品的一种口味以及相关的口味信息(如口味的具体配料、辣度等),
+ * 通过这个集合可以清晰地知道该菜品具体有哪些口味可供选择,便于进行菜品口味的管理、展示以及在业务流程中涉及口味调整等操作,满足用户对于菜品口味多样化的需求,是菜品个性化呈现的重要组成部分。
+ */
+ private List flavors = new ArrayList<>();
+
+ //private Integer copies;
+
+}
\ No newline at end of file
diff --git a/sky/sky-pojo/src/main/java/com/sky/vo/OrderReportVO.java b/sky/sky-pojo/src/main/java/com/sky/vo/OrderReportVO.java
new file mode 100644
index 0000000..4797d74
--- /dev/null
+++ b/sky/sky-pojo/src/main/java/com/sky/vo/OrderReportVO.java
@@ -0,0 +1,59 @@
+package com.sky.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import java.io.Serializable;
+
+/**
+ * OrderReportVO类,属于值对象(Value Object),主要用于在系统不同模块或业务场景之间传递订单相关的统计报告数据信息,
+ * 它将订单统计分析中的关键数据进行整合,方便在数据展示、报表生成以及不同业务层次间传递这些统计结果,遵循关注点分离原则,聚焦于呈现订单统计方面的核心内容,避免传递过多无关的数据,有助于提高数据处理和展示的效率。
+ * 该类实现了Serializable接口,这使得它能够被序列化,可应用于网络传输(比如从后端统计服务将订单统计数据发送到前端页面进行展示)、持久化存储(虽相对少见,但在特定数据缓存、备份订单统计结果等场景下可能涉及)等场景,保障数据的完整性以及能顺利地流转和使用。
+ * 通过使用Lombok提供的多个注解,极大地简化了代码编写时关于构造函数、Getter/Setter方法以及对象构建方式等方面的代码量。
+ * @Data注解自动生成常用的Getter、Setter、toString、equals和hashCode等方法,减少了手动编写这些重复代码的工作量;
+ * @Builder注解方便运用建造者模式来创建该类的对象,让对象的创建过程更加清晰、灵活,适合在需要灵活配置对象属性值的场景下使用;
+ * @NoArgsConstructor和@AllArgsConstructor注解分别生成无参构造函数和包含所有参数的构造函数,以满足不同业务场景下创建对象的需求,例如在默认初始化或者根据完整统计结果来创建对象用于传递数据等情况中可以按需选用。
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderReportVO implements Serializable {
+
+ /**
+ * 日期,以逗号分隔的字符串形式存储,例如:"2022-10-01,2022-10-02,2022-10-03",
+ * 这里记录的是进行订单统计所涉及的多个日期信息,方便后续在展示订单统计数据时,按照对应的日期来呈现相应的数据情况,比如展示不同日期的订单数量变化等,是构建订单时间序列统计的基础元素之一。
+ */
+ private String dateList;
+
+ /**
+ * 每日订单数,同样以逗号分隔的字符串形式呈现,像"260,210,215"这样,
+ * 其中每个数值对应着前面日期List中相应日期的订单数量,用于直观展示在各个统计日期内系统产生的订单总数情况,便于分析订单数量随时间的变化趋势以及进行订单流量方面的数据分析等操作。
+ */
+ private String orderCountList;
+
+ /**
+ * 每日有效订单数,也是以逗号分隔的字符串格式,例如"20,21,10",
+ * 它所包含的每个数值对应着特定日期下的有效订单数量,有效订单通常是指符合一定业务规则、完成了有效交易等的订单,通过这个数据可以进一步分析在不同时间段内有效订单的分布情况,与总订单数对比能看出订单质量等相关情况。
+ */
+ private String validOrderCountList;
+
+ /**
+ * 订单总数,以整数形式表示,是对所统计的一定时间段内所有订单数量的汇总值,
+ * 该数值可以通过对每日订单数(orderCountList中的各个数值累加)等方式获取,它反映了在特定统计范围内系统的总体订单规模,常用于整体业务量的衡量以及与其他统计周期对比等操作。
+ */
+ private Integer totalOrderCount;
+
+ /**
+ * 有效订单数,同样为整数类型,是所统计的整个时间段内符合有效订单定义的订单数量总和,
+ * 这个数值可以基于每日有效订单数(validOrderCountList中的数值累加)得出,有效订单数对于评估业务实际成交情况、分析运营效率等方面有着重要意义,常作为重要指标来衡量业务运营的质量。
+ */
+ private Integer validOrderCount;
+
+ /**
+ * 订单完成率,以双精度浮点数(Double)类型表示,它是通过有效订单数与订单总数之间的比例关系计算得出,计算公式一般为:有效订单数 / 订单总数,
+ * 以百分比的形式(通常会乘以100转化为百分数形式展示,但这里以小数形式存储便于后续计算和数据处理)体现了订单完成的比例情况,用于直观反映业务中订单最终成功完成的概率,是衡量业务流程完整性和运营效果的关键指标之一。
+ */
+ private Double orderCompletionRate;
+}
\ No newline at end of file
diff --git a/sky/sky-pojo/src/main/java/com/sky/vo/SalesTop10ReportVO.java b/sky/sky-pojo/src/main/java/com/sky/vo/SalesTop10ReportVO.java
new file mode 100644
index 0000000..ac7f34d
--- /dev/null
+++ b/sky/sky-pojo/src/main/java/com/sky/vo/SalesTop10ReportVO.java
@@ -0,0 +1,35 @@
+package com.sky.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import java.io.Serializable;
+
+/**
+ * SalesTop10ReportVO类,属于值对象(Value Object),主要用于在系统不同模块或业务场景之间传递商品销量排名前十相关的统计报告数据信息,
+ * 它将销量排名靠前的商品关键数据进行整合,方便在数据展示(比如生成销售排行榜报表展示给管理人员查看)、不同业务层次间传递这些统计结果,遵循关注点分离原则,聚焦于呈现销量排名方面的核心内容,避免传递过多无关的数据,有助于提高数据处理和展示的效率。
+ * 该类实现了Serializable接口,这使得它能够被序列化,可应用于网络传输(比如从后端统计服务将销量统计数据发送到前端页面进行展示)、持久化存储(虽相对少见,但在特定数据缓存、备份销量统计结果等场景下可能涉及)等场景,保障数据的完整性以及能顺利地流转和使用。
+ * 通过使用Lombok提供的多个注解,极大地简化了代码编写时关于构造函数、Getter/Setter方法以及对象构建方式等方面的代码量。
+ * @Data注解自动生成常用的Getter、Setter、toString、equals和hashCode等方法,减少了手动编写这些重复代码的工作量;
+ * @Builder注解方便运用建造者模式来创建该类的对象,让对象的创建过程更加清晰、灵活,适合在需要灵活配置对象属性值的场景下使用;
+ * @NoArgsConstructor和@AllArgsConstructor注解分别生成无参构造函数和包含所有参数的构造函数,以满足不同业务场景下创建对象的需求,例如在默认初始化或者根据完整统计结果来创建对象用于传递数据等情况中可以按需选用。
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SalesTop10ReportVO implements Serializable {
+
+ /**
+ * 商品名称列表,以逗号分隔的字符串形式存储,例如:"鱼香肉丝,宫保鸡丁,水煮鱼",
+ * 这里记录的是销量排名前十的商品的具体名称信息,按照顺序罗列,方便后续在展示销售排行榜等场景下,直观呈现出哪些商品的销量处于前列,让查看者快速知晓热门商品情况,是构成销量排名展示的重要内容之一。
+ */
+ private String nameList;
+
+ /**
+ * 销量列表,同样以逗号分隔的字符串格式,像"260,215,200"这样,
+ * 其中每个数值对应着前面商品名称列表中相应商品的销量数量,通过这种一一对应的方式,可以清晰地展示出每个热门商品具体的销售数量情况,便于进行销量对比以及分析不同商品的销售热度差异等操作。
+ */
+ private String numberList;
+}
\ No newline at end of file
diff --git a/sky/sky-pojo/src/main/java/com/sky/vo/UserLoginVO.java b/sky/sky-pojo/src/main/java/com/sky/vo/UserLoginVO.java
new file mode 100644
index 0000000..a3f519e
--- /dev/null
+++ b/sky/sky-pojo/src/main/java/com/sky/vo/UserLoginVO.java
@@ -0,0 +1,41 @@
+package com.sky.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import java.io.Serializable;
+
+/**
+ * UserLoginVO类,属于值对象(Value Object),主要用于在系统不同模块或业务场景之间传递用户登录相关的数据信息,
+ * 它整合了用户登录成功后关键的身份标识以及认证相关的数据,方便在后续的业务流程中(比如权限验证、接口访问控制等场景)传递用户登录状态,确保系统能基于这些信息识别当前登录用户并提供相应的服务,遵循关注点分离原则,聚焦于传递登录环节的核心数据,避免传递过多无关内容。
+ * 该类实现了Serializable接口,这使得它可以被序列化,能够应用在诸如网络传输(比如从登录验证模块将登录结果数据发送到其他需要知晓用户登录状态的模块)、持久化存储(虽相对较少但在特定缓存等场景可能涉及)等场景下,确保数据的完整性以及能够顺利地流转和使用。
+ * 通过使用Lombok提供的多个注解,极大地简化了代码编写时关于构造函数、Getter/Setter方法以及对象构建方式等方面的代码量。
+ * @Data注解自动生成常用的Getter、Setter、toString、equals和hashCode等方法,减少了手动编写这些重复代码的工作量;
+ * @Builder注解方便运用建造者模式来创建该类的对象,让对象的创建过程更加清晰、灵活,适合在需要灵活配置对象属性值的场景下使用;
+ * @NoArgsConstructor和@AllArgsConstructor注解分别生成无参构造函数和包含所有参数的构造函数,以满足不同业务场景下创建对象的需求,例如在某些默认初始化或者根据完整登录结果创建对象的情况中可以按需选用。
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class UserLoginVO implements Serializable {
+
+ /**
+ * 用户的唯一标识符,通常对应数据库中用户记录的主键,凭借这个id能够在整个系统中精准地定位到具体的某一位用户,
+ * 它在后续的诸多业务操作中(如查询用户详细信息、关联用户相关的订单、权限管理等)起着关键作用,是系统识别用户个体的重要依据,便于基于用户身份开展不同的业务逻辑处理。
+ */
+ private Long id;
+
+ /**
+ * 微信用户唯一标识(若系统与微信相关联登录的话),这个openid是用于区分不同微信用户的重要标识,
+ * 在基于微信生态的应用或者与微信进行关联登录等场景下,系统通过该openid来识别用户身份,与微信平台进行交互(如获取用户信息、验证登录状态等),是实现微信相关用户功能以及保障登录唯一性的关键属性。
+ */
+ private String openid;
+
+ /**
+ * 令牌(token),是用户登录成功后系统颁发给用户的一种认证标识,在后续用户访问受保护的资源(如需要登录后才能查看的页面、调用的接口等)时,
+ * 需要携带这个token来证明自己的身份合法性,系统会对token进行验证,只有验证通过才能允许用户进行相应的操作,它在保障系统安全、实现无状态登录验证等方面起着至关重要的作用。
+ */
+ private String token;
+}
\ No newline at end of file
diff --git a/sky/sky-server/src/main/java/com/sky/config/WebMvcConfiguration.java b/sky/sky-server/src/main/java/com/sky/config/WebMvcConfiguration.java
new file mode 100644
index 0000000..abd4b3a
--- /dev/null
+++ b/sky/sky-server/src/main/java/com/sky/config/WebMvcConfiguration.java
@@ -0,0 +1,132 @@
+package com.sky.config;
+
+import com.sky.interceptor.JwtTokenAdminInterceptor;
+import com.sky.interceptor.JwtTokenUserInterceptor;
+import com.sky.json.JacksonObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import java.util.List;
+
+/**
+ * WebMvcConfiguration类,作为配置类,主要用于注册web层相关的各类组件,
+ * 它继承自WebMvcConfigurationSupport类,借助Spring框架提供的配置机制,来定制化配置Spring MVC相关的功能,例如拦截器、接口文档生成以及消息转换器等,
+ * 以满足项目中对于Web层的特定业务需求,确保Web层的各个功能模块能够协同工作,高效处理HTTP请求和响应等相关操作。
+ */
+@Configuration
+@Slf4j
+public class WebMvcConfiguration extends WebMvcConfigurationSupport {
+
+ /**
+ * 自动注入JwtTokenAdminInterceptor类型的拦截器,这个拦截器通常用于处理与管理员相关的请求拦截逻辑,
+ * 比如验证管理员身份、权限校验等操作,在请求到达对应的管理员接口之前进行前置处理,保障接口的安全性和权限合法性。
+ */
+ @Autowired
+ private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;
+
+ /**
+ * 自动注入JwtTokenUserInterceptor类型的拦截器,该拦截器主要针对普通用户相关的请求进行拦截处理,
+ * 例如验证普通用户的登录状态、权限范围等,确保只有符合条件的用户请求才能顺利访问相应的用户接口,维护用户接口的访问安全和权限控制。
+ */
+ @Autowired
+ private JwtTokenUserInterceptor jwtTokenUserInterceptor;
+
+ /**
+ * 注册自定义拦截器的方法,在这个方法中,将之前注入的拦截器添加到拦截器注册表(InterceptorRegistry)中,
+ * 并配置它们要拦截的路径以及需要排除的路径,从而实现对不同类型请求(管理员请求和普通用户请求)的精准拦截控制,增强系统的安全性和权限管理。
+ *
+ * @param registry 拦截器注册表对象,通过它来注册和配置拦截器与相应的拦截路径规则等信息。
+ */
+ protected void addInterceptors(InterceptorRegistry registry) {
+ log.info("开始注册自定义拦截器...");
+ // 为管理员拦截器添加拦截路径规则,对以"/admin/"开头的所有路径进行拦截,意味着这些路径下的请求在到达具体的处理方法之前,会先经过这个拦截器进行相关处理。
+ // 同时排除"/admin/employee/login"路径,即该登录接口不进行拦截,方便管理员进行登录操作,避免登录请求也被拦截导致无法正常登录的情况。
+ registry.addInterceptor(jwtTokenAdminInterceptor)
+ .addPathPatterns("/admin/**")
+ .excludePathPatterns("/admin/employee/login");
+
+ // 为用户拦截器添加拦截路径规则,对以"/user/"开头的所有路径进行拦截,使得普通用户相关请求先经过此拦截器验证等操作。
+ // 排除"/user/user/login"路径,保障普通用户的登录接口能正常访问不受拦截;同时排除"/user/shop/status"路径,该路径对应的功能可能不需要拦截验证等情况,具体根据业务需求而定。
+ registry.addInterceptor(jwtTokenUserInterceptor)
+ .addPathPatterns("/user/**")
+ .excludePathPatterns("/user/user/login")
+ .excludePathPatterns("/user/shop/status");
+ }
+
+ /**
+ * 通过knife4j(基于Swagger 2进行扩展的工具)生成接口文档的方法,在这里配置接口文档的相关基本信息,
+ * 并指定要扫描生成文档的接口所在的包路径以及哪些路径下的接口需要被包含进来,最终返回一个Docket对象,用于构建和配置接口文档相关的详细信息。
+ *
+ * @return 返回配置好的Docket对象,该对象承载了接口文档的核心配置信息,供knife4j等工具来生成对应的接口文档展示页面。
+ */
+ @Bean
+ public Docket docket() {
+ // 创建ApiInfo对象,用于设置接口文档的标题、版本以及描述等基本信息,这些信息会展示在接口文档页面的头部等位置,方便使用者了解接口文档的整体情况。
+ ApiInfo apiInfo = new ApiInfoBuilder()
+ .title("接口文档")
+ .version("2.0")
+ .description("接口文档")
+ .build();
+
+ // 创建Docket对象,指定文档类型为DocumentationType.SWAGGER_2(即基于Swagger 2规范来生成文档),并设置之前构建好的ApiInfo对象,包含了文档的基本描述信息。
+ // 通过.select()方法开始配置选择哪些接口要生成文档,先指定要扫描的接口所在的基础包路径(这里是"com.sky.controller",意味着该包及其子包下的符合条件的接口会被扫描到),
+ // 然后通过.paths(PathSelectors.any())表示只要是符合前面包路径下的任何路径对应的接口都会被包含进文档中,最后构建出完整的Docket对象。
+ Docket docket = new Docket(DocumentationType.SWAGGER_2)
+ .apiInfo(apiInfo)
+ .select()
+ .apis(RequestHandlerSelectors.basePackage("com.sky.controller"))
+ .paths(PathSelectors.any())
+ .build();
+
+ return docket;
+ }
+
+ /**
+ * 设置静态资源映射的方法,重写了父类的addResourceHandlers方法,用于将特定的请求路径与对应的资源位置进行映射,
+ * 使得在Web应用中能够正确地访问到相应的静态资源,比如HTML页面、JavaScript文件、CSS文件等,保障前端页面能够正常加载和展示所需的资源内容。
+ *
+ * @param registry 资源处理器注册表对象,通过它来注册和配置静态资源的请求路径与实际资源位置的映射关系。
+ */
+ @Override
+ protected void addResourceHandlers(ResourceHandlerRegistry registry) {
+ // 将请求路径"/doc.html"映射到类路径下的"/META-INF/resources/"目录,通常用于将接口文档相关的HTML页面等资源正确映射,以便在访问该路径时能展示对应的接口文档页面。
+ registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
+
+ // 将以"/webjars/**"开头的请求路径映射到类路径下的"/META-INF/resources/webjars/"目录,"webjars"一般用于管理Web项目中的前端依赖库等静态资源,通过这样的映射确保这些资源能被正确访问和使用。
+ registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
+
+ super.addResourceHandlers(registry);
+ }
+
+ /**
+ * 扩展spring MVC框架的消息转化器的方法,在这个方法中,可以向Spring MVC的消息转换器列表中添加自定义的消息转换器,
+ * 或者对已有的消息转换器进行配置调整,以满足项目对于数据序列化、反序列化等方面的特殊需求,例如使用自定义的对象映射器来处理JSON数据与Java对象之间的转换。
+ *
+ * @param converters Spring MVC框架中原有的消息转换器列表,通过修改这个列表来实现消息转换器的扩展或调整操作。
+ */
+ protected void extendMessageConverters(List> converters) {
+ log.info("扩展消息转换器....");
+
+ // 创建一个MappingJackson2HttpMessageConverter类型的消息转换器对象,它是Spring框架中用于处理JSON数据与Java对象转换的常用消息转换器,基于Jackson库实现。
+ MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
+
+ // 需要为这个消息转化器设置一个对象转换器,这里使用自定义的JacksonObjectMapper,它继承自ObjectMapper,并且配置了一些特定的序列化和反序列化规则,
+ // 比如对日期时间类型等的处理方式,通过设置它可以让消息转换器按照项目的特定需求将Java对象准确地序列化为JSON数据,以及将接收到的JSON数据反序列化为Java对象。
+ converter.setObjectMapper(new JacksonObjectMapper());
+
+ // 将自己创建并配置好的消息转换器添加到容器中(即原有的消息转换器列表里),添加到索引为0的位置,确保它在处理消息转换时能优先被使用,按照自定义的规则进行数据转换操作。
+ converters.add(0, converter);
+ }
+}
\ No newline at end of file
diff --git a/sky/sky-server/src/main/java/com/sky/controller/admin/DishController.java b/sky/sky-server/src/main/java/com/sky/controller/admin/DishController.java
new file mode 100644
index 0000000..cd3d6ab
--- /dev/null
+++ b/sky/sky-server/src/main/java/com/sky/controller/admin/DishController.java
@@ -0,0 +1,186 @@
+package com.sky.controller.admin;
+
+import com.github.pagehelper.Page;
+import com.sky.dto.CategoryDTO;
+import com.sky.dto.DishDTO;
+import com.sky.dto.DishPageQueryDTO;
+import com.sky.entity.Dish;
+import com.sky.result.PageResult;
+import com.sky.result.Result;
+import com.sky.service.DishService;
+import com.sky.vo.DishVO;
+import com.sky.vo.SetmealVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.web.bind.annotation.*;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import static jdk.nashorn.internal.runtime.regexp.joni.Config.log;
+
+/**
+ * DishController类,作为Spring MVC框架中的一个控制器类,主要用于处理与菜品相关的各种HTTP请求,
+ * 它提供了一系列的接口方法,来实现菜品的分页查询、新增、删除、修改、状态变更以及根据分类查询等功能,并且与业务逻辑层(通过DishService)进行交互,同时还涉及缓存相关的操作(使用RedisTemplate),
+ * 旨在为管理员提供便捷的菜品管理相关的接口服务,方便对菜品信息进行全面的操作和管理,确保菜品数据在系统中的准确性和有效性。
+ */
+@RestController()
+@RequestMapping("/admin/dish")
+@Slf4j
+@Api("菜品相关接口")
+public class DishController {
+
+ /**
+ * 自动注入DishService,通过依赖注入的方式获取业务逻辑层的服务对象,
+ * DishService中封装了与菜品相关的各种业务逻辑方法,例如数据库操作、业务规则处理等,本控制器中的各个接口方法会调用其对应的方法来完成具体的业务功能。
+ */
+ @Autowired
+ DishService dishService;
+
+ /**
+ * 自动注入RedisTemplate,用于操作Redis缓存,在本控制器中主要用于清除缓存数据,
+ * 例如在菜品数据发生新增、修改、删除等变更操作后,通过RedisTemplate来删除对应的缓存键值对,保证缓存数据与数据库中的菜品数据一致性,提高系统性能和数据准确性。
+ */
+ @Autowired
+ RedisTemplate redisTemplate;
+
+ /**
+ * 菜品分页查询的接口方法,用于接收客户端发送的分页查询请求,根据传入的DishPageQueryDTO对象中的查询条件(如页码、每页数量、筛选条件等),
+ * 调用DishService的pageQuery方法进行分页查询操作,最终将查询结果封装在PageResult对象中返回给客户端,方便管理员分页查看菜品信息。
+ *
+ * @param dishPageQueryDTO 包含分页查询条件的传输对象,其中包含了诸如页码、每页显示记录数以及其他可能的筛选条件等信息,用于指定具体的查询要求。
+ * @return 返回一个Result对象,其泛型类型为PageResult,Result对象用于统一封装接口的返回结果(包含状态码、提示信息等),PageResult中包含了实际查询到的菜品分页数据(如总记录数、当前页数据列表等)。
+ */
+ @GetMapping("/page")
+ @ApiOperation("菜品分页查询")
+ public Result pageQuery(DishPageQueryDTO dishPageQueryDTO) {
+ log.info("菜品分页查询:{}", dishPageQueryDTO);
+ PageResult pageResult = dishService.pageQuery(dishPageQueryDTO);
+
+ return Result.success(pageResult);
+ }
+
+ /**
+ * 新增菜品的接口方法,接收客户端发送的包含菜品详细信息的DishDTO对象(以JSON格式放在请求体中传入,通过@RequestBody注解进行解析绑定),
+ * 将其传递给DishService的saveWithFlaver方法进行菜品的新增操作,新增成功后,调用cleanCache方法清除与菜品相关的缓存数据(以保证缓存与数据库数据的一致性),
+ * 最后返回表示成功的Result对象给客户端,告知客户端菜品新增操作已顺利完成。
+ *
+ * @param dishDTO 包含菜品详细信息的传输对象,例如菜品名称、价格、分类、口味等信息,用于在新增菜品时提供完整的数据支持。
+ * @return 返回一个Result对象,表示新增菜品操作的结果,成功时返回的Result对象中包含相应的成功提示信息等内容。
+ */
+ @PostMapping
+ @ApiOperation("新增菜品")
+ public Result save(@RequestBody DishDTO dishDTO) {
+ log.info("新增菜品:{}", dishDTO);
+ dishService.saveWithFlaver(dishDTO);
+
+ cleanCache("dish_"+dishDTO.getCategoryId());
+ return Result.success();
+ }
+
+ /**
+ * 批量删除菜品的接口方法,接收客户端发送的包含要删除的菜品id列表的ArrayList参数(通过@RequestParam注解指定该参数从请求参数中获取,因为使用集合接收参数需要添加此注解),
+ * 将该id列表传递给DishService的deleteBatch方法进行批量删除操作,操作完成后,调用cleanCache方法清除与菜品相关的所有缓存数据(使用通配符"dish_*"来匹配可能涉及的缓存键),
+ * 最后返回表示成功的Result对象给客户端,告知客户端批量删除菜品操作已成功执行。
+ *
+ * @param ids 包含要批量删除的菜品id的集合,通过该集合可以确定要从数据库中删除哪些菜品记录。
+ * @return 返回一个Result对象,表示批量删除菜品操作的结果,成功时返回的Result对象中包含相应的成功提示信息等内容。
+ */
+ @DeleteMapping
+ @ApiOperation("批量删除菜品")
+ public Result deleteBatch(@RequestParam ArrayList ids) {
+ log.info("批量删除菜品:{}", ids);
+ dishService.deleteBatch(ids);
+
+ cleanCache("dish_*");
+ return Result.success();
+ }
+
+ /**
+ * 根据菜品id获取菜品数据的接口方法,接收客户端发送的菜品id(通过@PathVariable注解从请求路径中获取对应的参数值),
+ * 将该id传递给DishService的getById方法,查询对应的菜品详细信息,并将查询结果(以DishVO对象形式返回)封装在Result对象中返回给客户端,方便管理员查看特定菜品的详细情况。
+ *
+ * @param id 要查询的菜品的唯一标识符,通过该id可以在数据库中精准定位到对应的菜品记录,获取其详细信息。
+ * @return 返回一个Result对象,其泛型类型为DishVO,Result对象用于统一封装接口的返回结果,DishVO中包含了查询到的菜品的详细信息(如名称、价格、分类、口味等)。
+ */
+ @GetMapping("/{id}")
+ public Result getByDishId(@PathVariable Long id) {
+ log.info("根据id获取菜品:{}", id);
+ DishVO dish = dishService.getById(id);
+
+ return Result.success(dish);
+ }
+
+ /**
+ * 修改菜品的接口方法,接收客户端发送的包含修改后菜品详细信息的DishDTO对象(以JSON格式放在请求体中传入,通过@RequestBody注解进行解析绑定),
+ * 将其传递给DishService的updateDish方法进行菜品信息的修改操作,修改成功后,调用cleanCache方法清除与菜品相关的所有缓存数据(使用通配符"dish_*"来匹配可能涉及的缓存键),
+ * 最后返回表示成功的Result对象给客户端,告知客户端菜品修改操作已顺利完成。
+ *
+ * @param dishDTO 包含修改后菜品详细信息的传输对象,例如修改后的菜品名称、价格、分类、口味等信息,用于更新数据库中对应菜品的记录。
+ * @return 返回一个Result对象,表示修改菜品操作的结果,成功时返回的Result对象中包含相应的成功提示信息等内容。
+ */
+ @PutMapping()
+ @ApiOperation("修改菜品")
+ public Result updateDish(@RequestBody DishDTO dishDTO) {
+ log.info("修改菜品:{}", dishDTO);
+ dishService.updateDish(dishDTO);
+
+ cleanCache("dish_*");
+ return Result.success();
+ }
+
+ /**
+ * 根据分类id查询菜品的接口方法,接收客户端发送的分类id参数(从请求参数中获取),
+ * 将该分类id传递给DishService的getByCategoryId方法,查询该分类下的所有菜品信息,并将查询结果(以ArrayList集合形式返回,集合中每个元素为一个菜品对象)封装在Result对象中返回给客户端,
+ * 方便管理员查看某个分类下包含的所有菜品情况,例如在菜单分类管理等场景下查看特定分类下的菜品列表。
+ *
+ * @param categoryId 菜品分类的唯一标识符,通过该id可以在数据库中查找属于该分类的所有菜品记录。
+ * @return 返回一个Result对象,其泛型类型为ArrayList,Result对象用于统一封装接口的返回结果,ArrayList中包含了查询到的属于该分类的所有菜品对象(每个菜品对象包含了菜品自身的详细信息)。
+ */
+ @GetMapping("/list")
+ @ApiOperation("根据分类id查询菜品")
+ public Result getByCategoryId(Long categoryId) {
+ log.info("根据分类id查询菜品");
+ ArrayList dishes = dishService.getByCategoryId(categoryId);
+
+ return Result.success(dishes);
+ }
+
+ /**
+ * 起售停售菜品的接口方法,接收客户端发送的菜品id以及要设置的状态值(通过@PathVariable注解从请求路径中获取状态参数,通过方法参数获取菜品id),
+ * 将这两个参数传递给DishService的startOrStop方法进行菜品销售状态的变更操作,操作完成后,调用cleanCache方法清除与菜品相关的所有缓存数据(使用通配符"dish_*"来匹配可能涉及的缓存键),
+ * 同时,该方法还使用了@CachePut注解,它可以在方法执行后更新缓存(根据具体的缓存配置和返回结果来更新对应的缓存数据,此处暂未明确其具体更新的缓存内容细节),
+ * 最后返回表示成功的Result对象给客户端,告知客户端菜品销售状态变更操作已成功执行。
+ *
+ * @param id 要变更销售状态的菜品的唯一标识符,通过该id可以在数据库中精准定位到对应的菜品记录,进行状态修改操作。
+ * @param status 要设置的菜品销售状态值,例如1表示起售,0表示停售等,用于确定将菜品设置为哪种销售状态。
+ * @return 返回一个Result对象,表示起售停售菜品操作的结果,成功时返回的Result对象中包含相应的成功提示信息等内容。
+ */
+ @CachePut
+ @PostMapping("/status/{status}")
+ public Result startOrStop(Long id, @PathVariable Integer status) {
+ log.info("起售停售菜品id:{},status:{}", id, status);
+ dishService.startOrStop(id, status);
+
+ cleanCache("dish_*");
+ return Result.success();
+ }
+
+ /**
+ * 私有方法,用于清除Redis缓存中符合指定模式的缓存键值对,通过RedisTemplate的keys方法根据传入的模式字符串(可以使用通配符,如"dish_*"表示以"dish_"开头的所有键)查找对应的缓存键集合,
+ * 然后使用RedisTemplate的delete方法将这些找到的缓存键对应的缓存数据删除,以此来保证缓存数据与数据库中菜品数据的一致性,避免出现数据不一致导致的业务问题。
+ *
+ * @param pattern 用于匹配缓存键的模式字符串,通过这个模式可以灵活指定要删除的缓存键范围,通常使用通配符来实现批量删除相关缓存数据的目的。
+ */
+ private void cleanCache(String pattern) {
+ Set keys = redisTemplate.keys(pattern);
+ redisTemplate.delete(keys);
+ }
+}
\ No newline at end of file
diff --git a/sky/sky-server/src/main/java/com/sky/controller/admin/SetmealController.java b/sky/sky-server/src/main/java/com/sky/controller/admin/SetmealController.java
new file mode 100644
index 0000000..453a6b8
--- /dev/null
+++ b/sky/sky-server/src/main/java/com/sky/controller/admin/SetmealController.java
@@ -0,0 +1,149 @@
+package com.sky.controller.admin;
+
+import com.sky.dto.CategoryDTO;
+import com.sky.dto.CategoryPageQueryDTO;
+import com.sky.dto.SetmealDTO;
+import com.sky.dto.SetmealPageQueryDTO;
+import com.sky.entity.Category;
+import com.sky.result.PageResult;
+import com.sky.result.Result;
+import com.sky.service.CategoryService;
+import com.sky.service.SetmealService;
+import com.sky.vo.SetmealVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.annotations.Delete;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+
+/**
+ * SetmealController类,作为Spring MVC框架中的一个控制器类,主要用于处理与套餐相关的各种HTTP请求,
+ * 它与SetmealService(业务逻辑层的服务类)进行交互,实现了诸如分页查询套餐、起售停售套餐、修改套餐信息、根据id查询套餐、批量删除套餐以及新增套餐等功能,
+ * 同时借助Spring的缓存注解(如@CacheEvict等)来管理缓存数据,确保缓存与数据库中套餐数据的一致性,为管理员提供便捷的套餐管理相关的接口服务,满足套餐管理方面的业务需求。
+ */
+@RestController
+@Api("套餐相关接口")
+@Slf4j
+@RequestMapping("/admin/setmeal")
+public class SetmealController {
+
+ /**
+ * 通过自动注入的方式获取SetmealService对象,SetmealService中封装了与套餐相关的各种业务逻辑方法,
+ * 例如套餐数据的数据库操作、业务规则处理等,本控制器中的各个接口方法会调用其对应的方法来完成具体的套餐管理业务功能。
+ */
+ @Autowired
+ SetmealService setmealService;
+
+ /**
+ * 分页查询套餐的接口方法,接收客户端发送的包含分页查询条件的SetmealPageQueryDTO对象(从请求参数中获取),
+ * 该对象可能包含了诸如页码、每页显示记录数以及其他筛选条件等信息,将其传递给SetmealService的pageQuery方法进行实际的分页查询操作,
+ * 最后把查询结果(封装在PageResult对象中,包含了总记录数、当前页数据列表等分页相关信息)通过Result对象进行统一封装后返回给客户端,方便管理员分页查看套餐信息。
+ *
+ * @param setmealPageQueryDTO 包含分页查询条件的传输对象,用于指定具体的套餐分页查询要求,以便获取符合条件的套餐分页数据。
+ * @return 返回一个Result对象,其泛型类型为PageResult,Result对象用于统一封装接口的返回结果(包含状态码、提示信息等),PageResult中则包含了实际查询到的套餐分页数据。
+ */
+ @GetMapping("/page")
+ @ApiOperation("分页查询套餐")
+ public Result pageQuery(SetmealPageQueryDTO setmealPageQueryDTO) {
+ log.info("分页查询套餐:{}", setmealPageQueryDTO);
+ PageResult result = setmealService.pageQuery(setmealPageQueryDTO);
+
+ return Result.success(result);
+ }
+
+ /**
+ * 起售停售套餐的接口方法,接收客户端发送的套餐状态值(通过@PathVariable注解从请求路径中获取,表示要设置的起售或停售状态,通常1表示起售,0表示停售等)
+ * 以及套餐id(从请求参数中获取),将这两个参数传递给SetmealService的startOrStop方法进行套餐销售状态的变更操作,
+ * 同时,该方法使用了@CacheEvict注解,指定了清除名为"setmealCache"的缓存中的所有数据(通过设置allEntries为true),以保证缓存与数据库中套餐数据的一致性,
+ * 最后返回表示成功的Result对象给客户端,告知客户端套餐销售状态变更操作已成功执行。
+ *
+ * @param status 要设置的套餐销售状态值,用于确定将套餐设置为起售还是停售状态,方便对套餐的售卖情况进行控制。
+ * @param id 要变更销售状态的套餐的唯一标识符,通过该id可以在数据库中精准定位到对应的套餐记录,进行状态修改操作。
+ * @return 返回一个Result对象,表示起售停售套餐操作的结果,成功时返回的Result对象中包含相应的成功提示信息等内容。
+ */
+ @PostMapping("/status/{status}")
+ @ApiOperation("起售停售套餐")
+ @CacheEvict(cacheNames = "setmealCache", allEntries = true)
+ public Result startOrStop(@PathVariable Integer status, Long id) {
+ log.info("{}套餐,id={}", status == 1? "起售" : "停售", id);
+ setmealService.startOrStop(status, id);
+
+ return Result.success();
+ }
+
+ /**
+ * 修改套餐信息的接口方法,接收客户端发送的包含修改后套餐详细信息的SetmealDTO对象(以JSON格式放在请求体中传入,通过@RequestBody注解进行解析绑定),
+ * 将其传递给SetmealService的updateSetmeal方法进行套餐信息的修改操作,同时,该方法使用了@CacheEvict注解,指定清除名为"setmealCache"的缓存中的所有数据(通过设置allEntries为true),
+ * 确保缓存数据能及时更新,与数据库中的套餐数据保持一致,最后返回表示成功的Result对象给客户端,告知客户端套餐修改操作已顺利完成。
+ *
+ * @param setmealDTO 包含修改后套餐详细信息的传输对象,例如套餐名称、包含的菜品、价格等信息,用于更新数据库中对应套餐的记录。
+ * @return 返回一个Result对象,表示修改套餐操作的结果,成功时返回的Result对象中包含相应的成功提示信息等内容。
+ */
+ @PutMapping
+ @ApiOperation("修改套餐信息")
+ @CacheEvict(cacheNames = "setmealCache", allEntries = true)
+ public Result updateSetmeal(@RequestBody SetmealDTO setmealDTO) {
+ log.info("修改套餐信息:{}", setmealDTO);
+ setmealService.updateSetmeal(setmealDTO);
+
+ return Result.success();
+ }
+
+ /**
+ * 根据id查询套餐的接口方法,接收客户端发送的套餐id(通过@PathVariable注解从请求路径中获取),
+ * 将该id传递给SetmealService的getDishById方法,查询对应的套餐详细信息,并将查询结果(以SetmealVO对象形式返回,其中包含了套餐的各种详细信息,如名称、菜品组成、价格等)
+ * 通过Result对象进行统一封装后返回给客户端,方便管理员查看特定套餐的详细情况。
+ *
+ * @param id 要查询的套餐的唯一标识符,通过该id可以在数据库中精准定位到对应的套餐记录,获取其详细信息。
+ * @return 返回一个Result对象,其泛型类型为SetmealVO,Result对象用于统一封装接口的返回结果,SetmealVO中包含了查询到的套餐的详细信息。
+ */
+ @GetMapping("/{id}")
+ @ApiOperation("根据id查询套餐")
+ public Result getDishById(@PathVariable Long id) {
+ log.info("根据套餐id查询套餐");
+ SetmealVO setmealVO = setmealService.getDishById(id);
+
+ return Result.success(setmealVO);
+ }
+
+ /**
+ * 根据id批量删除套餐的接口方法,接收客户端发送的包含要删除的套餐id列表的ArrayList参数(通过@RequestParam注解指定该参数从请求参数中获取,因为使用集合接收参数需要添加此注解),
+ * 将该id列表传递给SetmealService的batchDeleteById方法进行批量删除操作,同时,该方法使用了@CacheEvict注解,指定清除名为"setmealCache"的缓存中的所有数据(通过设置allEntries为true),
+ * 保证缓存与数据库数据的一致性,最后返回表示成功的Result对象给客户端,告知客户端批量删除套餐操作已成功执行。
+ *
+ * @param ids 包含要批量删除的套餐id的集合,通过该集合可以确定要从数据库中删除哪些套餐记录。
+ * @return 返回一个Result对象,表示批量删除套餐操作的结果,成功时返回的Result对象中包含相应的成功提示信息等内容。
+ */
+ @DeleteMapping
+ @ApiOperation("根据id批量删除套餐")
+ @CacheEvict(cacheNames = "setmealCache", allEntries = true)
+ public Result batchDeleteById(@RequestParam ArrayList ids) {
+ log.info("根据id批量删除套餐:{}", ids);
+ setmealService.batchDeleteById(ids);
+
+ return Result.success();
+ }
+
+ /**
+ * 新增套餐的接口方法,接收客户端发送的包含新增套餐详细信息的SetmealDTO对象(以JSON格式放在请求体中传入,通过@RequestBody注解进行解析绑定),
+ * 将其传递给SetmealService的insert方法进行套餐的新增操作,同时,该方法使用了@CacheEvict注解,根据传入的SetmealDTO对象中的categoryId属性值作为缓存键,
+ * 清除对应的缓存数据(这样在新增套餐后,如果涉及基于分类的套餐缓存,能及时更新缓存,避免数据不一致),最后返回表示成功的Result对象给客户端,告知客户端套餐新增操作已顺利完成。
+ *
+ * @param setmealDTO 包含新增套餐详细信息的传输对象,例如套餐名称、包含的菜品、价格等信息,用于在新增套餐时提供完整的数据支持,同时其categoryId属性用于缓存管理。
+ * @return 返回一个Result对象,表示新增套餐操作的结果,成功时返回的Result对象中包含相应的成功提示信息等内容。
+ */
+ @CacheEvict(cacheNames = "setmealCache", key = "#setmealDTO.categoryId")
+ @PostMapping
+ @ApiOperation("新增套餐")
+ public Result insert(@RequestBody SetmealDTO setmealDTO) {
+ log.info("新增套餐:{}", setmealDTO);
+ setmealService.insert(setmealDTO);
+
+ return Result.success();
+ }
+}
\ No newline at end of file
diff --git a/sky/sky-server/src/main/java/com/sky/controller/user/AddressBookController.java b/sky/sky-server/src/main/java/com/sky/controller/user/AddressBookController.java
new file mode 100644
index 0000000..bbb3781
--- /dev/null
+++ b/sky/sky-server/src/main/java/com/sky/controller/user/AddressBookController.java
@@ -0,0 +1,149 @@
+package com.sky.controller.user;
+
+import com.sky.context.BaseContext;
+import com.sky.entity.AddressBook;
+import com.sky.result.Result;
+import com.sky.service.AddressBookService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import java.util.List;
+
+/**
+ * AddressBookController类,作为Spring MVC框架中的一个控制器类,主要用于处理与C端(客户端,通常指普通用户端)地址簿相关的各种HTTP请求,
+ * 它通过依赖注入获取AddressBookService(业务逻辑层的服务类),并调用其相应方法来实现诸如查询用户所有地址信息、新增地址、根据id查询/修改/删除地址、设置默认地址以及查询默认地址等功能,
+ * 旨在为普通用户提供便捷的地址簿管理相关的接口服务,方便用户对自己的收货地址等地址信息进行操作和管理,满足日常使用中地址相关的业务需求。
+ */
+@RestController
+@RequestMapping("/user/addressBook")
+@Api(tags = "C端地址簿接口")
+@Slf4j
+public class AddressBookController {
+
+ /**
+ * 通过自动注入的方式获取AddressBookService对象,AddressBookService中封装了与地址簿相关的各种业务逻辑方法,
+ * 例如地址数据的数据库操作(增删改查等)、业务规则处理(如设置默认地址的逻辑等),本控制器中的各个接口方法会调用其对应的方法来完成具体的地址簿管理业务功能。
+ */
+ @Autowired
+ private AddressBookService addressBookService;
+
+ /**
+ * 查询当前登录用户的所有地址信息的接口方法,该方法无请求参数,在方法内部会先创建一个AddressBook对象,
+ * 并通过BaseContext.getCurrentId()方法(此处假设BaseContext类用于获取当前登录用户的相关上下文信息,比如用户id)获取当前登录用户的id,设置到AddressBook对象中,
+ * 然后将该对象传递给AddressBookService的list方法,用于查询该用户的所有地址信息,最后将查询结果(以List集合形式返回,集合中每个元素为一个地址对象)通过Result对象进行统一封装后返回给客户端,
+ * 方便用户查看自己已保存的所有地址情况。
+ *
+ * @return 返回一个Result对象,其泛型类型为List,Result对象用于统一封装接口的返回结果(包含状态码、提示信息等),List中包含了查询到的当前登录用户的所有地址对象(每个地址对象包含了地址相关的详细信息,如收货人、联系电话、详细地址等)。
+ */
+ @GetMapping("/list")
+ @ApiOperation("查询当前登录用户的所有地址信息")
+ public Result> list() {
+ log.info("查询当前登录用户的所有地址信息");
+ AddressBook addressBook = new AddressBook();
+ addressBook.setUserId(BaseContext.getCurrentId());
+ List list = addressBookService.list(addressBook);
+ return Result.success(list);
+ }
+
+ /**
+ * 新增地址的接口方法,接收客户端发送的包含地址详细信息的AddressBook对象(以JSON格式放在请求体中传入,通过@RequestBody注解进行解析绑定),
+ * 将该对象传递给AddressBookService的save方法进行地址的新增操作,最后返回表示成功的Result对象给客户端,告知客户端地址新增操作已顺利完成,方便用户添加新的收货地址等信息。
+ *
+ * @param addressBook 包含新增地址详细信息的对象,例如收货人姓名、联系电话、详细地址、是否为默认地址等信息,用于在新增地址时提供完整的数据支持,将其保存到数据库中对应的地址表中。
+ * @return 返回一个Result对象,表示新增地址操作的结果,成功时返回的Result对象中包含相应的成功提示信息等内容。
+ */
+ @PostMapping
+ @ApiOperation("新增地址")
+ public Result save(@RequestBody AddressBook addressBook) {
+ log.info("新增地址:{}", addressBook);
+ addressBookService.save(addressBook);
+ return Result.success();
+ }
+
+ /**
+ * 根据id查询地址的接口方法,接收客户端发送的地址id(通过@PathVariable注解从请求路径中获取),
+ * 将该id传递给AddressBookService的getById方法,查询对应的地址详细信息,并将查询结果(以AddressBook对象形式返回,其中包含了地址的各种详细信息,如收货人、联系电话、详细地址等)
+ * 通过Result对象进行统一封装后返回给客户端,方便用户查看特定地址的详细情况,例如在修改地址前查看原地址信息等场景下使用。
+ *
+ * @param id 要查询的地址的唯一标识符,通过该id可以在数据库中精准定位到对应的地址记录,获取其详细信息。
+ * @return 返回一个Result对象,其泛型类型为AddressBook,Result对象用于统一封装接口的返回结果,AddressBook中包含了查询到的地址的详细信息。
+ */
+ @GetMapping("/{id}")
+ @ApiOperation("根据id查询地址")
+ public Result getById(@PathVariable Long id) {
+ log.info("根据id查询地址,id:{}", id);
+ AddressBook addressBook = addressBookService.getById(id);
+ return Result.success(addressBook);
+ }
+
+ /**
+ * 根据id修改地址的接口方法,接收客户端发送的包含修改后地址详细信息的AddressBook对象(以JSON格式放在请求体中传入,通过@RequestBody注解进行解析绑定),
+ * 将该对象传递给AddressBookService的update方法进行地址信息的修改操作,最后返回表示成功的Result对象给客户端,告知客户端地址修改操作已顺利完成,方便用户更新已保存地址的相关信息。
+ *
+ * @param addressBook 包含修改后地址详细信息的对象,例如修改后的收货人姓名、联系电话、详细地址等信息,用于更新数据库中对应地址的记录。
+ * @return 返回一个Result对象,表示修改地址操作的结果,成功时返回的Result对象中包含相应的成功提示信息等内容。
+ */
+ @PutMapping
+ @ApiOperation("根据id修改地址")
+ public Result update(@RequestBody AddressBook addressBook) {
+ log.info("根据id修改地址:{}", addressBook);
+ addressBookService.update(addressBook);
+ return Result.success();
+ }
+
+ /**
+ * 设置默认地址的接口方法,接收客户端发送的包含地址相关信息的AddressBook对象(以JSON格式放在请求体中传入,通过@RequestBody注解进行解析绑定),
+ * 将该对象传递给AddressBookService的setDefault方法进行默认地址的设置操作,该操作通常会涉及将其他同用户的地址的默认标记取消,并将当前传入的地址设置为默认地址,具体逻辑由AddressBookService中的方法实现,
+ * 最后返回表示成功的Result对象给客户端,告知客户端默认地址设置操作已顺利完成,方便用户指定常用的收货地址为默认地址,便于后续下单等操作时默认使用。
+ *
+ * @param addressBook 包含地址相关信息的对象,该对象中的相关属性(如地址id等)会用于确定要设置为默认地址的具体地址记录,同时可能会涉及一些其他属性用于业务逻辑判断等情况,例如是否满足设置默认地址的条件等。
+ * @return 返回一个Result对象,表示设置默认地址操作的结果,成功时返回的Result对象中包含相应的成功提示信息等内容。
+ */
+ @PutMapping("/default")
+ @ApiOperation("设置默认地址")
+ public Result setDefault(@RequestBody AddressBook addressBook) {
+ log.info("设置默认地址:{}", addressBook);
+
+ addressBookService.setDefault(addressBook);
+ return Result.success();
+ }
+
+ /**
+ * 根据id删除地址的接口方法,接收客户端发送的地址id(从请求参数中获取),
+ * 将该id传递给AddressBookService的deleteById方法进行地址的删除操作,最后返回表示成功的Result对象给客户端,告知客户端地址删除操作已成功执行,方便用户删除不再需要的地址信息。
+ *
+ * @param id 要删除的地址的唯一标识符,通过该id可以在数据库中精准定位到对应的地址记录,进行删除操作。
+ * @return 返回一个Result对象,表示根据id删除地址操作的结果,成功时返回的Result对象中包含相应的成功提示信息等内容。
+ */
+ @DeleteMapping
+ @ApiOperation("根据id删除地址")
+ public Result deleteById(Long id) {
+ log.info("根据id删除地址,id:{}", id);
+ addressBookService.deleteById(id);
+ return Result.success();
+ }
+
+ /**
+ * 查询默认地址的接口方法,该方法无请求参数,在方法内部会先创建一个AddressBook对象,设置其默认地址标记(通常用一个字段表示,这里假设为isDefault,设置值为1表示查询默认地址)以及通过BaseContext.getCurrentId()方法获取当前登录用户的id并设置到AddressBook对象中,
+ * 然后将该对象传递给AddressBookService的list方法,用于查询该用户的默认地址信息,若查询到的结果列表不为空且只包含一个元素(即找到了唯一的默认地址),则将该地址对象通过Result对象进行统一封装后返回给客户端,
+ * 若未查询到符合条件的默认地址,则返回一个表示错误信息(提示“没有查询到默认地址”)的Result对象给客户端,方便用户获取自己设置的默认收货地址,在下单等操作中可直接使用该默认地址。
+ */
+ @GetMapping("default")
+ @ApiOperation("查询默认地址")
+ public Result getDefault() {
+ log.info("查询默认地址");
+ // SQL:select * from address_book where user_id =? and is_default = 1
+ AddressBook addressBook = new AddressBook();
+ addressBook.setIsDefault(1);
+ addressBook.setUserId(BaseContext.getCurrentId());
+ List list = addressBookService.list(addressBook);
+
+ if (list!= null && list.size() == 1) {
+ return Result.success(list.get(0));
+ }
+
+ return Result.error("没有查询到默认地址");
+ }
+}
\ No newline at end of file
diff --git a/sky/sky-server/src/main/java/com/sky/controller/user/SetmealController.java b/sky/sky-server/src/main/java/com/sky/controller/user/SetmealController.java
new file mode 100644
index 0000000..ea27463
--- /dev/null
+++ b/sky/sky-server/src/main/java/com/sky/controller/user/SetmealController.java
@@ -0,0 +1,81 @@
+package com.sky.controller.user;
+
+import com.sky.constant.StatusConstant;
+import com.sky.entity.Setmeal;
+import com.sky.result.Result;
+import com.sky.service.SetmealService;
+import com.sky.vo.DishItemVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * SetmealController类,作为Spring MVC框架中的一个控制器类,主要用于处理C端(客户端,也就是普通用户端)与套餐浏览相关的各种HTTP请求,
+ * 它通过依赖注入获取SetmealService(业务逻辑层的服务类),并调用其相应方法来实现诸如根据分类id查询起售套餐、根据套餐id查询套餐内包含的菜品列表等功能,
+ * 同时借助Spring的缓存注解(如@Cacheable)来优化数据获取性能,减少重复查询数据库的次数,旨在为普通用户提供便捷的套餐浏览相关的接口服务,方便用户查看和了解套餐及相关菜品信息,满足用户在点餐等场景下的业务需求。
+ */
+@RestController("userSetmealController")
+@RequestMapping("/user/setmeal")
+@Api(tags = "C端-套餐浏览接口")
+@Slf4j
+public class SetmealController {
+
+ /**
+ * 通过自动注入的方式获取SetmealService对象,SetmealService中封装了与套餐相关的各种业务逻辑方法,
+ * 例如根据条件查询套餐数据、获取套餐内菜品信息等数据库操作以及相关业务规则处理(如判断套餐是否起售等),本控制器中的各个接口方法会调用其对应的方法来完成具体的套餐浏览业务功能。
+ */
+ @Autowired
+ private SetmealService setmealService;
+
+ /**
+ * 条件查询的接口方法,用于根据分类id查询处于起售状态的套餐信息,接收客户端发送的分类id参数(从请求参数中获取),
+ * 在方法内部,首先创建一个Setmeal对象,将传入的分类id以及表示起售状态的常量(通过StatusConstant.ENABLE获取,假设该常量定义了起售状态对应的数值)设置到该对象中,
+ * 然后将这个Setmeal对象传递给SetmealService的list方法进行实际的查询操作,最后把查询结果(以List集合形式返回,集合中每个元素为一个符合条件的套餐对象)通过Result对象进行统一封装后返回给客户端,
+ * 方便用户查看某个分类下正在售卖的套餐情况,例如在浏览菜品分类页面时查看对应分类下有哪些可购买的套餐。
+ * 同时,该方法使用了@Cacheable注解,指定了缓存名称为"setmealCache",并以传入的分类id作为缓存键,这样在相同分类id的查询再次发起时,如果缓存中有对应的数据,就可以直接从缓存中获取,而无需再次查询数据库,提高了系统性能。
+ *
+ * @param categoryId 菜品分类的唯一标识符,通过该id可以筛选出属于该分类且处于起售状态的套餐记录,方便用户按照分类查看可购买的套餐。
+ * @return 返回一个Result对象,其泛型类型为List,Result对象用于统一封装接口的返回结果(包含状态码、提示信息等),List中包含了查询到的符合条件的套餐对象(每个套餐对象包含了套餐自身的详细信息,如套餐名称、价格等)。
+ */
+ @GetMapping("/list")
+ @ApiOperation("根据分类id查询起售套餐")
+ @Cacheable(cacheNames = "setmealCache", key = "#categoryId")
+ public Result> list(Long categoryId) {
+ log.info("根据分类id查询起售套餐:{}", categoryId);
+
+ Setmeal setmeal = new Setmeal();
+ setmeal.setCategoryId(categoryId);
+ setmeal.setStatus(StatusConstant.ENABLE);
+
+ List list = setmealService.list(setmeal);
+
+ return Result.success(list);
+ }
+
+ /**
+ * 根据套餐id查询包含的菜品列表的接口方法,接收客户端发送的套餐id(通过@PathVariable注解从请求路径中获取,指定了参数名称为"id"),
+ * 将该id传递给SetmealService的getDishItemById方法,用于查询该套餐内包含的菜品详细信息,最后把查询结果(以List集合形式返回,集合中每个元素为一个菜品相关的对象,包含菜品的具体信息)
+ * 通过Result对象进行统一封装后返回给客户端,方便用户查看某个套餐具体包含了哪些菜品,例如在用户想要了解套餐具体内容时使用。
+ *
+ * @param id 要查询的套餐的唯一标识符,通过该id可以在数据库中精准定位到对应的套餐记录,进而获取其包含的菜品列表信息。
+ * @return 返回一个Result对象,其泛型类型为List,Result对象用于统一封装接口的返回结果,List中包含了查询到的该套餐内包含的菜品的详细信息(如菜品名称、规格等)。
+ */
+ @GetMapping("/dish/{id}")
+ @ApiOperation("根据套餐id查询包含的菜品列表")
+ public Result> dishList(@PathVariable("id") Long id) {
+ log.info("根据套餐id查询包含的菜品列表{}", id);
+
+ List list = setmealService.getDishItemById(id);
+ return Result.success(list);
+ }
+}
\ No newline at end of file
diff --git a/sky/sky-server/src/main/java/com/sky/handler/GlobalExceptionHandler.java b/sky/sky-server/src/main/java/com/sky/handler/GlobalExceptionHandler.java
new file mode 100644
index 0000000..4fe2645
--- /dev/null
+++ b/sky/sky-server/src/main/java/com/sky/handler/GlobalExceptionHandler.java
@@ -0,0 +1,61 @@
+package com.sky.handler;
+
+import com.sky.constant.MessageConstant;
+import com.sky.exception.BaseException;
+import com.sky.result.Result;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import java.sql.SQLIntegrityConstraintViolationException;
+
+/**
+ * GlobalExceptionHandler类,作为全局异常处理器,其主要作用是统一处理项目运行过程中抛出的各类业务相关异常,
+ * 通过使用Spring框架提供的@RestControllerAdvice注解,使其能够对整个项目中的所有被@RestController标注的控制器类中的方法抛出的异常进行捕获和处理,
+ * 旨在增强项目的稳定性和容错性,为用户提供友好的错误提示信息,避免因未处理的异常导致系统崩溃或者给用户展示不友好的错误页面等情况。
+ */
+@RestControllerAdvice
+@Slf4j
+public class GlobalExceptionHandler {
+
+ /**
+ * 捕获业务异常的方法,使用了@ExceptionHandler注解并指定要处理的异常类型为BaseException(假设这是项目自定义的业务异常基类,所有具体的业务异常都继承自它),
+ * 当项目中任何地方抛出BaseException类型的异常时,该方法就会被触发执行。在方法内部,首先通过日志记录异常信息(记录异常的详细消息内容),
+ * 然后返回一个Result对象,该对象通过调用Result.error方法并传入异常消息来封装错误信息,最终将这个包含错误信息的Result对象返回给客户端(比如在接口调用时返回给前端页面展示错误提示给用户),
+ * 告知客户端业务操作出现了异常以及具体的异常原因,使客户端能够知晓操作失败并显示相应的错误提示内容给用户。
+ *
+ * @param ex 捕获到的BaseException类型的异常对象,通过该对象可以获取到异常的详细信息,比如具体的错误消息等内容,用于记录日志和返回给客户端展示错误提示。
+ * @return 返回一个Result对象,其用于统一封装接口的返回结果,在这里表示出现了业务异常,其中包含了异常对应的错误提示信息(即异常对象的消息内容),方便客户端进行相应的错误处理和展示。
+ */
+ @ExceptionHandler(BaseException.class)
+ public Result exceptionHandler(BaseException ex) {
+ log.error("异常信息:{}", ex.getMessage());
+ return Result.error(ex.getMessage());
+ }
+
+ /**
+ * 处理SQL异常的方法,使用了@ExceptionHandler注解(此处未指定具体异常类型,默认会处理方法参数中定义的异常类型,即SQLIntegrityConstraintViolationException),
+ * 用于捕获项目中因数据库操作违反完整性约束(比如插入重复数据等情况)而抛出的SQLIntegrityConstraintViolationException异常。
+ * 在方法内部,首先打印异常对象(可能是用于调试等临时查看异常的详细情况),然后获取异常的消息内容并进行分割处理(按照空格进行分割,假设消息内容有一定的格式规律),
+ * 通过判断消息中是否包含特定的关键字("Duplicate entry",通常表示插入了重复的数据)来进一步处理异常情况。
+ * 如果包含该关键字,则提取出重复的字段名称(这里简单地取分割后的第三个元素作为字段名,具体可能需要根据实际的异常消息格式调整),并记录详细的异常信息日志(包含字段名和相应的已存在提示信息,假设MessageConstant.ALREADY_EXISTS是一个定义好的表示已存在的常量消息),
+ * 如果不包含该关键字,则记录一个未知错误的异常信息日志(通过MessageConstant.UNKNOWN_ERROR常量表示未知错误消息)。最后统一返回一个表示出现异常的Result对象,其中包含了相应的错误提示信息(这里统一返回MessageConstant.ALREADY_EXISTS表示出现了重复数据等相关异常情况)给客户端,
+ * 告知客户端数据库操作出现了问题以及大致的错误原因,让客户端进行相应的提示展示等处理。
+ *
+ * @param exception 捕获到的SQLIntegrityConstraintViolationException类型的异常对象,通过该对象获取异常的详细消息内容来分析和处理具体的异常情况,判断是何种数据库完整性约束违反问题。
+ * @return 返回一个Result对象,其用于统一封装接口的返回结果,表示出现了SQL相关的异常,其中包含了相应的错误提示信息(这里通常是表示数据已存在等相关的提示内容),方便客户端进行相应的错误处理和展示。
+ */
+ @ExceptionHandler
+ public Result SQLExceptionHandler(SQLIntegrityConstraintViolationException exception) {
+ System.out.println(exception);
+ String msg = exception.getMessage();
+ String[] split = msg.split(" ");
+ if (msg.contains("Duplicate entry")) {
+ String name = split[2];
+ log.error("异常信息:{}", name + MessageConstant.ALREADY_EXISTS);
+ } else {
+ log.error("异常信息:{}", MessageConstant.UNKNOWN_ERROR);
+ }
+ return Result.error(MessageConstant.ALREADY_EXISTS);
+ }
+}
\ No newline at end of file
diff --git a/sky/sky-server/src/main/java/com/sky/mapper/CategoryMapper.java b/sky/sky-server/src/main/java/com/sky/mapper/CategoryMapper.java
new file mode 100644
index 0000000..e840f1c
--- /dev/null
+++ b/sky/sky-server/src/main/java/com/sky/mapper/CategoryMapper.java
@@ -0,0 +1,78 @@
+package com.sky.mapper;
+
+import com.github.pagehelper.Page;
+import com.sky.annotation.AutoFill;
+import com.sky.dto.CategoryDTO;
+import com.sky.dto.CategoryPageQueryDTO;
+import com.sky.entity.Category;
+import com.sky.enumeration.OperationType;
+import com.sky.result.PageResult;
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import org.aspectj.weaver.ast.Or;
+
+import java.util.List;
+
+/**
+ * CategoryMapper接口,作为MyBatis框架中的数据映射接口,主要用于定义与分类(Category)相关的数据库操作方法,
+ * 它通过MyBatis的注解或者方法签名来声明如何与数据库进行交互,例如执行分类的分页查询、条件查询、删除、修改以及新增等操作,
+ * 这些方法会被MyBatis的相关机制映射到对应的SQL语句上,实现对数据库中分类表数据的增删改查功能,为业务逻辑层提供数据持久化相关的操作支持,便于对分类数据进行管理。
+ */
+@Mapper
+public interface CategoryMapper {
+
+ /**
+ * 分类分页查询的方法,接收一个CategoryPageQueryDTO对象作为参数,该对象通常包含了分页查询所需的相关信息,如页码、每页显示记录数以及可能的筛选条件等,
+ * 通过MyBatis的相关机制,该方法会被映射到对应的SQL语句(可能由MyBatis的分页插件结合具体的配置生成合适的分页查询SQL),用于从数据库中获取符合条件的分类数据,并以Page对象形式返回查询结果,
+ * Page是一个分页数据结构,其中包含了当前页的分类数据列表以及分页相关的信息(如总记录数、总页数等),方便业务逻辑层进行分页数据的处理和展示。
+ *
+ * @param categoryPageQueryDTO 包含分页查询条件的传输对象,用于指定具体的分类分页查询要求,以便获取相应的分类分页数据。
+ * @return 返回一个Page对象,代表分类的分页查询结果,其中的泛型Category表示每个元素是一个分类实体对象,包含了分类的各种属性信息(如分类名称、类型、状态等)。
+ */
+ Page pageQuery(CategoryPageQueryDTO categoryPageQueryDTO);
+
+ /**
+ * 根据传入的CategoryDTO对象进行条件查询的方法,CategoryDTO对象中包含了用于筛选分类数据的相关条件信息,
+ * 通过MyBatis的映射机制,会执行对应的SQL语句(根据具体的配置和映射规则生成),从数据库中查找符合条件的分类数据,并以List集合形式返回查询结果,
+ * List集合中的每个元素为一个分类实体对象,方便业务逻辑层根据不同的查询条件获取相应的分类数据列表进行后续处理,例如展示符合特定条件的分类列表等。
+ *
+ * @param categoryDTO 包含查询条件的传输对象,用于指定具体的分类查询条件,以便获取符合要求的分类数据列表。
+ * @return 返回一个List对象,代表符合查询条件的分类数据列表,其中的泛型Category表示每个元素是一个分类实体对象,包含了分类的各种属性信息(如分类名称、类型、状态等)。
+ */
+ List query(CategoryDTO categoryDTO);
+
+ /**
+ * 删除分类的方法,接收一个表示分类id的Long类型参数,通过MyBatis的注解@Delete指定了对应的SQL删除语句,
+ * 当调用该方法时,会执行"delete from category where id=#{id}"这条SQL语句,从数据库的category表中根据传入的id删除对应的分类记录,实现对分类数据的删除操作,
+ * 该操作通常在业务逻辑层确定要删除某个分类时被调用,比如管理员在后台管理系统中删除不再需要的分类。
+ *
+ * @param id 要删除的分类的唯一标识符,通过该id可以在数据库的category表中精准定位到对应的分类记录,执行删除操作。
+ */
+ @Delete("delete from category where id=#{id}")
+ void delete(Long id);
+
+ /**
+ * 修改分类的方法,接收一个Category实体对象作为参数,该对象中包含了修改后的分类相关信息(如修改后的分类名称、类型、状态等属性值),
+ * 同时该方法使用了@AutoFill注解(假设这是一个自定义的注解,用于在执行该方法时自动填充一些通用的字段值,比如更新时间、更新用户等,具体填充逻辑由相关的切面或者拦截器实现,根据OperationType.UPDATE来确定是更新操作时的填充),
+ * 通过MyBatis的映射机制,会执行对应的SQL语句(根据实体对象的属性和配置生成合适的更新语句),将数据库中对应分类记录的相关信息更新为传入对象中的属性值,实现分类数据的修改操作,
+ * 常用于业务逻辑层在需要修改分类的某些属性时调用,例如修改分类名称、调整分类状态等场景。
+ *
+ * @param category 包含修改后分类信息的实体对象,其属性值将用于更新数据库中对应分类记录的相应字段内容,实现分类数据的修改。
+ */
+ @AutoFill(OperationType.UPDATE)
+ void updateCategory(Category category);
+
+ /**
+ * 新增分类的方法,接收一个Category实体对象作为参数,该对象中包含了要新增的分类相关信息(如分类名称、类型、状态等属性值),
+ * 该方法使用了@AutoFill注解(根据OperationType.INSERT来确定是插入操作时的自动填充,用于填充创建时间、创建用户等通用字段值,同样具体填充逻辑由相关机制实现)以及@Insert注解,
+ * 通过@Insert注解明确指定了对应的插入SQL语句,当调用该方法时,会执行该SQL语句将传入的Category对象中的属性值插入到数据库的category表中,实现分类数据的新增操作,
+ * 一般在业务逻辑层需要添加新的分类时被调用,比如添加新的菜品分类或者商品分类等情况。
+ *
+ * @param category 包含新增分类信息的实体对象,其属性值将按照指定的SQL语句格式插入到数据库的category表中,完成分类的新增操作。
+ */
+ @AutoFill(OperationType.INSERT)
+ @Insert("insert into category(type,name,sort,status,create_time,create_user,update_time,update_user)" +
+ "values (#{type},#{name},#{sort},#{status},#{createTime},#{createUser},#{updateTime},#{updateUser})")
+ void save(Category category);
+}
\ No newline at end of file
diff --git a/sky/sky-server/src/main/java/com/sky/mapper/OrderMapper.java b/sky/sky-server/src/main/java/com/sky/mapper/OrderMapper.java
new file mode 100644
index 0000000..553e493
--- /dev/null
+++ b/sky/sky-server/src/main/java/com/sky/mapper/OrderMapper.java
@@ -0,0 +1,125 @@
+package com.sky.mapper;
+
+import com.github.pagehelper.Page;
+import com.sky.dto.OrdersPageQueryDTO;
+import com.sky.entity.OrderDetail;
+import com.sky.entity.Orders;
+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;
+import java.util.Map;
+
+/**
+ * OrderMapper接口,作为MyBatis框架中的数据映射接口,主要用于定义与订单(Orders)相关的各种数据库操作方法,
+ * 涵盖了从订单数据的统计、查询(包括分页查询、按条件查询等)、插入、修改等多方面操作,通过MyBatis的注解与对应的SQL语句进行关联,实现对数据库中订单表数据的增删改查以及统计分析等功能,
+ * 为业务逻辑层提供了操作订单数据的底层支持,满足不同业务场景下对于订单管理和数据获取的需求。
+ */
+@Mapper
+public interface OrderMapper {
+
+ /**
+ * 根据状态统计订单数量的方法,使用了@Select注解指定对应的SQL查询语句,该语句会从数据库的orders表中统计状态为传入参数status所指定值的订单记录数量,
+ * 接收一个Integer类型的参数status,表示要统计的订单状态值,通过执行"select count(id) from orders where status = #{status}"这条SQL语句,
+ * 返回符合条件的订单数量(以Integer类型返回统计结果),常用于业务逻辑层需要了解处于特定状态下的订单数量的场景,比如统计已完成订单数量、待支付订单数量等情况,方便后续业务分析和展示。
+ *
+ * @param status 订单状态值,用于在数据库查询中筛选出处于该状态的订单记录,进而统计其数量,不同的业务中订单状态可能有不同的定义和取值,例如0表示未支付、1表示已支付等。
+ * @return 返回一个Integer类型的值,表示符合指定状态的订单数量,该数值反映了在数据库中处于相应状态的订单的记录个数,便于业务层进行相关数据统计和分析。
+ */
+ @Select("select count(id) from orders where status = #{status}")
+ Integer countStatus(Integer status) ;
+
+ /**
+ * 分页条件查询并按下单时间排序的方法,接收一个OrdersPageQueryDTO对象作为参数,该对象通常包含了分页查询所需的相关信息(如页码、每页显示记录数、筛选条件等)以及可能的排序相关要求(此处按下单时间排序),
+ * 通过MyBatis的相关机制(可能结合了分页插件等),该方法会被映射到对应的SQL语句(根据OrdersPageQueryDTO中的条件生成合适的分页查询且按时间排序的SQL语句),从数据库中获取符合条件的订单数据,并以Page对象形式返回查询结果,
+ * Page是一个分页数据结构,其中包含了当前页的订单数据列表以及分页相关的信息(如总记录数、总页数等),方便业务逻辑层进行分页数据的处理和展示,常用于在前端页面分页展示订单列表等场景,便于用户查看不同条件下的订单情况。
+ *
+ * @param ordersPageQueryDTO 包含分页查询条件和排序要求的传输对象,用于指定具体的订单分页查询以及下单时间排序要求,以便获取相应的订单分页数据并按时间顺序排列。
+ * @return 返回一个Page对象,代表订单的分页查询结果,其中的泛型Orders表示每个元素是一个订单实体对象,包含了订单的各种属性信息(如订单号、下单时间、订单状态、用户信息等)。
+ */
+ Page pageQuery(OrdersPageQueryDTO ordersPageQueryDTO);
+
+ /**
+ * 用户下单的方法,接收一个Orders实体对象作为参数,该对象中包含了新订单的相关信息(如用户信息、下单时间、订单金额、订单状态等各种属性值),
+ * 通过MyBatis的映射机制,会执行对应的插入SQL语句(根据Orders对象的属性和配置生成合适的插入语句,虽此处未明确写出@Insert注解对应的SQL语句,但MyBatis会根据实体与表的映射关系自动生成),
+ * 将传入的Orders对象中的属性值插入到数据库的orders表中,实现新订单的创建操作,在用户完成下单流程,业务逻辑层需要将订单数据持久化到数据库时调用该方法,完成订单数据的存储。
+ *
+ * @param orders 包含新订单信息的实体对象,其属性值将按照MyBatis生成的插入语句格式插入到数据库的orders表中,完成用户下单对应的订单新增操作。
+ */
+ void insert(Orders orders);
+
+ /**
+ * 根据订单号查询订单的方法,使用了@Select注解指定对应的SQL查询语句,该语句会从数据库的orders表中查找订单号与传入参数orderNumber相匹配的订单记录,
+ * 接收一个String类型的参数orderNumber,表示要查询的订单号,通过执行"select * from orders where number = #{orderNumber}"这条SQL语句,
+ * 返回对应的订单实体对象(以Orders类型返回查询结果),常用于业务逻辑层需要根据订单号获取特定订单详细信息的场景,比如在订单详情查看、订单状态跟踪等业务操作中,依据订单号来查询具体的订单情况。
+ *
+ * @param orderNumber 要查询的订单的唯一编号,通过该编号可以在数据库的orders表中精准定位到对应的订单记录,获取其详细信息。
+ * @return 返回一个Orders类型的对象,表示查询到的与传入订单号对应的订单实体,其中包含了该订单的各种详细信息(如订单号、下单时间、订单状态、用户信息等)。
+ */
+ @Select("select * from orders where number = #{orderNumber}")
+ Orders getByNumber(String orderNumber);
+
+ /**
+ * 修改订单信息的方法,接收一个Orders实体对象作为参数,该对象中包含了修改后的订单相关信息(如更新后的订单状态、修改后的收货地址等属性值),
+ * 通过MyBatis的映射机制,会执行对应的更新SQL语句(根据实体对象的属性和配置生成合适的更新语句),将数据库中对应订单记录的相关信息更新为传入对象中的属性值,实现订单数据的修改操作,
+ * 常用于业务逻辑层在订单状态变更、订单内容调整等需要修改订单部分属性的场景下调用,比如用户修改收货地址、商家修改订单配送状态等情况。
+ *
+ * @param orders 包含修改后订单信息的实体对象,其属性值将用于更新数据库中对应订单记录的相应字段内容,实现订单数据的修改。
+ */
+ void update(Orders orders);
+
+ /**
+ * 获取配送超时的订单的方法,接收两个参数,一个是Integer类型的pendingPayment(可能表示某种订单支付相关状态或者用于筛选的其他前置条件,具体含义根据业务而定),
+ * 另一个是LocalDateTime类型的time(通常用于表示一个时间界限,结合前面的状态等条件来判断订单是否配送超时),通过MyBatis的@Param注解对参数进行命名绑定,使得在对应的SQL语句中可以准确引用这两个参数,
+ * 该方法会执行对应的SQL语句(虽未明确写出,但根据参数和业务逻辑可知是筛选出符合特定状态且下单时间小于给定时间的配送超时的订单记录),并以List集合形式返回查询到的配送超时的订单列表,
+ * 方便业务逻辑层对这些配送超时的订单进行后续处理,例如提醒商家尽快处理、统计超时订单数量等情况,常用于订单配送管理相关的业务场景中。
+ *
+ * @param pendingPayment 用于筛选订单的一个条件参数,可能与订单支付状态等相关,用于和另一个时间参数共同确定哪些订单处于配送超时的情况,具体含义由业务逻辑决定。
+ * @param time 表示时间界限的参数,通常用于判断订单下单时间是否早于该时间,结合前面的状态参数来筛选出配送超时的订单,比如以当前时间为界限判断哪些订单下单太久还未完成配送等情况。
+ * @return 返回一个List对象,代表符合配送超时条件的订单列表,其中的泛型Orders表示每个元素是一个订单实体对象,包含了订单的各种属性信息(如订单号、下单时间、订单状态、用户信息等),便于业务层对这些超时订单进行后续处理。
+ */
+ List getByStatusAndOrderTimeLT(@Param("pendingPayment") Integer pendingPayment, @Param("time") LocalDateTime time);
+
+ /**
+ * 批量修改派送状态的方法,接收两个参数,一个是List类型的ordersList,表示要批量修改派送状态的订单列表,其中每个Orders对象包含了订单的基本信息以及对应的订单id等用于定位的关键信息,
+ * 另一个是Integer类型的status,表示要修改为的目标派送状态值,通过MyBatis的@Param注解对参数进行命名绑定,使得在对应的SQL语句中可以准确引用这两个参数,
+ * 该方法会执行对应的SQL语句(根据订单列表和目标状态生成合适的批量更新语句,虽未明确写出,但可实现批量修改操作),实现对多个订单的派送状态进行统一修改,常用于批量处理订单派送状态变更的业务场景,比如一批订单同时开始配送、同时完成配送等情况。
+ *
+ * @param ordersList 包含要批量修改派送状态的订单的列表,通过该列表可以确定具体哪些订单的派送状态需要进行修改,每个订单对象包含了订单自身的详细信息用于在数据库中定位和更新相应记录。
+ * @param status 要修改为的目标派送状态值,用于统一设置ordersList中各个订单的派送状态,使其变为该指定的值,不同的业务中派送状态可能有不同的定义和取值,例如1表示已派送、0表示未派送等。
+ */
+ void updateBatchStatus(@Param("ordersList") List ordersList, @Param("status") Integer status);
+
+ /**
+ * 根据orderId获取订单的方法,使用了@Select注解指定对应的SQL查询语句,该语句会从数据库的orders表中查找id与传入参数id相匹配的订单记录,
+ * 接收一个Long类型的参数id,表示要查询的订单的唯一标识符(通常对应数据库表中的主键),通过执行"select * from orders where id=#{id}"这条SQL语句,
+ * 返回对应的订单实体对象(以Orders类型返回查询结果),常用于业务逻辑层需要根据订单id获取特定订单详细信息的场景,比如在订单详情查看、订单状态跟踪等业务操作中,依据订单id来查询具体的订单情况,与根据订单号查询订单类似,但依据的是订单的内部唯一标识符。
+ *
+ * @param id 要查询的订单的唯一标识符,通过该标识符可以在数据库的orders表中精准定位到对应的订单记录,获取其详细信息。
+ * @return 返回一个Orders类型的对象,表示查询到的与传入订单id对应的订单实体,其中包含了该订单的各种详细信息(如订单号、下单时间、订单状态、用户信息等)。
+ */
+ @Select("select * from orders where id=#{id}")
+ Orders getById(Long id);
+
+ /**
+ * 查询总订单数的方法,接收一个Map类型的参数map,该Map中通常包含了用于筛选统计总订单数的相关条件信息(例如按照时间范围、用户范围等条件来统计符合要求的总订单数量),
+ * 通过MyBatis的@Param注解对参数进行命名绑定(此处将参数命名为"map"),使得在对应的SQL语句中可以准确引用该参数,执行对应的SQL语句(根据传入的条件Map生成合适的统计总订单数的SQL语句,虽未明确写出,但可实现相应统计功能),
+ * 并以Integer类型返回统计得到的总订单数量,常用于业务逻辑层需要了解在特定条件下的总订单数量的场景,比如统计某个时间段内的总订单量、某个用户的总订单数量等情况,方便业务数据的统计和分析。
+ *
+ * @param map 包含统计总订单数筛选条件的Map对象,其中的键值对可以根据业务需求设置不同的条件参数,例如时间区间、用户标识等,用于确定统计哪些订单的数量,以获取符合特定要求的总订单数量。
+ * @return 返回一个Integer类型的值,表示符合传入条件的总订单数量,该数值反映了在数据库中满足相应条件的订单的总记录个数,便于业务层进行相关数据统计和分析。
+ */
+ Integer countByMap(@Param("map") Map map);
+
+ /**
+ * 统计营业额的方法,接收一个Map类型的参数map,该Map中通常包含了用于筛选统计营业额的相关条件信息(例如按照时间范围、店铺范围等条件来统计符合要求的营业额数值),
+ * 通过MyBatis的@Param注解对参数进行命名绑定(此处将参数命名为"map"),使得在对应的SQL语句中可以准确引用该参数,执行对应的SQL语句(根据传入的条件Map生成合适的统计营业额的SQL语句,虽未明确写出,但可实现相应统计功能),
+ * 并以Double类型返回统计得到的营业额数值,常用于业务逻辑层需要了解在特定条件下的营业额情况的场景,比如统计某个时间段内的店铺营业额、某个分类商品的营业额等情况,方便业务数据的统计和分析以及财务相关的核算。
+ *
+ * @param map 包含统计营业额筛选条件的Map对象,其中的键值对可以根据业务需求设置不同的条件参数,例如时间区间、商品分类、店铺标识等,用于确定统计哪些订单产生的营业额,以获取符合特定要求的营业额数值。
+ * @return 返回一个Double类型的值,表示符合传入条件的营业额数值,该数值反映了在数据库中满足相应条件的订单所产生的营业额总和,便于业务层进行相关数据统计和分析以及财务处理。
+ */
+ Double sumByMap(@Param("map") Map map);
+}
\ No newline at end of file
diff --git a/sky/sky-server/src/main/java/com/sky/mapper/UserMapper.java b/sky/sky-server/src/main/java/com/sky/mapper/UserMapper.java
new file mode 100644
index 0000000..0e75ed7
--- /dev/null
+++ b/sky/sky-server/src/main/java/com/sky/mapper/UserMapper.java
@@ -0,0 +1,59 @@
+package com.sky.mapper;
+
+import com.sky.entity.User;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.Map;
+
+/**
+ * UserMapper接口,作为MyBatis框架中的数据映射接口,主要用于定义与用户(User)相关的各种数据库操作方法,
+ * 涵盖了从用户信息的查询(根据不同条件,如openid、用户id等)、用户注册新增,到特定统计(如统计今日新增用户数量)等功能,通过MyBatis的注解与对应的SQL语句进行关联,实现对数据库中用户表数据的增删改查以及统计分析等操作,
+ * 为业务逻辑层提供了操作用户数据的底层支持,满足不同业务场景下对于用户管理和数据获取的需求。
+ */
+@Mapper
+public interface UserMapper {
+
+ /**
+ * 根据openid获取用户的方法,使用了@Select注解指定对应的SQL查询语句,该语句会从数据库的user表中查找openid与传入参数openid相匹配的用户记录,
+ * 接收一个String类型的参数openid,通常在与第三方登录(比如微信登录等,openid作为第三方平台给用户的唯一标识)或者系统自身基于openid来识别用户的场景下使用,
+ * 通过执行"select * from user where openid=#{openid}"这条SQL语句,返回对应的用户实体对象(以User类型返回查询结果),常用于业务逻辑层需要根据openid获取特定用户详细信息的场景,
+ * 比如在登录验证、关联第三方账号等业务操作中,依据openid来查询具体的用户情况,确保能准确识别和获取用户相关信息。
+ *
+ * @param openid 要查询的用户在第三方平台或者系统内对应的唯一标识,通过该标识可以在数据库的user表中精准定位到对应的用户记录,获取其详细信息。
+ * @return 返回一个User类型的对象,表示查询到的与传入openid对应的用户实体,其中包含了该用户的各种详细信息(如用户名、密码、用户角色等,具体取决于用户表的字段定义)。
+ */
+ @Select("select * from user where openid=#{openid}")
+ User getByOpenId(String openid);
+
+ /**
+ * 注册新用户的方法,接收一个User实体对象作为参数,该对象中包含了新用户的相关注册信息(如用户名、密码、手机号等各种属性值,具体根据用户表的字段定义和注册业务要求而定),
+ * 通过MyBatis的映射机制,会执行对应的插入SQL语句(虽此处未明确写出@Insert注解对应的SQL语句,但MyBatis会根据实体与表的映射关系自动生成合适的插入语句),
+ * 将传入的User对象中的属性值插入到数据库的user表中,实现新用户注册信息的持久化操作,在用户完成注册流程,业务逻辑层需要将用户注册数据保存到数据库时调用该方法,完成新用户数据的存储。
+ *
+ * @param user 包含新用户注册信息的实体对象,其属性值将按照MyBatis生成的插入语句格式插入到数据库的user表中,完成用户注册对应的新增用户操作。
+ */
+ void insertUser(User user);
+
+ /**
+ * 通过用户id获取用户信息的方法,使用了@Select注解指定对应的SQL查询语句,该语句会从数据库的user表中查找id与传入参数userId相匹配的用户记录,
+ * 接收一个Long类型的参数userId,表示要查询的用户的唯一标识符(通常对应数据库表中的主键),通过执行"select * from user where id=#{userId}"这条SQL语句,
+ * 返回对应的用户实体对象(以User类型返回查询结果),常用于业务逻辑层需要根据用户id获取特定用户详细信息的场景,比如在用户详情查看、用户权限验证等业务操作中,依据用户id来查询具体的用户情况,获取用户的详细资料。
+ *
+ * @param userId 要查询的用户的唯一标识符,通过该标识符可以在数据库的user表中精准定位到对应的用户记录,获取其详细信息。
+ * @return 返回一个User类型的对象,表示查询到的与传入用户id对应的用户实体,其中包含了该用户的各种详细信息(如用户名、密码、用户角色等,具体取决于用户表的字段定义)。
+ */
+ @Select("select * from user where id=#{userId}")
+ User getById(Long userId);
+
+ /**
+ * 今日新增用户的方法,接收一个Map类型的参数map,该Map中通常包含了用于筛选统计今日新增用户的相关条件信息(例如按照创建时间范围来确定是今日新增的用户,可能涉及日期相关的比较条件等,具体根据业务和数据库表结构而定),
+ * 通过MyBatis的@Param注解对参数进行命名绑定(此处将参数命名为"map"),使得在对应的SQL语句中可以准确引用该参数,执行对应的SQL语句(根据传入的条件Map生成合适的统计今日新增用户数量的SQL语句,虽未明确写出,但可实现相应统计功能),
+ * 并以Integer类型返回统计得到的今日新增用户数量,常用于业务逻辑层需要了解每天新注册用户数量情况的场景,比如分析用户增长趋势、统计每日新增用户活跃度等情况,方便业务数据的统计和分析。
+ *
+ * @param map 包含统计今日新增用户筛选条件的Map对象,其中的键值对可以根据业务需求设置不同的条件参数,例如时间区间限定等,用于确定哪些用户是今日新增的,以获取符合特定要求的今日新增用户数量。
+ * @return 返回一个Integer类型的值,表示符合传入条件的今日新增用户数量,该数值反映了在数据库中今日新注册的用户的记录个数,便于业务层进行相关数据统计和分析。
+ */
+ Integer countByMap(@Param("map") Map map);
+}
\ No newline at end of file
diff --git a/sky/sky-server/src/main/java/com/sky/service/AddressBookService.java b/sky/sky-server/src/main/java/com/sky/service/AddressBookService.java
new file mode 100644
index 0000000..df55ff3
--- /dev/null
+++ b/sky/sky-server/src/main/java/com/sky/service/AddressBookService.java
@@ -0,0 +1,63 @@
+package com.sky.service;
+
+import com.sky.entity.AddressBook;
+import java.util.List;
+
+/**
+ * AddressBookService接口,定义了与地址簿(AddressBook)相关的一系列业务操作方法,
+ * 它作为业务逻辑层的抽象接口,旨在规范地址簿相关服务的功能,使得不同的业务实现类可以按照统一的方法定义来实现具体的业务逻辑,
+ * 为上层的控制器层等调用者提供了清晰的操作地址簿数据的接口,方便进行诸如查询、新增、获取单个、修改、设置默认以及删除地址等操作,以满足用户在地址管理方面的各种业务需求。
+ */
+public interface AddressBookService {
+
+ /**
+ * 根据传入的AddressBook对象中的条件(如用户id等属性,可用于筛选特定用户的地址信息)进行地址簿信息的列表查询操作,
+ * 返回符合条件的地址信息列表(以List集合形式返回,集合中的每个元素是一个AddressBook实体对象,包含了如地址、联系人、联系电话等地址相关详细信息),
+ * 方便在需要获取特定用户的多个地址信息时调用,例如在用户查看自己已保存的所有收货地址等场景下使用。
+ *
+ * @param addressBook 包含查询条件的地址簿实体对象,其属性可用于确定要查询哪些地址信息,比如通过设置用户id属性来获取该用户对应的所有地址记录。
+ * @return 返回一个List对象,代表符合传入条件的地址簿信息列表,其中的泛型AddressBook表示每个元素是一个地址簿实体对象,包含了地址的各种详细信息(如详细地址、联系人、联系电话等)。
+ */
+ List list(AddressBook addressBook);
+
+ /**
+ * 用于新增地址信息的方法,接收一个AddressBook实体对象作为参数,该对象中包含了要新增的地址详细信息(如详细地址、联系人、联系电话等属性值),
+ * 通过具体的业务实现类实现该方法时,会将传入的地址信息持久化到数据库中对应的地址簿表中,完成地址的新增操作,常用于用户添加新的收货地址等场景下调用,实现地址数据的存储。
+ *
+ * @param addressBook 包含新增地址详细信息的实体对象,其属性值将被保存到数据库的地址簿表中,作为一条新的地址记录,例如详细地址、联系人、联系电话等信息会被插入相应的字段。
+ */
+ void save(AddressBook addressBook);
+
+ /**
+ * 根据传入的地址id(Long类型的参数id)查询对应的单个地址信息,返回相应的AddressBook实体对象(该对象包含了该地址的详细信息,如详细地址、联系人、联系电话等),
+ * 方便在需要查看某个具体地址的详细情况时调用,例如在修改地址前查看原地址信息、在订单选择收货地址时查看特定地址详情等业务场景下使用。
+ *
+ * @param id 要查询的地址的唯一标识符,通过该id可以在数据库的地址簿表中精准定位到对应的地址记录,获取其详细信息。
+ * @return 返回一个AddressBook对象,代表查询到的与传入id对应的地址实体,其中包含了该地址的各种详细信息(如详细地址、联系人、联系电话等)。
+ */
+ AddressBook getById(Long id);
+
+ /**
+ * 用于修改地址信息的方法,接收一个AddressBook实体对象作为参数,该对象中包含了修改后的地址详细信息(如更新后的详细地址、联系人、联系电话等属性值),
+ * 通过具体的业务实现类实现该方法时,会根据该对象中的地址id等关键信息找到数据库中对应的地址记录,并将记录中的相关字段更新为传入对象中的新属性值,完成地址信息的修改操作,常用于用户更新已保存的收货地址等场景下调用。
+ *
+ * @param addressBook 包含修改后地址详细信息的实体对象,其属性值将用于更新数据库中对应地址记录的相应字段内容,实现地址数据的修改。
+ */
+ void update(AddressBook addressBook);
+
+ /**
+ * 用于设置默认地址的方法,接收一个AddressBook实体对象作为参数,该对象中通常包含了地址相关的关键信息(如地址id等,用于确定要设置为默认地址的具体地址记录),
+ * 通过具体的业务实现类实现该方法时,会按照业务规则进行操作,比如将其他同用户的非默认地址标记取消,并将传入的这个地址标记为默认地址(涉及对数据库中地址簿表相关字段的更新操作),方便用户指定常用的收货地址为默认地址,便于后续下单等操作时默认使用该地址。
+ *
+ * @param addressBook 包含地址相关信息的实体对象,其属性(如地址id等)会用于确定要设置为默认地址的具体地址记录,同时可能会涉及一些其他属性用于业务逻辑判断等情况,例如是否满足设置默认地址的条件等。
+ */
+ void setDefault(AddressBook addressBook);
+
+ /**
+ * 根据传入的地址id(Long类型的参数id)删除对应的地址信息,通过具体的业务实现类实现该方法时,会在数据库的地址簿表中根据该id找到对应的地址记录,并执行删除操作,将该记录从表中移除,
+ * 常用于用户删除不再需要的收货地址等场景下调用,实现地址数据的删除。
+ *
+ * @param id 要删除的地址的唯一标识符,通过该id可以在数据库的地址簿表中精准定位到对应的地址记录,执行删除操作。
+ */
+ void deleteById(Long id);
+}
\ No newline at end of file
diff --git a/sky/sky-server/src/main/java/com/sky/service/EmployeeService.java b/sky/sky-server/src/main/java/com/sky/service/EmployeeService.java
new file mode 100644
index 0000000..9c2164e
--- /dev/null
+++ b/sky/sky-server/src/main/java/com/sky/service/EmployeeService.java
@@ -0,0 +1,70 @@
+package com.sky.service;
+
+import com.sky.dto.EmployeeDTO;
+import com.sky.dto.EmployeeLoginDTO;
+import com.sky.dto.EmployeePageQueryDTO;
+import com.sky.entity.Employee;
+import com.sky.result.PageResult;
+
+/**
+ * EmployeeService接口,定义了与员工(Employee)相关的一系列业务操作方法,
+ * 它作为业务逻辑层的抽象接口,旨在规范员工相关服务的功能,使得不同的业务实现类可以按照统一的方法定义来实现具体的业务逻辑,
+ * 为上层的控制器层等调用者提供了清晰的操作员工数据的接口,方便进行诸如员工登录、新增、分页查询、账号状态变更、根据id查询以及编辑员工信息等操作,以满足企业在员工管理方面的各种业务需求。
+ */
+public interface EmployeeService {
+
+ /**
+ * 员工登录的业务方法,接收一个EmployeeLoginDTO对象作为参数,该对象通常包含了员工登录所需的关键信息,比如用户名(或工号)、密码等(具体取决于业务系统的设计),
+ * 通过具体的业务实现类实现该方法时,会根据传入的登录信息与数据库中存储的员工账号信息进行比对验证,若验证通过,则返回对应的Employee实体对象(该对象包含了员工的详细信息,如员工姓名、部门、岗位等),表示登录成功,
+ * 常用于员工在系统前端进行登录操作时,后端进行登录逻辑处理并返回相应结果的场景,确保只有合法的员工能够登录系统,获取相应的操作权限。
+ *
+ * @param employeeLoginDTO 包含员工登录信息的传输对象,其属性值(如用户名、密码等)用于在登录验证过程中与数据库中存储的员工账号信息进行匹配比对,以确定登录是否成功。
+ * @return 返回一个Employee对象,代表登录成功的员工实体,其中包含了该员工的各种详细信息(如员工姓名、部门、岗位等),若登录验证失败,则按照业务实现类的具体逻辑返回相应的错误提示或结果(比如返回null等表示登录失败)。
+ */
+ Employee login(EmployeeLoginDTO employeeLoginDTO);
+
+ /**
+ * 新增员工的业务方法,接收一个EmployeeDTO对象作为参数,该对象中包含了要新增员工的详细信息(如员工姓名、性别、联系方式、入职日期、岗位等属性值,具体根据业务系统中员工表的字段定义而定),
+ * 通过具体的业务实现类实现该方法时,会将传入的员工信息持久化到数据库中对应的员工表中,完成员工数据的新增操作,常用于企业人力资源部门添加新员工信息到系统等场景下调用,实现员工数据的存储,扩充企业员工信息库。
+ *
+ * @param employeeDTO 包含新增员工详细信息的实体对象,其属性值将被保存到数据库的员工表中,作为一条新的员工记录,例如员工姓名、性别、联系方式、入职日期、岗位等信息会被插入相应的字段。
+ */
+ void save(EmployeeDTO employeeDTO);
+
+ /**
+ * 分页查询的业务方法,接收一个EmployeePageQueryDTO对象作为参数,该对象通常包含了分页查询所需的相关信息,如页码、每页显示记录数以及可能的筛选条件(比如按照部门筛选员工、按照姓名关键字筛选等),
+ * 通过具体的业务实现类实现该方法时,会根据传入的分页查询条件进行数据库查询操作,并将查询结果按照分页规则进行处理,最后以PageResult对象形式返回查询结果(PageResult对象中包含了总记录数、当前页的员工数据列表等分页相关信息),
+ * 方便在需要分页展示员工信息(比如在企业管理系统的员工列表页面,按页查看员工情况)的场景下调用,满足用户对员工数据分页查看的需求。
+ *
+ * @param employeePageQueryDTO 包含分页查询条件的传输对象,其属性值(如页码、每页记录数、筛选条件等)用于确定具体的员工分页查询要求,以便获取相应的分页数据。
+ * @return 返回一个PageResult对象,用于封装分页查询结果,包含了总记录数(total)和当前页的员工记录列表(records)等信息,方便上层进行分页数据的处理和展示。
+ */
+ PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO);
+
+ /**
+ * 启用或禁用员工账号的业务方法,接收两个参数,一个是Integer类型的status,表示要设置的员工账号状态值(例如1表示启用,0表示禁用,具体状态值的定义根据业务系统设定),
+ * 另一个是Long类型的id,表示要变更账号状态的员工的唯一标识符(通过该id可以在数据库的员工表中精准定位到对应的员工记录),通过具体的业务实现类实现该方法时,会根据传入的状态值和员工id,更新数据库中对应员工记录的账号状态字段,
+ * 常用于企业管理人员对员工账号进行权限管理,比如在员工离职或暂时不需要使用系统时禁用账号,或者在员工重新入职或恢复使用权限时启用账号等场景下调用,实现对员工账号状态的灵活控制。
+ *
+ * @param status 要设置的员工账号状态值,用于确定将员工账号设置为启用还是禁用状态,改变数据库中对应员工记录的账号状态字段内容。
+ * @param id 要变更账号状态的员工的唯一标识符,通过该id可以在数据库的员工表中精准定位到对应的员工记录,进行账号状态修改操作。
+ */
+ void startOrStop(Integer status, Long id);
+
+ /**
+ * 通过id查询员工信息的业务方法,接收一个Long类型的参数id,该参数表示要查询的员工的唯一标识符,
+ * 通过具体的业务实现类实现该方法时,会根据传入的员工id在数据库的员工表中查找对应的员工记录,并返回相应的Employee实体对象(该对象包含了员工的详细信息,如员工姓名、部门、岗位等),
+ * 方便在需要查看某个具体员工的详细情况时调用,例如在查看员工个人资料、进行员工信息编辑前查看原信息等业务场景下使用。
+ *
+ * @param id 要查询的员工的唯一标识符,通过该id可以在数据库的员工表中精准定位到对应的员工记录,获取其详细信息。
+ */
+ Employee getById(Long id);
+
+ /**
+ * 编辑员工信息的业务方法,接收一个EmployeeDTO对象作为参数,该对象中包含了修改后的员工详细信息(如更新后的员工姓名、性别、联系方式、岗位等属性值),
+ * 通过具体的业务实现类实现该方法时,会根据该对象中的员工id等关键信息找到数据库中对应的员工记录,并将记录中的相关字段更新为传入对象中的新属性值,完成员工信息的修改操作,常用于企业管理人员更新员工相关信息(比如员工调岗、联系方式变更等情况)的场景下调用。
+ *
+ * @param employeeDTO 包含修改后员工详细信息的实体对象,其属性值将用于更新数据库中对应员工记录的相应字段内容,实现员工数据的修改。
+ */
+ void update(EmployeeDTO employeeDTO);
+}
\ No newline at end of file
diff --git a/sky/sky-server/src/main/java/com/sky/service/ShoppingCartService.java b/sky/sky-server/src/main/java/com/sky/service/ShoppingCartService.java
new file mode 100644
index 0000000..fa6b496
--- /dev/null
+++ b/sky/sky-server/src/main/java/com/sky/service/ShoppingCartService.java
@@ -0,0 +1,43 @@
+package com.sky.service;
+
+import com.sky.dto.ShoppingCartDTO;
+import com.sky.entity.ShoppingCart;
+import java.util.List;
+
+/**
+ * ShoppingCartService接口,定义了与购物车(ShoppingCart)相关的一系列业务操作方法,
+ * 它作为业务逻辑层的抽象接口,旨在规范购物车相关服务的功能,使得不同的业务实现类可以按照统一的方法定义来实现具体的业务逻辑,
+ * 为上层的控制器层等调用者提供了清晰的操作购物车数据的接口,方便进行诸如添加商品到购物车、查看购物车内容、删除购物车中商品以及清空购物车等操作,以满足用户在购物过程中对购物车管理的各种业务需求。
+ */
+public interface ShoppingCartService {
+
+ /**
+ * 添加购物车的业务方法,接收一个ShoppingCartDTO对象作为参数,该对象通常包含了要添加到购物车的商品相关信息(比如商品id、数量、规格等,具体取决于业务系统中购物车与商品关联的设计)以及用户相关信息(比如用户id,用于确定是哪个用户的购物车),
+ * 通过具体的业务实现类实现该方法时,会根据传入的购物车信息将对应的商品添加到数据库中对应的购物车表(或相关存储结构中,具体看数据存储设计),完成商品添加到购物车的操作,常用于用户在浏览商品时将心仪的商品加入购物车的场景下调用,实现购物车数据的更新。
+ *
+ * @param shoppingCartDTO 包含要添加到购物车的商品及用户相关信息的传输对象,其属性值(如商品id、数量、规格、用户id等)用于确定要添加哪些商品到哪个用户的购物车中,按照业务规则进行相应的数据存储操作。
+ */
+ void add(ShoppingCartDTO shoppingCartDTO);
+
+ /**
+ * 查看用户购物车的业务方法,该方法无参数传入,通过具体的业务实现类实现该方法时,会根据当前登录用户(通常是从系统上下文获取用户标识信息,比如用户id)从数据库的购物车表(或相关存储结构)中查询出该用户购物车中的所有商品信息,
+ * 并以List集合形式返回查询结果(集合中每个元素是一个ShoppingCart实体对象,包含了如商品id、商品名称、数量、规格、价格等购物车中商品的详细信息),方便用户查看自己购物车中已添加的商品情况,例如在购物车页面展示商品列表等场景下使用。
+ *
+ * @return 返回一个List对象,代表当前用户购物车中的商品信息列表,其中的泛型ShoppingCart表示每个元素是一个购物车中商品的实体对象,包含了商品的各种详细信息(如商品名称、数量、规格、价格等)。
+ */
+ List list();
+
+ /**
+ * 删除购物车中的商品的业务方法,接收一个ShoppingCartDTO对象作为参数,该对象通常包含了要删除的商品相关关键信息(比如商品id、规格等,用于精准定位购物车中要删除的具体商品记录)以及用户相关信息(比如用户id,确保是操作当前用户购物车中的商品),
+ * 通过具体的业务实现类实现该方法时,会根据传入的信息在数据库的购物车表(或相关存储结构)中找到对应的商品记录,并执行删除操作,将该商品从购物车中移除,常用于用户在购物车中移除不再需要的商品的场景下调用,实现购物车数据的更新。
+ *
+ * @param shoppingCartDTO 包含要删除的商品及用户相关信息的传输对象,其属性值(如商品id、规格、用户id等)用于确定要从哪个用户的购物车中删除哪些具体商品,按照业务规则进行相应的数据删除操作。
+ */
+ void delete(ShoppingCartDTO shoppingCartDTO);
+
+ /**
+ * 清空购物车的业务方法,该方法无参数传入,通过具体的业务实现类实现该方法时,会根据当前登录用户(同样通常从系统上下文获取用户标识信息,比如用户id)将数据库中该用户购物车对应的所有商品记录全部删除,实现清空购物车的操作,
+ * 常用于用户想要一次性移除购物车中所有商品的场景下调用,例如重新选购商品前清空之前添加的商品等情况,方便用户快速清理购物车内容。
+ */
+ void clean();
+}
\ No newline at end of file
diff --git a/sky/sky-server/src/main/java/com/sky/service/impl/DishServiceImpl.java b/sky/sky-server/src/main/java/com/sky/service/impl/DishServiceImpl.java
new file mode 100644
index 0000000..f51482a
--- /dev/null
+++ b/sky/sky-server/src/main/java/com/sky/service/impl/DishServiceImpl.java
@@ -0,0 +1,221 @@
+package com.sky.service.impl;
+
+import com.github.pagehelper.Page;
+import com.github.pagehelper.PageHelper;
+import com.sky.constant.MessageConstant;
+import com.sky.constant.StatusConstant;
+import com.sky.dto.DishDTO;
+import com.sky.dto.DishPageQueryDTO;
+import com.sky.entity.Dish;
+import com.sky.entity.DishFlavor;
+import com.sky.entity.Setmeal;
+import com.sky.entity.SetmealDish;
+import com.sky.exception.DeletionNotAllowedException;
+import com.sky.mapper.DishMapper;
+import com.sky.result.PageResult;
+import com.sky.service.DishService;
+import com.sky.vo.DishVO;
+import com.sky.vo.SetmealVO;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * DishServiceImpl类,实现了DishService接口,作为业务逻辑层的实现类,主要负责处理与菜品(Dish)相关的各种业务逻辑操作,
+ * 它依赖于DishMapper(数据访问层接口,用于与数据库进行交互)来完成数据的持久化和查询等基础操作,通过调用DishMapper的对应方法以及运用一些业务规则处理,实现了诸如菜品的分页查询、新增、删除、修改、状态变更以及根据不同条件查询菜品等功能,
+ * 在整个系统架构中起到了承上启下的作用,将上层控制器层的请求转化为对数据库的具体操作,并按照业务需求处理返回结果,为菜品管理相关业务提供核心的逻辑支持。
+ */
+@Service
+public class DishServiceImpl implements DishService {
+
+ /**
+ * 通过自动注入的方式获取DishMapper对象,DishMapper中定义了与菜品相关的各种数据库操作方法,
+ * 例如菜品数据的分页查询、单个菜品查询、菜品数据的新增、删除、更新以及与菜品口味等相关的数据操作方法,本业务逻辑实现类中的各个业务方法会调用其对应的方法来完成具体的数据库交互操作,实现菜品业务逻辑功能。
+ */
+ @Autowired
+ DishMapper dishMapper;
+
+ /**
+ * 菜品分页查询的业务方法,实现了DishService接口中定义的pageQuery方法,用于根据传入的分页查询条件对象(DishPageQueryDTO)进行菜品数据的分页查询操作,
+ * 首先从DishPageQueryDTO对象中获取页码(page)和每页显示记录数(pageSize)信息,然后借助PageHelper工具(用于在MyBatis中方便地实现分页功能)启动分页查询,
+ * 调用DishMapper的pageQuery方法获取分页查询结果(以Page对象形式返回,其中包含了查询到的当前页菜品数据以及分页相关的统计信息,如总记录数等),
+ * 接着从Page对象中提取出总记录数(total)和当前页的菜品数据列表(dishes),最后构建一个PageResult对象,将总记录数和菜品数据列表设置进去,返回该PageResult对象给上层调用者(通常是控制器层),
+ * 以便在前端页面进行分页展示菜品信息,满足用户分页查看菜品列表的需求。
+ *
+ * @param dishPageQueryDTO 包含分页查询条件的传输对象,其中有页码、每页记录数以及可能的筛选条件等信息,用于指定具体的菜品分页查询要求,获取相应的分页数据。
+ * @return 返回一个PageResult对象,用于封装分页查询结果,包含了总记录数(total)和当前页的菜品记录列表(records)等信息,方便上层进行分页数据的处理和展示。
+ */
+ @Override
+ public PageResult pageQuery(DishPageQueryDTO dishPageQueryDTO) {
+ int page = dishPageQueryDTO.getPage();
+ int pageSize = dishPageQueryDTO.getPageSize();
+ // 开始分页查询,通过PageHelper设置当前页码和每页显示数量,后续执行的数据库查询会自动按照此分页设置进行操作
+ PageHelper.startPage(page, pageSize);
+ Page pageResult = dishMapper.pageQuery(dishPageQueryDTO);
+ // 取出查询总数,即满足查询条件的所有记录数量,通过Page对象的getTotal方法获取
+ long total = pageResult.getTotal();
+ // 取出查询结果,即当前页的菜品数据列表,通过Page对象的getResult方法获取
+ List dishes = pageResult.getResult();
+ // 构建查询结果对象,用于将分页相关的数据按照统一的格式返回给上层调用者
+ PageResult pageResult1 = new PageResult();
+ pageResult1.setTotal(total);
+ pageResult1.setRecords(dishes);
+
+ return pageResult1;
+ }
+
+ /**
+ * 新增菜品和口味的业务方法,该方法使用了@Transactional注解,用于标记这个方法在执行过程中涉及的数据库操作应该在一个事务中进行,保证数据的一致性和完整性,
+ * 例如在新增菜品及其口味信息时,如果其中某个操作失败,整个操作都应该回滚,避免出现部分数据插入成功而部分失败导致的数据不一致情况。
+ * 首先将传入的DishDTO对象中的属性值复制到一个新创建的Dish实体对象中(通过BeanUtils.copyProperties方法实现属性值的拷贝),并设置菜品状态为启用状态(通过StatusConstant.ENABLE常量表示,假设这是定义好的表示启用的状态值),
+ * 然后调用DishMapper的save方法将菜品数据插入到菜品表中,获取插入后菜品的id(通常是数据库自动生成的主键值),接着获取DishDTO中包含的菜品口味列表(flavors),
+ * 如果口味列表不为空且包含元素,遍历口味列表,为每个口味对象设置对应的菜品id,最后调用DishMapper的insertBatchFlavors方法将这些口味数据批量插入到口味表中,实现菜品及其口味信息的同时新增操作,
+ * 常用于在管理员添加新菜品以及对应的口味时调用,完成菜品相关数据的完整添加过程。
+ *
+ * @param dishDTO 包含菜品及其口味详细信息的传输对象,例如菜品名称、价格、分类等菜品信息以及多个口味的具体描述(如口味名称、辣度等口味相关属性),用于在新增菜品时提供完整的数据支持。
+ */
+ @Transactional
+ public void saveWithFlaver(DishDTO dishDTO) {
+ // 向菜品表添加一条数据,创建一个新的Dish实体对象,用于接收从DishDTO拷贝过来的属性值
+ Dish dish = new Dish();
+ BeanUtils.copyProperties(dishDTO, dish);
+ dish.setStatus(StatusConstant.ENABLE);
+
+ dishMapper.save(dish);
+ // 向口味表添加n条数据,获取刚插入菜品的id,后续用于关联口味与菜品
+ Long dishId = dish.getId();
+ List flavors = dishDTO.getFlavors();
+
+ if (flavors!= null && flavors.size() > 0) {
+ flavors.forEach(dishFlavor -> {
+ dishFlavor.setDishId(dishId);
+ });
+ dishMapper.insertBatchFlavors(flavors);
+
+ }
+ }
+
+ /**
+ * 删除菜品的业务方法,用于批量删除菜品数据,但在删除之前需要进行一些业务规则的校验,
+ * 首先通过调用DishMapper的getByIdBatch方法获取要删除的菜品列表(根据传入的菜品id列表ids查询),然后遍历这些菜品,检查每个菜品的状态,
+ * 如果菜品处于起售状态(通过StatusConstant.ENABLE判断,起售期间按照业务规则通常不允许删除),则抛出DeletionNotAllowedException异常(自定义的异常类型,用于表示不允许删除的情况),并传递相应的提示信息(通过MessageConstant.DISH_ON_SALE常量表示,假设这是定义好的提示菜品正在销售不能删除的消息),
+ * 接着检查菜品是否被套餐绑定,通过调用DishMapper的countMealDish方法统计与传入的菜品id列表相关联的套餐菜品数量,如果数量大于0(表示有套餐绑定了这些菜品),同样抛出DeletionNotAllowedException异常,并传递相应的提示信息(通过MessageConstant.DISH_BE_RELATED_BY_SETMEAL常量表示,假设这是定义好的提示菜品被套餐关联不能删除的消息),
+ * 只有当菜品既不在起售状态且未被套餐绑定的情况下,才调用DishMapper的deleteBatch方法,根据传入的菜品id列表执行批量删除操作,实现菜品数据的批量删除功能,确保删除操作符合业务规则,避免误删正在使用的菜品数据。
+ *
+ * @param ids 包含要批量删除的菜品id的集合,通过该集合可以确定要从数据库中删除哪些菜品记录,但需要经过业务规则校验后才能执行实际的删除操作。
+ */
+ public void deleteBatch(ArrayList ids) {
+
+ // 判断菜品是否在起售,起售期间不能被删除,通过查询数据库获取对应菜品列表,遍历检查状态
+ ArrayList dishs = dishMapper.getByIdBatch(ids);
+ for (Dish dish : dishs) {
+ if (dish.getStatus() == StatusConstant.ENABLE) {
+ throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
+ }
+ }
+ // 判断菜品是否被套餐绑定,绑定期间不能被删除,通过查询统计与菜品关联的套餐菜品数量来判断
+ Integer count = dishMapper.countMealDish(ids);
+ if (count > 0) {
+ throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
+ }
+
+ dishMapper.deleteBatch(ids);
+
+ }
+
+ /**
+ * 修改菜品的业务方法,该方法同样使用了@Transactional注解,保证修改菜品及其相关口味信息的操作在一个事务内执行,确保数据的一致性,
+ * 首先将传入的DishDTO对象中的属性值复制到一个新创建的Dish实体对象中(通过BeanUtils.copyProperties方法实现属性值的拷贝),然后获取DishDTO中的菜品口味列表(flavors),为每个口味对象设置对应的菜品id(即要修改的菜品的id),
+ * 接着调用DishMapper的updateDish方法更新菜品表中的菜品基本信息,之后先调用DishMapper的deleteBatchFlavors方法删除该菜品原有的口味数据(可能是因为口味有修改,先删除旧的口味记录),再调用insertBatchFlavors方法插入更新后的口味数据,实现菜品及其口味信息的完整修改操作,
+ * 常用于管理员修改菜品的相关属性(如名称、价格等)以及对应的口味信息时调用,保证菜品数据的准确性和完整性。
+ *
+ * @param dishDTO 包含修改后菜品及其口味详细信息的传输对象,例如修改后的菜品名称、价格、分类等菜品信息以及多个口味的具体描述(如口味名称、辣度等口味相关属性),用于更新数据库中对应菜品及其口味的记录。
+ */
+ @Transactional
+ public void updateDish(DishDTO dishDTO) {
+ Dish dish = new Dish();
+ BeanUtils.copyProperties(dishDTO, dish);
+ List flavors = dishDTO.getFlavors();
+ flavors.forEach(dishFlavor -> {
+ dishFlavor.setDishId(dish.getId());
+ });
+
+ // 更新菜品,调用数据访问层方法更新菜品基本信息
+ dishMapper.updateDish(dish);
+ // 更新菜品对应的口味,先删除原有的口味数据,再插入更新后的口味数据
+ dishMapper.deleteBatchFlavors(flavors);
+ dishMapper.insertBatchFlavors(flavors);
+
+ }
+
+ /**
+ * 根据id获取菜品数据的业务方法,用于根据传入的菜品id查询对应的菜品详细信息以及其关联的口味信息,
+ * 首先创建一个包含传入id的ArrayList集合(方便后续调用以集合为参数的查询方法),然后通过调用DishMapper的getByIdBatch方法(假设该方法可以根据传入的id列表查询对应的菜品列表,这里只传入了一个id,所以只会获取到一个菜品对象)获取对应的菜品对象,
+ * 接着通过调用DishMapper的getFlavorById方法根据菜品id查询该菜品的口味列表,之后创建一个DishVO对象(假设这是用于展示菜品详细信息的视图对象,包含了菜品本身信息以及口味信息等),
+ * 通过BeanUtils.copyProperties方法将菜品对象的属性值复制到DishVO对象中,并将查询到的口味列表设置到DishVO对象的对应属性中,最后返回这个包含菜品详细信息和口味信息的DishVO对象给上层调用者,
+ * 方便在需要查看特定菜品详细情况(如在菜品详情页面展示)时获取完整的数据进行展示。
+ *
+ * @param id 要查询的菜品的唯一标识符,通过该id可以在数据库中精准定位到对应的菜品记录,获取其详细信息以及关联的口味信息。
+ * @return 返回一个DishVO对象,其中包含了查询到的菜品的详细信息(如菜品名称、价格、分类等)以及对应的口味信息(如口味名称、辣度等口味相关属性),便于展示菜品的完整详情。
+ */
+ public DishVO getById(Long id) {
+ ArrayList ids = new ArrayList<>();
+ ids.add(id);
+ // 根据id获取菜品,调用数据访问层方法获取对应菜品对象
+ Dish dish = dishMapper.getByIdBatch(ids).get(0);
+
+ // 根据菜品id获取该菜品的口味,调用数据访问层方法获取菜品对应的口味列表
+ ArrayList dishFlavors = dishMapper.getFlavorById(id);
+
+ DishVO dishVO = new DishVO();
+ BeanUtils.copyProperties(dish, dishVO);
+ dishVO.setFlavors(dishFlavors);
+ return dishVO;
+
+ }
+
+ /**
+ * 根据分类id获取菜品的业务方法,直接调用DishMapper的getByCategoryId方法(假设该方法可以根据传入的分类id以及可能的其他筛选条件,这里第二个参数传入null表示无其他额外筛选条件)查询对应分类下的菜品列表,
+ * 并以ArrayList集合形式返回查询结果,返回的菜品列表包含了属于该分类的所有菜品对象(每个菜品对象包含了菜品自身的详细信息,如菜品名称、价格、状态等),方便在需要按照分类查看菜品时获取相应的数据,
+ * 例如在前端展示菜品分类页面时,获取某个分类下的所有菜品进行展示。
+ *
+ * @param categoryId 菜品分类的唯一标识符,通过该id可以在数据库中查找属于该分类的所有菜品记录,获取相应的菜品列表。
+ * @return 返回一个ArrayList对象,代表属于传入分类id的菜品列表,其中的泛型Dish表示每个元素是一个菜品实体对象,包含了菜品的各种属性信息(如菜品名称、价格、状态等)。
+ */
+ public ArrayList getByCategoryId(Long categoryId) {
+ return dishMapper.getByCategoryId(categoryId, null);
+ }
+
+ /**
+ * 起售或停售菜品的业务方法,用于变更菜品的销售状态,首先创建一个Dish实体对象,将传入的菜品id(id)和要设置的状态值(status)设置到该对象的对应属性中,
+ * 然后调用DishMapper的updateDish方法,根据传入的包含菜品id和新状态的Dish对象,更新数据库中对应菜品记录的状态字段,实现菜品销售状态的变更操作,
+ * 常用于管理员在后台管理系统中对菜品进行起售(如将状态设置为启用状态)或停售(如将状态设置为禁用状态)的操作场景,方便控制菜品的售卖情况。
+ *
+ * @param id 要变更销售状态的菜品的唯一标识符,通过该id可以在数据库中精准定位到对应的菜品记录,进行状态修改操作。
+ * @param status 要设置的菜品销售状态值,例如1表示起售,0表示停售等,用于确定将菜品设置为哪种销售状态,改变数据库中对应菜品记录的状态字段内容。
+ */
+ public void startOrStop(Long id, Integer status) {
+ Dish dish = new Dish();
+ dish.setStatus(status);
+ dish.setId(id);
+
+ dishMapper.updateDish(dish);
+ }
+
+/**
+ * 根据菜品分类和起售状态查询菜品的业务方法,首先根据传入的Dish实体对象中的分类id(通过dish.getCategoryId()获取)以及起售状态(通过dish.getStatus()获取)调用DishMapper的getByCategoryId方法查询对应的菜品列表(以ArrayList集合形式返回),
+ * 接着遍历查询到的菜品列表,对于每个菜品,创建一个DishVO对象,通过BeanUtils.copyProperties方法将菜品对象的属性值复制到DishVO对象中,然后再根据菜品的id调用DishMapper的getFlavorById方法获取该菜品的口味列表,并设置到DishVO对象的对应属性中,
+ * 最后将构建好的包含菜品详细信息和口味信息的DishVO对象添加到一个新的ArrayList集合中,遍历完成后返回这个包含所有符合条件的菜品及其口味信息的DishVO对象列表,
+ * 方便在需要按照分类和销售状态展示菜品详情(包括口味信息)时获取相应的数据进行展示,例如在前端展示某个分类下正在销售的菜品及其口味列表的场景。
+ *
+ * @param dish 包含菜品分类id和起售状态等查询条件的菜品实体对象,通过其属性值可以确定要查询哪些菜品,例如指定分类以及
\ No newline at end of file
diff --git a/sky/sky-server/src/main/java/com/sky/service/impl/SetmealServiceImpl.java b/sky/sky-server/src/main/java/com/sky/service/impl/SetmealServiceImpl.java
new file mode 100644
index 0000000..c426c54
--- /dev/null
+++ b/sky/sky-server/src/main/java/com/sky/service/impl/SetmealServiceImpl.java
@@ -0,0 +1,205 @@
+package com.sky.service.impl;
+
+import com.github.pagehelper.Page;
+import com.github.pagehelper.PageHelper;
+import com.sky.constant.MessageConstant;
+import com.sky.constant.StatusConstant;
+import com.sky.dto.CategoryPageQueryDTO;
+import com.sky.dto.SetmealDTO;
+import com.sky.dto.SetmealPageQueryDTO;
+import com.sky.entity.Setmeal;
+import com.sky.entity.SetmealDish;
+import com.sky.exception.DeletionNotAllowedException;
+import com.sky.mapper.DishMapper;
+import com.sky.mapper.SetmealMapper;
+import com.sky.result.PageResult;
+import com.sky.service.SetmealService;
+import com.sky.vo.DishItemVO;
+import com.sky.vo.SetmealVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * SetmealServiceImpl类,实现了SetmealService接口,作为业务逻辑层的实现类,主要负责处理与套餐(Setmeal)相关的各种业务逻辑操作,
+ * 它依赖于SetmealMapper(用于操作套餐相关的数据表,如套餐表、套餐菜品关联表等)以及DishMapper(用于获取菜品相关信息,可能在套餐菜品关联等操作中会用到)来完成数据的持久化、查询以及关联处理等基础操作,
+ * 通过调用这两个Mapper的对应方法以及运用一些业务规则处理,实现了诸如套餐的条件查询、分页查询、起售停售、修改、根据id查询、批量删除以及新增等功能,在整个系统架构中起到了承上启下的作用,为套餐管理相关业务提供核心的逻辑支持,满足不同业务场景下对于套餐操作的需求。
+ */
+@Service
+@Slf4j
+public class SetmealServiceImpl implements SetmealService {
+
+ /**
+ * 通过自动注入的方式获取SetmealMapper对象,SetmealMapper中定义了与套餐相关的各种数据库操作方法,
+ * 例如套餐数据的查询(按条件查询、分页查询、根据id查询等)、套餐数据的新增、删除、更新以及套餐与菜品关联关系的操作(如插入、删除套餐菜品关联记录等)方法,本业务逻辑实现类中的各个业务方法会调用其对应的方法来完成具体的数据库交互操作,实现套餐业务逻辑功能。
+ */
+ @Autowired
+ private SetmealMapper setmealMapper;
+
+ /**
+ * 通过自动注入的方式获取DishMapper对象,虽然套餐业务主要围绕套餐本身及其与菜品的关联,但在一些操作中可能需要获取菜品的相关信息(比如获取套餐内菜品的详细信息等),
+ * DishMapper中定义了与菜品相关的各种数据库操作方法,本业务逻辑实现类中的部分方法会调用其对应的方法来辅助完成套餐相关业务逻辑,例如在构建包含菜品详细信息的套餐视图对象等场景下会用到。
+ */
+ @Autowired
+ private DishMapper dishMapper;
+
+ /**
+ * 条件查询的业务方法,实现了SetmealService接口中定义的list方法,用于根据传入的Setmeal对象(其中包含了查询条件,如分类id、状态等属性值用于筛选套餐)进行套餐数据的条件查询操作,
+ * 直接调用SetmealMapper的list方法,传入该Setmeal对象作为查询条件,获取符合条件的套餐数据列表(以List集合形式返回,集合中每个元素为一个符合条件的套餐对象),并将该列表返回给上层调用者(通常是控制器层),
+ * 方便在需要按照特定条件查看套餐时获取相应的数据,例如在前端根据分类筛选套餐列表等场景下使用。
+ *
+ * @param setmeal 包含查询条件的套餐实体对象,其属性值(如分类id、状态等)用于确定要查询哪些套餐,以便获取符合要求的套餐数据列表。
+ * @return 返回一个List对象,代表符合传入条件的套餐数据列表,其中的泛型Setmeal表示每个元素是一个套餐实体对象,包含了套餐的各种属性信息(如套餐名称、价格、包含的菜品等)。
+ */
+ public List list(Setmeal setmeal) {
+ List list = setmealMapper.list(setmeal);
+ return list;
+ }
+
+ /**
+ * 根据套餐id查询该套餐菜品的业务方法,实现了SetmealService接口中定义的getDishItemById方法,用于根据传入的套餐id查询该套餐所包含的菜品详细信息,
+ * 直接调用SetmealMapper的getDishItemBySetmealId方法,传入套餐id作为参数,获取对应的菜品信息列表(以List集合形式返回,假设DishItemVO是用于展示菜品详细信息的视图对象,包含了菜品名称、规格等菜品相关属性),
+ * 并将该列表返回给上层调用者(通常是控制器层),方便在需要查看某个套餐具体包含哪些菜品时获取相应的数据,例如在用户查看套餐详情页面展示套餐内菜品列表的场景下使用。
+ *
+ * @param id 要查询的套餐的唯一标识符,通过该id可以在数据库中精准定位到对应的套餐记录,进而获取其包含的菜品列表信息。
+ * @return 返回一个List对象,代表该套餐包含的菜品详细信息列表,其中的泛型DishItemVO表示每个元素是一个菜品相关的视图对象,包含了菜品的各种详细信息(如菜品名称、规格等)。
+ */
+ public List getDishItemById(Long id) {
+ return setmealMapper.getDishItemBySetmealId(id);
+ }
+
+ /**
+ * 分页查询套餐的业务方法,用于根据传入的分页查询条件对象(SetmealPageQueryDTO)进行套餐数据的分页查询操作,
+ * 首先借助PageHelper工具(用于在MyBatis中方便地实现分页功能)启动分页查询,通过调用PageHelper.startPage方法并传入SetmealPageQueryDTO中的页码(page)和每页显示记录数(pageSize)信息来设置分页参数,
+ * 然后调用SetmealMapper的pageQuery方法获取分页查询结果(以Page对象形式返回,其中包含了查询到的当前页套餐数据以及分页相关的统计信息,如总记录数等),
+ * 接着创建一个PageResult对象,将从Page对象中获取的总记录数(通过getTotal方法获取)和当前页的套餐数据列表(通过getResult方法获取)设置到PageResult对象的对应属性中,最后返回该PageResult对象给上层调用者(通常是控制器层),
+ * 以便在前端页面进行分页展示套餐信息,满足用户分页查看套餐列表的需求。
+ *
+ * @param setmealPageQueryDTO 包含分页查询条件的传输对象,其中有页码、每页记录数以及可能的筛选条件等信息,用于指定具体的套餐分页查询要求,获取相应的分页数据。
+ * @return 返回一个PageResult对象,用于封装分页查询结果,包含了总记录数(total)和当前页的套餐记录列表(records)等信息,方便上层进行分页数据的处理和展示。
+ */
+ public PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO) {
+ // 开始分页查询,通过PageHelper设置当前页码和每页显示数量,后续执行的数据库查询会自动按照此分页设置进行操作
+ PageHelper.startPage(setmealPageQueryDTO.getPage(), setmealPageQueryDTO.getPageSize());
+ Page list = setmealMapper.pageQuery(setmealPageQueryDTO);
+
+ // 处理查询结果,构建PageResult对象来封装分页相关数据,以便统一返回给上层调用者
+ PageResult pageResult = new PageResult();
+ pageResult.setTotal(list.getTotal());
+ pageResult.setRecords(list.getResult());
+
+ return pageResult;
+ }
+
+ /**
+ * 起售或停售套餐的业务方法,用于变更套餐的销售状态,首先创建一个Setmeal实体对象,将传入的套餐id(id)和要设置的状态值(status)设置到该对象的对应属性中,
+ * 然后调用SetmealMapper的updateSetmeal方法,根据传入的包含套餐id和新状态的Setmeal对象,更新数据库中对应套餐记录的状态字段,实现套餐销售状态的变更操作,
+ * 常用于管理员在后台管理系统中对套餐进行起售(如将状态设置为启用状态)或停售(如将状态设置为禁用状态)的操作场景,方便控制套餐的售卖情况。
+ *
+ * @param status 要设置的套餐销售状态值,例如1表示起售,0表示停售等,用于确定将套餐设置为哪种销售状态,改变数据库中对应套餐记录的状态字段内容。
+ * @param id 要变更销售状态的套餐的唯一标识符,通过该id可以在数据库中精准定位到对应的套餐记录,进行状态修改操作。
+ */
+ public void startOrStop(Integer status, Long id) {
+ Setmeal setmeal = new Setmeal();
+ setmeal.setStatus(status);
+ setmeal.setId(id);
+ // 更改套餐的起售或停售状态,调用数据访问层方法更新套餐在数据库中的状态记录
+ setmealMapper.updateSetmeal(setmeal);
+
+ }
+
+ /**
+ * 修改套餐信息的业务方法,该方法使用了@Transactional注解,用于标记这个方法在执行过程中涉及的数据库操作应该在一个事务中进行,保证数据的一致性和完整性,
+ * 例如在修改套餐信息及其关联的菜品信息时,如果其中某个操作失败,整个操作都应该回滚,避免出现部分数据修改成功而部分失败导致的数据不一致情况。
+ * 首先将传入的SetmealDTO对象中的属性值复制到一个新创建的Setmeal实体对象中(通过BeanUtils.copyProperties方法实现属性值的拷贝),然后调用SetmealMapper的updateSetmeal方法更新套餐表中的套餐基本信息,
+ * 接着通过调用SetmealMapper的deleteSetmealDish方法根据套餐id(从SetmealDTO中获取)删除该套餐原有的菜品关联记录(因为套餐菜品可能有修改,先删除旧的关联记录),
+ * 再获取SetmealDTO中的套餐菜品列表(SetmealDish类型的列表,表示套餐与菜品的关联信息),遍历该列表,为每个套餐菜品对象设置对应的套餐id,最后调用SetmealMapper的insertBatchSetmealDish方法将这些更新后的套餐菜品关联信息批量插入到套餐菜品关联表中,
+ * 实现套餐及其关联菜品信息的完整修改操作,常用于管理员修改套餐的相关属性(如名称、价格等)以及套餐内包含的菜品信息时调用,保证套餐数据的准确性和完整性。
+ *
+ * @param setmealDTO 包含修改后套餐及其菜品详细信息的传输对象,例如修改后的套餐名称、价格、包含的菜品等信息,用于更新数据库中对应套餐及其关联菜品的记录。
+ */
+ @Transactional
+ public void updateSetmeal(SetmealDTO setmealDTO) {
+ Setmeal setmeal = new Setmeal();
+ BeanUtils.copyProperties(setmealDTO, setmeal);
+ // 修改套餐信息,调用数据访问层方法更新套餐基本信息
+ setmealMapper.updateSetmeal(setmeal);
+ // 修改套餐的菜品信息,先删除原有的套餐菜品关联记录
+ // 通过套餐id删除绑定在套餐上的菜品
+ setmealMapper.deleteSetmealDish(setmealDTO.getId());
+ // 批量插入套餐绑定的菜品,获取修改后的套餐菜品关联信息列表,设置套餐id后插入到关联表中
+ List dishes = setmealDTO.getSetmealDishes();
+ dishes.forEach(setmealDish -> setmealDish.setSetmealId(setmealDTO.getId()));
+ setmealMapper.insertBatchSetmealDish(dishes);
+ }
+
+ /**
+ * 根据套餐id获取套餐的业务方法,用于根据传入的套餐id查询对应的套餐详细信息以及其关联的菜品信息,
+ * 首先通过调用SetmealMapper的getBySetmealId方法根据套餐id获取套餐对象(包含套餐自身的基本信息,如套餐名称、价格等),然后调用SetmealMapper的getSetmealDishById方法根据套餐id获取该套餐关联的菜品列表(以List集合形式返回,每个SetmealDish对象包含了套餐与菜品的关联信息,如菜品id等),
+ * 接着创建一个SetmealVO对象(假设这是用于展示套餐详细信息的视图对象,包含了套餐本身信息以及关联的菜品信息等),通过BeanUtils.copyProperties方法将套餐对象的属性值复制到SetmealVO对象中,并将获取到的套餐菜品列表设置到SetmealVO对象的对应属性中,
+ * 最后返回这个包含套餐详细信息和关联菜品信息的SetmealVO对象给上层调用者,方便在需要查看特定套餐详细情况(如在套餐详情页面展示)时获取完整的数据进行展示。
+ *
+ * @param id 要查询的套餐的唯一标识符,通过该id可以在数据库中精准定位到对应的套餐记录,获取其详细信息以及关联的菜品信息。
+ * @return 返回一个SetmealVO对象,其中包含了查询到的套餐的详细信息(如套餐名称、价格等)以及对应的菜品关联信息(如包含的菜品id等),便于展示套餐的完整详情。
+ */
+ public SetmealVO getDishById(Long id) {
+ // 获取套餐信息,调用数据访问层方法获取对应套餐对象
+ Setmeal setmeal = setmealMapper.getBySetmealId(id);
+ // 获取套餐绑定的菜品,调用数据访问层方法获取套餐对应的菜品关联列表
+ List setmealDishes = setmealMapper.getSetmealDishById(id);
+
+ // 构建返回对象,创建SetmealVO对象并将套餐及菜品关联信息复制和设置进去
+ SetmealVO setmealVO = new SetmealVO();
+ BeanUtils.copyProperties(setmeal, setmealVO);
+ setmealVO.setSetmealDishes(setmealDishes);
+
+ return setmealVO;
+ }
+
+ /**
+ * 根据套餐id批量删除套餐的业务方法,用于批量删除指定id的套餐及其相关联的数据(如套餐菜品关联数据),
+ * 首先遍历传入的套餐id列表(ids),对于每个id,通过调用SetmealMapper的getBySetmealId方法获取对应的套餐对象,检查套餐的状态,
+ * 如果套餐处于起售状态(通过StatusConstant.ENABLE判断,起售期间按照业务规则通常不允许删除),则抛出DeletionNotAllowedException异常(自定义的异常类型,用于表示不允许删除的情况),并传递相应的提示信息(通过MessageConstant.SETMEAL_ON_SALE常量表示,假设这是定义好的提示套餐正在销售不能删除的消息),
+ * 接着再次遍历套餐id列表,对于每个套餐id,先创建一个包含该id的ArrayList集合(方便后续调用以集合为参数的删除方法),调用SetmealMapper的batchDeleteSetmeal方法删除套餐表中对应的套餐记录,然后调用SetmealMapper的deleteSetmealDish方法删除该套餐在套餐菜品关联表中的关联记录,
+ * 实现批量删除套餐及其关联数据的操作,确保删除操作符合业务规则,避免误删正在销售的套餐数据。
+ *
+ * @param ids 包含要批量删除的套餐id的集合,通过该集合可以确定要从数据库中删除哪些套餐记录,但需要经过业务规则校验后才能执行实际的删除操作。
+ */
+ public void batchDeleteById(ArrayList ids) {
+ ids.forEach(id -> {
+ Setmeal setmeal = setmealMapper.getBySetmealId(id);
+ if (StatusConstant.ENABLE == setmeal.getStatus()) {
+ // 起售中的套餐不能删除,若处于起售状态则抛出异常提示
+ throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);
+ }
+ });
+
+ ids.forEach(setmealId -> {
+ // 删除套餐表中的数据,先构建包含套餐id的集合,再调用对应的删除方法
+ ArrayList setmealIds = new ArrayList<>();
+ setmealIds.add(setmealId);
+ setmealMapper.batchDeleteSetmeal(setmealIds);
+ // 删除套餐菜品关系表中的数据,直接调用对应的删除方法
+ setmealMapper.deleteSetmealDish(setmealId);
+ });
+
+ }
+
+ /**
+ * 新增套餐的业务方法,用于向数据库中插入新的套餐及其关联的菜品信息,
+ * 首先将传入的SetmealDTO对象中的属性值复制到一个新创建的Setmeal实体对象中(通过BeanUtils.copyProperties方法实现属性值的拷贝),然后调用SetmealMapper的insertBatchSetmealDish方法将SetmealDTO中的套餐菜品关联信息(以List列表形式表示,包含了套餐与要绑定的菜品的关联信息)批量插入到套餐菜品关联表中,
+ * 接着调用SetmealMapper的insertSetmeal方法将套餐对象的信息插入到套餐表中,实现套餐及其关联菜品信息的同时新增操作,常用于管理员添加新套餐以及设置套餐内包含的菜品时调用,完成套餐相关数据的完整添加过程。
+ *
+ * @param setmealDTO 包含新增套餐及其菜品详细信息的传输对象,例如套餐名称、价格、包含的菜品等信息,用于在新增套餐时提供完整的数据支持,同时其菜品关联信息用于构建套餐与菜品的关联关系插入到数据库中。
+ */
+ public void insert(SetmealDTO setmealDTO) {
+ Setmeal setmeal = new Setmeal();
+ BeanUtils.copyProperties(setmealDTO, setmeal);
+ // 新增套餐绑定的菜品,调用数据访问层方法批量插入套餐
\ No newline at end of file
diff --git a/sky/sky-server/src/main/java/com/sky/webSocket/WebSocketServer.java b/sky/sky-server/src/main/java/com/sky/webSocket/WebSocketServer.java
new file mode 100644
index 0000000..918c0f4
--- /dev/null
+++ b/sky/sky-server/src/main/java/com/sky/webSocket/WebSocketServer.java
@@ -0,0 +1,93 @@
+package com.sky.webSocket;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.websocket.OnClose;
+import javax.websocket.OnMessage;
+import javax.websocket.OnOpen;
+import javax.websocket.Session;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * WebSocketServer类,是一个基于Java WebSocket规范实现的WebSocket服务端组件,用于在服务器与客户端之间建立双向通信的WebSocket连接,实现实时消息交互功能,
+ * 通过使用相关的WebSocket注解(如@ServerEndpoint、@OnOpen、@OnMessage、@OnClose等)定义了WebSocket连接的端点、连接建立、消息接收以及连接关闭等相关行为,同时提供了向所有已连接客户端发送消息的方法,
+ * 在整个应用架构中,可用于实现诸如实时推送消息、在线聊天、实时数据更新展示等需要实时交互的业务场景,增强用户体验和系统的实时性。
+ */
+@Component
+@ServerEndpoint("/ws/{sid}")
+@Slf4j
+public class WebSocketServer {
+
+ /**
+ * 使用一个静态的Map来存储已建立WebSocket连接的客户端会话信息,其中键为客户端的唯一标识符(由传入的{sid}参数确定,通常可以是用户id、设备id等能唯一标识客户端的信息),值为对应的WebSocket会话对象(Session),
+ * 通过这个Map可以方便地管理和查找不同客户端的会话,以便后续进行消息发送、连接状态管理等操作,实现对多个客户端连接的统一管理。
+ */
+ private static Map sessionMap = new HashMap<>();
+
+ /**
+ * 连接开启调用的方法,该方法使用了@OnOpen注解,表明当有客户端与服务端建立WebSocket连接时,此方法会被自动调用,
+ * 它接收两个参数,一个是通过@PathParam("sid")注解获取的从客户端连接请求路径中传来的唯一标识符(sid),用于区分不同的客户端,另一个是代表当前客户端与服务端建立的WebSocket会话对象(Session),
+ * 在方法内部,首先通过日志记录客户端建立连接的信息(记录传入的sid,方便后续查看连接情况和排查问题),然后将该客户端的sid和对应的Session对象存入sessionMap中,实现对新连接客户端会话的记录和管理,方便后续与之通信以及跟踪连接状态。
+ *
+ * @param sid 客户端的唯一标识符,从客户端连接请求路径中获取,用于在服务端区分不同的客户端,是后续查找和管理对应客户端会话的关键依据。
+ * @param session 代表当前客户端与服务端建立的WebSocket会话对象,通过该对象可以与客户端进行双向通信,例如向客户端发送消息或者接收客户端发送过来的消息等操作。
+ */
+ @OnOpen
+ public void open(@PathParam("sid") String sid, Session session) {
+ log.info("建立连接:{}", sid);
+ sessionMap.put(sid, session);
+ }
+
+ /**
+ * 收到客户端消息调用的方法,该方法使用了@OnMessage注解,表明当服务端接收到客户端通过WebSocket连接发送过来的消息时,此方法会被自动调用,
+ * 它接收两个参数,一个是客户端发送过来的消息内容(message),以字符串形式接收,另一个是通过@PathParam("sid")注解获取的客户端的唯一标识符(sid),用于确定消息来自哪个客户端,
+ * 在方法内部,首先通过日志记录客户端发送消息的相关信息(记录sid和消息内容,方便后续查看消息交互情况和排查问题),这里可以根据具体业务需求对收到的消息进行进一步的处理,例如解析消息、根据消息内容执行相应的业务逻辑等,但当前代码只是简单地记录了日志。
+ *
+ * @param message 客户端通过WebSocket连接发送过来的消息内容,以字符串形式接收,其格式和含义由客户端与服务端约定的通信协议决定,可能包含各种业务相关的数据,如操作指令、实时数据等。
+ * @param sid 客户端的唯一标识符,从客户端连接请求路径中获取,用于确定消息来源,方便针对不同客户端的消息进行相应的业务处理以及后续回复等操作。
+ */
+ @OnMessage
+ public void onMessage(String message, @PathParam("sid") String sid) {
+ log.info("收到客户端:{}的信息:{}", sid, message);
+ }
+
+ /**
+ * 连接关闭调用的方法,该方法使用了@OnClose注解,表明当客户端与服务端的WebSocket连接关闭时,此方法会被自动调用,
+ * 它接收一个参数,即通过@PathParam("sid")注解获取的客户端的唯一标识符(sid),用于确定是哪个客户端的连接被关闭了,
+ * 在方法内部,首先通过日志记录客户端断开连接的信息(记录sid,方便后续查看连接情况和排查问题),然后从sessionMap中移除该客户端对应的会话记录,实现对已关闭连接客户端会话的清理,确保sessionMap中只保留当前有效的客户端连接信息。
+ *
+ * @param sid 客户端的唯一标识符,从客户端连接请求路径中获取,用于确定是哪个客户端的连接被关闭了,以便准确地从管理连接的Map中移除对应的会话对象。
+ */
+ @OnClose
+ public void close(@PathParam("sid") String sid) {
+ log.info("断开连接:{}", sid);
+ sessionMap.remove(sid);
+ }
+
+ /**
+ * 向每个与服务端建立WebSocket连接的客户端发送信息的方法,用于实现服务端主动向所有已连接的客户端推送消息的功能,
+ * 首先获取sessionMap中存储的所有客户端会话对象的集合(通过sessionMap.values()方法获取),然后遍历这个集合,对于每个会话对象,尝试通过调用其getBasicRemote().sendText(message)方法向对应的客户端发送传入的消息内容(message),
+ * 如果在发送过程中出现IOException异常(例如客户端网络异常、连接已断开等情况导致无法正常发送消息),则会抛出RuntimeException异常(当前代码只是简单地将异常抛出,实际应用中可能需要更精细的异常处理逻辑,比如记录错误日志、尝试重新发送等),
+ * 此方法常用于服务端有实时消息需要推送给所有客户端的场景,比如系统广播通知、实时数据更新推送等业务情况,确保所有在线客户端能及时收到相关信息。
+ *
+ * @param message 要发送给所有客户端的消息内容,以字符串形式传入,其格式和含义由具体的业务需求和客户端与服务端约定的通信协议决定,例如可以是通知消息、实时数据更新内容等。
+ */
+ public void sendToAllClient(String message) {
+ Collection sessionCollection = sessionMap.values();
+ for (Session session : sessionCollection) {
+ try {
+ session.getBasicRemote().sendText(message);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+
+}
\ No newline at end of file