前端-胡立永 21 hours ago
parent
commit
dba5270aae
4 changed files with 141 additions and 58 deletions
  1. +2
    -2
      admin-hanhai-vue/.env.production
  2. +126
    -35
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/api/service/impl/YaoDuApiServiceImpl.java
  3. +0
    -1
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/api/yaoduapi/YaoDuApiController.java
  4. +13
    -20
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/security/IpAccessLimitInterceptor.java

+ 2
- 2
admin-hanhai-vue/.env.production View File

@ -1,4 +1,4 @@
NODE_ENV=production
VUE_APP_API_BASE_URL=http://localhost:8081/api/
VUE_APP_CAS_BASE_URL=http://localhost:8888/cas
VUE_APP_API_BASE_URL=https://admin.hhlm1688.com/api/
VUE_APP_CAS_BASE_URL=https://admin.hhlm1688.com/cas
VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview

+ 126
- 35
jeecg-boot-module-system/src/main/java/org/jeecg/modules/api/service/impl/YaoDuApiServiceImpl.java View File

@ -22,6 +22,7 @@ import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.YaoDuCacheConstant;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.config.shiro.ShiroRealm;
@ -93,6 +94,7 @@ import org.jeecg.modules.hanHaiMember.entity.HanHaiMember;
import org.jeecg.modules.hanHaiMember.service.IHanHaiMemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
@ -366,8 +368,9 @@ public class YaoDuApiServiceImpl implements YaoDuApiService {
}
//根据分类获取动态帖子列表带分页
//根据分类获取动态帖子列表带分页
@Override
@Cacheable(value = YaoDuCacheConstant.YAODU_POST_PAGE_CACHE, key = "#classId + '_' + #pageBean.pageNo + '_' + #pageBean.pageSize")
public Result<?> getPostPage(String classId,PageBean pageBean){
Page<CityTrends> page = new Page<CityTrends>(pageBean.getPageNo(), pageBean.getPageSize());
Page<CityTrends> page1 = cityTrendsService
@ -376,51 +379,139 @@ public class YaoDuApiServiceImpl implements YaoDuApiService {
.orderByDesc(CityTrends::getCreateTime)
.page(page);
// 如果没有数据直接返回
if (page1.getRecords().isEmpty()) {
return Result.OK(page1);
}
for (CityTrends cityTrends : page1.getRecords()) {
cityTrends.setIsComment(Math.toIntExact(cityCommentService.lambdaQuery().eq(CityComment::getOrderId, cityTrends.getId()).count()));
// 批量获取所有需要的数据避免N+1查询问题
List<String> trendIds = page1.getRecords().stream()
.map(CityTrends::getId)
.collect(java.util.stream.Collectors.toList());
List<String> userIds = page1.getRecords().stream()
.map(CityTrends::getUserId)
.filter(StringUtils::isNotBlank)
.distinct()
.collect(java.util.stream.Collectors.toList());
List<String> shopIds = page1.getRecords().stream()
.map(CityTrends::getShopId)
.filter(StringUtils::isNotBlank)
.distinct()
.collect(java.util.stream.Collectors.toList());
// 批量查询评论数量
Map<String, Long> commentCountMap = new HashMap<>();
if (!trendIds.isEmpty()) {
List<Map<String, Object>> commentCounts = cityCommentService.listMaps(
new QueryWrapper<CityComment>()
.select("order_id, COUNT(*) as count")
.in("order_id", trendIds)
.groupBy("order_id")
);
commentCounts.forEach(map ->
commentCountMap.put((String) map.get("order_id"), ((Number) map.get("count")).longValue())
);
}
cityTrends.setIsBrowse(Math.toIntExact(appletBrowseRecordService
.lambdaQuery()
.eq(AppletBrowseRecord::getFormId, cityTrends.getId())
.eq(AppletBrowseRecord::getType, 0)
.eq(AppletBrowseRecord::getCategory, 0)
.count()));
// 批量查询浏览数量
Map<String, Long> browseCountMap = new HashMap<>();
if (!trendIds.isEmpty()) {
List<Map<String, Object>> browseCounts = appletBrowseRecordService.listMaps(
new QueryWrapper<AppletBrowseRecord>()
.select("form_id, COUNT(*) as count")
.in("form_id", trendIds)
.eq("type", 0)
.eq("category", 0)
.groupBy("form_id")
);
browseCounts.forEach(map ->
browseCountMap.put((String) map.get("form_id"), ((Number) map.get("count")).longValue())
);
}
cityTrends.setComments(cityCommentService.lambdaQuery()
.orderByDesc(CityComment::getCreateTime)
// 批量查询评论列表
Map<String, List<CityComment>> commentsMap = new HashMap<>();
if (!trendIds.isEmpty()) {
List<CityComment> allComments = cityCommentService.lambdaQuery()
.in(CityComment::getOrderId, trendIds)
.isNull(CityComment::getPid)
.eq(CityComment::getOrderId, cityTrends.getId())
.last("limit 3")
.list());
.orderByDesc(CityComment::getCreateTime)
.list();
// 按帖子ID分组评论每个帖子最多取3条
commentsMap = allComments.stream()
.collect(java.util.stream.Collectors.groupingBy(
CityComment::getOrderId,
java.util.stream.Collectors.collectingAndThen(
java.util.stream.Collectors.toList(),
list -> list.stream().limit(3).collect(java.util.stream.Collectors.toList())
)
));
}
HanHaiMember one = hanHaiMemberService.lambdaQuery()
.eq(HanHaiMember::getId, cityTrends.getUserId()).one();
// 批量查询用户信息
Map<String, HanHaiMember> memberMap = new HashMap<>();
if (!userIds.isEmpty()) {
List<HanHaiMember> members = hanHaiMemberService.lambdaQuery()
.in(HanHaiMember::getId, userIds)
.list();
memberMap = members.stream()
.collect(java.util.stream.Collectors.toMap(HanHaiMember::getId, member -> member));
}
if(StringUtils.isBlank(one.getName())){
cityTrends.setUserName(one.getNickName());
}else{
cityTrends.setUserName(one.getName());
}
cityTrends.setUserImage(one.getHeadImage());
// 批量查询店铺信息
Map<String, CityShop> shopMap = new HashMap<>();
if (!shopIds.isEmpty()) {
List<CityShop> shops = cityShopService.lambdaQuery()
.in(CityShop::getId, shopIds)
.list();
shopMap = shops.stream()
.collect(java.util.stream.Collectors.toMap(CityShop::getId, shop -> shop));
}
//获取今年是多少年
cityTrends.setYearDate(LocalDate.now().getYear() - one.getYearDate());
cityTrends.setAddId(one.getAddress());
if (one.getIdCardOpen() == null){
cityTrends.setIsContent("");
}else if (one.getIdCardOpen()== 1){
cityTrends.setIsContent("个人实名");
} else if (one.getIdCardOpen()== 2){
cityTrends.setIsContent("店铺实名");
}else{
cityTrends.setIsContent("");
// 设置查询结果
for (CityTrends cityTrends : page1.getRecords()) {
// 设置评论数量
cityTrends.setIsComment(commentCountMap.getOrDefault(cityTrends.getId(), 0L).intValue());
// 设置浏览数量
cityTrends.setIsBrowse(browseCountMap.getOrDefault(cityTrends.getId(), 0L).intValue());
// 设置评论列表
cityTrends.setComments(commentsMap.getOrDefault(cityTrends.getId(), new ArrayList<>()));
// 设置用户信息
HanHaiMember member = memberMap.get(cityTrends.getUserId());
if (member != null) {
if(StringUtils.isBlank(member.getName())){
cityTrends.setUserName(member.getNickName());
}else{
cityTrends.setUserName(member.getName());
}
cityTrends.setUserImage(member.getHeadImage());
//获取今年是多少年
if (member.getYearDate() != null) {
cityTrends.setYearDate(LocalDate.now().getYear() - member.getYearDate());
}
cityTrends.setAddId(member.getAddress());
if (member.getIdCardOpen() == null){
cityTrends.setIsContent("");
}else if (member.getIdCardOpen()== 1){
cityTrends.setIsContent("个人实名");
} else if (member.getIdCardOpen()== 2){
cityTrends.setIsContent("店铺实名");
}else{
cityTrends.setIsContent("");
}
}
//店铺信息
if(StringUtils.isNotBlank(cityTrends.getShopId())){
cityTrends.setShop(cityShopService.lambdaQuery().eq(CityShop::getId, cityTrends.getShopId()).one());
cityTrends.setShop(shopMap.get(cityTrends.getShopId()));
}
}


+ 0
- 1
jeecg-boot-module-system/src/main/java/org/jeecg/modules/api/yaoduapi/YaoDuApiController.java View File

@ -70,7 +70,6 @@ public class YaoDuApiController {
//根据分类获取动态帖子列表带分页
@ApiOperation(value="根据分类获取动态帖子列表带分页")
@GetMapping(value = "/getPostPage")
@Cacheable(value = YaoDuCacheConstant.YAODU_POST_PAGE_CACHE, key = "#classId + '_' + #pageBean.pageNo + '_' + #pageBean.pageSize")
public Result<?> getPostPage(String classId,PageBean pageBean) {
return yaoDuApiService.getPostPage(classId,pageBean);
}


+ 13
- 20
jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/security/IpAccessLimitInterceptor.java View File

@ -119,37 +119,30 @@ public class IpAccessLimitInterceptor implements HandlerInterceptor {
long currentSecond = currentTime / 1000;
long currentMinute = currentTime / 60000;
// 检查每秒请求数
String secondKey = IP_ACCESS_COUNT_KEY + ip + ":second:" + currentSecond;
Integer secondCount = (Integer) redisTemplate.opsForValue().get(secondKey);
if (secondCount == null) {
secondCount = 0;
}
String minuteKey = IP_ACCESS_COUNT_KEY + ip + ":minute:" + currentMinute;
// 先增加计数器
Long secondCount = redisTemplate.opsForValue().increment(secondKey);
redisTemplate.expire(secondKey, 2, TimeUnit.SECONDS);
if (secondCount >= MAX_REQUESTS_PER_SECOND) {
Long minuteCount = redisTemplate.opsForValue().increment(minuteKey);
redisTemplate.expire(minuteKey, 2, TimeUnit.MINUTES);
// 检查每秒请求数
if (secondCount > MAX_REQUESTS_PER_SECOND) {
recordViolation(ip);
log.warn("IP {} 每秒请求数超限: {}/{}", ip, secondCount, MAX_REQUESTS_PER_SECOND);
return false;
}
// 检查每分钟请求数
String minuteKey = IP_ACCESS_COUNT_KEY + ip + ":minute:" + currentMinute;
Integer minuteCount = (Integer) redisTemplate.opsForValue().get(minuteKey);
if (minuteCount == null) {
minuteCount = 0;
}
if (minuteCount >= MAX_REQUESTS_PER_MINUTE) {
if (minuteCount > MAX_REQUESTS_PER_MINUTE) {
recordViolation(ip);
log.warn("IP {} 每分钟请求数超限: {}/{}", ip, minuteCount, MAX_REQUESTS_PER_MINUTE);
return false;
}
// 更新计数器
redisTemplate.opsForValue().increment(secondKey);
redisTemplate.expire(secondKey, 2, TimeUnit.SECONDS);
redisTemplate.opsForValue().increment(minuteKey);
redisTemplate.expire(minuteKey, 2, TimeUnit.MINUTES);
return true;
}


Loading…
Cancel
Save