liusheng
2025-04-28 284545b6694878772a77ed329283b4901a4534f0
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
@startuml
start
:入参,userid,socketMessage;
    note right
           //发送内空的类型(text,image)
            private String type;
            //内容(这个是在开发测试的时候用)
            private String content;
            //模板ID
            private Long templateId;
            //问题信息
            private QuestionMessage questionMessage;
            //用户ID(接收放)
            private String userId;
            //图片
            private String image;
            //图片,音、视频的字节大小
            private Integer fileSize;
    end note
if (如果模板id不为空,socketMessage.getTemplateId() != null) then(不为空)
      partition "通过模板ID获取模板问题" {
            :通过模板ID获取模板信息,并将信息放到redis中,
            key为userId + "ivrLibaTemplateVO1",过期时间2小时;
            note left
                直接调用ivrLibaTemplateService.selectInfoByCondition
                获取到“模板信息”、“问题话术”、“话术选项”
             end note
            :从返回的模板信息中获取问题话术集合
            并将集合放到redis中,key为userId + "ivrLibaTemplateScriptVOList";
            note left
                  List<IvrLibaTemplateScriptVO> ivrLibaTemplateScriptVOList
                  根据IvrLibaTemplateScriptVO中的Targetid(暂时当一个问题的序号)
                  排序一下
             end note
            :定义一些redis,这里之所以大量用redis,是用来进行多进程隔离;
            note left
                   userId + "backQuset" 用来返回调查的总结果
                   userId + "noVoice"   用来记录无声响应次数
                   userId + "mateNum"   用来记录无匹配次数
                   userId + "isOver"    用来记录整个问卷是否结束 0 :未结束     1:结束
            end note
             :从ivrLibaTemplateScriptVOList中获取到targetid为1的题
             放到QuestionMessage中;
             note left
               QuestionMessage的字段为
                        String content 返回的内容
                        String kcb 开场白
                        String jsy 结束语
                        IvrLibaTemplateScriptVO nowQuestion 当前问题
              end note
             :定义“开场白”,
             和 userId + "returnQues" 的redis;
    }
 
 
else (为空)
    :获取前端返回的questionMessage“问题信息”;
    :去redis中获取到“话术问题集合”
    List<IvrLibaTemplateScriptVO> ivrLibaTemplateScriptVOList;
    :获取到当前的要问题的问题从questionMessage中,
     IvrLibaTemplateScriptVO ivrLibaTemplateScriptVO;
    :去redis中获取模板信息,IvrLibaTemplateVO ivrLibaTemplateVO1;
    if(questionMessage的content为空,说明对方没有回答) then(true)
      partition "静默话术" {
           :先去redis中,获取当前用户的对该题的实际静默次数 Integer noVoice;
           if(实际静默次数是否等于模板中配置的次数,noVoice == ivrLibaTemplateVO1.getNoVoiceNum().intValue()) then(true)
                 :该题记录到调查的总结果中,即backQuset中,更新redis中的userId + "backQuset";
                 if(本题的targetid 等于 题目数量的最大值,即ivrLibaTemplateScriptVO.getTargetid() == ivrLibaTemplateScriptVOList.size()) then(true)
                     :说明这就是最后一道题了,将调查的结果,和结束语放到对象中,进行返回给用户;
                     note right
                         List<IvrLibaTemplateScriptVO> backQusetRedis = redisCache.getCacheObject(userId + "backQuset");
                          returnQues.setContent(JSON.toJSONString(backQusetRedis));
                          returnQues.setJsy("感谢您的耐心回答,再见");
                          redisCache.setCacheObject(userId + "returnQues", returnQues, 120, TimeUnit.MINUTES);
                          redisCache.setCacheObject(userId + "isOver", 1, 120, TimeUnit.MINUTES);
                     end note
                 else(不等于)
                     :则还有下一题,就根据当前teagetID+1 获取下一题
                      并将下一题的信息放到reids中,key为userId + "returnQues", returnQues
                      将userId + "noVoice"清零;
                 endif
           else(实际静默次数是否 不等于 模板中配置的次数) then(false)
                 :进行再将询问;
                 :去redis中获取userId + "noVoice"(实际的静默次数),得到Integer noVoice2
                  对实际静默次数加1,再放回reids中;
             endif
     }
    else (对方有回答) then(false)
         partition "循环本题的选项,ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList()" {
               :获取循环,获取到选项的正则匹配,
                再获取到用户的回答信息,进行正则匹配;
                note right
                        Pattern pattern = Pattern.compile(ivrLibaTemplateScriptVO.getIvrLibaScriptTargetoptionList().get(j).getTargetregex());
                        Matcher matcher = pattern.matcher(questionMessage.getContent());
                end note
                if(匹配到了) then(matcher.matches()为true)
                        :则将该选项中的IsUserOperation,设置成true(前端会根据这个拿值);
                        :去redis中获取userId + "backQuset",得到 List<IvrLibaTemplateScriptVO> backQuset;
                        :将该题的信息放到backQuset中;
                        :更新redis中的userId + "backQuset",并将userId + "noVoice"置为0;
                        :结束当前循环;
                        :通过当前正确选项的nextQeestion,获取下一题的targetID,再去ivrLibaTemplateScriptVOList,
                        进行匹配,获取IvrLibaTemplateScriptVO(下一题的信息);
                        :将获取到的题信息放到redis中,key为userId + "returnQues";
                else(没匹配到)
                        :去redis中获取userId + "mateNum",得到Integer mateNum(无匹配次数);
                        :无匹配次数去判断是否到最大询问次数,并且是否所有的选项都匹配完了;
                        if(无匹配次数“等于”最大询问次数,并且所有的选项都匹配完了) then(true)
                             :去redis中获取userId + "backQuset",得到 List<IvrLibaTemplateScriptVO> backQuset;
                             :将该题的信息放到backQuset中,更新redis中的userId + "backQuset";
                             :判断是否还有下一题;
                             if(本题的targetid < 总题数) then(有下一题)
                                    :则还有下一题,就根据当前teagetID+1 获取下一题
                                     并将下一题的信息放到reids中,key为userId + "returnQues",
                                     将userId + "mateNum"清零;
                             else(没有题了)
                                    :定义一个空的QuestionMessage returnQues2(用于返参);
                                    :去reids中获取userId + "backQuset",放到returnQues2的content中;
                                    :给returnQues2设置结束语;
                                    :更新redis中的userId + "returnQues";
                                    :将redis中的userId + "isOver"值,设置为1(表示整个流程结束);
                              endif
 
                        else(无匹配次数“小于”最大询问次数,并且所有的选项都匹配完了)
                            :无匹配次数+1,更新redis中的userId + "mateNum";
                         endif
                 endif
         }
         :选项匹配完成后,需要再去通过库再进行匹配一次;
         :去模板信息中获取通过库模板ID集合;
         note right
            String extemplateID = ivrLibaTemplateVO1.getSubmoduleID();
         end note
         if(通用库模板ID集合不为空) then(true)
             :通过通用库模板ID获取通过话术信息集合;
             note right
                     List<IvrLibaExtemplatescript> ivrLibaExtemplatescripts = ivrLibaExtemplatescriptMapper.queryIvrLibaExtemplatescriptList(list1);
             end note
             partition "循环通用话术集合List<IvrLibaExtemplatescript> ivrLibaExtemplatescripts" {
                 :通过正则将前端传回的结果,和遍历出来的话术正则进行匹配;
                 :匹配到后,去redis中获取userId + "returnQues",将答案放到问题对象中的submoduleText中;
                  note right
                        QuestionMessage returnQues = redisCache.getCacheObject(userId + "returnQues");
                        IvrLibaTemplateScriptVO nowQuestion = returnQues.getNowQuestion();
                        nowQuestion.setSubmoduleText(ivrLibaExtemplatescript.getSwitchText());
                        nowQuestion.setSubmoduleVoice(ivrLibaExtemplatescript.getSwitchWav());
                        redisCache.setCacheObject(userId + "returnQues", returnQues, 120, TimeUnit.MINUTES);
                  end note
              }
           :结束循环;
          endif
    endif
endif
:去redis中获取userId + "returnQues",将结果返回给前端;
:清空redis所有的变量;
 
note left
      //整个流程是否结束,将redis中的该userId下的数据删除;
      Integer isOver = redisCache.getCacheObject(userId + "isOver");
       if (isOver == 1) {
          redisCache.deleteObject(userId + "ivrLibaTemplateScriptVOList");
          redisCache.deleteObject(userId + "backQuset");
          redisCache.deleteObject(userId + "noVoice");
          redisCache.deleteObject(userId + "returnQues");
          redisCache.deleteObject(userId + "isOver");
          redisCache.deleteObject(userId + "ivrLibaTemplateVO1");
       }
end note
stop
@enduml