refactor(category): 统一分类名称字段从typename改为categoryname
fix(security): 添加CORS过滤器到安全配置最前面 fix(prod): 修改生产环境JPA配置为create模式 feat(admin): 添加管理员账户初始化功能 test: 删除无用的测试类
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
package com.qf.myafterprojecy.config;
|
||||
|
||||
import com.qf.myafterprojecy.pojo.Users;
|
||||
import com.qf.myafterprojecy.repository.UsersRepository;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 管理员用户初始化器
|
||||
* 在应用启动时检查是否存在管理员账户,如果不存在则创建
|
||||
*/
|
||||
@Component
|
||||
public class AdminUserInitializer implements CommandLineRunner {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AdminUserInitializer.class);
|
||||
|
||||
@Autowired
|
||||
private UsersRepository usersRepository;
|
||||
|
||||
@Autowired
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
String adminUsername = "qf1121";
|
||||
|
||||
logger.info("开始执行管理员账户初始化...");
|
||||
|
||||
// 检查管理员账户是否已存在
|
||||
if (!usersRepository.existsByUsername(adminUsername)) {
|
||||
logger.info("管理员账户不存在,开始创建...");
|
||||
|
||||
// 创建管理员用户
|
||||
Users adminUser = new Users();
|
||||
adminUser.setUsername(adminUsername);
|
||||
adminUser.setPassword(passwordEncoder.encode(adminUsername)); // 密码与用户名相同
|
||||
adminUser.setEmail(adminUsername + "@example.com");
|
||||
adminUser.setPhone("13800138000");
|
||||
adminUser.setRole(1); // 1 表示管理员角色
|
||||
adminUser.setCreateTime(LocalDateTime.now());
|
||||
|
||||
// 保存管理员用户
|
||||
usersRepository.save(adminUser);
|
||||
logger.info("管理员账户创建成功: {}", adminUsername);
|
||||
} else {
|
||||
logger.info("管理员账户已存在,跳过创建");
|
||||
}
|
||||
|
||||
logger.info("管理员账户初始化完成");
|
||||
}
|
||||
}
|
||||
@@ -61,8 +61,6 @@ public class CorsConfig {
|
||||
config.addExposedHeader("Content-Type");
|
||||
config.addExposedHeader("X-Requested-With");
|
||||
config.addExposedHeader("Accept");
|
||||
config.addExposedHeader("Access-Control-Allow-Origin");
|
||||
config.addExposedHeader("Access-Control-Allow-Credentials");
|
||||
config.addExposedHeader("X-Total-Count"); // 分页常用
|
||||
config.addExposedHeader("Link"); // HATEOAS 常用
|
||||
// 设置预检请求的有效期(秒),从配置文件读取
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.web.filter.CorsFilter;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
@@ -28,6 +29,9 @@ public class SecurityConfig {
|
||||
@Autowired
|
||||
private JwtAuthenticationFilter jwtAuthenticationFilter;
|
||||
|
||||
@Autowired
|
||||
private CorsFilter corsFilter;
|
||||
|
||||
/**
|
||||
* 配置AuthenticationManager Bean
|
||||
* 使用AuthenticationConfiguration来获取认证管理器,这是更现代的方式
|
||||
@@ -81,6 +85,9 @@ public class SecurityConfig {
|
||||
response.getWriter().write("{\"message\": \"未授权访问,请先登录\"}");
|
||||
});
|
||||
|
||||
// 添加CORS过滤器到最前面,确保CORS配置能够正确应用到所有请求
|
||||
http.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
// 添加JWT认证过滤器
|
||||
http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ public class CategoryController {
|
||||
@PostMapping
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseMessage<Category> createCategory(@Valid @RequestBody CategoryDto categoryDto) {
|
||||
log.info("接收创建分类的请求: {}", categoryDto.getTypename());
|
||||
log.info("接收创建分类的请求: {}", categoryDto.getcategoryname());
|
||||
return categoryService.saveCategory(categoryDto);
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ public class CategoryController {
|
||||
public ResponseMessage<Category> updateCategory(
|
||||
@PathVariable Integer id,
|
||||
@Valid @RequestBody CategoryDto categoryDto) {
|
||||
log.info("接收更新分类的请求: ID={}, 分类名称={}", id, categoryDto.getTypename());
|
||||
log.info("接收更新分类的请求: ID={}, 分类名称={}", id, categoryDto.getcategoryname());
|
||||
return categoryService.updateCategory(id, categoryDto);
|
||||
}
|
||||
|
||||
@@ -101,12 +101,12 @@ public class CategoryController {
|
||||
|
||||
/**
|
||||
* 根据分类名称搜索分类
|
||||
* @param typename 分类名称
|
||||
* @param categoryname 分类名称
|
||||
* @return 返回符合条件的分类列表
|
||||
*/
|
||||
@GetMapping("/search")
|
||||
public ResponseMessage<List<Category>> searchCategoriesByTypename(@RequestParam String typename) {
|
||||
log.info("接收根据名称搜索分类的请求: {}", typename);
|
||||
return categoryService.searchCategoriesByTypename(typename);
|
||||
public ResponseMessage<List<Category>> searchCategoriesBycategoryname(@RequestParam String categoryname) {
|
||||
log.info("接收根据名称搜索分类的请求: {}", categoryname);
|
||||
return categoryService.searchCategoriesBycategoryname(categoryname);
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,8 @@ public class Category {
|
||||
private Integer categoryid;
|
||||
|
||||
@NotBlank(message = "分类名称不能为空")
|
||||
@Column(name = "typename")
|
||||
private String typename;
|
||||
@Column(name = "categoryname")
|
||||
private String categoryname;
|
||||
|
||||
@Column(name = "description")
|
||||
private String description;
|
||||
@@ -34,12 +34,12 @@ public class Category {
|
||||
this.categoryid = categoryid;
|
||||
}
|
||||
|
||||
public String getTypename() {
|
||||
return typename;
|
||||
public String getCategoryname() {
|
||||
return categoryname;
|
||||
}
|
||||
|
||||
public void setTypename(String typename) {
|
||||
this.typename = typename;
|
||||
public void setCategoryname(String categoryname) {
|
||||
this.categoryname = categoryname;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
|
||||
@@ -7,7 +7,7 @@ public class CategoryDto {
|
||||
private Integer Categoryid;
|
||||
|
||||
@NotBlank(message = "分类名称不能为空")
|
||||
private String typename;
|
||||
private String categoryname;
|
||||
|
||||
private String description;
|
||||
|
||||
@@ -24,12 +24,12 @@ public class CategoryDto {
|
||||
this.Categoryid = Categoryid;
|
||||
}
|
||||
|
||||
public String getTypename() {
|
||||
return typename;
|
||||
public String getcategoryname() {
|
||||
return categoryname;
|
||||
}
|
||||
|
||||
public void setTypename(String typename) {
|
||||
this.typename = typename;
|
||||
public void setcategoryname(String categoryname) {
|
||||
this.categoryname = categoryname;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
|
||||
@@ -11,16 +11,16 @@ public interface CategoryRepository extends JpaRepository<Category, Integer> {
|
||||
|
||||
/**
|
||||
* 根据分类名称查询分类信息
|
||||
* @param typename 分类名称
|
||||
* @param categoryname 分类名称
|
||||
* @return 返回符合条件的分类列表
|
||||
*/
|
||||
|
||||
List<Category> findByTypenameContaining(String typename);
|
||||
List<Category> findBycategorynameContaining(String categoryname);
|
||||
|
||||
/**
|
||||
* 检查分类名称是否存在
|
||||
* @param typename 分类名称
|
||||
* @param categoryname 分类名称
|
||||
* @return 返回是否存在
|
||||
*/
|
||||
boolean existsByTypename(String typename);
|
||||
boolean existsBycategoryname(String categoryname);
|
||||
}
|
||||
@@ -49,8 +49,8 @@ public interface ICategoryService {
|
||||
|
||||
/**
|
||||
* 根据分类名称搜索分类
|
||||
* @param typename 分类名称
|
||||
* @param categoryname 分类名称
|
||||
* @return 返回符合条件的分类列表
|
||||
*/
|
||||
ResponseMessage<List<Category>> searchCategoriesByTypename(String typename);
|
||||
ResponseMessage<List<Category>> searchCategoriesBycategoryname(String categoryname);
|
||||
}
|
||||
@@ -75,7 +75,7 @@ public class CategoryService implements ICategoryService {
|
||||
public ResponseMessage<Category> saveCategory(CategoryDto categoryDto) {
|
||||
try {
|
||||
// 检查分类名称是否已存在
|
||||
if (categoryRepository.existsByTypename(categoryDto.getTypename())) {
|
||||
if (categoryRepository.existsBycategoryname(categoryDto.getcategoryname())) {
|
||||
return ResponseMessage.badRequest( "分类名称已存在");
|
||||
}
|
||||
|
||||
@@ -104,8 +104,8 @@ public class CategoryService implements ICategoryService {
|
||||
.orElseThrow(() -> new RuntimeException("分类不存在"));
|
||||
|
||||
// 如果修改了分类名称,检查新名称是否已存在
|
||||
if (!category.getTypename().equals(categoryDto.getTypename()) &&
|
||||
categoryRepository.existsByTypename(categoryDto.getTypename())) {
|
||||
if (!category.getCategoryname().equals(categoryDto.getcategoryname()) &&
|
||||
categoryRepository.existsBycategoryname(categoryDto.getcategoryname())) {
|
||||
return ResponseMessage.badRequest("分类名称已存在");
|
||||
}
|
||||
|
||||
@@ -150,13 +150,13 @@ public class CategoryService implements ICategoryService {
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseMessage<List<Category>> searchCategoriesByTypename(String typename) {
|
||||
public ResponseMessage<List<Category>> searchCategoriesBycategoryname(String categoryname) {
|
||||
try {
|
||||
if (typename == null || typename.trim().isEmpty()) {
|
||||
if (categoryname == null || categoryname.trim().isEmpty()) {
|
||||
return ResponseMessage.badRequest("分类名称不能为空");
|
||||
}
|
||||
|
||||
List<Category> categories = categoryRepository.findByTypenameContaining(typename);
|
||||
List<Category> categories = categoryRepository.findBycategorynameContaining(categoryname);
|
||||
return ResponseMessage.success(categories, "搜索分类成功");
|
||||
} catch (DataAccessException e) {
|
||||
log.error("搜索分类失败: {}", e.getMessage());
|
||||
@@ -189,7 +189,7 @@ public class CategoryService implements ICategoryService {
|
||||
private CategoryTreeDto buildCategoryTreeNode(Category category) {
|
||||
CategoryTreeDto node = new CategoryTreeDto();
|
||||
node.setId(category.getCategoryid());
|
||||
node.setName(category.getTypename());
|
||||
node.setName(category.getCategoryname());
|
||||
List<Categoryattribute> categoryAttributes = categoryAttributeRepository.findByCategoryId(category.getCategoryid());
|
||||
List<CategoryAttributeDto> categoryAttributeDtos = categoryAttributes.stream()
|
||||
.map(attr -> {
|
||||
|
||||
@@ -23,7 +23,7 @@ spring.datasource.hikari.connection-test-query=SELECT 1
|
||||
spring.datasource.hikari.pool-name=WebProjectHikariCP
|
||||
|
||||
# JPA配置(生产环境禁用自动DDL,避免意外修改表结构)
|
||||
spring.jpa.hibernate.ddl-auto=none
|
||||
spring.jpa.hibernate.ddl-auto=create
|
||||
spring.jpa.show-sql=false
|
||||
spring.jpa.properties.hibernate.format_sql=false
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.qf.myafterprojecy;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class MyAfterProjecyApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user