1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.oying.modules.pc.store.service.impl;
 
import cn.hutool.core.util.NumberUtil;
import com.oying.modules.pc.store.domain.Store;
import com.oying.modules.pc.store.domain.dto.StoreQueryCriteria;
import com.oying.modules.pc.store.mapper.StoreMapper;
import com.oying.modules.pc.store.service.StoreQueryService;
import com.oying.modules.pc.store.service.StoreService;
import com.oying.utils.PageResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
 
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
 
@Slf4j
@Service
@RequiredArgsConstructor
public class StoreQueryServiceImpl implements StoreQueryService {
 
    private final RedisTemplate<Object, Object> redisTemplate;
    private final StoreService storeService;
    private final StoreMapper storeMapper;
 
    @Override
    public PageResult<Store> findPagedStores(StoreQueryCriteria criteria) {
 
        PageResult<Store> page = new PageResult<>();
 
        // 1. 检查ZSET是否存在
        String setKey = criteria.buildConditionCacheKey();
        Long total = redisTemplate.opsForZSet().size(setKey);
        if (total == null || total == 0) {
            // 初始化缓存
            List<Long> ids = storeMapper.queryStoreIds(criteria);
            for (Long id : ids) {
                redisTemplate.opsForZSet().add(setKey, 1, id);
            }
            // 设置缓存过期时间
            redisTemplate.expire(setKey, 30, TimeUnit.MINUTES);
            total = (long) ids.size();
        }
 
        // 2. 从ZSET获取分页ID
        Long offset = NumberUtil.mul(criteria.getPage(), criteria.getSize()).longValue();
        long end = NumberUtil.add(offset, criteria.getSize()).longValue();
        Set<Long> storeIds = Optional.ofNullable(redisTemplate.opsForZSet()
                        .range(setKey, offset, end - 1)).orElse(Collections.emptySet())
                .stream().map(i-> (Long) i).collect(Collectors.toSet());
 
        // 3. 获取详情数据
        List<Store> stores = storeService.listByIds(storeIds);
 
        page.setContent(stores);
        page.setTotalElements(total);
        return page;
    }
}