shikeyin
2024-01-11 65da8373531677b1c37a98f53eaa30c892f35e5a
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
package com.iplatform.base.cache;
 
import com.iplatform.base.Constants;
import com.iplatform.base.DeptCacheProvider;
import com.iplatform.base.service.DeptServiceImpl;
import com.iplatform.base.util.DeptUtils;
import com.iplatform.model.po.S_dept;
import com.walker.cache.Cache;
import com.walker.infrastructure.utils.JsonUtils;
import com.walker.infrastructure.utils.StringUtils;
import com.walker.support.redis.cache.RedisCacheProvider;
 
import java.util.ArrayList;
import java.util.List;
 
public class RedisDeptCacheProvider extends RedisCacheProvider<String> implements DeptCacheProvider {
 
    private boolean allowCacheChildren = true;
 
    private DeptServiceImpl deptService;
 
    public void setDeptService(DeptServiceImpl deptService) {
        this.deptService = deptService;
    }
 
    public RedisDeptCacheProvider(){
        this.setUseRedis(true);
        this.setLoadPage(false);
    }
 
    @Override
    public void setAllowCacheChildren(boolean allow) {
        this.allowCacheChildren = allow;
    }
 
    @Override
    public S_dept getDept(long deptId) {
        // 超级用户虚拟一个机构
        if(deptId == 0){
            return DeptUtils.SUPER_VISOR_DEPT;
        }
 
        String data = this.getCacheData(String.valueOf(deptId));
        if(StringUtils.isEmpty(data)){
            logger.error("查询机构缓存不存在,重新加载:" + deptId);
            S_dept s_dept = this.deptService.queryOneDept(deptId);
            if(s_dept == null){
                throw new IllegalStateException("数据库加载机构不存在,id=" + deptId);
            }
            try {
                if(this.allowCacheChildren){
                    this.putDept(s_dept);
                } else {
                    this.putCacheData(String.valueOf(deptId), JsonUtils.objectToJsonString(s_dept));
                }
                return s_dept;
            } catch (Exception ex){
                throw new RuntimeException("添加 [机构] 缓存错误:" + ex.getMessage(), ex);
            }
        }
        try {
            return JsonUtils.jsonStringToObject(data, S_dept.class);
        } catch (Exception e) {
            throw new RuntimeException("获得机构缓存错误:" + deptId + ", " + e.getMessage(), e);
        }
    }
 
    @Override
    public void updateDept(S_dept s_dept) {
        try {
            this.updateCacheData(String.valueOf(s_dept.getId()), JsonUtils.objectToJsonString(s_dept));
        } catch (Exception e) {
            throw new RuntimeException("更新机构缓存错误:" + s_dept.getId() + ", " + e.getMessage(), e);
        }
    }
 
    @Override
    public void removeDept(long deptId) {
        String key = String.valueOf(deptId);
        String keyChildren = key + DeptUtils.KEY_CHILDREN_PREFIX;
 
        S_dept current = this.getDept(deptId);
        if(current == null){
            logger.warn("机构缓存已不存在,无需删除");
            return;
        }
 
        // 删除该机构子机构缓存列表
        this.removeCacheData(keyChildren);
        this.removeCacheData(key);
 
        if(current.getParent_id().longValue() == 0){
            return;
        }
 
        // 2023-07-17,针对机构较大的项目,是不需要把机构树放Redis缓存的。
        if(this.allowCacheChildren){
            // 更新父机构对应的childrenList
            String parentId = String.valueOf(current.getParent_id());
            List<String> parentChildrenList = this.getChildrenDeptIdOneLevel(current.getParent_id());
            if(parentChildrenList != null){
                parentChildrenList.remove(String.valueOf(deptId));
                try {
                    this.updateCacheData(parentId + DeptUtils.KEY_CHILDREN_PREFIX, JsonUtils.objectToJsonString(parentChildrenList));
                } catch (Exception e) {
                    throw new RuntimeException("删除机构缓存时,更新父节点childrenList报错:" + e.getMessage(), e);
                }
            }
        }
    }
 
    @Override
    public void putDept(S_dept s_dept) {
        String id = String.valueOf(s_dept.getId());
        try {
            // 添加机构对象缓存
            this.putCacheData(id, JsonUtils.objectToJsonString(s_dept));
            if(this.allowCacheChildren){
                // 2023-07-17
                // 添加机构子机构列表,目前为空列表
                this.putCacheData(id + DeptUtils.KEY_CHILDREN_PREFIX, JsonUtils.objectToJsonString(new ArrayList<String>(2)));
            }
 
            if(s_dept.getParent_id().longValue() == 0){
                // 顶级单位,没有父机构了
                logger.debug("顶级机构,不用更新父机构列表, " + id);
                return;
            }
 
            if(this.allowCacheChildren){
                // 2023-07-17
                // 更新父机构列表
                List<String> parentChildrenList = this.getChildrenDeptIdOneLevel(s_dept.getParent_id());
                if(StringUtils.isEmptyList(parentChildrenList)){
                    parentChildrenList = new ArrayList<>();
                }
                parentChildrenList.add(id);
                this.updateCacheData(String.valueOf(s_dept.getParent_id()) + DeptUtils.KEY_CHILDREN_PREFIX, JsonUtils.objectToJsonString(parentChildrenList));
                if(logger.isDebugEnabled()){
                    logger.debug("添加机构缓存,parentChildrenList = " + parentChildrenList);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("添加 [机构] 缓存错误:" + e.getMessage(), e);
        }
    }
 
    @Override
    public List<String> getChildrenDeptIdOneLevel(long deptId) {
        if(this.allowCacheChildren){
            String key = String.valueOf(deptId) + DeptUtils.KEY_CHILDREN_PREFIX;
            String data = this.getCacheData(key);
            if(StringUtils.isEmpty(data)){
                logger.error("未找到缓存中子机构列表: " + key);
                return null;
            }
            try {
                return JsonUtils.jsonStringToObject(data, List.class);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            // 2023-07-17,不支持缓存树结构,从数据库查询
            throw new UnsupportedOperationException("暂未实现代码:从数据库加载:"+ deptId + " 下一级所有子机构ID集合");
        }
    }
 
    @Override
    public List<S_dept> getChildrenDeptOneLevel(long deptId) {
        List<String> childrenIdList = this.getChildrenDeptIdOneLevel(deptId);
        if(StringUtils.isEmptyList(childrenIdList)){
            return null;
        }
 
        List<S_dept> resultList = new ArrayList<>();
        S_dept s_dept = null;
        for(String id : childrenIdList){
            s_dept = this.getDept(Long.parseLong(id));
            resultList.add(s_dept);
        }
        return resultList;
    }
 
//    @Override
//    protected int loadDataToCache(Cache cache) {
//        List<S_dept> list = this.deptService.queryAllDeptListForCache();
//        if(!StringUtils.isEmptyList(list)){
//            // 如果redis中缓存数量和数据库中不一致(少),则清空redis缓存,重新加载数据库数据到缓存中。
//            long totalCache = cache.getPersistentSize();
//            if(totalCache < list.size()){
//                logger.info("redis缓存中[机构]数量小于实际用户,需要清空缓存重新加载! cache = " + totalCache + ", db = " + list.size());
//                cache.clear();
//                for(S_dept h : list){
//                    this.putDept(h);
//                }
//            }
//            return list.size();
//        }
//        return 0;
//    }
 
    @Override
    public String getProviderName() {
        return Constants.CACHE_NAME_DEPT;
    }
 
    @Override
    public Class<?> getProviderType() {
        return String.class;
    }
 
//    private static final String KEY_CHILDREN_PREFIX = ".children";
}