From 8a84ae7d9fb037ba9494ed38c40d65890913beaa Mon Sep 17 00:00:00 2001 From: qingfeng1121 Date: Thu, 8 Jan 2026 11:01:11 +0800 Subject: [PATCH] =?UTF-8?q?refactor(category):=20=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E5=88=86=E7=B1=BB=E5=90=8D=E7=A7=B0=E5=AD=97=E6=AE=B5=E4=BB=8E?= =?UTF-8?q?typename=E6=94=B9=E4=B8=BAcategoryname?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix(security): 添加CORS过滤器到安全配置最前面 fix(prod): 修改生产环境JPA配置为create模式 feat(admin): 添加管理员账户初始化功能 test: 删除无用的测试类 --- .../config/AdminUserInitializer.java | 57 +++++++++++++++++++ .../qf/myafterprojecy/config/CorsConfig.java | 2 - .../myafterprojecy/config/SecurityConfig.java | 7 +++ .../controller/CategoryController.java | 12 ++-- .../com/qf/myafterprojecy/pojo/Category.java | 12 ++-- .../myafterprojecy/pojo/dto/CategoryDto.java | 10 ++-- .../repository/CategoryRepository.java | 8 +-- .../service/ICategoryService.java | 4 +- .../service/impl/CategoryService.java | 14 ++--- .../resources/application-prod.properties | 2 +- .../MyAfterProjecyApplicationTests.java | 13 ----- 11 files changed, 95 insertions(+), 46 deletions(-) create mode 100644 src/main/java/com/qf/myafterprojecy/config/AdminUserInitializer.java delete mode 100644 src/test/java/com/qf/myafterprojecy/MyAfterProjecyApplicationTests.java diff --git a/src/main/java/com/qf/myafterprojecy/config/AdminUserInitializer.java b/src/main/java/com/qf/myafterprojecy/config/AdminUserInitializer.java new file mode 100644 index 0000000..a9ab78f --- /dev/null +++ b/src/main/java/com/qf/myafterprojecy/config/AdminUserInitializer.java @@ -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("管理员账户初始化完成"); + } +} diff --git a/src/main/java/com/qf/myafterprojecy/config/CorsConfig.java b/src/main/java/com/qf/myafterprojecy/config/CorsConfig.java index 7eb3ecd..f860e9c 100644 --- a/src/main/java/com/qf/myafterprojecy/config/CorsConfig.java +++ b/src/main/java/com/qf/myafterprojecy/config/CorsConfig.java @@ -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 常用 // 设置预检请求的有效期(秒),从配置文件读取 diff --git a/src/main/java/com/qf/myafterprojecy/config/SecurityConfig.java b/src/main/java/com/qf/myafterprojecy/config/SecurityConfig.java index eda347e..7b1ff8c 100644 --- a/src/main/java/com/qf/myafterprojecy/config/SecurityConfig.java +++ b/src/main/java/com/qf/myafterprojecy/config/SecurityConfig.java @@ -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); diff --git a/src/main/java/com/qf/myafterprojecy/controller/CategoryController.java b/src/main/java/com/qf/myafterprojecy/controller/CategoryController.java index 4bb40fa..8a96c97 100644 --- a/src/main/java/com/qf/myafterprojecy/controller/CategoryController.java +++ b/src/main/java/com/qf/myafterprojecy/controller/CategoryController.java @@ -68,7 +68,7 @@ public class CategoryController { @PostMapping @PreAuthorize("hasRole('ADMIN')") public ResponseMessage 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 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> searchCategoriesByTypename(@RequestParam String typename) { - log.info("接收根据名称搜索分类的请求: {}", typename); - return categoryService.searchCategoriesByTypename(typename); + public ResponseMessage> searchCategoriesBycategoryname(@RequestParam String categoryname) { + log.info("接收根据名称搜索分类的请求: {}", categoryname); + return categoryService.searchCategoriesBycategoryname(categoryname); } } \ No newline at end of file diff --git a/src/main/java/com/qf/myafterprojecy/pojo/Category.java b/src/main/java/com/qf/myafterprojecy/pojo/Category.java index 746d5f5..dbacfed 100644 --- a/src/main/java/com/qf/myafterprojecy/pojo/Category.java +++ b/src/main/java/com/qf/myafterprojecy/pojo/Category.java @@ -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() { diff --git a/src/main/java/com/qf/myafterprojecy/pojo/dto/CategoryDto.java b/src/main/java/com/qf/myafterprojecy/pojo/dto/CategoryDto.java index 0988af8..90d963e 100644 --- a/src/main/java/com/qf/myafterprojecy/pojo/dto/CategoryDto.java +++ b/src/main/java/com/qf/myafterprojecy/pojo/dto/CategoryDto.java @@ -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() { diff --git a/src/main/java/com/qf/myafterprojecy/repository/CategoryRepository.java b/src/main/java/com/qf/myafterprojecy/repository/CategoryRepository.java index 8703d69..1b1c16d 100644 --- a/src/main/java/com/qf/myafterprojecy/repository/CategoryRepository.java +++ b/src/main/java/com/qf/myafterprojecy/repository/CategoryRepository.java @@ -11,16 +11,16 @@ public interface CategoryRepository extends JpaRepository { /** * 根据分类名称查询分类信息 - * @param typename 分类名称 + * @param categoryname 分类名称 * @return 返回符合条件的分类列表 */ - List findByTypenameContaining(String typename); + List findBycategorynameContaining(String categoryname); /** * 检查分类名称是否存在 - * @param typename 分类名称 + * @param categoryname 分类名称 * @return 返回是否存在 */ - boolean existsByTypename(String typename); + boolean existsBycategoryname(String categoryname); } \ No newline at end of file diff --git a/src/main/java/com/qf/myafterprojecy/service/ICategoryService.java b/src/main/java/com/qf/myafterprojecy/service/ICategoryService.java index 7ea3eb7..f447a49 100644 --- a/src/main/java/com/qf/myafterprojecy/service/ICategoryService.java +++ b/src/main/java/com/qf/myafterprojecy/service/ICategoryService.java @@ -49,8 +49,8 @@ public interface ICategoryService { /** * 根据分类名称搜索分类 - * @param typename 分类名称 + * @param categoryname 分类名称 * @return 返回符合条件的分类列表 */ - ResponseMessage> searchCategoriesByTypename(String typename); + ResponseMessage> searchCategoriesBycategoryname(String categoryname); } \ No newline at end of file diff --git a/src/main/java/com/qf/myafterprojecy/service/impl/CategoryService.java b/src/main/java/com/qf/myafterprojecy/service/impl/CategoryService.java index 2dfa02c..e889395 100644 --- a/src/main/java/com/qf/myafterprojecy/service/impl/CategoryService.java +++ b/src/main/java/com/qf/myafterprojecy/service/impl/CategoryService.java @@ -75,7 +75,7 @@ public class CategoryService implements ICategoryService { public ResponseMessage 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> searchCategoriesByTypename(String typename) { + public ResponseMessage> searchCategoriesBycategoryname(String categoryname) { try { - if (typename == null || typename.trim().isEmpty()) { + if (categoryname == null || categoryname.trim().isEmpty()) { return ResponseMessage.badRequest("分类名称不能为空"); } - List categories = categoryRepository.findByTypenameContaining(typename); + List 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 categoryAttributes = categoryAttributeRepository.findByCategoryId(category.getCategoryid()); List categoryAttributeDtos = categoryAttributes.stream() .map(attr -> { diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties index 2cd8359..2339ca0 100644 --- a/src/main/resources/application-prod.properties +++ b/src/main/resources/application-prod.properties @@ -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 diff --git a/src/test/java/com/qf/myafterprojecy/MyAfterProjecyApplicationTests.java b/src/test/java/com/qf/myafterprojecy/MyAfterProjecyApplicationTests.java deleted file mode 100644 index 82fe420..0000000 --- a/src/test/java/com/qf/myafterprojecy/MyAfterProjecyApplicationTests.java +++ /dev/null @@ -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() { - } - -}