liusheng
2026-10-12 b25c3b5188e402695f3792ad7da53e452682cd80
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
package com.ruoyi.satisfaction.api;
 
import com.ruoyi.satisfaction.domain.ServiceSubtaskDetailRatioExport;
import com.ruoyi.satisfaction.service.SatisfactionSubtaskService;
import com.ruoyi.satisfaction.support.MydOptionRatioChartBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
 
import java.util.List;
import java.util.Map;
 
/**
 * {@link SatisfactionApi} 的内部实现(<b>常驻 Bean</b>)。
 * <p>
 * 开关已改为存放在 {@code sys_config} 参数表的 {@code satisfaction.enabled},
 * <b>运行时热读</b>,因此本 Bean 无条件创建:
 * <ul>
 *   <li>参数为 {@code true}(默认)→ {@link SatisfactionFacade} 正常转发到本实现;</li>
 *   <li>参数为 {@code false} → 本 Bean 仍然存在,但门面在
 *       {@link com.ruoyi.satisfaction.config.SatisfactionSwitch} 判断为关闭后
 *       不再转发,而是返回安全空值/全零。</li>
 * </ul>
 * 之所以不再用 {@code @ConditionalOnProperty}:那个注解只在<b>启动时</b>求值一次,
 * 与"改完参数配置即时生效"的诉求冲突。
 * <p>
 * 调用方<b>不要</b>直接注入本类,应注入 {@link SatisfactionFacade}。
 */
@Slf4j
@Component
public class DefaultSatisfactionApi implements SatisfactionApi {
 
    private final SatisfactionSubtaskService satisfactionSubtaskService;
 
    public DefaultSatisfactionApi(SatisfactionSubtaskService satisfactionSubtaskService) {
        this.satisfactionSubtaskService = satisfactionSubtaskService;
    }
 
    @Override
    public boolean isEnabled() {
        return true;
    }
 
    @Override
    public Map<String, Object> getSatisfactionCategories(String orgid) {
        return satisfactionSubtaskService.getSatisfactionCategories(orgid);
    }
 
    @Override
    public SatisfactionExportBundle getQuestionOptionRatioExport(List<Long> subtaskIds, String questiontext) {
        List<ServiceSubtaskDetailRatioExport> rows =
                satisfactionSubtaskService.statMydQuestionOptionForExport(subtaskIds, questiontext);
        if (rows == null || rows.isEmpty()) {
            // 没有行时不给图表构建器:ExcelUtil 会跳过该 Sheet(与原实现"空数据不画图"一致)
            return new SatisfactionExportBundle(rows, ServiceSubtaskDetailRatioExport.class, null);
        }
        return new SatisfactionExportBundle(rows, ServiceSubtaskDetailRatioExport.class,
                new MydOptionRatioChartBuilder(rows));
    }
 
    @Override
    public boolean hasSatisfactionCategory(String orgid) {
        Map<String, Object> categories = satisfactionSubtaskService.getSatisfactionCategories(orgid);
        if (categories == null || categories.isEmpty()) {
            return false;
        }
        Object voice = categories.get("voiceCategories");
        Object questionnaire = categories.get("questionnaireCategorys");
        return isNotEmpty(voice) || isNotEmpty(questionnaire);
    }
 
    private boolean isNotEmpty(Object value) {
        return value instanceof java.util.Collection && !((java.util.Collection<?>) value).isEmpty();
    }
 
    @Override
    public Map<String, Object> getSatisfactionIndex(String type, String code, String orgid,
                                                    Long ivrCategoryid, Long svyCategoryid) {
        return satisfactionSubtaskService.getSatisfactionIndex(type, code, orgid, ivrCategoryid, svyCategoryid);
    }
}