fzzj пре 9 месеци
родитељ
комит
e610168dae
20 измењених фајлова са 295 додато и 196 уклоњено
  1. 4
    1
      RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
  2. 4
    4
      RuoYi-Vue/ruoyi-admin/src/main/resources/application.yml
  3. 4
    4
      RuoYi-Vue/ruoyi-system/pom.xml
  4. 42
    42
      RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/config/ElasticsearchConfig.java
  5. 34
    33
      RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/config/ElasticsearchInitializer.java
  6. 21
    6
      RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/controller/NovelController.java
  7. 11
    11
      RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/domain/Novel.java
  8. 23
    0
      RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/domain/User.java
  9. 3
    2
      RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/mapper/NovelMapper.java
  10. 8
    8
      RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/repository/elastic/NovelSearchRepository.java
  11. 2
    1
      RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/repository/jpa/NovelRepository.java
  12. 3
    6
      RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/repository/jpa/UserRepository.java
  13. 2
    1
      RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/service/ChapterRepository.java
  14. 4
    4
      RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/service/NovelSearchService.java
  15. 9
    9
      RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/service/NovelService.java
  16. 1
    1
      RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/service/impl/AuthServiceImpl.java
  17. 100
    57
      RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/service/impl/NovelSearchServiceImpl.java
  18. 2
    2
      RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/service/impl/NovelServiceImpl.java
  19. 4
    3
      RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/utils/JwtTokenProvider.java
  20. 14
    1
      RuoYi-Vue/ruoyi-system/src/main/resources/mapper/novel/NovelMapper.xml

+ 4
- 1
RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java Прегледај датотеку

@@ -2,7 +2,9 @@ package com.ruoyi;
2 2
 
3 3
 import org.springframework.boot.SpringApplication;
4 4
 import org.springframework.boot.autoconfigure.SpringBootApplication;
5
+import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration;
5 6
 import org.springframework.boot.autoconfigure.domain.EntityScan;
7
+import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration;
6 8
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
7 9
 import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
8 10
 import org.springframework.context.annotation.ComponentScan;
@@ -13,7 +15,8 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
13 15
  * 
14 16
  * @author ruoyi
15 17
  */
16
-@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class},
18
+@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class,
19
+        ElasticsearchRestClientAutoConfiguration.class},
17 20
         scanBasePackages = {
18 21
                 "com.ruoyi",
19 22
                 "com.ruoyi.novel"  // 确保包含 novel 包

+ 4
- 4
RuoYi-Vue/ruoyi-admin/src/main/resources/application.yml Прегледај датотеку

@@ -89,10 +89,10 @@ spring:
89 89
         max-active: 8
90 90
         # #连接池最大阻塞等待时间(使用负值表示没有限制)
91 91
         max-wait: -1ms
92
-  elasticsearch:
93
-    uris: http://localhost:9200 # ES地址
94
-    connection-timeout: 3000
95
-    socket-timeout: 5000
92
+#  elasticsearch:
93
+#    uris: http://localhost:9200 # ES地址
94
+#    connection-timeout: 3000
95
+#    socket-timeout: 5000
96 96
   jpa:
97 97
     show-sql: true
98 98
     hibernate:

+ 4
- 4
RuoYi-Vue/ruoyi-system/pom.xml Прегледај датотеку

@@ -47,10 +47,10 @@
47 47
             <artifactId>spring-web</artifactId>
48 48
         </dependency>
49 49
         <!-- Elasticsearch -->
50
-        <dependency>
51
-            <groupId>org.springframework.boot</groupId>
52
-            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
53
-        </dependency>
50
+<!--        <dependency>-->
51
+<!--            <groupId>org.springframework.boot</groupId>-->
52
+<!--            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>-->
53
+<!--        </dependency>-->
54 54
         <!-- MyBatis-Plus 核心依赖 -->
55 55
         <dependency>
56 56
             <groupId>com.baomidou</groupId>

+ 42
- 42
RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/config/ElasticsearchConfig.java Прегледај датотеку

@@ -1,42 +1,42 @@
1
-package com.ruoyi.novel.config;
2
-
3
-import org.elasticsearch.client.RequestOptions;
4
-import org.elasticsearch.client.RestHighLevelClient;
5
-import org.springframework.boot.actuate.health.AbstractHealthIndicator;
6
-import org.springframework.boot.actuate.health.Health;
7
-import org.springframework.boot.actuate.health.HealthIndicator;
8
-import org.springframework.boot.actuate.health.Status;
9
-import org.springframework.context.annotation.Bean;
10
-import org.springframework.context.annotation.Configuration;
11
-import org.springframework.data.elasticsearch.client.ClientConfiguration;
12
-import org.springframework.data.elasticsearch.client.RestClients;
13
-import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
14
-
15
-@Configuration
16
-public class ElasticsearchConfig {
17
-
18
-    @Bean
19
-    public ElasticsearchRestTemplate elasticsearchRestTemplate(RestHighLevelClient client) {
20
-        return new ElasticsearchRestTemplate(client);
21
-    }
22
-
23
-    @Bean
24
-    public RestHighLevelClient elasticsearchClient() {
25
-        return RestClients.create(ClientConfiguration.localhost()).rest();
26
-    }
27
-
28
-    @Bean
29
-    public HealthIndicator elasticsearchHealthIndicator(RestHighLevelClient client) {
30
-        return new AbstractHealthIndicator() {
31
-            @Override
32
-            protected void doHealthCheck(Health.Builder builder) throws Exception {
33
-                try {
34
-                    boolean available = client.ping(RequestOptions.DEFAULT);
35
-                    builder.status(available ? Status.UP : Status.DOWN);
36
-                } catch (Exception e) {
37
-                    builder.down(e);
38
-                }
39
-            }
40
-        };
41
-    }
42
-}
1
+//package com.ruoyi.novel.config;
2
+//
3
+//import org.elasticsearch.client.RequestOptions;
4
+//import org.elasticsearch.client.RestHighLevelClient;
5
+//import org.springframework.boot.actuate.health.AbstractHealthIndicator;
6
+//import org.springframework.boot.actuate.health.Health;
7
+//import org.springframework.boot.actuate.health.HealthIndicator;
8
+//import org.springframework.boot.actuate.health.Status;
9
+//import org.springframework.context.annotation.Bean;
10
+//import org.springframework.context.annotation.Configuration;
11
+//import org.springframework.data.elasticsearch.client.ClientConfiguration;
12
+//import org.springframework.data.elasticsearch.client.RestClients;
13
+//import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
14
+//
15
+//@Configuration
16
+//public class ElasticsearchConfig {
17
+//
18
+////    @Bean
19
+////    public ElasticsearchRestTemplate elasticsearchRestTemplate(RestHighLevelClient client) {
20
+////        return new ElasticsearchRestTemplate(client);
21
+////    }
22
+////
23
+////    @Bean
24
+////    public RestHighLevelClient elasticsearchClient() {
25
+////        return RestClients.create(ClientConfiguration.localhost()).rest();
26
+////    }
27
+//
28
+////    @Bean
29
+////    public HealthIndicator elasticsearchHealthIndicator(RestHighLevelClient client) {
30
+////        return new AbstractHealthIndicator() {
31
+////            @Override
32
+////            protected void doHealthCheck(Health.Builder builder) throws Exception {
33
+////                try {
34
+////                    boolean available = client.ping(RequestOptions.DEFAULT);
35
+////                    builder.status(available ? Status.UP : Status.DOWN);
36
+////                } catch (Exception e) {
37
+////                    builder.down(e);
38
+////                }
39
+////            }
40
+////        };
41
+////    }
42
+//}

+ 34
- 33
RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/config/ElasticsearchInitializer.java Прегледај датотеку

@@ -1,33 +1,34 @@
1
-package com.ruoyi.novel.config;
2
-
3
-import com.ruoyi.novel.domain.Novel;
4
-import com.ruoyi.novel.service.impl.NovelServiceImpl;
5
-import org.slf4j.Logger;
6
-import org.slf4j.LoggerFactory;
7
-import org.springframework.boot.ApplicationArguments;
8
-import org.springframework.boot.ApplicationRunner;
9
-import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
10
-import org.springframework.stereotype.Component;
11
-
12
-@Component
13
-public class ElasticsearchInitializer implements ApplicationRunner {
14
-    private static final Logger logger = LoggerFactory.getLogger(ElasticsearchInitializer.class);
15
-    private final ElasticsearchRestTemplate elasticsearchTemplate;
16
-
17
-    public ElasticsearchInitializer(ElasticsearchRestTemplate elasticsearchTemplate) {
18
-        this.elasticsearchTemplate = elasticsearchTemplate;
19
-    }
20
-
21
-    @Override
22
-    public void run(ApplicationArguments args) {
23
-        try {
24
-            if (!elasticsearchTemplate.indexOps(Novel.class).exists()) {
25
-                elasticsearchTemplate.indexOps(Novel.class).create();
26
-                elasticsearchTemplate.indexOps(Novel.class).putMapping();
27
-                logger.info("Created Elasticsearch index for Novel");
28
-            }
29
-        } catch (Exception e) {
30
-            logger.warn("Failed to create Elasticsearch index", e);
31
-        }
32
-    }
33
-}
1
+//package com.ruoyi.novel.config;
2
+//
3
+//import com.ruoyi.novel.domain.Novel;
4
+//import com.ruoyi.novel.service.impl.NovelServiceImpl;
5
+//import org.slf4j.Logger;
6
+//import org.slf4j.LoggerFactory;
7
+//import org.springframework.boot.ApplicationArguments;
8
+//import org.springframework.boot.ApplicationRunner;
9
+//import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
10
+//import org.springframework.stereotype.Component;
11
+//
12
+//@Component
13
+//public class ElasticsearchInitializer implements ApplicationRunner {
14
+//    private static final Logger logger = LoggerFactory.getLogger(ElasticsearchInitializer.class);
15
+////    private final ElasticsearchRestTemplate elasticsearchTemplate;
16
+////
17
+////    public ElasticsearchInitializer(ElasticsearchRestTemplate elasticsearchTemplate) {
18
+////        this.elasticsearchTemplate = elasticsearchTemplate;
19
+////    }
20
+//
21
+//    @Override
22
+//    public void run(ApplicationArguments args) {
23
+//        logger.info("Created Elasticsearch index for Novel");
24
+////        try {
25
+////            if (!elasticsearchTemplate.indexOps(Novel.class).exists()) {
26
+////                elasticsearchTemplate.indexOps(Novel.class).create();
27
+////                elasticsearchTemplate.indexOps(Novel.class).putMapping();
28
+////                logger.info("Created Elasticsearch index for Novel");
29
+////            }
30
+////        } catch (Exception e) {
31
+////            logger.warn("Failed to create Elasticsearch index", e);
32
+////        }
33
+//    }
34
+//}

+ 21
- 6
RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/controller/NovelController.java Прегледај датотеку

@@ -16,11 +16,15 @@ import com.ruoyi.novel.service.NovelSearchService;
16 16
 import com.ruoyi.novel.service.NovelService;
17 17
 import jdk.jfr.Category;
18 18
 import org.springframework.beans.factory.annotation.Autowired;
19
+import org.springframework.beans.factory.annotation.Qualifier;
20
+import org.springframework.cache.annotation.Cacheable;
19 21
 import org.springframework.http.ResponseEntity;
22
+import org.springframework.scheduling.annotation.Async;
20 23
 import org.springframework.web.bind.annotation.*;
21 24
 
22 25
 import java.util.List;
23 26
 import java.util.Map;
27
+import java.util.concurrent.CompletableFuture;
24 28
 
25 29
 // NovelController.java
26 30
 @RestController
@@ -31,6 +35,7 @@ public class NovelController extends BaseController {
31 35
     @Autowired
32 36
     private final NovelService novelService;
33 37
 
38
+    @Qualifier("authServiceImpl")
34 39
     @Autowired
35 40
     private final IAuthService authService;
36 41
     @Autowired
@@ -38,7 +43,7 @@ public class NovelController extends BaseController {
38 43
     @Autowired
39 44
     private NovelMapper novelMapper;
40 45
     // 构造函数注入
41
-    public NovelController(NovelService novelService, IAuthService authService) {
46
+    public NovelController(NovelService novelService, @Qualifier("authServiceImpl") IAuthService authService) {
42 47
         this.novelService = novelService;
43 48
         this.authService = authService;
44 49
     }
@@ -150,30 +155,40 @@ public AjaxResult getChapterContent(@PathVariable Long chapterId) {
150 155
     }
151 156
     // 其他接口...
152 157
     @GetMapping("/search")
153
-    public AjaxResult searchNovels(@RequestParam String keyword) {
154
-        List<Novel> novels = searchService.searchNovels(keyword);
158
+    @Cacheable(value = "novelSearch", key = "#keyword + '-' + #categoryId")
159
+    public AjaxResult searchNovels(@RequestParam String keyword, @RequestParam  Long categoryId) {
160
+        List<Novel> novels = searchService.searchNovels(keyword, categoryId);
155 161
         return AjaxResult.success(novels);
156 162
     }
163
+    @Async
164
+    public CompletableFuture<List<Novel>> searchNovelsAsync(String keyword, Long categoryId) {
165
+        return CompletableFuture.completedFuture((List<Novel>) searchNovels(keyword, categoryId));
166
+    }
167
+    @GetMapping("/suggest")
168
+    public List<String> suggestKeywords(@RequestParam String prefix) {
169
+        return novelMapper.suggestKeywords(prefix + "%", 10);
170
+    }
157 171
 
172
+    // Mapper中
158 173
 
159 174
     @PostMapping("/create")
160 175
     public AjaxResult addNovel(@RequestBody Novel novel) {
161 176
         novelMapper.insert(novel);
162
-        searchService.indexNovel(novel); // 创建索引
177
+        //searchService.indexNovel(novel); // 创建索引
163 178
         return AjaxResult.success();
164 179
     }
165 180
 
166 181
     @PutMapping
167 182
     public AjaxResult updateNovel(@RequestBody Novel novel) {
168 183
         novelMapper.updateById(novel);
169
-        searchService.updateNovelIndex(novel); // 更新索引
184
+        //searchService.updateNovelIndex(novel); // 更新索引
170 185
         return AjaxResult.success();
171 186
     }
172 187
 
173 188
     @DeleteMapping("/{id}")
174 189
     public AjaxResult deleteNovel(@PathVariable Long id) {
175 190
         novelMapper.deleteById(id);
176
-        searchService.deleteNovelIndex(id); // 删除索引
191
+        //searchService.deleteNovelIndex(id); // 删除索引
177 192
         return AjaxResult.success();
178 193
     }
179 194
 }

+ 11
- 11
RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/domain/Novel.java Прегледај датотеку

@@ -5,9 +5,9 @@ import com.baomidou.mybatisplus.annotation.TableId;
5 5
 import com.baomidou.mybatisplus.annotation.TableName;
6 6
 import lombok.Data;
7 7
 import org.springframework.data.annotation.Id;
8
-import org.springframework.data.elasticsearch.annotations.Document;
9
-import org.springframework.data.elasticsearch.annotations.Field;
10
-import org.springframework.data.elasticsearch.annotations.FieldType;
8
+//import org.springframework.data.elasticsearch.annotations.Document;
9
+//import org.springframework.data.elasticsearch.annotations.Field;
10
+//import org.springframework.data.elasticsearch.annotations.FieldType;
11 11
 
12 12
 import javax.persistence.Column;
13 13
 import javax.persistence.Entity;
@@ -19,7 +19,7 @@ import java.util.Date;
19 19
 
20 20
 @Entity
21 21
 @TableName("novel")
22
-@Document(indexName = "novels")
22
+//@Document(indexName = "novels")
23 23
 @Data
24 24
 public class Novel {
25 25
     @javax.persistence.Id
@@ -27,23 +27,23 @@ public class Novel {
27 27
     @GeneratedValue(strategy = GenerationType.IDENTITY)
28 28
     @TableId(type = IdType.AUTO)
29 29
     private Long id;
30
-    @Field(type = FieldType.Text, analyzer = "ik_max_word")
30
+    //@Field(type = FieldType.Text, analyzer = "ik_max_word")
31 31
     private String title;
32
-    @Field(type = FieldType.Keyword)
32
+    //@Field(type = FieldType.Keyword)
33 33
     private String author;
34 34
     private Long authorId;
35 35
     private String cover;
36 36
     private String coverImg;
37
-    @Field(type = FieldType.Long)
37
+    //@Field(type = FieldType.Long)
38 38
     private Long categoryId;
39
-    @Field(type = FieldType.Keyword)
39
+    //@Field(type = FieldType.Keyword)
40 40
     private Integer status = 0; // 0: 连载中, 1: 已完结// 连载/完本
41
-    @Field(type = FieldType.Text, analyzer = "ik_smart")
41
+    //@Field(type = FieldType.Text, analyzer = "ik_smart")
42 42
     private String description;
43 43
     private Long wordCount;
44
-    @Field(type = FieldType.Long)
44
+    //@Field(type = FieldType.Long)
45 45
     private Long readCount;
46
-    @Field(type = FieldType.Date)
46
+    //@Field(type = FieldType.Date)
47 47
     @Column(name = "create_time")
48 48
     private Date createTime = new Date();
49 49
     @Column(name = "update_time")

+ 23
- 0
RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/domain/User.java Прегледај датотеку

@@ -0,0 +1,23 @@
1
+package com.ruoyi.novel.domain;
2
+import javax.persistence.Entity;
3
+import javax.persistence.GeneratedValue;
4
+import javax.persistence.GenerationType;
5
+import javax.persistence.Id;
6
+import javax.persistence.Table;
7
+
8
+@Entity
9
+@Table(name = "sys_user")
10
+public class User {
11
+
12
+    @Id
13
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
14
+    private Long id;
15
+
16
+    private String username;
17
+    private String password;
18
+    private String email;
19
+    private String token;
20
+
21
+    // Getters and setters
22
+    // 构造函数
23
+}

+ 3
- 2
RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/mapper/NovelMapper.java Прегледај датотеку

@@ -12,7 +12,7 @@ import java.util.Map;
12 12
 @Mapper
13 13
 // NovelMapper.java
14 14
 public interface NovelMapper extends BaseMapper<Novel> {
15
-    List<Novel> selectNovelList(Novel novel);
15
+    List<Novel> selectNovelList(@Param("novel") Novel novel,@Param("keyword") String keyword);
16 16
     Novel selectNovelById(Long id);
17 17
     int insertNovel(Novel novel);
18 18
     int updateNovel(Novel novel);
@@ -37,6 +37,7 @@ public interface NovelMapper extends BaseMapper<Novel> {
37 37
   //  List<Novel> selectNovelList(Novel novel);
38 38
     List<Novel> selectHotNovels(Map<String, Object> params);
39 39
 
40
-
40
+    @Select("SELECT DISTINCT title FROM novel WHERE title LIKE #{prefix} LIMIT #{limit}")
41
+    List<String> suggestKeywords(@Param("prefix") String prefix, @Param("limit") int limit);
41 42
 }
42 43
 

+ 8
- 8
RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/repository/elastic/NovelSearchRepository.java Прегледај датотеку

@@ -1,8 +1,8 @@
1
-package com.ruoyi.novel.repository.elastic;
2
-
3
-import com.ruoyi.novel.domain.Novel;
4
-import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
5
-
6
-public interface NovelSearchRepository extends ElasticsearchRepository<Novel, Long> {
7
-    // Elasticsearch 特定查询方法
8
-}
1
+//package com.ruoyi.novel.repository.elastic;
2
+//
3
+//import com.ruoyi.novel.domain.Novel;
4
+//import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
5
+//
6
+//public interface NovelSearchRepository extends ElasticsearchRepository<Novel, Long> {
7
+//    // Elasticsearch 特定查询方法
8
+//}

+ 2
- 1
RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/repository/jpa/NovelRepository.java Прегледај датотеку

@@ -2,8 +2,9 @@ package com.ruoyi.novel.repository.jpa;
2 2
 
3 3
 import com.ruoyi.novel.domain.Novel;
4 4
 import org.apache.ibatis.annotations.Param;
5
-import org.springframework.data.elasticsearch.annotations.Query;
5
+//import org.springframework.data.elasticsearch.annotations.Query;
6 6
 import org.springframework.data.jpa.repository.JpaRepository;
7
+import org.springframework.data.jpa.repository.Query;
7 8
 import org.springframework.data.repository.NoRepositoryBean;
8 9
 import org.springframework.stereotype.Repository;
9 10
 

RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/service/UserRepository.java → RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/repository/jpa/UserRepository.java Прегледај датотеку

@@ -1,15 +1,12 @@
1
-package com.ruoyi.novel.service;
1
+package com.ruoyi.novel.repository.jpa;
2 2
 
3
-import org.elasticsearch.client.security.user.User;
3
+import com.ruoyi.common.core.domain.entity.SysUser;
4
+import com.ruoyi.novel.domain.User;  // 确保导入正确
4 5
 import org.springframework.data.jpa.repository.JpaRepository;
5 6
 import org.springframework.stereotype.Repository;
6 7
 
7
-import java.util.Optional;
8 8
 @Repository
9
-// UserRepository.java
10 9
 public interface UserRepository extends JpaRepository<User, Long> {
11
-
12
-    //Optional<User> findByUsername(String username);
13 10
     // 自定义查询方法
14 11
     User findByUsername(String username);
15 12
     User findByEmail(String email);

+ 2
- 1
RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/service/ChapterRepository.java Прегледај датотеку

@@ -2,8 +2,9 @@ package com.ruoyi.novel.service;
2 2
 
3 3
 import com.ruoyi.novel.domain.Chapter;
4 4
 import org.apache.ibatis.annotations.Param;
5
-import org.springframework.data.elasticsearch.annotations.Query;
5
+//import org.springframework.data.elasticsearch.annotations.Query;
6 6
 import org.springframework.data.jpa.repository.JpaRepository;
7
+import org.springframework.data.jpa.repository.Query;
7 8
 
8 9
 import java.util.List;
9 10
 

+ 4
- 4
RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/service/NovelSearchService.java Прегледај датотеку

@@ -6,8 +6,8 @@ import java.util.List;
6 6
 
7 7
 // NovelSearchService.java
8 8
 public interface NovelSearchService {
9
-    List<Novel> searchNovels(String keyword);
10
-    void indexNovel(Novel novel);
11
-    void updateNovelIndex(Novel novel);
12
-    void deleteNovelIndex(Long id);
9
+    List<Novel> searchNovels(String keyword, Long categoryId);
10
+//    void indexNovel(Novel novel);
11
+//    void updateNovelIndex(Novel novel);
12
+//    void deleteNovelIndex(Long id);
13 13
 }

+ 9
- 9
RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/service/NovelService.java Прегледај датотеку

@@ -4,10 +4,10 @@ import com.ruoyi.novel.domain.AuthorApplication;
4 4
 import com.ruoyi.novel.domain.AuthorApplicationDTO;
5 5
 import com.ruoyi.novel.domain.Chapter;
6 6
 import com.ruoyi.novel.domain.Novel;
7
-import com.ruoyi.novel.repository.elastic.NovelSearchRepository;
7
+//import com.ruoyi.novel.repository.elastic.NovelSearchRepository;
8 8
 import com.ruoyi.novel.repository.jpa.NovelRepository;
9 9
 import jdk.jfr.Category;
10
-import org.elasticsearch.client.tasks.ElasticsearchException;
10
+//import org.elasticsearch.client.tasks.ElasticsearchException;
11 11
 import org.springframework.scheduling.annotation.Async;
12 12
 import org.springframework.stereotype.Service;
13 13
 import org.springframework.transaction.annotation.Propagation;
@@ -57,17 +57,17 @@ public interface NovelService {
57 57
 //    String getChapterContent(Long chapterId);
58 58
 //    void submitAuthorApplication(AuthorApplicationDTO dto, Long userId);
59 59
 public NovelRepository novelRepository = null; // JPA
60
-    public NovelSearchRepository novelSearchRepository = null; // ES
60
+    //public NovelSearchRepository novelSearchRepository = null; // ES
61 61
     @Transactional(propagation = Propagation.REQUIRED)
62 62
     public default void syncNovelToEs(Long novelId) {
63 63
         Novel novel = novelRepository.findById(novelId).orElseThrow();
64
-        novelSearchRepository.save(novel);
64
+        //novelSearchRepository.save(novel);
65 65
     }
66 66
 
67
-    @Async
68
-    public default void asyncIndexToEs(Novel novel) {
69
-        novelSearchRepository.save(novel);
70
-    }
67
+//    @Async
68
+//    public default void asyncIndexToEs(Novel novel) {
69
+//        novelSearchRepository.save(novel);
70
+//    }
71 71
 //    @Retryable(value = { ElasticsearchException.class }, maxAttempts = 3, backoff = @Backoff(delay = 1000))
72 72
 //    public void saveToEsWithRetry(Novel novel) {
73 73
 //        novelSearchRepository.save(novel);
@@ -75,6 +75,6 @@ public NovelRepository novelRepository = null; // JPA
75 75
     @PostConstruct
76 76
     public default void checkRepositories() {
77 77
         assert novelRepository != null : "JPA Repository未注入";
78
-        assert novelSearchRepository != null : "ES Repository未注入";
78
+        //assert novelSearchRepository != null : "ES Repository未注入";
79 79
     }
80 80
 }

+ 1
- 1
RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/service/impl/AuthServiceImpl.java Прегледај датотеку

@@ -1,8 +1,8 @@
1 1
 package com.ruoyi.novel.service.impl;
2 2
 
3 3
 import com.ruoyi.common.core.domain.model.LoginUser;
4
+import com.ruoyi.novel.repository.jpa.UserRepository;
4 5
 import com.ruoyi.novel.service.IAuthService;
5
-import com.ruoyi.novel.service.UserRepository;
6 6
 import com.ruoyi.novel.utils.JwtTokenProvider;
7 7
 import org.springframework.beans.factory.annotation.Autowired;
8 8
 import org.springframework.stereotype.Service;

+ 100
- 57
RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/service/impl/NovelSearchServiceImpl.java Прегледај датотеку

@@ -1,19 +1,26 @@
1 1
 package com.ruoyi.novel.service.impl;
2 2
 
3
+import com.ruoyi.common.constant.HttpStatus;
4
+import com.ruoyi.common.core.page.PageDomain;
5
+import com.ruoyi.common.core.page.TableDataInfo;
6
+import com.ruoyi.common.utils.PageUtils;
7
+import com.ruoyi.common.utils.StringUtils;
8
+import com.ruoyi.novel.config.TableSupport;
3 9
 import com.ruoyi.novel.domain.Novel;
4 10
 import com.ruoyi.novel.mapper.NovelMapper;
5 11
 import com.ruoyi.novel.service.NovelSearchService;
6
-import org.elasticsearch.index.query.QueryBuilders;
12
+//import org.elasticsearch.index.query.QueryBuilders;
7 13
 import org.slf4j.Logger;
8 14
 import org.slf4j.LoggerFactory;
9 15
 import org.springframework.beans.factory.annotation.Autowired;
10
-import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
11
-import org.springframework.data.elasticsearch.core.IndexOperations;
12
-import org.springframework.data.elasticsearch.core.SearchHit;
13
-import org.springframework.data.elasticsearch.core.SearchHits;
14
-import org.springframework.data.elasticsearch.core.document.Document;
15
-import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
16
-import org.springframework.data.elasticsearch.core.query.*;
16
+import org.springframework.cache.annotation.Cacheable;
17
+//import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
18
+//import org.springframework.data.elasticsearch.core.IndexOperations;
19
+//import org.springframework.data.elasticsearch.core.SearchHit;
20
+//import org.springframework.data.elasticsearch.core.SearchHits;
21
+//import org.springframework.data.elasticsearch.core.document.Document;
22
+//import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
23
+//import org.springframework.data.elasticsearch.core.query.*;
17 24
 import org.springframework.scheduling.annotation.Scheduled;
18 25
 import org.springframework.stereotype.Service;
19 26
 
@@ -28,58 +35,93 @@ import java.util.stream.Collectors;
28 35
 public class NovelSearchServiceImpl implements NovelSearchService {
29 36
     private static final Logger logger = LoggerFactory.getLogger(NovelSearchServiceImpl.class);
30 37
 
31
-    @Autowired
32
-    private ElasticsearchRestTemplate elasticTemplate;
38
+//    @Autowired
39
+//    private ElasticsearchRestTemplate elasticTemplate;
33 40
     @Autowired
34 41
     private NovelMapper novelMapper;
35 42
 
36 43
     private static final String INDEX_NAME = "novels";
37 44
 
38 45
 //    @PostConstruct
39
-    public void createIndexIfNotExists() {
40
-        IndexOperations indexOps = elasticTemplate.indexOps(IndexCoordinates.of(INDEX_NAME));
41
-        if (!indexOps.exists()) {
42
-            // 创建索引
43
-            indexOps.create();
44
-
45
-            // 创建映射
46
-            Document mapping = indexOps.createMapping(Novel.class);
47
-            indexOps.putMapping(mapping);
48
-        }
49
-//        if (!elasticTemplate.indexExists(INDEX_NAME)) {
50
-//            elasticTemplate.createIndex(INDEX_NAME);
51
-//            elasticTemplate.putMapping(Novel.class);
46
+//    public void createIndexIfNotExists() {
47
+//        IndexOperations indexOps = elasticTemplate.indexOps(IndexCoordinates.of(INDEX_NAME));
48
+//        if (!indexOps.exists()) {
49
+//            // 创建索引
50
+//            indexOps.create();
51
+//
52
+//            // 创建映射
53
+//            Document mapping = indexOps.createMapping(Novel.class);
54
+//            indexOps.putMapping(mapping);
52 55
 //        }
56
+////        if (!elasticTemplate.indexExists(INDEX_NAME)) {
57
+////            elasticTemplate.createIndex(INDEX_NAME);
58
+////            elasticTemplate.putMapping(Novel.class);
59
+////        }
60
+//    }
61
+//    public List<Novel> searchNovels(String keyword) {
62
+//        // 构建查询条件
63
+//        NativeSearchQuery query = new NativeSearchQueryBuilder()
64
+//                .withQuery(QueryBuilders.multiMatchQuery(keyword, "title", "author", "description"))
65
+//                .build();
66
+//        // 执行搜索
67
+//        SearchHits<Novel> hits = elasticTemplate.search(query, Novel.class);
68
+//        return hits.stream()
69
+//                .map(SearchHit::getContent)
70
+//                .collect(Collectors.toList());
71
+//
72
+//        //return elasticTemplate.search(query, Novel.class).getContent();
73
+//    }
74
+@Cacheable(value = "novelSearch", key = "#keyword + '-' + #categoryId")
75
+public List<Novel> searchNovels(String keyword, Long categoryId) {
76
+    startPage();
77
+    PageDomain pageDomain = TableSupport.buildPageRequest();
78
+    if (pageDomain.getPageSize() > 100) {
79
+        pageDomain.setPageSize(100); // 限制最大分页大小
53 80
     }
54
-    public List<Novel> searchNovels(String keyword) {
55
-        // 构建查询条件
56
-        NativeSearchQuery query = new NativeSearchQueryBuilder()
57
-                .withQuery(QueryBuilders.multiMatchQuery(keyword, "title", "author", "description"))
58
-                .build();
59
-        // 执行搜索
60
-        SearchHits<Novel> hits = elasticTemplate.search(query, Novel.class);
61
-        return hits.stream()
62
-                .map(SearchHit::getContent)
63
-                .collect(Collectors.toList());
81
+    Novel novel = new Novel();
64 82
 
65
-        //return elasticTemplate.search(query, Novel.class).getContent();
83
+    // 设置分类过滤
84
+    if (categoryId != null && categoryId > 0) {
85
+        novel.setCategoryId(categoryId);
66 86
     }
87
+    // 执行搜索
88
+    List<Novel> list = novelMapper.selectNovelList(novel, keyword);
89
+    return (List<Novel>) getDataTable(list);
90
+
91
+}
67 92
 
68
-    @Override
69
-    public void indexNovel(Novel novel) {
70
-        IndexQuery indexQuery = new IndexQueryBuilder()
71
-                .withId(novel.getId().toString())
72
-                .withObject(novel)
73
-                .build();
74
-        elasticTemplate.index(indexQuery, IndexCoordinates.of(INDEX_NAME));
93
+    protected void startPage() {
94
+        PageDomain pageDomain = TableSupport.buildPageRequest();
95
+        Integer pageNum = pageDomain.getPageNum();
96
+        Integer pageSize = pageDomain.getPageSize();
97
+        if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)) {
98
+            String orderBy = pageDomain.getOrderBy();
99
+            PageUtils.startPage(pageNum, pageSize, orderBy);
100
+        }
75 101
     }
76
-    @Override
77
-    public void updateNovelIndex(Novel novel) {
78
-        UpdateQuery updateQuery = UpdateQuery.builder(novel.getId().toString())
79
-                .withDocument(Document.from(convertNovelToMap(novel)))
80
-                .build();
81
-        elasticTemplate.update(updateQuery, IndexCoordinates.of(INDEX_NAME));
102
+    protected TableDataInfo getDataTable(List<?> list) {
103
+        TableDataInfo rspData = new TableDataInfo();
104
+        rspData.setCode(HttpStatus.SUCCESS);
105
+        rspData.setMsg("查询成功");
106
+        rspData.setRows(list);
107
+        rspData.setTotal(PageUtils.getLocalPage().getTotal());
108
+        return rspData;
82 109
     }
110
+//    @Override
111
+//    public void indexNovel(Novel novel) {
112
+//        IndexQuery indexQuery = new IndexQueryBuilder()
113
+//                .withId(novel.getId().toString())
114
+//                .withObject(novel)
115
+//                .build();
116
+//        elasticTemplate.index(indexQuery, IndexCoordinates.of(INDEX_NAME));
117
+//    }
118
+//    @Override
119
+//    public void updateNovelIndex(Novel novel) {
120
+//        UpdateQuery updateQuery = UpdateQuery.builder(novel.getId().toString())
121
+//                .withDocument(Document.from(convertNovelToMap(novel)))
122
+//                .build();
123
+//        elasticTemplate.update(updateQuery, IndexCoordinates.of(INDEX_NAME));
124
+//    }
83 125
     private Map<String, Object> convertNovelToMap(Novel novel) {
84 126
         Map<String, Object> map = new HashMap<>();
85 127
         map.put("title", novel.getTitle());
@@ -89,15 +131,16 @@ public class NovelSearchServiceImpl implements NovelSearchService {
89 131
         map.put("status", novel.getStatus());
90 132
         return map;
91 133
     }
92
-    @Override
93
-    public void deleteNovelIndex(Long id) {
94
-        elasticTemplate.delete(id.toString(), IndexCoordinates.of(INDEX_NAME));
95
-    }
134
+
135
+//    @Override
136
+//    public void deleteNovelIndex(Long id) {
137
+//        elasticTemplate.delete(id.toString(), IndexCoordinates.of(INDEX_NAME));
138
+//    }
96 139
     // 定时同步数据库数据到ES
97
-    @Scheduled(fixedRate = 3600000) // 每小时同步一次
98
-    public void syncDataToEs() {
99
-        List<Novel> novels = novelMapper.selectList(null);
100
-        novels.forEach(this::indexNovel);
101
-        logger.info("同步 {} 条小说数据到ES", novels.size());
102
-    }
140
+//    @Scheduled(fixedRate = 3600000) // 每小时同步一次
141
+//    public void syncDataToEs() {
142
+//        List<Novel> novels = novelMapper.selectList(null);
143
+//        novels.forEach(this::indexNovel);
144
+//        logger.info("同步 {} 条小说数据到ES", novels.size());
145
+//    }
103 146
 }

+ 2
- 2
RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/service/impl/NovelServiceImpl.java Прегледај датотеку

@@ -275,7 +275,7 @@ public class NovelServiceImpl implements NovelService {
275 275
             novel.setCategoryId(categoryId);
276 276
         }
277 277
 
278
-        List<Novel> list = novelMapper.selectNovelList(novel);
278
+        List<Novel> list = novelMapper.selectNovelList(novel,null);
279 279
         return (List<Novel>) getDataTable(list);
280 280
     }
281 281
 
@@ -341,7 +341,7 @@ public class NovelServiceImpl implements NovelService {
341 341
     }
342 342
     @Override
343 343
     public List<Novel> selectNovelList(Novel novel) {
344
-        return novelMapper.selectNovelList(novel);
344
+        return novelMapper.selectNovelList(novel,null);
345 345
     }
346 346
 
347 347
     @Override

+ 4
- 3
RuoYi-Vue/ruoyi-system/src/main/java/com/ruoyi/novel/utils/JwtTokenProvider.java Прегледај датотеку

@@ -1,9 +1,10 @@
1 1
 package com.ruoyi.novel.utils;
2 2
 
3
+import com.ruoyi.common.core.domain.entity.SysUser;
3 4
 import io.jsonwebtoken.Claims;
4 5
 import io.jsonwebtoken.Jwts;
5 6
 import io.jsonwebtoken.SignatureAlgorithm;
6
-import org.elasticsearch.client.security.user.User;
7
+//import org.elasticsearch.client.security.user.User;
7 8
 import org.springframework.beans.factory.annotation.Value;
8 9
 import org.springframework.stereotype.Component;
9 10
 
@@ -19,12 +20,12 @@ public class JwtTokenProvider {
19 20
     @Value("${app.jwt.expiration}")
20 21
     private int jwtExpirationInMs;
21 22
 
22
-    public String generateToken(User user) {
23
+    public String generateToken(SysUser user) {
23 24
         Date now = new Date();
24 25
         Date expiryDate = new Date(now.getTime() + jwtExpirationInMs);
25 26
 
26 27
         return Jwts.builder()
27
-                .setSubject(user.getUsername())
28
+                .setSubject(user.getUserName())
28 29
                 .setIssuedAt(now)
29 30
                 .setExpiration(expiryDate)
30 31
                 .signWith(SignatureAlgorithm.HS512, jwtSecret)

+ 14
- 1
RuoYi-Vue/ruoyi-system/src/main/resources/mapper/novel/NovelMapper.xml Прегледај датотеку

@@ -32,8 +32,21 @@
32 32
         <include refid="selectNovelVo"/>
33 33
         <where>
34 34
             <if test="title != null and title != ''"> AND title LIKE CONCAT('%', #{title}, '%')</if>
35
-            <if test="authorName != null and authorName != ''"> AND author_name LIKE CONCAT('%', #{authorName}, '%')</if>
36 35
             <if test="categoryId != null"> AND category_id = #{categoryId}</if>
36
+            <if test="keyword != null and keyword != ''">
37
+                <!-- 普通模式 -->
38
+                <!-- AND (
39
+                    title LIKE CONCAT('%', #{keyword}, '%')
40
+                    OR author LIKE CONCAT('%', #{keyword}, '%')
41
+                    OR description LIKE CONCAT('%', #{keyword}, '%')
42
+                ) -->
43
+
44
+                <!-- 全文索引模式 -->
45
+                AND MATCH(title, author, description) AGAINST (#{keyword} IN BOOLEAN MODE)
46
+            </if>
47
+            <if test="authorName != null and authorName != ''"> AND author_name LIKE CONCAT('%', #{authorName}, '%')</if>
48
+            <if test="description != null and description != ''"> AND description LIKE CONCAT('%', #{description}, '%')</if>
49
+
37 50
             <if test="status != null and status != ''"> AND status = #{status}</if>
38 51
         </where>
39 52
         ORDER BY update_time DESC

Loading…
Откажи
Сачувај