feat(admin): Add admin authentication and user management
This commit is contained in:
BIN
Binary file not shown.
Generated
+3
-2
File diff suppressed because one or more lines are too long
@@ -0,0 +1,20 @@
|
|||||||
|
@echo off
|
||||||
|
echo 开始构建和部署视频平台项目...
|
||||||
|
|
||||||
|
echo 1. 构建项目...
|
||||||
|
call mvn clean package -DskipTests
|
||||||
|
|
||||||
|
echo 2. 构建Sentinel Dashboard镜像...
|
||||||
|
cd sentinel-dashboard
|
||||||
|
docker build -t sentinel-dashboard:1.8.6 .
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
echo 3. 启动Docker Compose...
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
echo 部署完成!
|
||||||
|
echo 服务访问地址:
|
||||||
|
echo - 网关: http://localhost:9000
|
||||||
|
echo - Nacos: http://localhost:8848/nacos
|
||||||
|
echo - Sentinel: http://localhost:8080
|
||||||
|
echo - MinIO: http://localhost:9001
|
||||||
@@ -0,0 +1,262 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
# 基础设施服务
|
||||||
|
mysql:
|
||||||
|
image: mysql:8.0
|
||||||
|
container_name: mysql
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: root
|
||||||
|
MYSQL_DATABASE: video_platform
|
||||||
|
ports:
|
||||||
|
- "3306:3306"
|
||||||
|
volumes:
|
||||||
|
- mysql_data:/var/lib/mysql
|
||||||
|
- ./sql:/docker-entrypoint-initdb.d
|
||||||
|
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||||
|
networks:
|
||||||
|
- video-network
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7.0-alpine
|
||||||
|
container_name: redis
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "6379:6379"
|
||||||
|
volumes:
|
||||||
|
- redis_data:/data
|
||||||
|
command: redis-server --requirepass redis_EsJ8FX
|
||||||
|
networks:
|
||||||
|
- video-network
|
||||||
|
|
||||||
|
nacos:
|
||||||
|
image: nacos/nacos-server:v2.3.2
|
||||||
|
container_name: nacos
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- MODE=standalone
|
||||||
|
- JVM_XMS=512m
|
||||||
|
- JVM_XMX=512m
|
||||||
|
ports:
|
||||||
|
- "8848:8848"
|
||||||
|
- "9848:9848"
|
||||||
|
- "9849:9849"
|
||||||
|
networks:
|
||||||
|
- video-network
|
||||||
|
|
||||||
|
rmqnamesrv:
|
||||||
|
image: apache/rocketmq:5.1.4
|
||||||
|
container_name: rmqnamesrv
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "9876:9876"
|
||||||
|
command: sh mqnamesrv
|
||||||
|
networks:
|
||||||
|
- video-network
|
||||||
|
|
||||||
|
rmqbroker:
|
||||||
|
image: apache/rocketmq:5.1.4
|
||||||
|
container_name: rmqbroker
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "10909:10909"
|
||||||
|
- "10911:10911"
|
||||||
|
environment:
|
||||||
|
- NAMESRV_ADDR=rmqnamesrv:9876
|
||||||
|
- JAVA_OPTS=-Duser.home=/opt
|
||||||
|
command: sh mqbroker -c /home/rocketmq/rocketmq-5.1.4/conf/broker.conf
|
||||||
|
depends_on:
|
||||||
|
- rmqnamesrv
|
||||||
|
networks:
|
||||||
|
- video-network
|
||||||
|
|
||||||
|
minio:
|
||||||
|
image: quay.io/minio/minio
|
||||||
|
container_name: minio
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "9002:9000"
|
||||||
|
- "9001:9001"
|
||||||
|
environment:
|
||||||
|
- MINIO_ROOT_USER=minioadmin
|
||||||
|
- MINIO_ROOT_PASSWORD=minioadmin
|
||||||
|
volumes:
|
||||||
|
- minio_data:/data
|
||||||
|
command: server /data --console-address ":9001"
|
||||||
|
networks:
|
||||||
|
- video-network
|
||||||
|
|
||||||
|
sentinel:
|
||||||
|
image: sentinel-dashboard:1.8.6
|
||||||
|
container_name: sentinel
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
networks:
|
||||||
|
- video-network
|
||||||
|
|
||||||
|
# 微服务
|
||||||
|
video-gateway:
|
||||||
|
build:
|
||||||
|
context: ./video-gateway
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: video-gateway
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "9000:9000"
|
||||||
|
environment:
|
||||||
|
- SPRING_PROFILES_ACTIVE=prod
|
||||||
|
- NACOS_HOST=nacos
|
||||||
|
- NACOS_PORT=8848
|
||||||
|
- SENTINEL_HOST=sentinel
|
||||||
|
- SENTINEL_PORT=8080
|
||||||
|
depends_on:
|
||||||
|
- nacos
|
||||||
|
- sentinel
|
||||||
|
networks:
|
||||||
|
- video-network
|
||||||
|
|
||||||
|
video-auth:
|
||||||
|
build:
|
||||||
|
context: ./video-auth
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: video-auth
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- SPRING_PROFILES_ACTIVE=prod
|
||||||
|
- NACOS_HOST=nacos
|
||||||
|
- NACOS_PORT=8848
|
||||||
|
- MYSQL_HOST=mysql
|
||||||
|
- MYSQL_PORT=3306
|
||||||
|
- REDIS_HOST=redis
|
||||||
|
- REDIS_PORT=6379
|
||||||
|
depends_on:
|
||||||
|
- nacos
|
||||||
|
- mysql
|
||||||
|
- redis
|
||||||
|
networks:
|
||||||
|
- video-network
|
||||||
|
|
||||||
|
video-user:
|
||||||
|
build:
|
||||||
|
context: ./video-user
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: video-user
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- SPRING_PROFILES_ACTIVE=prod
|
||||||
|
- NACOS_HOST=nacos
|
||||||
|
- NACOS_PORT=8848
|
||||||
|
- MYSQL_HOST=mysql
|
||||||
|
- MYSQL_PORT=3306
|
||||||
|
- REDIS_HOST=redis
|
||||||
|
- REDIS_PORT=6379
|
||||||
|
depends_on:
|
||||||
|
- nacos
|
||||||
|
- mysql
|
||||||
|
- redis
|
||||||
|
networks:
|
||||||
|
- video-network
|
||||||
|
|
||||||
|
video-content:
|
||||||
|
build:
|
||||||
|
context: ./video-content
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: video-content
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- SPRING_PROFILES_ACTIVE=prod
|
||||||
|
- NACOS_HOST=nacos
|
||||||
|
- NACOS_PORT=8848
|
||||||
|
- MYSQL_HOST=mysql
|
||||||
|
- MYSQL_PORT=3306
|
||||||
|
- REDIS_HOST=redis
|
||||||
|
- REDIS_PORT=6379
|
||||||
|
- ROCKETMQ_HOST=rmqnamesrv
|
||||||
|
- ROCKETMQ_PORT=9876
|
||||||
|
- MINIO_HOST=minio
|
||||||
|
- MINIO_PORT=9000
|
||||||
|
- MINIO_ACCESS_KEY=minioadmin
|
||||||
|
- MINIO_SECRET_KEY=minioadmin
|
||||||
|
- MINIO_BUCKET=video-platform
|
||||||
|
depends_on:
|
||||||
|
- nacos
|
||||||
|
- mysql
|
||||||
|
- redis
|
||||||
|
- rmqnamesrv
|
||||||
|
- minio
|
||||||
|
networks:
|
||||||
|
- video-network
|
||||||
|
|
||||||
|
video-admin:
|
||||||
|
build:
|
||||||
|
context: ./video-admin
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: video-admin
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- SPRING_PROFILES_ACTIVE=prod
|
||||||
|
- NACOS_HOST=nacos
|
||||||
|
- NACOS_PORT=8848
|
||||||
|
- MYSQL_HOST=mysql
|
||||||
|
- MYSQL_PORT=3306
|
||||||
|
- REDIS_HOST=redis
|
||||||
|
- REDIS_PORT=6379
|
||||||
|
depends_on:
|
||||||
|
- nacos
|
||||||
|
- mysql
|
||||||
|
- redis
|
||||||
|
networks:
|
||||||
|
- video-network
|
||||||
|
|
||||||
|
video-comment:
|
||||||
|
build:
|
||||||
|
context: ./video-comment
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: video-comment
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- SPRING_PROFILES_ACTIVE=prod
|
||||||
|
- NACOS_HOST=nacos
|
||||||
|
- NACOS_PORT=8848
|
||||||
|
- MYSQL_HOST=mysql
|
||||||
|
- MYSQL_PORT=3306
|
||||||
|
- REDIS_HOST=redis
|
||||||
|
- REDIS_PORT=6379
|
||||||
|
depends_on:
|
||||||
|
- nacos
|
||||||
|
- mysql
|
||||||
|
- redis
|
||||||
|
networks:
|
||||||
|
- video-network
|
||||||
|
|
||||||
|
video-recommend:
|
||||||
|
build:
|
||||||
|
context: ./video-recommend
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: video-recommend
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- SPRING_PROFILES_ACTIVE=prod
|
||||||
|
- NACOS_HOST=nacos
|
||||||
|
- NACOS_PORT=8848
|
||||||
|
- MYSQL_HOST=mysql
|
||||||
|
- MYSQL_PORT=3306
|
||||||
|
- REDIS_HOST=redis
|
||||||
|
- REDIS_PORT=6379
|
||||||
|
depends_on:
|
||||||
|
- nacos
|
||||||
|
- mysql
|
||||||
|
- redis
|
||||||
|
networks:
|
||||||
|
- video-network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
video-network:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mysql_data:
|
||||||
|
redis_data:
|
||||||
|
minio_data:
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
FROM eclipse-temurin:8-jre
|
||||||
|
|
||||||
|
# 下载 Sentinel 1.8.6 官方 JAR
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y wget && \
|
||||||
|
wget -O /sentinel-dashboard.jar \
|
||||||
|
https://github.com/alibaba/Sentinel/releases/download/1.8.6/sentinel-dashboard-1.8.6.jar && \
|
||||||
|
apt-get remove -y wget && \
|
||||||
|
apt-get clean && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# 设置时区
|
||||||
|
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
CMD ["java", "-Dserver.port=8080", "-Dcsp.sentinel.dashboard.server=localhost:8080", "-jar", "/sentinel-dashboard.jar"]
|
||||||
@@ -764,13 +764,6 @@ INSERT IGNORE INTO `admin_role_permission` (`role_id`, `permission_id`) VALUES
|
|||||||
(3, 1),
|
(3, 1),
|
||||||
(4, 9), (4, 10);
|
(4, 9), (4, 10);
|
||||||
|
|
||||||
-- 初始化超级管理员账号(密码:admin123)
|
|
||||||
INSERT IGNORE INTO `admin_user` (`id`, `username`, `password`, `salt`, `real_name`, `email`, `phone`, `status`) VALUES
|
|
||||||
(1, 'admin', '$2a$10$oRZ7x/.dW.6Q9z0QY1JZ5e9ZQ9z0QY1JZ5e9ZQ9z0QY1JZ5e9ZQ', 'abcdefg', '超级管理员', 'admin@nuaa.edu.cn', '13800138000', 1);
|
|
||||||
|
|
||||||
INSERT IGNORE INTO `admin_user_role` (`admin_id`, `role_id`) VALUES
|
|
||||||
(1, 1);
|
|
||||||
|
|
||||||
-- 初始化系统配置
|
-- 初始化系统配置
|
||||||
INSERT IGNORE INTO `admin_system_config` (`config_key`, `config_value`, `description`) VALUES
|
INSERT IGNORE INTO `admin_system_config` (`config_key`, `config_value`, `description`) VALUES
|
||||||
('site_name', '高可用在线视频平台', '网站名称'),
|
('site_name', '高可用在线视频平台', '网站名称'),
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
FROM eclipse-temurin:17-jre
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY target/video-admin-*.jar app.jar
|
||||||
|
|
||||||
|
ENTRYPOINT ["java", "-jar", "app.jar"]
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.nuaa.video.admin.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class PasswordConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PasswordEncoder passwordEncoder() {
|
||||||
|
return new BCryptPasswordEncoder();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.nuaa.video.admin.config;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
|
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||||
|
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class RedisConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
|
||||||
|
RedisTemplate<String, Object> template = new RedisTemplate<>();
|
||||||
|
template.setConnectionFactory(factory);
|
||||||
|
|
||||||
|
// 创建配置好的ObjectMapper
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||||
|
mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
|
||||||
|
|
||||||
|
// 使用Jackson2JsonRedisSerializer
|
||||||
|
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(mapper, Object.class);
|
||||||
|
|
||||||
|
template.setKeySerializer(new StringRedisSerializer());
|
||||||
|
template.setValueSerializer(serializer);
|
||||||
|
template.setHashKeySerializer(new StringRedisSerializer());
|
||||||
|
template.setHashValueSerializer(serializer);
|
||||||
|
|
||||||
|
template.afterPropertiesSet();
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,6 +32,12 @@ public class AdminUserDetails implements UserDetails {
|
|||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 盐
|
||||||
|
*/
|
||||||
|
@JsonIgnore
|
||||||
|
private String salt;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 授权列表
|
* 授权列表
|
||||||
*/
|
*/
|
||||||
|
|||||||
+57
@@ -0,0 +1,57 @@
|
|||||||
|
package com.nuaa.video.admin.security;
|
||||||
|
|
||||||
|
import com.nuaa.video.admin.entity.AdminUser;
|
||||||
|
import com.nuaa.video.admin.service.AdminUserService;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AdminUserDetailsServiceImpl implements UserDetailsService {
|
||||||
|
|
||||||
|
private final AdminUserService adminUserService;
|
||||||
|
|
||||||
|
// 添加@Lazy注解打破循环依赖
|
||||||
|
public AdminUserDetailsServiceImpl(@Lazy AdminUserService adminUserService) {
|
||||||
|
this.adminUserService = adminUserService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
|
// 从数据库加载用户
|
||||||
|
AdminUser adminUser = adminUserService.getByUsername(username);
|
||||||
|
if (adminUser == null) {
|
||||||
|
throw new UsernameNotFoundException("用户不存在: " + username);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建UserDetails对象
|
||||||
|
AdminUserDetails userDetails = new AdminUserDetails();
|
||||||
|
userDetails.setId(adminUser.getId());
|
||||||
|
userDetails.setUsername(adminUser.getUsername());
|
||||||
|
userDetails.setPassword(adminUser.getPassword());
|
||||||
|
userDetails.setSalt(adminUser.getSalt());
|
||||||
|
|
||||||
|
// 设置权限
|
||||||
|
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
|
||||||
|
// 从用户的角色中设置权限...
|
||||||
|
if (adminUser.getRoles() != null) {
|
||||||
|
adminUser.getRoles().forEach(role -> {
|
||||||
|
authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getCode()));
|
||||||
|
if (role.getPermissions() != null) {
|
||||||
|
role.getPermissions().forEach(permission ->
|
||||||
|
authorities.add(new SimpleGrantedAuthority(permission.getCode()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
userDetails.setAuthorities(authorities);
|
||||||
|
|
||||||
|
return userDetails;
|
||||||
|
}
|
||||||
|
}
|
||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
package com.nuaa.video.admin.security;
|
||||||
|
|
||||||
|
import com.nuaa.video.admin.service.PasswordService;
|
||||||
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class CustomAuthenticationProvider extends DaoAuthenticationProvider {
|
||||||
|
|
||||||
|
private final PasswordService passwordService;
|
||||||
|
|
||||||
|
public CustomAuthenticationProvider(UserDetailsService userDetailsService,
|
||||||
|
PasswordEncoder passwordEncoder,
|
||||||
|
PasswordService passwordService) {
|
||||||
|
super();
|
||||||
|
setUserDetailsService(userDetailsService);
|
||||||
|
setPasswordEncoder(passwordEncoder);
|
||||||
|
this.passwordService = passwordService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void additionalAuthenticationChecks(UserDetails userDetails,
|
||||||
|
UsernamePasswordAuthenticationToken authentication)
|
||||||
|
throws AuthenticationException {
|
||||||
|
|
||||||
|
if (authentication.getCredentials() == null) {
|
||||||
|
throw new BadCredentialsException("认证失败:没有提供密码");
|
||||||
|
}
|
||||||
|
|
||||||
|
String presentedPassword = authentication.getCredentials().toString();
|
||||||
|
|
||||||
|
// 使用密码服务验证密码,不再需要盐值
|
||||||
|
if (!passwordService.matches(presentedPassword, "", userDetails.getPassword())) {
|
||||||
|
throw new BadCredentialsException("密码不正确");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,17 @@
|
|||||||
package com.nuaa.video.admin.security;
|
package com.nuaa.video.admin.security;
|
||||||
|
|
||||||
|
import com.nuaa.video.admin.service.PasswordService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
@@ -24,11 +27,15 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
|
|||||||
public class SecurityConfig {
|
public class SecurityConfig {
|
||||||
|
|
||||||
private final JwtAuthenticationFilter jwtAuthenticationFilter;
|
private final JwtAuthenticationFilter jwtAuthenticationFilter;
|
||||||
|
private final UserDetailsService userDetailsService;
|
||||||
|
private final PasswordService passwordService;
|
||||||
|
private final PasswordEncoder passwordEncoder; // Inject instead of creating
|
||||||
|
|
||||||
@Bean
|
// Remove this method
|
||||||
public PasswordEncoder passwordEncoder() {
|
// @Bean
|
||||||
return new BCryptPasswordEncoder();
|
// public PasswordEncoder passwordEncoder() {
|
||||||
}
|
// return new BCryptPasswordEncoder();
|
||||||
|
// }
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
|
public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
|
||||||
@@ -51,4 +58,13 @@ public class SecurityConfig {
|
|||||||
|
|
||||||
return http.build();
|
return http.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public DaoAuthenticationProvider authenticationProvider() {
|
||||||
|
CustomAuthenticationProvider provider = new CustomAuthenticationProvider(
|
||||||
|
userDetailsService,
|
||||||
|
passwordEncoder, // Use injected passwordEncoder
|
||||||
|
passwordService);
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.nuaa.video.admin.service;
|
||||||
|
|
||||||
|
import com.nuaa.video.admin.entity.AdminUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 密码处理服务接口 - 使用标准BCrypt方式
|
||||||
|
*/
|
||||||
|
public interface PasswordService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成新的盐值 (BCrypt已内置盐值,此方法保留但不再使用)
|
||||||
|
* @return 盐值字符串
|
||||||
|
*/
|
||||||
|
String generateSalt();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密密码
|
||||||
|
* @param rawPassword 原始密码
|
||||||
|
* @param salt 盐值 (BCrypt已内置盐值,此参数不再使用)
|
||||||
|
* @return 加密后的密码
|
||||||
|
*/
|
||||||
|
String encryptPassword(String rawPassword, String salt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证密码
|
||||||
|
* @param rawPassword 原始密码
|
||||||
|
* @param salt 盐值 (BCrypt已内置盐值,此参数不再使用)
|
||||||
|
* @param encodedPassword 加密后的密码
|
||||||
|
* @return 是否匹配
|
||||||
|
*/
|
||||||
|
boolean matches(String rawPassword, String salt, String encodedPassword);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为用户设置密码
|
||||||
|
* @param user 用户对象
|
||||||
|
* @param rawPassword 原始密码
|
||||||
|
*/
|
||||||
|
void setPassword(AdminUser user, String rawPassword);
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package com.nuaa.video.admin.service.impl;
|
||||||
|
|
||||||
|
import com.nuaa.video.admin.entity.AdminUser;
|
||||||
|
import com.nuaa.video.admin.entity.AdminUserRole;
|
||||||
|
import com.nuaa.video.admin.mapper.AdminUserMapper;
|
||||||
|
import com.nuaa.video.admin.mapper.AdminUserRoleMapper;
|
||||||
|
import com.nuaa.video.admin.security.AdminUserDetails;
|
||||||
|
import com.nuaa.video.admin.service.PasswordService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.ApplicationArguments;
|
||||||
|
import org.springframework.boot.ApplicationRunner;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class AdminUserInitService implements ApplicationRunner {
|
||||||
|
|
||||||
|
private final AdminUserMapper adminUserMapper;
|
||||||
|
private final AdminUserRoleMapper adminUserRoleMapper;
|
||||||
|
private final PasswordService passwordService;
|
||||||
|
|
||||||
|
@Value("${app.init.admin-password:admin123}")
|
||||||
|
private String initAdminPassword;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(ApplicationArguments args) throws Exception {
|
||||||
|
initAdminAccount();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除 @Override 注解,因为这不是覆盖父类或接口的方法
|
||||||
|
public void initAdminAccount() {
|
||||||
|
// 检查是否已存在admin账号
|
||||||
|
AdminUser existingAdmin = adminUserMapper.selectByUsername("admin");
|
||||||
|
if (existingAdmin != null) {
|
||||||
|
log.info("管理员账号已存在,无需初始化");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建管理员账号
|
||||||
|
AdminUser adminUser = new AdminUser();
|
||||||
|
adminUser.setUsername("admin");
|
||||||
|
|
||||||
|
// 使用密码服务设置密码,不再需要手动设置盐值
|
||||||
|
passwordService.setPassword(adminUser, initAdminPassword);
|
||||||
|
|
||||||
|
adminUser.setRealName("系统管理员");
|
||||||
|
adminUser.setEmail("admin@example.com");
|
||||||
|
adminUser.setStatus(1); // 正常状态
|
||||||
|
adminUser.setSalt("aaaaaa"); // 盐值可以设置为默认值,该字段已抛弃
|
||||||
|
adminUser.setCreatedBy("system");
|
||||||
|
adminUser.setUpdatedBy("system");
|
||||||
|
adminUser.setCreateTime(LocalDateTime.now());
|
||||||
|
adminUser.setUpdateTime(LocalDateTime.now());
|
||||||
|
|
||||||
|
// 保存管理员
|
||||||
|
adminUserMapper.insert(adminUser);
|
||||||
|
|
||||||
|
// 创建管理员角色关联
|
||||||
|
AdminUserRole userRole = new AdminUserRole();
|
||||||
|
userRole.setAdminId(adminUser.getId());
|
||||||
|
userRole.setRoleId(1L); // 假设ID为1的角色是超级管理员
|
||||||
|
userRole.setCreatedBy("system");
|
||||||
|
userRole.setCreateTime(LocalDateTime.now());
|
||||||
|
|
||||||
|
adminUserRoleMapper.insert(userRole);
|
||||||
|
|
||||||
|
log.info("管理员账号初始化完成");
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
-14
@@ -6,9 +6,12 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|||||||
import com.nuaa.video.admin.dto.AdminUserDTO;
|
import com.nuaa.video.admin.dto.AdminUserDTO;
|
||||||
import com.nuaa.video.admin.entity.AdminUser;
|
import com.nuaa.video.admin.entity.AdminUser;
|
||||||
import com.nuaa.video.admin.entity.AdminUserRole;
|
import com.nuaa.video.admin.entity.AdminUserRole;
|
||||||
|
import com.nuaa.video.admin.mapper.AdminPermissionMapper;
|
||||||
|
import com.nuaa.video.admin.mapper.AdminRoleMapper;
|
||||||
import com.nuaa.video.admin.mapper.AdminUserMapper;
|
import com.nuaa.video.admin.mapper.AdminUserMapper;
|
||||||
import com.nuaa.video.admin.mapper.AdminUserRoleMapper;
|
import com.nuaa.video.admin.mapper.AdminUserRoleMapper;
|
||||||
import com.nuaa.video.admin.service.AdminUserService;
|
import com.nuaa.video.admin.service.AdminUserService;
|
||||||
|
import com.nuaa.video.admin.service.PasswordService;
|
||||||
import com.nuaa.video.admin.vo.AdminRoleVO;
|
import com.nuaa.video.admin.vo.AdminRoleVO;
|
||||||
import com.nuaa.video.admin.vo.AdminUserVO;
|
import com.nuaa.video.admin.vo.AdminUserVO;
|
||||||
import com.nuaa.video.common.model.vo.Result;
|
import com.nuaa.video.common.model.vo.Result;
|
||||||
@@ -30,13 +33,18 @@ import java.util.stream.Collectors;
|
|||||||
* 管理员服务实现类
|
* 管理员服务实现类
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
// 在类定义中添加 PasswordService 依赖
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser> implements AdminUserService {
|
public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser> implements AdminUserService {
|
||||||
|
|
||||||
private final AdminUserMapper adminUserMapper;
|
private final AdminUserMapper adminUserMapper;
|
||||||
private final AdminUserRoleMapper adminUserRoleMapper;
|
private final AdminUserRoleMapper adminUserRoleMapper;
|
||||||
private final PasswordEncoder passwordEncoder;
|
private final AdminRoleMapper adminRoleMapper;
|
||||||
|
private final AdminPermissionMapper adminPermissionMapper;
|
||||||
|
private final PasswordService passwordService;
|
||||||
|
// 移除 PasswordEncoder 依赖
|
||||||
|
// private final PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AdminUser getByUsername(String username) {
|
public AdminUser getByUsername(String username) {
|
||||||
@@ -137,17 +145,10 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser
|
|||||||
AdminUser adminUser = new AdminUser();
|
AdminUser adminUser = new AdminUser();
|
||||||
BeanUtils.copyProperties(adminUserDTO, adminUser);
|
BeanUtils.copyProperties(adminUserDTO, adminUser);
|
||||||
|
|
||||||
// 生成盐值
|
// 使用密码服务设置密码 - 使用标准BCrypt方式
|
||||||
String salt = UUID.randomUUID().toString().replace("-", "");
|
String rawPassword = StringUtils.hasText(adminUserDTO.getPassword()) ?
|
||||||
adminUser.setSalt(salt);
|
adminUserDTO.getPassword() : "123456";
|
||||||
|
passwordService.setPassword(adminUser, rawPassword);
|
||||||
// 加密密码
|
|
||||||
if (StringUtils.hasText(adminUserDTO.getPassword())) {
|
|
||||||
adminUser.setPassword(passwordEncoder.encode(adminUserDTO.getPassword()));
|
|
||||||
} else {
|
|
||||||
// 默认密码为123456
|
|
||||||
adminUser.setPassword(passwordEncoder.encode("123456"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置默认状态
|
// 设置默认状态
|
||||||
if (adminUser.getStatus() == null) {
|
if (adminUser.getStatus() == null) {
|
||||||
@@ -214,10 +215,13 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser
|
|||||||
|
|
||||||
// 如果密码不为空,则更新密码
|
// 如果密码不为空,则更新密码
|
||||||
if (StringUtils.hasText(adminUserDTO.getPassword())) {
|
if (StringUtils.hasText(adminUserDTO.getPassword())) {
|
||||||
adminUser.setPassword(passwordEncoder.encode(adminUserDTO.getPassword()));
|
// 使用密码服务设置新密码
|
||||||
|
adminUser.setSalt(existUser.getSalt()); // 保留原有盐值
|
||||||
|
passwordService.setPassword(adminUser, adminUserDTO.getPassword());
|
||||||
} else {
|
} else {
|
||||||
// 不更新密码
|
// 不更新密码
|
||||||
adminUser.setPassword(null);
|
adminUser.setPassword(null);
|
||||||
|
adminUser.setSalt(null); // 同时不更新盐值
|
||||||
}
|
}
|
||||||
|
|
||||||
adminUser.setUpdatedBy(operator);
|
adminUser.setUpdatedBy(operator);
|
||||||
@@ -291,7 +295,11 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser
|
|||||||
// 更新密码
|
// 更新密码
|
||||||
AdminUser adminUser = new AdminUser();
|
AdminUser adminUser = new AdminUser();
|
||||||
adminUser.setId(id);
|
adminUser.setId(id);
|
||||||
adminUser.setPassword(passwordEncoder.encode(newPassword));
|
adminUser.setSalt(existUser.getSalt()); // 保留原有盐值
|
||||||
|
|
||||||
|
// 使用密码服务设置新密码
|
||||||
|
passwordService.setPassword(adminUser, newPassword);
|
||||||
|
|
||||||
adminUser.setUpdatedBy(operator);
|
adminUser.setUpdatedBy(operator);
|
||||||
adminUser.setUpdateTime(LocalDateTime.now());
|
adminUser.setUpdateTime(LocalDateTime.now());
|
||||||
|
|
||||||
|
|||||||
@@ -190,6 +190,7 @@ public class AuthServiceImpl implements AuthService {
|
|||||||
userDetails.setId(adminUser.getId());
|
userDetails.setId(adminUser.getId());
|
||||||
userDetails.setUsername(adminUser.getUsername());
|
userDetails.setUsername(adminUser.getUsername());
|
||||||
userDetails.setPassword(adminUser.getPassword());
|
userDetails.setPassword(adminUser.getPassword());
|
||||||
|
userDetails.setSalt(adminUser.getSalt());
|
||||||
|
|
||||||
// 设置权限
|
// 设置权限
|
||||||
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
|
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package com.nuaa.video.admin.service.impl;
|
||||||
|
|
||||||
|
import com.nuaa.video.admin.entity.AdminUser;
|
||||||
|
import com.nuaa.video.admin.service.PasswordService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 密码处理服务实现 - 使用标准BCrypt方式
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class PasswordServiceImpl implements PasswordService {
|
||||||
|
|
||||||
|
private final PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String generateSalt() {
|
||||||
|
// BCrypt已包含盐值,此方法不再需要
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String encryptPassword(String rawPassword, String salt) {
|
||||||
|
// 忽略salt参数,直接使用BCrypt加密
|
||||||
|
return passwordEncoder.encode(rawPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(String rawPassword, String salt, String encodedPassword) {
|
||||||
|
// 添加日志
|
||||||
|
log.debug("密码验证 - 原始密码: [隐藏], 加密密码: {}", encodedPassword);
|
||||||
|
// 忽略salt参数,直接使用BCrypt验证
|
||||||
|
boolean result = passwordEncoder.matches(rawPassword, encodedPassword);
|
||||||
|
log.debug("密码验证结果: {}", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPassword(AdminUser user, String rawPassword) {
|
||||||
|
// 直接使用BCrypt加密密码
|
||||||
|
user.setPassword(passwordEncoder.encode(rawPassword));
|
||||||
|
// 不再需要设置盐值
|
||||||
|
user.setSalt(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
server:
|
||||||
|
port: 9004
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: video-admin
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
server-addr: ${NACOS_HOST:nacos}:${NACOS_PORT:8848}
|
||||||
|
namespace: public
|
||||||
|
group: DEFAULT_GROUP
|
||||||
|
sentinel:
|
||||||
|
transport:
|
||||||
|
dashboard: ${SENTINEL_HOST:sentinel}:${SENTINEL_PORT:8080}
|
||||||
|
port: 8724
|
||||||
|
eager: true
|
||||||
|
datasource:
|
||||||
|
url: jdbc:mysql://${MYSQL_HOST:mysql}:${MYSQL_PORT:3306}/video_admin?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
|
||||||
|
username: root
|
||||||
|
password: root
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
data:
|
||||||
|
redis:
|
||||||
|
host: ${REDIS_HOST:redis}
|
||||||
|
port: ${REDIS_PORT:6379}
|
||||||
|
password: redis_EsJ8FX
|
||||||
|
database: 3
|
||||||
|
timeout: 10000
|
||||||
|
lettuce:
|
||||||
|
pool:
|
||||||
|
max-active: 200
|
||||||
|
max-wait: -1
|
||||||
|
max-idle: 10
|
||||||
|
min-idle: 0
|
||||||
|
|
||||||
|
mybatis-plus:
|
||||||
|
mapper-locations: classpath:mapper/*.xml
|
||||||
|
type-aliases-package: com.nuaa.video.admin.entity
|
||||||
|
configuration:
|
||||||
|
map-underscore-to-camel-case: true
|
||||||
|
cache-enabled: false
|
||||||
|
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||||
|
global-config:
|
||||||
|
db-config:
|
||||||
|
id-type: auto
|
||||||
|
logic-delete-field: is_deleted
|
||||||
|
logic-delete-value: 1
|
||||||
|
logic-not-delete-value: 0
|
||||||
|
|
||||||
|
app:
|
||||||
|
init:
|
||||||
|
admin-password: admin123
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
FROM eclipse-temurin:17-jre
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY target/video-auth-*.jar app.jar
|
||||||
|
|
||||||
|
ENTRYPOINT ["java", "-jar", "app.jar"]
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
FROM eclipse-temurin:17-jre
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY target/video-comment-*.jar app.jar
|
||||||
|
|
||||||
|
ENTRYPOINT ["java", "-jar", "app.jar"]
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
FROM eclipse-temurin:17-jre
|
||||||
|
|
||||||
|
# 安装FFmpeg
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y ffmpeg && \
|
||||||
|
apt-get clean && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY target/video-content-*.jar app.jar
|
||||||
|
|
||||||
|
ENTRYPOINT ["java", "-jar", "app.jar"]
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
server:
|
||||||
|
port: 9003
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: video-content
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
server-addr: ${NACOS_HOST:nacos}:${NACOS_PORT:8848}
|
||||||
|
namespace: public
|
||||||
|
group: DEFAULT_GROUP
|
||||||
|
sentinel:
|
||||||
|
transport:
|
||||||
|
dashboard: ${SENTINEL_HOST:sentinel}:${SENTINEL_PORT:8080}
|
||||||
|
port: 8723
|
||||||
|
eager: true
|
||||||
|
datasource:
|
||||||
|
url: jdbc:mysql://${MYSQL_HOST:mysql}:${MYSQL_PORT:3306}/video_content?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
|
||||||
|
username: root
|
||||||
|
password: root
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
data:
|
||||||
|
redis:
|
||||||
|
host: ${REDIS_HOST:redis}
|
||||||
|
port: ${REDIS_PORT:6379}
|
||||||
|
password: redis_EsJ8FX
|
||||||
|
database: 2
|
||||||
|
timeout: 10000
|
||||||
|
lettuce:
|
||||||
|
pool:
|
||||||
|
max-active: 200
|
||||||
|
max-wait: -1
|
||||||
|
max-idle: 10
|
||||||
|
min-idle: 0
|
||||||
|
|
||||||
|
# 文件上传配置
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
max-file-size: 1024MB
|
||||||
|
max-request-size: 1024MB
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
# RocketMQ配置
|
||||||
|
rocketmq:
|
||||||
|
topic-prefix: video-platform-
|
||||||
|
name-server: ${ROCKETMQ_HOST:rmqnamesrv}:${ROCKETMQ_PORT:9876}
|
||||||
|
producer:
|
||||||
|
group: video-content-producer
|
||||||
|
send-message-timeout: 3000
|
||||||
|
retry-times-when-send-failed: 3
|
||||||
|
retry-times-when-send-async-failed: 3
|
||||||
|
|
||||||
|
mybatis-plus:
|
||||||
|
mapper-locations: classpath:mapper/*.xml
|
||||||
|
type-aliases-package: com.nuaa.video.content.entity
|
||||||
|
configuration:
|
||||||
|
map-underscore-to-camel-case: true
|
||||||
|
cache-enabled: false
|
||||||
|
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||||
|
global-config:
|
||||||
|
db-config:
|
||||||
|
id-type: auto
|
||||||
|
logic-delete-field: is_deleted
|
||||||
|
logic-delete-value: 1
|
||||||
|
logic-not-delete-value: 0
|
||||||
|
|
||||||
|
# MinIO配置
|
||||||
|
minio:
|
||||||
|
endpoint: http://${MINIO_HOST:minio}:${MINIO_PORT:9000}
|
||||||
|
accessKey: ${MINIO_ACCESS_KEY:minioadmin}
|
||||||
|
secretKey: ${MINIO_SECRET_KEY:minioadmin}
|
||||||
|
bucketName: ${MINIO_BUCKET:video-platform}
|
||||||
|
|
||||||
|
# FFmpeg配置
|
||||||
|
ffmpeg:
|
||||||
|
binary:
|
||||||
|
path: ${FFMPEG_PATH:/usr/bin/ffmpeg}
|
||||||
|
probe:
|
||||||
|
path: ${FFPROBE_PATH:/usr/bin/ffprobe}
|
||||||
|
temp:
|
||||||
|
path: ${FFMPEG_TEMP_PATH:/tmp/ffmpeg}
|
||||||
|
|
||||||
|
auth:
|
||||||
|
ignore-urls:
|
||||||
|
- /api/v1/videos/public/**
|
||||||
|
- /api/v1/categories/**
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
FROM eclipse-temurin:17-jre
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY target/video-gateway-*.jar app.jar
|
||||||
|
|
||||||
|
EXPOSE 9000
|
||||||
|
|
||||||
|
ENTRYPOINT ["java", "-jar", "app.jar"]
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
server:
|
||||||
|
port: 9000
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: video-gateway
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
server-addr: ${NACOS_HOST:nacos}:${NACOS_PORT:8848}
|
||||||
|
namespace: public
|
||||||
|
group: DEFAULT_GROUP
|
||||||
|
sentinel:
|
||||||
|
transport:
|
||||||
|
dashboard: ${SENTINEL_HOST:sentinel}:${SENTINEL_PORT:8080}
|
||||||
|
port: 8722
|
||||||
|
eager: true
|
||||||
|
gateway:
|
||||||
|
discovery:
|
||||||
|
locator:
|
||||||
|
enabled: true
|
||||||
|
lower-case-service-id: true
|
||||||
|
routes:
|
||||||
|
- id: video-auth
|
||||||
|
uri: lb://video-auth
|
||||||
|
predicates:
|
||||||
|
- Path=/auth/**
|
||||||
|
filters:
|
||||||
|
- StripPrefix=1
|
||||||
|
- id: video-user
|
||||||
|
uri: lb://video-user
|
||||||
|
predicates:
|
||||||
|
- Path=/user/**
|
||||||
|
filters:
|
||||||
|
- StripPrefix=1
|
||||||
|
- id: video-content
|
||||||
|
uri: lb://video-content
|
||||||
|
predicates:
|
||||||
|
- Path=/content/**
|
||||||
|
filters:
|
||||||
|
- StripPrefix=1
|
||||||
|
- id: video-admin
|
||||||
|
uri: lb://video-admin
|
||||||
|
predicates:
|
||||||
|
- Path=/admin/**
|
||||||
|
filters:
|
||||||
|
- StripPrefix=1
|
||||||
|
- id: video-comment
|
||||||
|
uri: lb://video-comment
|
||||||
|
predicates:
|
||||||
|
- Path=/comment/**
|
||||||
|
filters:
|
||||||
|
- StripPrefix=1
|
||||||
|
- id: video-recommend
|
||||||
|
uri: lb://video-recommend
|
||||||
|
predicates:
|
||||||
|
- Path=/recommend/**
|
||||||
|
filters:
|
||||||
|
- StripPrefix=1
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
FROM eclipse-temurin:17-jre
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY target/video-recommend-*.jar app.jar
|
||||||
|
|
||||||
|
ENTRYPOINT ["java", "-jar", "app.jar"]
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
FROM eclipse-temurin:17-jre
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY target/video-user-*.jar app.jar
|
||||||
|
|
||||||
|
ENTRYPOINT ["java", "-jar", "app.jar"]
|
||||||
Reference in New Issue
Block a user