parent
f5ed96dca8
commit
dae3c5b24a
@ -0,0 +1,139 @@ |
||||
package com.keyware.shandan.browser; |
||||
|
||||
import cn.hutool.core.date.DateField; |
||||
import cn.hutool.core.date.DateTime; |
||||
import cn.hutool.core.date.DateUtil; |
||||
import cn.hutool.json.JSONUtil; |
||||
import com.alibaba.fastjson.JSONArray; |
||||
import com.alibaba.fastjson.JSONObject; |
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
import com.keyware.shandan.common.util.StringUtils; |
||||
import com.keyware.shandan.system.entity.SysOperateLog; |
||||
import com.keyware.shandan.system.service.SysOperateLogService; |
||||
import com.keyware.shandan.system.utils.DictUtil; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import java.util.*; |
||||
import java.util.stream.Collectors; |
||||
|
||||
/** |
||||
* 用于处理分析系统热词和用户搜索历史 |
||||
*/ |
||||
@Slf4j |
||||
@Component |
||||
public class SearchLogProcessor extends Thread { |
||||
private final SysOperateLogService logService; |
||||
private int cycle = 7; |
||||
private DateField unit = DateField.DAY_OF_MONTH; |
||||
private final Map<String, Integer> systemWords = new HashMap<>(); |
||||
|
||||
public SearchLogProcessor(SysOperateLogService logService) { |
||||
this.logService = logService; |
||||
} |
||||
|
||||
@Override |
||||
public void run() { |
||||
log.info("搜索日志处理程序启动成功"); |
||||
while (true) { |
||||
parseConfig(); |
||||
systemWords.clear(); |
||||
LambdaQueryWrapper<SysOperateLog> query = new LambdaQueryWrapper<>(); |
||||
DateTime date = DateUtil.offset(new Date(), unit, cycle); |
||||
query.gt(SysOperateLog::getOperateTime, date.toJdkDate()); |
||||
logService.list(query).forEach(logs -> { |
||||
String word = parseLogs(logs); |
||||
if (StringUtils.hasText(word)) { |
||||
addSystemWords(word); |
||||
} |
||||
}); |
||||
try { |
||||
Thread.sleep(1000 * 60 * 30); |
||||
} catch (InterruptedException ignore) { |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 获取用户的搜索历史 |
||||
* |
||||
* @param loginName |
||||
* @return |
||||
*/ |
||||
public List<String> getUserSearchHistory(String loginName) { |
||||
List<String> searchHistory = new ArrayList<>(); |
||||
LambdaQueryWrapper<SysOperateLog> query = new LambdaQueryWrapper<>(); |
||||
query.eq(SysOperateLog::getLoginName, loginName).orderByDesc(SysOperateLog::getOperateTime).last("limit 30"); |
||||
for (SysOperateLog logs : logService.list(query)) { |
||||
String word = parseLogs(logs); |
||||
if (StringUtils.hasText(word) && !searchHistory.contains(word)) { |
||||
searchHistory.add(word); |
||||
} |
||||
} |
||||
return searchHistory; |
||||
} |
||||
|
||||
/** |
||||
* 获取系统级热词 |
||||
* |
||||
* @return |
||||
*/ |
||||
public List<String> getSystemWords() { |
||||
return systemWords |
||||
.entrySet() |
||||
.stream() |
||||
//.sorted(Comparator.comparingInt(Map.Entry::getValue))
|
||||
.sorted((a, b) -> b.getValue() - a.getValue()) |
||||
.map(Map.Entry::getKey) |
||||
.collect(Collectors.toList()); |
||||
} |
||||
|
||||
|
||||
private String parseLogs(SysOperateLog logs) { |
||||
String value = null; |
||||
String url = logs.getUrl(); |
||||
if (url.startsWith("/browser/search/")) { |
||||
String paramsText = logs.getParams(); |
||||
if (JSONUtil.isJsonArray(logs.getParams())) { |
||||
for (Object object : JSONArray.parseArray(paramsText)) { |
||||
JSONObject json = (JSONObject) object; |
||||
String fieldName = json.getString("fieldName"); |
||||
if ("metadataName".equals(fieldName)) { |
||||
value = json.getString("fieldValue"); |
||||
break; |
||||
} |
||||
} |
||||
} else { |
||||
JSONObject json = JSONObject.parseObject(paramsText); |
||||
if (json.containsKey("search")) { |
||||
value = json.getString("search"); |
||||
} |
||||
} |
||||
|
||||
} |
||||
return value; |
||||
} |
||||
|
||||
private void addSystemWords(String word) { |
||||
Integer count = systemWords.get(word); |
||||
count = count == null ? 0 : count; |
||||
systemWords.put(word, ++count); |
||||
} |
||||
|
||||
private void parseConfig() { |
||||
String systemWordsConfig = DictUtil.getPublicDict("browser_system_words_config"); |
||||
if (StringUtils.hasText(systemWordsConfig)) { |
||||
systemWordsConfig = systemWordsConfig.toLowerCase(); |
||||
if (systemWordsConfig.endsWith("d")) { |
||||
cycle = -Math.abs(Integer.parseInt(systemWordsConfig.replace("d", ""))); |
||||
unit = DateField.DAY_OF_YEAR; |
||||
} else if (systemWordsConfig.endsWith("m")) { |
||||
cycle = -Math.abs(Integer.parseInt(systemWordsConfig.replace("m", ""))); |
||||
unit = DateField.MONTH; |
||||
} else if (systemWordsConfig.endsWith("y")) { |
||||
cycle = -Math.abs(Integer.parseInt(systemWordsConfig.replace("y", ""))); |
||||
unit = DateField.YEAR; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,34 @@ |
||||
package com.keyware.shandan.browser.controller; |
||||
|
||||
import com.keyware.shandan.browser.SearchLogProcessor; |
||||
import com.keyware.shandan.common.entity.Result; |
||||
import com.keyware.shandan.frame.config.security.SecurityUtil; |
||||
import org.springframework.security.core.Authentication; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
/** |
||||
* 搜索建议前端控制器 |
||||
*/ |
||||
@RestController |
||||
@RequestMapping("/search/suggest") |
||||
public class SearchSuggestController { |
||||
|
||||
private final SearchLogProcessor logProcessor; |
||||
|
||||
public SearchSuggestController(SearchLogProcessor logProcessor) { |
||||
this.logProcessor = logProcessor; |
||||
} |
||||
|
||||
@GetMapping("/user/history") |
||||
public Result<Object> getUserHistory() { |
||||
String loginName = SecurityUtil.getLoginUsername(); |
||||
return Result.of(logProcessor.getUserSearchHistory(loginName)); |
||||
} |
||||
|
||||
@GetMapping("/system/words") |
||||
public Result<Object> getSystemWords() { |
||||
return Result.of(logProcessor.getSystemWords()); |
||||
} |
||||
} |
Reference in new issue