diff --git a/.gitattributes b/.gitattributes index fb9a0d2..13ccfbc 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,25 @@ -# Auto detect text files and perform LF normalization +# Chuẩn hóa line ending trong repository. +# Source/config dùng LF ổn định trên mọi môi trường; script Windows giữ CRLF. * text=auto +*.java text eol=lf +*.xml text eol=lf +*.properties text eol=lf +*.md text eol=lf +*.yml text eol=lf +*.yaml text eol=lf +*.json text eol=lf +*.sql text eol=lf +*.html text eol=lf +*.css text eol=lf +*.js text eol=lf +*.sh text eol=lf +.gitignore text eol=lf +.gitattributes text eol=lf +Dockerfile text eol=lf +Jenkinsfile text eol=lf +Procfile text eol=lf +*.cmd text eol=crlf +*.bat text eol=crlf *.jpg filter=lfs diff=lfs merge=lfs -text *.mwb filter=lfs diff=lfs merge=lfs -text *.png filter=lfs diff=lfs merge=lfs -text @@ -9,3 +29,6 @@ *.woff2 filter=lfs diff=lfs merge=lfs -text *.eot filter=lfs diff=lfs merge=lfs -text *.ttf filter=lfs diff=lfs merge=lfs -text + +# Bộ icon vendor này đang được lưu trực tiếp trong Git, không phải pointer LFS. +src/main/resources/static/assets/vendor/remixicon/** -filter -diff -merge -text diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 001e7b5..94310a8 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -1,12 +1,9 @@ -# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven +# Workflow này build và test dự án ecommerce_project bằng Maven trên JDK 17. +# Tài liệu tham khảo: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. +# Một số action bên dưới do bên thứ ba cung cấp và tuân theo điều khoản riêng của nhà phát hành. -name: Java CI with Maven +name: Ecommerce CI with Maven on: push: @@ -21,15 +18,15 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: - java-version: '11' + java-version: '17' distribution: 'temurin' cache: maven - name: Build with Maven run: mvn -B package --file pom.xml - # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive + # Gửi dependency graph để Dependabot có dữ liệu cảnh báo bảo mật chính xác hơn. - name: Update dependency graph uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6 diff --git a/Dockerfile b/Dockerfile index 0161da5..c71bafa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,24 @@ -FROM eclipse-temurin:17-jdk-focal - -WORKDIR /app - +# Build WAR ở stage riêng, runtime chỉ cần JRE để image deploy gọn hơn. +FROM eclipse-temurin:17-jdk-focal AS build + +WORKDIR /workspace + COPY .mvn/ .mvn COPY mvnw pom.xml ./ -RUN chmod +x mvnw +RUN chmod +x mvnw && ./mvnw -B -DskipTests dependency:go-offline -RUN ./mvnw dependency:go-offline - COPY src ./src - -CMD ["./mvnw", "spring-boot:run"] \ No newline at end of file + +RUN ./mvnw -B -DskipTests clean package + +FROM eclipse-temurin:17-jre-focal + +WORKDIR /app + +ENV PORT=8080 +EXPOSE 8080 + +COPY --from=build /workspace/target/ecommerce_project-0.0.1-SNAPSHOT.war app.war + +ENTRYPOINT ["java", "-jar", "/app/app.war"] diff --git a/Jenkinsfile b/Jenkinsfile index dbe5b19..534cbaa 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -2,11 +2,11 @@ pipeline { agent any environment { - // Telegram configre + // Cấu hình gửi thông báo Telegram từ credential Jenkins. TOKEN = credentials('telegram_token') CHAT_ID = credentials('telegram_chatid') - // Telegram message + // Nội dung thông báo mô tả commit đang được build/deploy. GIT_MESSAGE = sh(returnStdout: true, script: "git log -n 1 --format=%s ${GIT_COMMIT}").trim() GIT_AUTHOR = sh(returnStdout: true, script: "git log -n 1 --format=%ae ${GIT_COMMIT}").trim() GIT_COMMIT_SHORT = sh(returnStdout: true, script: "git rev-parse --short ${GIT_COMMIT}").trim() @@ -18,7 +18,7 @@ pipeline { TEXT_CLEAN = "${JOB_NAME} is Cleaning" TEXT_RUN = "${JOB_NAME} is Running" - // Telegram parameters + // Trạng thái cuối pipeline gửi về Telegram. TEXT_SUCCESS_BUILD = "${JOB_NAME} is Success" TEXT_FAILURE_BUILD = "${JOB_NAME} is Failure" } @@ -59,9 +59,9 @@ pipeline { stage('Run') { steps { sh "curl --location --request POST 'https://api.telegram.org/bot${TOKEN}/sendMessage' --form text='${TEXT_RUN}' --form chat_id='${CHAT_ID}'" - sh 'docker container stop ecommerce || echo "this container does not exist"' + sh 'docker rm -f ecommerce || echo "this container does not exist"' sh 'docker network create yan || echo "this network exist"' - sh 'echo y | docker container prune' + sh 'docker container prune -f' sh 'docker run --name ecommerce --network yan --restart=unless-stopped -d yamiannephilim/ecommerce:latest' } } diff --git a/Procfile b/Procfile index 1d07570..b1fc669 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -web: java -jar target/jira_project-0.0.1-SNAPSHOT.war \ No newline at end of file +web: java -jar target/ecommerce_project-0.0.1-SNAPSHOT.war \ No newline at end of file diff --git a/README.md b/README.md index d030e99..b0c8a6b 100644 --- a/README.md +++ b/README.md @@ -1,72 +1,89 @@ # DỰ ÁN WEB THƯƠNG MẠI ĐIỆN TỬ -Trang web thương mại điện tử được thiết lập để phục vụ một phần hoặc toàn bộ quy trình của hoạt động mua bán hàng hóa hay cung ứng dịch vụ, từ trưng bày giới thiệu hàng hóa, dịch vụ đến giao kết hợp đồng, cung ứng dịch vụ, thanh toán và dịch vụ sau bán hàng. -## LINK DEMO -
+`ecommerce_project` là website thương mại điện tử xây dựng bằng Spring Boot, Thymeleaf, Spring Security và MySQL. Ứng dụng hỗ trợ luồng mua sắm cơ bản: xem sản phẩm, phân loại, chi tiết sản phẩm, giỏ hàng, thanh toán, lịch sử đơn hàng, hồ sơ khách hàng, đăng ký, đăng nhập và đặt lại mật khẩu qua email. + +## TÍNH NĂNG CHÍNH + +- Hiển thị danh sách sản phẩm, sản phẩm mới, sản phẩm bán chạy và sản phẩm theo phân loại. +- Quản lý giỏ hàng, mã giảm giá, phí vận chuyển và thông tin người nhận. +- Tạo đơn hàng với các phương thức thanh toán tiền mặt, chuyển khoản hoặc thẻ. +- Xác thực người dùng bằng Spring Security và phát JWT cho API refresh token. +- Gửi email đặt lại mật khẩu bằng cấu hình SMTP qua biến môi trường. + +## CÔNG NGHỆ + +- Java 17 +- Spring Boot 2.7.x +- Spring MVC, Spring Data JPA, Spring Security, Thymeleaf +- MySQL +- Maven Wrapper +- Docker, Jenkins, GitHub Actions + +## CẤU HÌNH MÔI TRƯỜNG + +Ứng dụng không còn lưu credential trực tiếp trong source. Khi chạy local hoặc deploy, cấu hình các biến môi trường sau nếu giá trị mặc định chưa phù hợp: + +```bash +PORT=8080 +DB_URL=jdbc:mysql://localhost:3306/ecommerce?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Ho_Chi_Minh +DB_USERNAME=root +DB_PASSWORD=your_database_password +MAIL_HOST=smtp.gmail.com +MAIL_PORT=587 +MAIL_USERNAME=your_email@gmail.com +MAIL_PASSWORD=your_app_password +JWT_SECRET=your_jwt_secret +JPA_SHOW_SQL=false +JPA_FORMAT_SQL=false +JPA_DDL_AUTO=update +``` -[Click vào đây để xem chi tiết](https://ecommerce.yamiannephilim.com) +## CHẠY LOCAL -
+```bash +./mvnw spring-boot:run +``` + +Trên Windows: + +```powershell +.\mvnw.cmd spring-boot:run +``` + +## BUILD + +```bash +./mvnw clean package +``` + +File WAR sau khi build nằm tại: + +```text +target/ecommerce_project-0.0.1-SNAPSHOT.war +``` ## HÌNH ẢNH DEMO +

## VIDEO DEMO +
-[![IMAGE ALT TEXT HERE](https://img.youtube.com/vi/YXG24rEs8Q4/0.jpg)](https://youtu.be/YXG24rEs8Q4) +[![Video demo dự án thương mại điện tử](https://img.youtube.com/vi/YXG24rEs8Q4/0.jpg)](https://youtu.be/YXG24rEs8Q4)
-## CẤU HÌNH API REFRESH TOKEN -```java -// Refresh token - @GetMapping(TOKEN_VIEW + REFRESH_VIEW) - public void refreshToken(HttpServletRequest request, HttpServletResponse response) - throws StreamWriteException, DatabindException, IOException { - var header = request.getHeader(AUTHORIZATION); - // check token format in authorization header - if (header != null && header.startsWith(TOKEN_PREFIX)) { - // get token from authorization header - try { - var refreshToken = header.substring(TOKEN_PREFIX.length()); - var algorithm = HMAC256(SECRET_KEY.getBytes()); - var user = userService.getUser(require(algorithm).build().verify(refreshToken).getSubject()); - var tokens = new HashMap<>(); - tokens.put(ACCESS_TOKEN_KEY, - create().withSubject(user.getEmail()) - .withExpiresAt(new Date(currentTimeMillis() + EXPIRATION_TIME)) - .withIssuer(request.getRequestURL().toString()) - .withClaim(ROLE_CLAIM_KEY, - singleton(new Role(ROLE_PREFIX + user.getRole().getName().toUpperCase())) - .stream().map(Role::getName).collect(toList())) - .sign(algorithm)); - tokens.put(REFRESH_TOKEN_KEY, refreshToken); - response.setContentType(APPLICATION_JSON_VALUE); - new ObjectMapper().writeValue(response.getOutputStream(), tokens); - } catch (Exception e) { - var errorMsg = e.getMessage(); - response.setHeader(ERROR_HEADER_KEY, errorMsg); - response.setStatus(FORBIDDEN.value()); - var error = new HashMap<>(); - error.put(ERROR_MESSAGE_KEY, errorMsg); - response.setContentType(APPLICATION_JSON_VALUE); - new ObjectMapper().writeValue(response.getOutputStream(), error); - } - } else { - throw new RuntimeException("Refresh token is missing"); - } - } -``` +## EER DIAGRAM -## EER Diagram

-### THÀNH VIÊN +## THÀNH VIÊN + Nhóm NOHIT gồm các thành viên: @@ -79,11 +96,3 @@ Nhóm NOHIT gồm các thành viên: - Nguyễn Tiến Đạt - -### TÍCH HỢP - -
- -- Java JWT » 4.0.0 - -
diff --git a/database/ecommerce.sql b/database/ecommerce.sql index ee2dc9a..48a733a 100644 --- a/database/ecommerce.sql +++ b/database/ecommerce.sql @@ -1,3 +1,4 @@ +-- Summary: Script khởi tạo database ecommerce, bảng dữ liệu và dữ liệu mẫu cho website thương mại điện tử. -- dispose db DROP DATABASE IF EXISTS ecommerce; diff --git a/design/Ecommerce.mwb b/design/Ecommerce.mwb new file mode 100644 index 0000000..7924334 --- /dev/null +++ b/design/Ecommerce.mwb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1479e8910eb9d225361249c2129f112aa53d435bbdecfa953acb22cb7ff384c2 +size 17458 diff --git a/design/Ecommerce.png b/design/Ecommerce.png new file mode 100644 index 0000000..1a6c5a3 --- /dev/null +++ b/design/Ecommerce.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c4f94e48519f7ec46b6cb967624db2d3048587479c808b1841ebbb7d1ef047a +size 732684 diff --git a/design/Ecommerce.xmind b/design/Ecommerce.xmind new file mode 100644 index 0000000..79ca0d5 --- /dev/null +++ b/design/Ecommerce.xmind @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87b64b292058bccadc42695209fe82816f346ca514ede60a8aa3360ab7e3d1db +size 170381 diff --git a/design/Jira.mwb b/design/Jira.mwb deleted file mode 100644 index 3dde9c0..0000000 Binary files a/design/Jira.mwb and /dev/null differ diff --git a/design/Jira.png b/design/Jira.png deleted file mode 100644 index 5c04590..0000000 Binary files a/design/Jira.png and /dev/null differ diff --git a/design/Jira.xmind b/design/Jira.xmind deleted file mode 100644 index 19025c7..0000000 Binary files a/design/Jira.xmind and /dev/null differ diff --git a/pom.xml b/pom.xml index ed0fa47..f5aabe9 100644 --- a/pom.xml +++ b/pom.xml @@ -10,13 +10,14 @@ com.nohit - jira_project + ecommerce_project 0.0.1-SNAPSHOT war - jira_project - Demo project for Spring Boot + + ecommerce_project + Website thương mại điện tử xây dựng bằng Spring Boot, Thymeleaf, Spring Security và MySQL. - 11 + 17 @@ -178,4 +179,4 @@ - \ No newline at end of file + diff --git a/src/main/java/com/nohit/ecommerce_project/EcommerceProjectApplication.java b/src/main/java/com/nohit/ecommerce_project/EcommerceProjectApplication.java new file mode 100644 index 0000000..0c7a4ee --- /dev/null +++ b/src/main/java/com/nohit/ecommerce_project/EcommerceProjectApplication.java @@ -0,0 +1,14 @@ +package com.nohit.ecommerce_project; + +import org.springframework.boot.*; +import org.springframework.boot.autoconfigure.*; + +/** + * Điểm khởi chạy chính của ứng dụng thương mại điện tử Spring Boot. + */ +@SpringBootApplication +public class EcommerceProjectApplication { + public static void main(String[] args) { + SpringApplication.run(EcommerceProjectApplication.class, args); + } +} diff --git a/src/main/java/com/nohit/jira_project/ServletInitializer.java b/src/main/java/com/nohit/ecommerce_project/ServletInitializer.java similarity index 56% rename from src/main/java/com/nohit/jira_project/ServletInitializer.java rename to src/main/java/com/nohit/ecommerce_project/ServletInitializer.java index d5546b7..d05bae9 100644 --- a/src/main/java/com/nohit/jira_project/ServletInitializer.java +++ b/src/main/java/com/nohit/ecommerce_project/ServletInitializer.java @@ -1,11 +1,14 @@ -package com.nohit.jira_project; +package com.nohit.ecommerce_project; import org.springframework.boot.builder.*; import org.springframework.boot.web.servlet.support.*; +/** + * Cấu hình khởi tạo ứng dụng khi đóng gói WAR và chạy trên servlet container ngoài. + */ public class ServletInitializer extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { - return application.sources(JiraProjectApplication.class); + return application.sources(EcommerceProjectApplication.class); } } diff --git a/src/main/java/com/nohit/ecommerce_project/common/Bean.java b/src/main/java/com/nohit/ecommerce_project/common/Bean.java new file mode 100644 index 0000000..2d0a774 --- /dev/null +++ b/src/main/java/com/nohit/ecommerce_project/common/Bean.java @@ -0,0 +1,9 @@ +package com.nohit.ecommerce_project.common; + +/** + * Lưu trạng thái thông báo dùng chung giữa các controller theo thiết kế ban đầu của dự án. + */ +public class Bean { + public static String _msg; + public static boolean _isMsgShow; +} diff --git a/src/main/java/com/nohit/jira_project/config/ApplicationConfig.java b/src/main/java/com/nohit/ecommerce_project/config/ApplicationConfig.java similarity index 78% rename from src/main/java/com/nohit/jira_project/config/ApplicationConfig.java rename to src/main/java/com/nohit/ecommerce_project/config/ApplicationConfig.java index 6a3bf67..e950100 100644 --- a/src/main/java/com/nohit/jira_project/config/ApplicationConfig.java +++ b/src/main/java/com/nohit/ecommerce_project/config/ApplicationConfig.java @@ -1,10 +1,13 @@ -package com.nohit.jira_project.config; +package com.nohit.ecommerce_project.config; import org.springframework.context.annotation.*; import org.springframework.security.crypto.bcrypt.*; import org.springframework.security.crypto.password.*; import org.springframework.security.web.savedrequest.*; +/** + * Khai báo bean dùng chung cho ứng dụng, gồm PasswordEncoder và request cache không tự tạo session. + */ @Configuration public class ApplicationConfig { @Bean diff --git a/src/main/java/com/nohit/jira_project/config/WebConfig.java b/src/main/java/com/nohit/ecommerce_project/config/WebConfig.java similarity index 73% rename from src/main/java/com/nohit/jira_project/config/WebConfig.java rename to src/main/java/com/nohit/ecommerce_project/config/WebConfig.java index ceacf56..3c6d4a7 100644 --- a/src/main/java/com/nohit/jira_project/config/WebConfig.java +++ b/src/main/java/com/nohit/ecommerce_project/config/WebConfig.java @@ -1,14 +1,17 @@ -package com.nohit.jira_project.config; +package com.nohit.ecommerce_project.config; import org.springframework.boot.web.server.*; import org.springframework.boot.web.servlet.server.*; import org.springframework.context.annotation.*; import org.springframework.web.servlet.config.annotation.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; -import static com.nohit.jira_project.constant.ViewConstant.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.ViewConstant.*; import static org.springframework.http.HttpStatus.*; +/** + * Cấu hình MVC bổ sung view controller và cookie session bảo mật hơn. + */ @Configuration public class WebConfig implements WebMvcConfigurer { @Override diff --git a/src/main/java/com/nohit/jira_project/constant/ApplicationConstant.java b/src/main/java/com/nohit/ecommerce_project/constant/ApplicationConstant.java similarity index 89% rename from src/main/java/com/nohit/jira_project/constant/ApplicationConstant.java rename to src/main/java/com/nohit/ecommerce_project/constant/ApplicationConstant.java index b5739c9..19d13a1 100644 --- a/src/main/java/com/nohit/jira_project/constant/ApplicationConstant.java +++ b/src/main/java/com/nohit/ecommerce_project/constant/ApplicationConstant.java @@ -1,12 +1,15 @@ -package com.nohit.jira_project.constant; +package com.nohit.ecommerce_project.constant; import java.util.*; import static java.util.Map.*; +/** + * Tập hợp hằng số nghiệp vụ như thời hạn token, vai trò, menu, mã giảm giá và kiểu thanh toán. + */ public class ApplicationConstant { public static final long EXPIRATION_TIME = 60 * 60 * 1000; - public static final String SECRET_KEY = "secret"; + public static final String SECRET_KEY = System.getenv().getOrDefault("JWT_SECRET", "change-me-in-local-dev"); public static final String DEFAULT_ROLE = "client"; public static final String DEFAULT_STATUS = "Đang giao"; diff --git a/src/main/java/com/nohit/jira_project/constant/AttributeConstant.java b/src/main/java/com/nohit/ecommerce_project/constant/AttributeConstant.java similarity index 93% rename from src/main/java/com/nohit/jira_project/constant/AttributeConstant.java rename to src/main/java/com/nohit/ecommerce_project/constant/AttributeConstant.java index cf60d83..186dc83 100644 --- a/src/main/java/com/nohit/jira_project/constant/AttributeConstant.java +++ b/src/main/java/com/nohit/ecommerce_project/constant/AttributeConstant.java @@ -1,5 +1,8 @@ -package com.nohit.jira_project.constant; +package com.nohit.ecommerce_project.constant; +/** + * Tập hợp tên attribute/model key dùng khi truyền dữ liệu sang template Thymeleaf. + */ public class AttributeConstant { public static final String AVATAR_PREFIX = "avatar_"; public static final String TOKEN_PREFIX = "Bearer "; diff --git a/src/main/java/com/nohit/jira_project/constant/TemplateConstant.java b/src/main/java/com/nohit/ecommerce_project/constant/TemplateConstant.java similarity index 87% rename from src/main/java/com/nohit/jira_project/constant/TemplateConstant.java rename to src/main/java/com/nohit/ecommerce_project/constant/TemplateConstant.java index 6a0e6df..ded28e2 100644 --- a/src/main/java/com/nohit/jira_project/constant/TemplateConstant.java +++ b/src/main/java/com/nohit/ecommerce_project/constant/TemplateConstant.java @@ -1,5 +1,8 @@ -package com.nohit.jira_project.constant; +package com.nohit.ecommerce_project.constant; +/** + * Tập hợp tên template Thymeleaf để controller trả view nhất quán. + */ public class TemplateConstant { public static final String NOT_FOUND_TEMP = "404"; public static final String BLANK_TEMP = "blank"; diff --git a/src/main/java/com/nohit/jira_project/constant/ViewConstant.java b/src/main/java/com/nohit/ecommerce_project/constant/ViewConstant.java similarity index 93% rename from src/main/java/com/nohit/jira_project/constant/ViewConstant.java rename to src/main/java/com/nohit/ecommerce_project/constant/ViewConstant.java index 8eb60dc..968f36f 100644 --- a/src/main/java/com/nohit/jira_project/constant/ViewConstant.java +++ b/src/main/java/com/nohit/ecommerce_project/constant/ViewConstant.java @@ -1,5 +1,8 @@ -package com.nohit.jira_project.constant; +package com.nohit.ecommerce_project.constant; +/** + * Tập hợp đường dẫn route và action dùng chung trong controller/security. + */ public class ViewConstant { public static final String NOT_FOUND_VIEW = "/404"; public static final String BLANK_VIEW = "/blank"; diff --git a/src/main/java/com/nohit/jira_project/controller/ApiController.java b/src/main/java/com/nohit/ecommerce_project/controller/ApiController.java similarity index 73% rename from src/main/java/com/nohit/jira_project/controller/ApiController.java rename to src/main/java/com/nohit/ecommerce_project/controller/ApiController.java index 11abca2..1dfe86a 100644 --- a/src/main/java/com/nohit/jira_project/controller/ApiController.java +++ b/src/main/java/com/nohit/ecommerce_project/controller/ApiController.java @@ -1,39 +1,43 @@ -package com.nohit.jira_project.controller; +package com.nohit.ecommerce_project.controller; + +import lombok.*; import java.io.*; import java.util.*; import javax.servlet.http.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.web.bind.annotation.*; import com.fasterxml.jackson.core.exc.*; import com.fasterxml.jackson.databind.*; -import com.nohit.jira_project.service.*; +import com.nohit.ecommerce_project.service.*; import static com.auth0.jwt.JWT.*; import static com.auth0.jwt.algorithms.Algorithm.*; -import static com.nohit.jira_project.constant.ApplicationConstant.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; -import static com.nohit.jira_project.constant.ViewConstant.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.ViewConstant.*; import static java.lang.System.*; import static org.springframework.http.HttpHeaders.*; import static org.springframework.http.HttpStatus.*; import static org.springframework.http.MediaType.*; +/** + * REST controller xử lý refresh token và trả JWT mới cho client đã có refresh token hợp lệ. + */ @RestController @RequestMapping(API_VIEW) +@RequiredArgsConstructor public class ApiController { - @Autowired - private KhachHangService userService; + private final KhachHangService userService; - // Refresh token + // Làm mới access token. @GetMapping(TOKEN_VIEW + REFRESH_VIEW) public void refreshToken(HttpServletRequest request, HttpServletResponse response) throws StreamWriteException, DatabindException, IOException { var header = request.getHeader(AUTHORIZATION); - // Check token format in authorization header + // Kiểm tra định dạng token trong header Authorization. if (header != null && header.startsWith(TOKEN_PREFIX)) { try { var refreshToken = header.substring(TOKEN_PREFIX.length()); @@ -44,13 +48,13 @@ public void refreshToken(HttpServletRequest request, HttpServletResponse respons create().withSubject(user.getEmail()) .withExpiresAt(new Date(currentTimeMillis() + EXPIRATION_TIME)) .withIssuer(request.getRequestURL().toString()) - .withClaim(ROLE_CLAIM_KEY, ROLE_PREFIX + user.getVaiTro().toUpperCase()) + .withClaim(ROLE_CLAIM_KEY, List.of(ROLE_PREFIX + user.getVaiTro().toUpperCase())) .sign(algorithm)); tokens.put(REFRESH_TOKEN_KEY, refreshToken); response.setContentType(APPLICATION_JSON_VALUE); new ObjectMapper().writeValue(response.getOutputStream(), tokens); } catch (Exception e) { - var errorMsg = e.getMessage(); + var errorMsg = "Refresh token không hợp lệ hoặc đã hết hạn."; response.setHeader(ERROR_HEADER_KEY, errorMsg); response.setStatus(FORBIDDEN.value()); var error = new HashMap<>(); diff --git a/src/main/java/com/nohit/jira_project/controller/ApplicationController.java b/src/main/java/com/nohit/ecommerce_project/controller/ApplicationController.java similarity index 54% rename from src/main/java/com/nohit/jira_project/controller/ApplicationController.java rename to src/main/java/com/nohit/ecommerce_project/controller/ApplicationController.java index bbd799d..8d4423e 100644 --- a/src/main/java/com/nohit/jira_project/controller/ApplicationController.java +++ b/src/main/java/com/nohit/ecommerce_project/controller/ApplicationController.java @@ -1,44 +1,42 @@ -package com.nohit.jira_project.controller; +package com.nohit.ecommerce_project.controller; + +import lombok.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; -import static com.nohit.jira_project.common.Bean.*; -import static com.nohit.jira_project.constant.ApplicationConstant.Menu.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; -import static com.nohit.jira_project.constant.TemplateConstant.*; -import static com.nohit.jira_project.constant.ViewConstant.*; +import static com.nohit.ecommerce_project.common.Bean.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.Menu.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.TemplateConstant.*; +import static com.nohit.ecommerce_project.constant.ViewConstant.*; +/** + * Controller điều hướng trang chủ, đăng nhập, tìm kiếm và đăng ký nhận thông báo. + */ @Controller @RequestMapping("") +@RequiredArgsConstructor public class ApplicationController { - @Autowired - private SanPhamService sanPhamService; - - @Autowired - private TheoDoiService theoDoiService; - - @Autowired - private AuthenticationUtil authenticationUtil; - - @Autowired - private ApplicationUtil applicationUtil; + private final SanPhamService sanPhamService; + private final TheoDoiService theoDoiService; + private final AuthenticationUtil authenticationUtil; + private final ApplicationUtil applicationUtil; - // Load login + // Hiển thị trang đăng nhập. @GetMapping(LOGIN_VIEW) public ModelAndView login(boolean error) { - // check login + // Kiểm tra người dùng đã đăng nhập. if (authenticationUtil.getAccount() != null) { return new ModelAndView(REDIRECT_PREFIX + INDEX_VIEW); } else { var mav = new ModelAndView(LOGIN_TEMP); - // login failed + // Hiển thị thông báo khi đăng nhập thất bại. if (error) { _isMsgShow = true; _msg = "Tài khoản đăng nhập chưa đúng!"; @@ -49,7 +47,7 @@ public ModelAndView login(boolean error) { } } - // Load dashboard + // Hiển thị trang chủ. @GetMapping(value = { INDEX_VIEW, "/", "" }) public ModelAndView index() { var mav = new ModelAndView(INDEX_TEMP); @@ -58,19 +56,19 @@ public ModelAndView index() { mav.addObject(TITLE_PARAM, TRANG_CHU); mav.addObject(CART_PARAM, applicationUtil.getOrDefaultGioHang(client)); mav.addObject(LOGIN_PARAM, client != null); - mav.addObject(NEW_PRODUCTS_PARAM, newestProducts.subList(0, 6)); - mav.addObject(TOP_SALES_PARAM, sanPhamService.getDsSanPhamTopSale().subList(0, 3)); - mav.addObject(TOP_DISCOUNTS_PARAM, sanPhamService.getDsSanPhamDescendingDiscount().subList(0, 3)); - mav.addObject(TOP_NEWS_PARAM, newestProducts.subList(0, 3)); + mav.addObject(NEW_PRODUCTS_PARAM, applicationUtil.limit(newestProducts, 6)); + mav.addObject(TOP_SALES_PARAM, applicationUtil.limit(sanPhamService.getDsSanPhamTopSale(), 3)); + mav.addObject(TOP_DISCOUNTS_PARAM, applicationUtil.limit(sanPhamService.getDsSanPhamDescendingDiscount(), 3)); + mav.addObject(TOP_NEWS_PARAM, applicationUtil.limit(newestProducts, 3)); _isMsgShow = applicationUtil.showMessageBox(mav); return mav; } - // Add thu_phan_hoi + // Lưu thông tin đăng ký/phản hồi. @PostMapping(SUBCRIBE_VIEW) public String subcribe(TheoDoi theoDoi) { _isMsgShow = true; - // check email is already exist + // Kiểm tra email đã tồn tại. if (theoDoiService.getTheoDoi(theoDoi.getEmail()) != null) { _msg = "Email này đã được đăng ký!"; } else { @@ -80,11 +78,11 @@ public String subcribe(TheoDoi theoDoi) { return REDIRECT_PREFIX + INDEX_VIEW; } - // Load search + // Tìm sản phẩm theo tên. @GetMapping(SEARCH_VIEW) public String search(String ten) { var product = sanPhamService.getSanPham(ten); - // check if product is exist + // Kiểm tra sản phẩm còn tồn tại và còn hàng. if (product == null || product.getTonKho() < 1) { return REDIRECT_PREFIX + BLANK_VIEW; } else { @@ -92,7 +90,7 @@ public String search(String ten) { } } - // Load blank + // Hiển thị trang trống khi không tìm thấy dữ liệu phù hợp. @GetMapping(BLANK_VIEW) public ModelAndView blank() { var mav = new ModelAndView(BLANK_TEMP); @@ -100,9 +98,9 @@ public ModelAndView blank() { mav.addObject(TITLE_PARAM, CHI_TIET); mav.addObject(CART_PARAM, applicationUtil.getOrDefaultGioHang(client)); mav.addObject(LOGIN_PARAM, client != null); - mav.addObject(TOP_DISCOUNTS_PARAM, sanPhamService.getDsSanPhamDescendingDiscount().subList(0, 3)); - mav.addObject(TOP_NEWS_PARAM, sanPhamService.getDsSanPhamNewest().subList(0, 3)); - mav.addObject(TOP_SALES_PARAM, sanPhamService.getDsSanPhamTopSale().subList(0, 4)); + mav.addObject(TOP_DISCOUNTS_PARAM, applicationUtil.limit(sanPhamService.getDsSanPhamDescendingDiscount(), 3)); + mav.addObject(TOP_NEWS_PARAM, applicationUtil.limit(sanPhamService.getDsSanPhamNewest(), 3)); + mav.addObject(TOP_SALES_PARAM, applicationUtil.limit(sanPhamService.getDsSanPhamTopSale(), 4)); _isMsgShow = applicationUtil.showMessageBox(mav); return mav; } diff --git a/src/main/java/com/nohit/jira_project/controller/ChiTietSanPhamController.java b/src/main/java/com/nohit/ecommerce_project/controller/ChiTietSanPhamController.java similarity index 64% rename from src/main/java/com/nohit/jira_project/controller/ChiTietSanPhamController.java rename to src/main/java/com/nohit/ecommerce_project/controller/ChiTietSanPhamController.java index 400dd64..08a5208 100644 --- a/src/main/java/com/nohit/jira_project/controller/ChiTietSanPhamController.java +++ b/src/main/java/com/nohit/ecommerce_project/controller/ChiTietSanPhamController.java @@ -1,35 +1,33 @@ -package com.nohit.jira_project.controller; +package com.nohit.ecommerce_project.controller; + +import lombok.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; -import static com.nohit.jira_project.common.Bean.*; -import static com.nohit.jira_project.constant.ApplicationConstant.Menu.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; -import static com.nohit.jira_project.constant.TemplateConstant.*; -import static com.nohit.jira_project.constant.ViewConstant.*; +import static com.nohit.ecommerce_project.common.Bean.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.Menu.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.TemplateConstant.*; +import static com.nohit.ecommerce_project.constant.ViewConstant.*; import static java.lang.Math.*; +/** + * Controller hiển thị chi tiết sản phẩm và ghi nhận đánh giá của khách hàng. + */ @Controller @RequestMapping(DETAIL_VIEW) +@RequiredArgsConstructor public class ChiTietSanPhamController { - @Autowired - private SanPhamService sanPhamService; - - @Autowired - private NhanXetService nhanXetService; - - @Autowired - private AuthenticationUtil authenticationUtil; - - @Autowired - private ApplicationUtil applicationUtil; + private final SanPhamService sanPhamService; + private final NhanXetService nhanXetService; + private final AuthenticationUtil authenticationUtil; + private final ApplicationUtil applicationUtil; @GetMapping("") public String detail() { @@ -38,11 +36,11 @@ public String detail() { return REDIRECT_PREFIX + PRODUCT_VIEW; } - // Load detail + // Hiển thị chi tiết sản phẩm. @GetMapping(FIND_VIEW) public ModelAndView detailFind(int id) { var product = sanPhamService.getSanPham(id); - // check if product is exist + // Kiểm tra sản phẩm còn tồn tại và còn hàng. if (product == null || product.getTonKho() < 1) { _isMsgShow = true; _msg = "Sản phẩm không còn tồn tại!"; @@ -54,26 +52,26 @@ public ModelAndView detailFind(int id) { mav.addObject(CART_PARAM, applicationUtil.getOrDefaultGioHang(client)); mav.addObject(LOGIN_PARAM, client != null); mav.addObject(PRODUCT_PARAM, product); - mav.addObject(TOP_DISCOUNTS_PARAM, sanPhamService.getDsSanPhamDescendingDiscount().subList(0, 3)); - mav.addObject(TOP_NEWS_PARAM, sanPhamService.getDsSanPhamNewest().subList(0, 3)); - mav.addObject(TOP_SALES_PARAM, sanPhamService.getDsSanPhamTopSale().subList(0, 4)); + mav.addObject(TOP_DISCOUNTS_PARAM, applicationUtil.limit(sanPhamService.getDsSanPhamDescendingDiscount(), 3)); + mav.addObject(TOP_NEWS_PARAM, applicationUtil.limit(sanPhamService.getDsSanPhamNewest(), 3)); + mav.addObject(TOP_SALES_PARAM, applicationUtil.limit(sanPhamService.getDsSanPhamTopSale(), 4)); _isMsgShow = applicationUtil.showMessageBox(mav); return mav; } } - // Rate product + // Ghi nhận đánh giá sản phẩm. @PostMapping(RATE_VIEW) public String detailRate(NhanXet nhanXet, int idSanPham) { var client = authenticationUtil.getAccount(); _isMsgShow = true; - // check current account still valid + // Kiểm tra phiên đăng nhập hiện tại còn hợp lệ. if (client == null) { _msg = "Cần đăng nhập để nhận xét sản phẩm!"; return REDIRECT_PREFIX + LOGIN_VIEW; } else { var product = sanPhamService.getSanPham(idSanPham); - // check if product is exist + // Kiểm tra sản phẩm còn tồn tại và còn hàng. if (product == null || product.getTonKho() < 1) { _msg = "Sản phẩm không còn tồn tại!"; return REDIRECT_PREFIX + PRODUCT_VIEW; @@ -81,7 +79,7 @@ public String detailRate(NhanXet nhanXet, int idSanPham) { var votes = product.getDsNhanXet(); var votesSize = votes.size(); var rate = 0; - // get all danh_gia of product + // Tính tổng điểm đánh giá hiện có của sản phẩm. for (var i = 0; i < votesSize; i++) { rate += votes.get(i).getDanhGia(); } diff --git a/src/main/java/com/nohit/jira_project/controller/DangKyController.java b/src/main/java/com/nohit/ecommerce_project/controller/DangKyController.java similarity index 53% rename from src/main/java/com/nohit/jira_project/controller/DangKyController.java rename to src/main/java/com/nohit/ecommerce_project/controller/DangKyController.java index a5b90de..0e90903 100644 --- a/src/main/java/com/nohit/jira_project/controller/DangKyController.java +++ b/src/main/java/com/nohit/ecommerce_project/controller/DangKyController.java @@ -1,43 +1,39 @@ -package com.nohit.jira_project.controller; +package com.nohit.ecommerce_project.controller; + +import lombok.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; -import static com.nohit.jira_project.common.Bean.*; -import static com.nohit.jira_project.constant.ApplicationConstant.*; -import static com.nohit.jira_project.constant.ApplicationConstant.Menu.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; -import static com.nohit.jira_project.constant.TemplateConstant.*; -import static com.nohit.jira_project.constant.ViewConstant.*; +import static com.nohit.ecommerce_project.common.Bean.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.Menu.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.TemplateConstant.*; +import static com.nohit.ecommerce_project.constant.ViewConstant.*; +/** + * Controller xử lý màn hình đăng ký tài khoản khách hàng mới. + */ @Controller @RequestMapping(REGISTER_VIEW) +@RequiredArgsConstructor public class DangKyController { - @Autowired - private KhachHangService khachHangService; - - @Autowired - private GioHangService gioHangService; - - @Autowired - private CreditCardService creditCardService; - - @Autowired - private AuthenticationUtil authenticationUtil; - - @Autowired - private ApplicationUtil applicationUtil; + private final KhachHangService khachHangService; + private final GioHangService gioHangService; + private final CreditCardService creditCardService; + private final AuthenticationUtil authenticationUtil; + private final ApplicationUtil applicationUtil; - // Load register + // Hiển thị trang đăng ký. @GetMapping("") public ModelAndView register() { - // check login + // Kiểm tra người dùng đã đăng nhập. if (authenticationUtil.getAccount() != null) { return new ModelAndView(REDIRECT_PREFIX + INDEX_VIEW); } else { @@ -48,11 +44,11 @@ public ModelAndView register() { } } - // Register + // Xử lý đăng ký tài khoản. @PostMapping("") public String register(KhachHang khachHang) { _isMsgShow = true; - // check email is already exist + // Kiểm tra email đã tồn tại. if (khachHangService.getKhachHang(khachHang.getEmail()) != null) { _msg = "Email này đã được đăng ký!"; return REDIRECT_PREFIX + REGISTER_VIEW; diff --git a/src/main/java/com/nohit/ecommerce_project/controller/DonHangController.java b/src/main/java/com/nohit/ecommerce_project/controller/DonHangController.java new file mode 100644 index 0000000..f133cae --- /dev/null +++ b/src/main/java/com/nohit/ecommerce_project/controller/DonHangController.java @@ -0,0 +1,53 @@ +package com.nohit.ecommerce_project.controller; + +import lombok.*; + +import org.springframework.stereotype.*; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.*; + +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; + +import static com.nohit.ecommerce_project.common.Bean.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.Menu.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.TemplateConstant.*; +import static com.nohit.ecommerce_project.constant.ViewConstant.*; + +/** + * Controller hiển thị danh sách đơn hàng của khách hàng đang đăng nhập. + */ +@Controller +@RequestMapping(ORDER_VIEW) +@RequiredArgsConstructor +public class DonHangController { + private final DonHangService donHangService; + private final AuthenticationUtil authenticationUtil; + private final ApplicationUtil applicationUtil; + + @GetMapping("") + public String order() { + _isMsgShow = true; + _msg = "Cần chọn 1 đơn hàng để xem!"; + return REDIRECT_PREFIX + HISTORY_VIEW; + } + + // Hiển thị danh sách đơn hàng. + @GetMapping(FIND_VIEW) + public ModelAndView orderFind(int id) { + var client = authenticationUtil.getAccount(); + // Kiểm tra phiên đăng nhập hiện tại còn hợp lệ. + if (client == null) { + return new ModelAndView(REDIRECT_PREFIX + LOGOUT_VIEW); + } else { + var mav = new ModelAndView(ORDER_TEMP); + mav.addObject(TITLE_PARAM, DON_HANG); + mav.addObject(CART_PARAM, applicationUtil.getOrDefaultGioHang(client)); + mav.addObject(LOGIN_PARAM, client != null); + mav.addObject(ORDER_PARAM, donHangService.getDonHang(id)); + _isMsgShow = applicationUtil.showMessageBox(mav); + return mav; + } + } +} diff --git a/src/main/java/com/nohit/jira_project/controller/GioHangController.java b/src/main/java/com/nohit/ecommerce_project/controller/GioHangController.java similarity index 68% rename from src/main/java/com/nohit/jira_project/controller/GioHangController.java rename to src/main/java/com/nohit/ecommerce_project/controller/GioHangController.java index b62d93c..88d01c0 100644 --- a/src/main/java/com/nohit/jira_project/controller/GioHangController.java +++ b/src/main/java/com/nohit/ecommerce_project/controller/GioHangController.java @@ -1,69 +1,61 @@ -package com.nohit.jira_project.controller; +package com.nohit.ecommerce_project.controller; + +import lombok.*; import java.util.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; - -import lombok.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; -import static com.nohit.jira_project.common.Bean.*; -import static com.nohit.jira_project.constant.ApplicationConstant.*; -import static com.nohit.jira_project.constant.ApplicationConstant.Menu.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; -import static com.nohit.jira_project.constant.TemplateConstant.*; -import static com.nohit.jira_project.constant.ViewConstant.*; +import static com.nohit.ecommerce_project.common.Bean.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.Menu.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.TemplateConstant.*; +import static com.nohit.ecommerce_project.constant.ViewConstant.*; import static org.springframework.web.bind.annotation.RequestMethod.*; +/** + * Controller quản lý giỏ hàng, mã giảm giá, phí vận chuyển và số lượng sản phẩm. + */ @Controller @RequestMapping(CART_VIEW) +@RequiredArgsConstructor public class GioHangController { - @Autowired - private SanPhamService sanPhamService; - - @Autowired - private GioHangService gioHangService; - - @Autowired - private ChiTietGioHangService chiTietGioHangService; - - @Autowired - private TinhThanhService tinhThanhService; - - @Autowired - private AuthenticationUtil authenticationUtil; - - @Autowired - private ApplicationUtil applicationUtil; - - // Load cart + private final SanPhamService sanPhamService; + private final GioHangService gioHangService; + private final ChiTietGioHangService chiTietGioHangService; + private final TinhThanhService tinhThanhService; + private final AuthenticationUtil authenticationUtil; + private final ApplicationUtil applicationUtil; + + // Hiển thị giỏ hàng. @GetMapping("") public ModelAndView cart() { var client = authenticationUtil.getAccount(); - // Check current account still valid + // Kiểm tra phiên đăng nhập hiện tại còn hợp lệ. if (client == null) { return new ModelAndView(LOGIN_TEMP); } else { var mav = new ModelAndView(CART_TEMP); - var cart = client.getGioHang(); + var cart = applicationUtil.getOrDefaultGioHang(client); var productsCount = cart.getTongSoLuong(); var inventories = new ArrayList<>(); - // get ton_kho each product + // Lấy tồn kho của từng sản phẩm trong giỏ. for (var item : cart.getDsChiTietGioHang()) { inventories.add(item.getSanPham().getTonKho()); } mav.addObject(TITLE_PARAM, GIO_HANG); mav.addObject(CART_PARAM, cart); mav.addObject(LOGIN_PARAM, client != null); - mav.addObject(TOP_DISCOUNTS_PARAM, sanPhamService.getDsSanPhamDescendingDiscount().subList(0, 3)); - mav.addObject(TOP_NEWS_PARAM, sanPhamService.getDsSanPhamNewest().subList(0, 3)); - mav.addObject(TOP_SALES_PARAM, sanPhamService.getDsSanPhamTopSale().subList(0, 2)); + mav.addObject(TOP_DISCOUNTS_PARAM, applicationUtil.limit(sanPhamService.getDsSanPhamDescendingDiscount(), 3)); + mav.addObject(TOP_NEWS_PARAM, applicationUtil.limit(sanPhamService.getDsSanPhamNewest(), 3)); + mav.addObject(TOP_SALES_PARAM, applicationUtil.limit(sanPhamService.getDsSanPhamTopSale(), 2)); mav.addObject(PROVINCES_PARAM, tinhThanhService.getDsTinhThanh()); mav.addObject(COUPON_PARAM, productsCount < 1 ? 0 : cart.getGiamGia()); mav.addObject(SHIPFEE_PARAM, productsCount < 1 ? 0 : cart.getTinhThanh().getChiPhiVanChuyen()); @@ -73,24 +65,24 @@ public ModelAndView cart() { } } - // Add to cart + // Thêm sản phẩm vào giỏ hàng. @RequestMapping(value = ADD_VIEW + PRODUCT_VIEW, method = { GET, POST }) public String cartAddProduct(int id, int soLuongSanPham) { var client = authenticationUtil.getAccount(); - // Check current account still valid + // Kiểm tra phiên đăng nhập hiện tại còn hợp lệ. if (client == null) { return REDIRECT_PREFIX + LOGOUT_VIEW; } else { var cart = applicationUtil.getOrDefaultGioHang(client); var product = sanPhamService.getSanPham(id); _isMsgShow = true; - // check if product is exist + // Kiểm tra sản phẩm còn tồn tại và còn hàng. if (product == null || product.getTonKho() < 1) { _msg = "Sản phẩm không còn tồn tại!"; return REDIRECT_PREFIX + PRODUCT_VIEW; } else { var idCartDetail = new ChiTietGioHangId(client.getId(), id); - // chech chi_tiet_gio_hang exist + // Kiểm tra sản phẩm đã có trong giỏ hàng. if (chiTietGioHangService.getChiTietGioHang(idCartDetail) != null) { _msg = "Sản phẩm đã tồn tại trong giỏ hàng!"; } else { @@ -109,18 +101,18 @@ public String cartAddProduct(int id, int soLuongSanPham) { } } - // Update coupon + // Cập nhật mã giảm giá. @RequestMapping(value = EDIT_VIEW + COUPON_VIEW, method = { GET, PUT }) public String cartEditCoupon(String maGiamGia) { var client = authenticationUtil.getAccount(); - // Check current account still valid + // Kiểm tra phiên đăng nhập hiện tại còn hợp lệ. if (client == null) { return REDIRECT_PREFIX + LOGOUT_VIEW; } else { var cart = applicationUtil.getOrDefaultGioHang(client); - var coupon = COUPON_MAP.get(maGiamGia); + var coupon = maGiamGia == null ? null : COUPON_MAP.get(maGiamGia.trim().toLowerCase()); _isMsgShow = true; - // check coupon + // Kiểm tra mã giảm giá. if (coupon == null) { _msg = "Mã giảm giá chưa chính xác!"; } else { @@ -132,11 +124,11 @@ public String cartEditCoupon(String maGiamGia) { } } - // Update ship fee + // Cập nhật phí vận chuyển. @RequestMapping(value = EDIT_VIEW + SHIP_FEE_VIEW, method = { GET, PUT }) public String cartEditShipFee(int id, String huyenQuan) { var client = authenticationUtil.getAccount(); - // Check current account still valid + // Kiểm tra phiên đăng nhập hiện tại còn hợp lệ. if (client == null) { return REDIRECT_PREFIX + LOGOUT_VIEW; } else { @@ -150,19 +142,24 @@ public String cartEditShipFee(int id, String huyenQuan) { } } - // Update cart + // Cập nhật giỏ hàng. @RequestMapping(value = SAVE_VIEW, method = { GET, PUT }) public String cartSave(int[] soSanPham) { var client = authenticationUtil.getAccount(); - // Check current account still valid + // Kiểm tra phiên đăng nhập hiện tại còn hợp lệ. if (client == null) { return REDIRECT_PREFIX + LOGOUT_VIEW; } else { var cart = applicationUtil.getOrDefaultGioHang(client); + if (soSanPham == null || soSanPham.length < cart.getDsChiTietGioHang().size()) { + _isMsgShow = true; + _msg = "Dữ liệu cập nhật giỏ hàng chưa hợp lệ!"; + return REDIRECT_PREFIX + CART_VIEW; + } var productsCount = 0; var cartTotal = 0; var index = 0; - // update chi_tiet_gio_hang + // Cập nhật từng dòng chi tiết giỏ hàng. for (var item : cart.getDsChiTietGioHang()) { item.setSoLuongSanPham(soSanPham[index]); item = chiTietGioHangService.saveChiTietGioHang(item); @@ -179,17 +176,22 @@ public String cartSave(int[] soSanPham) { } } - // Delete chi_tiet_gio_hang + // Xóa dòng chi tiết giỏ hàng. @RequestMapping(value = DELETE_VIEW + PRODUCT_VIEW, method = { GET, DELETE }) public String cartDeleteProduct(int id) { var client = authenticationUtil.getAccount(); - // Check current account still valid + // Kiểm tra phiên đăng nhập hiện tại còn hợp lệ. if (client == null) { return REDIRECT_PREFIX + LOGOUT_VIEW; } else { var cart = applicationUtil.getOrDefaultGioHang(client); var idCartDetail = new ChiTietGioHangId(client.getId(), id); var cartDetail = chiTietGioHangService.getChiTietGioHang(idCartDetail); + if (cartDetail == null) { + _isMsgShow = true; + _msg = "Sản phẩm không còn trong giỏ hàng!"; + return REDIRECT_PREFIX + CART_VIEW; + } cart.setTongGioHang(cart.getTongGioHang() - cartDetail.getTongTienSanPham()); cart.setTongSoLuong(cart.getTongSoLuong() - cartDetail.getSoLuongSanPham()); cart = gioHangService.saveGioHang(cart); diff --git a/src/main/java/com/nohit/ecommerce_project/controller/GioiThieuController.java b/src/main/java/com/nohit/ecommerce_project/controller/GioiThieuController.java new file mode 100644 index 0000000..066a1f3 --- /dev/null +++ b/src/main/java/com/nohit/ecommerce_project/controller/GioiThieuController.java @@ -0,0 +1,38 @@ +package com.nohit.ecommerce_project.controller; + +import lombok.*; + +import org.springframework.stereotype.*; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.*; + +import com.nohit.ecommerce_project.util.*; + +import static com.nohit.ecommerce_project.common.Bean.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.Menu.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.TemplateConstant.*; +import static com.nohit.ecommerce_project.constant.ViewConstant.*; + +/** + * Controller hiển thị trang giới thiệu nhóm và thông tin dự án. + */ +@Controller +@RequestMapping(ABOUT_VIEW) +@RequiredArgsConstructor +public class GioiThieuController { + private final ApplicationUtil applicationUtil; + private final AuthenticationUtil authenticationUtil; + + // Hiển thị trang giới thiệu. + @GetMapping("") + public ModelAndView about() { + var mav = new ModelAndView(ABOUT_TEMP); + var client = authenticationUtil.getAccount(); + mav.addObject(TITLE_PARAM, GIOI_THIEU); + mav.addObject(CART_PARAM, applicationUtil.getOrDefaultGioHang(client)); + mav.addObject(LOGIN_PARAM, client != null); + _isMsgShow = applicationUtil.showMessageBox(mav); + return mav; + } +} diff --git a/src/main/java/com/nohit/jira_project/controller/HoSoController.java b/src/main/java/com/nohit/ecommerce_project/controller/HoSoController.java similarity index 63% rename from src/main/java/com/nohit/jira_project/controller/HoSoController.java rename to src/main/java/com/nohit/ecommerce_project/controller/HoSoController.java index 1510f87..e3697cb 100644 --- a/src/main/java/com/nohit/jira_project/controller/HoSoController.java +++ b/src/main/java/com/nohit/ecommerce_project/controller/HoSoController.java @@ -1,56 +1,48 @@ -package com.nohit.jira_project.controller; +package com.nohit.ecommerce_project.controller; + +import lombok.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.security.crypto.password.*; import org.springframework.stereotype.*; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; -import lombok.*; - -import static com.nohit.jira_project.common.Bean.*; -import static com.nohit.jira_project.constant.ApplicationConstant.Menu.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; -import static com.nohit.jira_project.constant.TemplateConstant.*; -import static com.nohit.jira_project.constant.ViewConstant.*; +import static com.nohit.ecommerce_project.common.Bean.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.Menu.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.TemplateConstant.*; +import static com.nohit.ecommerce_project.constant.ViewConstant.*; import static org.springframework.web.bind.annotation.RequestMethod.*; +/** + * Controller quản lý hồ sơ, mật khẩu và thông tin thẻ của khách hàng. + */ @Controller @RequestMapping(PROFILE_VIEW) +@RequiredArgsConstructor public class HoSoController { - @Autowired - private KhachHangService khachHangService; - - @Autowired - private CreditCardService creditCardService; - - @Autowired - private TinhThanhService tinhThanhService; - - @Autowired - private AuthenticationUtil authenticationUtil; - - @Autowired - private ApplicationUtil applicationUtil; - - @Autowired - private PasswordEncoder passwordEncoder; + private final KhachHangService khachHangService; + private final CreditCardService creditCardService; + private final TinhThanhService tinhThanhService; + private final AuthenticationUtil authenticationUtil; + private final ApplicationUtil applicationUtil; + private final PasswordEncoder passwordEncoder; - // Load profile + // Hiển thị hồ sơ khách hàng. @GetMapping("") public ModelAndView profile() { var client = authenticationUtil.getAccount(); - // Check current account still valid + // Kiểm tra phiên đăng nhập hiện tại còn hợp lệ. if (client == null) { return new ModelAndView(REDIRECT_PREFIX + LOGOUT_VIEW); } else { var mav = new ModelAndView(PROFILE_TEMP); mav.addObject(TITLE_PARAM, THONG_TIN); - mav.addObject(CART_PARAM, client.getGioHang()); + mav.addObject(CART_PARAM, applicationUtil.getOrDefaultGioHang(client)); mav.addObject(LOGIN_PARAM, client != null); mav.addObject(CLIENT_PARAM, client); mav.addObject(CREDIT_CARD_PARAM, client.getCreditCard()); @@ -60,10 +52,10 @@ public ModelAndView profile() { } } - // Update info + // Cập nhật thông tin cá nhân. @RequestMapping(value = INFO_VIEW, method = { GET, PUT }) public String profileInfo(KhachHang khachHang) { - // Check current account still valid + // Kiểm tra phiên đăng nhập hiện tại còn hợp lệ. if (authenticationUtil.getAccount() == null) { return REDIRECT_PREFIX + LOGOUT_VIEW; } else { @@ -74,16 +66,16 @@ public String profileInfo(KhachHang khachHang) { } } - // Update password + // Cập nhật mật khẩu. @PostMapping(PASSWORD_VIEW) public String profilePassword(String oldPassword, String newPassword, String rePassword) { var client = authenticationUtil.getAccount(); - // Check current account still valid + // Kiểm tra phiên đăng nhập hiện tại còn hợp lệ. if (client == null) { return REDIRECT_PREFIX + LOGOUT_VIEW; } else { _isMsgShow = true; - // check valid password + // Kiểm tra mật khẩu cũ và xác nhận mật khẩu mới. if (passwordEncoder.matches(oldPassword, client.getMatKhau()) && rePassword.equals(newPassword)) { khachHangService.updatePassword(client.getId(), newPassword); _msg = "Mật khẩu đã được cập nhật thành công!"; @@ -94,10 +86,10 @@ public String profilePassword(String oldPassword, String newPassword, String reP } } - // Update card + // Cập nhật thông tin thẻ. @PostMapping(CARD_VIEW) public String profileCard(CreditCard creditCard) { - // Check current account still valid + // Kiểm tra phiên đăng nhập hiện tại còn hợp lệ. if (authenticationUtil.getAccount() == null) { return REDIRECT_PREFIX + LOGOUT_VIEW; } else { diff --git a/src/main/java/com/nohit/ecommerce_project/controller/LichSuController.java b/src/main/java/com/nohit/ecommerce_project/controller/LichSuController.java new file mode 100644 index 0000000..65a94d9 --- /dev/null +++ b/src/main/java/com/nohit/ecommerce_project/controller/LichSuController.java @@ -0,0 +1,44 @@ +package com.nohit.ecommerce_project.controller; + +import lombok.*; + +import org.springframework.stereotype.*; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.*; + +import com.nohit.ecommerce_project.util.*; + +import static com.nohit.ecommerce_project.common.Bean.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.Menu.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.TemplateConstant.*; +import static com.nohit.ecommerce_project.constant.ViewConstant.*; + +/** + * Controller hiển thị lịch sử mua hàng của khách hàng. + */ +@Controller +@RequestMapping(HISTORY_VIEW) +@RequiredArgsConstructor +public class LichSuController { + private final AuthenticationUtil authenticationUtil; + private final ApplicationUtil applicationUtil; + + // Hiển thị lịch sử mua hàng. + @GetMapping("") + public ModelAndView history() { + var client = authenticationUtil.getAccount(); + // Kiểm tra phiên đăng nhập hiện tại còn hợp lệ. + if (client == null) { + return new ModelAndView(REDIRECT_PREFIX + LOGOUT_VIEW); + } else { + var mav = new ModelAndView(HISTORY_TEMP); + mav.addObject(TITLE_PARAM, LICH_SU); + mav.addObject(CART_PARAM, applicationUtil.getOrDefaultGioHang(client)); + mav.addObject(LOGIN_PARAM, client != null); + mav.addObject(ORDERS_PARAM, client.getDsDonHang()); + _isMsgShow = applicationUtil.showMessageBox(mav); + return mav; + } + } +} diff --git a/src/main/java/com/nohit/jira_project/controller/LienHeController.java b/src/main/java/com/nohit/ecommerce_project/controller/LienHeController.java similarity index 51% rename from src/main/java/com/nohit/jira_project/controller/LienHeController.java rename to src/main/java/com/nohit/ecommerce_project/controller/LienHeController.java index 7a047a4..ca7a462 100644 --- a/src/main/java/com/nohit/jira_project/controller/LienHeController.java +++ b/src/main/java/com/nohit/ecommerce_project/controller/LienHeController.java @@ -1,33 +1,33 @@ -package com.nohit.jira_project.controller; +package com.nohit.ecommerce_project.controller; + +import lombok.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; -import static com.nohit.jira_project.common.Bean.*; -import static com.nohit.jira_project.constant.ApplicationConstant.Menu.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; -import static com.nohit.jira_project.constant.TemplateConstant.*; -import static com.nohit.jira_project.constant.ViewConstant.*; +import static com.nohit.ecommerce_project.common.Bean.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.Menu.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.TemplateConstant.*; +import static com.nohit.ecommerce_project.constant.ViewConstant.*; +/** + * Controller hiển thị trang liên hệ và lưu thư phản hồi từ khách hàng. + */ @Controller @RequestMapping(CONTACT_VIEW) +@RequiredArgsConstructor public class LienHeController { - @Autowired - private ThuPhanHoiService thuPhanHoiService; - - @Autowired - private ApplicationUtil applicationUtil; - - @Autowired - private AuthenticationUtil authenticationUtil; + private final ThuPhanHoiService thuPhanHoiService; + private final ApplicationUtil applicationUtil; + private final AuthenticationUtil authenticationUtil; - // Load contact + // Hiển thị trang liên hệ. @GetMapping("") public ModelAndView contact() { var mav = new ModelAndView(CONTACT_TEMP); @@ -40,7 +40,7 @@ public ModelAndView contact() { return mav; } - // Add thu_phan_hoi + // Lưu thông tin đăng ký/phản hồi. @PostMapping("") public String contact(ThuPhanHoi thuPhanHoi) { thuPhanHoiService.saveThuPhanHoi(thuPhanHoi); diff --git a/src/main/java/com/nohit/jira_project/controller/MatKhauController.java b/src/main/java/com/nohit/ecommerce_project/controller/MatKhauController.java similarity index 55% rename from src/main/java/com/nohit/jira_project/controller/MatKhauController.java rename to src/main/java/com/nohit/ecommerce_project/controller/MatKhauController.java index 269caaf..f684650 100644 --- a/src/main/java/com/nohit/jira_project/controller/MatKhauController.java +++ b/src/main/java/com/nohit/ecommerce_project/controller/MatKhauController.java @@ -1,33 +1,35 @@ -package com.nohit.jira_project.controller; +package com.nohit.ecommerce_project.controller; + +import lombok.*; import java.io.*; import javax.mail.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.*; -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; -import static com.nohit.jira_project.common.Bean.*; -import static com.nohit.jira_project.constant.ApplicationConstant.Menu.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; -import static com.nohit.jira_project.constant.TemplateConstant.*; -import static com.nohit.jira_project.constant.ViewConstant.*; +import static com.nohit.ecommerce_project.common.Bean.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.Menu.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.TemplateConstant.*; +import static com.nohit.ecommerce_project.constant.ViewConstant.*; +/** + * Controller xử lý luồng quên mật khẩu và gửi mật khẩu mới qua email. + */ @Controller @RequestMapping(PASSWORD_RESET_VIEW) +@RequiredArgsConstructor public class MatKhauController { - @Autowired - private KhachHangService khachHangService; - - @Autowired - private ApplicationUtil applicationUtil; + private final KhachHangService khachHangService; + private final ApplicationUtil applicationUtil; - // Load password-reset + // Hiển thị trang quên mật khẩu. @GetMapping("") public ModelAndView resetPassword() { var mav = new ModelAndView(PASSWORD_RESET_TEMP); @@ -36,11 +38,11 @@ public ModelAndView resetPassword() { return mav; } - // Reset password + // Xử lý đặt lại mật khẩu. @PostMapping("") public String resetPassword(String email) throws UnsupportedEncodingException, MessagingException { _isMsgShow = true; - // check email is already exist + // Kiểm tra email đã tồn tại. if (khachHangService.getKhachHang(email) == null) { _msg = "Email này chưa được đăng ký!"; return REDIRECT_PREFIX + PASSWORD_RESET_VIEW; diff --git a/src/main/java/com/nohit/jira_project/controller/PhanLoaiController.java b/src/main/java/com/nohit/ecommerce_project/controller/PhanLoaiController.java similarity index 64% rename from src/main/java/com/nohit/jira_project/controller/PhanLoaiController.java rename to src/main/java/com/nohit/ecommerce_project/controller/PhanLoaiController.java index ea7807f..2e9ad9c 100644 --- a/src/main/java/com/nohit/jira_project/controller/PhanLoaiController.java +++ b/src/main/java/com/nohit/ecommerce_project/controller/PhanLoaiController.java @@ -1,47 +1,45 @@ -package com.nohit.jira_project.controller; +package com.nohit.ecommerce_project.controller; + +import lombok.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.*; -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; -import static com.nohit.jira_project.common.Bean.*; -import static com.nohit.jira_project.constant.ApplicationConstant.*; -import static com.nohit.jira_project.constant.ApplicationConstant.Menu.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; -import static com.nohit.jira_project.constant.TemplateConstant.*; -import static com.nohit.jira_project.constant.ViewConstant.*; +import static com.nohit.ecommerce_project.common.Bean.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.Menu.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.TemplateConstant.*; +import static com.nohit.ecommerce_project.constant.ViewConstant.*; +/** + * Controller hiển thị, lọc và phân trang sản phẩm theo phân loại. + */ @Controller @RequestMapping(CATEGORY_VIEW) +@RequiredArgsConstructor public class PhanLoaiController { - @Autowired - private SanPhamService sanPhamService; - - @Autowired - private AuthenticationUtil authenticationUtil; - - @Autowired - private ApplicationUtil applicationUtil; + private final SanPhamService sanPhamService; + private final AuthenticationUtil authenticationUtil; + private final ApplicationUtil applicationUtil; - // Load category + // Hiển thị trang phân loại. @GetMapping("") public ModelAndView category() { var mav = new ModelAndView(CATEGORY_TEMP); var client = authenticationUtil.getAccount(); var products = sanPhamService.getDsSanPhamTonKho(); - var maxProducts = products.size(); - var maxSize = (maxProducts - 1) / DEFAULT_SIZE_PAGE + 1; + var maxSize = applicationUtil.maxPage(products, DEFAULT_SIZE_PAGE); mav.addObject(TITLE_PARAM, PHAN_LOAI); mav.addObject(CART_PARAM, applicationUtil.getOrDefaultGioHang(client)); mav.addObject(LOGIN_PARAM, client != null); - mav.addObject(PRODUCTS_PARAM, - products.subList(0, maxProducts < DEFAULT_SIZE_PAGE ? maxProducts : DEFAULT_SIZE_PAGE)); + mav.addObject(PRODUCTS_PARAM, applicationUtil.limit(products, DEFAULT_SIZE_PAGE)); mav.addObject(RADIO_CHECK_PARAM, DEFAULT_CATEGORY); - mav.addObject(MAX_SIZE_PARAM, (maxProducts - 1) / DEFAULT_SIZE_PAGE + 1); + mav.addObject(MAX_SIZE_PARAM, maxSize); mav.addObject(VIEW_PARAM, PAGE_VIEW + "?page="); mav.addObject(PREVIOUS_PARAM, PAGE_VIEW + "?page=" + 1); mav.addObject(NEXT_PARAM, PAGE_VIEW + "?page=" + (2 > maxSize ? maxSize : 2)); @@ -49,22 +47,19 @@ public ModelAndView category() { return mav; } - // Load category from page + // Hiển thị phân loại theo trang. @GetMapping(PAGE_VIEW) public ModelAndView category(int page) { var mav = new ModelAndView(CATEGORY_TEMP); var client = authenticationUtil.getAccount(); var products = sanPhamService.getDsSanPhamTonKho(); - var maxProducts = products.size(); - var maxPage = page * DEFAULT_SIZE_PAGE; - var maxSize = (maxProducts - 1) / DEFAULT_SIZE_PAGE + 1; + var maxSize = applicationUtil.maxPage(products, DEFAULT_SIZE_PAGE); var previous = page - 1; var next = page + 1; mav.addObject(TITLE_PARAM, PHAN_LOAI); mav.addObject(CART_PARAM, applicationUtil.getOrDefaultGioHang(client)); mav.addObject(LOGIN_PARAM, client != null); - mav.addObject(PRODUCTS_PARAM, - products.subList((page - 1) * DEFAULT_SIZE_PAGE, maxPage > maxProducts ? maxProducts : maxPage)); + mav.addObject(PRODUCTS_PARAM, applicationUtil.page(products, page, DEFAULT_SIZE_PAGE)); mav.addObject(RADIO_CHECK_PARAM, DEFAULT_CATEGORY); mav.addObject(MAX_SIZE_PARAM, maxSize); mav.addObject(VIEW_PARAM, PAGE_VIEW + "?page="); @@ -74,21 +69,19 @@ public ModelAndView category(int page) { return mav; } - // Load filter products + // Hiển thị sản phẩm theo bộ lọc phân loại. @GetMapping(FILTER_VIEW) public ModelAndView categoryFilter(String filter) { var mav = new ModelAndView(CATEGORY_TEMP); var client = authenticationUtil.getAccount(); var products = sanPhamService.getDsSanPham(filter); - var maxProducts = products.size(); - var maxSize = (maxProducts - 1) / DEFAULT_SIZE_PAGE + 1; + var maxSize = applicationUtil.maxPage(products, DEFAULT_SIZE_PAGE); mav.addObject(TITLE_PARAM, PHAN_LOAI); mav.addObject(CART_PARAM, applicationUtil.getOrDefaultGioHang(client)); mav.addObject(LOGIN_PARAM, client != null); - mav.addObject(PRODUCTS_PARAM, - products.subList(0, maxProducts < DEFAULT_SIZE_PAGE ? maxProducts : DEFAULT_SIZE_PAGE)); + mav.addObject(PRODUCTS_PARAM, applicationUtil.limit(products, DEFAULT_SIZE_PAGE)); mav.addObject(RADIO_CHECK_PARAM, CATEGORIES_MAP.get(filter)); - mav.addObject(MAX_SIZE_PARAM, (maxProducts - 1) / DEFAULT_SIZE_PAGE + 1); + mav.addObject(MAX_SIZE_PARAM, maxSize); mav.addObject(VIEW_PARAM, FILTER_VIEW + PAGE_VIEW + "?filter=" + filter + "&page="); mav.addObject(PREVIOUS_PARAM, FILTER_VIEW + PAGE_VIEW + "?filter=" + filter + "&page=" + 1); mav.addObject(NEXT_PARAM, @@ -97,22 +90,19 @@ public ModelAndView categoryFilter(String filter) { return mav; } - // Load filter products from page + // Hiển thị sản phẩm theo bộ lọc phân loại ở trang cụ thể. @GetMapping(FILTER_VIEW + PAGE_VIEW) public ModelAndView categoryFilter(String filter, int page) { var mav = new ModelAndView(CATEGORY_TEMP); var client = authenticationUtil.getAccount(); var products = sanPhamService.getDsSanPham(filter); - var maxProducts = products.size(); - var maxPage = page * DEFAULT_SIZE_PAGE; - var maxSize = (maxProducts - 1) / DEFAULT_SIZE_PAGE + 1; + var maxSize = applicationUtil.maxPage(products, DEFAULT_SIZE_PAGE); var previous = page - 1; var next = page + 1; mav.addObject(TITLE_PARAM, PHAN_LOAI); mav.addObject(CART_PARAM, applicationUtil.getOrDefaultGioHang(client)); mav.addObject(LOGIN_PARAM, client != null); - mav.addObject(PRODUCTS_PARAM, - products.subList((page - 1) * DEFAULT_SIZE_PAGE, maxPage > maxProducts ? maxProducts : maxPage)); + mav.addObject(PRODUCTS_PARAM, applicationUtil.page(products, page, DEFAULT_SIZE_PAGE)); mav.addObject(RADIO_CHECK_PARAM, CATEGORIES_MAP.get(filter)); mav.addObject(MAX_SIZE_PARAM, maxSize); mav.addObject(VIEW_PARAM, FILTER_VIEW + PAGE_VIEW + "?filter=" + filter + "&page="); diff --git a/src/main/java/com/nohit/jira_project/controller/SanPhamController.java b/src/main/java/com/nohit/ecommerce_project/controller/SanPhamController.java similarity index 66% rename from src/main/java/com/nohit/jira_project/controller/SanPhamController.java rename to src/main/java/com/nohit/ecommerce_project/controller/SanPhamController.java index 0e73c3c..b137769 100644 --- a/src/main/java/com/nohit/jira_project/controller/SanPhamController.java +++ b/src/main/java/com/nohit/ecommerce_project/controller/SanPhamController.java @@ -1,50 +1,48 @@ -package com.nohit.jira_project.controller; +package com.nohit.ecommerce_project.controller; + +import lombok.*; import java.util.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; -import static com.nohit.jira_project.common.Bean.*; -import static com.nohit.jira_project.constant.ApplicationConstant.*; -import static com.nohit.jira_project.constant.ApplicationConstant.Menu.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; -import static com.nohit.jira_project.constant.TemplateConstant.*; -import static com.nohit.jira_project.constant.ViewConstant.*; +import static com.nohit.ecommerce_project.common.Bean.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.Menu.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.TemplateConstant.*; +import static com.nohit.ecommerce_project.constant.ViewConstant.*; +/** + * Controller hiển thị, sắp xếp và phân trang danh sách sản phẩm. + */ @Controller @RequestMapping(PRODUCT_VIEW) +@RequiredArgsConstructor public class SanPhamController { - @Autowired - private AuthenticationUtil authenticationUtil; - - @Autowired - private SanPhamService sanPhamService; - - @Autowired - private ApplicationUtil applicationUtil; + private final AuthenticationUtil authenticationUtil; + private final SanPhamService sanPhamService; + private final ApplicationUtil applicationUtil; - // Load product + // Hiển thị trang sản phẩm. @GetMapping("") public ModelAndView product() { var mav = new ModelAndView(PRODUCT_TEMP); var client = authenticationUtil.getAccount(); var products = sanPhamService.getDsSanPhamTonKho(); - var maxProducts = products.size(); - var maxSize = (maxProducts - 1) / DEFAULT_SIZE_PAGE + 1; + var maxSize = applicationUtil.maxPage(products, DEFAULT_SIZE_PAGE); mav.addObject(TITLE_PARAM, SAN_PHAM); mav.addObject(CART_PARAM, applicationUtil.getOrDefaultGioHang(client)); mav.addObject(LOGIN_PARAM, client != null); - mav.addObject(PRODUCTS_PARAM, - products.subList(0, maxProducts < DEFAULT_SIZE_PAGE ? maxProducts : DEFAULT_SIZE_PAGE)); + mav.addObject(PRODUCTS_PARAM, applicationUtil.limit(products, DEFAULT_SIZE_PAGE)); mav.addObject(RADIO_CHECK_PARAM, DEFAULT_PRODUCT); - mav.addObject(MAX_SIZE_PARAM, (maxProducts - 1) / DEFAULT_SIZE_PAGE + 1); + mav.addObject(MAX_SIZE_PARAM, maxSize); mav.addObject(VIEW_PARAM, PAGE_VIEW + "?page="); mav.addObject(PREVIOUS_PARAM, PAGE_VIEW + "?page=" + 1); mav.addObject(NEXT_PARAM, PAGE_VIEW + "?page=" + (2 > maxSize ? maxSize : 2)); @@ -52,22 +50,19 @@ public ModelAndView product() { return mav; } - // Load product from page + // Hiển thị sản phẩm theo trang. @GetMapping(PAGE_VIEW) public ModelAndView product(int page) { var mav = new ModelAndView(PRODUCT_TEMP); var client = authenticationUtil.getAccount(); var products = sanPhamService.getDsSanPhamTonKho(); - var maxProducts = products.size(); - var maxPage = page * DEFAULT_SIZE_PAGE; - var maxSize = (maxProducts - 1) / DEFAULT_SIZE_PAGE + 1; + var maxSize = applicationUtil.maxPage(products, DEFAULT_SIZE_PAGE); var previous = page - 1; var next = page + 1; mav.addObject(TITLE_PARAM, SAN_PHAM); mav.addObject(CART_PARAM, applicationUtil.getOrDefaultGioHang(client)); mav.addObject(LOGIN_PARAM, client != null); - mav.addObject(PRODUCTS_PARAM, - products.subList((page - 1) * DEFAULT_SIZE_PAGE, maxPage > maxProducts ? maxProducts : maxPage)); + mav.addObject(PRODUCTS_PARAM, applicationUtil.page(products, page, DEFAULT_SIZE_PAGE)); mav.addObject(RADIO_CHECK_PARAM, DEFAULT_CATEGORY); mav.addObject(MAX_SIZE_PARAM, maxSize); mav.addObject(VIEW_PARAM, PAGE_VIEW + "?page="); @@ -77,21 +72,19 @@ public ModelAndView product(int page) { return mav; } - // Load sort products + // Hiển thị sản phẩm theo kiểu sắp xếp. @GetMapping(SORT_VIEW) public ModelAndView productSort(String sort) { var mav = new ModelAndView(PRODUCT_TEMP); var client = authenticationUtil.getAccount(); var products = sortProducts(sort); - var maxProducts = products.size(); - var maxSize = (maxProducts - 1) / DEFAULT_SIZE_PAGE + 1; + var maxSize = applicationUtil.maxPage(products, DEFAULT_SIZE_PAGE); mav.addObject(TITLE_PARAM, SAN_PHAM); mav.addObject(CART_PARAM, applicationUtil.getOrDefaultGioHang(client)); mav.addObject(LOGIN_PARAM, client != null); - mav.addObject(PRODUCTS_PARAM, - products.subList(0, maxProducts < DEFAULT_SIZE_PAGE ? maxProducts : DEFAULT_SIZE_PAGE)); + mav.addObject(PRODUCTS_PARAM, applicationUtil.limit(products, DEFAULT_SIZE_PAGE)); mav.addObject(RADIO_CHECK_PARAM, PRODUCTS_MAP.get(sort)); - mav.addObject(MAX_SIZE_PARAM, (maxProducts - 1) / DEFAULT_SIZE_PAGE + 1); + mav.addObject(MAX_SIZE_PARAM, maxSize); mav.addObject(VIEW_PARAM, SORT_VIEW + PAGE_VIEW + "?sort=" + sort + "&page="); mav.addObject(PREVIOUS_PARAM, SORT_VIEW + PAGE_VIEW + "?sort=" + sort + "&page=" + 1); mav.addObject(NEXT_PARAM, SORT_VIEW + PAGE_VIEW + "?sort=" + sort + "&page=" + (2 > maxSize ? maxSize : 2)); @@ -99,22 +92,19 @@ public ModelAndView productSort(String sort) { return mav; } - // Load sort products + // Hiển thị sản phẩm theo kiểu sắp xếp. @GetMapping(SORT_VIEW + PAGE_VIEW) public ModelAndView productSort(String sort, int page) { var mav = new ModelAndView(PRODUCT_TEMP); var client = authenticationUtil.getAccount(); var products = sortProducts(sort); - var maxProducts = products.size(); - var maxPage = page * DEFAULT_SIZE_PAGE; - var maxSize = (maxProducts - 1) / DEFAULT_SIZE_PAGE + 1; + var maxSize = applicationUtil.maxPage(products, DEFAULT_SIZE_PAGE); var previous = page - 1; var next = page + 1; mav.addObject(TITLE_PARAM, SAN_PHAM); mav.addObject(CART_PARAM, applicationUtil.getOrDefaultGioHang(client)); mav.addObject(LOGIN_PARAM, client != null); - mav.addObject(PRODUCTS_PARAM, - products.subList((page - 1) * DEFAULT_SIZE_PAGE, maxPage > maxProducts ? maxProducts : maxPage)); + mav.addObject(PRODUCTS_PARAM, applicationUtil.page(products, page, DEFAULT_SIZE_PAGE)); mav.addObject(RADIO_CHECK_PARAM, PRODUCTS_MAP.get(sort)); mav.addObject(MAX_SIZE_PARAM, maxSize); mav.addObject(VIEW_PARAM, SORT_VIEW + PAGE_VIEW + "?sort=" + sort + "&page="); @@ -126,7 +116,7 @@ public ModelAndView productSort(String sort, int page) { return mav; } - // Get list products by sort + // Lấy danh sách sản phẩm theo kiểu sắp xếp. private List sortProducts(String sort) { switch (sort) { case "topSale": { @@ -145,7 +135,7 @@ private List sortProducts(String sort) { return sanPhamService.getDsSanPhamDescendingPrice(); } default: { - return sanPhamService.getDsSanPham(); + return sanPhamService.getDsSanPhamTonKho(); } } } diff --git a/src/main/java/com/nohit/jira_project/controller/ThanhToanController.java b/src/main/java/com/nohit/ecommerce_project/controller/ThanhToanController.java similarity index 66% rename from src/main/java/com/nohit/jira_project/controller/ThanhToanController.java rename to src/main/java/com/nohit/ecommerce_project/controller/ThanhToanController.java index bbac118..a7617e9 100644 --- a/src/main/java/com/nohit/jira_project/controller/ThanhToanController.java +++ b/src/main/java/com/nohit/ecommerce_project/controller/ThanhToanController.java @@ -1,75 +1,61 @@ -package com.nohit.jira_project.controller; +package com.nohit.ecommerce_project.controller; + +import lombok.*; import java.util.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; - -import lombok.*; - -import static com.nohit.jira_project.common.Bean.*; -import static com.nohit.jira_project.constant.ApplicationConstant.*; -import static com.nohit.jira_project.constant.ApplicationConstant.Menu.*; -import static com.nohit.jira_project.constant.ApplicationConstant.Payment.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; -import static com.nohit.jira_project.constant.TemplateConstant.*; -import static com.nohit.jira_project.constant.ViewConstant.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; + +import static com.nohit.ecommerce_project.common.Bean.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.Menu.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.Payment.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.TemplateConstant.*; +import static com.nohit.ecommerce_project.constant.ViewConstant.*; import static org.springframework.util.StringUtils.*; +/** + * Controller xử lý thanh toán, tạo đơn hàng và cập nhật tồn kho sau khi đặt hàng. + */ @Controller @RequestMapping(CHECKOUT_VIEW) +@RequiredArgsConstructor public class ThanhToanController { - @Autowired - private NguoiNhanService nguoiNhanService; - - @Autowired - private SanPhamService sanPhamService; - - @Autowired - private GioHangService gioHangService; - - @Autowired - private ChiTietGioHangService chiTietGioHangService; - - @Autowired - private DonHangService donHangService; - - @Autowired - private ChiTietDonHangService chiTietDonHangService; - - @Autowired - private TinhThanhService tinhThanhService; - - @Autowired - private AuthenticationUtil authenticationUtil; - - @Autowired - private ApplicationUtil applicationUtil; - - // Load checkout + private final NguoiNhanService nguoiNhanService; + private final SanPhamService sanPhamService; + private final GioHangService gioHangService; + private final ChiTietGioHangService chiTietGioHangService; + private final DonHangService donHangService; + private final ChiTietDonHangService chiTietDonHangService; + private final TinhThanhService tinhThanhService; + private final AuthenticationUtil authenticationUtil; + private final ApplicationUtil applicationUtil; + + // Hiển thị trang thanh toán. @GetMapping("") public ModelAndView checkout() { var client = authenticationUtil.getAccount(); - // Check current account still valid + // Kiểm tra phiên đăng nhập hiện tại còn hợp lệ. if (client == null) { return new ModelAndView(LOGIN_TEMP); } else { var mav = new ModelAndView(CHECKOUT_TEMP); - var cart = client.getGioHang(); + var cart = applicationUtil.getOrDefaultGioHang(client); var provinceCart = cart.getIdTinhThanh(); var differentAddress = provinceCart != client.getIdTinhThanh(); mav.addObject(TITLE_PARAM, THANH_TOAN); mav.addObject(CART_PARAM, cart); mav.addObject(LOGIN_PARAM, client != null); mav.addObject(CLIENT_PARAM, client); - mav.addObject(TOP_DISCOUNTS_PARAM, sanPhamService.getDsSanPhamDescendingDiscount().subList(0, 3)); - mav.addObject(TOP_NEWS_PARAM, sanPhamService.getDsSanPhamNewest().subList(0, 3)); + mav.addObject(TOP_DISCOUNTS_PARAM, applicationUtil.limit(sanPhamService.getDsSanPhamDescendingDiscount(), 3)); + mav.addObject(TOP_NEWS_PARAM, applicationUtil.limit(sanPhamService.getDsSanPhamNewest(), 3)); mav.addObject(PROVINCES_PARAM, tinhThanhService.getDsTinhThanh()); mav.addObject(DEFAULT_PROVINCE_PARAM, differentAddress ? provinceCart : DEFAULT_PROVINCE); mav.addObject(DEFAULT_WARD_PARAM, differentAddress ? cart.getHuyenQuan() : ""); @@ -78,17 +64,17 @@ public ModelAndView checkout() { } } - // Checkout + // Xử lý đặt hàng. @PostMapping("") public String checkout(NguoiNhan nguoiNhan, boolean differentAddress, String phuongThucThanhToan) { var client = authenticationUtil.getAccount(); - // Check current account still valid + // Kiểm tra phiên đăng nhập hiện tại còn hợp lệ. if (client == null) { return REDIRECT_PREFIX + LOGIN_VIEW; } else { var cart = applicationUtil.getOrDefaultGioHang(client); _isMsgShow = true; - // check cart + // Kiểm tra trạng thái giỏ hàng. if (cart.getTongSoLuong() <= 0) { _msg = "Không thể thanh toán giỏ hàng trống!"; return REDIRECT_PREFIX + CHECKOUT_VIEW; @@ -99,9 +85,9 @@ public String checkout(NguoiNhan nguoiNhan, boolean differentAddress, String phu var address = client.getDiaChi(); var ward = client.getXaPhuong(); var district = client.getHuyenQuan(); - // check exists credit_card - if (phuongThucThanhToan.equals(CARD) - && (!hasText(creditCard.getNameOnCard()) || !hasText(creditCard.getCardNumber()) + // Kiểm tra thông tin thẻ khi khách chọn thanh toán bằng thẻ. + if (CARD.equals(phuongThucThanhToan) + && (creditCard == null || !hasText(creditCard.getNameOnCard()) || !hasText(creditCard.getCardNumber()) || !hasText(creditCard.getExpiration()) || !hasText(creditCard.getSecurityCode()))) { _msg = "Bạn chưa có thông tin thẻ tín dụng trong tài khoản!"; return REDIRECT_PREFIX + PROFILE_VIEW; @@ -110,7 +96,7 @@ public String checkout(NguoiNhan nguoiNhan, boolean differentAddress, String phu _msg = "Bạn chưa có thông tin cá nhân đầy đủ để thanh toán!"; return REDIRECT_PREFIX + PROFILE_VIEW; } else { - // check different address + // Dùng địa chỉ hồ sơ nếu khách không nhập địa chỉ nhận khác. if (!differentAddress) { nguoiNhan.setHoTen(name); nguoiNhan.setSoDienThoai(phone); @@ -124,7 +110,8 @@ public String checkout(NguoiNhan nguoiNhan, boolean differentAddress, String phu var order = new DonHang(); order.setNgayDat(new Date()); order.setTongGioHang(cart.getTongGioHang()); - order.setChiPhiVanChuyen(client.getTinhThanh().getChiPhiVanChuyen()); + var tinhThanhGiaoHang = cart.getTinhThanh() != null ? cart.getTinhThanh() : client.getTinhThanh(); + order.setChiPhiVanChuyen(tinhThanhGiaoHang == null ? 0 : tinhThanhGiaoHang.getChiPhiVanChuyen()); order.setGiamGia(cart.getGiamGia()); order.setPhuongThucThanhToan(phuongThucThanhToan); order.setTrangThai(DEFAULT_STATUS); @@ -132,19 +119,18 @@ public String checkout(NguoiNhan nguoiNhan, boolean differentAddress, String phu order.setIdNguoiNhan(idReceiver); order = donHangService.saveDonHang(order); var id = order.getId(); - // update cart detail + // Chuyển từng dòng giỏ hàng sang chi tiết đơn hàng. for (var item : cart.getDsChiTietGioHang()) { var product = item.getSanPham(); - var idProduct = product.getId(); - var inventory = product.getTonKho(); var productsCount = item.getSoLuongSanPham(); - // check valid product - if (product == null || inventory < productsCount) { + if (product == null || product.getTonKho() < productsCount) { nguoiNhanService.deleteNguoiNhan(idReceiver); donHangService.deleteDonHang(id); _msg = "Không còn đủ sản phẩm để thanh toán!"; - return REDIRECT_PREFIX + CARD_VIEW + DELETE_VIEW + PRODUCT_VIEW + "?id=" + idProduct; + return REDIRECT_PREFIX + CART_VIEW; } + var idProduct = product.getId(); + var inventory = product.getTonKho(); var orderDetail = new ChiTietDonHang(); orderDetail.setSoLuongSanPham(productsCount); orderDetail.setGiaBanSanPham(item.getGiaBanSanPham()); diff --git a/src/main/java/com/nohit/jira_project/filter/AuthenticationFilter.java b/src/main/java/com/nohit/ecommerce_project/filter/AuthenticationFilter.java similarity index 87% rename from src/main/java/com/nohit/jira_project/filter/AuthenticationFilter.java rename to src/main/java/com/nohit/ecommerce_project/filter/AuthenticationFilter.java index f938f12..6a4ef00 100644 --- a/src/main/java/com/nohit/jira_project/filter/AuthenticationFilter.java +++ b/src/main/java/com/nohit/ecommerce_project/filter/AuthenticationFilter.java @@ -1,4 +1,6 @@ -package com.nohit.jira_project.filter; +package com.nohit.ecommerce_project.filter; + +import lombok.*; import java.io.*; import java.util.*; @@ -13,21 +15,23 @@ import com.fasterxml.jackson.databind.*; -import lombok.*; import lombok.extern.slf4j.*; import static com.auth0.jwt.JWT.*; import static com.auth0.jwt.algorithms.Algorithm.*; -import static com.nohit.jira_project.constant.ApplicationConstant.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; import static java.lang.System.*; import static java.util.stream.Collectors.*; import static org.springframework.http.MediaType.*; +/** + * Filter xác thực API login và phát access token, refresh token cho khách hàng hợp lệ. + */ @RequiredArgsConstructor @Slf4j public class AuthenticationFilter extends UsernamePasswordAuthenticationFilter { - // Fields + // Phụ thuộc bắt buộc của filter. private final AuthenticationManager authenticationManager; @Override @@ -36,7 +40,6 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ var username = request.getParameter("username"); var password = request.getParameter("password"); log.info("Email: {}", username); - log.info("Password: {}", password); return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password)); } diff --git a/src/main/java/com/nohit/jira_project/filter/AuthorizationFilter.java b/src/main/java/com/nohit/ecommerce_project/filter/AuthorizationFilter.java similarity index 80% rename from src/main/java/com/nohit/jira_project/filter/AuthorizationFilter.java rename to src/main/java/com/nohit/ecommerce_project/filter/AuthorizationFilter.java index da0af8e..4b791bb 100644 --- a/src/main/java/com/nohit/jira_project/filter/AuthorizationFilter.java +++ b/src/main/java/com/nohit/ecommerce_project/filter/AuthorizationFilter.java @@ -1,8 +1,7 @@ -package com.nohit.jira_project.filter; +package com.nohit.ecommerce_project.filter; import java.io.*; import java.util.*; -import java.util.ArrayList; import javax.servlet.*; import javax.servlet.http.*; @@ -17,28 +16,31 @@ import static com.auth0.jwt.JWT.*; import static com.auth0.jwt.algorithms.Algorithm.*; -import static com.nohit.jira_project.constant.ApplicationConstant.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; -import static com.nohit.jira_project.constant.ViewConstant.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.ViewConstant.*; import static java.util.Arrays.*; import static org.springframework.http.HttpHeaders.*; import static org.springframework.http.HttpStatus.*; import static org.springframework.http.MediaType.*; import static org.springframework.security.core.context.SecurityContextHolder.*; +/** + * Filter đọc JWT trên request API và đưa quyền người dùng vào SecurityContext. + */ @Slf4j public class AuthorizationFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { var servletPath = request.getServletPath(); - // urls login vs refresh pass + // Bỏ qua endpoint login và refresh token. if (servletPath.equals(API_VIEW + LOGIN_VIEW) || servletPath.equals(API_VIEW + TOKEN_VIEW + REFRESH_VIEW)) { filterChain.doFilter(request, response); return; } else { var header = request.getHeader(AUTHORIZATION); - // get token from header + // Lấy token từ header Authorization. if (header != null && header.startsWith(TOKEN_PREFIX)) { try { var decodedJwt = require(HMAC256(SECRET_KEY.getBytes())).build() @@ -50,8 +52,8 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse new UsernamePasswordAuthenticationToken(decodedJwt.getSubject(), null, authorities)); filterChain.doFilter(request, response); } catch (Exception e) { - var errorMsg = e.getMessage(); - log.error("Error logging in: {}", errorMsg); + var errorMsg = "Access token không hợp lệ hoặc đã hết hạn."; + log.error("JWT authorization failed: {}", e.getMessage()); response.setHeader(ERROR_HEADER_KEY, errorMsg); response.setStatus(FORBIDDEN.value()); var error = new HashMap<>(); diff --git a/src/main/java/com/nohit/jira_project/model/ChiTietDonHang.java b/src/main/java/com/nohit/ecommerce_project/model/ChiTietDonHang.java similarity index 85% rename from src/main/java/com/nohit/jira_project/model/ChiTietDonHang.java rename to src/main/java/com/nohit/ecommerce_project/model/ChiTietDonHang.java index 920898a..daecbfb 100644 --- a/src/main/java/com/nohit/jira_project/model/ChiTietDonHang.java +++ b/src/main/java/com/nohit/ecommerce_project/model/ChiTietDonHang.java @@ -1,11 +1,15 @@ -package com.nohit.jira_project.model; +package com.nohit.ecommerce_project.model; + +import lombok.*; import javax.persistence.*; -import lombok.*; import static javax.persistence.FetchType.*; +/** + * Entity JPA biểu diễn dữ liệu ChiTietDonHang trong miền thương mại điện tử. + */ @Entity(name = "chi_tiet_don_hang") @Data @AllArgsConstructor diff --git a/src/main/java/com/nohit/jira_project/model/ChiTietDonHangId.java b/src/main/java/com/nohit/ecommerce_project/model/ChiTietDonHangId.java similarity index 67% rename from src/main/java/com/nohit/jira_project/model/ChiTietDonHangId.java rename to src/main/java/com/nohit/ecommerce_project/model/ChiTietDonHangId.java index c8d1e8c..cec95c2 100644 --- a/src/main/java/com/nohit/jira_project/model/ChiTietDonHangId.java +++ b/src/main/java/com/nohit/ecommerce_project/model/ChiTietDonHangId.java @@ -1,11 +1,15 @@ -package com.nohit.jira_project.model; +package com.nohit.ecommerce_project.model; + +import lombok.*; import java.io.*; import javax.persistence.*; -import lombok.*; +/** + * Khóa chính tổng hợp cho entity ChiTietDonHang trong cơ sở dữ liệu ecommerce. + */ @Embeddable @Data @AllArgsConstructor diff --git a/src/main/java/com/nohit/jira_project/model/ChiTietGioHang.java b/src/main/java/com/nohit/ecommerce_project/model/ChiTietGioHang.java similarity index 85% rename from src/main/java/com/nohit/jira_project/model/ChiTietGioHang.java rename to src/main/java/com/nohit/ecommerce_project/model/ChiTietGioHang.java index 933ccf5..5452907 100644 --- a/src/main/java/com/nohit/jira_project/model/ChiTietGioHang.java +++ b/src/main/java/com/nohit/ecommerce_project/model/ChiTietGioHang.java @@ -1,11 +1,15 @@ -package com.nohit.jira_project.model; +package com.nohit.ecommerce_project.model; + +import lombok.*; import javax.persistence.*; -import lombok.*; import static javax.persistence.FetchType.*; +/** + * Entity JPA biểu diễn dữ liệu ChiTietGioHang trong miền thương mại điện tử. + */ @Entity(name = "chi_tiet_gio_hang") @Data @AllArgsConstructor diff --git a/src/main/java/com/nohit/jira_project/model/ChiTietGioHangId.java b/src/main/java/com/nohit/ecommerce_project/model/ChiTietGioHangId.java similarity index 67% rename from src/main/java/com/nohit/jira_project/model/ChiTietGioHangId.java rename to src/main/java/com/nohit/ecommerce_project/model/ChiTietGioHangId.java index 52613e3..bbb0f5a 100644 --- a/src/main/java/com/nohit/jira_project/model/ChiTietGioHangId.java +++ b/src/main/java/com/nohit/ecommerce_project/model/ChiTietGioHangId.java @@ -1,11 +1,15 @@ -package com.nohit.jira_project.model; +package com.nohit.ecommerce_project.model; + +import lombok.*; import java.io.*; import javax.persistence.*; -import lombok.*; +/** + * Khóa chính tổng hợp cho entity ChiTietGioHang trong cơ sở dữ liệu ecommerce. + */ @Embeddable @Data @AllArgsConstructor diff --git a/src/main/java/com/nohit/jira_project/model/CreditCard.java b/src/main/java/com/nohit/ecommerce_project/model/CreditCard.java similarity index 82% rename from src/main/java/com/nohit/jira_project/model/CreditCard.java rename to src/main/java/com/nohit/ecommerce_project/model/CreditCard.java index a264bb9..6a05a09 100644 --- a/src/main/java/com/nohit/jira_project/model/CreditCard.java +++ b/src/main/java/com/nohit/ecommerce_project/model/CreditCard.java @@ -1,11 +1,15 @@ -package com.nohit.jira_project.model; +package com.nohit.ecommerce_project.model; + +import lombok.*; import javax.persistence.*; -import lombok.*; import static javax.persistence.FetchType.*; +/** + * Entity JPA biểu diễn dữ liệu CreditCard trong miền thương mại điện tử. + */ @Entity(name = "credit_card") @Data @AllArgsConstructor diff --git a/src/main/java/com/nohit/jira_project/model/DonHang.java b/src/main/java/com/nohit/ecommerce_project/model/DonHang.java similarity index 92% rename from src/main/java/com/nohit/jira_project/model/DonHang.java rename to src/main/java/com/nohit/ecommerce_project/model/DonHang.java index 6aa0413..b910511 100644 --- a/src/main/java/com/nohit/jira_project/model/DonHang.java +++ b/src/main/java/com/nohit/ecommerce_project/model/DonHang.java @@ -1,4 +1,6 @@ -package com.nohit.jira_project.model; +package com.nohit.ecommerce_project.model; + +import lombok.*; import java.util.*; @@ -6,11 +8,13 @@ import org.springframework.format.annotation.*; -import lombok.*; import static javax.persistence.FetchType.*; import static javax.persistence.GenerationType.*; +/** + * Entity JPA biểu diễn dữ liệu DonHang trong miền thương mại điện tử. + */ @Entity(name = "don_hang") @Data @AllArgsConstructor diff --git a/src/main/java/com/nohit/jira_project/model/GioHang.java b/src/main/java/com/nohit/ecommerce_project/model/GioHang.java similarity index 87% rename from src/main/java/com/nohit/jira_project/model/GioHang.java rename to src/main/java/com/nohit/ecommerce_project/model/GioHang.java index 69c471a..afc69b9 100644 --- a/src/main/java/com/nohit/jira_project/model/GioHang.java +++ b/src/main/java/com/nohit/ecommerce_project/model/GioHang.java @@ -1,13 +1,17 @@ -package com.nohit.jira_project.model; +package com.nohit.ecommerce_project.model; + +import lombok.*; import java.util.*; import javax.persistence.*; -import lombok.*; import static javax.persistence.FetchType.*; +/** + * Entity JPA biểu diễn dữ liệu GioHang trong miền thương mại điện tử. + */ @Entity(name = "gio_hang") @Data @AllArgsConstructor diff --git a/src/main/java/com/nohit/jira_project/model/KhachHang.java b/src/main/java/com/nohit/ecommerce_project/model/KhachHang.java similarity index 91% rename from src/main/java/com/nohit/jira_project/model/KhachHang.java rename to src/main/java/com/nohit/ecommerce_project/model/KhachHang.java index 20fa24c..47485bc 100644 --- a/src/main/java/com/nohit/jira_project/model/KhachHang.java +++ b/src/main/java/com/nohit/ecommerce_project/model/KhachHang.java @@ -1,14 +1,18 @@ -package com.nohit.jira_project.model; +package com.nohit.ecommerce_project.model; + +import lombok.*; import java.util.*; import javax.persistence.*; -import lombok.*; import static javax.persistence.FetchType.*; import static javax.persistence.GenerationType.*; +/** + * Entity JPA biểu diễn dữ liệu KhachHang trong miền thương mại điện tử. + */ @Entity(name = "khach_hang") @Data @AllArgsConstructor diff --git a/src/main/java/com/nohit/jira_project/model/NguoiNhan.java b/src/main/java/com/nohit/ecommerce_project/model/NguoiNhan.java similarity index 88% rename from src/main/java/com/nohit/jira_project/model/NguoiNhan.java rename to src/main/java/com/nohit/ecommerce_project/model/NguoiNhan.java index 9917fdf..c79e5d4 100644 --- a/src/main/java/com/nohit/jira_project/model/NguoiNhan.java +++ b/src/main/java/com/nohit/ecommerce_project/model/NguoiNhan.java @@ -1,14 +1,18 @@ -package com.nohit.jira_project.model; +package com.nohit.ecommerce_project.model; + +import lombok.*; import java.util.*; import javax.persistence.*; -import lombok.*; import static javax.persistence.FetchType.*; import static javax.persistence.GenerationType.*; +/** + * Entity JPA biểu diễn dữ liệu NguoiNhan trong miền thương mại điện tử. + */ @Entity(name = "nguoi_nhan") @Data @AllArgsConstructor diff --git a/src/main/java/com/nohit/jira_project/model/NhanXet.java b/src/main/java/com/nohit/ecommerce_project/model/NhanXet.java similarity index 83% rename from src/main/java/com/nohit/jira_project/model/NhanXet.java rename to src/main/java/com/nohit/ecommerce_project/model/NhanXet.java index d4b330e..d4d5595 100644 --- a/src/main/java/com/nohit/jira_project/model/NhanXet.java +++ b/src/main/java/com/nohit/ecommerce_project/model/NhanXet.java @@ -1,11 +1,15 @@ -package com.nohit.jira_project.model; +package com.nohit.ecommerce_project.model; + +import lombok.*; import javax.persistence.*; -import lombok.*; import static javax.persistence.FetchType.*; +/** + * Entity JPA biểu diễn dữ liệu NhanXet trong miền thương mại điện tử. + */ @Entity(name = "nhan_xet") @Data @AllArgsConstructor diff --git a/src/main/java/com/nohit/jira_project/model/NhanXetId.java b/src/main/java/com/nohit/ecommerce_project/model/NhanXetId.java similarity index 68% rename from src/main/java/com/nohit/jira_project/model/NhanXetId.java rename to src/main/java/com/nohit/ecommerce_project/model/NhanXetId.java index 9f7607e..b395e9e 100644 --- a/src/main/java/com/nohit/jira_project/model/NhanXetId.java +++ b/src/main/java/com/nohit/ecommerce_project/model/NhanXetId.java @@ -1,11 +1,15 @@ -package com.nohit.jira_project.model; +package com.nohit.ecommerce_project.model; + +import lombok.*; import java.io.*; import javax.persistence.*; -import lombok.*; +/** + * Khóa chính tổng hợp cho entity NhanXet trong cơ sở dữ liệu ecommerce. + */ @Embeddable @Data @AllArgsConstructor diff --git a/src/main/java/com/nohit/jira_project/model/SanPham.java b/src/main/java/com/nohit/ecommerce_project/model/SanPham.java similarity index 90% rename from src/main/java/com/nohit/jira_project/model/SanPham.java rename to src/main/java/com/nohit/ecommerce_project/model/SanPham.java index c073ad5..ffe1885 100644 --- a/src/main/java/com/nohit/jira_project/model/SanPham.java +++ b/src/main/java/com/nohit/ecommerce_project/model/SanPham.java @@ -1,4 +1,6 @@ -package com.nohit.jira_project.model; +package com.nohit.ecommerce_project.model; + +import lombok.*; import java.util.*; @@ -6,10 +8,12 @@ import org.springframework.format.annotation.*; -import lombok.*; import static javax.persistence.GenerationType.*; +/** + * Entity JPA biểu diễn dữ liệu SanPham trong miền thương mại điện tử. + */ @Entity(name = "san_pham") @Data @AllArgsConstructor diff --git a/src/main/java/com/nohit/jira_project/model/TheoDoi.java b/src/main/java/com/nohit/ecommerce_project/model/TheoDoi.java similarity index 73% rename from src/main/java/com/nohit/jira_project/model/TheoDoi.java rename to src/main/java/com/nohit/ecommerce_project/model/TheoDoi.java index 4aa7a39..9a3bbc7 100644 --- a/src/main/java/com/nohit/jira_project/model/TheoDoi.java +++ b/src/main/java/com/nohit/ecommerce_project/model/TheoDoi.java @@ -1,11 +1,15 @@ -package com.nohit.jira_project.model; +package com.nohit.ecommerce_project.model; + +import lombok.*; import javax.persistence.*; -import lombok.*; import static javax.persistence.GenerationType.*; +/** + * Entity JPA biểu diễn dữ liệu TheoDoi trong miền thương mại điện tử. + */ @Entity(name = "theo_doi") @Data @AllArgsConstructor diff --git a/src/main/java/com/nohit/jira_project/model/ThuPhanHoi.java b/src/main/java/com/nohit/ecommerce_project/model/ThuPhanHoi.java similarity index 79% rename from src/main/java/com/nohit/jira_project/model/ThuPhanHoi.java rename to src/main/java/com/nohit/ecommerce_project/model/ThuPhanHoi.java index 1fac282..2c60c1a 100644 --- a/src/main/java/com/nohit/jira_project/model/ThuPhanHoi.java +++ b/src/main/java/com/nohit/ecommerce_project/model/ThuPhanHoi.java @@ -1,11 +1,15 @@ -package com.nohit.jira_project.model; +package com.nohit.ecommerce_project.model; + +import lombok.*; import javax.persistence.*; -import lombok.*; import static javax.persistence.GenerationType.*; +/** + * Entity JPA biểu diễn dữ liệu ThuPhanHoi trong miền thương mại điện tử. + */ @Entity(name = "thu_phan_hoi") @Data @AllArgsConstructor diff --git a/src/main/java/com/nohit/jira_project/model/TinhThanh.java b/src/main/java/com/nohit/ecommerce_project/model/TinhThanh.java similarity index 83% rename from src/main/java/com/nohit/jira_project/model/TinhThanh.java rename to src/main/java/com/nohit/ecommerce_project/model/TinhThanh.java index c14ee3b..1712685 100644 --- a/src/main/java/com/nohit/jira_project/model/TinhThanh.java +++ b/src/main/java/com/nohit/ecommerce_project/model/TinhThanh.java @@ -1,13 +1,17 @@ -package com.nohit.jira_project.model; +package com.nohit.ecommerce_project.model; + +import lombok.*; import java.util.*; import javax.persistence.*; -import lombok.*; import static javax.persistence.GenerationType.*; +/** + * Entity JPA biểu diễn dữ liệu TinhThanh trong miền thương mại điện tử. + */ @Entity(name = "tinh_thanh") @Data @AllArgsConstructor diff --git a/src/main/java/com/nohit/jira_project/repository/ChiTietDonHangRepository.java b/src/main/java/com/nohit/ecommerce_project/repository/ChiTietDonHangRepository.java similarity index 53% rename from src/main/java/com/nohit/jira_project/repository/ChiTietDonHangRepository.java rename to src/main/java/com/nohit/ecommerce_project/repository/ChiTietDonHangRepository.java index 3b8ee58..9c553e9 100644 --- a/src/main/java/com/nohit/jira_project/repository/ChiTietDonHangRepository.java +++ b/src/main/java/com/nohit/ecommerce_project/repository/ChiTietDonHangRepository.java @@ -1,10 +1,13 @@ -package com.nohit.jira_project.repository; +package com.nohit.ecommerce_project.repository; import org.springframework.data.jpa.repository.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Repository Spring Data JPA truy cập dữ liệu cho entity ChiTietDonHang. + */ @Repository public interface ChiTietDonHangRepository extends JpaRepository { } diff --git a/src/main/java/com/nohit/jira_project/repository/ChiTietGioHangRepository.java b/src/main/java/com/nohit/ecommerce_project/repository/ChiTietGioHangRepository.java similarity index 53% rename from src/main/java/com/nohit/jira_project/repository/ChiTietGioHangRepository.java rename to src/main/java/com/nohit/ecommerce_project/repository/ChiTietGioHangRepository.java index 42d135a..dd523e5 100644 --- a/src/main/java/com/nohit/jira_project/repository/ChiTietGioHangRepository.java +++ b/src/main/java/com/nohit/ecommerce_project/repository/ChiTietGioHangRepository.java @@ -1,10 +1,13 @@ -package com.nohit.jira_project.repository; +package com.nohit.ecommerce_project.repository; import org.springframework.data.jpa.repository.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Repository Spring Data JPA truy cập dữ liệu cho entity ChiTietGioHang. + */ @Repository public interface ChiTietGioHangRepository extends JpaRepository { } diff --git a/src/main/java/com/nohit/jira_project/repository/CreditCardRepository.java b/src/main/java/com/nohit/ecommerce_project/repository/CreditCardRepository.java similarity index 52% rename from src/main/java/com/nohit/jira_project/repository/CreditCardRepository.java rename to src/main/java/com/nohit/ecommerce_project/repository/CreditCardRepository.java index 99169a6..0d0ef05 100644 --- a/src/main/java/com/nohit/jira_project/repository/CreditCardRepository.java +++ b/src/main/java/com/nohit/ecommerce_project/repository/CreditCardRepository.java @@ -1,10 +1,13 @@ -package com.nohit.jira_project.repository; +package com.nohit.ecommerce_project.repository; import org.springframework.data.jpa.repository.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Repository Spring Data JPA truy cập dữ liệu cho entity CreditCard. + */ @Repository public interface CreditCardRepository extends JpaRepository { } diff --git a/src/main/java/com/nohit/jira_project/repository/DonHangRepository.java b/src/main/java/com/nohit/ecommerce_project/repository/DonHangRepository.java similarity index 51% rename from src/main/java/com/nohit/jira_project/repository/DonHangRepository.java rename to src/main/java/com/nohit/ecommerce_project/repository/DonHangRepository.java index 807f144..71c18ac 100644 --- a/src/main/java/com/nohit/jira_project/repository/DonHangRepository.java +++ b/src/main/java/com/nohit/ecommerce_project/repository/DonHangRepository.java @@ -1,10 +1,13 @@ -package com.nohit.jira_project.repository; +package com.nohit.ecommerce_project.repository; import org.springframework.data.jpa.repository.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Repository Spring Data JPA truy cập dữ liệu cho entity DonHang. + */ @Repository public interface DonHangRepository extends JpaRepository { } diff --git a/src/main/java/com/nohit/jira_project/repository/GioHangRepository.java b/src/main/java/com/nohit/ecommerce_project/repository/GioHangRepository.java similarity index 51% rename from src/main/java/com/nohit/jira_project/repository/GioHangRepository.java rename to src/main/java/com/nohit/ecommerce_project/repository/GioHangRepository.java index 72cea2c..878ace8 100644 --- a/src/main/java/com/nohit/jira_project/repository/GioHangRepository.java +++ b/src/main/java/com/nohit/ecommerce_project/repository/GioHangRepository.java @@ -1,10 +1,13 @@ -package com.nohit.jira_project.repository; +package com.nohit.ecommerce_project.repository; import org.springframework.data.jpa.repository.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Repository Spring Data JPA truy cập dữ liệu cho entity GioHang. + */ @Repository public interface GioHangRepository extends JpaRepository { } diff --git a/src/main/java/com/nohit/jira_project/repository/KhachHangRepository.java b/src/main/java/com/nohit/ecommerce_project/repository/KhachHangRepository.java similarity index 57% rename from src/main/java/com/nohit/jira_project/repository/KhachHangRepository.java rename to src/main/java/com/nohit/ecommerce_project/repository/KhachHangRepository.java index 31283db..dfef8a3 100644 --- a/src/main/java/com/nohit/jira_project/repository/KhachHangRepository.java +++ b/src/main/java/com/nohit/ecommerce_project/repository/KhachHangRepository.java @@ -1,10 +1,13 @@ -package com.nohit.jira_project.repository; +package com.nohit.ecommerce_project.repository; import org.springframework.data.jpa.repository.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Repository Spring Data JPA truy cập dữ liệu cho entity KhachHang. + */ @Repository public interface KhachHangRepository extends JpaRepository { public KhachHang findByEmail(String email); diff --git a/src/main/java/com/nohit/jira_project/repository/NguoiNhanRepository.java b/src/main/java/com/nohit/ecommerce_project/repository/NguoiNhanRepository.java similarity index 51% rename from src/main/java/com/nohit/jira_project/repository/NguoiNhanRepository.java rename to src/main/java/com/nohit/ecommerce_project/repository/NguoiNhanRepository.java index da22710..f79ba53 100644 --- a/src/main/java/com/nohit/jira_project/repository/NguoiNhanRepository.java +++ b/src/main/java/com/nohit/ecommerce_project/repository/NguoiNhanRepository.java @@ -1,10 +1,13 @@ -package com.nohit.jira_project.repository; +package com.nohit.ecommerce_project.repository; import org.springframework.data.jpa.repository.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Repository Spring Data JPA truy cập dữ liệu cho entity NguoiNhan. + */ @Repository public interface NguoiNhanRepository extends JpaRepository { } diff --git a/src/main/java/com/nohit/jira_project/repository/NhanXetRepository.java b/src/main/java/com/nohit/ecommerce_project/repository/NhanXetRepository.java similarity index 51% rename from src/main/java/com/nohit/jira_project/repository/NhanXetRepository.java rename to src/main/java/com/nohit/ecommerce_project/repository/NhanXetRepository.java index b67f8a8..6ff4b65 100644 --- a/src/main/java/com/nohit/jira_project/repository/NhanXetRepository.java +++ b/src/main/java/com/nohit/ecommerce_project/repository/NhanXetRepository.java @@ -1,10 +1,13 @@ -package com.nohit.jira_project.repository; +package com.nohit.ecommerce_project.repository; import org.springframework.data.jpa.repository.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Repository Spring Data JPA truy cập dữ liệu cho entity NhanXet. + */ @Repository public interface NhanXetRepository extends JpaRepository { } diff --git a/src/main/java/com/nohit/jira_project/repository/SanPhamRepository.java b/src/main/java/com/nohit/ecommerce_project/repository/SanPhamRepository.java similarity index 56% rename from src/main/java/com/nohit/jira_project/repository/SanPhamRepository.java rename to src/main/java/com/nohit/ecommerce_project/repository/SanPhamRepository.java index 41bd2cf..ec8c940 100644 --- a/src/main/java/com/nohit/jira_project/repository/SanPhamRepository.java +++ b/src/main/java/com/nohit/ecommerce_project/repository/SanPhamRepository.java @@ -1,12 +1,16 @@ -package com.nohit.jira_project.repository; +package com.nohit.ecommerce_project.repository; import java.util.*; import org.springframework.data.jpa.repository.*; +import org.springframework.data.repository.query.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Repository Spring Data JPA truy cập dữ liệu cho entity SanPham. + */ @Repository public interface SanPhamRepository extends JpaRepository { public List findByPhanLoai(String phanLoai); @@ -15,9 +19,9 @@ public interface SanPhamRepository extends JpaRepository { @Modifying @Query("UPDATE san_pham sp SET sp.tonKho = :tonKho WHERE sp.id = :id") - public void saveTonKho(int id, int tonKho); + public void saveTonKho(@Param("id") int id, @Param("tonKho") int tonKho); @Modifying @Query("UPDATE san_pham sp SET sp.danhGia = :danhGia WHERE sp.id = :id") - public void saveDanhGia(int id, int danhGia); + public void saveDanhGia(@Param("id") int id, @Param("danhGia") int danhGia); } diff --git a/src/main/java/com/nohit/jira_project/repository/TheoDoiRepository.java b/src/main/java/com/nohit/ecommerce_project/repository/TheoDoiRepository.java similarity index 57% rename from src/main/java/com/nohit/jira_project/repository/TheoDoiRepository.java rename to src/main/java/com/nohit/ecommerce_project/repository/TheoDoiRepository.java index 8f62aab..4d03517 100644 --- a/src/main/java/com/nohit/jira_project/repository/TheoDoiRepository.java +++ b/src/main/java/com/nohit/ecommerce_project/repository/TheoDoiRepository.java @@ -1,10 +1,13 @@ -package com.nohit.jira_project.repository; +package com.nohit.ecommerce_project.repository; import org.springframework.data.jpa.repository.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Repository Spring Data JPA truy cập dữ liệu cho entity TheoDoi. + */ @Repository public interface TheoDoiRepository extends JpaRepository { public TheoDoi findByEmail(String email); diff --git a/src/main/java/com/nohit/jira_project/repository/ThuPhanHoiRepository.java b/src/main/java/com/nohit/ecommerce_project/repository/ThuPhanHoiRepository.java similarity index 52% rename from src/main/java/com/nohit/jira_project/repository/ThuPhanHoiRepository.java rename to src/main/java/com/nohit/ecommerce_project/repository/ThuPhanHoiRepository.java index 09ab88a..4abd1b8 100644 --- a/src/main/java/com/nohit/jira_project/repository/ThuPhanHoiRepository.java +++ b/src/main/java/com/nohit/ecommerce_project/repository/ThuPhanHoiRepository.java @@ -1,10 +1,13 @@ -package com.nohit.jira_project.repository; +package com.nohit.ecommerce_project.repository; import org.springframework.data.jpa.repository.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Repository Spring Data JPA truy cập dữ liệu cho entity ThuPhanHoi. + */ @Repository public interface ThuPhanHoiRepository extends JpaRepository { } diff --git a/src/main/java/com/nohit/jira_project/repository/TinhThanhRepository.java b/src/main/java/com/nohit/ecommerce_project/repository/TinhThanhRepository.java similarity index 51% rename from src/main/java/com/nohit/jira_project/repository/TinhThanhRepository.java rename to src/main/java/com/nohit/ecommerce_project/repository/TinhThanhRepository.java index a5ece4b..a1d5951 100644 --- a/src/main/java/com/nohit/jira_project/repository/TinhThanhRepository.java +++ b/src/main/java/com/nohit/ecommerce_project/repository/TinhThanhRepository.java @@ -1,10 +1,13 @@ -package com.nohit.jira_project.repository; +package com.nohit.ecommerce_project.repository; import org.springframework.data.jpa.repository.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Repository Spring Data JPA truy cập dữ liệu cho entity TinhThanh. + */ @Repository public interface TinhThanhRepository extends JpaRepository { } diff --git a/src/main/java/com/nohit/jira_project/security/ApplicationSecurity.java b/src/main/java/com/nohit/ecommerce_project/security/ApplicationSecurity.java similarity index 81% rename from src/main/java/com/nohit/jira_project/security/ApplicationSecurity.java rename to src/main/java/com/nohit/ecommerce_project/security/ApplicationSecurity.java index 2e61025..5f5506a 100644 --- a/src/main/java/com/nohit/jira_project/security/ApplicationSecurity.java +++ b/src/main/java/com/nohit/ecommerce_project/security/ApplicationSecurity.java @@ -1,6 +1,7 @@ -package com.nohit.jira_project.security; +package com.nohit.ecommerce_project.security; + +import lombok.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.context.annotation.*; import org.springframework.security.authentication.*; import org.springframework.security.config.annotation.authentication.builders.*; @@ -11,24 +12,22 @@ import org.springframework.security.web.authentication.*; import org.springframework.security.web.savedrequest.*; -import com.nohit.jira_project.filter.*; -import com.nohit.jira_project.filter.AuthenticationFilter; +import com.nohit.ecommerce_project.filter.*; -import static com.nohit.jira_project.constant.ApplicationConstant.Role.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; -import static com.nohit.jira_project.constant.ViewConstant.*; +import static com.nohit.ecommerce_project.constant.ApplicationConstant.Role.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.ViewConstant.*; +/** + * Cấu hình Spring Security cho đăng nhập form, JWT API, phân quyền giỏ hàng và hồ sơ khách hàng. + */ @Configuration @EnableWebSecurity +@RequiredArgsConstructor public class ApplicationSecurity extends WebSecurityConfigurerAdapter { - @Autowired - private UserDetailsService userDetailsService; - - @Autowired - private PasswordEncoder passwordEncoder; - - @Autowired - private HttpSessionRequestCache httpSessionRequestCache; + private final UserDetailsService userDetailsService; + private final PasswordEncoder passwordEncoder; + private final HttpSessionRequestCache httpSessionRequestCache; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { diff --git a/src/main/java/com/nohit/jira_project/service/ChiTietDonHangService.java b/src/main/java/com/nohit/ecommerce_project/service/ChiTietDonHangService.java similarity index 65% rename from src/main/java/com/nohit/jira_project/service/ChiTietDonHangService.java rename to src/main/java/com/nohit/ecommerce_project/service/ChiTietDonHangService.java index ef23c7b..4b7434e 100644 --- a/src/main/java/com/nohit/jira_project/service/ChiTietDonHangService.java +++ b/src/main/java/com/nohit/ecommerce_project/service/ChiTietDonHangService.java @@ -1,9 +1,12 @@ -package com.nohit.jira_project.service; +package com.nohit.ecommerce_project.service; import java.util.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Interface khai báo nghiệp vụ cho miền dữ liệu ChiTietDonHang. + */ public interface ChiTietDonHangService { public List getDsChiTietDonHang(); diff --git a/src/main/java/com/nohit/jira_project/service/ChiTietGioHangService.java b/src/main/java/com/nohit/ecommerce_project/service/ChiTietGioHangService.java similarity index 65% rename from src/main/java/com/nohit/jira_project/service/ChiTietGioHangService.java rename to src/main/java/com/nohit/ecommerce_project/service/ChiTietGioHangService.java index bdebea8..88a0248 100644 --- a/src/main/java/com/nohit/jira_project/service/ChiTietGioHangService.java +++ b/src/main/java/com/nohit/ecommerce_project/service/ChiTietGioHangService.java @@ -1,9 +1,12 @@ -package com.nohit.jira_project.service; +package com.nohit.ecommerce_project.service; import java.util.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Interface khai báo nghiệp vụ cho miền dữ liệu ChiTietGioHang. + */ public interface ChiTietGioHangService { public List getDsChiTietGioHang(); diff --git a/src/main/java/com/nohit/jira_project/service/CreditCardService.java b/src/main/java/com/nohit/ecommerce_project/service/CreditCardService.java similarity index 65% rename from src/main/java/com/nohit/jira_project/service/CreditCardService.java rename to src/main/java/com/nohit/ecommerce_project/service/CreditCardService.java index 32b6cec..0dbc485 100644 --- a/src/main/java/com/nohit/jira_project/service/CreditCardService.java +++ b/src/main/java/com/nohit/ecommerce_project/service/CreditCardService.java @@ -1,9 +1,12 @@ -package com.nohit.jira_project.service; +package com.nohit.ecommerce_project.service; import java.util.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Interface khai báo nghiệp vụ cho miền dữ liệu CreditCard. + */ public interface CreditCardService { public List getDsCreditCard(); diff --git a/src/main/java/com/nohit/jira_project/service/DonHangService.java b/src/main/java/com/nohit/ecommerce_project/service/DonHangService.java similarity index 58% rename from src/main/java/com/nohit/jira_project/service/DonHangService.java rename to src/main/java/com/nohit/ecommerce_project/service/DonHangService.java index 7c12cb9..3136170 100644 --- a/src/main/java/com/nohit/jira_project/service/DonHangService.java +++ b/src/main/java/com/nohit/ecommerce_project/service/DonHangService.java @@ -1,9 +1,12 @@ -package com.nohit.jira_project.service; +package com.nohit.ecommerce_project.service; import java.util.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Interface khai báo nghiệp vụ cho miền dữ liệu DonHang. + */ public interface DonHangService { public List getDsDonHang(); diff --git a/src/main/java/com/nohit/jira_project/service/GioHangService.java b/src/main/java/com/nohit/ecommerce_project/service/GioHangService.java similarity index 63% rename from src/main/java/com/nohit/jira_project/service/GioHangService.java rename to src/main/java/com/nohit/ecommerce_project/service/GioHangService.java index 41b4e87..0e776eb 100644 --- a/src/main/java/com/nohit/jira_project/service/GioHangService.java +++ b/src/main/java/com/nohit/ecommerce_project/service/GioHangService.java @@ -1,9 +1,12 @@ -package com.nohit.jira_project.service; +package com.nohit.ecommerce_project.service; import java.util.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Interface khai báo nghiệp vụ cho miền dữ liệu GioHang. + */ public interface GioHangService { public List getDsGioHang(); diff --git a/src/main/java/com/nohit/jira_project/service/KhachHangService.java b/src/main/java/com/nohit/ecommerce_project/service/KhachHangService.java similarity index 77% rename from src/main/java/com/nohit/jira_project/service/KhachHangService.java rename to src/main/java/com/nohit/ecommerce_project/service/KhachHangService.java index 2efe7fe..6cda637 100644 --- a/src/main/java/com/nohit/jira_project/service/KhachHangService.java +++ b/src/main/java/com/nohit/ecommerce_project/service/KhachHangService.java @@ -1,12 +1,15 @@ -package com.nohit.jira_project.service; +package com.nohit.ecommerce_project.service; import java.io.*; import java.util.*; import javax.mail.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Interface khai báo nghiệp vụ cho miền dữ liệu KhachHang. + */ public interface KhachHangService { public List getDsKhachHang(); diff --git a/src/main/java/com/nohit/jira_project/service/NguoiNhanService.java b/src/main/java/com/nohit/ecommerce_project/service/NguoiNhanService.java similarity index 59% rename from src/main/java/com/nohit/jira_project/service/NguoiNhanService.java rename to src/main/java/com/nohit/ecommerce_project/service/NguoiNhanService.java index f6d58e3..361f789 100644 --- a/src/main/java/com/nohit/jira_project/service/NguoiNhanService.java +++ b/src/main/java/com/nohit/ecommerce_project/service/NguoiNhanService.java @@ -1,9 +1,12 @@ -package com.nohit.jira_project.service; +package com.nohit.ecommerce_project.service; import java.util.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Interface khai báo nghiệp vụ cho miền dữ liệu NguoiNhan. + */ public interface NguoiNhanService { public List getDsNguoiNhan(); diff --git a/src/main/java/com/nohit/jira_project/service/NhanXetService.java b/src/main/java/com/nohit/ecommerce_project/service/NhanXetService.java similarity index 59% rename from src/main/java/com/nohit/jira_project/service/NhanXetService.java rename to src/main/java/com/nohit/ecommerce_project/service/NhanXetService.java index a016f60..0e9ecd3 100644 --- a/src/main/java/com/nohit/jira_project/service/NhanXetService.java +++ b/src/main/java/com/nohit/ecommerce_project/service/NhanXetService.java @@ -1,9 +1,12 @@ -package com.nohit.jira_project.service; +package com.nohit.ecommerce_project.service; import java.util.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Interface khai báo nghiệp vụ cho miền dữ liệu NhanXet. + */ public interface NhanXetService { public List getDsNhanXet(); diff --git a/src/main/java/com/nohit/jira_project/service/SanPhamService.java b/src/main/java/com/nohit/ecommerce_project/service/SanPhamService.java similarity index 83% rename from src/main/java/com/nohit/jira_project/service/SanPhamService.java rename to src/main/java/com/nohit/ecommerce_project/service/SanPhamService.java index 3b3730a..e109180 100644 --- a/src/main/java/com/nohit/jira_project/service/SanPhamService.java +++ b/src/main/java/com/nohit/ecommerce_project/service/SanPhamService.java @@ -1,9 +1,12 @@ -package com.nohit.jira_project.service; +package com.nohit.ecommerce_project.service; import java.util.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Interface khai báo nghiệp vụ cho miền dữ liệu SanPham. + */ public interface SanPhamService { public List getDsSanPham(); diff --git a/src/main/java/com/nohit/jira_project/service/TheoDoiService.java b/src/main/java/com/nohit/ecommerce_project/service/TheoDoiService.java similarity index 62% rename from src/main/java/com/nohit/jira_project/service/TheoDoiService.java rename to src/main/java/com/nohit/ecommerce_project/service/TheoDoiService.java index 9e8dab6..1acc301 100644 --- a/src/main/java/com/nohit/jira_project/service/TheoDoiService.java +++ b/src/main/java/com/nohit/ecommerce_project/service/TheoDoiService.java @@ -1,9 +1,12 @@ -package com.nohit.jira_project.service; +package com.nohit.ecommerce_project.service; import java.util.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Interface khai báo nghiệp vụ cho miền dữ liệu TheoDoi. + */ public interface TheoDoiService { public List getDsTheoDoi(); diff --git a/src/main/java/com/nohit/jira_project/service/ThuPhanHoiService.java b/src/main/java/com/nohit/ecommerce_project/service/ThuPhanHoiService.java similarity index 60% rename from src/main/java/com/nohit/jira_project/service/ThuPhanHoiService.java rename to src/main/java/com/nohit/ecommerce_project/service/ThuPhanHoiService.java index 5f93adf..f31e16a 100644 --- a/src/main/java/com/nohit/jira_project/service/ThuPhanHoiService.java +++ b/src/main/java/com/nohit/ecommerce_project/service/ThuPhanHoiService.java @@ -1,9 +1,12 @@ -package com.nohit.jira_project.service; +package com.nohit.ecommerce_project.service; import java.util.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Interface khai báo nghiệp vụ cho miền dữ liệu ThuPhanHoi. + */ public interface ThuPhanHoiService { public List getDsThuPhanHoi(); diff --git a/src/main/java/com/nohit/jira_project/service/TinhThanhService.java b/src/main/java/com/nohit/ecommerce_project/service/TinhThanhService.java similarity index 59% rename from src/main/java/com/nohit/jira_project/service/TinhThanhService.java rename to src/main/java/com/nohit/ecommerce_project/service/TinhThanhService.java index c2c3f01..f4fa15b 100644 --- a/src/main/java/com/nohit/jira_project/service/TinhThanhService.java +++ b/src/main/java/com/nohit/ecommerce_project/service/TinhThanhService.java @@ -1,9 +1,12 @@ -package com.nohit.jira_project.service; +package com.nohit.ecommerce_project.service; import java.util.*; -import com.nohit.jira_project.model.*; +import com.nohit.ecommerce_project.model.*; +/** + * Interface khai báo nghiệp vụ cho miền dữ liệu TinhThanh. + */ public interface TinhThanhService { public List getDsTinhThanh(); diff --git a/src/main/java/com/nohit/jira_project/service/Impl/ChiTietDonHangServiceImpl.java b/src/main/java/com/nohit/ecommerce_project/service/impl/ChiTietDonHangServiceImpl.java similarity index 72% rename from src/main/java/com/nohit/jira_project/service/Impl/ChiTietDonHangServiceImpl.java rename to src/main/java/com/nohit/ecommerce_project/service/impl/ChiTietDonHangServiceImpl.java index 6591adc..87dc60d 100644 --- a/src/main/java/com/nohit/jira_project/service/Impl/ChiTietDonHangServiceImpl.java +++ b/src/main/java/com/nohit/ecommerce_project/service/impl/ChiTietDonHangServiceImpl.java @@ -1,24 +1,28 @@ -package com.nohit.jira_project.service.Impl; +package com.nohit.ecommerce_project.service.impl; + +import lombok.*; import java.util.*; import javax.transaction.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.repository.*; -import com.nohit.jira_project.service.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.repository.*; +import com.nohit.ecommerce_project.service.*; import lombok.extern.slf4j.*; +/** + * Cài đặt nghiệp vụ và chuẩn hóa dữ liệu cho service ChiTietDonHang. + */ @Service @Transactional @Slf4j +@RequiredArgsConstructor public class ChiTietDonHangServiceImpl implements ChiTietDonHangService { - @Autowired - private ChiTietDonHangRepository chiTietDonHangRepository; + private final ChiTietDonHangRepository chiTietDonHangRepository; @Override public List getDsChiTietDonHang() { diff --git a/src/main/java/com/nohit/jira_project/service/Impl/ChiTietGioHangServiceImpl.java b/src/main/java/com/nohit/ecommerce_project/service/impl/ChiTietGioHangServiceImpl.java similarity index 74% rename from src/main/java/com/nohit/jira_project/service/Impl/ChiTietGioHangServiceImpl.java rename to src/main/java/com/nohit/ecommerce_project/service/impl/ChiTietGioHangServiceImpl.java index 2cbd217..777aea1 100644 --- a/src/main/java/com/nohit/jira_project/service/Impl/ChiTietGioHangServiceImpl.java +++ b/src/main/java/com/nohit/ecommerce_project/service/impl/ChiTietGioHangServiceImpl.java @@ -1,24 +1,28 @@ -package com.nohit.jira_project.service.Impl; +package com.nohit.ecommerce_project.service.impl; + +import lombok.*; import java.util.*; import javax.transaction.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.repository.*; -import com.nohit.jira_project.service.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.repository.*; +import com.nohit.ecommerce_project.service.*; import lombok.extern.slf4j.*; +/** + * Cài đặt nghiệp vụ và chuẩn hóa dữ liệu cho service ChiTietGioHang. + */ @Service @Transactional @Slf4j +@RequiredArgsConstructor public class ChiTietGioHangServiceImpl implements ChiTietGioHangService { - @Autowired - private ChiTietGioHangRepository chiTietGioHangRepository; + private final ChiTietGioHangRepository chiTietGioHangRepository; @Override public List getDsChiTietGioHang() { diff --git a/src/main/java/com/nohit/jira_project/service/Impl/CreditCardServiceImpl.java b/src/main/java/com/nohit/ecommerce_project/service/impl/CreditCardServiceImpl.java similarity index 74% rename from src/main/java/com/nohit/jira_project/service/Impl/CreditCardServiceImpl.java rename to src/main/java/com/nohit/ecommerce_project/service/impl/CreditCardServiceImpl.java index 00fd0c3..06ed60b 100644 --- a/src/main/java/com/nohit/jira_project/service/Impl/CreditCardServiceImpl.java +++ b/src/main/java/com/nohit/ecommerce_project/service/impl/CreditCardServiceImpl.java @@ -1,28 +1,30 @@ -package com.nohit.jira_project.service.Impl; +package com.nohit.ecommerce_project.service.impl; + +import lombok.*; import java.util.*; import javax.transaction.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.repository.*; -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.repository.*; +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; import lombok.extern.slf4j.*; +/** + * Cài đặt nghiệp vụ và chuẩn hóa dữ liệu cho service CreditCard. + */ @Service @Transactional @Slf4j +@RequiredArgsConstructor public class CreditCardServiceImpl implements CreditCardService { - @Autowired - private CreditCardRepository creditCardRepository; - - @Autowired - private StringUtil stringUtil; + private final CreditCardRepository creditCardRepository; + private final StringUtil stringUtil; @Override public List getDsCreditCard() { diff --git a/src/main/java/com/nohit/jira_project/service/Impl/DonHangServiceImpl.java b/src/main/java/com/nohit/ecommerce_project/service/impl/DonHangServiceImpl.java similarity index 72% rename from src/main/java/com/nohit/jira_project/service/Impl/DonHangServiceImpl.java rename to src/main/java/com/nohit/ecommerce_project/service/impl/DonHangServiceImpl.java index 86757fa..5c33f8f 100644 --- a/src/main/java/com/nohit/jira_project/service/Impl/DonHangServiceImpl.java +++ b/src/main/java/com/nohit/ecommerce_project/service/impl/DonHangServiceImpl.java @@ -1,24 +1,28 @@ -package com.nohit.jira_project.service.Impl; +package com.nohit.ecommerce_project.service.impl; + +import lombok.*; import java.util.*; import javax.transaction.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.repository.*; -import com.nohit.jira_project.service.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.repository.*; +import com.nohit.ecommerce_project.service.*; import lombok.extern.slf4j.*; +/** + * Cài đặt nghiệp vụ và chuẩn hóa dữ liệu cho service DonHang. + */ @Service @Transactional @Slf4j +@RequiredArgsConstructor public class DonHangServiceImpl implements DonHangService { - @Autowired - private DonHangRepository donHangRepository; + private final DonHangRepository donHangRepository; @Override public List getDsDonHang() { diff --git a/src/main/java/com/nohit/jira_project/service/Impl/GioHangServiceImpl.java b/src/main/java/com/nohit/ecommerce_project/service/impl/GioHangServiceImpl.java similarity index 76% rename from src/main/java/com/nohit/jira_project/service/Impl/GioHangServiceImpl.java rename to src/main/java/com/nohit/ecommerce_project/service/impl/GioHangServiceImpl.java index d6ed86a..7e334ce 100644 --- a/src/main/java/com/nohit/jira_project/service/Impl/GioHangServiceImpl.java +++ b/src/main/java/com/nohit/ecommerce_project/service/impl/GioHangServiceImpl.java @@ -1,24 +1,28 @@ -package com.nohit.jira_project.service.Impl; +package com.nohit.ecommerce_project.service.impl; + +import lombok.*; import java.util.*; import javax.transaction.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.repository.*; -import com.nohit.jira_project.service.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.repository.*; +import com.nohit.ecommerce_project.service.*; import lombok.extern.slf4j.*; +/** + * Cài đặt nghiệp vụ và chuẩn hóa dữ liệu cho service GioHang. + */ @Service @Transactional @Slf4j +@RequiredArgsConstructor public class GioHangServiceImpl implements GioHangService { - @Autowired - private GioHangRepository gioHangRepository; + private final GioHangRepository gioHangRepository; @Override public List getDsGioHang() { diff --git a/src/main/java/com/nohit/jira_project/service/Impl/KhachHangServiceImpl.java b/src/main/java/com/nohit/ecommerce_project/service/impl/KhachHangServiceImpl.java similarity index 86% rename from src/main/java/com/nohit/jira_project/service/Impl/KhachHangServiceImpl.java rename to src/main/java/com/nohit/ecommerce_project/service/impl/KhachHangServiceImpl.java index 329d855..a011d97 100644 --- a/src/main/java/com/nohit/jira_project/service/Impl/KhachHangServiceImpl.java +++ b/src/main/java/com/nohit/ecommerce_project/service/impl/KhachHangServiceImpl.java @@ -1,4 +1,6 @@ -package com.nohit.jira_project.service.Impl; +package com.nohit.ecommerce_project.service.impl; + +import lombok.*; import java.io.*; import java.util.*; @@ -6,47 +8,41 @@ import javax.mail.*; import javax.transaction.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.mail.javamail.*; import org.springframework.security.core.authority.*; import org.springframework.security.core.userdetails.*; import org.springframework.security.crypto.password.*; import org.springframework.stereotype.Service; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.repository.*; -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.repository.*; +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; import lombok.extern.slf4j.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; import static java.util.Collections.*; import static net.bytebuddy.utility.RandomString.*; +/** + * Cài đặt nghiệp vụ và chuẩn hóa dữ liệu cho service KhachHang. + */ @Service @Transactional @Slf4j +@RequiredArgsConstructor public class KhachHangServiceImpl implements KhachHangService, UserDetailsService { - @Autowired - private KhachHangRepository khachHangRepository; - - @Autowired - private PasswordEncoder passwordEncoder; - - @Autowired - private StringUtil stringUtil; - - @Autowired - private AddressUtil addressUtil; - - @Autowired - private JavaMailSender mailSender; + private final KhachHangRepository khachHangRepository; + private final PasswordEncoder passwordEncoder; + private final StringUtil stringUtil; + private final AddressUtil addressUtil; + private final JavaMailSender mailSender; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { var user = khachHangRepository.findByEmail(username); - // check user exists + // Kiểm tra khách hàng có tồn tại. if (user == null) { log.error("khach_hang not found"); throw new UsernameNotFoundException("khach_hang not found"); diff --git a/src/main/java/com/nohit/jira_project/service/Impl/NguoiNhanServiceImpl.java b/src/main/java/com/nohit/ecommerce_project/service/impl/NguoiNhanServiceImpl.java similarity index 71% rename from src/main/java/com/nohit/jira_project/service/Impl/NguoiNhanServiceImpl.java rename to src/main/java/com/nohit/ecommerce_project/service/impl/NguoiNhanServiceImpl.java index 7570e46..c937487 100644 --- a/src/main/java/com/nohit/jira_project/service/Impl/NguoiNhanServiceImpl.java +++ b/src/main/java/com/nohit/ecommerce_project/service/impl/NguoiNhanServiceImpl.java @@ -1,34 +1,32 @@ -package com.nohit.jira_project.service.Impl; +package com.nohit.ecommerce_project.service.impl; + +import lombok.*; import java.util.*; import javax.transaction.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.repository.*; -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.repository.*; +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; import lombok.extern.slf4j.*; +/** + * Cài đặt nghiệp vụ và chuẩn hóa dữ liệu cho service NguoiNhan. + */ @Service @Transactional @Slf4j +@RequiredArgsConstructor public class NguoiNhanServiceImpl implements NguoiNhanService { - @Autowired - private NguoiNhanRepository nguoiNhanRepository; - - @Autowired - private StringUtil stringUtil; - - @Autowired - private TextUtil textUtil; - - @Autowired - private AddressUtil addressUtil; + private final NguoiNhanRepository nguoiNhanRepository; + private final StringUtil stringUtil; + private final TextUtil textUtil; + private final AddressUtil addressUtil; @Override public List getDsNguoiNhan() { diff --git a/src/main/java/com/nohit/jira_project/service/Impl/NhanXetServiceImpl.java b/src/main/java/com/nohit/ecommerce_project/service/impl/NhanXetServiceImpl.java similarity index 68% rename from src/main/java/com/nohit/jira_project/service/Impl/NhanXetServiceImpl.java rename to src/main/java/com/nohit/ecommerce_project/service/impl/NhanXetServiceImpl.java index 215637c..9ffa192 100644 --- a/src/main/java/com/nohit/jira_project/service/Impl/NhanXetServiceImpl.java +++ b/src/main/java/com/nohit/ecommerce_project/service/impl/NhanXetServiceImpl.java @@ -1,28 +1,30 @@ -package com.nohit.jira_project.service.Impl; +package com.nohit.ecommerce_project.service.impl; + +import lombok.*; import java.util.*; import javax.transaction.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.repository.*; -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.repository.*; +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; import lombok.extern.slf4j.*; +/** + * Cài đặt nghiệp vụ và chuẩn hóa dữ liệu cho service NhanXet. + */ @Service @Transactional @Slf4j +@RequiredArgsConstructor public class NhanXetServiceImpl implements NhanXetService { - @Autowired - private NhanXetRepository nhanXetRepository; - - @Autowired - private TextUtil textUtil; + private final NhanXetRepository nhanXetRepository; + private final TextUtil textUtil; @Override public List getDsNhanXet() { diff --git a/src/main/java/com/nohit/jira_project/service/Impl/SanPhamServiceImpl.java b/src/main/java/com/nohit/ecommerce_project/service/impl/SanPhamServiceImpl.java similarity index 67% rename from src/main/java/com/nohit/jira_project/service/Impl/SanPhamServiceImpl.java rename to src/main/java/com/nohit/ecommerce_project/service/impl/SanPhamServiceImpl.java index e324841..4176c89 100644 --- a/src/main/java/com/nohit/jira_project/service/Impl/SanPhamServiceImpl.java +++ b/src/main/java/com/nohit/ecommerce_project/service/impl/SanPhamServiceImpl.java @@ -1,33 +1,33 @@ -package com.nohit.jira_project.service.Impl; +package com.nohit.ecommerce_project.service.impl; + +import lombok.*; import java.util.*; import javax.transaction.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.repository.*; -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.repository.*; +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; import lombok.extern.slf4j.*; import static java.util.stream.Collectors.*; +/** + * Cài đặt nghiệp vụ và chuẩn hóa dữ liệu cho service SanPham. + */ @Service @Transactional @Slf4j +@RequiredArgsConstructor public class SanPhamServiceImpl implements SanPhamService { - @Autowired - private SanPhamRepository sanPhamRepository; - - @Autowired - private StringUtil stringUtil; - - @Autowired - private TextUtil textUtil; + private final SanPhamRepository sanPhamRepository; + private final StringUtil stringUtil; + private final TextUtil textUtil; @Override public List getDsSanPham() { @@ -39,8 +39,8 @@ public List getDsSanPham() { public List getDsSanPham(String phanLoai) { log.info("Fetching all san_pham by phan_loai {}", phanLoai); var result = sanPhamRepository.findByPhanLoai(phanLoai); - // check exists san_pham - if (result.size() == 0) { + // Kiểm tra danh sách sản phẩm theo phân loại. + if (result.isEmpty()) { result = sanPhamRepository.findAll(); } return result.stream().filter(sanPham -> sanPham.getTonKho() > 0).collect(toList()); @@ -71,11 +71,13 @@ public SanPham saveSanPham(SanPham sanPham) { @Override public void updateTonKho(int id, int tonKho) { log.info("Update ton_kho san_pham with id: {}", id); + sanPhamRepository.saveTonKho(id, tonKho); } @Override public void updateDanhGia(int id, int danhGia) { log.info("Update danh_gia san_pham with id: {}", id); + sanPhamRepository.saveDanhGia(id, danhGia); } @Override @@ -93,9 +95,7 @@ public List getDsSanPhamTonKho() { @Override public List getDsSanPhamTopSale() { var dsSanPham = getDsSanPhamTonKho(); - dsSanPham.sort((firstProduct, secondProduct) -> { - return secondProduct.getTonKho() < firstProduct.getTonKho() ? 1 : -1; - }); + dsSanPham.sort(Comparator.comparingInt(SanPham::getTonKho)); log.info("Fetching san_pham with top sale"); return dsSanPham; } @@ -103,9 +103,7 @@ public List getDsSanPhamTopSale() { @Override public List getDsSanPhamNewest() { var dsSanPham = getDsSanPhamTonKho(); - dsSanPham.sort((firstProduct, secondProduct) -> { - return secondProduct.getNgayNhap().compareTo(firstProduct.getNgayNhap()); - }); + dsSanPham.sort(Comparator.comparing(SanPham::getNgayNhap).reversed()); log.info("Fetching san_pham with newest"); return dsSanPham; } @@ -113,10 +111,7 @@ public List getDsSanPhamNewest() { @Override public List getDsSanPhamAscendingPrice() { var dsSanPham = getDsSanPhamTonKho(); - dsSanPham.sort((firstProduct, secondProduct) -> { - return secondProduct.getGiaGoc() - secondProduct.getKhuyenMai() < firstProduct.getGiaGoc() - - firstProduct.getKhuyenMai() ? 1 : -1; - }); + dsSanPham.sort(Comparator.comparingInt(this::getGiaSauKhuyenMai)); log.info("Fetching san_pham with ascending price"); return dsSanPham; } @@ -124,20 +119,15 @@ public List getDsSanPhamAscendingPrice() { @Override public List getDsSanPhamDescendingPrice() { var dsSanPham = getDsSanPhamTonKho(); - dsSanPham.sort((firstProduct, secondProduct) -> { - return secondProduct.getGiaGoc() - secondProduct.getKhuyenMai() > firstProduct.getGiaGoc() - - firstProduct.getKhuyenMai() ? 1 : -1; - }); - log.info("Fetching san_pham with ascending price"); + dsSanPham.sort(Comparator.comparingInt(this::getGiaSauKhuyenMai).reversed()); + log.info("Fetching san_pham with descending price"); return dsSanPham; } @Override public List getDsSanPhamAscendingDiscount() { var dsSanPham = getDsSanPhamTonKho(); - dsSanPham.sort((firstProduct, secondProduct) -> { - return secondProduct.getKhuyenMai() < firstProduct.getKhuyenMai() ? 1 : -1; - }); + dsSanPham.sort(Comparator.comparingInt(SanPham::getKhuyenMai)); log.info("Fetching san_pham with ascending discount"); return dsSanPham; } @@ -145,10 +135,12 @@ public List getDsSanPhamAscendingDiscount() { @Override public List getDsSanPhamDescendingDiscount() { var dsSanPham = getDsSanPhamTonKho(); - dsSanPham.sort((firstProduct, secondProduct) -> { - return secondProduct.getKhuyenMai() > firstProduct.getKhuyenMai() ? 1 : -1; - }); + dsSanPham.sort(Comparator.comparingInt(SanPham::getKhuyenMai).reversed()); log.info("Fetching san_pham with descending discount"); return dsSanPham; } + + private int getGiaSauKhuyenMai(SanPham sanPham) { + return sanPham.getGiaGoc() - sanPham.getKhuyenMai(); + } } diff --git a/src/main/java/com/nohit/jira_project/service/Impl/TheoDoiServiceImpl.java b/src/main/java/com/nohit/ecommerce_project/service/impl/TheoDoiServiceImpl.java similarity index 72% rename from src/main/java/com/nohit/jira_project/service/Impl/TheoDoiServiceImpl.java rename to src/main/java/com/nohit/ecommerce_project/service/impl/TheoDoiServiceImpl.java index 0ca2ad1..a791d79 100644 --- a/src/main/java/com/nohit/jira_project/service/Impl/TheoDoiServiceImpl.java +++ b/src/main/java/com/nohit/ecommerce_project/service/impl/TheoDoiServiceImpl.java @@ -1,28 +1,30 @@ -package com.nohit.jira_project.service.Impl; +package com.nohit.ecommerce_project.service.impl; + +import lombok.*; import java.util.*; import javax.transaction.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.repository.*; -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.repository.*; +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; import lombok.extern.slf4j.*; +/** + * Cài đặt nghiệp vụ và chuẩn hóa dữ liệu cho service TheoDoi. + */ @Service @Transactional @Slf4j +@RequiredArgsConstructor public class TheoDoiServiceImpl implements TheoDoiService { - @Autowired - private TheoDoiRepository theoDoiRepository; - - @Autowired - private StringUtil stringUtil; + private final TheoDoiRepository theoDoiRepository; + private final StringUtil stringUtil; @Override public List getDsTheoDoi() { diff --git a/src/main/java/com/nohit/jira_project/service/Impl/ThuPhanHoiServiceImpl.java b/src/main/java/com/nohit/ecommerce_project/service/impl/ThuPhanHoiServiceImpl.java similarity index 70% rename from src/main/java/com/nohit/jira_project/service/Impl/ThuPhanHoiServiceImpl.java rename to src/main/java/com/nohit/ecommerce_project/service/impl/ThuPhanHoiServiceImpl.java index 04de96f..e1abc9c 100644 --- a/src/main/java/com/nohit/jira_project/service/Impl/ThuPhanHoiServiceImpl.java +++ b/src/main/java/com/nohit/ecommerce_project/service/impl/ThuPhanHoiServiceImpl.java @@ -1,31 +1,31 @@ -package com.nohit.jira_project.service.Impl; +package com.nohit.ecommerce_project.service.impl; + +import lombok.*; import java.util.*; import javax.transaction.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.repository.*; -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.repository.*; +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; import lombok.extern.slf4j.*; +/** + * Cài đặt nghiệp vụ và chuẩn hóa dữ liệu cho service ThuPhanHoi. + */ @Service @Transactional @Slf4j +@RequiredArgsConstructor public class ThuPhanHoiServiceImpl implements ThuPhanHoiService { - @Autowired - private ThuPhanHoiRepository phanHoiRepository; - - @Autowired - private StringUtil stringUtil; - - @Autowired - private TextUtil textUtil; + private final ThuPhanHoiRepository phanHoiRepository; + private final StringUtil stringUtil; + private final TextUtil textUtil; @Override public List getDsThuPhanHoi() { diff --git a/src/main/java/com/nohit/jira_project/service/Impl/TinhThanhServiceImpl.java b/src/main/java/com/nohit/ecommerce_project/service/impl/TinhThanhServiceImpl.java similarity index 68% rename from src/main/java/com/nohit/jira_project/service/Impl/TinhThanhServiceImpl.java rename to src/main/java/com/nohit/ecommerce_project/service/impl/TinhThanhServiceImpl.java index a654b41..8339d45 100644 --- a/src/main/java/com/nohit/jira_project/service/Impl/TinhThanhServiceImpl.java +++ b/src/main/java/com/nohit/ecommerce_project/service/impl/TinhThanhServiceImpl.java @@ -1,28 +1,30 @@ -package com.nohit.jira_project.service.Impl; +package com.nohit.ecommerce_project.service.impl; + +import lombok.*; import java.util.*; import javax.transaction.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.repository.*; -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.repository.*; +import com.nohit.ecommerce_project.service.*; +import com.nohit.ecommerce_project.util.*; import lombok.extern.slf4j.*; +/** + * Cài đặt nghiệp vụ và chuẩn hóa dữ liệu cho service TinhThanh. + */ @Service @Transactional @Slf4j +@RequiredArgsConstructor public class TinhThanhServiceImpl implements TinhThanhService { - @Autowired - private TinhThanhRepository tinhThanhRepository; - - @Autowired - private StringUtil stringUtil; + private final TinhThanhRepository tinhThanhRepository; + private final StringUtil stringUtil; @Override public List getDsTinhThanh() { diff --git a/src/main/java/com/nohit/jira_project/util/AddressUtil.java b/src/main/java/com/nohit/ecommerce_project/util/AddressUtil.java similarity index 97% rename from src/main/java/com/nohit/jira_project/util/AddressUtil.java rename to src/main/java/com/nohit/ecommerce_project/util/AddressUtil.java index f804e96..4a54f19 100644 --- a/src/main/java/com/nohit/jira_project/util/AddressUtil.java +++ b/src/main/java/com/nohit/ecommerce_project/util/AddressUtil.java @@ -1,33 +1,37 @@ -package com.nohit.jira_project.util; +package com.nohit.ecommerce_project.util; + +import lombok.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; import org.thymeleaf.util.*; import static org.springframework.util.StringUtils.*; -// Ex: " 6C Đường số 8,phường.linh Tây- Quận Thủ đức-HCM " +// Ví dụ: " 6C Đường số 8,phường.linh Tây- Quận Thủ đức-HCM " +/** + * Tiện ích chuẩn hóa địa chỉ tiếng Việt trước khi lưu hoặc hiển thị. + */ @Component +@RequiredArgsConstructor public class AddressUtil { - @Autowired - private StringUtil stringUtil; + private final StringUtil stringUtil; - // Re-format violate rule one "-" + // Chuẩn hóa địa chỉ có quá nhiều dấu gạch ngang. private String reformatViolateOneHyphen(String s) { return s.length() - s.replaceAll("-", "").length() > 1 ? s.replaceAll("-", ",") : s; } - // Re-format violate rule single "." + // Chuẩn hóa địa chỉ có nhiều dấu chấm liên tiếp. private String reformatViolateSingleDot(String s) { return s.replaceAll("\\.{2,}", "."); } - // Insert keyword "tỉnh" or "thành phố" before city name + // Bổ sung tiền tố tỉnh/thành phố trước tên địa phương cuối. private String insertKeywordTinhThanh(String s) { return hasText(s) ? s.replaceAll(",(?!.*,)", ",TP.") : s; } - // Parse string to legal address + // Chuẩn hóa chuỗi địa chỉ về dạng dễ đọc. public String parseToLegalAddress(String s) { if (hasText(s)) { s = stringUtil.removeWhiteSpaceBeforeAndAfterChar(stringUtil.removeWhiteSpaceBeforeAndAfterChar( @@ -37,7 +41,7 @@ public String parseToLegalAddress(String s) { stringUtil.removeWhiteSpaceBeginAndEnd(s), "-")), ",", ", "), "\\.", "\\. ")), - ","), "/"); // para para for condition + ","), "/"); // Tách riêng bước chuẩn hóa để giữ điều kiện đọc được. s = stringUtil.removeWhiteSpaceBeforeAndAfterChar(reformatViolateSingleDot(stringUtil .replaceWordFoundByKeyword(stringUtil.replaceWordFoundByKeyword( stringUtil.replaceWordFoundByKeyword(stringUtil.replaceWordFoundByKeyword( diff --git a/src/main/java/com/nohit/ecommerce_project/util/ApplicationUtil.java b/src/main/java/com/nohit/ecommerce_project/util/ApplicationUtil.java new file mode 100644 index 0000000..14fd1c0 --- /dev/null +++ b/src/main/java/com/nohit/ecommerce_project/util/ApplicationUtil.java @@ -0,0 +1,69 @@ +package com.nohit.ecommerce_project.util; + +import lombok.*; + +import java.util.*; + +import org.springframework.stereotype.*; +import org.springframework.web.servlet.*; + +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.service.*; + +import static com.nohit.ecommerce_project.common.Bean.*; +import static com.nohit.ecommerce_project.constant.AttributeConstant.*; + +/** + * Tiện ích gom các thao tác lặp lại cho giỏ hàng, phân trang và thông báo giao diện. + */ +@Component +@RequiredArgsConstructor +public class ApplicationUtil { + private final GioHangService gioHangService; + + // Lấy giỏ hàng hiện tại hoặc tạo mới khi khách hàng chưa có giỏ. + public GioHang getOrDefaultGioHang(KhachHang khachHang) { + if (khachHang == null) { + return new GioHang(); + } else { + var gioHang = khachHang.getGioHang(); + return gioHang == null ? gioHangService.createGioHang(khachHang) : gioHang; + } + } + + // Giới hạn số phần tử hiển thị mà không làm lỗi khi dữ liệu ít hơn kỳ vọng. + public List limit(List items, int maxSize) { + if (items == null || items.isEmpty() || maxSize <= 0) { + return Collections.emptyList(); + } + return items.subList(0, Math.min(items.size(), maxSize)); + } + + // Cắt dữ liệu phân trang và tự kẹp page vào khoảng hợp lệ. + public List page(List items, int page, int pageSize) { + if (items == null || items.isEmpty() || pageSize <= 0) { + return Collections.emptyList(); + } + var currentPage = Math.min(Math.max(page, 1), maxPage(items, pageSize)); + var fromIndex = (currentPage - 1) * pageSize; + var toIndex = Math.min(fromIndex + pageSize, items.size()); + return items.subList(fromIndex, toIndex); + } + + // Tính tổng số trang, luôn trả tối thiểu 1 để template không bị trạng thái rỗng khó xử lý. + public int maxPage(List items, int pageSize) { + if (items == null || items.isEmpty() || pageSize <= 0) { + return 1; + } + return (items.size() - 1) / pageSize + 1; + } + + // Đưa thông báo flash-like từ Bean chung vào ModelAndView rồi tắt cờ hiển thị. + public boolean showMessageBox(ModelAndView mav) { + if (_isMsgShow) { + mav.addObject(FLAG_MSG_PARAM, true); + mav.addObject(MSG_PARAM, _msg); + } + return false; + } +} diff --git a/src/main/java/com/nohit/ecommerce_project/util/AuthenticationUtil.java b/src/main/java/com/nohit/ecommerce_project/util/AuthenticationUtil.java new file mode 100644 index 0000000..a3c1c8c --- /dev/null +++ b/src/main/java/com/nohit/ecommerce_project/util/AuthenticationUtil.java @@ -0,0 +1,27 @@ +package com.nohit.ecommerce_project.util; + +import lombok.*; + +import org.springframework.security.authentication.*; +import org.springframework.stereotype.*; + +import com.nohit.ecommerce_project.model.*; +import com.nohit.ecommerce_project.service.*; + +import static org.springframework.security.core.context.SecurityContextHolder.*; + +/** + * Tiện ích lấy tài khoản khách hàng hiện tại từ Spring SecurityContext. + */ +@Component +@RequiredArgsConstructor +public class AuthenticationUtil { + private final KhachHangService khachHangService; + + // Lấy tài khoản hiện tại từ SecurityContextHolder. + public KhachHang getAccount() { + var authentication = getContext().getAuthentication(); + return authentication == null || authentication instanceof AnonymousAuthenticationToken ? null + : khachHangService.getKhachHang(authentication.getName()); + } +} diff --git a/src/main/java/com/nohit/jira_project/util/NumberUtil.java b/src/main/java/com/nohit/ecommerce_project/util/NumberUtil.java similarity index 61% rename from src/main/java/com/nohit/jira_project/util/NumberUtil.java rename to src/main/java/com/nohit/ecommerce_project/util/NumberUtil.java index 815eb8a..617408f 100644 --- a/src/main/java/com/nohit/jira_project/util/NumberUtil.java +++ b/src/main/java/com/nohit/ecommerce_project/util/NumberUtil.java @@ -1,12 +1,15 @@ -package com.nohit.jira_project.util; +package com.nohit.ecommerce_project.util; import org.springframework.stereotype.*; import static java.lang.Integer.*; +/** + * Tiện ích kiểm tra chuỗi có thể chuyển thành số nguyên hay không. + */ @Component public class NumberUtil { - // Check string is number or not + // Kiểm tra chuỗi có phải số nguyên hay không. public boolean isNumeric(String s) { try { parseInt(s); diff --git a/src/main/java/com/nohit/jira_project/util/StringUtil.java b/src/main/java/com/nohit/ecommerce_project/util/StringUtil.java similarity index 72% rename from src/main/java/com/nohit/jira_project/util/StringUtil.java rename to src/main/java/com/nohit/ecommerce_project/util/StringUtil.java index accc264..252732b 100644 --- a/src/main/java/com/nohit/jira_project/util/StringUtil.java +++ b/src/main/java/com/nohit/ecommerce_project/util/StringUtil.java @@ -1,33 +1,36 @@ -package com.nohit.jira_project.util; +package com.nohit.ecommerce_project.util; import org.springframework.stereotype.*; import org.thymeleaf.util.*; import static org.springframework.util.StringUtils.*; +/** + * Tiện ích chuẩn hóa chuỗi, tên, email và khoảng trắng cho dữ liệu đầu vào. + */ @Component public class StringUtil { - // Search word + // Kiểm tra chuỗi có chứa từ khóa. public boolean isWordContains(String s, String word) { return hasText(s) ? s.toUpperCase().contains(word.toUpperCase()) : false; } - // Replace word found by keyword + // Thay từ tìm thấy bằng từ khóa chuẩn hóa. public String replaceWordFoundByKeyword(String s, String word, String keyword) { return hasText(s) ? s.replaceAll("(?i)" + word + "", keyword) : s; } - // Replace multi by single whitespace + // Rút gọn nhiều khoảng trắng thành một khoảng trắng. public String replaceMultiBySingleWhitespace(String s) { return hasText(s) ? s.replaceAll("\\s+", " ") : s; } - // Parse to name + // Chuẩn hóa họ tên tiếng Việt. public String parseName(String s) { return hasText(s) ? titleCase(replaceMultiBySingleWhitespace(removeNumAndWhiteSpaceBeginAndEnd(s))) : s; } - // Parse to international name + // Chuẩn hóa tên theo dạng quốc tế. public String parseNameInternational(String s) { return hasText(s) ? titleCase( @@ -35,7 +38,7 @@ public String parseNameInternational(String s) { : s; } - // Parse to on card name + // Chuẩn hóa tên in trên thẻ. public String parseNameOnCard(String s) { return hasText(s) ? upperCase( @@ -43,37 +46,37 @@ public String parseNameOnCard(String s) { : s; } - // Parse to email + // Chuẩn hóa email. public String parseEmail(String s) { return hasText(s) ? lowerCase(removeSpCharsBeginAndEnd(removeNumAndWhiteSpaceEnd(s))) : s; } - // Convert to lower case advanced + // Chuyển về chữ thường khi có nội dung. public String lowerCase(String s) { return hasText(s) ? s.toLowerCase() : s; } - // Convert to upper case advanced + // Chuyển về chữ hoa khi có nội dung. public String upperCase(String s) { return hasText(s) ? s.toUpperCase() : s; } - // Convert to capitalize case advanced + // Viết hoa ký tự đầu khi có nội dung. public String capitalizeCase(String s) { return hasText(s) ? capitalize(s) : s; } - // Convert to sentence case advanced + // Chuẩn hóa dạng câu. public String sentenceCase(String s) { return hasText(s) ? capitalize(s.toLowerCase()) : s; } - // Convert to title case advanced + // Chuẩn hóa dạng tiêu đề. public String titleCase(String s) { return hasText(s) ? StringUtils.capitalizeWords(s.toLowerCase()) : s; } - // Capitalize after character + // Viết hoa ký tự sau dấu phân tách. public String capitalizeAfterChar(String s, String character) { if (hasText(s)) { var index = s.indexOf(character); @@ -84,62 +87,62 @@ public String capitalizeAfterChar(String s, String character) { return s; } - // Remove all whitespace at begin + // Xóa khoảng trắng đầu chuỗi. public String removeWhiteSpaceBegin(String s) { return hasText(s) ? s.replaceAll("^\\s+", "") : s; } - // Remove all whitespace at end + // Xóa khoảng trắng cuối chuỗi. public String removeWhiteSpaceEnd(String s) { return hasText(s) ? s.replaceAll("\\s+$", "") : s; } - // Remove all whitespace at begin and end + // Xóa khoảng trắng ở cả đầu và cuối chuỗi. public String removeWhiteSpaceBeginAndEnd(String s) { return hasText(s) ? s.replaceAll("^\\s+|\\s+$", "") : s; } - // Remove all special characters at begin + // Xóa ký tự đặc biệt ở đầu chuỗi. public String removeSpCharsBegin(String s) { return hasText(s) ? s.replaceAll("^[^a-zA-Z0-9]+", "") : s; } - // Remove all special characters at end + // Xóa ký tự đặc biệt ở cuối chuỗi. public String removeSpCharsEnd(String s) { return hasText(s) ? s.replaceAll("[^a-zA-Z0-9]+$", "") : s; } - // Remove all special characters at begin and end + // Xóa ký tự đặc biệt ở cả đầu và cuối chuỗi. public String removeSpCharsBeginAndEnd(String s) { return hasText(s) ? s.replaceAll("^[^a-zA-Z0-9]+|[^a-zA-Z0-9]+$", "") : s; } - // Remove all number and whitespace at begin + // Xóa số và khoảng trắng ở đầu chuỗi. public String removeNumAndWhiteSpaceBegin(String s) { return hasText(s) ? s.replaceAll("^[0-9\\s]+", "") : s; } - // Remove all number and whitespace at end + // Xóa số và khoảng trắng ở cuối chuỗi. public String removeNumAndWhiteSpaceEnd(String s) { return hasText(s) ? s.replaceAll("[0-9\\s]+$", "") : s; } - // Remove all number and whitespace at begin and end + // Xóa số và khoảng trắng ở cả đầu và cuối chuỗi. public String removeNumAndWhiteSpaceBeginAndEnd(String s) { return hasText(s) ? s.replaceAll("^[0-9\\s]+|[0-9\\s]+$", "") : s; } - // Remove all whitespace before character + // Xóa khoảng trắng trước ký tự. public String removeWhiteSpaceBeforeChar(String s, String character) { return hasText(s) ? s.replaceAll("\\s+" + character, character) : s; } - // Remove all whitespace after character + // Xóa khoảng trắng sau ký tự. public String removeWhiteSpaceAfterChar(String s, String character) { return hasText(s) ? s.replaceAll(character + "\\s+", character) : s; } - // Remove all whitespace before and after character + // Xóa khoảng trắng trước và sau ký tự. public String removeWhiteSpaceBeforeAndAfterChar(String s, String character) { return hasText(s) ? s.replaceAll("\\s*" + character + "\\s*", character) : s; } diff --git a/src/main/java/com/nohit/jira_project/util/TextUtil.java b/src/main/java/com/nohit/ecommerce_project/util/TextUtil.java similarity index 94% rename from src/main/java/com/nohit/jira_project/util/TextUtil.java rename to src/main/java/com/nohit/ecommerce_project/util/TextUtil.java index a9a35cf..349254d 100644 --- a/src/main/java/com/nohit/jira_project/util/TextUtil.java +++ b/src/main/java/com/nohit/ecommerce_project/util/TextUtil.java @@ -1,28 +1,30 @@ -package com.nohit.jira_project.util; +package com.nohit.ecommerce_project.util; + +import lombok.*; -import org.springframework.beans.factory.annotation.*; import org.springframework.stereotype.*; import static org.springframework.util.StringUtils.*; -//Ex: " ai?đứng như bóng dừa!tóc(dài )bay( trong gió). có phải,người còn đó:là con gái của Bến Tre thời 4.0. " +// Ví dụ: " ai?đứng như bóng dừa!tóc(dài )bay( trong gió). có phải,người còn đó:là con gái của Bến Tre thời 4.0. " +/** + * Tiện ích chuẩn hóa đoạn mô tả sản phẩm và nội dung văn bản tiếng Việt. + */ @Component +@RequiredArgsConstructor public class TextUtil { - @Autowired - private StringUtil stringUtil; - - @Autowired - private NumberUtil numberUtil; + private final StringUtil stringUtil; + private final NumberUtil numberUtil; - // Add whitespace after character + // Thêm khoảng trắng sau ký tự khi cần. public String charWithSpace(String s, String character) { - // If string is not empty + // Chỉ xử lý khi chuỗi có nội dung. if (hasText(s)) { var index = s.indexOf(character); - // Found character + // Đã tìm thấy ký tự cần chuẩn hóa. if (index != -1) { var iStart = index + 1; - // Next character is not number + // Không thêm khoảng trắng khi ký tự kế tiếp là số. if (iStart < s.length() && !numberUtil.isNumeric(s.substring(iStart, iStart + 1))) { s = s.substring(0, index) + character + " " + s.substring(index + 1); } @@ -31,7 +33,7 @@ public String charWithSpace(String s, String character) { return s; } - // Parse string to legal text + // Chuẩn hóa văn bản mô tả về dạng dễ đọc. public String parseToLegalText(String s) { return capitalize(stringUtil.replaceMultiBySingleWhitespace(stringUtil.removeWhiteSpaceBeginAndEnd( charWithSpace(charWithSpace(charWithSpace(charWithSpace(charWithSpace(charWithSpace(stringUtil diff --git a/src/main/java/com/nohit/jira_project/JiraProjectApplication.java b/src/main/java/com/nohit/jira_project/JiraProjectApplication.java deleted file mode 100644 index ad599b8..0000000 --- a/src/main/java/com/nohit/jira_project/JiraProjectApplication.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.nohit.jira_project; - -import org.springframework.boot.*; -import org.springframework.boot.autoconfigure.*; - -@SpringBootApplication -public class JiraProjectApplication { - public static void main(String[] args) { - SpringApplication.run(JiraProjectApplication.class, args); - } -} diff --git a/src/main/java/com/nohit/jira_project/common/Bean.java b/src/main/java/com/nohit/jira_project/common/Bean.java deleted file mode 100644 index 330cf89..0000000 --- a/src/main/java/com/nohit/jira_project/common/Bean.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.nohit.jira_project.common; - -public class Bean { - public static String _msg; - public static boolean _isMsgShow; -} diff --git a/src/main/java/com/nohit/jira_project/controller/DonHangController.java b/src/main/java/com/nohit/jira_project/controller/DonHangController.java deleted file mode 100644 index 12a3018..0000000 --- a/src/main/java/com/nohit/jira_project/controller/DonHangController.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.nohit.jira_project.controller; - -import org.springframework.beans.factory.annotation.*; -import org.springframework.stereotype.*; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.servlet.*; - -import com.nohit.jira_project.service.*; -import com.nohit.jira_project.util.*; - -import static com.nohit.jira_project.common.Bean.*; -import static com.nohit.jira_project.constant.ApplicationConstant.Menu.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; -import static com.nohit.jira_project.constant.TemplateConstant.*; -import static com.nohit.jira_project.constant.ViewConstant.*; - -@Controller -@RequestMapping(ORDER_VIEW) -public class DonHangController { - @Autowired - private DonHangService donHangService; - - @Autowired - private AuthenticationUtil authenticationUtil; - - @Autowired - private ApplicationUtil applicationUtil; - - @GetMapping("") - public String order() { - _isMsgShow = true; - _msg = "Cần chọn 1 đơn hàng để xem!"; - return REDIRECT_PREFIX + HISTORY_VIEW; - } - - // Load order - @GetMapping(FIND_VIEW) - public ModelAndView orderFind(int id) { - var client = authenticationUtil.getAccount(); - // check current account still valid - if (client == null) { - return new ModelAndView(REDIRECT_PREFIX + LOGOUT_VIEW); - } else { - var mav = new ModelAndView(ORDER_TEMP); - mav.addObject(TITLE_PARAM, DON_HANG); - mav.addObject(CART_PARAM, client.getGioHang()); - mav.addObject(LOGIN_PARAM, client != null); - mav.addObject(ORDER_PARAM, donHangService.getDonHang(id)); - _isMsgShow = applicationUtil.showMessageBox(mav); - return mav; - } - } -} diff --git a/src/main/java/com/nohit/jira_project/controller/GioiThieuController.java b/src/main/java/com/nohit/jira_project/controller/GioiThieuController.java deleted file mode 100644 index 1855e4b..0000000 --- a/src/main/java/com/nohit/jira_project/controller/GioiThieuController.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.nohit.jira_project.controller; - -import org.springframework.beans.factory.annotation.*; -import org.springframework.stereotype.*; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.servlet.*; - -import com.nohit.jira_project.util.*; - -import static com.nohit.jira_project.common.Bean.*; -import static com.nohit.jira_project.constant.ApplicationConstant.Menu.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; -import static com.nohit.jira_project.constant.TemplateConstant.*; -import static com.nohit.jira_project.constant.ViewConstant.*; - -@Controller -@RequestMapping(ABOUT_VIEW) -public class GioiThieuController { - @Autowired - private ApplicationUtil applicationUtil; - - @Autowired - private AuthenticationUtil authenticationUtil; - - // Load about - @GetMapping("") - public ModelAndView about() { - var mav = new ModelAndView(ABOUT_TEMP); - var client = authenticationUtil.getAccount(); - mav.addObject(TITLE_PARAM, GIOI_THIEU); - mav.addObject(CART_PARAM, applicationUtil.getOrDefaultGioHang(client)); - mav.addObject(LOGIN_PARAM, client != null); - _isMsgShow = applicationUtil.showMessageBox(mav); - return mav; - } -} diff --git a/src/main/java/com/nohit/jira_project/controller/LichSuController.java b/src/main/java/com/nohit/jira_project/controller/LichSuController.java deleted file mode 100644 index a8b79e0..0000000 --- a/src/main/java/com/nohit/jira_project/controller/LichSuController.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.nohit.jira_project.controller; - -import org.springframework.beans.factory.annotation.*; -import org.springframework.stereotype.*; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.servlet.*; - -import com.nohit.jira_project.util.*; - -import static com.nohit.jira_project.common.Bean.*; -import static com.nohit.jira_project.constant.ApplicationConstant.Menu.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; -import static com.nohit.jira_project.constant.TemplateConstant.*; -import static com.nohit.jira_project.constant.ViewConstant.*; - -@Controller -@RequestMapping(HISTORY_VIEW) -public class LichSuController { - @Autowired - private AuthenticationUtil authenticationUtil; - - @Autowired - private ApplicationUtil applicationUtil; - - // Load history - @GetMapping("") - public ModelAndView history() { - var client = authenticationUtil.getAccount(); - // check current account still valid - if (client == null) { - return new ModelAndView(REDIRECT_PREFIX + LOGOUT_VIEW); - } else { - var mav = new ModelAndView(HISTORY_TEMP); - mav.addObject(TITLE_PARAM, LICH_SU); - mav.addObject(CART_PARAM, client.getGioHang()); - mav.addObject(LOGIN_PARAM, client != null); - mav.addObject(ORDERS_PARAM, client.getDsDonHang()); - _isMsgShow = applicationUtil.showMessageBox(mav); - return mav; - } - } -} diff --git a/src/main/java/com/nohit/jira_project/util/ApplicationUtil.java b/src/main/java/com/nohit/jira_project/util/ApplicationUtil.java deleted file mode 100644 index 898dd83..0000000 --- a/src/main/java/com/nohit/jira_project/util/ApplicationUtil.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.nohit.jira_project.util; - -import org.springframework.beans.factory.annotation.*; -import org.springframework.stereotype.*; -import org.springframework.web.servlet.*; - -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.service.*; - -import static com.nohit.jira_project.common.Bean.*; -import static com.nohit.jira_project.constant.AttributeConstant.*; - -@Component -public class ApplicationUtil { - @Autowired - private GioHangService gioHangService; - - // Get gio_hang by account or create new - public GioHang getOrDefaultGioHang(KhachHang khachHang) { - if (khachHang == null) { - return new GioHang(); - } else { - var gioHang = khachHang.getGioHang(); - return gioHang == null ? gioHangService.createGioHang(khachHang) : gioHang; - } - } - - // Show message - public boolean showMessageBox(ModelAndView mav) { - // check flag - if (_isMsgShow) { - mav.addObject(FLAG_MSG_PARAM, true); - mav.addObject(MSG_PARAM, _msg); - } - return false; - } -} diff --git a/src/main/java/com/nohit/jira_project/util/AuthenticationUtil.java b/src/main/java/com/nohit/jira_project/util/AuthenticationUtil.java deleted file mode 100644 index cf1e109..0000000 --- a/src/main/java/com/nohit/jira_project/util/AuthenticationUtil.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.nohit.jira_project.util; - -import org.springframework.beans.factory.annotation.*; -import org.springframework.security.authentication.*; -import org.springframework.stereotype.*; - -import com.nohit.jira_project.model.*; -import com.nohit.jira_project.service.*; - -import static org.springframework.security.core.context.SecurityContextHolder.*; - -@Component -public class AuthenticationUtil { - @Autowired - private KhachHangService khachHangService; - - // Get current user account from SecurityContextHolder - public KhachHang getAccount() { - var authentication = getContext().getAuthentication(); - return authentication instanceof AnonymousAuthenticationToken ? null - : khachHangService.getKhachHang(authentication.getName()); - } -} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 7e92456..8f5b1b8 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,18 +1,20 @@ +# Cấu hình runtime của ecommerce_project; credential được lấy từ biến môi trường. +spring.application.name=ecommerce_project server.port=${PORT:8080} spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -spring.datasource.url=jdbc:mysql://192.168.100.9:3306/ecommerce -spring.datasource.username=root -spring.datasource.password=admin123@ +spring.datasource.url=${DB_URL:jdbc:mysql://localhost:3306/ecommerce?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Ho_Chi_Minh} +spring.datasource.username=${DB_USERNAME:root} +spring.datasource.password=${DB_PASSWORD:} -spring.jpa.show-sql=true -spring.jpa.hibernate.ddl-auto=update +spring.jpa.show-sql=${JPA_SHOW_SQL:false} +spring.jpa.hibernate.ddl-auto=${JPA_DDL_AUTO:update} spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect -spring.jpa.properties.hibernate.format_sql=true +spring.jpa.properties.hibernate.format_sql=${JPA_FORMAT_SQL:false} -spring.mail.host=smtp.gmail.com -spring.mail.port=587 -spring.mail.username=nohitshopp@gmail.com -spring.mail.password=eukufrkwwurwnnug +spring.mail.host=${MAIL_HOST:smtp.gmail.com} +spring.mail.port=${MAIL_PORT:587} +spring.mail.username=${MAIL_USERNAME:} +spring.mail.password=${MAIL_PASSWORD:} spring.mail.properties.mail.smtp.auth=true -spring.mail.properties.mail.smtp.starttls.enable=true \ No newline at end of file +spring.mail.properties.mail.smtp.starttls.enable=true diff --git a/src/main/resources/static/css/responsive.css b/src/main/resources/static/css/responsive.css index 6575eb3..eb5187b 100644 --- a/src/main/resources/static/css/responsive.css +++ b/src/main/resources/static/css/responsive.css @@ -1,3 +1,4 @@ +/* Summary: CSS responsive giúp storefront hiển thị tốt trên nhiều kích thước màn hình. */ @media only screen and (max-width: 1199px) { div.cart-collaterals ul.products li.product { float: left; diff --git a/src/main/resources/static/css/style-ex.css b/src/main/resources/static/css/style-ex.css index d0690ea..03ca7ae 100644 --- a/src/main/resources/static/css/style-ex.css +++ b/src/main/resources/static/css/style-ex.css @@ -1,3 +1,4 @@ +/* Summary: CSS bổ sung cho các khối giao diện phụ và trạng thái màu trong storefront. */ @import url("https://fonts.googleapis.com/css?family=Open+Sans:400,600,700"); @import url("https://fonts.googleapis.com/css?family=Open+Sans:400,600,700"); diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css index 3e1235c..97d9b79 100644 --- a/src/main/resources/static/css/style.css +++ b/src/main/resources/static/css/style.css @@ -1,3 +1,4 @@ +/* Summary: CSS chính cho storefront, bố cục sản phẩm, giỏ hàng và các trang mua sắm. */ .floatleft { float: left; } diff --git a/src/main/resources/static/js/main.js b/src/main/resources/static/js/main.js index 6468a4f..57bf51a 100644 --- a/src/main/resources/static/js/main.js +++ b/src/main/resources/static/js/main.js @@ -1,3 +1,4 @@ +/* Summary: JavaScript khởi tạo sticky menu, carousel và tương tác frontend của storefront. */ jQuery(document).ready(function ($) { // jQuery sticky Menu diff --git a/src/main/resources/templates/404.html b/src/main/resources/templates/404.html index f3bd3cb..00b084a 100644 --- a/src/main/resources/templates/404.html +++ b/src/main/resources/templates/404.html @@ -1,4 +1,6 @@ + + diff --git a/src/main/resources/templates/about.html b/src/main/resources/templates/about.html index 2d57e68..353df19 100644 --- a/src/main/resources/templates/about.html +++ b/src/main/resources/templates/about.html @@ -1,4 +1,6 @@ + + diff --git a/src/main/resources/templates/blank.html b/src/main/resources/templates/blank.html index 610a73e..27c636f 100644 --- a/src/main/resources/templates/blank.html +++ b/src/main/resources/templates/blank.html @@ -1,4 +1,6 @@ + + diff --git a/src/main/resources/templates/cart.html b/src/main/resources/templates/cart.html index c69ca29..586e130 100644 --- a/src/main/resources/templates/cart.html +++ b/src/main/resources/templates/cart.html @@ -1,4 +1,6 @@ + + diff --git a/src/main/resources/templates/category.html b/src/main/resources/templates/category.html index f0c0f5f..009266c 100644 --- a/src/main/resources/templates/category.html +++ b/src/main/resources/templates/category.html @@ -1,4 +1,6 @@ + + diff --git a/src/main/resources/templates/checkout.html b/src/main/resources/templates/checkout.html index 5787042..ef484bb 100644 --- a/src/main/resources/templates/checkout.html +++ b/src/main/resources/templates/checkout.html @@ -1,4 +1,6 @@ + + diff --git a/src/main/resources/templates/contact.html b/src/main/resources/templates/contact.html index 45e01f8..1267e4b 100644 --- a/src/main/resources/templates/contact.html +++ b/src/main/resources/templates/contact.html @@ -1,4 +1,6 @@ + + diff --git a/src/main/resources/templates/detail.html b/src/main/resources/templates/detail.html index 38755ee..a197f67 100644 --- a/src/main/resources/templates/detail.html +++ b/src/main/resources/templates/detail.html @@ -1,4 +1,6 @@ + + diff --git a/src/main/resources/templates/fragments/branding.html b/src/main/resources/templates/fragments/branding.html index 0d22ca6..e6c171d 100644 --- a/src/main/resources/templates/fragments/branding.html +++ b/src/main/resources/templates/fragments/branding.html @@ -1,3 +1,4 @@ +
diff --git a/src/main/resources/templates/fragments/detail.html b/src/main/resources/templates/fragments/detail.html index ed6d18e..ce908f1 100644 --- a/src/main/resources/templates/fragments/detail.html +++ b/src/main/resources/templates/fragments/detail.html @@ -1,3 +1,4 @@ +