urls = new ArrayList<>();
20 | }
21 |
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/properties/JWTTokenProperties.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.properties;
2 |
3 | import lombok.Data;
4 | import org.springframework.boot.context.properties.ConfigurationProperties;
5 | import org.springframework.context.annotation.Configuration;
6 |
7 | /**
8 | * Cấu hình hết hạn token
9 | *
10 | * @author vantrang
11 | */
12 | @Data
13 | @Configuration
14 | @ConfigurationProperties(prefix = "myshop.jwt-setting")
15 | public class JWTTokenProperties {
16 |
17 | /**
18 | * Thời gian hết hạn mặc định của token
19 | */
20 | private long tokenExpireTime = 60;
21 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/properties/SystemProperties.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.properties;
2 |
3 |
4 | import lombok.Data;
5 | import org.springframework.boot.context.properties.ConfigurationProperties;
6 | import org.springframework.context.annotation.Configuration;
7 |
8 | /**
9 | * Cài đặt hệ thống
10 | */
11 | @Data
12 | @Configuration
13 | @ConfigurationProperties(prefix = "myshop.system")
14 | public class SystemProperties {
15 |
16 |
17 | /**
18 | * Chế độ demo
19 | */
20 | private Boolean demoMode = false;
21 |
22 | /**
23 | * Chế độ thử nghiệm
24 | * Mã xác thực SMS là 6 chữ số 1
25 | */
26 | private Boolean testMode = false;
27 |
28 | /**
29 | * Mức độ ẩn thông tin:
30 | * 0: Không ẩn thông tin
31 | * 1: Ẩn thông tin của người dùng quản trị (như số điện thoại)
32 | * 2: Ẩn thông tin của cửa hàng (nếu là 2, thì cả quản trị và cửa hàng đều ẩn thông tin)
33 | *
34 | * PS:
35 | */
36 | private Integer dataMaskingLevel = 0;
37 |
38 |
39 | public Boolean getDemoMode() {
40 | if (demoMode == null) {
41 | return false;
42 | }
43 | return demoMode;
44 | }
45 |
46 | public Boolean getTestMode() {
47 | if (testMode == null) {
48 | return false;
49 | }
50 | return testMode;
51 | }
52 |
53 | public Integer getDataMaskingLevel() {
54 | if (dataMaskingLevel == null) {
55 | return 0;
56 | }
57 | return dataMaskingLevel;
58 | }
59 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/properties/ThreadPoolProperties.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.properties;
2 |
3 | import lombok.Data;
4 | import org.springframework.boot.context.properties.ConfigurationProperties;
5 | import org.springframework.context.annotation.Configuration;
6 |
7 | /**
8 | * Cấu hình luồng
9 | */
10 | @Data
11 | @Configuration
12 | @ConfigurationProperties(prefix = "myshop.thread")
13 | public class ThreadPoolProperties {
14 |
15 |
16 | /**
17 | * Số lượng luồng core
18 | */
19 | private Integer corePoolSize = 10;
20 |
21 | /**
22 | * Số lượng luồng tối đa
23 | */
24 | private Integer maxPoolSize = 50;
25 |
26 | /**
27 | * Độ dài tối đa của hàng đợi
28 | */
29 | private Integer queueCapacity = Integer.MAX_VALUE;
30 |
31 | /**
32 | * Cho phép đóng luồng hết thời gian chờ
33 | */
34 | private Boolean allowCoreThreadTimeOut = false;
35 |
36 | /**
37 | * Keep Alive
38 | */
39 | private Integer keepAliveSeconds = 60;
40 |
41 |
42 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/security/AuthUser.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.security;
2 |
3 | import com.myshop.common.security.enums.UserEnums;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import java.io.Serializable;
10 |
11 | /**
12 | * @author vantrang
13 | */
14 | @Data
15 | @NoArgsConstructor
16 | @AllArgsConstructor
17 | @Builder
18 | public class AuthUser implements Serializable {
19 |
20 | private static final long serialVersionUID = 582441893336003319L;
21 |
22 | /**
23 | * username
24 | */
25 | private String username;
26 |
27 | /**
28 | * nickname
29 | */
30 | private String nickName;
31 |
32 | /**
33 | * avatar
34 | */
35 | private String face;
36 |
37 | /**
38 | * id
39 | */
40 | private String id;
41 |
42 | /**
43 | * Có hiệu lực trong thời gian dài (được sử dụng trong các tình huống đăng nhập ứng dụng di động hoặc các tình huống tin cậy, v.v.)
44 | */
45 | private Boolean longTerm = false;
46 |
47 | /**
48 | * @see UserEnums
49 | * Vai trò
50 | */
51 | private UserEnums role;
52 |
53 | /**
54 | * Nếu vai trò là người bán, trường id cửa hàng này sẽ tồn tại
55 | * storeId
56 | */
57 | private String storeId;
58 | /**
59 | * Nếu vai trò là người bán thì trường id cửa hàng này sẽ tồn tại
60 | * clerkId
61 | */
62 | private String clerkId;
63 |
64 | /**
65 | * Nếu vai trò là người bán thì trường tên cửa hàng này sẽ tồn tại
66 | * storeName
67 | */
68 | private String storeName;
69 |
70 | /**
71 | * Có phải là siêu quản trị viên không?
72 | */
73 | private Boolean isSuper = false;
74 |
75 | /**
76 | * id tenant
77 | */
78 | private String tenantId;
79 |
80 |
81 | /**
82 | * // Khai báo constructor của lớp AuthUser, nhận vào các tham số: username, id, nickName, face, role
83 | *
84 | * @param username
85 | * @param id
86 | * @param nickName
87 | * @param face
88 | * @param role
89 | */
90 | public AuthUser(String username, String id, String nickName, String face, UserEnums role) {
91 | // Gán giá trị cho thuộc tính username,...
92 | this.username = username;
93 | this.face = face;
94 | this.id = id;
95 | this.role = role;
96 | this.nickName = nickName;
97 | }
98 |
99 |
100 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/security/CustomAccessDeniedHandler.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.security;
2 |
3 | import com.myshop.common.utils.ResponseUtil;
4 | import jakarta.servlet.http.HttpServletRequest;
5 | import jakarta.servlet.http.HttpServletResponse;
6 | import lombok.extern.slf4j.Slf4j;
7 | import org.springframework.security.access.AccessDeniedException;
8 | import org.springframework.security.web.access.AccessDeniedHandler;
9 | import org.springframework.stereotype.Component;
10 |
11 |
12 | /**
13 | * Trình xử lý truy cập bị từ chối tùy chỉnh
14 | *
15 | * @author vantrang
16 | */
17 | @Component
18 | @Slf4j
19 | public class CustomAccessDeniedHandler implements AccessDeniedHandler {
20 |
21 | @Override
22 | public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) {
23 | // Xuất ra phản hồi cho client khi truy cập bị từ chối.
24 | ResponseUtil.output(response, ResponseUtil.resultMap(false, 401, "Xin lỗi, bạn không có quyền truy cập"));
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/security/InvalidAuthenticationEntryPoint.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.security;
2 |
3 | import com.myshop.common.utils.ResponseUtil;
4 | import jakarta.servlet.http.HttpServletRequest;
5 | import jakarta.servlet.http.HttpServletResponse;
6 | import lombok.extern.slf4j.Slf4j;
7 | import org.springframework.security.core.AuthenticationException;
8 | import org.springframework.security.web.AuthenticationEntryPoint;
9 | import org.springframework.stereotype.Component;
10 |
11 | import java.io.IOException;
12 |
13 | @Slf4j
14 | @Component
15 | public class InvalidAuthenticationEntryPoint implements AuthenticationEntryPoint {
16 |
17 | @Override
18 | public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
19 | log.warn("Unauthorized => {}", request.getRequestURI());
20 | ResponseUtil.output(response, ResponseUtil.resultMap(false, HttpServletResponse.SC_UNAUTHORIZED, "You do not have access rights!"));
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/security/OperationalAssessment.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.security;
2 |
3 | import com.myshop.common.enums.ResultCode;
4 | import com.myshop.common.exception.ServiceException;
5 | import com.myshop.common.security.context.UserContext;
6 | import com.myshop.common.utils.BeanUtil;
7 |
8 | import java.util.Objects;
9 |
10 | /**
11 | * Xác định toàn cục xem có thể thao tác thuộc tính nào không
12 | */
13 | public class OperationalAssessment {
14 |
15 | /**
16 | * Đối tượng cần xác định phải chứa thuộc tính memberId, storeId đại diện cho vai trò được xác định
17 | *
18 | * @param object Đối tượng được xác định
19 | * @param Loại đối tượng được xác định
20 | * @return Kết quả xử lý
21 | */
22 | public static T judgment(T object) {
23 | // Gọi phương thức judgment với đối tượng object và các tên trường mặc định "memberId" và "storeId"
24 | return judgment(object, "memberId", "storeId");
25 | }
26 |
27 | /**
28 | * Đối tượng cần xác định phải chứa thuộc tính memberId, storeId đại diện cho vai trò được xác định
29 | *
30 | * @param object Đối tượng được xác định
31 | * @param buyerIdField ID người mua
32 | * @param storeIdField ID cửa hàng
33 | * @param Loại đối tượng
34 | * @return Trả về bản thân đối tượng đã được xác định, tránh việc truy vấn đối tượng nhiều lần
35 | */
36 | public static T judgment(T object, String buyerIdField, String storeIdField) {
37 | // Lấy đối tượng AuthUser của người dùng hiện tại từ UserContext và kiểm tra xem nó có null hay không
38 | AuthUser tokenUser = Objects.requireNonNull(UserContext.getCurrentUser());
39 | // Kiểm tra vai trò của người dùng
40 | switch (tokenUser.getRole()) {
41 | // Nếu người dùng là MANAGER
42 | case MANAGER:
43 | return object;
44 | // Nếu người dùng là MEMBER
45 | case MEMBER:
46 | // Kiểm tra xem ID của người dùng hiện tại có khớp với giá trị của trường buyerIdField trong đối tượng object hay
47 | if (tokenUser.getId().equals(BeanUtil.getFieldValueByName(buyerIdField, object))) {
48 | // Nếu khớp, trả về đối tượng object
49 | return object;
50 | } else {
51 | throw new ServiceException(ResultCode.USER_PERMISSION_ERROR);
52 | }
53 | // Nếu người dùng là STORE
54 | case STORE:
55 | // Kiểm tra xem storeId của người dùng hiện tại có khớp với giá trị của trường storeIdField trong đối tượng
56 | if (tokenUser.getStoreId().equals(BeanUtil.getFieldValueByName(storeIdField, object))) {
57 | // Nếu khớp, trả về đối tượng object
58 | return object;
59 | } else {
60 | throw new ServiceException(ResultCode.USER_PERMISSION_ERROR);
61 | }
62 | default:
63 | throw new ServiceException(ResultCode.USER_PERMISSION_ERROR);
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/security/SecurityBean.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.security;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
6 | import org.springframework.web.cors.CorsConfiguration;
7 | import org.springframework.web.cors.CorsConfigurationSource;
8 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
9 |
10 | import java.util.Collections;
11 |
12 | /**
13 | * Bean Security
14 | */
15 | @Configuration
16 | public class SecurityBean {
17 |
18 | @Bean
19 | public BCryptPasswordEncoder passwordEncoder() {
20 | return new BCryptPasswordEncoder();
21 | }
22 |
23 | /**
24 | * Định nghĩa cấu hình chéo miền
25 | *
26 | * @return bean
27 | */
28 | @Bean
29 | CorsConfigurationSource corsConfigurationSource() {
30 | // Khởi tạo một đối tượng UrlBasedCorsConfigurationSource, một lớp được sử dụng để cấu hình CORS dựa trên URL
31 | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
32 | // Khởi tạo một đối tượng CorsConfiguration, một lớp được sử dụng để xác định các thông số cấu hình CORS
33 | CorsConfiguration config = new CorsConfiguration();
34 | // Cho phép gửi cookie trong các yêu cầu cross-origin
35 | config.setAllowCredentials(true);
36 | // Cho phép tất cả các nguồn gốc
37 | config.setAllowedOriginPatterns(Collections.singletonList(CorsConfiguration.ALL));
38 | // Cho phép tất cả các header
39 | config.addAllowedHeader(CorsConfiguration.ALL);
40 | // Cho phép tất cả các phương thức HTTP
41 | config.addAllowedMethod(CorsConfiguration.ALL);
42 | // Đăng ký cấu hình CORS cho tất cả các URL
43 | source.registerCorsConfiguration("/**", config);
44 | // Trả về đối tượng CorsConfigurationSource
45 | return source;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/security/enums/PermissionEnum.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.security.enums;
2 |
3 | /**
4 | * Danh sách quyền hạn
5 | *
6 | * @author vantrang
7 | */
8 | public enum PermissionEnum {
9 |
10 | /**
11 | * Quyền hạn siêu cấp, quyền xem
12 | */
13 | SUPER, QUERY
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/security/enums/SecurityEnum.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.security.enums;
2 |
3 | /**
4 | * Các hằng số liên quan đến bảo mật
5 | *
6 | * @author vantrang
7 | */
8 | public enum SecurityEnum {
9 |
10 | /**
11 | * Tên tham số token trong header
12 | */
13 | AUTHORIZATION_HEADER("accessToken"),
14 |
15 | /**
16 | * Tên trường lưu thông tin người dùng trong token JWT
17 | */
18 | USER_CONTEXT_KEY("userContext"),
19 |
20 | /**
21 | * Khóa bí mật cho mã hóa và giải mã token JWT
22 | */
23 | JWT_SECRET("secret"),
24 |
25 | /**
26 | * Tên header chứa UUID của người dùng
27 | */
28 | UUID("uuid"),
29 |
30 | /**
31 | * Tên header hoặc tên trường trong token JWT chứa ID người mời
32 | */
33 | INVITER("inviter");
34 |
35 | String value;
36 |
37 | SecurityEnum(String value) {
38 | // Gán giá trị của chuỗi value cho thuộc tính value của enum
39 | this.value = value;
40 | }
41 |
42 | public String getValue() {
43 | return value;
44 | }
45 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/security/enums/UserEnums.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.security.enums;
2 |
3 | /**
4 | * Token Role Type
5 | *
6 | * @author vantrang
7 | * @since 2024/10/22
8 | */
9 | public enum UserEnums {
10 | /**
11 | * Vai trò
12 | */
13 | MEMBER("member"),
14 | STORE("store"),
15 | MANAGER("manager"),
16 | SYSTEM("system");
17 | private final String role;
18 |
19 | UserEnums(String r) {
20 | this.role = r;
21 | }
22 |
23 | public String getRole() {
24 | return role;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/security/sensitive/SensitiveData.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.security.sensitive;
2 |
3 | import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
4 | import com.fasterxml.jackson.databind.annotation.JsonSerialize;
5 | import com.myshop.common.security.sensitive.enums.SensitiveStrategy;
6 |
7 | import java.lang.annotation.ElementType;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.RetentionPolicy;
10 | import java.lang.annotation.Target;
11 |
12 |
13 | /**
14 | * Chú thích nhạy cảm
15 | */
16 | @Retention(RetentionPolicy.RUNTIME)
17 | @Target(ElementType.FIELD)
18 | @JacksonAnnotationsInside
19 | @JsonSerialize(using = SensitiveJsonSerializer.class)
20 | public @interface SensitiveData {
21 | SensitiveStrategy strategy();
22 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/security/sensitive/SensitiveJsonSerializer.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.security.sensitive;
2 |
3 | import com.fasterxml.jackson.core.JsonGenerator;
4 | import com.fasterxml.jackson.databind.BeanProperty;
5 | import com.fasterxml.jackson.databind.JsonMappingException;
6 | import com.fasterxml.jackson.databind.JsonSerializer;
7 | import com.fasterxml.jackson.databind.SerializerProvider;
8 | import com.fasterxml.jackson.databind.ser.ContextualSerializer;
9 | import com.myshop.common.properties.SystemProperties;
10 | import com.myshop.common.security.AuthUser;
11 | import com.myshop.common.security.context.UserContext;
12 | import com.myshop.common.security.enums.UserEnums;
13 | import com.myshop.common.security.sensitive.enums.SensitiveStrategy;
14 | import org.springframework.beans.BeansException;
15 | import org.springframework.context.ApplicationContext;
16 | import org.springframework.context.ApplicationContextAware;
17 |
18 | import java.io.IOException;
19 | import java.util.Objects;
20 |
21 | /**
22 | * Lọc thông tin nhạy cảm khi serialize
23 | */
24 | public class SensitiveJsonSerializer extends JsonSerializer implements ContextualSerializer, ApplicationContextAware {
25 |
26 | private SensitiveStrategy sensitiveStrategy;
27 |
28 | // Cấu hình hệ thống
29 | private SystemProperties systemProperties;
30 |
31 | @Override
32 | public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
33 | // Xử lý serialize cho trường
34 | gen.writeString(sensitiveStrategy.maskingFunction().apply(value));
35 | }
36 |
37 | @Override
38 | public JsonSerializer> createContextual(SerializerProvider provider, BeanProperty property) throws JsonMappingException {
39 |
40 | // Kiểm tra xem có cần xử lý ẩn thông tin hay không
41 | if (desensitization()) {
42 | // Lấy enum nhạy cảm
43 | SensitiveData sensitiveAnnotation = property.getAnnotation(SensitiveData.class);
44 | // Nếu có chú thích nhạy cảm, áp dụng quy tắc ẩn thông tin
45 | if (Objects.nonNull(sensitiveAnnotation) && Objects.equals(String.class, property.getType().getRawClass())) {
46 | this.sensitiveStrategy = sensitiveAnnotation.strategy();
47 | return this;
48 | }
49 | }
50 | return provider.findValueSerializer(property.getType(), property);
51 |
52 | }
53 |
54 | @Override
55 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
56 | systemProperties = applicationContext.getBean(SystemProperties.class);
57 | }
58 |
59 | /**
60 | * Kiểm tra xem có cần xử lý ẩn thông tin hay không
61 | *
62 | * @return
63 | */
64 | private boolean desensitization() {
65 |
66 | // Người dùng hiện tại
67 | AuthUser currentAuthUser = UserContext.getCurrentUser();
68 | // Mặc định là không ẩn thông tin
69 | if (currentAuthUser == null) {
70 | return false;
71 | }
72 |
73 | // Nếu là cửa hàng
74 | if (currentAuthUser.getRole().equals(UserEnums.STORE)) {
75 | // Cửa hàng cần ẩn thông tin, thì xử lý ẩn thông tin
76 | return systemProperties.getDataMaskingLevel() == 2;
77 | }
78 |
79 |
80 | // Nếu là quản trị viên
81 | if (currentAuthUser.getRole().equals(UserEnums.MANAGER)) {
82 | // Quản trị viên cần ẩn thông tin, thì xử lý ẩn thông tin
83 | return systemProperties.getDataMaskingLevel() >= 1;
84 | }
85 |
86 | return false;
87 | }
88 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/security/sensitive/enums/SensitiveStrategy.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.security.sensitive.enums;
2 |
3 | import java.util.function.Function;
4 |
5 | /**
6 | * Enum Sensitive Strategy
7 | */
8 |
9 | public enum SensitiveStrategy {
10 | /**
11 | * Chiến lược nhạy cảm cho Username.
12 | */
13 | USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")),
14 | /**
15 | * Loại nhạy cảm cho chứng minh nhân dân.
16 | */
17 | ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2")),
18 | /**
19 | * Loại nhạy cảm cho số điện thoại.
20 | */
21 | PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")),
22 | /**
23 | * Loại nhạy cảm cho email.
24 | */
25 | EMAIL(s -> s.replaceAll("(^\\w)[^@]*(@.*$)", "$1****$2")),
26 | /**
27 | * Loại nhạy cảm cho địa chỉ.
28 | */
29 | ADDRESS(s -> s.replaceAll("(\\S{3})\\S{2}(\\S*)\\S{2}", "$1****$2****"));
30 |
31 |
32 | private final Function maskingFunction;
33 |
34 | SensitiveStrategy(Function maskingFunction) {
35 | this.maskingFunction = maskingFunction;
36 | }
37 |
38 | public Function maskingFunction() {
39 | return maskingFunction;
40 | }
41 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/security/token/SecretKeyUtil.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.security.token;
2 |
3 | import io.jsonwebtoken.io.Decoders;
4 | import io.jsonwebtoken.security.Keys;
5 | import org.apache.commons.codec.binary.Base64;
6 |
7 | import javax.crypto.SecretKey;
8 |
9 | /**
10 | * Secret key util
11 | *
12 | * @author vantrang
13 | */
14 | public class SecretKeyUtil {
15 | public static SecretKey generalKey() {
16 | // tuỳ chỉnh
17 | byte[] encodedKey = Base64.decodeBase64("cuAihCz53DZRjZwbsGcZJ2sajdkakqasAi6At+T142uphtJMsk7iQ=");
18 | SecretKey key = Keys.hmacShaKeyFor(encodedKey);
19 | return key;
20 | }
21 |
22 | public static SecretKey generalKeyByDecoders() {
23 | return Keys.hmacShaKeyFor(Decoders.BASE64.decode("cuAihCz53DZRjZwbsGcZJ2sajdkakqasAi6At+T142uphtJMsk7iQ="));
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/security/token/Token.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.security.token;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * Lớp thực thể Token
7 | *
8 | * @author vantrang
9 | */
10 | @Data
11 | public class Token {
12 | /**
13 | * Access token
14 | */
15 | private String accessToken;
16 |
17 | /**
18 | * Refresh token
19 | */
20 | private String refreshToken;
21 |
22 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/security/token/base/TokenGeneratorBase.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.security.token.base;
2 |
3 | import com.myshop.common.security.enums.UserEnums;
4 | import com.myshop.common.security.token.Token;
5 |
6 | /**
7 | * AbstractToken
8 | * Lớp trừu tượng token, định nghĩa lớp tạo token
9 | *
10 | * @author vantrang
11 | */
12 | public abstract class TokenGeneratorBase {
13 |
14 | /**
15 | * Tạo token
16 | *
17 | * @param user Tên người dùng
18 | * @param lTerm Có thời hạn dài hay không
19 | * @return Đối tượng TOKEN
20 | */
21 | public abstract Token createToken(T user, Boolean lTerm);
22 |
23 | /**
24 | * Làm mới token
25 | *
26 | * @param reToken Token làm mới
27 | * @return token
28 | */
29 | public abstract Token refreshToken(String reToken);
30 |
31 | /**
32 | * Vai trò mặc định
33 | */
34 | public UserEnums role = UserEnums.MANAGER;
35 |
36 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/thread/ThreadPoolConfig.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.thread;
2 |
3 | import com.myshop.common.properties.ThreadPoolProperties;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.scheduling.annotation.AsyncConfigurer;
7 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
8 |
9 | import java.util.concurrent.Executor;
10 |
11 | /**
12 | * Cấu hình đa luồng
13 | */
14 | @Configuration
15 | public class ThreadPoolConfig implements AsyncConfigurer {
16 |
17 |
18 | @Autowired
19 | private ThreadPoolProperties threadPoolProperties;
20 |
21 | @Override
22 | public Executor getAsyncExecutor() {
23 | ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor();
24 | //Số lượng luồng cốt lõi, mặc định là 5
25 | threadPool.setCorePoolSize(threadPoolProperties.getCorePoolSize());
26 | //Số lượng luồng tối đa, mặc định là 10
27 | threadPool.setMaxPoolSize(threadPoolProperties.getMaxPoolSize());
28 | //Độ dài tối đa của hàng đợi, thường cần thiết lập giá trị đủ lớn
29 | threadPool.setQueueCapacity(threadPoolProperties.getQueueCapacity());
30 | //Thời gian chờ tối đa của luồng trong bộ nhớ cache, mặc định là 60s
31 | threadPool.setKeepAliveSeconds(threadPoolProperties.getKeepAliveSeconds());
32 | //Cho phép đóng luồng hết thời gian chờ
33 | threadPool.setAllowCoreThreadTimeOut(threadPoolProperties.getAllowCoreThreadTimeOut());
34 | threadPool.initialize();
35 | return threadPool;
36 | }
37 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/utils/CommonUtil.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.utils;
2 |
3 | import java.util.UUID;
4 | import java.util.concurrent.ThreadLocalRandom;
5 |
6 | /**
7 | * Công cụ chung
8 | */
9 | public class CommonUtil {
10 |
11 | public static final String NUMBER_DIGITS = "0123456789";
12 |
13 | /**
14 | * Đổi tên bằng UUID
15 | *
16 | * @param fileName Tên tệp
17 | * @return Tên đã được định dạng
18 | */
19 | public static String generateUniqueFileName(String fileName) {
20 | String extension = fileName.substring(fileName.lastIndexOf("."));
21 | return UUID.randomUUID().toString().replace("-", "") + extension;
22 | }
23 |
24 |
25 | /**
26 | * Tạo số ngẫu nhiên 6 chữ số
27 | */
28 | public static String getRandomNum() {
29 | StringBuilder sb = new StringBuilder(6);
30 | for (int i = 0; i < 6; i++) {
31 | int num = ThreadLocalRandom.current().nextInt(NUMBER_DIGITS.length());
32 | sb.append(NUMBER_DIGITS.charAt(num));
33 | }
34 | return sb.toString();
35 | }
36 |
37 | /**
38 | * Lấy chuỗi đặc biệt + 6 chữ số ngẫu nhiên
39 | *
40 | * @return
41 | */
42 | public static String generateSpecialString(String str) {
43 | return str + getRandomNum();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/utils/CookieUtil.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.utils;
2 |
3 | import jakarta.servlet.http.Cookie;
4 | import jakarta.servlet.http.HttpServletRequest;
5 | import jakarta.servlet.http.HttpServletResponse;
6 | import lombok.extern.slf4j.Slf4j;
7 |
8 |
9 | /**
10 | * Công cụ Cookie
11 | */
12 | @Slf4j
13 | public class CookieUtil {
14 |
15 |
16 | /**
17 | * Thêm cookie
18 | *
19 | * @param cookieKey Giá trị khóa
20 | * @param cookieValue Giá trị tương ứng
21 | * @param maxAge Thời gian hiệu lực của cookie
22 | * @param response Phản hồi
23 | */
24 | public static void addCookie(String cookieKey, String cookieValue, Integer maxAge, HttpServletResponse response) {
25 | try {
26 | Cookie cookie = new Cookie(cookieKey, cookieValue);
27 | cookie.setMaxAge(maxAge);
28 | cookie.setPath("/");
29 | response.addCookie(cookie);
30 | } catch (Exception e) {
31 | log.error("Thêm cookie lỗi", e);
32 | }
33 | }
34 |
35 | /**
36 | * Xóa cookie
37 | *
38 | * @param cookieKey Giá trị khóa
39 | * @param response Phản hồi
40 | */
41 | public static void delCookie(String cookieKey, HttpServletResponse response) {
42 | try {
43 | Cookie cookie = new Cookie(cookieKey, "");
44 | cookie.setMaxAge(0);
45 | response.addCookie(cookie);
46 | } catch (Exception e) {
47 | log.error("Xóa cookie lỗi", e);
48 | }
49 | }
50 |
51 | /**
52 | * Lấy cookie
53 | *
54 | * @param cookieKey Giá trị khóa
55 | * @param request Yêu cầu
56 | * @return Giá trị cookie
57 | */
58 | public static String getCookie(String cookieKey, HttpServletRequest request) {
59 | try {
60 | if (request.getCookies() == null) {
61 | return null;
62 | }
63 | for (int i = 0; i < request.getCookies().length; i++) {
64 | if (request.getCookies()[i].getName().equals(cookieKey)) {
65 | return request.getCookies()[i].getValue();
66 | }
67 | }
68 | } catch (Exception e) {
69 | log.error("Lấy cookie lỗi", e);
70 | }
71 | return null;
72 | }
73 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/validation/EnumValue.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.validation;
2 |
3 | import com.myshop.common.validation.impl.EnumValueChecker;
4 | import jakarta.validation.Constraint;
5 | import jakarta.validation.Payload;
6 |
7 | import java.lang.annotation.Documented;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.Target;
10 |
11 | import static java.lang.annotation.ElementType.*;
12 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
13 |
14 | /**
15 | * Chú thích xác thực giá trị enum
16 | */
17 | @Documented
18 | @Retention(RUNTIME)
19 | @Constraint(validatedBy = {EnumValueChecker.class})
20 | @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
21 | public @interface EnumValue {
22 |
23 | String message() default "Phải là giá trị đã chỉ định";
24 |
25 | String[] strValues() default {};
26 |
27 | int[] intValues() default {};
28 |
29 | // groups
30 | Class>[] groups() default {};
31 |
32 | // payload
33 | Class extends Payload>[] payload() default {};
34 |
35 |
36 | @Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE})
37 | @Retention(RUNTIME)
38 | @Documented
39 | @interface List {
40 | EnumValue[] value();
41 | }
42 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/validation/Mobile.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.validation;
2 |
3 | import com.myshop.common.validation.impl.MobileValidator;
4 | import jakarta.validation.Constraint;
5 | import jakarta.validation.Payload;
6 |
7 | import java.lang.annotation.Documented;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.Target;
10 |
11 | import static java.lang.annotation.ElementType.*;
12 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
13 |
14 | /**
15 | * Chú thích xác thực số điện thoại
16 | */
17 | @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
18 | @Retention(RUNTIME)
19 | @Documented
20 | @Constraint(validatedBy = {MobileValidator.class})
21 | public @interface Mobile {
22 |
23 | String regexp() default "";
24 |
25 | String message() default "Số điện thoại không hợp lệ";
26 |
27 | Class>[] groups() default {};
28 |
29 | Class extends Payload>[] payload() default {};
30 | }
31 |
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/validation/impl/EnumValueChecker.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.validation.impl;
2 |
3 |
4 | import com.myshop.common.validation.EnumValue;
5 | import jakarta.validation.ConstraintValidator;
6 | import jakarta.validation.ConstraintValidatorContext;
7 |
8 | /**
9 | * Xác thực giá trị enum
10 | */
11 | public class EnumValueChecker implements ConstraintValidator {
12 |
13 | private String[] stringValues;
14 | private int[] integerValues;
15 |
16 | @Override
17 | public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
18 | if (value instanceof String) {
19 | for (String s : stringValues) {
20 | if (s.equals(value)) {
21 | return true;
22 | }
23 | }
24 | } else if (value instanceof Integer) {
25 | for (int s : integerValues) {
26 | if (s == ((Integer) value).intValue()) {
27 | return true;
28 | }
29 | }
30 | }
31 | return false;
32 | }
33 |
34 | @Override
35 | public void initialize(EnumValue constraintAnnotation) {
36 | stringValues = constraintAnnotation.strValues();
37 | integerValues = constraintAnnotation.intValues();
38 | }
39 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/validation/impl/MobileValidator.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.validation.impl;
2 |
3 | import com.myshop.common.validation.Mobile;
4 | import jakarta.validation.ConstraintValidator;
5 | import jakarta.validation.ConstraintValidatorContext;
6 |
7 | import java.util.regex.Matcher;
8 | import java.util.regex.Pattern;
9 |
10 | /**
11 | * Xác thực số điện thoại
12 | * Hỗ trợ xác thực cả số di động và số điện thoại cố định
13 | */
14 | public class MobileValidator implements ConstraintValidator {
15 |
16 | private static final Pattern MOBILE_PHONE_PATTERN = Pattern.compile("^0?(13[0-9]|14[0-9]|15[0-9]|16[0-9]|17[0-9]|18[0-9]|19[0-9])[0-9]{8}$");
17 | private static final Pattern AREA_PHONE_PATTERN = Pattern.compile("0\\d{2,3}[-]?\\d{7,8}|0\\d{2,3}\\s?\\d{7,8}|13[0-9]\\d{8}|15[1089]\\d{8}|16[2-7]\\d{8}|17[6-8]\\d{8}|18[0-9]\\d{8}");
18 | private static final Pattern SHORT_PHONE_PATTERN = Pattern.compile("^[1-9]{1}[0-9]{5,8}$");
19 |
20 | @Override
21 | public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
22 | Matcher matcher = null;
23 | // Xác thực số di động
24 | if (value.length() == 11) {
25 | matcher = MOBILE_PHONE_PATTERN.matcher(value);
26 | // Xác thực số điện thoại cố định có mã vùng
27 | } else if (value.length() > 9) {
28 | matcher = AREA_PHONE_PATTERN.matcher(value);
29 | // Xác thực số điện thoại cố định không có mã vùng
30 | } else {
31 | matcher = SHORT_PHONE_PATTERN.matcher(value);
32 | }
33 | return matcher.matches();
34 | }
35 |
36 |
37 | @Override
38 | public void initialize(Mobile constraint) {
39 | // Không cần thực hiện gì trong phương thức này
40 | }
41 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/vo/PageVO/PageVO.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.vo.PageVO;
2 |
3 | import cn.hutool.core.text.CharSequenceUtil;
4 | import com.myshop.common.utils.StringUtils;
5 | import io.swagger.annotations.ApiModelProperty;
6 | import lombok.Data;
7 |
8 | import java.io.Serializable;
9 |
10 | /**
11 | * Tham số truy vấn
12 | */
13 | @Data
14 | public class PageVO implements Serializable {
15 |
16 | private static final long serialVersionUID = 1L;
17 |
18 | @ApiModelProperty(value = "Số trang")
19 | private Integer currentPage = 1;
20 |
21 | @ApiModelProperty(value = "Số lượng mỗi trang")
22 | private Integer pageLimit = 10;
23 |
24 | @ApiModelProperty(value = "Trường sắp xếp")
25 | private String sortBy;
26 |
27 | @ApiModelProperty(value = "Cách sắp xếp asc/desc")
28 | private String sortOrder;
29 |
30 | @ApiModelProperty(value = "Cần chuyển đổi camel sang snake", notes = "Thường không xử lý, nếu cơ sở dữ liệu là snake, thì phần này cần được xử lý.")
31 | private Boolean convertCamelToSnake;
32 |
33 | public String getSortField() {
34 | if (CharSequenceUtil.isNotEmpty(sortBy)) {
35 | if (convertCamelToSnake == null || Boolean.FALSE.equals(convertCamelToSnake)) {
36 | return StringUtils.camel2Underline(sortBy);
37 | } else {
38 | return sortBy;
39 | }
40 | }
41 | return sortBy;
42 | }
43 |
44 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/common/vo/ResultMessage.java:
--------------------------------------------------------------------------------
1 | package com.myshop.common.vo;
2 |
3 | import lombok.Data;
4 |
5 | import java.io.Serializable;
6 |
7 | /**
8 | * VO tương tác giữa frontend và backend
9 | *
10 | * @author vantrang
11 | */
12 | @Data
13 | public class ResultMessage implements Serializable {
14 |
15 | private static final long serialVersionUID = 1L;
16 |
17 | /**
18 | * Cờ thành công
19 | */
20 | private boolean success;
21 |
22 | /**
23 | * Thông báo
24 | */
25 | private String message;
26 |
27 | /**
28 | * Mã trả về
29 | */
30 | private Integer code;
31 |
32 | /**
33 | * Dấu thời gian
34 | */
35 | private long timestamp = System.currentTimeMillis();
36 |
37 | /**
38 | * Đối tượng kết quả
39 | */
40 | private T result;
41 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/modules/member/entity/dos/Employee.java:
--------------------------------------------------------------------------------
1 | package com.myshop.modules.member.entity.dos;
2 |
3 | import cn.hutool.core.text.CharSequenceUtil;
4 | import com.baomidou.mybatisplus.annotation.TableName;
5 | import com.myshop.modules.member.entity.dto.EmployeeAddDTO;
6 | import com.myshop.modules.store.entity.dos.Store;
7 | import com.myshop.orm.BaseEntity;
8 | import io.swagger.annotations.ApiModel;
9 | import io.swagger.annotations.ApiModelProperty;
10 | import lombok.AllArgsConstructor;
11 | import lombok.Data;
12 | import lombok.NoArgsConstructor;
13 |
14 | /**
15 | * Mô hình nhân viên
16 | */
17 | @Data
18 | @TableName("myshop_employee")
19 | @ApiModel(value = "Nhân viên")
20 | @NoArgsConstructor
21 | @AllArgsConstructor
22 | public class Employee extends BaseEntity {
23 |
24 | private static final long serialVersionUID = 1L;
25 |
26 | @ApiModelProperty(value = "Tên nhân viên")
27 | private String name;
28 |
29 | @ApiModelProperty(value = "ID thành viên")
30 | private String memberID;
31 |
32 | @ApiModelProperty(value = "ID cửa hàng")
33 | private String storeID;
34 |
35 | @ApiModelProperty(value = "ID bộ phận")
36 | private String departmentID;
37 |
38 | @ApiModelProperty(value = "Bộ sưu tập ID vai trò")
39 | private String roleIDs;
40 |
41 | @ApiModelProperty(value = "Có phải là chủ cửa hàng hay không", hidden = true)
42 | private Boolean isShopkeeper = false;
43 |
44 | @ApiModelProperty(value = "Có phải là quản trị viên hay không", hidden = true)
45 | private Boolean isAdmin = false;
46 |
47 | @ApiModelProperty(value = "Trạng thái Mặc định true bình thường false vô hiệu hóa")
48 | private Boolean isEnabled = true;
49 |
50 | /**
51 | * Xây dựng nhân viên
52 | *
53 | * @param employeeAddDTO
54 | */
55 | public Employee(EmployeeAddDTO employeeAddDTO) {
56 | if (employeeAddDTO.getRoles() != null && !employeeAddDTO.getRoles().isEmpty()) {
57 | this.roleIDs = CharSequenceUtil.join(",", employeeAddDTO.getRoles());
58 | }
59 | this.memberID = employeeAddDTO.getMemberId();
60 | this.departmentID = employeeAddDTO.getDepartmentId();
61 | this.storeID = employeeAddDTO.getStoreId();
62 | this.name = employeeAddDTO.getUsername();
63 |
64 | }
65 |
66 |
67 | public Employee(Store store) {
68 | this.memberID = store.getMemberId();
69 | this.storeID = store.getId();
70 | this.name = store.getMemberName();
71 | this.setIsShopkeeper(true);
72 | this.setIsAdmin(true);
73 | this.setIsEnabled(true);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/modules/member/entity/dos/StoreMenu.java:
--------------------------------------------------------------------------------
1 | package com.myshop.modules.member.entity.dos;
2 |
3 | import com.baomidou.mybatisplus.annotation.TableName;
4 | import com.myshop.orm.BaseEntity;
5 | import io.swagger.annotations.ApiModel;
6 | import io.swagger.annotations.ApiModelProperty;
7 | import lombok.Data;
8 |
9 | /**
10 | * Quyền hạn menu
11 | */
12 | @Data
13 | @TableName("myshop_store_menu")
14 | @ApiModel(value = "Quyền hạn menu của cửa hàng")
15 | public class StoreMenu extends BaseEntity {
16 |
17 | private static final long serialVersionUID = 7050754476203495207L;
18 |
19 |
20 | @ApiModelProperty(value = "Tiêu đề menu")
21 | private String title;
22 |
23 | @ApiModelProperty(value = "Tên định tuyến")
24 | private String name;
25 |
26 | @ApiModelProperty(value = "Đường dẫn")
27 | private String path;
28 |
29 | @ApiModelProperty(value = "Cấp bậc menu")
30 | private Integer level;
31 |
32 | @ApiModelProperty(value = "Tệp đường dẫn frontend")
33 | private String frontendRoute;
34 |
35 | @ApiModelProperty(value = "ID cha")
36 | private String parentId = "0";
37 |
38 | @ApiModelProperty(value = "Giá trị sắp xếp")
39 | private Double sortOrder;
40 |
41 | @ApiModelProperty(value = "URL quyền hạn, * là ký hiệu đại diện, phân cách bằng dấu phẩy")
42 | private String permission;
43 |
44 |
45 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/modules/member/entity/dos/StoreRoleMenu.java:
--------------------------------------------------------------------------------
1 | package com.myshop.modules.member.entity.dos;
2 |
3 |
4 | import com.baomidou.mybatisplus.annotation.TableName;
5 | import com.myshop.orm.BaseEntity;
6 | import io.swagger.annotations.ApiModel;
7 | import io.swagger.annotations.ApiModelProperty;
8 | import lombok.Data;
9 |
10 |
11 | /**
12 | * Liên kết quyền hạn của vai trò
13 | */
14 | @Data
15 | @TableName("myshop_store_role_menu")
16 | @ApiModel(value = "Quyền hạn của vai trò cửa hàng")
17 | public class StoreRoleMenu extends BaseEntity {
18 |
19 | private static final long serialVersionUID = -4680260093546996026L;
20 |
21 | @ApiModelProperty(value = "ID của vai trò")
22 | private String roleId;
23 |
24 | @ApiModelProperty(value = "Menu")
25 | private String menuId;
26 |
27 | @ApiModelProperty(value = "ID của cửa hàng")
28 | private String storeId;
29 |
30 | @ApiModelProperty(value = "Có quyền thao tác dữ liệu hay không, nếu không thì chỉ có quyền xem")
31 | private Boolean isSuper;
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/modules/member/entity/dto/EmployeeAddDTO.java:
--------------------------------------------------------------------------------
1 | package com.myshop.modules.member.entity.dto;
2 |
3 | import com.myshop.common.security.sensitive.SensitiveData;
4 | import com.myshop.common.security.sensitive.enums.SensitiveStrategy;
5 | import io.swagger.annotations.ApiModelProperty;
6 | import jakarta.validation.constraints.NotEmpty;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 | import org.hibernate.validator.constraints.Length;
10 |
11 | import java.util.List;
12 |
13 | /**
14 | * DTO của nhân viên
15 | */
16 | @Data
17 | @NoArgsConstructor
18 | public class EmployeeAddDTO {
19 |
20 | private static final long serialVersionUID = 1L;
21 |
22 | @ApiModelProperty(value = "Tên người dùng thành viên")
23 | @NotEmpty(message = "Tên người dùng thành viên không được để trống")
24 | @Length(max = 30, message = "Tên người dùng thành viên không được vượt quá 30 ký tự")
25 | private String username;
26 |
27 | @ApiModelProperty(value = "Mật khẩu thành viên")
28 | @NotEmpty(message = "Mật khẩu thành viên không được để trống")
29 | private String password;
30 |
31 | @NotEmpty(message = "Số điện thoại không được để trống")
32 | @ApiModelProperty(value = "Số điện thoại", required = true)
33 | @SensitiveData(strategy = SensitiveStrategy.PHONE)
34 | private String mobile;
35 |
36 | @ApiModelProperty(value = "ID bộ phận")
37 | private String departmentId;
38 |
39 | @ApiModelProperty(value = "Có phải là quản trị viên siêu cấp hay không Quản trị viên siêu cấp/Quản trị viên thông thường")
40 | private Boolean isSuper = false;
41 |
42 | @ApiModelProperty(value = "Vai trò")
43 | private List roles;
44 |
45 | @ApiModelProperty(value = "ID thành viên", required = true)
46 | private String memberId;
47 |
48 | @ApiModelProperty(value = "Có phải là chủ cửa hàng hay không", hidden = true)
49 | private Boolean shopkeeper = false;
50 |
51 | @ApiModelProperty(value = "ID cửa hàng", hidden = true)
52 | private String storeId;
53 |
54 |
55 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/modules/member/entity/vo/StoreMenuUserVO.java:
--------------------------------------------------------------------------------
1 | package com.myshop.modules.member.entity.vo;
2 |
3 | import com.myshop.modules.member.entity.dos.StoreMenu;
4 | import lombok.Data;
5 |
6 | /**
7 | * StoreUserMenuVO
8 | */
9 | @Data
10 | public class StoreMenuUserVO extends StoreMenu {
11 |
12 | private static final long serialVersionUID = -7478970595109016162L;
13 |
14 | /**
15 | * Là siêu quản trị viên hay không
16 | */
17 | private Boolean isSuper;
18 |
19 | public Boolean getSuper() {
20 | return isSuper != null && isSuper;
21 | }
22 | }
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/modules/member/mapper/EmployeeMapper.java:
--------------------------------------------------------------------------------
1 | package com.myshop.modules.member.mapper;
2 |
3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
4 | import com.myshop.modules.member.entity.dos.Employee;
5 |
6 | public interface EmployeeMapper extends BaseMapper {
7 | }
8 |
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/modules/member/mapper/StoreMenuMapper.java:
--------------------------------------------------------------------------------
1 | package com.myshop.modules.member.mapper;
2 |
3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
4 | import com.myshop.modules.member.entity.dos.StoreMenu;
5 | import com.myshop.modules.member.entity.vo.StoreMenuUserVO;
6 |
7 | import java.util.List;
8 |
9 | public interface StoreMenuMapper extends BaseMapper {
10 |
11 |
12 | /**
13 | * Lấy quyền hạn menu dựa trên người dùng
14 | *
15 | * @param userId ID người dùng
16 | * @return Danh sách StoreMenuUserVO của người dùng
17 | */
18 | List getUserRoleMenu(String userId);
19 | }
20 |
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/modules/member/mapper/StoreRoleMenuMapper.java:
--------------------------------------------------------------------------------
1 | package com.myshop.modules.member.mapper;
2 |
3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
4 | import com.myshop.modules.member.entity.dos.StoreRoleMenu;
5 |
6 | public interface StoreRoleMenuMapper extends BaseMapper {
7 | }
8 |
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/modules/member/service/EmployeeService.java:
--------------------------------------------------------------------------------
1 | package com.myshop.modules.member.service;
2 |
3 | import com.baomidou.mybatisplus.extension.service.IService;
4 | import com.myshop.modules.member.entity.dos.Employee;
5 |
6 | public interface EmployeeService extends IService {
7 | /**
8 | * Lấy thông tin nhân viên dựa trên ID thành viên
9 | *
10 | * @param memberId ID thành viên
11 | * @return
12 | */
13 | Employee getEmployeeByMemberId(String memberId);
14 | }
15 |
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/modules/member/service/MemberService.java:
--------------------------------------------------------------------------------
1 | package com.myshop.modules.member.service;
2 |
3 | import com.baomidou.mybatisplus.extension.service.IService;
4 | import com.myshop.common.security.token.Token;
5 | import com.myshop.modules.member.entity.dos.Member;
6 |
7 | public interface MemberService extends IService {
8 |
9 | /**
10 | * Đăng nhập: Tên đăng nhập, mật khẩu
11 | *
12 | * @param username Tên đăng nhập
13 | * @param password Mật khẩu
14 | * @return token
15 | */
16 | Token login(String username, String password);
17 | }
18 |
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/modules/member/service/StoreMenuService.java:
--------------------------------------------------------------------------------
1 | package com.myshop.modules.member.service;
2 |
3 | import com.baomidou.mybatisplus.extension.service.IService;
4 | import com.myshop.modules.member.entity.dos.StoreMenu;
5 | import com.myshop.modules.member.entity.vo.StoreMenuUserVO;
6 | import org.springframework.cache.annotation.CacheConfig;
7 |
8 | import java.util.List;
9 |
10 | @CacheConfig(cacheNames = "{store_menu_data}")
11 | public interface StoreMenuService extends IService {
12 |
13 | List getUserRoleMenu(String employeeId);
14 | }
15 |
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/modules/member/service/StoreRoleMenuService.java:
--------------------------------------------------------------------------------
1 | package com.myshop.modules.member.service;
2 |
3 | import com.baomidou.mybatisplus.extension.service.IService;
4 | import com.myshop.modules.member.entity.dos.StoreRoleMenu;
5 | import com.myshop.modules.member.entity.vo.StoreMenuUserVO;
6 |
7 | import java.util.List;
8 |
9 | public interface StoreRoleMenuService extends IService {
10 |
11 |
12 | /**
13 | * Lấy danh sách quyền hạn menu chi tiết dựa trên tập hợp vai trò
14 | *
15 | * @param clerkId ID nhân viên
16 | * @param memberId ID thành viên
17 | * @return
18 | */
19 | List findAllMenu(String clerkId, String memberId);
20 | }
21 |
--------------------------------------------------------------------------------
/myshop-framework/src/main/java/com/myshop/modules/member/service/StoreRoleMenuServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.myshop.modules.member.service;
2 |
3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
4 | import com.myshop.cache.Cache;
5 | import com.myshop.cache.CachePrefix;
6 | import com.myshop.modules.member.entity.dos.StoreRoleMenu;
7 | import com.myshop.modules.member.entity.vo.StoreMenuUserVO;
8 | import com.myshop.modules.member.mapper.StoreRoleMenuMapper;
9 | import lombok.extern.slf4j.Slf4j;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.stereotype.Service;
12 | import org.springframework.transaction.annotation.Transactional;
13 |
14 | import java.util.List;
15 |
16 | /**
17 | * Triển khai lớp nghiệp vụ của menu vai trò
18 | */
19 | @Slf4j
20 | @Service
21 | @Transactional(rollbackFor = Exception.class)
22 | public class StoreRoleMenuServiceImpl extends ServiceImpl implements StoreRoleMenuService {
23 |
24 | @Autowired
25 | private StoreMenuService storeMenuService;
26 |
27 | @Autowired
28 | private Cache